#include <parametrized.h>
#include <transform.h>
-MODULE_ID("$Id: tic.c,v 1.209 2015/04/04 14:53:41 tom Exp $")
+MODULE_ID("$Id: tic.c,v 1.220 2015/12/27 01:46:01 tom Exp $")
#define STDIN_NAME "<stdin>"
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)")
DATA(" -L translate entries to full terminfo source form")
DATA(" -N disable smart defaults for source translation")
DATA(" -o<dir> set output directory for compiled entry writes")
+ DATA(" -Q[n] dump compiled description")
+ DATA(" -q brief listing, removes headers")
DATA(" -R<name> restrict translation to given terminfo/termcap version")
DATA(" -r force resolution of all use entries in source translation")
DATA(" -s print summary statistics")
}
}
+static void
+add_digit(int *target, int source)
+{
+ *target = (*target * 10) + (source - '0');
+}
+
#define VtoTrace(opt) (unsigned) ((opt > 0) ? opt : (opt == 0))
int
char *outdir = (char *) NULL;
bool check_only = FALSE;
bool suppress_untranslatable = FALSE;
+ int quickdump = 0;
+ bool quiet = FALSE;
log_fp = stderr;
* 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) {
smart_defaults = FALSE;
literal = TRUE;
break;
+ case 'Q':
+ quickdump = 0;
+ break;
case 'R':
tversion = optarg;
break;
case 'o':
outdir = optarg;
break;
+ case 'q':
+ quiet = TRUE;
+ break;
case 'r':
forceresolve = TRUE;
break;
}
}
- if (infodump) {
+ if (infodump || check_only) {
dump_init(tversion,
smart_defaults
? outform
: F_LITERAL,
- sortmode, width, height, debug_level, formatted);
+ sortmode, width, height, debug_level, formatted ||
+ check_only, check_only, quickdump);
} else if (capdump) {
dump_init(tversion,
outform,
- sortmode, width, height, debug_level, FALSE);
+ sortmode, width, height, debug_level, FALSE, FALSE, FALSE);
}
/* parse entries out of the source file */
}
/* write or dump all entries */
- if (!check_only) {
+ if (check_only) {
+ /* this is in case infotocap() generates warnings */
+ _nc_curr_col = _nc_curr_line = -1;
+
+ for_entry_list(qp) {
+ if (matches(namelst, qp->tterm.term_names)) {
+ /* this is in case infotocap() generates warnings */
+ _nc_set_type(_nc_first_name(qp->tterm.term_names));
+ _nc_curr_line = (int) qp->startline;
+ repair_acsc(&qp->tterm);
+ dump_entry(&qp->tterm, suppress_untranslatable,
+ limited, numbers, NULL);
+ }
+ }
+ } else {
if (!infodump && !capdump) {
_nc_set_writedir(outdir);
for_entry_list(qp) {
/* 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);
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;
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
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;
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));
}
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");
}
#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;
}
}
+/*
+ * 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;
+ while (*test != 0) {
+ if (isdigit(UChar(*test))) {
+ param = 10 * param + (*test - '0');
+ ++count;
+ } else {
+ if (count) {
+ if (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)
*/
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);
("will trim sgr0\n\toriginal sgr0=%s\n\ttrimmed sgr0=%s",
_nc_visbuf2(1, exit_attribute_mode),
_nc_visbuf2(2, check_sgr0)));
- free(check_sgr0);
} else {
DEBUG(2,
("will not trim sgr0\n\toriginal sgr0=%s",
_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);