• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
DUMP(void)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 
parse_error(struct parse_state * state,const char * fmt,...)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 
next_token(struct parse_state * state)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