X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Fcomp_scan.c;h=b2072577a49989c50d5922e2dbf51659a6e85d3a;hp=17c42df59aa91d5d794310f5cab22a8a7156f836;hb=fe43d506ce08d1deef9e9e5a6d5fd4f9c9c32e1d;hpb=03f728e5bb3630a54fffc4a2ff2f8dbfcce9088e diff --git a/ncurses/tinfo/comp_scan.c b/ncurses/tinfo/comp_scan.c index 17c42df5..b2072577 100644 --- a/ncurses/tinfo/comp_scan.c +++ b/ncurses/tinfo/comp_scan.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. * + * Copyright (c) 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 * @@ -50,7 +50,7 @@ #include #include -MODULE_ID("$Id: comp_scan.c,v 1.94 2011/10/22 15:46:43 tom Exp $") +MODULE_ID("$Id: comp_scan.c,v 1.108 2017/08/25 22:57:21 tom Exp $") /* * Maximum length of string capability we'll accept before raising an error. @@ -128,14 +128,19 @@ _nc_reset_input(FILE *fp, char *buf) * Returns the final nonblank character on the current input buffer */ static int -last_char(void) +last_char(int from_end) { size_t len = strlen(bufptr); + int result = 0; + while (len--) { - if (!isspace(UChar(bufptr[len]))) - return bufptr[len]; + if (!isspace(UChar(bufptr[len]))) { + if (from_end < (int) len) + result = bufptr[(int) len - from_end]; + break; + } } - return 0; + return result; } /* @@ -163,6 +168,8 @@ next_char(void) if (result != 0) { FreeAndNull(result); FreeAndNull(pushname); + bufptr = 0; + bufstart = 0; allocated = 0; } /* @@ -184,19 +191,19 @@ next_char(void) * quite hard to get completely right. Try it and see. If you * succeed, don't forget to hack push_back() correspondingly. */ - size_t used; size_t len; do { + size_t used = 0; bufstart = 0; - used = 0; do { if (used + (LEXBUFSIZ / 4) >= allocated) { allocated += (allocated + LEXBUFSIZ); result = typeRealloc(char, allocated, result); if (result == 0) return (EOF); - bufstart = result; + if (bufstart) + bufstart = result; } if (used == 0) _nc_curr_file_pos = ftell(yyin); @@ -213,10 +220,12 @@ next_char(void) } } else { if (used != 0) - strcat(result, "\n"); + _nc_STRCAT(result, "\n", allocated); } if ((bufptr = bufstart) != 0) { used = strlen(bufptr); + if (used == 0) + return (EOF); while (iswhite(*bufptr)) { if (*bufptr == '\t') { _nc_curr_col = (_nc_curr_col | 7) + 1; @@ -340,13 +349,13 @@ _nc_get_token(bool silent) { static const char terminfo_punct[] = "@%&*!#"; - char *after_list; - char *after_name; + char *after_name; /* after primary name */ + char *after_list; /* after primary and alias list */ char *numchk; char *tok_ptr; char *s; char numbuf[80]; - int ch; + int ch, c0, c1; int dot_flag = FALSE; int type; long number; @@ -374,7 +383,7 @@ _nc_get_token(bool silent) if (end_of_stream()) { yyin = 0; - next_char(); /* frees its allocated memory */ + (void) next_char(); /* frees its allocated memory */ if (tok_buf != 0) { if (_nc_curr_token.tk_name == tok_buf) _nc_curr_token.tk_name = 0; @@ -426,7 +435,7 @@ _nc_get_token(bool silent) #if NCURSES_EXT_FUNCS && !(ch == '.' && _nc_disable_period) #endif - && !strchr(terminfo_punct, (char) ch)) { + && ((strchr) (terminfo_punct, (char) ch) == 0)) { if (!silent) _nc_warning("Illegal character (expected alphanumeric or %s) - '%s'", terminfo_punct, unctrl(UChar(ch))); @@ -459,7 +468,7 @@ _nc_get_token(bool silent) after_list = tok_ptr; if (after_name == 0) after_name = tok_ptr; - } else if (ch == ':' && last_char() != ',') { + } else if (ch == ':' && last_char(0) != ',') { _nc_syntax = SYN_TERMCAP; separator = ':'; break; @@ -473,12 +482,64 @@ _nc_get_token(bool silent) if (after_name == 0) break; /* - * If we see a comma, we assume this is terminfo unless we - * subsequently run into a colon. But we don't stop - * looking for a colon until hitting a newline. This - * allows commas to be embedded in description fields of - * either syntax. + * We saw a comma, but are not entirely sure this is + * terminfo format, since we can still be parsing the + * description field (for either syntax). + * + * A properly formatted termcap line ends with either a + * colon, or a backslash after a colon. It is possible + * to have a backslash in the middle of a capability, but + * then there would be no leading whitespace on the next + * line - something we want to discourage. */ + c0 = last_char(0); + c1 = last_char(1); + if (c1 != ':' && c0 != '\\' && c0 != ':') { + bool capability = FALSE; + + /* + * Since it is not termcap, assume the line is terminfo + * format. However, the comma can be embedded in a + * description field. It also can be a separator + * between a description field and a capability. + * + * Improve the guess by checking if the next word after + * the comma does not look like a capability. In that + * case, extend the description past the comma. + */ + for (s = bufptr; isspace(UChar(*s)); ++s) { + ; + } + if (islower(UChar(*s))) { + char *name = s; + while (isalnum(UChar(*s))) { + ++s; + } + if (*s == '#' || *s == '=' || *s == '@') { + /* + * Checking solely with syntax allows us to + * support extended capabilities with string + * values. + */ + capability = TRUE; + } else if (*s == ',') { + c0 = *s; + *s = '\0'; + /* + * Otherwise, we can handle predefined boolean + * capabilities, still aided by syntax. + */ + if (_nc_find_entry(name, + _nc_get_hash_table(FALSE))) { + capability = TRUE; + } + *s = (char) c0; + } + } + if (capability) { + break; + } + } } else ch = eat_escaped_newline(ch); @@ -611,7 +672,15 @@ _nc_get_token(bool silent) if (numchk == numbuf) _nc_warning("no value given for `%s'", tok_buf); if ((*numchk != '\0') || (ch != separator)) - _nc_warning("Missing separator"); + _nc_warning("Missing separator for `%s'", tok_buf); + if (number < 0) + _nc_warning("value of `%s' cannot be negative", tok_buf); + if (number > MAX_OF_TYPE(NCURSES_INT2)) { + _nc_warning("limiting value of `%s' from %#lx to %#x", + tok_buf, + number, MAX_OF_TYPE(NCURSES_INT2)); + number = MAX_OF_TYPE(NCURSES_INT2); + } } _nc_curr_token.tk_name = tok_buf; _nc_curr_token.tk_valnumber = (int) number; @@ -752,8 +821,6 @@ _nc_trans_string(char *ptr, char *last) } if (c == '?' && (_nc_syntax != SYN_TERMCAP)) { *(ptr++) = '\177'; - if (_nc_tracing) - _nc_warning("Allow ^? as synonym for \\177"); } else { if ((c &= 037) == 0) c = 128; @@ -766,8 +833,6 @@ _nc_trans_string(char *ptr, char *last) if (c == EOF) _nc_err_abort(MSG_NO_INPUTS); -#define isoctal(c) ((c) >= '0' && (c) <= '7') - if (isoctal(c) || (strict_bsd && isdigit(c))) { number = c - '0'; for (i = 0; i < 2; i++) { @@ -932,10 +997,8 @@ _nc_push_token(int tokclass) NCURSES_EXPORT(void) _nc_panic_mode(char ch) { - int c; - for (;;) { - c = next_char(); + int c = next_char(); if (c == ch) return; if (c == EOF)