parser.c revision 6310a8261c922533a692fb3e74ece2da98d4bafa
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 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 105textdone: 106 state->ptr = x; 107 *s = 0; 108 return T_TEXT; 109text: 110 state->text = s = x; 111textresume: 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