diff options
Diffstat (limited to 'progs/infocmp.c')
-rw-r--r-- | progs/infocmp.c | 163 |
1 files changed, 101 insertions, 62 deletions
diff --git a/progs/infocmp.c b/progs/infocmp.c index dbdbdc2dfe35..7932203ac2b1 100644 --- a/progs/infocmp.c +++ b/progs/infocmp.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2020 Thomas E. Dickey * + * Copyright 2020-2022,2023 Thomas E. Dickey * * Copyright 1998-2016,2017 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * @@ -43,7 +43,7 @@ #include <dump_entry.h> -MODULE_ID("$Id: infocmp.c,v 1.145 2020/07/07 20:28:47 tom Exp $") +MODULE_ID("$Id: infocmp.c,v 1.163 2023/12/16 17:27:47 tom Exp $") #define MAX_STRING 1024 /* maximum formatted string */ @@ -94,7 +94,7 @@ typedef struct { static ENTERED *entered; #undef ExitProgram -static void ExitProgram(int code) GCC_NORETURN; +static GCC_NORETURN void ExitProgram(int code); /* prototype is to get gcc to accept the noreturn attribute */ static void ExitProgram(int code) @@ -124,17 +124,19 @@ failed(const char *s) ExitProgram(EXIT_FAILURE); } -static char * -canonical_name(char *ptr, char *buf) +static void +canonical_name(char *source, char *target) /* extract the terminal type's primary name */ { - char *bp; - - _nc_STRCPY(buf, ptr, NAMESIZE); - if ((bp = strchr(buf, '|')) != 0) - *bp = '\0'; + int limit = NAMESIZE; - return (buf); + while (--limit > 0) { + char ch = *source++; + if (ch == '|') + break; + *target++ = ch; + } + *target = '\0'; } static bool @@ -156,7 +158,7 @@ no_numeric(int value) } static bool -no_string(char *value) +no_string(const char *const value) { bool result = (value == ABSENT_STRING); if (!strcmp(s_absent, s_cancel)) @@ -185,10 +187,21 @@ capcmp(PredIdx idx, const char *s, const char *t) return (_nc_capcmp(s, t)); } +/* + * Predicate function to use for "use=" decompilation. + * + * Return value is used in fmt_entry: + * FAIL show nothing for this capability. + * FALSE show cancel for booleans (a compromise) + * TRUE show capability + * + * The only difference between FALSE/TRUE returns is in the treatment of + * booleans. + */ static int use_predicate(unsigned type, PredIdx idx) -/* predicate function to use for use decompilation */ { + int result = FAIL; ENTRY *ep; switch (type) { @@ -207,16 +220,18 @@ use_predicate(unsigned type, PredIdx idx) * unlike numbers and strings, whose cancelled/absent state is * recorded in the terminfo database. */ - for (ep = &entries[1]; ep < entries + termcount; ep++) - if (ep->tterm.Booleans[idx] == TRUE) { - is_set = entries[0].tterm.Booleans[idx]; - break; + if (idx < NUM_BOOLEANS(&(entries[0].tterm))) { + for (ep = &entries[1]; ep < entries + termcount; ep++) { + if (idx < NUM_BOOLEANS(&(ep->tterm)) + && (is_set = ep->tterm.Booleans[idx])) { + break; + } } - if (is_set != entries[0].tterm.Booleans[idx]) - return (!is_set); - else - return (FAIL); + if (is_set != entries[0].tterm.Booleans[idx]) + result = (!is_set); + } } + break; case NUMBER: { @@ -227,45 +242,56 @@ use_predicate(unsigned type, PredIdx idx) * capability gets the first non-default value found * in the sequence of use entries'. */ - for (ep = &entries[1]; ep < entries + termcount; ep++) - if (VALID_NUMERIC(ep->tterm.Numbers[idx])) { - value = ep->tterm.Numbers[idx]; - break; - } + if (idx < NUM_NUMBERS(&(entries[0].tterm))) { + for (ep = &entries[1]; ep < entries + termcount; ep++) + if (idx < NUM_NUMBERS(&(ep->tterm)) + && VALID_NUMERIC(ep->tterm.Numbers[idx])) { + value = ep->tterm.Numbers[idx]; + break; + } - if (value != entries[0].tterm.Numbers[idx]) - return (value != ABSENT_NUMERIC); - else - return (FAIL); + if (value != entries[0].tterm.Numbers[idx]) + result = (value != ABSENT_NUMERIC); + } } + break; case STRING: { - char *termstr, *usestr = ABSENT_STRING; - - termstr = entries[0].tterm.Strings[idx]; + char *termstr = entries[0].tterm.Strings[idx]; + char *usestr = ABSENT_STRING; /* * We take the semantics of multiple uses to be 'each * capability gets the first non-default value found * in the sequence of use entries'. */ - for (ep = &entries[1]; ep < entries + termcount; ep++) - if (ep->tterm.Strings[idx]) { - usestr = ep->tterm.Strings[idx]; - break; - } + if (idx < NUM_STRINGS(&(entries[0].tterm))) { + for (ep = &entries[1]; ep < entries + termcount; ep++) + if (idx < NUM_STRINGS(&(ep->tterm)) + && ep->tterm.Strings[idx]) { + usestr = ep->tterm.Strings[idx]; + break; + } - if (usestr == ABSENT_STRING && termstr == ABSENT_STRING) - return (FAIL); - else if (!usestr || !termstr || capcmp(idx, usestr, termstr)) - return (TRUE); - else - return (FAIL); + if (usestr == CANCELLED_STRING && termstr == ABSENT_STRING) + result = (FAIL); + else if (usestr == CANCELLED_STRING && termstr == CANCELLED_STRING) + result = (TRUE); + else if (usestr == ABSENT_STRING && termstr == ABSENT_STRING) + result = (FAIL); + else if (!usestr || !termstr || capcmp(idx, usestr, termstr)) + result = (TRUE); + } } + break; + + default: + result = FALSE; + break; } - return (FALSE); /* pacify compiler */ + return (result); } static bool @@ -322,16 +348,17 @@ static void print_uses(ENTRY * ep, FILE *fp) /* print an entry's use references */ { - unsigned i; - - if (!ep->nuses) + if (!ep->nuses) { fputs("NULL", fp); - else + } else { + unsigned i; + for (i = 0; i < ep->nuses; i++) { fputs(ep->uses[i].name, fp); if (i < ep->nuses - 1) fputs(" ", fp); } + } } static const char * @@ -418,7 +445,7 @@ show_comparing(char **names) /* * ncurses stores two types of non-standard capabilities: - * a) capabilities listed past the "STOP-HERE" comment in the Caps file. + * a) capabilities listed past the "STOP-HERE" comment in the Caps file. * These are used in the terminfo source file to provide data for termcaps, * e.g., when there is no equivalent capability in terminfo, as well as for * widely-used non-standard capabilities. @@ -835,6 +862,8 @@ analyze_string(const char *name, const char *cap, TERMTYPE2 *tp) char *cp = tp->Strings[i]; /* don't use function-key capabilities */ + if (strnames[i] == NULL) + continue; if (strnames[i][0] == 'k' && strnames[i][1] == 'f') continue; @@ -900,7 +929,6 @@ analyze_string(const char *name, const char *cap, TERMTYPE2 *tp) sizeof(buf2)); _nc_STRNCPY(buf3, sp + csi, len); buf3[len] = '\0'; - len += (size_t) csi + 1; expansion = lookup_params(std_modes, buf2, buf3); } @@ -921,7 +949,6 @@ analyze_string(const char *name, const char *cap, TERMTYPE2 *tp) sizeof(buf2)); _nc_STRNCPY(buf3, sp + csi + 1, len); buf3[len] = '\0'; - len += (size_t) csi + 2; expansion = lookup_params(private_modes, buf2, buf3); } @@ -1129,8 +1156,8 @@ file_comparison(int argc, char *argv[]) if (entryeq(&qp->tterm, &rp->tterm) && useeq(qp, rp)) { char name1[NAMESIZE], name2[NAMESIZE]; - (void) canonical_name(qp->tterm.term_names, name1); - (void) canonical_name(rp->tterm.term_names, name2); + canonical_name(qp->tterm.term_names, name1); + canonical_name(rp->tterm.term_names, name2); (void) printf("%s = %s\n", name1, name2); } @@ -1158,8 +1185,8 @@ file_comparison(int argc, char *argv[]) entries[0] = *qp; entries[1] = *rp; - (void) canonical_name(qp->tterm.term_names, name1); - (void) canonical_name(rp->tterm.term_names, name2); + canonical_name(qp->tterm.term_names, name1); + canonical_name(rp->tterm.term_names, name2); switch (compare) { case C_DIFFERENCE: @@ -1305,9 +1332,9 @@ dump_initializers(TERMTYPE2 *term) name_initializer("alias"), entries->tterm.term_names); for_each_string(n, term) { - char buf[MAX_STRING], *sp, *tp; - if (VALID_STRING(term->Strings[n])) { + char buf[MAX_STRING], *sp, *tp; + tp = buf; #define TP_LIMIT ((MAX_STRING - 5) - (size_t)(tp - buf)) *tp++ = '"'; @@ -1510,6 +1537,8 @@ show_databases(void) #if NO_LEAKS #define MAIN_LEAKS() \ + _nc_free_termtype2(&entries[0].tterm); \ + _nc_free_termtype2(&entries[1].tterm); \ free(myargv); \ free(tfile); \ free(tname) @@ -1529,7 +1558,7 @@ main(int argc, char *argv[]) char **myargv; char *firstdir, *restdir; - int c, i, len; + int c; bool formatted = FALSE; bool filecompare = FALSE; int initdump = 0; @@ -1720,7 +1749,7 @@ main(int argc, char *argv[]) case 'v': itrace = (unsigned) optarg_to_number(); - set_trace_level(itrace); + use_verbosity(itrace); break; case 'W': @@ -1853,8 +1882,16 @@ main(int argc, char *argv[]) } #if NCURSES_XNAMES - if (termcount > 1) - _nc_align_termtype(&entries[0].tterm, &entries[1].tterm); + if (termcount > 1) { + /* + * User-defined capabilities in different terminal descriptions + * may have the same name/type but different indices. Line up + * the names to use comparable indices. We may have more than two + * entries to compare when processing the "-u" option. + */ + for (c = 1; c < termcount; ++c) + _nc_align_termtype(&entries[c].tterm, &entries[0].tterm); + } #endif /* dump as C initializer for the terminal type */ @@ -1881,6 +1918,8 @@ main(int argc, char *argv[]) analyze_string("rmkx", keypad_local, &entries[0].tterm); #undef CUR } else { + int i; + int len; /* * Here's where the real work gets done |