📄 conffile.c
字号:
default: if (exp == CONF_IDENT) tok = CONF_IDENT; else tok = lookup_keyword(tokenval.v.s); break; } } else { ch = conftoken_getc(); while(ch != EOF && ch != '\n' && isspace(ch)) ch = conftoken_getc(); if (ch == '#') { /* comment - eat everything but eol/eof */ while((ch = conftoken_getc()) != EOF && ch != '\n') { (void)ch; /* Quiet empty loop complaints */ } } if (isalpha(ch)) { /* identifier */ buf = tkbuf; token_overflow = 0; do { if (buf < tkbuf+sizeof(tkbuf)-1) { *buf++ = (char)ch; } else { *buf = '\0'; if (!token_overflow) { conf_parserror(_("token too long: %.20s..."), tkbuf); } token_overflow = 1; } ch = conftoken_getc(); } while(isalnum(ch) || ch == '_' || ch == '-'); if (ch != EOF && conftoken_ungetc(ch) == EOF) { if (ferror(current_file)) { conf_parserror(_("Pushback of '%c' failed: %s"), ch, strerror(ferror(current_file))); } else { conf_parserror(_("Pushback of '%c' failed: EOF"), ch); } } *buf = '\0'; tokenval.v.s = tkbuf; if (token_overflow) tok = CONF_UNKNOWN; else if (exp == CONF_IDENT) tok = CONF_IDENT; else tok = lookup_keyword(tokenval.v.s); } else if (isdigit(ch)) { /* integer */ sign = 1;negative_number: /* look for goto negative_number below sign is set there */ am64 = 0; do { am64 = am64 * 10 + (ch - '0'); ch = conftoken_getc(); } while (isdigit(ch)); if (ch != '.') { if (exp == CONF_INT) { tok = CONF_INT; tokenval.v.i = sign * (int)am64; } else if (exp != CONF_REAL) { tok = CONF_AM64; tokenval.v.am64 = (off_t)sign * am64; } else { /* automatically convert to real when expected */ tokenval.v.r = (double)sign * (double)am64; tok = CONF_REAL; } } else { /* got a real number, not an int */ tokenval.v.r = sign * (double) am64; am64 = 0; d = 1; ch = conftoken_getc(); while (isdigit(ch)) { am64 = am64 * 10 + (ch - '0'); d = d * 10; ch = conftoken_getc(); } tokenval.v.r += sign * ((double)am64) / d; tok = CONF_REAL; } if (ch != EOF && conftoken_ungetc(ch) == EOF) { if (ferror(current_file)) { conf_parserror(_("Pushback of '%c' failed: %s"), ch, strerror(ferror(current_file))); } else { conf_parserror(_("Pushback of '%c' failed: EOF"), ch); } } } else switch(ch) { case '"': /* string */ buf = tkbuf; token_overflow = 0; inquote = 1; *buf++ = (char)ch; while (inquote && ((ch = conftoken_getc()) != EOF)) { if (ch == '\n') { if (!escape) break; escape = 0; buf--; /* Consume escape in buffer */ } else if (ch == '\\') { escape = 1; } else { if (ch == '"') { if (!escape) inquote = 0; } escape = 0; } if(buf >= &tkbuf[sizeof(tkbuf) - 1]) { if (!token_overflow) { conf_parserror(_("string too long: %.20s..."), tkbuf); } token_overflow = 1; break; } *buf++ = (char)ch; } *buf = '\0'; /* * A little manuver to leave a fully unquoted, unallocated string * in tokenval.v.s */ tmps = unquote_string(tkbuf); strncpy(tkbuf, tmps, sizeof(tkbuf)); amfree(tmps); tokenval.v.s = tkbuf; tok = (token_overflow) ? CONF_UNKNOWN : (exp == CONF_IDENT) ? CONF_IDENT : CONF_STRING; break; case '-': ch = conftoken_getc(); if (isdigit(ch)) { sign = -1; goto negative_number; } else { if (ch != EOF && conftoken_ungetc(ch) == EOF) { if (ferror(current_file)) { conf_parserror(_("Pushback of '%c' failed: %s"), ch, strerror(ferror(current_file))); } else { conf_parserror(_("Pushback of '%c' failed: EOF"), ch); } } tok = CONF_UNKNOWN; } break; case ',': tok = CONF_COMMA; break; case '{': tok = CONF_LBRACE; break; case '}': tok = CONF_RBRACE; break; case '\n': tok = CONF_NL; break; case EOF: tok = CONF_END; break; default: tok = CONF_UNKNOWN; break; } } if (exp != CONF_ANY && tok != exp) { char *str; keytab_t *kwp; switch(exp) { case CONF_LBRACE: str = "\"{\""; break; case CONF_RBRACE: str = "\"}\""; break; case CONF_COMMA: str = "\",\""; break; case CONF_NL: str = _("end of line"); break; case CONF_END: str = _("end of file"); break; case CONF_INT: str = _("an integer"); break; case CONF_REAL: str = _("a real number"); break; case CONF_STRING: str = _("a quoted string"); break; case CONF_IDENT: str = _("an identifier"); break; default: for(kwp = keytable; kwp->keyword != NULL; kwp++) { if (exp == kwp->token) break; } if (kwp->keyword == NULL) str = _("token not"); else str = kwp->keyword; break; } conf_parserror(_("%s is expected"), str); tok = exp; if (tok == CONF_INT) tokenval.v.i = 0; else tokenval.v.s = ""; }}static voidunget_conftoken(void){ assert(!token_pushed); token_pushed = 1; pushed_tok = tok; tok = CONF_UNKNOWN;}static intconftoken_getc(void){ if(current_line == NULL) return getc(current_file); if(*current_char == '\0') return -1; return(*current_char++);}static intconftoken_ungetc( int c){ if(current_line == NULL) return ungetc(c, current_file); else if(current_char > current_line) { if(c == -1) return c; current_char--; if(*current_char != c) { error(_("*current_char != c : %c %c"), *current_char, c); /* NOTREACHED */ } } else { error(_("current_char == current_line")); /* NOTREACHED */ } return c;}/* * Parser Implementation */static gbooleanread_conffile( char *filename, gboolean is_client){ /* Save global locations. */ FILE *save_file = current_file; char *save_filename = current_filename; int save_line_num = current_line_num; int rc; if (is_client) { keytable = client_keytab; parsetable = client_var; } else { keytable = server_keytab; parsetable = server_var; } current_filename = config_dir_relative(filename); if ((current_file = fopen(current_filename, "r")) == NULL) { g_fprintf(stderr, _("could not open conf file \"%s\": %s\n"), current_filename, strerror(errno)); got_parserror = TRUE; goto finish; } current_line_num = 0; do { /* read_confline() can invoke us recursively via "includefile" */ rc = read_confline(is_client); } while (rc != 0); afclose(current_file);finish: amfree(current_filename); /* Restore servers */ current_line_num = save_line_num; current_file = save_file; current_filename = save_filename; return !got_parserror;}static gbooleanread_confline( gboolean is_client){ conf_var_t *np; current_line_num += 1; get_conftoken(CONF_ANY); switch(tok) { case CONF_INCLUDEFILE: get_conftoken(CONF_STRING); if (!read_conffile(tokenval.v.s, is_client)) return 0; break; case CONF_HOLDING: if (is_client) { handle_invalid_keyword(tokenval.v.s); } else { get_holdingdisk();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -