Home | History | Annotate | Download | only in init
      1 #include "parser.h"
      2 
      3 #include <stdarg.h>
      4 #include <stdio.h>
      5 #include <string.h>
      6 
      7 #include "log.h"
      8 
      9 void parse_error(struct parse_state *state, const char *fmt, ...)
     10 {
     11     va_list ap;
     12     char buf[128];
     13     int off;
     14 
     15     snprintf(buf, sizeof(buf), "%s: %d: ", state->filename, state->line);
     16     buf[127] = 0;
     17     off = strlen(buf);
     18 
     19     va_start(ap, fmt);
     20     vsnprintf(buf + off, 128 - off, fmt, ap);
     21     va_end(ap);
     22     buf[127] = 0;
     23     LOG(ERROR) << buf;
     24 }
     25 
     26 int next_token(struct parse_state *state)
     27 {
     28     char *x = state->ptr;
     29     char *s;
     30 
     31     if (state->nexttoken) {
     32         int t = state->nexttoken;
     33         state->nexttoken = 0;
     34         return t;
     35     }
     36 
     37     for (;;) {
     38         switch (*x) {
     39         case 0:
     40             state->ptr = x;
     41             return T_EOF;
     42         case '\n':
     43             x++;
     44             state->ptr = x;
     45             return T_NEWLINE;
     46         case ' ':
     47         case '\t':
     48         case '\r':
     49             x++;
     50             continue;
     51         case '#':
     52             while (*x && (*x != '\n')) x++;
     53             if (*x == '\n') {
     54                 state->ptr = x+1;
     55                 return T_NEWLINE;
     56             } else {
     57                 state->ptr = x;
     58                 return T_EOF;
     59             }
     60         default:
     61             goto text;
     62         }
     63     }
     64 
     65 textdone:
     66     state->ptr = x;
     67     *s = 0;
     68     return T_TEXT;
     69 text:
     70     state->text = s = x;
     71 textresume:
     72     for (;;) {
     73         switch (*x) {
     74         case 0:
     75             goto textdone;
     76         case ' ':
     77         case '\t':
     78         case '\r':
     79             x++;
     80             goto textdone;
     81         case '\n':
     82             state->nexttoken = T_NEWLINE;
     83             x++;
     84             goto textdone;
     85         case '"':
     86             x++;
     87             for (;;) {
     88                 switch (*x) {
     89                 case 0:
     90                         /* unterminated quoted thing */
     91                     state->ptr = x;
     92                     return T_EOF;
     93                 case '"':
     94                     x++;
     95                     goto textresume;
     96                 default:
     97                     *s++ = *x++;
     98                 }
     99             }
    100             break;
    101         case '\\':
    102             x++;
    103             switch (*x) {
    104             case 0:
    105                 goto textdone;
    106             case 'n':
    107                 *s++ = '\n';
    108                 break;
    109             case 'r':
    110                 *s++ = '\r';
    111                 break;
    112             case 't':
    113                 *s++ = '\t';
    114                 break;
    115             case '\\':
    116                 *s++ = '\\';
    117                 break;
    118             case '\r':
    119                     /* \ <cr> <lf> -> line continuation */
    120                 if (x[1] != '\n') {
    121                     x++;
    122                     continue;
    123                 }
    124             case '\n':
    125                     /* \ <lf> -> line continuation */
    126                 state->line++;
    127                 x++;
    128                     /* eat any extra whitespace */
    129                 while((*x == ' ') || (*x == '\t')) x++;
    130                 continue;
    131             default:
    132                     /* unknown escape -- just copy */
    133                 *s++ = *x++;
    134             }
    135             continue;
    136         default:
    137             *s++ = *x++;
    138         }
    139     }
    140     return T_EOF;
    141 }
    142