X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Fparse_entry.c;h=a77cd0b2120958da1b2ccc925111dab2aee3caf6;hp=bbbfcb270ac424e7f697a79d85c887ee9fc05ece;hb=deb0d07e8eb4803b9e9653359eab17a30d04369d;hpb=5c2245b6fc619f8d96ce940281dfbf13b5b8900b diff --git a/ncurses/tinfo/parse_entry.c b/ncurses/tinfo/parse_entry.c index bbbfcb27..a77cd0b2 100644 --- a/ncurses/tinfo/parse_entry.c +++ b/ncurses/tinfo/parse_entry.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 1998-2016,2017 Free Software Foundation, Inc. * + * Copyright 2018-2020,2021 Thomas E. Dickey * + * Copyright 1998-2016,2017 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 * @@ -47,7 +48,7 @@ #include #include -MODULE_ID("$Id: parse_entry.c,v 1.91 2017/08/26 16:13:34 tom Exp $") +MODULE_ID("$Id: parse_entry.c,v 1.102 2021/09/04 10:54:35 tom Exp $") #ifdef LINT static short const parametrized[] = @@ -63,7 +64,7 @@ static struct name_table_entry const *lookup_fullname(const char *name); #if NCURSES_XNAMES static struct name_table_entry const * -_nc_extend_names(ENTRY * entryp, char *name, int token_type) +_nc_extend_names(ENTRY * entryp, const char *name, int token_type) { static struct name_table_entry temp; TERMTYPE2 *tp = &(entryp->tterm); @@ -178,6 +179,39 @@ _nc_extend_names(ENTRY * entryp, char *name, int token_type) return &temp; } + +static const char * +usertype2s(int mask) +{ + const char *result = "unknown"; + if (mask & (1 << BOOLEAN)) { + result = "boolean"; + } else if (mask & (1 << NUMBER)) { + result = "number"; + } else if (mask & (1 << STRING)) { + result = "string"; + } + return result; +} + +static bool +expected_type(const char *name, int token_type, bool silent) +{ + struct user_table_entry const *entry = _nc_find_user_entry(name); + bool result = TRUE; + if ((entry != 0) && (token_type != CANCEL)) { + int have_type = (1 << token_type); + if (!(entry->ute_type & have_type)) { + if (!silent) + _nc_warning("expected %s-type for %s, have %s", + usertype2s(entry->ute_type), + name, + usertype2s(have_type)); + result = FALSE; + } + } + return result; +} #endif /* NCURSES_XNAMES */ static bool @@ -217,7 +251,7 @@ valid_entryname(const char *name) { bad_tc_usage = TRUE; \ _nc_warning("Legacy termcap allows only a trailing tc= clause"); } -#define MAX_NUMBER 0x7fff /* positive shorts only */ +#define MAX_NUMBER MAX_OF_TYPE(NCURSES_INT2) NCURSES_EXPORT(int) _nc_parse_entry(ENTRY * entryp, int literal, bool silent) @@ -328,7 +362,7 @@ _nc_parse_entry(ENTRY * entryp, int literal, bool silent) _nc_get_hash_table(_nc_syntax)); /* - * Our kluge to handle aliasing. The reason it's done + * Our kluge to handle aliasing. The reason it is done * this ugly way, with a linear search, is so the hashing * machinery doesn't have to be made really complicated * (also we get better warnings this way). No point in @@ -385,12 +419,20 @@ _nc_parse_entry(ENTRY * entryp, int literal, bool silent) * define a name based on its context. */ if (entry_ptr == NOTFOUND - && _nc_user_definable - && (entry_ptr = _nc_extend_names(entryp, - _nc_curr_token.tk_name, - token_type)) != 0) { - if (_nc_tracing >= DEBUG_LEVEL(1)) - _nc_warning("extended capability '%s'", _nc_curr_token.tk_name); + && _nc_user_definable) { + if (expected_type(_nc_curr_token.tk_name, token_type, silent)) { + if ((entry_ptr = _nc_extend_names(entryp, + _nc_curr_token.tk_name, + token_type)) != 0) { + if (_nc_tracing >= DEBUG_LEVEL(1)) { + _nc_warning("extended capability '%s'", + _nc_curr_token.tk_name); + } + } + } else { + /* ignore it: we have already printed error message */ + continue; + } } #endif /* NCURSES_XNAMES */ @@ -489,20 +531,27 @@ _nc_parse_entry(ENTRY * entryp, int literal, bool silent) break; case NUMBER: +#if !NCURSES_EXT_NUMBERS if (_nc_curr_token.tk_valnumber > MAX_NUMBER) { entryp->tterm.Numbers[entry_ptr->nte_index] = MAX_NUMBER; - } else { + } else +#endif + { entryp->tterm.Numbers[entry_ptr->nte_index] = - (short) _nc_curr_token.tk_valnumber; + (NCURSES_INT2) _nc_curr_token.tk_valnumber; } break; case STRING: ptr = _nc_curr_token.tk_valstring; - if (_nc_syntax == SYN_TERMCAP) + if (_nc_syntax == SYN_TERMCAP) { + int n = entry_ptr->nte_index; ptr = _nc_captoinfo(_nc_curr_token.tk_name, ptr, - parametrized[entry_ptr->nte_index]); + (n < (int) SIZEOF(parametrized)) + ? parametrized[n] + : 0); + } entryp->tterm.Strings[entry_ptr->nte_index] = _nc_save_str(ptr); break; @@ -543,9 +592,11 @@ _nc_parse_entry(ENTRY * entryp, int literal, bool silent) * Otherwise, look for a base entry that will already * have picked up defaults via translation. */ - for (i = 0; i < entryp->nuses; i++) - if (!strchr((char *) entryp->uses[i].name, '+')) + for (i = 0; i < entryp->nuses; i++) { + if (entryp->uses[i].name != 0 + && !strchr(entryp->uses[i].name, '+')) has_base_entry = TRUE; + } } postprocess_termcap(&entryp->tterm, has_base_entry); @@ -608,12 +659,12 @@ _nc_capcmp(const char *s, const char *t) } static void -append_acs0(string_desc * dst, int code, int src) +append_acs0(string_desc * dst, int code, char *src, size_t off) { - if (src != 0) { + if (src != 0 && off < strlen(src)) { char temp[3]; temp[0] = (char) code; - temp[1] = (char) src; + temp[1] = src[off]; temp[2] = 0; _nc_safe_strcat(dst, temp); } @@ -623,7 +674,7 @@ static void append_acs(string_desc * dst, int code, char *src) { if (VALID_STRING(src) && strlen(src) == 1) { - append_acs0(dst, code, *src); + append_acs0(dst, code, src, 0); } } @@ -878,7 +929,7 @@ postprocess_termcap(TERMTYPE2 *tp, bool has_base) if (tp->Strings[to_ptr->nte_index]) { const char *s = tp->Strings[from_ptr->nte_index]; const char *t = tp->Strings[to_ptr->nte_index]; - /* There's no point in warning about it if it's the same + /* There's no point in warning about it if it is the same * string; that's just an inefficiency. */ if (VALID_STRING(s) && VALID_STRING(t) && strcmp(s, t) != 0) @@ -992,17 +1043,17 @@ postprocess_terminfo(TERMTYPE2 *tp) _nc_str_init(&result, buf2, sizeof(buf2)); _nc_safe_strcat(&result, acs_chars); - append_acs0(&result, 'l', box_chars_1[0]); /* ACS_ULCORNER */ - append_acs0(&result, 'q', box_chars_1[1]); /* ACS_HLINE */ - append_acs0(&result, 'k', box_chars_1[2]); /* ACS_URCORNER */ - append_acs0(&result, 'x', box_chars_1[3]); /* ACS_VLINE */ - append_acs0(&result, 'j', box_chars_1[4]); /* ACS_LRCORNER */ - append_acs0(&result, 'm', box_chars_1[5]); /* ACS_LLCORNER */ - append_acs0(&result, 'w', box_chars_1[6]); /* ACS_TTEE */ - append_acs0(&result, 'u', box_chars_1[7]); /* ACS_RTEE */ - append_acs0(&result, 'v', box_chars_1[8]); /* ACS_BTEE */ - append_acs0(&result, 't', box_chars_1[9]); /* ACS_LTEE */ - append_acs0(&result, 'n', box_chars_1[10]); /* ACS_PLUS */ + append_acs0(&result, 'l', box_chars_1, 0); /* ACS_ULCORNER */ + append_acs0(&result, 'q', box_chars_1, 1); /* ACS_HLINE */ + append_acs0(&result, 'k', box_chars_1, 2); /* ACS_URCORNER */ + append_acs0(&result, 'x', box_chars_1, 3); /* ACS_VLINE */ + append_acs0(&result, 'j', box_chars_1, 4); /* ACS_LRCORNER */ + append_acs0(&result, 'm', box_chars_1, 5); /* ACS_LLCORNER */ + append_acs0(&result, 'w', box_chars_1, 6); /* ACS_TTEE */ + append_acs0(&result, 'u', box_chars_1, 7); /* ACS_RTEE */ + append_acs0(&result, 'v', box_chars_1, 8); /* ACS_BTEE */ + append_acs0(&result, 't', box_chars_1, 9); /* ACS_LTEE */ + append_acs0(&result, 'n', box_chars_1, 10); /* ACS_PLUS */ if (buf2[0]) { acs_chars = _nc_save_str(buf2);