parser.c revision 1be6968d9d51f43fdb00535708a6fed0be6bfbca
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 11void 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 52void 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 69int 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 x++; 87 state->ptr = x; 88 return T_NEWLINE; 89 case ' ': 90 case '\t': 91 case '\r': 92 x++; 93 continue; 94 case '#': 95 while (*x && (*x != '\n')) x++; 96 if (*x == '\n') { 97 state->ptr = x+1; 98 return T_NEWLINE; 99 } else { 100 state->ptr = x; 101 return T_EOF; 102 } 103 default: 104 goto text; 105 } 106 } 107 108textdone: 109 state->ptr = x; 110 *s = 0; 111 return T_TEXT; 112text: 113 state->text = s = x; 114textresume: 115 for (;;) { 116 switch (*x) { 117 case 0: 118 goto textdone; 119 case ' ': 120 case '\t': 121 case '\r': 122 x++; 123 goto textdone; 124 case '\n': 125 state->nexttoken = T_NEWLINE; 126 x++; 127 goto textdone; 128 case '"': 129 x++; 130 for (;;) { 131 switch (*x) { 132 case 0: 133 /* unterminated quoted thing */ 134 state->ptr = x; 135 return T_EOF; 136 case '"': 137 x++; 138 goto textresume; 139 default: 140 *s++ = *x++; 141 } 142 } 143 break; 144 case '\\': 145 x++; 146 switch (*x) { 147 case 0: 148 goto textdone; 149 case 'n': 150 *s++ = '\n'; 151 break; 152 case 'r': 153 *s++ = '\r'; 154 break; 155 case 't': 156 *s++ = '\t'; 157 break; 158 case '\\': 159 *s++ = '\\'; 160 break; 161 case '\r': 162 /* \ <cr> <lf> -> line continuation */ 163 if (x[1] != '\n') { 164 x++; 165 continue; 166 } 167 case '\n': 168 /* \ <lf> -> line continuation */ 169 state->line++; 170 x++; 171 /* eat any extra whitespace */ 172 while((*x == ' ') || (*x == '\t')) x++; 173 continue; 174 default: 175 /* unknown escape -- just copy */ 176 *s++ = *x++; 177 } 178 continue; 179 default: 180 *s++ = *x++; 181 } 182 } 183 return T_EOF; 184} 185