Module Name: src Committed By: roy Date: Sun Mar 29 21:54:03 UTC 2020
Modified Files: src/usr.bin/tic: tic.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.38 -r1.39 src/usr.bin/tic/tic.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/tic/tic.c diff -u src/usr.bin/tic/tic.c:1.38 src/usr.bin/tic/tic.c:1.39 --- src/usr.bin/tic/tic.c:1.38 Sat Mar 28 15:37:04 2020 +++ src/usr.bin/tic/tic.c Sun Mar 29 21:54:03 2020 @@ -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 @@ __RCSID("$NetBSD: tic.c,v 1.38 2020/03/2 #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 @@ find_term(const char *name) } 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 @@ merge(TIC *rtic, TIC *utic, int flags) 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 @@ merge(TIC *rtic, TIC *utic, int flags) } } +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 @@ merge_use(int flags) 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 @@ merge_use(int flags) 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 @@ merge_use(int flags) merged++; } } + free(basename); } if (merged == 0 && skipped != 0) @@ -410,7 +505,7 @@ print_dump(int argc, char **argv) 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;