static int read_key (struct cw_KTV_Reader *r, char *key, int max_len) { int c,n; do { c = skip_chars (r, " \t\n\a\v"); if (c == '#') { c = skip_to_chars (r, "\n\a"); } else { break; } } while (c != EOF); unget_char(r,c); c=get_char_q(r); n=0; while(c!=EOF && n<max_len){ if (!r->quote && !isalnum(c) && !strchr("._/-()@#|{}[]\\",c)){ unget_char(r,c); break; } key[n]=c; c=get_char_q(r); n++; } key[n]=0; return n; }
static int check_bom(int get_char(struct tok_state *), void unget_char(int, struct tok_state *), int set_readline(struct tok_state *, const char *), struct tok_state *tok) { int ch1, ch2, ch3; ch1 = get_char(tok); tok->decoding_state = 1; if (ch1 == EOF) { return 1; } else if (ch1 == 0xEF) { ch2 = get_char(tok); if (ch2 != 0xBB) { unget_char(ch2, tok); unget_char(ch1, tok); return 1; } ch3 = get_char(tok); if (ch3 != 0xBF) { unget_char(ch3, tok); unget_char(ch2, tok); unget_char(ch1, tok); return 1; } #if 0 /* Disable support for UTF-16 BOMs until a decision is made whether this needs to be supported. */ } else if (ch1 == 0xFE) { ch2 = get_char(tok); if (ch2 != 0xFF) { unget_char(ch2, tok); unget_char(ch1, tok); return 1; } if (!set_readline(tok, "utf-16-be")) return 0; tok->decoding_state = -1; } else if (ch1 == 0xFF) { ch2 = get_char(tok); if (ch2 != 0xFE) { unget_char(ch2, tok); unget_char(ch1, tok); return 1; } if (!set_readline(tok, "utf-16-le")) return 0; tok->decoding_state = -1; #endif } else { unget_char(ch1, tok); return 1; } if (tok->encoding != NULL) PyMem_FREE(tok->encoding); tok->encoding = new_string("utf-8", 5); /* resulting is in utf-8 */ return 1; }
/* get token */ static int token(Scheme *sc) { int c = skipspace(sc); if (c == EOF) return (TOK_EOF); switch (c = get_char(sc)) { case EOF: return (TOK_EOF); case '(': return (TOK_LPAREN); case ')': return (TOK_RPAREN); case '.': c = get_char(sc); if (find_char_in_string(" \n\t", c)) { return (TOK_DOT); } else { unget_char(sc, c); unget_char(sc, '.'); return TOK_ATOM; } case '\'': //引用 return (TOK_QUOTE); case ';': //注释 while ((c = get_char(sc)) != '\n' && c != EOF) ; //跳过注释 if (c == EOF) return TOK_EOF; else return token(sc); case '"': //双引号 return (TOK_DQUOTE); case '#': c = get_char(sc); if (c == '(') return TOK_VECTOR; else if (c == '!') { //#!开头的注释 while ((c = get_char(sc)) != '\n' && c != EOF) ; if (c == EOF) return TOK_EOF; return token(sc); } else { unget_char(sc, c); if (find_char_in_string(" tfodxb\\", c)) return TOK_SHARP_CONST; else return (TOK_SHARP); } default: unget_char(sc, c); return (TOK_ATOM); } }
static int read_type(struct cw_KTV_Reader * r, char *type, int max_len) { int c,n; c = skip_to_colon(r); if (c==-1) return -1; if (c=='='){ unget_char(r,c); return sprintf(type,"%s","Str"); } c = skip_chars (r, " \t"); if (c==':'){ unget_char(r,c); sprintf(type,"%s","Str"); return 0; } if (!isalpha(c)){ if (c=='\n'){ unget_char(r,c); /*sprintf(p->error,"Error at line %d, pos %d: Unexpected EOL.", p->line, p->pos);*/ return -1; } /*sprintf(p->error,"Error at line %d, pos %d: Letter expected.", p->line, p->pos);*/ return -1; } n=0; while(c!=EOF && n<max_len){ if (!isalnum(c) && !strchr("_/-.()@#|{}[]",c)/*strchr(": \t\n\a",c)*/){ unget_char(r,c); break; } type[n]=c; c=get_char(r); n++; } type[n]=0; return n; }
static int read_val(struct cw_KTV_Reader *r, char *val, int max_len){ int c,n,quote; c = skip_to_colon(r); if (c==-1) return -1; c = skip_chars (r, " \t"); if (c=='"'){ quote=1; c=get_char(r); } else{ quote=0; } n=0; while(c!=EOF && n<max_len){ if (quote && c=='"'){ break; } if (c=='\n'){ break; } if (quote){ if (c=='\\'){ c = get_char(r); switch(c){ case 'n': c='\n'; break; case '\\': break; case '"': break; default: unget_char(r,c); c='\\'; } } } val[n++]=c; c=get_char(r); } if(!quote && n>0){ while(n>0){ if (isspace(val[n-1])) n--; else break; } } val[n]=0; return n; }
/* skip white characters */ static int skipspace(Scheme *sc) { int c = 0; do { c = get_char(sc); } while (isspace(c)); if (c != EOF) { unget_char(sc, c); return 1; } else return EOF; }
//读取一个字符串直到遇到分隔符 static char *readstr_upto(Scheme *sc, char *delim) { String str = init_string(); while(TRUE) { char c = get_char(sc); str = append_char(str, c); if (*str && !find_char_in_string(delim, c)) ; else break; } unget_char(sc, *(str - 1)); *(str + strlen(str) - 1) = '\0'; return str; }
static int get_number(int *numptr, int low, const char * const names[], int ch, FILE *file, const char *terms) { char temp[MAX_TEMPSTR], *pc; int len, i; pc = temp; len = 0; /* first look for a number */ while (isdigit((unsigned char)ch)) { if (++len >= MAX_TEMPSTR) goto bad; *pc++ = (char)ch; ch = get_char(file); } *pc = '\0'; if (len != 0) { /* got a number, check for valid terminator */ if (!strchr(terms, ch)) goto bad; *numptr = atoi(temp); return (ch); } /* no numbers, look for a string if we have any */ if (names) { while (isalpha((unsigned char)ch)) { if (++len >= MAX_TEMPSTR) goto bad; *pc++ = (char)ch; ch = get_char(file); } *pc = '\0'; if (len != 0 && strchr(terms, ch)) { for (i = 0; names[i] != NULL; i++) { Debug(DPARS|DEXT, ("get_num, compare(%s,%s)\n", names[i], temp)); if (!strcasecmp(names[i], temp)) { *numptr = i+low; return (ch); } } } } bad: unget_char(ch, file); return (EOF); }
static int check_bom(int get_char(struct tok_state *), void unget_char(int, struct tok_state *), int set_readline(struct tok_state *, const char *), struct tok_state *tok) { int ch = get_char(tok); tok->decoding_state = 1; if (ch == EOF) { return 1; } else if (ch == 0xEF) { ch = get_char(tok); if (ch != 0xBB) goto NON_BOM; ch = get_char(tok); if (ch != 0xBF) goto NON_BOM; #if 0 /* Disable support for UTF-16 BOMs until a decision is made whether this needs to be supported. */ } else if (ch == 0xFE) { ch = get_char(tok); if (ch != 0xFF) goto NON_BOM; if (!set_readline(tok, "utf-16-be")) return 0; tok->decoding_state = -1; } else if (ch == 0xFF) { ch = get_char(tok); if (ch != 0xFE) goto NON_BOM; if (!set_readline(tok, "utf-16-le")) return 0; tok->decoding_state = -1; #endif } else { unget_char(ch, tok); return 1; } if (tok->encoding != NULL) PyMem_FREE(tok->encoding); tok->encoding = new_string("utf-8", 5); /* resulting is in utf-8 */ return 1; NON_BOM: /* any token beginning with '\xEF', '\xFE', '\xFF' is a bad token */ unget_char(0xFF, tok); /* XXX this will cause a syntax error */ return 1; }
static int skip_to_colon(struct cw_KTV_Reader * r) { int c; c = skip_chars (r, " \t"); if (c!=':' && c!='='){ if (c=='\n'){ unget_char(r,c); sprintf(r->error,"Unexpected EOL, colon or equal sign expected."); return -1; } sprintf(r->error,"Colon or equal sign expected."); return -1; } return c; }
/* skip_comments(file) : read past comment (if any) */ void skip_comments(FILE *file) { int ch; while (EOF != (ch = get_char(file))) { /* ch is now the first character of a line. */ while (ch == ' ' || ch == '\t') { ch = get_char(file); } if (ch == EOF) { break; } /* ch is now the first non-blank character of a line. */ if (ch != '\n' && ch != '#') { break; } /* ch must be a newline or comment as first non-blank * character on a line. */ while (ch != '\n' && ch != EOF) { ch = get_char(file); } /* ch is now the newline of a line which we're going to * ignore. */ } if (ch != EOF) { unget_char(ch, file); } }
static int get_char_q(struct cw_KTV_Reader *p) { int c; while(1) { c = get_char(p); if (c==EOF || c=='\n') return c; if(c=='"' && !p->quote){ p->quote=1; continue; } if(c=='"' && p->quote){ p->quote=0; continue; } break; } if (!p->quote) return c; if (c!='\\') return c; c = get_char(p); switch(c){ case EOF: return c; case 'n': return '\n'; case '\\': return '\\'; case '"': return '"'; default: unget_char(p,c); return '\\'; } /* We will never reach here */ /* return c;*/ }
static int get_range(bitstr_t *bits, int low, int high, const char * const names[], int ch, FILE *file) { /* range = number | number "-" number [ "/" number ] */ int i, num1, num2, num3; int qmark, star; qmark = star = FALSE; Debug(DPARS|DEXT, ("get_range()...entering, exit won't show\n")); if (ch == '*') { /* '*' means "first-last" but can still be modified by /step */ star = TRUE; num1 = low; num2 = high; ch = get_char(file); if (ch == EOF) return (EOF); } else if (ch == '?') { qmark = TRUE; ch = get_char(file); if (ch == EOF) return EOF; if (!isdigit(ch)) { num1 = random_with_range(low, high); if (EOF == set_element(bits, low, high, num1)) return EOF; return ch; } } if (!star) { ch = get_number(&num1, low, names, ch, file, ",- \t\n"); if (ch == EOF) return (EOF); if (ch != '-') { /* not a range, it's a single number. * a single number after '?' is bogus. */ if (qmark) return EOF; if (EOF == set_element(bits, low, high, num1)) { unget_char(ch, file); return (EOF); } return (ch); } else { /* eat the dash */ ch = get_char(file); if (ch == EOF) return (EOF); /* get the number following the dash */ ch = get_number(&num2, low, names, ch, file, "/, \t\n"); if (ch == EOF || num1 > num2) return (EOF); /* if we have a random range, it is really * like having a single number. */ if (qmark) { if (num1 > num2) return EOF; num1 = random_with_range(num1, num2); if (EOF == set_element(bits, low, high, num1)) return EOF; return ch; } } } /* check for step size */ if (ch == '/') { /* '?' is incompatible with '/' */ if (qmark) return EOF; /* eat the slash */ ch = get_char(file); if (ch == EOF) return (EOF); /* get the step size -- note: we don't pass the * names here, because the number is not an * element id, it's a step size. 'low' is * sent as a 0 since there is no offset either. */ ch = get_number(&num3, 0, PPC_NULL, ch, file, ", \t\n"); if (ch == EOF || num3 == 0) return (EOF); } else { /* no step. default==1. */ num3 = 1; } /* range. set all elements from num1 to num2, stepping * by num3. (the step is a downward-compatible extension * proposed conceptually by bob@acornrc, syntactically * designed then implemented by paul vixie). */ for (i = num1; i <= num2; i += num3) if (EOF == set_element(bits, low, high, i)) { unget_char(ch, file); return (EOF); } return (ch); }
Token Lexer::get_token() { int c; while((c = get_char()) != -1) { if (isspace(c)) { // ignore } else if (isdigit(c) || c == '.') // number { bool real = false; if (c == '.') { real = true; } std::string str; str += static_cast<char>(c); while((c = get_char()) != -1) { if (c == '.' && !real) { real = true; str += static_cast<char>(c); } else if (!isdigit(c)) { unget_char(); break; } else { str += static_cast<char>(c); } } if (real) { return Token::real(static_cast<float>(atof(str.c_str()))); } else { return Token::integer(atoi(str.c_str())); } } else if (isalpha(c)) { std::string str; str += static_cast<char>(c); while((c = get_char()) != -1) { if (!isalpha(c) && !isdigit(c) && c != '_') { unget_char(); break; } else { str += static_cast<char>(c); } } return Token::string(str); } else if (c == '=') { if ((c = get_char()) != -1 && c == '=') { return Token::equal(); } else { throw std::runtime_error("syntax error"); } } else if (c == '~') { return Token::bitwise_not(); } else if (c == '!') { if ((c = get_char()) != -1 && c == '=') { return Token::not_equal(); } else { unget_char(); return Token::logical_not(); } } else if (c == '<') { if ((c = get_char()) != -1) { if (c == '=') return Token::smaller_or_equal_then(); else if (c == '<') return Token::shift_left(); else { unget_char(); return Token::smaller_then(); } } else { unget_char(); return Token::smaller_then(); } } else if (c == '>') { if ((c = get_char()) != -1) { if (c == '=') { return Token::larger_or_equal_then(); } else if (c == '>') { return Token::shift_right(); } else { unget_char(); return Token::larger_then(); } } else { unget_char(); return Token::larger_then(); } } else if (c == '|') { if ((c = get_char()) != -1 && c == '|') { return Token::logical_or(); } else { unget_char(); return Token::bitwise_or(); } } else if (c == '^') { return Token::bitwise_xor(); } else if (c == '&') { if ((c = get_char()) != -1 && c == '&') { return Token::logical_and(); } else { unget_char(); return Token::bitwise_and(); } } else if (c == '+') { return Token::plus(); } else if (c == '%') { return Token::modulo(); } else if (c == '-') { return Token::minus(); } else if (c == '*') { return Token::mult(); } else if (c == '/') { return Token::div(); } else if (c == '(') { return Token::parent_left(); } else if (c == ')') { return Token::parent_right(); } else if (c == ',') { return Token::comma(); } else if (c == '?') { return Token::questionmark(); } else if (c == ':') { return Token::colon(); } else { throw std::runtime_error("syntax error"); } } return Token::eof(); }
parse_real (unsigned char c) { if ((__ctype_ptr[c]&04) && c != '.') unget_char ( c); }
int get_token(void) { int type = TOKEN_TYPE_ERR; int index = 0; int status = SCAN_STATUS_START; int save; int c; while (status != SCAN_STATUS_DONE) { c = get_char(); save = BOOL_YES; switch (status) { case SCAN_STATUS_START: if (' ' == c || '\t' == c) { save = BOOL_NO; } else if ('\n' == c) { save = BOOL_NO; ++g_line_numer; } else if (isdigit(c)) { status = SCAN_STATUS_IN_CINT; } else if (isalpha(c) || '_' == c) { status = SCAN_STATUS_IN_ID; } else if ('.' == c) { status = SCAN_STATUS_IN_ACCESS; } else if ('#' == c) { save = BOOL_NO; status = SCAN_STATUE_IN_COMMENT; } else { status = SCAN_STATUS_DONE; switch (c) { case EOF: save = BOOL_NO; type = TOKEN_TYPE_EOF; break; case '=': type = TOKEN_TYPE_ASSIGN; break; case '<': type = TOKEN_TYPE_INHERIT; break; case '[': type = TOKEN_TYPE_LBRACKET; break; case ']': type = TOKEN_TYPE_RBRACKET; break; case '{': type = TOKEN_TYPE_LBRACE; break; case '}': type = TOKEN_TYPE_RBRACE; break; default: save = BOOL_NO; type = TOKEN_TYPE_ERR; break; } } break; case SCAN_STATUS_IN_ACCESS: if (isalpha(c) || '_' == c) { unget_char(); save = BOOL_NO; status = SCAN_STATUS_DONE; type = TOKEN_TYPE_ACCESS; } else { fprintf(stderr, "Lexial error: [%d] after '.' ...\n", g_line_numer); exit(1); } break; case SCAN_STATUS_IN_ID: if (!isalnum(c) && '_' != c) { unget_char(); save = BOOL_NO; status = SCAN_STATUS_DONE; type = TOKEN_TYPE_ID; } break; case SCAN_STATUS_IN_CINT: if ('.' == c) { status = SCAN_STATUS_IN_CREAL; } else { if (!isdigit(c)) { unget_char(); save = BOOL_NO; status = SCAN_STATUS_DONE; type = TOKEN_TYPE_CINT; } } break; case SCAN_STATUS_IN_CREAL: if (!isdigit(c)) { unget_char(); save = BOOL_NO; status = SCAN_STATUS_DONE; type = TOKEN_TYPE_CREAL; } break; case SCAN_STATUE_IN_COMMENT: save = BOOL_NO; if (EOF == c) { status = SCAN_STATUS_DONE; type = TOKEN_TYPE_EOF; } else if ('\n' == c) { ++g_line_numer; status = SCAN_STATUS_START; } break; case SCAN_STATUS_DONE: default: fprintf(g_scan_stream, "Scanner bug: status = %d\n", status); status = SCAN_STATUS_DONE; type = TOKEN_TYPE_ERR; break; } if (save && index < MAX_TOKEN) g_token[index++] = (char)c; if (SCAN_STATUS_DONE == status) { g_token[index] = 0; if (TOKEN_TYPE_ID == type) type = lookup_reserved(g_token); } } echo_scanner(g_scan_stream, g_line_numer, type, g_token); return type; }
static format_token format_lex (format_data *fmt) { format_token token; int negative_flag; int c; char delim; if (fmt->saved_token != FMT_NONE) { token = fmt->saved_token; fmt->saved_token = FMT_NONE; return token; } negative_flag = 0; c = next_char (fmt, 0); switch (c) { case '*': token = FMT_STAR; break; case '(': token = FMT_LPAREN; break; case ')': token = FMT_RPAREN; break; case '-': negative_flag = 1; /* Fall Through */ case '+': c = next_char (fmt, 0); if (!isdigit (c)) { token = FMT_UNKNOWN; break; } fmt->value = c - '0'; for (;;) { c = next_char (fmt, 0); if (!isdigit (c)) break; fmt->value = 10 * fmt->value + c - '0'; } unget_char (fmt); if (negative_flag) fmt->value = -fmt->value; token = FMT_SIGNED_INT; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': fmt->value = c - '0'; for (;;) { c = next_char (fmt, 0); if (!isdigit (c)) break; fmt->value = 10 * fmt->value + c - '0'; } unget_char (fmt); token = (fmt->value == 0) ? FMT_ZERO : FMT_POSINT; break; case '.': token = FMT_PERIOD; break; case ',': token = FMT_COMMA; break; case ':': token = FMT_COLON; break; case '/': token = FMT_SLASH; break; case '$': token = FMT_DOLLAR; break; case 'T': switch (next_char (fmt, 0)) { case 'L': token = FMT_TL; break; case 'R': token = FMT_TR; break; default: token = FMT_T; unget_char (fmt); break; } break; case 'X': token = FMT_X; break; case 'S': switch (next_char (fmt, 0)) { case 'S': token = FMT_SS; break; case 'P': token = FMT_SP; break; default: token = FMT_S; unget_char (fmt); break; } break; case 'B': switch (next_char (fmt, 0)) { case 'N': token = FMT_BN; break; case 'Z': token = FMT_BZ; break; default: token = FMT_B; unget_char (fmt); break; } break; case '\'': case '"': delim = c; fmt->string = fmt->format_string; fmt->value = 0; /* This is the length of the string */ for (;;) { c = next_char (fmt, 1); if (c == -1) { token = FMT_BADSTRING; fmt->error = bad_string; break; } if (c == delim) { c = next_char (fmt, 1); if (c == -1) { token = FMT_BADSTRING; fmt->error = bad_string; break; } if (c != delim) { unget_char (fmt); token = FMT_STRING; break; } } fmt->value++; } break; case 'P': token = FMT_P; break; case 'I': token = FMT_I; break; case 'O': token = FMT_O; break; case 'Z': token = FMT_Z; break; case 'F': token = FMT_F; break; case 'E': switch (next_char (fmt, 0)) { case 'N': token = FMT_EN; break; case 'S': token = FMT_ES; break; default: token = FMT_E; unget_char (fmt); break; } break; case 'G': token = FMT_G; break; case 'H': token = FMT_H; break; case 'L': token = FMT_L; break; case 'A': token = FMT_A; break; case 'D': switch (next_char (fmt, 0)) { case 'P': token = FMT_DP; break; case 'C': token = FMT_DC; break; default: token = FMT_D; unget_char (fmt); break; } break; case 'R': switch (next_char (fmt, 0)) { case 'C': token = FMT_RC; break; case 'D': token = FMT_RD; break; case 'N': token = FMT_RN; break; case 'P': token = FMT_RP; break; case 'U': token = FMT_RU; break; case 'Z': token = FMT_RZ; break; default: unget_char (fmt); token = FMT_UNKNOWN; break; } break; case -1: token = FMT_END; break; default: token = FMT_UNKNOWN; break; } return token; }
/* return NULL if eof or syntax error occurs; * otherwise return a pointer to a new entry. */ entry * load_entry(FILE *file, void (*error_func)(const char *), struct passwd *pw, char **envp) { /* this function reads one crontab entry -- the next -- from a file. * it skips any leading blank lines, ignores comments, and returns * NULL if for any reason the entry can't be read and parsed. * * the entry is also parsed here. * * syntax: * user crontab: * minutes hours doms months dows cmd\n * system crontab (/etc/crontab): * minutes hours doms months dows USERNAME cmd\n */ ecode_e ecode = e_none; entry *e; int ch; char cmd[MAX_COMMAND]; char envstr[MAX_ENVSTR]; char **tenvp; Debug(DPARS, ("load_entry()...about to eat comments\n")); skip_comments(file); ch = get_char(file); if (ch == EOF) return (NULL); /* ch is now the first useful character of a useful line. * it may be an @special or it may be the first character * of a list of minutes. */ e = calloc(sizeof(*e), sizeof(char)); if (ch == '@') { /* all of these should be flagged and load-limited; i.e., * instead of @hourly meaning "0 * * * *" it should mean * "close to the front of every hour but not 'til the * system load is low". Problems are: how do you know * what "low" means? (save me from /etc/cron.conf!) and: * how to guarantee low variance (how low is low?), which * means how to we run roughly every hour -- seems like * we need to keep a history or let the first hour set * the schedule, which means we aren't load-limited * anymore. too much for my overloaded brain. (vix, jan90) * HINT */ ch = get_string(cmd, MAX_COMMAND, file, " \t\n"); if (!strcmp("reboot", cmd)) { e->flags |= WHEN_REBOOT; } else if (!strcmp("yearly", cmd) || !strcmp("annually", cmd)){ bit_set(e->minute, 0); bit_set(e->hour, 0); bit_set(e->dom, 0); bit_set(e->month, 0); bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1)); e->flags |= DOW_STAR; } else if (!strcmp("monthly", cmd)) { bit_set(e->minute, 0); bit_set(e->hour, 0); bit_set(e->dom, 0); bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1)); bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1)); e->flags |= DOW_STAR; } else if (!strcmp("weekly", cmd)) { bit_set(e->minute, 0); bit_set(e->hour, 0); bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1)); bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1)); bit_set(e->dow, 0); e->flags |= DOM_STAR; } else if (!strcmp("daily", cmd) || !strcmp("midnight", cmd)) { bit_set(e->minute, 0); bit_set(e->hour, 0); bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1)); bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1)); bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1)); e->flags |= DOM_STAR | DOW_STAR; } else if (!strcmp("hourly", cmd)) { bit_set(e->minute, 0); bit_nset(e->hour, 0, (LAST_HOUR-FIRST_HOUR+1)); bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1)); bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1)); bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1)); e->flags |= DOM_STAR | DOW_STAR; } else { ecode = e_timespec; goto eof; } /* Advance past whitespace between shortcut and * username/command. */ Skip_Blanks(ch, file); if (ch == EOF || ch == '\n') { ecode = e_cmd; goto eof; } } else { Debug(DPARS, ("load_entry()...about to parse numerics\n")); if (ch == '*') e->flags |= MIN_STAR; ch = get_list(e->minute, FIRST_MINUTE, LAST_MINUTE, PPC_NULL, ch, file); if (ch == EOF) { ecode = e_minute; goto eof; } /* hours */ if (ch == '*') e->flags |= HR_STAR; ch = get_list(e->hour, FIRST_HOUR, LAST_HOUR, PPC_NULL, ch, file); if (ch == EOF) { ecode = e_hour; goto eof; } /* DOM (days of month) */ if (ch == '*') e->flags |= DOM_STAR; ch = get_list(e->dom, FIRST_DOM, LAST_DOM, PPC_NULL, ch, file); if (ch == EOF) { ecode = e_dom; goto eof; } /* month */ ch = get_list(e->month, FIRST_MONTH, LAST_MONTH, MonthNames, ch, file); if (ch == EOF) { ecode = e_month; goto eof; } /* DOW (days of week) */ if (ch == '*') e->flags |= DOW_STAR; ch = get_list(e->dow, FIRST_DOW, LAST_DOW, DowNames, ch, file); if (ch == EOF) { ecode = e_dow; goto eof; } } /* make sundays equivalent */ if (bit_test(e->dow, 0) || bit_test(e->dow, 7)) { bit_set(e->dow, 0); bit_set(e->dow, 7); } /* check for permature EOL and catch a common typo */ if (ch == '\n' || ch == '*') { ecode = e_cmd; goto eof; } /* ch is the first character of a command, or a username */ unget_char(ch, file); if (!pw) { char *username = cmd; /* temp buffer */ Debug(DPARS, ("load_entry()...about to parse username\n")); ch = get_string(username, MAX_COMMAND, file, " \t\n"); Debug(DPARS, ("load_entry()...got %s\n",username)); if (ch == EOF || ch == '\n' || ch == '*') { ecode = e_cmd; goto eof; } pw = getpwnam(username); if (pw == NULL) { ecode = e_username; goto eof; } Debug(DPARS, ("load_entry()...uid %ld, gid %ld\n", (long)pw->pw_uid, (long)pw->pw_gid)); } if ((e->pwd = pw_dup(pw)) == NULL) { ecode = e_memory; goto eof; } (void)memset(e->pwd->pw_passwd, 0, strlen(e->pwd->pw_passwd)); /* copy and fix up environment. some variables are just defaults and * others are overrides. */ if ((e->envp = env_copy(envp)) == NULL) { ecode = e_memory; goto eof; } if (!env_get("SHELL", e->envp)) { if (glue_strings(envstr, sizeof envstr, "SHELL", _PATH_BSHELL, '=')) { if ((tenvp = env_set(e->envp, envstr)) == NULL) { ecode = e_memory; goto eof; } e->envp = tenvp; } else log_it("CRON", getpid(), "error", "can't set SHELL"); } if (!env_get("HOME", e->envp)) { if (glue_strings(envstr, sizeof envstr, "HOME", pw->pw_dir, '=')) { if ((tenvp = env_set(e->envp, envstr)) == NULL) { ecode = e_memory; goto eof; } e->envp = tenvp; } else log_it("CRON", getpid(), "error", "can't set HOME"); } /* If login.conf is in used we will get the default PATH later. */ if (!env_get("PATH", e->envp)) { if (glue_strings(envstr, sizeof envstr, "PATH", _PATH_DEFPATH, '=')) { if ((tenvp = env_set(e->envp, envstr)) == NULL) { ecode = e_memory; goto eof; } e->envp = tenvp; } else log_it("CRON", getpid(), "error", "can't set PATH"); } if (glue_strings(envstr, sizeof envstr, "LOGNAME", pw->pw_name, '=')) { if ((tenvp = env_set(e->envp, envstr)) == NULL) { ecode = e_memory; goto eof; } e->envp = tenvp; } else log_it("CRON", getpid(), "error", "can't set LOGNAME"); #if defined(BSD) || defined(__linux) if (glue_strings(envstr, sizeof envstr, "USER", pw->pw_name, '=')) { if ((tenvp = env_set(e->envp, envstr)) == NULL) { ecode = e_memory; goto eof; } e->envp = tenvp; } else log_it("CRON", getpid(), "error", "can't set USER"); #endif Debug(DPARS, ("load_entry()...about to parse command\n")); /* If the first character of the command is '-' it is a cron option. */ while ((ch = get_char(file)) == '-') { switch (ch = get_char(file)) { case 'q': e->flags |= DONT_LOG; Skip_Nonblanks(ch, file); break; default: ecode = e_option; goto eof; } Skip_Blanks(ch, file); if (ch == EOF || ch == '\n') { ecode = e_cmd; goto eof; } } unget_char(ch, file); /* Everything up to the next \n or EOF is part of the command... * too bad we don't know in advance how long it will be, since we * need to malloc a string for it... so, we limit it to MAX_COMMAND. */ ch = get_string(cmd, MAX_COMMAND, file, "\n"); /* a file without a \n before the EOF is rude, so we'll complain... */ if (ch == EOF) { ecode = e_cmd; goto eof; } /* got the command in the 'cmd' string; save it in *e. */ if ((e->cmd = strdup(cmd)) == NULL) { ecode = e_memory; goto eof; } Debug(DPARS, ("load_entry()...returning successfully\n")); /* success, fini, return pointer to the entry we just created... */ return (e); eof: if (e->envp) env_free(e->envp); if (e->pwd) free(e->pwd); if (e->cmd) free(e->cmd); free(e); while (ch != '\n' && !feof(file)) ch = get_char(file); if (ecode != e_none && error_func) (*error_func)(ecodes[(int)ecode]); return (NULL); }
static format_token format_lex(void) { format_token token; char y, delim; if (saved_token != FMT_NONE) { token = saved_token; saved_token = FMT_NONE; return token; } if (mode == MODE_FORMAT) where = new_where; do { y = next_char(0); } while(g95_is_whitespace(y)); switch(y) { case '-': case '+': y = next_char(0); if (!isdigit(y)) { token = FMT_UNKNOWN; break; } do { y = next_char(0); } while(isdigit(y)); unget_char(); token = FMT_SIGNED_INT; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': repeat = y - '0'; for(;;) { y = next_char(0); if (!isdigit(y)) break; repeat = 10*repeat + y - '0'; } unget_char(); token = (repeat == 0) ? FMT_ZERO : FMT_POSINT; break; case '.': token = FMT_PERIOD; break; case ',': token = FMT_COMMA; break; case ':': token = FMT_COLON; break; case '/': token = FMT_SLASH; break; case '$': token = FMT_DOLLAR; break; case 'T': y = next_char(0); if (y != 'L' && y != 'R') unget_char(); token = FMT_POS; break; case '(': token = FMT_LPAREN; break; case ')': token = FMT_RPAREN; break; case 'X': token = FMT_X; break; case 'S': y = next_char(0); if (y != 'P' && y != 'S') unget_char(); token = FMT_SIGN; break; case 'B': y = next_char(0); if (y == 'N' || y == 'Z') token = FMT_BLANK; else { unget_char(); token = FMT_IBOZ; } break; case '\'': case '"': delim = y; for(;;) { y = next_char(1); if (y == '\0') { token = FMT_END; break; } if (y == delim) { y = next_char(1); if (y == '\0') { token = FMT_END; break; } if (y != delim) { unget_char(); token = FMT_CHAR; break; } } } break; case 'P': token = FMT_P; break; case 'I': case 'O': case 'Z': token = FMT_IBOZ; break; case 'F': token = FMT_F; break; case 'E': y = next_char(0); if (y == 'N' || y == 'S') token = FMT_EXT; else { token = FMT_E; unget_char(); } break; case 'G': token = FMT_G; break; case 'H': token = FMT_H; break; case 'L': token = FMT_L; break; case 'A': token = FMT_A; break; case 'D': token = FMT_D; break; case '\0': token = FMT_END; break; default: token = FMT_UNKNOWN; break; } new_where = g95_current_locus; return token; }
static Cell* readstrexp(Scheme *sc) { String str = init_string(); int c1 = 0; enum { st_ok, st_bsl, st_x1, st_x2, st_oct1, st_oct2 } state = st_ok; while (TRUE) { char c = get_char(sc); if (c == EOF) { return &g_false; } switch (state) { case st_ok: switch (c) { case '\\': state = st_bsl; break; case '"': return make_string_n(sc, str, strlen(str)); //free(str); ? default: str = append_char(str, c); break; } break; case st_bsl: switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': state = st_oct1; c1 = c - '0'; break; case 'x': case 'X': state = st_x1; c1 = 0; break; case 'n': str = append_char(str, '\n'); state = st_ok; break; case 't': str = append_char(str, '\t'); state = st_ok; break; case 'r': str = append_char(str, '\r'); state = st_ok; break; case '"': str = append_char(str, '"'); state = st_ok; break; default: str = append_char(str, c); state = st_ok; break; } break; case st_x1: case st_x2: c = toupper(c); if (c >= '0' && c <= 'F') { if (c <= '9') { c1 = (c1 << 4) + c - '0'; } else { c1 = (c1 << 4) + c - 'A' + 10; } if (state == st_x1) { state = st_x2; } else { str = append_char(str, c1); state = st_ok; } } else { return &g_false; } break; case st_oct1: case st_oct2: if (c < '0' || c > '7') { str = append_char(str, c1); unget_char(sc, c); state = st_ok; } else { if (state == st_oct2 && c1 >= 32) return &g_false; c1 = (c1 << 3) + (c - '0'); if (state == st_oct1) state = st_oct2; else { str = append_char(str, c1); state = st_ok; } } break; } } }
/* * Removes comments (normal and single line) from the file and * fixes long lines (lines that are divided to multiple lines with '\') * to single line. Carriage returns are added when needed to keep * file's line numbers correct. * */ void postprocess(FILE *fp_in, FILE *fp_out) { int c1,c2,c3,fixed,done,i,string; fixed = 0; string = 0; while ((c1 = get_char(fp_in)) != EOF) { c2 = get_char(fp_in); c3 = get_char(fp_in); switch (c1) { case '\\': // // case: \\n // if (c1 == '\\' && c2 == '\n') { fixed++; unget_char(c3); // // case: \\\n (in a string) // } else if (c1 == '\\' && c2 == '\\' && c3 == '\n' && string) { putc(c1,fp_out); unget_char(c3); unget_char(c2); // // case: \\ (in a string) // } else if (c1 == '\\' && c2 == '\\' && string) { putc(c1,fp_out); putc(c2,fp_out); unget_char(c3); // // case: \ (in a string) // } else if (c1 == '\\' && string) { putc(c1,fp_out); putc(c2,fp_out); unget_char(c3); // // case: \ // } else if (c1 == '\\' && !string) { putc(c1, fp_out); unget_char(c3); unget_char(c2); } else { putc(c1, fp_out); unget_char(c3); unget_char(c2); } break; case '\n': if (c1 == '\n' && fixed > 0) { putc(c1,fp_out); unget_char(c3); unget_char(c2); for (i=0; i < fixed; i++) { putc('\n', fp_out); } } else { putc(c1,fp_out); unget_char(c3); unget_char(c2); } fixed = 0; break; case '/': // // remove C-style comments // if (c1 == '/' && c2 == '*' && !string) { done = 0; while (!done) { if (c2 == '*' && c3 == '/') { done = 1; } else if (c2 == '\n') { putc(c2, fp_out); unget_char(c3); } else { unget_char(c3); } if (!done) { c2 = get_char(fp_in); c3 = get_char(fp_in); } } // // remove C++-style comments // } else if (c1 == '/' && c2 == '/' && !string) { while (c3 != '\n') { c3 = get_char(fp_in); } putc(c3, fp_out); } else { putc(c1, fp_out); unget_char(c3); unget_char(c2); } break; case '\'': // // case: '"' and '\"' // if (c1 == '\'' && c2 == '"' && c3 == '\'' && !string || c1 == '\'' && c2 == '\\' && c3 == '"' && !string) { putc(c1,fp_out); putc(c2,fp_out); putc(c3,fp_out); } else { putc(c1,fp_out); unget_char(c3); unget_char(c2); } break; case '"': // // toggle string mode on/off // if (string == 0) { string = 1; } else { string = 0; } putc(c1, fp_out); unget_char(c3); unget_char(c2); break; default: putc(c1, fp_out); unget_char(c3); unget_char(c2); break; } } }
/* ARGSUSED */ static int isearch(int f GCC_UNUSED, int n) { static TBUFF *pat_save = 0; /* Saved copy of the old pattern str */ int status; /* Search status */ register int cpos; /* character number in search string */ register int c; /* current input character */ MARK curpos, curp; /* Current point on entry */ int init_direction; /* The initial search direction */ /* Initialize starting conditions */ cmd_reexecute = -1; /* We're not re-executing (yet?) */ itb_init(&cmd_buff, EOS); /* Init the command buffer */ /* Save the old pattern string */ (void) tb_copy(&pat_save, searchpat); curpos = DOT; /* Save the current pointer */ init_direction = n; /* Save the initial search direction */ ignorecase = window_b_val(curwp, MDIGNCASE); scanboundry(FALSE, DOT, FORWARD); /* keep scanner() finite */ /* This is a good place to start a re-execution: */ start_over: /* ask the user for the text of a pattern */ promptpattern("ISearch: "); status = TRUE; /* Assume everything's cool */ /* * Get the first character in the pattern. If we get an initial * Control-S or Control-R, re-use the old search string and find the * first occurrence */ c = kcod2key(get_char()); /* Get the first character */ if ((c == IS_FORWARD) || (c == IS_REVERSE)) { /* Reuse old search string? */ for (cpos = 0; cpos < (int) tb_length(searchpat); ++cpos) echochar(tb_values(searchpat)[cpos]); /* and re-echo the string */ curp = DOT; if (c == IS_REVERSE) { /* forward search? */ n = -1; /* No, search in reverse */ last_srch_direc = REVERSE; backchar(TRUE, 1); /* Be defensive about EOB */ } else { n = 1; /* Yes, search forward */ last_srch_direc = FORWARD; forwchar(TRUE, 1); } unget_char(); status = scanmore(searchpat, n); /* Do the search */ if (status != TRUE) DOT = curp; c = kcod2key(get_char()); /* Get another character */ } else { tb_init(&searchpat, EOS); } /* Top of the per character loop */ for_ever { /* ISearch per character loop */ /* Check for special characters, since they might change the * search to be done */ if (ABORTED(c) || c == '\r') /* search aborted? */ return (TRUE); /* end the search */ if (isbackspace(c)) c = '\b'; if (c == quotec) /* quote character? */ c = kcod2key(get_char()); /* Get the next char */ switch (c) { /* dispatch on the input char */ case IS_REVERSE: /* If backward search */ case IS_FORWARD: /* If forward search */ curp = DOT; if (c == IS_REVERSE) { /* forward search? */ last_srch_direc = REVERSE; n = -1; /* No, search in reverse */ backchar(TRUE, 1); /* Be defensive about * EOB */ } else { n = 1; /* Yes, search forward */ last_srch_direc = FORWARD; forwchar(TRUE, 1); } status = scanmore(searchpat, n); /* Do the search */ if (status != TRUE) DOT = curp; c = kcod2key(get_char()); /* Get the next char */ continue; /* Go continue with the search */ case '\t': /* Generically allowed */ case '\n': /* controlled characters */ break; /* Make sure we use it */ case '\b': /* or if a Rubout: */ if (itb_length(cmd_buff) <= 1) /* Anything to delete? */ return (TRUE); /* No, just exit */ unget_char(); DOT = curpos; /* Reset the pointer */ n = init_direction; /* Reset the search direction */ (void) tb_copy(&searchpat, pat_save); /* Restore the old search str */ cmd_reexecute = 0; /* Start the whole mess over */ goto start_over; /* Let it take care of itself */ /* Presumably a quasi-normal character comes here */ default: /* All other chars */ if (!isPrint(c)) { /* Is it printable? */ /* Nope. */ unkeystroke(c); /* Re-eat the char */ return (TRUE); /* And return the last status */ } } /* Switch */ /* I guess we got something to search for, so search for it */ tb_append(&searchpat, c); /* put the char in the buffer */ echochar(c); /* Echo the character */ if (!status) { /* If we lost last time */ kbd_alarm(); /* Feep again */ } else /* Otherwise, we must have won */ status = scanmore(searchpat, n); /* or find the next * match */ c = kcod2key(get_char()); /* Get the next char */ } /* for_ever */ }