Home | History | Annotate | Download | only in init
      1 #include <stdio.h>
      2 #include <stdarg.h>
      3 #include <string.h>
      4 
      5 #include "parser.h"
      6 #include "list.h"
      7 #include "log.h"
      8 
      9 #define RAW(x...) log_write(6, x)
     10 
     11 void DUMP(void)
     12 {
     13 #if 0
     14     struct service *svc;
     15     struct action *act;
     16     struct command *cmd;
     17     struct listnode *node;
     18     struct listnode *node2;
     19     struct socketinfo *si;
     20     int n;
     21 
     22     list_for_each(node, &service_list) {
     23         svc = node_to_item(node, struct service, slist);
     24         RAW("service %s\n", svc->name);
     25         RAW("  class '%s'\n", svc->classname);
     26         RAW("  exec");
     27         for (n = 0; n < svc->nargs; n++) {
     28             RAW(" '%s'", svc->args[n]);
     29         }
     30         RAW("\n");
     31         for (si = svc->sockets; si; si = si->next) {
     32             RAW("  socket %s %s 0%o\n", si->name, si->type, si->perm);
     33         }
     34     }
     35 
     36     list_for_each(node, &action_list) {
     37         act = node_to_item(node, struct action, alist);
     38         RAW("on %s\n", act->name);
     39         list_for_each(node2, &act->commands) {
     40             cmd = node_to_item(node2, struct command, clist);
     41             RAW("  %p", cmd->func);
     42             for (n = 0; n < cmd->nargs; n++) {
     43                 RAW(" %s", cmd->args[n]);
     44             }
     45             RAW("\n");
     46         }
     47         RAW("\n");
     48     }
     49 #endif
     50 }
     51 
     52 void parse_error(struct parse_state *state, const char *fmt, ...)
     53 {
     54     va_list ap;
     55     char buf[128];
     56     int off;
     57 
     58     snprintf(buf, 128, "%s: %d: ", state->filename, state->line);
     59     buf[127] = 0;
     60     off = strlen(buf);
     61 
     62     va_start(ap, fmt);
     63     vsnprintf(buf + off, 128 - off, fmt, ap);
     64     va_end(ap);
     65     buf[127] = 0;
     66     ERROR("%s", buf);
     67 }
     68 
     69 int next_token(struct parse_state *state)
     70 {
     71     char *x = state->ptr;
     72     char *s;
     73 
     74     if (state->nexttoken) {
     75         int t = state->nexttoken;
     76         state->nexttoken = 0;
     77         return t;
     78     }
     79 
     80     for (;;) {
     81         switch (*x) {
     82         case 0:
     83             state->ptr = x;
     84             return T_EOF;
     85         case '\n':
     86             state->line++;
     87             x++;
     88             state->ptr = x;
     89             return T_NEWLINE;
     90         case ' ':
     91         case '\t':
     92         case '\r':
     93             x++;
     94             continue;
     95         case '#':
     96             while (*x && (*x != '\n')) x++;
     97             state->line++;
     98             state->ptr = x;
     99             return T_NEWLINE;
    100         default:
    101             goto text;
    102         }
    103     }
    104 
    105 textdone:
    106     state->ptr = x;
    107     *s = 0;
    108     return T_TEXT;
    109 text:
    110     state->text = s = x;
    111 textresume:
    112     for (;;) {
    113         switch (*x) {
    114         case 0:
    115             goto textdone;
    116         case ' ':
    117         case '\t':
    118         case '\r':
    119             x++;
    120             goto textdone;
    121         case '\n':
    122             state->nexttoken = T_NEWLINE;
    123             x++;
    124             goto textdone;
    125         case '"':
    126             x++;
    127             for (;;) {
    128                 switch (*x) {
    129                 case 0:
    130                         /* unterminated quoted thing */
    131                     state->ptr = x;
    132                     return T_EOF;
    133                 case '"':
    134                     x++;
    135                     goto textresume;
    136                 default:
    137                     *s++ = *x++;
    138                 }
    139             }
    140             break;
    141         case '\\':
    142             x++;
    143             switch (*x) {
    144             case 0:
    145                 goto textdone;
    146             case 'n':
    147                 *s++ = '\n';
    148                 break;
    149             case 'r':
    150                 *s++ = '\r';
    151                 break;
    152             case 't':
    153                 *s++ = '\t';
    154                 break;
    155             case '\\':
    156                 *s++ = '\\';
    157                 break;
    158             case '\r':
    159                     /* \ <cr> <lf> -> line continuation */
    160                 if (x[1] != '\n') {
    161                     x++;
    162                     continue;
    163                 }
    164             case '\n':
    165                     /* \ <lf> -> line continuation */
    166                 state->line++;
    167                 x++;
    168                     /* eat any extra whitespace */
    169                 while((*x == ' ') || (*x == '\t')) x++;
    170                 continue;
    171             default:
    172                     /* unknown escape -- just copy */
    173                 *s++ = *x++;
    174             }
    175             continue;
    176         default:
    177             *s++ = *x++;
    178         }
    179     }
    180     return T_EOF;
    181 }
    182