X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=progs%2Ftic.c;h=134788994159e79bc62279d896ed6774e23ce4b0;hp=10cc4d2d606362fb6bb3b7f6e797fd032f763402;hb=89ca7974b018d46049b6eaf1b7f17784e3a001d1;hpb=955553313af0a9fa960ec0faba552c0bae4ca65e diff --git a/progs/tic.c b/progs/tic.c index 10cc4d2d..13478899 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.211 2015/07/04 21:12:41 tom Exp $") +MODULE_ID("$Id: tic.c,v 1.221 2016/01/02 20:04:37 tom Exp $") #define STDIN_NAME "" @@ -142,6 +142,7 @@ usage(void) static const char options_string[] = { DATA("Options:") + DATA(" -0 format translation output all capabilities on one line") DATA(" -1 format translation output one capability per line") #if NCURSES_XNAMES DATA(" -a retain commented-out capabilities (sets -x also)") @@ -158,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") @@ -659,6 +662,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 @@ -689,6 +698,8 @@ main(int argc, char *argv[]) char *outdir = (char *) NULL; bool check_only = FALSE; bool suppress_untranslatable = FALSE; + int quickdump = 0; + bool quiet = FALSE; log_fp = stderr; @@ -714,14 +725,17 @@ main(int argc, char *argv[]) * be optional. */ while ((this_opt = getopt(argc, argv, - "0123456789CDIKLNR:TUVace:fGgo:rstvwx")) != -1) { + "0123456789CDIKLNQR:TUVace: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) { @@ -772,6 +786,9 @@ main(int argc, char *argv[]) smart_defaults = FALSE; literal = TRUE; break; + case 'Q': + quickdump = 0; + break; case 'R': tversion = optarg; break; @@ -802,6 +819,9 @@ main(int argc, char *argv[]) case 'o': outdir = optarg; break; + case 'q': + quiet = TRUE; + break; case 'r': forceresolve = TRUE; break; @@ -913,11 +933,11 @@ main(int argc, char *argv[]) ? outform : F_LITERAL, sortmode, width, height, debug_level, formatted || - check_only, check_only); + check_only, check_only, quickdump); } else if (capdump) { dump_init(tversion, outform, - sortmode, width, height, debug_level, FALSE, FALSE); + sortmode, width, height, debug_level, FALSE, FALSE, FALSE); } /* parse entries out of the source file */ @@ -988,12 +1008,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); @@ -1006,7 +1028,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; @@ -2006,6 +2028,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 @@ -2015,21 +2054,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; @@ -2037,12 +2061,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)); } @@ -2149,7 +2175,7 @@ get_fkey_list(TERMTYPE *tp) NAME_VALUE *result = typeMalloc(NAME_VALUE, NUM_STRINGS(tp) + 1); const struct tinfo_fkeys *all_fkeys = _nc_tinfo_fkeys; int used = 0; - int j; + unsigned j; if (result == 0) failed("get_fkey_list"); @@ -2165,7 +2191,7 @@ get_fkey_list(TERMTYPE *tp) } #if NCURSES_XNAMES for (j = STRCOUNT; j < NUM_STRINGS(tp); ++j) { - const char *name = ExtStrname(tp, j, strnames); + const char *name = ExtStrname(tp, (int) j, strnames); if (*name == 'k') { result[used].keycode = -1; result[used].name = name; @@ -2242,6 +2268,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)) { + 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) */ @@ -2324,7 +2446,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); @@ -2343,10 +2465,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) {