📄 tic.c
字号:
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"); if (keypad_index(key_b2) >= 0) strcat(show, " kb2"); if (keypad_index(key_c1) >= 0) strcat(show, " kc1"); if (keypad_index(key_c3) >= 0) strcat(show, " kc3"); if (*show != '\0') _nc_warning("vt100 keypad map incomplete:%s", show); }}/* * Returns the expected number of parameters for the given capability. */static intexpected_params(const char *name){ /* *INDENT-OFF* */ static const struct { const char *name; int count; } table[] = { { "S0", 1 }, /* 'screen' extension */ { "birep", 2 }, { "chr", 1 }, { "colornm", 1 }, { "cpi", 1 }, { "csnm", 1 }, { "csr", 2 }, { "cub", 1 }, { "cud", 1 }, { "cuf", 1 }, { "cup", 2 }, { "cuu", 1 }, { "cvr", 1 }, { "cwin", 5 }, { "dch", 1 }, { "defc", 3 }, { "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 }, { "rcsd", 1 }, { "rep", 2 }, { "rin", 1 }, { "sclk", 3 }, { "scp", 1 }, { "scs", 1 }, { "scsd", 2 }, { "setab", 1 }, { "setaf", 1 }, { "setb", 1 }, { "setcolor", 1 }, { "setf", 1 }, { "sgr", 9 }, { "sgr1", 6 }, { "slength", 1 }, { "slines", 1 }, { "smgbp", 1 }, /* 2 if smgtp is not given */ { "smglp", 1 }, { "smglr", 2 }, { "smgrp", 1 }, { "smgtb", 2 }, { "smgtp", 1 }, { "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 voidcheck_params(TERMTYPE * tp, const char *name, char *value){ int expected = expected_params(name); int actual = 0; int n; bool params[10]; char *s = value;#ifdef set_top_margin_parm if (!strcmp(name, "smgbp") && set_top_margin_parm == 0) expected = 2;#endif 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); } }}static char *skip_delay(char *s){ while (*s == '/' || isdigit(UChar(*s))) ++s; return s;}/* * 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 * sanity check. */static boolsimilar_sgr(int num, char *a, char *b){ static const char *names[] = { "none" ,"standout" ,"underline" ,"reverse" ,"blink" ,"dim" ,"bold" ,"invis" ,"protect" ,"altcharset" }; 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] == '<') { _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), _nc_visbuf2(2, base_b), _nc_visbuf2(3, b)); } return FALSE; } else if (delaying) { a = skip_delay(a); b = skip_delay(b); } else { a++; } } switch (*a) { case '$': if (delaying == 0) delaying = 1; break; case '<': if (delaying == 1) delaying = 2; break; default: delaying = 0; break; } a++; b++; } return TRUE;}static voidcheck_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); tparm_errs += _nc_tparm_err; if (test != 0) { if (PRESENT(cap)) { if (!similar_sgr(num, test, cap)) { _nc_warning("%s differs from sgr(%d)\n\t%s=%s\n\tsgr(%d)=%s", name, num, name, _nc_visbuf2(1, cap), num, _nc_visbuf2(2, test)); } } else if (strcmp(test, zero)) { _nc_warning("sgr(%d) present, but not %s", num, name); } } else if (PRESENT(cap)) { _nc_warning("sgr(%d) missing, but %s present", num, name); }}#define CHECK_SGR(num,name) check_sgr(tp, zero, num, name, #name)/* other sanity-checks (things that we don't want in the normal * logic that reads a terminfo entry) */static voidcheck_termtype(TERMTYPE * tp){ bool conflict = FALSE; unsigned j, k; char fkeys[STRCOUNT]; /* * A terminal entry may contain more than one keycode assigned to * a given string (e.g., KEY_END and KEY_LL). But curses will only * return one (the last one assigned). */ memset(fkeys, 0, sizeof(fkeys)); for (j = 0; _nc_tinfo_fkeys[j].code; j++) { char *a = tp->Strings[_nc_tinfo_fkeys[j].offset]; bool first = TRUE; if (!VALID_STRING(a)) continue; for (k = j + 1; _nc_tinfo_fkeys[k].code; k++) { char *b = tp->Strings[_nc_tinfo_fkeys[k].offset]; if (!VALID_STRING(b) || fkeys[k]) continue; if (!strcmp(a, b)) { fkeys[j] = 1; fkeys[k] = 1; if (first) { if (!conflict) { _nc_warning("Conflicting key definitions (using the last)"); 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); } check_acs(tp); check_colors(tp); check_keypad(tp); /* * These may be mismatched because the terminal description relies on * restoring the cursor visibility by resetting it. */ ANDMISSING(cursor_invisible, cursor_normal); ANDMISSING(cursor_visible, cursor_normal); if (PRESENT(cursor_visible) && PRESENT(cursor_normal) && !strcmp(cursor_visible, cursor_normal)) _nc_warning("cursor_visible is same as cursor_normal"); /* * From XSI & O'Reilly, we gather that sc/rc are required if csr is * given, because the cursor position after the scrolling operation is * performed is undefined. */ ANDMISSING(change_scroll_region, save_cursor); ANDMISSING(change_scroll_region, restore_cursor); tparm_errs = 0; if (PRESENT(set_attributes)) { char *zero = tparm(set_attributes, 0, 0, 0, 0, 0, 0, 0, 0, 0); zero = strdup(zero); CHECK_SGR(1, enter_standout_mode); CHECK_SGR(2, enter_underline_mode); CHECK_SGR(3, enter_reverse_mode); CHECK_SGR(4, enter_blink_mode); CHECK_SGR(5, enter_dim_mode); CHECK_SGR(6, enter_bold_mode); CHECK_SGR(7, enter_secure_mode); CHECK_SGR(8, enter_protected_mode); CHECK_SGR(9, enter_alt_charset_mode); free(zero); if (tparm_errs) _nc_warning("stack error in sgr string"); } /* * Some standard applications (e.g., vi) and some non-curses * applications (e.g., jove) get confused if we have both ich1 and * smir/rmir. Let's be nice and warn about that, too, even though * ncurses handles it. */ if ((PRESENT(enter_insert_mode) || PRESENT(exit_insert_mode)) && PRESENT(parm_ich)) { _nc_warning("non-curses applications may be confused by ich1 with smir/rmir"); } /* * Finally, do the non-verbose checks */ if (save_check_termtype != 0) save_check_termtype(tp);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -