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