📄 comp_scan.c
字号:
} else if (ch == ',') { _nc_syntax = SYN_TERMINFO; separator = ','; /* * If we did not see a '|', then we found a name with no * aliases or description. */ 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. */ } else ch = eat_escaped_newline(ch); *ptr++ = ch; } ptr[0] = '\0'; if (_nc_syntax == ERR) { /* * Grrr...what we ought to do here is barf, complaining that * the entry is malformed. But because a couple of name fields * in the 8.2 termcap file end with |\, we just have to assume * it's termcap syntax. */ _nc_syntax = SYN_TERMCAP; separator = ':'; } else if (_nc_syntax == SYN_TERMINFO) { /* throw away trailing /, *$/ */ for (--ptr; iswhite(*ptr) || *ptr == ','; ptr--) continue; ptr[1] = '\0'; } /* * This is the soonest we have the terminal name fetched. Set up * for following warning messages. If there's no '|', then there * is no description. */ if (after_name != 0) { ch = *after_name; *after_name = '\0'; _nc_set_type(buffer); *after_name = ch; } /* * Compute the boundary between the aliases and the description * field for syntax-checking purposes. */ if (after_list != 0) { if (!silent) { if (*after_list == '\0') _nc_warning("empty longname field"); else if (strchr(after_list, ' ') == 0) _nc_warning("older tic versions may treat the description field as an alias"); } } else { after_list = buffer + strlen(buffer); DEBUG(1, ("missing description")); } /* * Whitespace in a name field other than the long name can confuse * rdist and some termcap tools. Slashes are a no-no. Other * special characters can be dangerous due to shell expansion. */ for (s = buffer; s < after_list; ++s) { if (isspace(UChar(*s))) { if (!silent) _nc_warning("whitespace in name or alias field"); break; } else if (*s == '/') { if (!silent) _nc_warning("slashes aren't allowed in names or aliases"); break; } else if (strchr("$[]!*?", *s)) { if (!silent) _nc_warning("dubious character `%c' in name or alias field", *s); break; } } _nc_curr_token.tk_name = buffer; type = NAMES; } else { if (had_newline && _nc_syntax == SYN_TERMCAP) { _nc_warning("Missing backslash before newline"); had_newline = FALSE; } while ((ch = next_char()) != EOF) { if (!isalnum(UChar(ch))) { if (_nc_syntax == SYN_TERMINFO) { if (ch != '_') break; } else { /* allow ';' for "k;" */ if (ch != ';') break; } } *(ptr++) = ch; } *ptr++ = '\0'; switch (ch) { case ',': case ':': if (ch != separator) _nc_err_abort("Separator inconsistent with syntax"); _nc_curr_token.tk_name = buffer; type = BOOLEAN; break; case '@': if ((ch = next_char()) != separator && !silent) _nc_warning("Missing separator after `%s', have %s", buffer, unctrl((chtype) ch)); _nc_curr_token.tk_name = buffer; type = CANCEL; break; case '#': found = 0; while (isalnum(ch = next_char())) { numbuf[found++] = ch; if (found >= sizeof(numbuf) - 1) break; } numbuf[found] = '\0'; number = strtol(numbuf, &numchk, 0); if (!silent) { if (numchk == numbuf) _nc_warning("no value given for `%s'", buffer); if ((*numchk != '\0') || (ch != separator)) _nc_warning("Missing separator"); } _nc_curr_token.tk_name = buffer; _nc_curr_token.tk_valnumber = number; type = NUMBER; break; case '=': ch = _nc_trans_string(ptr, buffer + MAX_ENTRY_SIZE); if (!silent && ch != separator) _nc_warning("Missing separator"); _nc_curr_token.tk_name = buffer; _nc_curr_token.tk_valstring = ptr; type = STRING; break; case EOF: type = EOF; break; default: /* just to get rid of the compiler warning */ type = UNDEF; if (!silent) _nc_warning("Illegal character - '%s'", unctrl((chtype) ch)); } } /* end else (first_column == FALSE) */ } /* end else (ch != EOF) */ end_of_token:#ifdef TRACE if (dot_flag == TRUE) DEBUG(8, ("Commented out ")); if (_nc_tracing >= DEBUG_LEVEL(8)) { _tracef("parsed %d.%d to %d.%d", old_line, old_col, _nc_curr_line, _nc_curr_col); } if (_nc_tracing >= DEBUG_LEVEL(7)) { switch (type) { case BOOLEAN: _tracef("Token: Boolean; name='%s'", _nc_curr_token.tk_name); break; case NUMBER: _tracef("Token: Number; name='%s', value=%d", _nc_curr_token.tk_name, _nc_curr_token.tk_valnumber); break; case STRING: _tracef("Token: String; name='%s', value=%s", _nc_curr_token.tk_name, _nc_visbuf(_nc_curr_token.tk_valstring)); break; case CANCEL: _tracef("Token: Cancel; name='%s'", _nc_curr_token.tk_name); break; case NAMES: _tracef("Token: Names; value='%s'", _nc_curr_token.tk_name); break; case EOF: _tracef("Token: End of file"); break; default: _nc_warning("Bad token type"); } }#endif if (dot_flag == TRUE) /* if commented out, use the next one */ type = _nc_get_token(silent); DEBUG(3, ("token: `%s', class %d", ((_nc_curr_token.tk_name != 0) ? _nc_curr_token.tk_name : "<null>"), type)); return (type);}/* * char * trans_string(ptr) * * Reads characters using next_char() until encountering a separator, nl, * or end-of-file. The returned value is the character which caused * reading to stop. The following translations are done on the input: * * ^X goes to ctrl-X (i.e. X & 037) * {\E,\n,\r,\b,\t,\f} go to * {ESCAPE,newline,carriage-return,backspace,tab,formfeed} * {\^,\\} go to {carat,backslash} * \ddd (for ddd = up to three octal digits) goes to the character ddd * * \e == \E * \0 == \200 * */NCURSES_EXPORT(int)_nc_trans_string(char *ptr, char *last){ int count = 0; int number = 0; int i, c; chtype ch, last_ch = '\0'; bool ignored = FALSE; bool long_warning = FALSE; while ((ch = c = next_char()) != (chtype) separator && c != EOF) { if (ptr == (last - 1)) break; if ((_nc_syntax == SYN_TERMCAP) && c == '\n') break; if (ch == '^' && last_ch != '%') { ch = c = next_char(); if (c == EOF) _nc_err_abort(MSG_NO_INPUTS); if (!(is7bits(ch) && isprint(ch))) { _nc_warning("Illegal ^ character - '%s'", unctrl(ch)); } if (ch == '?') { *(ptr++) = '\177'; if (_nc_tracing) _nc_warning("Allow ^? as synonym for \\177"); } else { if ((ch &= 037) == 0) ch = 128; *(ptr++) = (char) (ch); } } else if (ch == '\\') { ch = c = next_char(); if (c == EOF) _nc_err_abort(MSG_NO_INPUTS); if (ch >= '0' && ch <= '7') { number = ch - '0'; for (i = 0; i < 2; i++) { ch = c = next_char(); if (c == EOF) _nc_err_abort(MSG_NO_INPUTS); if (c < '0' || c > '7') { if (isdigit(c)) { _nc_warning("Non-octal digit `%c' in \\ sequence", c); /* allow the digit; it'll do less harm */ } else { push_back((char) c); break; } } number = number * 8 + c - '0'; } if (number == 0) number = 0200; *(ptr++) = (char) number; } else { switch (c) { case 'E': case 'e': *(ptr++) = '\033'; break; case 'a': *(ptr++) = '\007'; break; case 'l': case 'n': *(ptr++) = '\n'; break; case 'r': *(ptr++) = '\r'; break; case 'b': *(ptr++) = '\010'; break; case 's': *(ptr++) = ' '; break; case 'f': *(ptr++) = '\014'; break; case 't': *(ptr++) = '\t'; break; case '\\': *(ptr++) = '\\'; break; case '^': *(ptr++) = '^'; break; case ',': *(ptr++) = ','; break; case ':': *(ptr++) = ':'; break; case '\n': continue; default: _nc_warning("Illegal character '%s' in \\ sequence", unctrl(ch)); /* FALLTHRU */ case '|': *(ptr++) = (char) ch; } /* endswitch (ch) */ } /* endelse (ch < '0' || ch > '7') */ } /* end else if (ch == '\\') */ else if (ch == '\n' && (_nc_syntax == SYN_TERMINFO)) { /* * Newlines embedded in a terminfo string are ignored, provided * that the next line begins with whitespace. */ ignored = TRUE; } else { *(ptr++) = (char) ch; } if (!ignored) { if (_nc_curr_col <= 1) { push_back(ch); ch = '\n'; break; } last_ch = ch; count++; } ignored = FALSE; if (count > MAXCAPLEN && !long_warning) { _nc_warning("Very long string found. Missing separator?"); long_warning = TRUE; } } /* end while */ *ptr = '\0'; return (ch);}/* * _nc_push_token() * * Push a token of given type so that it will be reread by the next * get_token() call. */NCURSES_EXPORT(void)_nc_push_token(int tokclass){ /* * This implementation is kind of bogus, it will fail if we ever do more * than one pushback at a time between get_token() calls. It relies on the * fact that _nc_curr_token is static storage that nothing but * _nc_get_token() touches. */ pushtype = tokclass; if (pushname == 0) pushname = typeMalloc(char, MAX_NAME_SIZE + 1); _nc_get_type(pushname); DEBUG(3, ("pushing token: `%s', class %d", ((_nc_curr_token.tk_name != 0) ? _nc_curr_token.tk_name : "<null>"), pushtype));}/* * Panic mode error recovery - skip everything until a "ch" is found. */NCURSES_EXPORT(void)_nc_panic_mode(char ch){ int c; for (;;) { c = next_char(); if (c == ch) return; if (c == EOF) return; }}#if NO_LEAKSNCURSES_EXPORT(void)_nc_comp_scan_leaks(void){ FreeAndNull(pushname);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -