Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/tic tic: Duplicate and promote v1 records when mergi...



details:   https://anonhg.NetBSD.org/src/rev/70b237ddbe2b
branches:  trunk
changeset: 1008648:70b237ddbe2b
user:      roy <roy%NetBSD.org@localhost>
date:      Sun Mar 29 21:54:03 2020 +0000

description:
tic: Duplicate and promote v1 records when merging a v3 record

When this occurs, tic merges the matching v1 record into the original v1.

The screen-256color record by itself doesn't have any numerics bigger
than a short, but the xterm+256setaf record does.

The screen-256color record is now as it was before the recent terminfo2.cdb
merge into terminfo.cdb.

diffstat:

 usr.bin/tic/tic.c |  145 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 120 insertions(+), 25 deletions(-)

diffs (231 lines):

diff -r e7f978f908d1 -r 70b237ddbe2b usr.bin/tic/tic.c
--- a/usr.bin/tic/tic.c Sun Mar 29 21:46:22 2020 +0000
+++ b/usr.bin/tic/tic.c Sun Mar 29 21:54:03 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tic.c,v 1.38 2020/03/28 15:37:04 roy Exp $ */
+/* $NetBSD: tic.c,v 1.39 2020/03/29 21:54:03 roy Exp $ */
 
 /*
  * Copyright (c) 2009, 2010, 2020 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: tic.c,v 1.38 2020/03/28 15:37:04 roy Exp $");
+__RCSID("$NetBSD: tic.c,v 1.39 2020/03/29 21:54:03 roy Exp $");
 
 #include <sys/types.h>
 #include <sys/queue.h>
@@ -51,6 +51,7 @@
 #include <fcntl.h>
 #include <search.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -141,6 +142,22 @@
 }
 
 static TERM *
+find_newest_term(const char *name)
+{
+       char *lname;
+       TERM *term;
+
+       lname = _ti_getname(TERMINFO_RTYPE, name);
+       if (lname == NULL)
+               return NULL;
+       term = find_term(lname);
+       free(lname);
+       if (term == NULL)
+               term = find_term(name);
+       return term;
+}
+
+static TERM *
 store_term(const char *name, TERM *base_term)
 {
        TERM *term;
@@ -228,24 +245,9 @@
        int num;
        size_t n;
 
-       /* Promote record type if needed. */
-       if (rtic->rtype < utic->rtype) {
-               char *obuf = rtic->nums.buf;
-
-               cap = rtic->nums.buf;
-               rtic->nums.buf = NULL;
-               rtic->nums.buflen = rtic->nums.bufpos = 0;
-               for (n = rtic->nums.entries; n > 0; n--) {
-                       ind = _ti_decode_16(&cap);
-                       num = _ti_decode_num(&cap, rtic->rtype);
-                       if (VALID_NUMERIC(num) &&
-                           !_ti_encode_buf_id_num(&rtic->nums, ind, num,
-                           _ti_numsize(utic)))
-                               err(EXIT_FAILURE, "encode num");
-               }
-               rtic->rtype = utic->rtype;
-               free(obuf);
-       }
+       if (rtic->rtype < utic->rtype)
+               errx(EXIT_FAILURE, "merge rtype diff (%s:%d into %s:%d)",
+                   utic->name, utic->rtype, rtic->name, rtic->rtype);
 
        cap = utic->flags.buf;
        for (n = utic->flags.entries; n > 0; n--) {
@@ -318,20 +320,95 @@
        }
 }
 
+static int
+dup_tbuf(TBUF *dst, const TBUF *src)
+{
+
+       if (src->buflen == 0)
+               return 0;
+       dst->buf = malloc(src->buflen);
+       if (dst->buf == NULL)
+               return -1;
+       dst->buflen = src->buflen;
+       memcpy(dst->buf, src->buf, dst->buflen);
+       dst->bufpos = src->bufpos;
+       dst->entries = src->entries;
+       return 0;
+}
+
+static int
+promote(TIC *rtic, TIC *utic)
+{
+       TERM *nrterm = find_newest_term(rtic->name);
+       TERM *nuterm = find_newest_term(utic->name);
+       TERM *term;
+       TIC *tic;
+
+       if (nrterm == NULL || nuterm == NULL)
+               return -1;
+       if (nrterm->tic->rtype >= nuterm->tic->rtype)
+               return 0;
+
+       tic = calloc(1, sizeof(*tic));
+       if (tic == NULL)
+               return -1;
+
+       tic->name = _ti_getname(TERMINFO_RTYPE, rtic->name);
+       if (tic->name == NULL)
+               goto err;
+       if (rtic->desc != NULL) {
+               tic->desc = strdup(rtic->desc);
+               if (tic->desc == NULL)
+                       goto err;
+       }
+
+       tic->rtype = rtic->rtype;
+       if (dup_tbuf(&tic->flags, &rtic->flags) == -1)
+               goto err;
+       if (dup_tbuf(&tic->nums, &rtic->nums) == -1)
+               goto err;
+       if (dup_tbuf(&tic->strs, &rtic->strs) == -1)
+               goto err;
+       if (dup_tbuf(&tic->extras, &rtic->extras) == -1)
+               goto err;
+       if (_ti_promote(tic) == -1)
+               goto err;
+
+       term = store_term(tic->name, NULL);
+       if (term != NULL) {
+               term->tic = tic;
+               return 0;
+       }
+
+err:
+       free(tic->flags.buf);
+       free(tic->nums.buf);
+       free(tic->strs.buf);
+       free(tic->extras.buf);
+       free(tic->desc);
+       free(tic->name);
+       free(tic);
+       return -1;
+}
+
 static size_t
 merge_use(int flags)
 {
        size_t skipped, merged, memn;
        const char *cap;
+       char *name, *basename;
        uint16_t num;
        TIC *rtic, *utic;
-       TERM *term, *uterm;;
+       TERM *term, *uterm;
+       bool promoted;
 
        skipped = merged = 0;
        STAILQ_FOREACH(term, &terms, next) {
                if (term->base_term != NULL)
                        continue;
                rtic = term->tic;
+               basename = _ti_getname(TERMINFO_RTYPE_O1, rtic->name);
+               promoted = false;
                while ((cap = _ti_find_extra(rtic, &rtic->extras, "use"))
                    != NULL) {
                        if (*cap++ != 's') {
@@ -339,11 +416,19 @@
                                break;
                        }
                        cap += sizeof(uint16_t);
-                       if (strcmp(rtic->name, cap) == 0) {
+                       if (strcmp(basename, cap) == 0) {
                                dowarn("%s: uses itself", rtic->name);
                                goto remove;
                        }
-                       uterm = find_term(cap);
+                       name = _ti_getname(rtic->rtype, cap);
+                       if (name == NULL) {
+                               dowarn("%s: ???: %s", rtic->name, cap);
+                               goto remove;
+                       }
+                       uterm = find_term(name);
+                       free(name);
+                       if (uterm == NULL)
+                               uterm = find_term(cap);
                        if (uterm != NULL && uterm->base_term != NULL)
                                uterm = uterm->base_term;
                        if (uterm == NULL) {
@@ -361,7 +446,16 @@
                                skipped++;
                                break;
                        }
-                       cap = _ti_find_extra(rtic, &rtic->extras, "use");
+
+                       /* If we need to merge in a term that requires
+                        * this term to be promoted, we need to duplicate
+                        * this term, promote it and append it to our list. */
+                       if (!promoted && rtic->rtype != TERMINFO_RTYPE) {
+                               if (promote(rtic, utic) == -1)
+                                       err(EXIT_FAILURE, "promote");
+                               promoted = true;
+                       }
+
                        merge(rtic, utic, flags);
        remove:
                        /* The pointers may have changed, find the use again */
@@ -384,6 +478,7 @@
                                merged++;
                        }
                }
+               free(basename);
        }
 
        if (merged == 0 && skipped != 0)
@@ -410,7 +505,7 @@
 
        n = 0;
        for (i = 0; i < argc; i++) {
-               term = find_term(argv[i]);
+               term = find_newest_term(argv[i]);
                if (term == NULL) {
                        warnx("%s: no description for terminal", argv[i]);
                        continue;



Home | Main Index | Thread Index | Old Index