📄 infocmp.c
字号:
*tp++ = '"'; for (sp = term->Strings[n]; *sp != 0 && (tp - buf) < MAX_STRING - 6; sp++) { if (isascii(UChar(*sp)) && isprint(UChar(*sp)) && *sp != '\\' && *sp != '"') *tp++ = *sp; else { (void) sprintf(tp, "\\%03o", UChar(*sp)); tp += 4; } } *tp++ = '"'; *tp = '\0'; size += (strlen(term->Strings[n]) + 1); (void) printf("static char %-20s[] = %s;\n", string_variable(ExtStrname(term, n, strnames)), buf); } } printf("\n"); (void) printf("static char %s[] = %s\n", name_initializer("bool"), L_CURL); for_each_boolean(n, term) { switch ((int) (term->Booleans[n])) { case TRUE: str = "TRUE"; break; case FALSE: str = "FALSE"; break; case ABSENT_BOOLEAN: str = "ABSENT_BOOLEAN"; break; case CANCELLED_BOOLEAN: str = "CANCELLED_BOOLEAN"; break; } (void) printf("\t/* %3u: %-8s */\t%s,\n", n, ExtBoolname(term, n, boolnames), str); } (void) printf("%s;\n", R_CURL); (void) printf("static short %s[] = %s\n", name_initializer("number"), L_CURL); for_each_number(n, term) { char buf[BUFSIZ]; switch (term->Numbers[n]) { case ABSENT_NUMERIC: str = "ABSENT_NUMERIC"; break; case CANCELLED_NUMERIC: str = "CANCELLED_NUMERIC"; break; default: sprintf(buf, "%d", term->Numbers[n]); str = buf; break; } (void) printf("\t/* %3u: %-8s */\t%s,\n", n, ExtNumname(term, n, numnames), str); } (void) printf("%s;\n", R_CURL); size = (sizeof(TERMTYPE) + (NUM_BOOLEANS(term) * sizeof(term->Booleans[0])) + (NUM_NUMBERS(term) * sizeof(term->Numbers[0]))); (void) printf("static char * %s[] = %s\n", name_initializer("string"), L_CURL); for_each_string(n, term) { if (term->Strings[n] == ABSENT_STRING) str = "ABSENT_STRING"; else if (term->Strings[n] == CANCELLED_STRING) str = "CANCELLED_STRING"; else { str = string_variable(ExtStrname(term, n, strnames)); } (void) printf("\t/* %3u: %-8s */\t%s,\n", n, ExtStrname(term, n, strnames), str); } (void) printf("%s;\n", R_CURL);#if NCURSES_XNAMES if ((NUM_BOOLEANS(term) != BOOLCOUNT) || (NUM_NUMBERS(term) != NUMCOUNT) || (NUM_STRINGS(term) != STRCOUNT)) { (void) printf("static char * %s[] = %s\n", name_initializer("string_ext"), L_CURL); for (n = BOOLCOUNT; n < NUM_BOOLEANS(term); ++n) { (void) printf("\t/* %3u: bool */\t\"%s\",\n", n, ExtBoolname(term, n, boolnames)); } for (n = NUMCOUNT; n < NUM_NUMBERS(term); ++n) { (void) printf("\t/* %3u: num */\t\"%s\",\n", n, ExtNumname(term, n, numnames)); } for (n = STRCOUNT; n < NUM_STRINGS(term); ++n) { (void) printf("\t/* %3u: str */\t\"%s\",\n", n, ExtStrname(term, n, strnames)); } (void) printf("%s;\n", R_CURL); }#endif}/* dump C initializers for the terminal type */static voiddump_termtype(TERMTYPE *term){ (void) printf("\t%s\n\t\t%s,\n", L_CURL, name_initializer("alias")); (void) printf("\t\t(char *)0,\t/* pointer to string table */\n"); (void) printf("\t\t%s,\n", name_initializer("bool")); (void) printf("\t\t%s,\n", name_initializer("number")); (void) printf("\t\t%s,\n", name_initializer("string"));#if NCURSES_XNAMES (void) printf("#if NCURSES_XNAMES\n"); (void) printf("\t\t(char *)0,\t/* pointer to extended string table */\n"); (void) printf("\t\t%s,\t/* ...corresponding names */\n", ((NUM_BOOLEANS(term) != BOOLCOUNT) || (NUM_NUMBERS(term) != NUMCOUNT) || (NUM_STRINGS(term) != STRCOUNT)) ? name_initializer("string_ext") : "(char **)0"); (void) printf("\t\t%d,\t\t/* count total Booleans */\n", NUM_BOOLEANS(term)); (void) printf("\t\t%d,\t\t/* count total Numbers */\n", NUM_NUMBERS(term)); (void) printf("\t\t%d,\t\t/* count total Strings */\n", NUM_STRINGS(term)); (void) printf("\t\t%d,\t\t/* count extensions to Booleans */\n", NUM_BOOLEANS(term) - BOOLCOUNT); (void) printf("\t\t%d,\t\t/* count extensions to Numbers */\n", NUM_NUMBERS(term) - NUMCOUNT); (void) printf("\t\t%d,\t\t/* count extensions to Strings */\n", NUM_STRINGS(term) - STRCOUNT); (void) printf("#endif /* NCURSES_XNAMES */\n");#endif /* NCURSES_XNAMES */ (void) printf("\t%s\n", R_CURL);}static intoptarg_to_number(void){ char *temp = 0; long value = strtol(optarg, &temp, 0); if (temp == 0 || temp == optarg || *temp != 0) { fprintf(stderr, "Expected a number, not \"%s\"\n", optarg); ExitProgram(EXIT_FAILURE); } return (int) value;}static char *terminal_env(void){ char *terminal; if ((terminal = getenv("TERM")) == 0) { (void) fprintf(stderr, "infocmp: environment variable TERM not set\n"); exit(EXIT_FAILURE); } return terminal;}/*************************************************************************** * * Main sequence * ***************************************************************************/intmain(int argc, char *argv[]){ char *firstdir, *restdir; /* Avoid "local data >32k" error with mwcc */ /* Also avoid overflowing smaller stacks on systems like AmigaOS */ path *tfile = (path *) malloc(sizeof(path) * MAXTERMS); int c, i, len; bool formatted = FALSE; bool filecompare = FALSE; int initdump = 0; bool init_analyze = FALSE; bool suppress_untranslatable = FALSE; /* where is the terminfo database location going to default to? */ restdir = firstdir = 0;#if NCURSES_XNAMES use_extended_names(FALSE);#endif while ((c = getopt(argc, argv, "1A:aB:CcdEeFfGgIiLlnpqR:rs:TtUuVv:w:x")) != EOF) switch (c) { case '1': mwidth = 0; break; case 'A': firstdir = optarg; break;#if NCURSES_XNAMES case 'a': _nc_disable_period = TRUE; use_extended_names(TRUE); break;#endif case 'B': restdir = optarg; break; case 'C': outform = F_TERMCAP; tversion = "BSD"; if (sortmode == S_DEFAULT) sortmode = S_TERMCAP; break; case 'c': compare = C_COMMON; break; case 'd': compare = C_DIFFERENCE; break; case 'E': initdump |= 2; break; case 'e': initdump |= 1; break; case 'F': filecompare = TRUE; break; case 'f': formatted = TRUE; break; case 'G': numbers = 1; break; case 'g': numbers = -1; break; case 'I': outform = F_TERMINFO; if (sortmode == S_DEFAULT) sortmode = S_VARIABLE; tversion = 0; break; case 'i': init_analyze = TRUE; break; case 'L': outform = F_VARIABLE; if (sortmode == S_DEFAULT) sortmode = S_VARIABLE; break; case 'l': outform = F_TERMINFO; break; case 'n': compare = C_NAND; break; case 'p': ignorepads = TRUE; break; case 'q': quiet = TRUE; s_absent = "-"; s_cancel = "@"; bool_sep = ", "; break; case 'R': tversion = optarg; break; case 'r': tversion = 0; limited = FALSE; break; case 's': if (*optarg == 'd') sortmode = S_NOSORT; else if (*optarg == 'i') sortmode = S_TERMINFO; else if (*optarg == 'l') sortmode = S_VARIABLE; else if (*optarg == 'c') sortmode = S_TERMCAP; else { (void) fprintf(stderr, "infocmp: unknown sort mode\n"); return EXIT_FAILURE; } break; case 'T': limited = FALSE; break;#if NCURSES_XNAMES case 't': _nc_disable_period = FALSE; suppress_untranslatable = TRUE; break;#endif case 'U': literal = TRUE; break; case 'u': compare = C_USEALL; break; case 'V': puts(curses_version()); ExitProgram(EXIT_SUCCESS); case 'v': itrace = optarg_to_number(); set_trace_level(itrace); break; case 'w': mwidth = optarg_to_number(); break;#if NCURSES_XNAMES case 'x': use_extended_names(TRUE); break;#endif default: usage(); } /* by default, sort by terminfo name */ if (sortmode == S_DEFAULT) sortmode = S_TERMINFO; /* set up for display */ dump_init(tversion, outform, sortmode, mwidth, itrace, formatted); /* make sure we have at least one terminal name to work with */ if (optind >= argc) argv[argc++] = terminal_env(); /* if user is after a comparison, make sure we have two entries */ if (compare != C_DEFAULT && optind >= argc - 1) argv[argc++] = terminal_env(); /* exactly two terminal names with no options means do -d */ if (argc - optind == 2 && compare == C_DEFAULT) compare = C_DIFFERENCE; if (!filecompare) { /* grab the entries */ termcount = 0; for (; optind < argc; optind++) { if (termcount >= MAXTERMS) { (void) fprintf(stderr, "infocmp: too many terminal type arguments\n"); return EXIT_FAILURE; } else { const char *directory = termcount ? restdir : firstdir; int status; tname[termcount] = argv[optind]; if (directory) { (void) sprintf(tfile[termcount], "%s/%c/%s", directory, *argv[optind], argv[optind]); if (itrace) (void) fprintf(stderr, "infocmp: reading entry %s from file %s\n", argv[optind], tfile[termcount]); status = _nc_read_file_entry(tfile[termcount], &entries[termcount].tterm); } else { if (itrace) (void) fprintf(stderr, "infocmp: reading entry %s from system directories %s\n", argv[optind], tname[termcount]); status = _nc_read_entry(tname[termcount], tfile[termcount], &entries[termcount].tterm); directory = TERMINFO; /* for error message */ } if (status <= 0) { (void) fprintf(stderr, "infocmp: couldn't open terminfo file %s.\n", tfile[termcount]); return EXIT_FAILURE; } repair_acsc(&entries[termcount].tterm); termcount++; } }#if NCURSES_XNAMES if (termcount > 1) _nc_align_termtype(&entries[0].tterm, &entries[1].tterm);#endif /* dump as C initializer for the terminal type */ if (initdump) { if (initdump & 1) dump_termtype(&entries[0].tterm); if (initdump & 2) dump_initializers(&entries[0].tterm); ExitProgram(EXIT_SUCCESS); } /* analyze the init strings */ if (init_analyze) {#undef CUR#define CUR entries[0].tterm. analyze_string("is1", init_1string, &entries[0].tterm); analyze_string("is2", init_2string, &entries[0].tterm); analyze_string("is3", init_3string, &entries[0].tterm); analyze_string("rs1", reset_1string, &entries[0].tterm); analyze_string("rs2", reset_2string, &entries[0].tterm); analyze_string("rs3", reset_3string, &entries[0].tterm); analyze_string("smcup", enter_ca_mode, &entries[0].tterm); analyze_string("rmcup", exit_ca_mode, &entries[0].tterm);#undef CUR ExitProgram(EXIT_SUCCESS); } /* * Here's where the real work gets done */ switch (compare) { case C_DEFAULT: if (itrace) (void) fprintf(stderr, "infocmp: about to dump %s\n", tname[0]); (void) printf("#\tReconstructed via infocmp from file: %s\n", tfile[0]); len = dump_entry(&entries[0].tterm, suppress_untranslatable, limited, 0, numbers, NULL); putchar('\n'); if (itrace) (void) fprintf(stderr, "infocmp: length %d\n", len); break; case C_DIFFERENCE: if (itrace) (void) fprintf(stderr, "infocmp: dumping differences\n"); (void) printf("comparing %s to %s.\n", tname[0], tname[1]); compare_entry(compare_predicate, &entries->tterm, quiet); break; case C_COMMON: if (itrace) (void) fprintf(stderr, "infocmp: dumping common capabilities\n"); (void) printf("comparing %s to %s.\n", tname[0], tname[1]); compare_entry(compare_predicate, &entries->tterm, quiet); break; case C_NAND: if (itrace) (void) fprintf(stderr, "infocmp: dumping differences\n"); (void) printf("comparing %s to %s.\n", tname[0], tname[1]); compare_entry(compare_predicate, &entries->tterm, quiet); break; case C_USEALL: if (itrace) (void) fprintf(stderr, "infocmp: dumping use entry\n"); len = dump_entry(&entries[0].tterm, suppress_untranslatable, limited, 0, numbers, use_predicate); for (i = 1; i < termcount; i++) len += dump_uses(tname[i], !(outform == F_TERMCAP || outform == F_TCONVERR)); putchar('\n'); if (itrace) (void) fprintf(stderr, "infocmp: length %d\n", len); break; } } else if (compare == C_USEALL) (void) fprintf(stderr, "Sorry, -u doesn't work with -F\n"); else if (compare == C_DEFAULT) (void) fprintf(stderr, "Use `tic -[CI] <file>' for this.\n"); else if (argc - optind != 2) (void) fprintf(stderr, "File comparison needs exactly two file arguments.\n"); else file_comparison(argc - optind, argv + optind); ExitProgram(EXIT_SUCCESS);}/* infocmp.c ends here */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -