📄 tic.c
字号:
case 'v': v_opt = (v_opt * 10) + (this_opt - '0'); break; case 'w': width = (width * 10) + (this_opt - '0'); break; default: if (this_opt != '1') usage(); last_opt = this_opt; width = 0; } continue; } switch (this_opt) { case 'C': capdump = TRUE; outform = F_TERMCAP; sortmode = S_TERMCAP; break; case 'I': infodump = TRUE; outform = F_TERMINFO; sortmode = S_TERMINFO; break; case 'L': infodump = TRUE; outform = F_VARIABLE; sortmode = S_VARIABLE; break; case 'N': smart_defaults = FALSE; literal = TRUE; break; case 'R': tversion = optarg; break; case 'T': limited = FALSE; break; case 'U': literal = TRUE; break; case 'V': puts(curses_version()); return EXIT_SUCCESS; case 'c': check_only = TRUE; break; case 'e': namelst = make_namelist(optarg); break; case 'f': formatted = TRUE; break; case 'G': numbers = 1; break; case 'g': numbers = -1; break; case 'o': outdir = optarg; break; case 'r': forceresolve = TRUE; break; case 's': showsummary = TRUE; break; case 'v': v_opt = 0; break; case 'w': width = 0; break;#if NCURSES_XNAMES case 't': _nc_disable_period = FALSE; suppress_untranslatable = TRUE; break; case 'a': _nc_disable_period = TRUE; /* FALLTHRU */ case 'x': use_extended_names(TRUE); break;#endif default: usage(); } last_opt = this_opt; } debug_level = (v_opt > 0) ? v_opt : (v_opt == 0); set_trace_level(debug_level); if (_nc_tracing) { save_check_termtype = _nc_check_termtype2; _nc_check_termtype2 = check_termtype; }#if !HAVE_BIG_CORE /* * Aaargh! immedhook seriously hoses us! * * One problem with immedhook is it means we can't do -e. Problem * is that we can't guarantee that for each terminal listed, all the * terminals it depends on will have been kept in core for reference * resolution -- in fact it's certain the primitive types at the end * of reference chains *won't* be in core unless they were explicitly * in the select list themselves. */ if (namelst && (!infodump && !capdump)) { (void) fprintf(stderr, "Sorry, -e can't be used without -I or -C\n"); cleanup(); ExitProgram(EXIT_FAILURE); }#endif /* HAVE_BIG_CORE */ if (optind < argc) { 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); ExitProgram(EXIT_FAILURE); } } else { if (infodump == TRUE) { /* captoinfo's no-argument case */ source_file = "/etc/termcap"; if ((termcap = getenv("TERMCAP")) != 0 && (namelst = make_namelist(getenv("TERM"))) != 0) { 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("tmpnam"); } } } else { /* tic */ fprintf(stderr, "%s: File name needed. Usage:\n\t%s %s", _nc_progname, _nc_progname, usage_string); cleanup(); ExitProgram(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 || literal, FALSE, ((check_only || infodump || capdump) ? NULLHOOK : immedhook)); /* do use resolution */ if (check_only || (!infodump && !capdump) || forceresolve) { if (!_nc_resolve_uses2(TRUE, literal) && !check_only) { cleanup(); ExitProgram(EXIT_FAILURE); } } /* length check */ if (check_only && (capdump || infodump)) { for_entry_list(qp) { if (matches(namelst, qp->tterm.term_names)) { int len = fmt_entry(&qp->tterm, NULL, FALSE, TRUE, infodump, numbers); 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); } } } /* write or dump all entries */ if (!check_only) { if (!infodump && !capdump) { _nc_set_writedir(outdir); for_entry_list(qp) { if (matches(namelst, qp->tterm.term_names)) write_it(qp); } } else { /* 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)) { int j = qp->cend - qp->cstart; int len = 0; /* 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--) { if (infodump) (void) putchar(fgetc(tmp_fp)); else put_translate(fgetc(tmp_fp)); } len = dump_entry(&qp->tterm, suppress_untranslatable, limited, 0, numbers, NULL); for (j = 0; j < qp->nuses; j++) len += dump_uses(qp->uses[j].name, !capdump); (void) putchar('\n'); if (debug_level != 0 && !limited) printf("# length=%d\n", len); } } if (!namelst && _nc_tail) { int c, oldc = '\0'; bool in_comment = FALSE; bool trailing_comment = FALSE; (void) fseek(tmp_fp, _nc_tail->cend, SEEK_SET); while ((c = fgetc(tmp_fp)) != EOF) { if (oldc == '\n') { if (c == '#') { trailing_comment = TRUE; in_comment = TRUE; } else { in_comment = FALSE; } } if (trailing_comment && (in_comment || (oldc == '\n' && c == '\n'))) putchar(c); oldc = c; } } } } /* Show the directory into which entries were written, and the total * number of entries */ if (showsummary && (!(check_only || infodump || capdump))) { 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"); } cleanup(); ExitProgram(EXIT_SUCCESS);}/* * This bit of legerdemain turns all the terminfo variable names into * references to locations in the arrays Booleans, Numbers, and Strings --- * precisely what's needed (see comp_parse.c). */TERMINAL *cur_term; /* tweak to avoid linking lib_cur_term.c */#undef CUR#define CUR tp->/* * Check if the alternate character-set capabilities are consistent. */static voidcheck_acs(TERMTYPE *tp){ if (VALID_STRING(acs_chars)) { const char *boxes = "lmkjtuvwqxn"; char mapped[256]; char missing[256]; const char *p; char *q; memset(mapped, 0, sizeof(mapped)); for (p = acs_chars; *p != '\0'; p += 2) { if (p[1] == '\0') { _nc_warning("acsc has odd number of characters"); break; } mapped[UChar(p[0])] = p[1]; } if (mapped[UChar('I')] && !mapped[UChar('i')]) { _nc_warning("acsc refers to 'I', which is probably an error"); } for (p = boxes, q = missing; *p != '\0'; ++p) { if (!mapped[UChar(p[0])]) { *q++ = p[0]; } *q = '\0'; } if (*missing != '\0' && strcmp(missing, boxes)) { _nc_warning("acsc is missing some line-drawing mapping: %s", missing); } }}/* * Check if the color capabilities are consistent */static voidcheck_colors(TERMTYPE *tp){ if ((max_colors > 0) != (max_pairs > 0) || ((max_colors > max_pairs) && (initialize_pair == 0))) _nc_warning("inconsistent values for max_colors (%d) and max_pairs (%d)", max_colors, max_pairs); PAIRED(set_foreground, set_background); PAIRED(set_a_foreground, set_a_background); PAIRED(set_color_pair, initialize_pair); if (VALID_STRING(set_foreground) && VALID_STRING(set_a_foreground) && !_nc_capcmp(set_foreground, set_a_foreground)) _nc_warning("expected setf/setaf to be different"); if (VALID_STRING(set_background) && VALID_STRING(set_a_background) && !_nc_capcmp(set_background, set_a_background)) _nc_warning("expected setb/setab to be different"); /* see: has_colors() */ if (VALID_NUMERIC(max_colors) && VALID_NUMERIC(max_pairs) && (((set_foreground != NULL) && (set_background != NULL)) || ((set_a_foreground != NULL) && (set_a_background != NULL)) || set_color_pair)) { if (!VALID_STRING(orig_pair) && !VALID_STRING(orig_colors)) _nc_warning("expected either op/oc string for resetting colors"); }}static intkeypad_final(const char *string){ int result = '\0'; if (VALID_STRING(string) && *string++ == '\033' && *string++ == 'O' && strlen(string) == 1) { result = *string; } return result;}static intkeypad_index(const char *string){ char *test; const char *list = "PQRSwxymtuvlqrsPpn"; /* app-keypad except "Enter" */ int ch; int result = -1; if ((ch = keypad_final(string)) != '\0') { test = strchr(list, ch); if (test != 0) result = (test - list); } return result;}/* * Do a quick sanity-check for vt100-style keypads to see if the 5-key keypad * is mapped inconsistently. */static voidcheck_keypad(TERMTYPE *tp){ char show[80]; if (VALID_STRING(key_a1) && VALID_STRING(key_a3) && VALID_STRING(key_b2) && VALID_STRING(key_c1) && VALID_STRING(key_c3)) { char final[6]; int list[5]; int increase = 0; int j, k, kk; int last; int test; final[0] = keypad_final(key_a1); final[1] = keypad_final(key_a3); final[2] = keypad_final(key_b2); final[3] = keypad_final(key_c1); final[4] = keypad_final(key_c3); final[5] = '\0'; /* special case: legacy coding using 1,2,3,0,. on the bottom */ if (!strcmp(final, "qsrpn")) return; list[0] = keypad_index(key_a1); list[1] = keypad_index(key_a3); list[2] = keypad_index(key_b2); list[3] = keypad_index(key_c1); list[4] = keypad_index(key_c3); /* check that they're all vt100 keys */ for (j = 0; j < 5; ++j) { if (list[j] < 0) { return; } } /* check if they're all in increasing order */ for (j = 1; j < 5; ++j) { if (list[j] > list[j - 1]) { ++increase; } } if (increase != 4) { show[0] = '\0'; for (j = 0, last = -1; j < 5; ++j) { for (k = 0, kk = -1, test = 100; k < 5; ++k) { if (list[k] > last && list[k] < test) { test = list[k]; kk = k; } } last = test; switch (kk) { case 0: strcat(show, " ka1"); break; case 1: strcat(show, " ka3"); break; case 2: strcat(show, " kb2"); break; case 3: strcat(show, " kc1"); break; case 4: strcat(show, " kc3"); break; } } _nc_warning("vt100 keypad order inconsistent: %s", show); } } else if (VALID_STRING(key_a1) || VALID_STRING(key_a3) || VALID_STRING(key_b2) || VALID_STRING(key_c1) || VALID_STRING(key_c3)) { show[0] = '\0'; if (keypad_index(key_a1) >= 0) strcat(show, " ka1"); if (keypad_index(key_a3) >= 0) strcat(show, " ka3");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -