X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=progs%2Ftic.c;h=739e7ed71ac4aa7fab979c6fdca22d176391e4a8;hp=3d894acd2d406b850c465268400a2b6c2933c31b;hb=c120fddebe9e9c1e2b29dbd744a6b1d03652bf8b;hpb=3996fe0bf797f113d6abc4329cc869951735a4d8 diff --git a/progs/tic.c b/progs/tic.c index 3d894acd..739e7ed7 100644 --- a/progs/tic.c +++ b/progs/tic.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2008,2009 Free Software Foundation, Inc. * + * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -44,7 +44,7 @@ #include #include -MODULE_ID("$Id: tic.c,v 1.139 2009/12/12 17:30:12 Nicholas.Marriott Exp $") +MODULE_ID("$Id: tic.c,v 1.150 2011/05/21 18:15:45 tom Exp $") const char *_nc_progname = "tic"; @@ -221,7 +221,7 @@ write_it(ENTRY * ep) } _nc_set_type(_nc_first_name(ep->tterm.term_names)); - _nc_curr_line = ep->startline; + _nc_curr_line = (int) ep->startline; _nc_write_entry(&ep->tterm); } @@ -339,20 +339,23 @@ put_translate(int c) static char * stripped(char *src) { + char *dst = 0; + while (isspace(UChar(*src))) src++; + if (*src != '\0') { - char *dst; size_t len; - if ((dst = strdup(src)) == NULL) + if ((dst = strdup(src)) == NULL) { failed("strdup"); - len = strlen(dst); - while (--len != 0 && isspace(UChar(dst[len]))) - dst[len] = '\0'; - return dst; + } else { + len = strlen(dst); + while (--len != 0 && isspace(UChar(dst[len]))) + dst[len] = '\0'; + } } - return 0; + return dst; } static FILE * @@ -472,7 +475,8 @@ int main(int argc, char *argv[]) { char my_tmpname[PATH_MAX]; - int v_opt = -1, debug_level; + int v_opt = -1; + unsigned debug_level; int smart_defaults = TRUE; char *termcap; ENTRY *qp; @@ -615,7 +619,7 @@ main(int argc, char *argv[]) last_opt = this_opt; } - debug_level = (v_opt > 0) ? v_opt : (v_opt == 0); + debug_level = (unsigned) ((v_opt > 0) ? v_opt : (v_opt == 0)); set_trace_level(debug_level); if (_nc_tracing) { @@ -747,7 +751,7 @@ main(int argc, char *argv[]) for_entry_list(qp) { if (matches(namelst, qp->tterm.term_names)) { - int j = qp->cend - qp->cstart; + long j = qp->cend - qp->cstart; int len = 0; /* this is in case infotocap() generates warnings */ @@ -761,9 +765,10 @@ main(int argc, char *argv[]) put_translate(fgetc(tmp_fp)); } + repair_acsc(&qp->tterm); dump_entry(&qp->tterm, suppress_untranslatable, limited, numbers, NULL); - for (j = 0; j < (int) qp->nuses; j++) + for (j = 0; j < (long) qp->nuses; j++) dump_uses(qp->uses[j].name, !capdump); len = show_entry(); if (debug_level != 0 && !limited) @@ -911,22 +916,172 @@ keypad_final(const char *string) return result; } -static int +static long keypad_index(const char *string) { char *test; const char *list = "PQRSwxymtuvlqrsPpn"; /* app-keypad except "Enter" */ int ch; - int result = -1; + long result = -1; if ((ch = keypad_final(string)) != '\0') { test = strchr(list, ch); if (test != 0) - result = (test - list); + result = (long) (test - list); } return result; } +/* + * list[] is down, up, left, right + * "left" may be ^H rather than \E[D + * "down" may be ^J rather than \E[B + * But up/right are generally consistently escape sequences for ANSI terminals. + */ +static void +check_ansi_cursor(char *list[4]) +{ + int j, k; + int want; + size_t prefix = 0; + size_t suffix; + bool skip[4]; + bool repeated = FALSE; + + for (j = 0; j < 4; ++j) { + skip[j] = FALSE; + for (k = 0; k < j; ++k) { + if (j != k + && !strcmp(list[j], list[k])) { + char *value = _nc_tic_expand(list[k], TRUE, 0); + _nc_warning("repeated cursor control %s\n", value); + repeated = TRUE; + } + } + } + if (!repeated) { + char *up = list[1]; + + if (UChar(up[0]) == '\033') { + if (up[1] == '[') { + prefix = 2; + } else { + prefix = 1; + } + } else if (UChar(up[0]) == UChar('\233')) { + prefix = 1; + } + if (prefix) { + suffix = prefix; + while (up[suffix] && isdigit(UChar(up[suffix]))) + ++suffix; + } + if (prefix && up[suffix] == 'A') { + skip[1] = TRUE; + if (!strcmp(list[0], "\n")) + skip[0] = TRUE; + if (!strcmp(list[2], "\b")) + skip[2] = TRUE; + + for (j = 0; j < 4; ++j) { + if (skip[j] || strlen(list[j]) == 1) + continue; + if (memcmp(list[j], up, prefix)) { + char *value = _nc_tic_expand(list[j], TRUE, 0); + _nc_warning("inconsistent prefix for %s\n", value); + continue; + } + if (strlen(list[j]) < suffix) { + char *value = _nc_tic_expand(list[j], TRUE, 0); + _nc_warning("inconsistent length for %s, expected %d\n", + value, (int) suffix + 1); + continue; + } + want = "BADC"[j]; + if (list[j][suffix] != want) { + char *value = _nc_tic_expand(list[j], TRUE, 0); + _nc_warning("inconsistent suffix for %s, expected %c, have %c\n", + value, want, list[j][suffix]); + } + } + } + } +} + +#define EXPECTED(name) if (!PRESENT(name)) _nc_warning("expected " #name) + +static void +check_cursor(TERMTYPE *tp) +{ + int count; + char *list[4]; + + /* if we have a parameterized form, then the non-parameterized is easy */ + ANDMISSING(parm_down_cursor, cursor_down); + ANDMISSING(parm_up_cursor, cursor_up); + ANDMISSING(parm_left_cursor, cursor_left); + ANDMISSING(parm_right_cursor, cursor_right); + + /* Given any of a set of cursor movement, the whole set should be present. + * Technically this is not true (we could use cursor_address to fill in + * unsupported controls), but it is likely. + */ + count = 0; + if (PRESENT(parm_down_cursor)) { + list[count++] = parm_down_cursor; + } + if (PRESENT(parm_up_cursor)) { + list[count++] = parm_up_cursor; + } + if (PRESENT(parm_left_cursor)) { + list[count++] = parm_left_cursor; + } + if (PRESENT(parm_right_cursor)) { + list[count++] = parm_right_cursor; + } + if (count == 4) { + check_ansi_cursor(list); + } else if (count != 0) { + EXPECTED(parm_down_cursor); + EXPECTED(parm_up_cursor); + EXPECTED(parm_left_cursor); + EXPECTED(parm_right_cursor); + } + + count = 0; + if (PRESENT(cursor_down)) { + list[count++] = cursor_down; + } + if (PRESENT(cursor_up)) { + list[count++] = cursor_up; + } + if (PRESENT(cursor_left)) { + list[count++] = cursor_left; + } + if (PRESENT(cursor_right)) { + list[count++] = cursor_right; + } + if (count == 4) { + check_ansi_cursor(list); + } else if (count != 0) { + count = 0; + if (PRESENT(cursor_down) && strcmp(cursor_down, "\n")) + ++count; + if (PRESENT(cursor_left) && strcmp(cursor_left, "\b")) + ++count; + if (PRESENT(cursor_up) && strlen(cursor_up) > 1) + ++count; + if (PRESENT(cursor_right) && strlen(cursor_right) > 1) + ++count; + if (count) { + EXPECTED(cursor_down); + EXPECTED(cursor_up); + EXPECTED(cursor_left); + EXPECTED(cursor_right); + } + } +} + #define MAX_KP 5 /* * Do a quick sanity-check for vt100-style keypads to see if the 5-key keypad @@ -943,11 +1098,11 @@ check_keypad(TERMTYPE *tp) VALID_STRING(key_c1) && VALID_STRING(key_c3)) { char final[MAX_KP + 1]; - int list[MAX_KP]; + long list[MAX_KP]; int increase = 0; int j, k, kk; - int last; - int test; + long last; + long test; final[0] = keypad_final(key_a1); final[1] = keypad_final(key_a3); @@ -1036,6 +1191,32 @@ check_keypad(TERMTYPE *tp) } } +static void +check_printer(TERMTYPE *tp) +{ + PAIRED(enter_doublewide_mode, exit_doublewide_mode); + PAIRED(enter_italics_mode, exit_italics_mode); + PAIRED(enter_leftward_mode, exit_leftward_mode); + PAIRED(enter_micro_mode, exit_micro_mode); + PAIRED(enter_shadow_mode, exit_shadow_mode); + PAIRED(enter_subscript_mode, exit_subscript_mode); + PAIRED(enter_superscript_mode, exit_superscript_mode); + PAIRED(enter_upward_mode, exit_upward_mode); + + ANDMISSING(start_char_set_def, stop_char_set_def); + + /* if we have a parameterized form, then the non-parameterized is easy */ + ANDMISSING(set_bottom_margin_parm, set_bottom_margin); + ANDMISSING(set_left_margin_parm, set_left_margin); + ANDMISSING(set_right_margin_parm, set_right_margin); + ANDMISSING(set_top_margin_parm, set_top_margin); + + ANDMISSING(parm_down_micro, micro_down); + ANDMISSING(parm_left_micro, micro_left); + ANDMISSING(parm_right_micro, micro_right); + ANDMISSING(parm_up_micro, micro_up); +} + /* * Returns the expected number of parameters for the given capability. */ @@ -1272,6 +1453,8 @@ similar_sgr(int num, char *a, char *b) } else if (delaying) { a = skip_delay(a); b = skip_delay(b); + } else if ((*b == '0' || (*b == ';')) && *a == 'm') { + b++; } else { a++; } @@ -1347,7 +1530,7 @@ show_where(unsigned level) if (_nc_tracing >= DEBUG_LEVEL(level)) { char my_name[256]; _nc_get_type(my_name); - fprintf(stderr, "\"%s\", line %d, '%s' ", + _tracef("\"%s\", line %d, '%s'", _nc_get_source(), _nc_curr_line, my_name); } @@ -1410,12 +1593,14 @@ check_termtype(TERMTYPE *tp, bool literal) 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_params(tp, ExtStrname(tp, (int) j, strnames), a); } check_acs(tp); check_colors(tp); + check_cursor(tp); check_keypad(tp); + check_printer(tp); /* * These may be mismatched because the terminal description relies on @@ -1436,6 +1621,11 @@ check_termtype(TERMTYPE *tp, bool literal) ANDMISSING(change_scroll_region, save_cursor); ANDMISSING(change_scroll_region, restore_cursor); + /* + * If we can clear tabs, we should be able to initialize them. + */ + ANDMISSING(clear_all_tabs, set_tab); + if (PRESENT(set_attributes)) { char *zero = 0;