In article <431d1631-ef82-d1ec-98ff-e39b71418...@marples.name>, Roy Marples <r...@marples.name> wrote: >On 27/03/2020 13:15, Christos Zoulas wrote: >> >> >>> On Mar 27, 2020, at 4:05 AM, Roy Marples <r...@marples.name> wrote: >>> >>> On 27/03/2020 02:06, Christos Zoulas wrote: >>>> @@ -494,6 +530,7 @@ >>>> if (tic == NULL) >>>> return NULL; >>>> + tic->rtype = _ti_find_rtype(cap); >>>> buf.buf = NULL; >>>> buf.buflen = 0; >>> >>> If I'm reading this patch correctly, it means that the old terminfo >library cannot read the records for at least screen-256color and >xterm-256color because they will be stored in version 3. >> >> Yes, and I can fix that by implementing the full proposal with just a >few more lines of code: >> 1. create a v1 entry with clamped values >> 2. create a v3 entry called <name>@v3 >> 3. always lookup for <name>@v3 first and if that fails, use <name>. >> >> I am not sure if it is worth it, as the user can always export >TERM=xterm and export TERM=screen to get a slightly less functional and >working setup. >> But if people feel otherwise, I will make my fingers even shorter and >implement it. > >I think it's worthwhile not to break people working terminals.
Ok, done. christos Index: distrib/sets/lists/base/mi =================================================================== RCS file: /cvsroot/src/distrib/sets/lists/base/mi,v retrieving revision 1.1233 diff -u -u -r1.1233 mi --- distrib/sets/lists/base/mi 22 Mar 2020 20:21:53 -0000 1.1233 +++ distrib/sets/lists/base/mi 27 Mar 2020 14:25:21 -0000 @@ -4841,7 +4841,8 @@ ./usr/share/misc/more.help base-obsolete obsolete ./usr/share/misc/nslookup.help base-obsolete obsolete ./usr/share/misc/terminfo base-terminfo-share share -./usr/share/misc/terminfo2.cdb base-terminfo-share share +./usr/share/misc/terminfo.cdb base-terminfo-share share +./usr/share/misc/terminfo2.cdb base-obsolete obsolete ./usr/share/misc/units.lib base-reference-share share ./usr/share/misc/usb_hid_usages base-reference-share share ./usr/share/misc/vgrindefs.db base-groff-share share Index: share/terminfo/Makefile =================================================================== RCS file: /cvsroot/src/share/terminfo/Makefile,v retrieving revision 1.4 diff -u -u -r1.4 Makefile --- share/terminfo/Makefile 13 Mar 2020 15:19:25 -0000 1.4 +++ share/terminfo/Makefile 27 Mar 2020 14:25:21 -0000 @@ -1,12 +1,12 @@ # $NetBSD: Makefile,v 1.4 2020/03/13 15:19:25 roy Exp $ # from: @(#)Makefile 8.1 (Berkeley) 6/8/93 -CLEANFILES= terminfo2.cdb -realall: terminfo2.cdb -FILES=terminfo2.cdb terminfo +CLEANFILES= terminfo.cdb +realall: terminfo.cdb +FILES=terminfo.cdb terminfo FILESDIR=${BINDIR}/misc -terminfo2.cdb: terminfo ${TOOL_TIC} +terminfo.cdb: terminfo ${TOOL_TIC} ${_MKTARGET_CREATE} ${TOOL_TIC} -ax -o ${.TARGET} "${.CURDIR}/terminfo" Index: usr.bin/tic/tic.c =================================================================== RCS file: /cvsroot/src/usr.bin/tic/tic.c,v retrieving revision 1.32 diff -u -u -r1.32 tic.c --- usr.bin/tic/tic.c 13 Mar 2020 15:19:25 -0000 1.32 +++ usr.bin/tic/tic.c 27 Mar 2020 14:25:21 -0000 @@ -167,6 +167,7 @@ char *p, *e, *alias; TERM *term; TIC *tic; + TBUF sbuf = *buf; if (buf->bufpos == 0) return 0; @@ -211,13 +212,17 @@ free(alias); } + if (tic->rtype == TERMINFO_RTYPE) + return process_entry(&sbuf, flags | TIC_COMPAT_V1); + return 0; } static void merge(TIC *rtic, TIC *utic, int flags) { - char *cap, flag, *code, type, *str; + char flag, type; + const char *cap, *code, *str; short ind, len; int num; size_t n; @@ -228,7 +233,7 @@ cap += sizeof(uint16_t); flag = *cap++; if (VALID_BOOLEAN(flag) && - _ti_find_cap(&rtic->flags, 'f', ind) == NULL) + _ti_find_cap(rtic, &rtic->flags, 'f', ind) == NULL) { _ti_grow_tbuf(&rtic->flags, sizeof(uint16_t) + 1); le16enc(rtic->flags.buf + rtic->flags.bufpos, ind); @@ -242,17 +247,15 @@ for (n = utic->nums.entries; n > 0; n--) { ind = le16dec(cap); cap += sizeof(uint16_t); - num = le32dec(cap); - cap += sizeof(uint32_t); + num = _ti_decode_num(utic->rtype, &cap); if (VALID_NUMERIC(num) && - _ti_find_cap(&rtic->nums, 'n', ind) == NULL) + _ti_find_cap(rtic, &rtic->nums, 'n', ind) == NULL) { grow_tbuf(&rtic->nums, sizeof(uint16_t) + - sizeof(uint32_t)); + _ti_numsize(rtic)); le16enc(rtic->nums.buf + rtic->nums.bufpos, ind); rtic->nums.bufpos += sizeof(uint16_t); - le32enc(rtic->nums.buf + rtic->nums.bufpos, num); - rtic->nums.bufpos += sizeof(uint32_t); + _ti_encode_num(rtic, &rtic->nums, num); rtic->nums.entries++; } } @@ -264,7 +267,7 @@ len = le16dec(cap); cap += sizeof(uint16_t); if (len > 0 && - _ti_find_cap(&rtic->strs, 's', ind) == NULL) + _ti_find_cap(rtic, &rtic->strs, 's', ind) == NULL) { grow_tbuf(&rtic->strs, (sizeof(uint16_t) * 2) + len); le16enc(rtic->strs.buf + rtic->strs.bufpos, ind); @@ -295,8 +298,7 @@ continue; break; case 'n': - num = le32dec(cap); - cap += sizeof(uint32_t); + num = _ti_decode_num(utic->rtype, &cap); if (!VALID_NUMERIC(num)) continue; break; @@ -328,7 +330,8 @@ if (term->base_term != NULL) continue; rtic = term->tic; - while ((cap = _ti_find_extra(&rtic->extras, "use")) != NULL) { + while ((cap = _ti_find_extra(rtic, &rtic->extras, "use")) + != NULL) { if (*cap++ != 's') { dowarn("%s: use is not string", rtic->name); break; @@ -351,15 +354,16 @@ dowarn("%s: uses itself", rtic->name); goto remove; } - if (_ti_find_extra(&utic->extras, "use") != NULL) { + if (_ti_find_extra(utic, &utic->extras, "use") + != NULL) { skipped++; break; } - cap = _ti_find_extra(&rtic->extras, "use"); + cap = _ti_find_extra(rtic, &rtic->extras, "use"); merge(rtic, utic, flags); remove: /* The pointers may have changed, find the use again */ - cap = _ti_find_extra(&rtic->extras, "use"); + cap = _ti_find_extra(rtic, &rtic->extras, "use"); if (cap == NULL) dowarn("%s: use no longer exists - impossible", rtic->name); Index: lib/libterminfo/compile.c =================================================================== RCS file: /cvsroot/src/lib/libterminfo/compile.c,v retrieving revision 1.14 diff -u -u -r1.14 compile.c --- lib/libterminfo/compile.c 13 Mar 2020 15:19:25 -0000 1.14 +++ lib/libterminfo/compile.c 27 Mar 2020 14:25:21 -0000 @@ -87,7 +87,7 @@ } char * -_ti_find_cap(TBUF *tbuf, char type, short ind) +_ti_find_cap(TIC *tic, TBUF *tbuf, char type, short ind) { size_t n; uint16_t num; @@ -106,7 +106,7 @@ cap++; break; case 'n': - cap += sizeof(uint32_t); + cap += _ti_numsize(tic); break; case 's': num = le16dec(cap); @@ -121,7 +121,7 @@ } char * -_ti_find_extra(TBUF *tbuf, const char *code) +_ti_find_extra(TIC *tic, TBUF *tbuf, const char *code) { size_t n; uint16_t num; @@ -142,7 +142,7 @@ cap++; break; case 'n': - cap += sizeof(uint32_t); + cap += _ti_numsize(tic); break; case 's': num = le16dec(cap); @@ -156,16 +156,58 @@ return NULL; } +void +_ti_encode_num(TIC *tic, TBUF *rbuf, int num) +{ + if (_ti_numsize(tic) == sizeof(uint16_t)) { + if (num > SHRT_MAX) + num = SHRT_MAX; + le16enc(rbuf->buf + rbuf->bufpos, (uint16_t)num); + } else { + le32enc(rbuf->buf + rbuf->bufpos, (uint32_t)num); + } + rbuf->bufpos += _ti_numsize(tic); +} + +int +_ti_decode_num(int rtype, const char **cap) +{ + int rv; + + if (rtype == TERMINFO_RTYPE_O1) { + rv = (int)le16dec(*cap); + *cap += sizeof(uint16_t); + } else { + rv = (int)le32dec(*cap); + *cap += sizeof(uint32_t); + } + return rv; +} + +char * +_ti_getname(int rtype, const char *orig) +{ + char *name; + + if (rtype == TERMINFO_RTYPE) { + if (asprintf(&name, "%s@v3", orig) < 0) + name = NULL; + } else { + name = strdup(orig); + } + return name; +} + size_t -_ti_store_extra(TIC *tic, int wrn, char *id, char type, char flag, int num, - char *str, size_t strl, int flags) +_ti_store_extra(TIC *tic, int wrn, const char *id, char type, char flag, + int num, const char *str, size_t strl, int flags) { size_t l; _DIAGASSERT(tic != NULL); if (strcmp(id, "use") != 0) { - if (_ti_find_extra(&tic->extras, id) != NULL) + if (_ti_find_extra(tic, &tic->extras, id) != NULL) return 0; if (!(flags & TIC_EXTRA)) { if (wrn != 0) @@ -182,7 +224,7 @@ } if (!_ti_grow_tbuf(&tic->extras, - l + strl + sizeof(uint16_t) + sizeof(uint32_t) + 1)) + l + strl + sizeof(uint16_t) + _ti_numsize(tic) + 1)) return 0; le16enc(tic->extras.buf + tic->extras.bufpos, (uint16_t)l); tic->extras.bufpos += sizeof(uint16_t); @@ -194,8 +236,7 @@ tic->extras.buf[tic->extras.bufpos++] = flag; break; case 'n': - le32enc(tic->extras.buf + tic->extras.bufpos, (uint32_t)num); - tic->extras.bufpos += sizeof(uint32_t); + _ti_encode_num(tic, &tic->extras, num); break; case 's': le16enc(tic->extras.buf + tic->extras.bufpos, (uint16_t)strl); @@ -239,7 +280,7 @@ return -1; cap = *buf; - *cap++ = TERMINFO_RTYPE; /* Record type 3 */ + *cap++ = tic->rtype; le16enc(cap, (uint16_t)len); cap += sizeof(uint16_t); memcpy(cap, tic->name, len); @@ -451,6 +492,17 @@ return token; } +static int +_ti_find_rtype(const char *cap) +{ + for (const char *ptr = cap; (ptr = strchr(ptr, '#')) != NULL;) { + if (strtol(++ptr, NULL, 0) > SHRT_MAX) { + return TERMINFO_RTYPE; + } + } + return TERMINFO_RTYPE_O1; +} + TIC * _ti_compile(char *cap, int flags) { @@ -467,7 +519,7 @@ name = _ti_get_token(&cap, ','); if (name == NULL) { - dowarn(flags, "no seperator found: %s", cap); + dowarn(flags, "no separator found: %s", cap); return NULL; } desc = strrchr(name, '|'); @@ -494,14 +546,16 @@ if (tic == NULL) return NULL; + tic->rtype = (flags & TIC_COMPAT_V1) ? TERMINFO_RTYPE_O1 : + _ti_find_rtype(cap); buf.buf = NULL; buf.buflen = 0; - tic->name = strdup(name); + tic->name = _ti_getname(tic->rtype, name); if (tic->name == NULL) goto error; if (alias != NULL && flags & TIC_ALIAS) { - tic->alias = strdup(alias); + tic->alias = _ti_getname(tic->rtype, alias); if (tic->alias == NULL) goto error; } @@ -533,7 +587,7 @@ /* Don't use the string if we already have it */ ind = (short)_ti_strindex(token); if (ind != -1 && - _ti_find_cap(&tic->strs, 's', ind) != NULL) + _ti_find_cap(tic, &tic->strs, 's', ind) != NULL) continue; /* Encode the string to our scratch buffer */ @@ -579,7 +633,7 @@ /* Don't use the number if we already have it */ ind = (short)_ti_numindex(token); if (ind != -1 && - _ti_find_cap(&tic->nums, 'n', ind) != NULL) + _ti_find_cap(tic, &tic->nums, 'n', ind) != NULL) continue; cnum = strtol(p, &e, 0); @@ -600,14 +654,12 @@ num, NULL, 0, flags); else { if (_ti_grow_tbuf(&tic->nums, - sizeof(uint16_t) + sizeof(uint32_t))==NULL) + sizeof(uint16_t) + _ti_numsize(tic))==NULL) goto error; le16enc(tic->nums.buf + tic->nums.bufpos, (uint16_t)ind); tic->nums.bufpos += sizeof(uint16_t); - le32enc(tic->nums.buf + tic->nums.bufpos, - (uint32_t)num); - tic->nums.bufpos += sizeof(uint32_t); + _ti_encode_num(tic, &tic->nums, num); tic->nums.entries++; } continue; @@ -622,21 +674,22 @@ ind = (short)_ti_flagindex(token); if (ind == -1 && flag == CANCELLED_BOOLEAN) { if ((ind = (short)_ti_numindex(token)) != -1) { - if (_ti_find_cap(&tic->nums, 'n', ind) != NULL) + if (_ti_find_cap(tic, &tic->nums, 'n', ind) + != NULL) continue; - if (_ti_grow_tbuf(&tic->nums, - sizeof(uint16_t) * 2) == NULL) + if (_ti_grow_tbuf(&tic->nums, sizeof(uint16_t) + + _ti_numsize(tic)) == NULL) goto error; le16enc(tic->nums.buf + tic->nums.bufpos, (uint16_t)ind); tic->nums.bufpos += sizeof(uint16_t); - le32enc(tic->nums.buf + tic->nums.bufpos, - (uint32_t)CANCELLED_NUMERIC); - tic->nums.bufpos += sizeof(uint32_t); + _ti_encode_num(tic, &tic->nums, + CANCELLED_NUMERIC); tic->nums.entries++; continue; } else if ((ind = (short)_ti_strindex(token)) != -1) { - if (_ti_find_cap(&tic->strs, 's', ind) != NULL) + if (_ti_find_cap(tic, &tic->strs, 's', ind) + != NULL) continue; if (_ti_grow_tbuf(&tic->strs, (sizeof(uint16_t) * 2) + 1) == NULL) @@ -652,7 +705,7 @@ if (ind == -1) _ti_store_extra(tic, 1, token, 'f', flag, 0, NULL, 0, flags); - else if (_ti_find_cap(&tic->flags, 'f', ind) == NULL) { + else if (_ti_find_cap(tic, &tic->flags, 'f', ind) == NULL) { if (_ti_grow_tbuf(&tic->flags, sizeof(uint16_t) + 1) == NULL) goto error; Index: lib/libterminfo/term.c =================================================================== RCS file: /cvsroot/src/lib/libterminfo/term.c,v retrieving revision 1.30 diff -u -u -r1.30 term.c --- lib/libterminfo/term.c 13 Mar 2020 15:19:25 -0000 1.30 +++ lib/libterminfo/term.c 27 Mar 2020 14:25:21 -0000 @@ -48,7 +48,7 @@ * Although we can read v1 structure (which includes v2 alias records) * we really want a v3 structure to get numerics of type int rather than short. */ -#define _PATH_TERMINFO "/usr/share/misc/terminfo2:/usr/share/misc/terminfo" +#define _PATH_TERMINFO "/usr/share/misc/terminfo" static char __ti_database[PATH_MAX]; const char *_ti_database; @@ -150,13 +150,7 @@ for (; num != 0; num--) { ind = le16dec(cap); cap += sizeof(uint16_t); - if (rtype == TERMINFO_RTYPE_O1) { - term->nums[ind] = (int)le16dec(cap); - cap += sizeof(uint16_t); - } else { - term->nums[ind] = (int)le32dec(cap); - cap += sizeof(uint32_t); - } + term->nums[ind] = _ti_decode_num(rtype, &cap); if (flags == 0 && !VALID_NUMERIC(term->nums[ind])) term->nums[ind] = ABSENT_NUMERIC; } @@ -213,13 +207,7 @@ break; case 'n': ud->flag = ABSENT_BOOLEAN; - if (rtype == TERMINFO_RTYPE_O1) { - ud->num = (int)le16dec(cap); - cap += sizeof(uint16_t); - } else { - ud->num = (int)le32dec(cap); - cap += sizeof(uint32_t); - } + ud->num = _ti_decode_num(rtype, &cap); if (flags == 0 && !VALID_NUMERIC(ud->num)) ud->num = ABSENT_NUMERIC; @@ -323,7 +311,7 @@ goto out; /* If the entry is an alias, load the indexed terminfo description. */ - if (data8[0] == 2) { + if (data8[0] == TERMINFO_ALIAS) { if (cdbr_get(db, le32dec(data8 + 1), &data, &len)) goto out; data8 = data; @@ -453,6 +441,15 @@ int r; size_t i; const struct compiled_term *t; + char *namev3; + + namev3 = _ti_getname(TERMINFO_RTYPE, name); + if (namev3 != NULL) { + r = _ti_findterm(term, namev3, flags); + free(namev3); + if (r == 1) + return r; + } r = _ti_findterm(term, name, flags); if (r == 1) Index: lib/libterminfo/term_private.h =================================================================== RCS file: /cvsroot/src/lib/libterminfo/term_private.h,v retrieving revision 1.12 diff -u -u -r1.12 term_private.h --- lib/libterminfo/term_private.h 13 Mar 2020 15:19:25 -0000 1.12 +++ lib/libterminfo/term_private.h 27 Mar 2020 14:25:21 -0000 @@ -140,6 +140,7 @@ #define TIC_ALIAS (1 << 2) #define TIC_COMMENT (1 << 3) #define TIC_EXTRA (1 << 4) +#define TIC_COMPAT_V1 (1 << 5) #define UINT16_T_MAX 0xffff @@ -154,18 +155,25 @@ char *name; char *alias; char *desc; + int rtype; TBUF flags; TBUF nums; TBUF strs; TBUF extras; } TIC; +#define _ti_numsize(tic) \ + ((tic)->rtype == TERMINFO_RTYPE_O1 ? sizeof(uint16_t) : sizeof(uint32_t)) + char *_ti_grow_tbuf(TBUF *, size_t); char *_ti_get_token(char **, char); -char *_ti_find_cap(TBUF *, char, short); -char *_ti_find_extra(TBUF *, const char *); -size_t _ti_store_extra(TIC *, int, char *, char, char, int, - char *, size_t, int); +char *_ti_find_cap(TIC *, TBUF *, char, short); +char *_ti_find_extra(TIC *, TBUF *, const char *); +char *_ti_getname(int, const char *); +size_t _ti_store_extra(TIC *, int, const char *, char, char, int, + const char *, size_t, int); +void _ti_encode_num(TIC *, TBUF *, int ); +int _ti_decode_num(int, const char **); TIC *_ti_compile(char *, int); ssize_t _ti_flatten(uint8_t **, const TIC *); void _ti_freetic(TIC *); Index: lib/libterminfo/tparm.c =================================================================== RCS file: /cvsroot/src/lib/libterminfo/tparm.c,v retrieving revision 1.17 diff -u -u -r1.17 tparm.c --- lib/libterminfo/tparm.c 4 May 2017 09:42:23 -0000 1.17 +++ lib/libterminfo/tparm.c 27 Mar 2020 14:25:21 -0000 @@ -265,7 +265,8 @@ /* Handle formatting. */ fp = fmt; *fp++ = '%'; - done = dot = minus = width = precision = 0; + done = dot = minus = 0; + width = precision = 0; val = 0; while (done == 0 && (size_t)(fp - fmt) < sizeof(fmt)) { switch (c) {