📄 comp_scan.c
字号:
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(char)_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 */ ignored = TRUE; } else { *(ptr++) = (char) ch; } if (!ignored) { 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, 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; }}/***************************************************************************** * * Character-stream handling * *****************************************************************************/#define LEXBUFSIZ 1024static char *bufptr; /* otherwise, the input buffer pointer */static char *bufstart; /* start of buffer so we can compute offsets */static FILE *yyin; /* scanner's input file descriptor *//* * _nc_reset_input() * * Resets the input-reading routines. Used on initialization, * or after a seek has been done. Exactly one argument must be * non-null. */NCURSES_EXPORT(void)_nc_reset_input(FILE *fp, char *buf){ pushtype = NO_PUSHBACK; if (pushname != 0) pushname[0] = '\0'; yyin = fp; bufstart = bufptr = buf; _nc_curr_file_pos = 0L; if (fp != 0) _nc_curr_line = 0; _nc_curr_col = 0;}/* * int last_char() * * Returns the final nonblank character on the current input buffer */static intlast_char(void){ size_t len = strlen(bufptr); while (len--) { if (!isspace(UChar(bufptr[len]))) return bufptr[len]; } return 0;}/* * int next_char() * * Returns the next character in the input stream. Comments and leading * white space are stripped. * * The global state variable 'firstcolumn' is set TRUE if the character * returned is from the first column of the input line. * * The global variable _nc_curr_line is incremented for each new line. * The global variable _nc_curr_file_pos is set to the file offset of the * beginning of each line. */static intnext_char(void){ if (!yyin) { /* * An string with an embedded null will truncate the input. This is * intentional (we don't read binary files here). */ if (*bufptr == '\0') return (EOF); if (*bufptr == '\n') { _nc_curr_line++; _nc_curr_col = 0; } } else if (!bufptr || !*bufptr) { /* * In theory this could be recoded to do its I/O one character at a * time, saving the buffer space. In practice, this turns out to be * quite hard to get completely right. Try it and see. If you * succeed, don't forget to hack push_back() correspondingly. */ static char *result; static size_t allocated; size_t used; size_t len; do { bufstart = 0; used = 0; do { if (used + (LEXBUFSIZ / 4) >= allocated) { allocated += (allocated + LEXBUFSIZ); result = typeRealloc(char, allocated, result); if (result == 0) return (EOF); } if (used == 0) _nc_curr_file_pos = ftell(yyin); if (fgets(result + used, allocated - used, yyin) != 0) { bufstart = result; if (used == 0) { _nc_curr_line++; _nc_curr_col = 0; } } else { if (used != 0) strcat(result, "\n"); } if ((bufptr = bufstart) != 0) { used = strlen(bufptr); while (iswhite(*bufptr)) bufptr++; /* * Treat a trailing <cr><lf> the same as a <newline> so we * can read files on OS/2, etc. */ if ((len = strlen(bufptr)) > 1) { if (bufptr[len - 1] == '\n' && bufptr[len - 2] == '\r') { len--; bufptr[len - 1] = '\n'; bufptr[len] = '\0'; } } } else { return (EOF); } } while (bufptr[len - 1] != '\n'); /* complete a line */ } while (result[0] == '#'); /* ignore comments */ } first_column = (bufptr == bufstart); if (first_column) had_newline = FALSE; _nc_curr_col++; return (*bufptr++);}static voidpush_back(char c)/* push a character back onto the input stream */{ if (bufptr == bufstart) _nc_syserr_abort("Can't backspace off beginning of line"); *--bufptr = c;}static longstream_pos(void)/* return our current character position in the input stream */{ return (yyin ? ftell(yyin) : (bufptr ? bufptr - bufstart : 0));}static boolend_of_stream(void)/* are we at end of input? */{ return ((yyin ? feof(yyin) : (bufptr && *bufptr == '\0')) ? TRUE : FALSE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -