X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=progs%2Ftic.c;h=e559d1b35c283d61c3b6c0010764b4b13caf987a;hp=1175d9a479a921aa4376a0fd775ad36a1880504d;hb=f06e14af5e11df95d6542964bf1b349d2843bb11;hpb=21c8ffa0edf2e389f3f674f0c08009002c6f357d diff --git a/progs/tic.c b/progs/tic.c index 1175d9a4..e559d1b3 100644 --- a/progs/tic.c +++ b/progs/tic.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2014,2015 Free Software Foundation, Inc. * + * Copyright (c) 1998-2015,2016 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -48,7 +48,7 @@ #include #include -MODULE_ID("$Id: tic.c,v 1.213 2015/08/22 23:49:57 tom Exp $") +MODULE_ID("$Id: tic.c,v 1.224 2016/10/01 12:46:54 tom Exp $") #define STDIN_NAME "" @@ -159,6 +159,8 @@ usage(void) DATA(" -L translate entries to full terminfo source form") DATA(" -N disable smart defaults for source translation") DATA(" -o set output directory for compiled entry writes") + DATA(" -Q[n] dump compiled description") + DATA(" -q brief listing, removes headers") DATA(" -R restrict translation to given terminfo/termcap version") DATA(" -r force resolution of all use entries in source translation") DATA(" -s print summary statistics") @@ -168,6 +170,7 @@ usage(void) #endif DATA(" -U suppress post-processing of entries") DATA(" -V print version") + DATA(" -W wrap long strings according to -w[n] option") DATA(" -v[n] set verbosity level") DATA(" -w[n] set format width for translation output") #if NCURSES_XNAMES @@ -660,6 +663,12 @@ show_databases(const char *outdir) } } +static void +add_digit(int *target, int source) +{ + *target = (*target * 10) + (source - '0'); +} + #define VtoTrace(opt) (unsigned) ((opt > 0) ? opt : (opt == 0)) int @@ -690,6 +699,9 @@ main(int argc, char *argv[]) char *outdir = (char *) NULL; bool check_only = FALSE; bool suppress_untranslatable = FALSE; + int quickdump = 0; + bool quiet = FALSE; + bool wrap_strings = FALSE; log_fp = stderr; @@ -715,14 +727,17 @@ main(int argc, char *argv[]) * be optional. */ while ((this_opt = getopt(argc, argv, - "0123456789CDIKLNR:TUVace:fGgo:rstvwx")) != -1) { + "0123456789CDIKLNQR:TUVWace:fGgo:qrstvwx")) != -1) { if (isdigit(this_opt)) { switch (last_opt) { + case 'Q': + add_digit(&quickdump, this_opt); + break; case 'v': - v_opt = (v_opt * 10) + (this_opt - '0'); + add_digit(&v_opt, this_opt); break; case 'w': - width = (width * 10) + (this_opt - '0'); + add_digit(&width, this_opt); break; default: switch (this_opt) { @@ -773,6 +788,9 @@ main(int argc, char *argv[]) smart_defaults = FALSE; literal = TRUE; break; + case 'Q': + quickdump = 0; + break; case 'R': tversion = optarg; break; @@ -785,6 +803,9 @@ main(int argc, char *argv[]) case 'V': puts(curses_version()); ExitProgram(EXIT_SUCCESS); + case 'W': + wrap_strings = TRUE; + break; case 'c': check_only = TRUE; break; @@ -803,6 +824,9 @@ main(int argc, char *argv[]) case 'o': outdir = optarg; break; + case 'q': + quiet = TRUE; + break; case 'r': forceresolve = TRUE; break; @@ -910,15 +934,18 @@ main(int argc, char *argv[]) if (infodump || check_only) { dump_init(tversion, - smart_defaults - ? outform - : F_LITERAL, - sortmode, width, height, debug_level, formatted || - check_only, check_only); + (smart_defaults + ? outform + : F_LITERAL), + sortmode, + wrap_strings, width, height, + debug_level, formatted || check_only, check_only, quickdump); } else if (capdump) { dump_init(tversion, outform, - sortmode, width, height, debug_level, FALSE, FALSE); + sortmode, + wrap_strings, width, height, + debug_level, FALSE, FALSE, FALSE); } /* parse entries out of the source file */ @@ -989,12 +1016,14 @@ main(int argc, char *argv[]) /* this is in case infotocap() generates warnings */ _nc_set_type(_nc_first_name(qp->tterm.term_names)); - (void) fseek(tmp_fp, qp->cstart, SEEK_SET); - while (j-- > 0) { - if (infodump) - (void) putchar(fgetc(tmp_fp)); - else - put_translate(fgetc(tmp_fp)); + if (!quiet) { + (void) fseek(tmp_fp, qp->cstart, SEEK_SET); + while (j-- > 0) { + if (infodump) + (void) putchar(fgetc(tmp_fp)); + else + put_translate(fgetc(tmp_fp)); + } } repair_acsc(&qp->tterm); @@ -1007,7 +1036,7 @@ main(int argc, char *argv[]) printf("# length=%d\n", len); } } - if (!namelst && _nc_tail) { + if (!namelst && _nc_tail && !quiet) { int c, oldc = '\0'; bool in_comment = FALSE; bool trailing_comment = FALSE; @@ -1755,7 +1784,9 @@ check_1_infotocap(const char *name, NCURSES_CONST char *value, int count) *next++ = '\0'; for (k = 1; k <= NUM_PARM; k++) { numbers[k] = count; - sprintf(next, "XYZ%d", count); + _nc_SPRINTF(next, + _nc_SLIMIT(sizeof(blob) - (next - blob)) + "XYZ%d", count); strings[k] = next; next += strlen(next) + 1; } @@ -2007,6 +2038,23 @@ ignore_delays(char *s) return s; } +#define DATA(name) { #name } +static const char sgr_names[][11] = +{ + DATA(none), + DATA(standout), + DATA(underline), + DATA(reverse), + DATA(blink), + DATA(dim), + DATA(bold), + DATA(invis), + DATA(protect), + DATA(altcharset), + "" +}; +#undef DATA + /* * An sgr string may contain several settings other than the one we're * interested in, essentially sgr0 + rmacs + whatever. As long as the @@ -2016,21 +2064,6 @@ ignore_delays(char *s) static bool similar_sgr(int num, char *a, char *b) { -#define DATA(name) { #name } - static const char names[][11] = - { - DATA(none), - DATA(standout), - DATA(underline), - DATA(reverse), - DATA(blink), - DATA(dim), - DATA(bold), - DATA(invis), - DATA(protect), - DATA(altcharset), - }; -#undef DATA char *base_a = a; char *base_b = b; int delaying = 0; @@ -2038,12 +2071,14 @@ similar_sgr(int num, char *a, char *b) while (*b != 0) { while (*a != *b) { if (*a == 0) { - if (b[0] == '$' - && b[1] == '<') { + if (num < 0) { + ; + } else if (b[0] == '$' + && b[1] == '<') { _nc_warning("Did not find delay %s", _nc_visbuf(b)); } else { _nc_warning("checking sgr(%s) %s\n\tcompare to %s\n\tunmatched %s", - names[num], _nc_visbuf2(1, base_a), + sgr_names[num], _nc_visbuf2(1, base_a), _nc_visbuf2(2, base_b), _nc_visbuf2(3, b)); } @@ -2243,6 +2278,102 @@ check_conflict(TERMTYPE *tp) } } +/* + * Exiting a video mode should not duplicate sgr0 + */ +static void +check_exit_attribute(const char *name, char *test, char *trimmed, char *untrimmed) +{ + if (VALID_STRING(test) && (trimmed != 0)) { + if (similar_sgr(-1, trimmed, test) || + similar_sgr(-1, untrimmed, test)) { + _nc_warning("%s matches exit_attribute_mode", name); + } + } +} + +/* + * Returns true if the string looks like a standard SGR string. + */ +static bool +is_sgr_string(char *value) +{ + bool result = FALSE; + + if (VALID_STRING(value)) { + if (value[0] == '\033' && value[1] == '[') { + result = TRUE; + value += 2; + } else if (UChar(value[0]) == 0x9a) { + result = TRUE; + value += 1; + } + if (result) { + int ch; + while ((ch = UChar(*value++)) != '\0') { + if (isdigit(ch) || ch == ';') { + ; + } else if (ch == 'm' && *value == '\0') { + ; + } else { + result = FALSE; + break; + } + } + } + } + return result; +} + +/* + * Check if the given capability contains a given SGR attribute. + */ +static void +check_sgr_param(TERMTYPE *tp, int code, const char *name, char *value) +{ + if (VALID_STRING(value)) { + int ncv = ((code != 0) ? (1 << (code - 1)) : 0); + char *test = tgoto(value, 0, 0); + if (is_sgr_string(test)) { + int param = 0; + int count = 0; + int skips = 0; + int color = (value == set_a_foreground || + value == set_a_background || + value == set_foreground || + value == set_background); + while (*test != 0) { + if (isdigit(UChar(*test))) { + param = 10 * param + (*test - '0'); + ++count; + } else { + if (count) { + /* + * Avoid unnecessary warning for xterm 256color codes. + */ + if (color && (param == 38 || param == 48)) + skips = 3; + if ((skips-- <= 0) && (param == code)) + break; + } + count = 0; + param = 0; + } + ++test; + } + if (count != 0 && param == code) { + if (code == 0 || + no_color_video < 0 || + !(no_color_video & ncv)) { + _nc_warning("\"%s\" SGR-attribute used in %s", + sgr_names[code], + name); + } + } + } + } +} + /* other sanity-checks (things that we don't want in the normal * logic that reads a terminfo entry) */ @@ -2325,7 +2456,7 @@ check_termtype(TERMTYPE *tp, bool literal) if (_nc_syntax == SYN_TERMINFO) _nc_warning("missing sgr string"); } - +#define CHECK_SGR0(name) check_exit_attribute(#name, name, check_sgr0, exit_attribute_mode) if (PRESENT(exit_attribute_mode)) { char *check_sgr0 = _nc_trim_sgr0(tp); @@ -2344,10 +2475,20 @@ check_termtype(TERMTYPE *tp, bool literal) _nc_visbuf(exit_attribute_mode))); } } + CHECK_SGR0(exit_italics_mode); + CHECK_SGR0(exit_standout_mode); + CHECK_SGR0(exit_underline_mode); if (check_sgr0 != exit_attribute_mode) { free(check_sgr0); } } +#define CHECK_SGR_PARAM(code, name) check_sgr_param(tp, (int)code, #name, name) + for (j = 0; *sgr_names[j] != '\0'; ++j) { + CHECK_SGR_PARAM(j, set_a_foreground); + CHECK_SGR_PARAM(j, set_a_background); + CHECK_SGR_PARAM(j, set_foreground); + CHECK_SGR_PARAM(j, set_background); + } #ifdef TRACE show_where(2); if (!auto_right_margin) {