=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tic/tic.c,v retrieving revision 1.20 retrieving revision 1.21 diff -c -r1.20 -r1.21 *** src/usr.bin/tic/tic.c 2000/06/19 03:53:59 1.20 --- src/usr.bin/tic/tic.c 2000/10/08 22:47:10 1.21 *************** *** 38,48 **** */ #include #include #include ! MODULE_ID("$From: tic.c,v 1.69 2000/04/08 23:53:49 tom Exp $") const char *_nc_progname = "tic"; --- 38,50 ---- */ #include + #include #include #include + #include ! MODULE_ID("$From: tic.c,v 1.82 2000/10/01 02:11:39 tom Exp $") const char *_nc_progname = "tic"; *************** *** 54,60 **** static void (*save_check_termtype) (TERMTYPE *); static void check_termtype(TERMTYPE * tt); ! static const char usage_string[] = "[-h] [-v[n]] [-e names] [-CILNRTcfrswx1] source-file\n"; static void cleanup(void) --- 56,62 ---- static void (*save_check_termtype) (TERMTYPE *); static void check_termtype(TERMTYPE * tt); ! static const char usage_string[] = "[-V] [-v[n]] [-e names] [-CILNRTcfrswx1] source-file\n"; static void cleanup(void) *************** *** 91,96 **** --- 93,99 ---- " -N disable smart defaults for source translation", " -R restrict translation to given terminfo/termcap version", " -T remove size-restrictions on compiled description", + " -V print version", #if NCURSES_XNAMES " -a retain commented-out capabilities (sets -x also)", #endif *************** *** 114,120 **** size_t j; fprintf(stderr, "Usage: %s %s\n", _nc_progname, usage_string); ! for (j = 0; j < sizeof(tbl) / sizeof(tbl[0]); j++) { fputs(tbl[j], stderr); putc('\n', stderr); } --- 117,123 ---- size_t j; fprintf(stderr, "Usage: %s %s\n", _nc_progname, usage_string); ! for (j = 0; j < SIZEOF(tbl); j++) { fputs(tbl[j], stderr); putc('\n', stderr); } *************** *** 148,154 **** if (ch == '\\') { *d++ = *t++; } else if ((ch == '%') ! && (*t == L_BRACE)) { char *v = 0; long value = strtol(t + 1, &v, 0); if (v != 0 --- 151,157 ---- if (ch == '\\') { *d++ = *t++; } else if ((ch == '%') ! && (*t == L_BRACE)) { char *v = 0; long value = strtol(t + 1, &v, 0); if (v != 0 *************** *** 179,185 **** immedhook(ENTRY * ep GCC_UNUSED) /* write out entries with no use capabilities immediately to save storage */ { ! #ifndef HAVE_BIG_CORE /* * This is strictly a core-economy kluge. The really clean way to handle * compilation is to slurp the whole file into core and then do all the --- 182,188 ---- immedhook(ENTRY * ep GCC_UNUSED) /* write out entries with no use capabilities immediately to save storage */ { ! #if !HAVE_BIG_CORE /* * This is strictly a core-economy kluge. The really clean way to handle * compilation is to slurp the whole file into core and then do all the *************** *** 301,306 **** --- 304,327 ---- return 0; } + static FILE * + open_input(const char *filename) + { + FILE *fp = fopen(filename, "r"); + struct stat sb; + + if (fp == 0) { + fprintf(stderr, "%s: Can't open %s\n", _nc_progname, filename); + exit(EXIT_FAILURE); + } + if (fstat(fileno(fp), &sb) < 0 + || (sb.st_mode & S_IFMT) != S_IFREG) { + fprintf(stderr, "%s: %s is not a file\n", _nc_progname, filename); + exit(EXIT_FAILURE); + } + return fp; + } + /* Parse the "-e" option-value into a list of names */ static const char ** make_namelist(char *src) *************** *** 314,322 **** if (src == 0) { /* EMPTY */ ; } else if (strchr(src, '/') != 0) { /* a filename */ ! FILE *fp = fopen(src, "r"); ! if (fp == 0) ! failed(src); for (pass = 1; pass <= 2; pass++) { nn = 0; --- 335,341 ---- if (src == 0) { /* EMPTY */ ; } else if (strchr(src, '/') != 0) { /* a filename */ ! FILE *fp = open_input(src); for (pass = 1; pass <= 2; pass++) { nn = 0; *************** *** 425,440 **** log_fp = stderr; ! if ((_nc_progname = strrchr(argv[0], '/')) == NULL) ! _nc_progname = argv[0]; ! else ! _nc_progname++; ! if ((infodump = (strcmp(_nc_progname, "captoinfo") == 0)) != FALSE) { outform = F_TERMINFO; sortmode = S_TERMINFO; } ! if ((capdump = (strcmp(_nc_progname, "infotocap") == 0)) != FALSE) { outform = F_TERMCAP; sortmode = S_TERMCAP; } --- 444,456 ---- log_fp = stderr; ! _nc_progname = _nc_basename(argv[0]); ! if ((infodump = (strcmp(_nc_progname, PROG_CAPTOINFO) == 0)) != FALSE) { outform = F_TERMINFO; sortmode = S_TERMINFO; } ! if ((capdump = (strcmp(_nc_progname, PROG_INFOTOCAP) == 0)) != FALSE) { outform = F_TERMCAP; sortmode = S_TERMCAP; } *************** *** 448,454 **** * be optional. */ while ((this_opt = getopt(argc, argv, ! "0123456789CILNR:TVace:fGgo:rsvwx")) != -1) { if (isdigit(this_opt)) { switch (last_opt) { case 'v': --- 464,470 ---- * be optional. */ while ((this_opt = getopt(argc, argv, ! "0123456789CILNR:TVace:fGgo:rsvwx")) != -1) { if (isdigit(this_opt)) { switch (last_opt) { case 'v': *************** *** 491,497 **** limited = FALSE; break; case 'V': ! puts(NCURSES_VERSION); return EXIT_SUCCESS; case 'c': check_only = TRUE; --- 507,513 ---- limited = FALSE; break; case 'V': ! puts(curses_version()); return EXIT_SUCCESS; case 'c': check_only = TRUE; *************** *** 544,550 **** save_check_termtype = _nc_check_termtype; _nc_check_termtype = check_termtype; } ! #ifndef HAVE_BIG_CORE /* * Aaargh! immedhook seriously hoses us! * --- 560,566 ---- save_check_termtype = _nc_check_termtype; _nc_check_termtype = check_termtype; } ! #if !HAVE_BIG_CORE /* * Aaargh! immedhook seriously hoses us! * *************** *** 557,563 **** */ if (namelst && (!infodump && !capdump)) { (void) fprintf(stderr, ! "Sorry, -e can't be used without -I or -C\n"); cleanup(); return EXIT_FAILURE; } --- 573,579 ---- */ if (namelst && (!infodump && !capdump)) { (void) fprintf(stderr, ! "Sorry, -e can't be used without -I or -C\n"); cleanup(); return EXIT_FAILURE; } *************** *** 567,576 **** source_file = argv[optind++]; if (optind < argc) { fprintf(stderr, ! "%s: Too many file names. Usage:\n\t%s %s", ! _nc_progname, ! _nc_progname, ! usage_string); return EXIT_FAILURE; } } else { --- 583,592 ---- source_file = argv[optind++]; if (optind < argc) { fprintf(stderr, ! "%s: Too many file names. Usage:\n\t%s %s", ! _nc_progname, ! _nc_progname, ! usage_string); return EXIT_FAILURE; } } else { *************** *** 582,592 **** if (access(termcap, F_OK) == 0) { /* file exists */ source_file = termcap; ! } else if ((tmp_fp = open_tempfile(my_tmpname)) != 0) { source_file = my_tmpname; fprintf(tmp_fp, "%s\n", termcap); fclose(tmp_fp); ! tmp_fp = fopen(source_file, "r"); to_remove = source_file; } else { failed("mkstemp"); --- 598,610 ---- if (access(termcap, F_OK) == 0) { /* file exists */ source_file = termcap; ! } else if ((tmp_fp = open_tempfile(strcpy(my_tmpname, ! "/tmp/XXXXXX"))) ! != 0) { source_file = my_tmpname; fprintf(tmp_fp, "%s\n", termcap); fclose(tmp_fp); ! tmp_fp = open_input(source_file); to_remove = source_file; } else { failed("mkstemp"); *************** *** 595,635 **** } else { /* tic */ fprintf(stderr, ! "%s: File name needed. Usage:\n\t%s %s", ! _nc_progname, ! _nc_progname, ! usage_string); cleanup(); return EXIT_FAILURE; } } ! if (tmp_fp == 0 ! && (tmp_fp = fopen(source_file, "r")) == 0) { ! fprintf(stderr, "%s: Can't open %s\n", _nc_progname, source_file); ! return EXIT_FAILURE; ! } if (infodump) dump_init(tversion, ! smart_defaults ! ? outform ! : F_LITERAL, ! sortmode, width, debug_level, formatted); else if (capdump) dump_init(tversion, ! outform, ! sortmode, width, debug_level, FALSE); /* parse entries out of the source file */ _nc_set_source(source_file); ! #ifndef HAVE_BIG_CORE if (!(check_only || infodump || capdump)) _nc_set_writedir(outdir); #endif /* HAVE_BIG_CORE */ _nc_read_entry_source(tmp_fp, (char *) NULL, ! !smart_defaults, FALSE, ! (check_only || infodump || capdump) ? NULLHOOK : immedhook); /* do use resolution */ if (check_only || (!infodump && !capdump) || forceresolve) { --- 613,650 ---- } else { /* tic */ fprintf(stderr, ! "%s: File name needed. Usage:\n\t%s %s", ! _nc_progname, ! _nc_progname, ! usage_string); cleanup(); return EXIT_FAILURE; } } ! if (tmp_fp == 0) ! tmp_fp = open_input(source_file); if (infodump) dump_init(tversion, ! smart_defaults ! ? outform ! : F_LITERAL, ! sortmode, width, debug_level, formatted); else if (capdump) dump_init(tversion, ! outform, ! sortmode, width, debug_level, FALSE); /* parse entries out of the source file */ _nc_set_source(source_file); ! #if !HAVE_BIG_CORE if (!(check_only || infodump || capdump)) _nc_set_writedir(outdir); #endif /* HAVE_BIG_CORE */ _nc_read_entry_source(tmp_fp, (char *) NULL, ! !smart_defaults, FALSE, ! (check_only || infodump || capdump) ? NULLHOOK : immedhook); /* do use resolution */ if (check_only || (!infodump && !capdump) || forceresolve) { *************** *** 647,655 **** if (len > (infodump ? MAX_TERMINFO_LENGTH : MAX_TERMCAP_LENGTH)) (void) fprintf(stderr, ! "warning: resolved %s entry is %d bytes long\n", ! _nc_first_name(qp->tterm.term_names), ! len); } } } --- 662,670 ---- if (len > (infodump ? MAX_TERMINFO_LENGTH : MAX_TERMCAP_LENGTH)) (void) fprintf(stderr, ! "warning: resolved %s entry is %d bytes long\n", ! _nc_first_name(qp->tterm.term_names), ! len); } } } *************** *** 722,729 **** int total = _nc_tic_written(); if (total != 0) fprintf(log_fp, "%d entries written to %s\n", ! total, ! _nc_tic_dir((char *) 0)); else fprintf(log_fp, "No entries written\n"); } --- 737,744 ---- int total = _nc_tic_written(); if (total != 0) fprintf(log_fp, "%d entries written to %s\n", ! total, ! _nc_tic_dir((char *) 0)); else fprintf(log_fp, "No entries written\n"); } *************** *** 743,748 **** --- 758,902 ---- #define CUR tp-> /* + * Returns the expected number of parameters for the given capability. + */ + static int + expected_params(char *name) + { + /* *INDENT-OFF* */ + static const struct { + const char *name; + int count; + } table[] = { + { "birep", 2 }, + { "chr", 1 }, + { "colornm", 1 }, + { "cpi", 1 }, + { "csr", 2 }, + { "cub", 1 }, + { "cud", 1 }, + { "cuf", 1 }, + { "cup", 2 }, + { "cvr", 1 }, + { "cuu", 1 }, + { "cwin", 5 }, + { "dch", 1 }, + { "dclk", 2 }, + { "dial", 1 }, + { "dispc", 1 }, + { "dl", 1 }, + { "ech", 1 }, + { "getm", 1 }, + { "hpa", 1 }, + { "ich", 1 }, + { "il", 1 }, + { "indn", 1 }, + { "initc", 4 }, + { "initp", 7 }, + { "lpi", 1 }, + { "mc5p", 1 }, + { "mrcup", 2 }, + { "mvpa", 1 }, + { "pfkey", 2 }, + { "pfloc", 2 }, + { "pfx", 2 }, + { "pfxl", 3 }, + { "pln", 2 }, + { "qdial", 1 }, + { "rep", 2 }, + { "rin", 1 }, + { "sclk", 3 }, + { "scp", 1 }, + { "scs", 1 }, + { "setab", 1 }, + { "setaf", 1 }, + { "setb", 1 }, + { "setcolor", 1 }, + { "setf", 1 }, + { "sgr", 9 }, + { "sgr1", 6 }, + { "slength", 1 }, + { "slines", 1 }, + { "smgbp", 2 }, + { "smglp", 2 }, + { "smglr", 2 }, + { "smgrp", 1 }, + { "smgtb", 2 }, + { "smgtp", 2 }, + { "tsl", 1 }, + { "u6", -1 }, + { "vpa", 1 }, + { "wind", 4 }, + { "wingo", 1 }, + }; + /* *INDENT-ON* */ + + unsigned n; + int result = 0; /* function-keys, etc., use none */ + + for (n = 0; n < SIZEOF(table); n++) { + if (!strcmp(name, table[n].name)) { + result = table[n].count; + break; + } + } + + return result; + } + + /* + * Make a quick sanity check for the parameters which are used in the given + * strings. If there are no "%p" tokens, then there should be no other "%" + * markers. + */ + static void + check_params(TERMTYPE * tp, char *name, char *value) + { + int expected = expected_params(name); + int actual = 0; + int n; + bool params[10]; + char *s = value; + + for (n = 0; n < 10; n++) + params[n] = FALSE; + + while (*s != 0) { + if (*s == '%') { + if (*++s == '\0') { + _nc_warning("expected character after %% in %s", name); + break; + } else if (*s == 'p') { + if (*++s == '\0' || !isdigit((int) *s)) { + _nc_warning("expected digit after %%p in %s", name); + return; + } else { + n = (*s - '0'); + if (n > actual) + actual = n; + params[n] = TRUE; + } + } + } + s++; + } + + if (params[0]) { + _nc_warning("%s refers to parameter 0 (%%p0), which is not allowed", name); + } + if (value == set_attributes || expected < 0) { + ; + } else if (expected != actual) { + _nc_warning("%s uses %d parameters, expected %d", name, + actual, expected); + for (n = 1; n < actual; n++) { + if (!params[n]) + _nc_warning("%s omits parameter %d", name, n); + } + } + } + + /* * An sgr string may contain several settings other than the one we're * interested in, essentially sgr0 + rmacs + whatever. As long as the * "whatever" is contained in the sgr string, that is close enough for our *************** *** 767,786 **** check_sgr(TERMTYPE * tp, char *zero, int num, char *cap, const char *name) { char *test = tparm(set_attributes, ! num == 1, ! num == 2, ! num == 3, ! num == 4, ! num == 5, ! num == 6, ! num == 7, ! num == 8, ! num == 9); if (test != 0) { if (PRESENT(cap)) { if (!similar_sgr(test, cap)) { _nc_warning("%s differs from sgr(%d): %s", name, num, ! _nc_visbuf(test)); } } else if (strcmp(test, zero)) { _nc_warning("sgr(%d) present, but not %s", num, name); --- 921,940 ---- check_sgr(TERMTYPE * tp, char *zero, int num, char *cap, const char *name) { char *test = tparm(set_attributes, ! num == 1, ! num == 2, ! num == 3, ! num == 4, ! num == 5, ! num == 6, ! num == 7, ! num == 8, ! num == 9); if (test != 0) { if (PRESENT(cap)) { if (!similar_sgr(test, cap)) { _nc_warning("%s differs from sgr(%d): %s", name, num, ! _nc_visbuf(test)); } } else if (strcmp(test, zero)) { _nc_warning("sgr(%d) present, but not %s", num, name); *************** *** 827,843 **** conflict = TRUE; } fprintf(stderr, "... %s is the same as %s", ! keyname(_nc_tinfo_fkeys[j].code), ! keyname(_nc_tinfo_fkeys[k].code)); first = FALSE; } else { fprintf(stderr, ", %s", ! keyname(_nc_tinfo_fkeys[k].code)); } } } if (!first) fprintf(stderr, "\n"); } /* --- 981,1003 ---- conflict = TRUE; } fprintf(stderr, "... %s is the same as %s", ! keyname(_nc_tinfo_fkeys[j].code), ! keyname(_nc_tinfo_fkeys[k].code)); first = FALSE; } else { fprintf(stderr, ", %s", ! keyname(_nc_tinfo_fkeys[k].code)); } } } if (!first) fprintf(stderr, "\n"); + } + + for (j = 0; j < NUM_STRINGS(tp); j++) { + char *a = tp->Strings[j]; + if (VALID_STRING(a)) + check_params(tp, ExtStrname(tp, j, strnames), a); } /*