parser.cpp revision f3cf438714aa1284d8a58e2f3b108ba93f6d3abb
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 10void 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 char name_str[256] = ""; 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 "); 39 build_triggers_string(name_str, sizeof(name_str), act); 40 RAW("%s", name_str); 41 RAW("\n"); 42 43 list_for_each(node2, &act->commands) { 44 cmd = node_to_item(node2, struct command, clist); 45 RAW(" %p", cmd->func); 46 for (n = 0; n < cmd->nargs; n++) { 47 RAW(" %s", cmd->args[n]); 48 } 49 RAW("\n"); 50 } 51 RAW("\n"); 52 } 53#endif 54} 55 56void parse_error(struct parse_state *state, const char *fmt, ...) 57{ 58 va_list ap; 59 char buf[128]; 60 int off; 61 62 snprintf(buf, 128, "%s: %d: ", state->filename, state->line); 63 buf[127] = 0; 64 off = strlen(buf); 65 66 va_start(ap, fmt); 67 vsnprintf(buf + off, 128 - off, fmt, ap); 68 va_end(ap); 69 buf[127] = 0; 70 ERROR("%s", buf); 71} 72 73int next_token(struct parse_state *state) 74{ 75 char *x = state->ptr; 76 char *s; 77 78 if (state->nexttoken) { 79 int t = state->nexttoken; 80 state->nexttoken = 0; 81 return t; 82 } 83 84 for (;;) { 85 switch (*x) { 86 case 0: 87 state->ptr = x; 88 return T_EOF; 89 case '\n': 90 x++; 91 state->ptr = x; 92 return T_NEWLINE; 93 case ' ': 94 case '\t': 95 case '\r': 96 x++; 97 continue; 98 case '#': 99 while (*x && (*x != '\n')) x++; 100 if (*x == '\n') { 101 state->ptr = x+1; 102 return T_NEWLINE; 103 } else { 104 state->ptr = x; 105 return T_EOF; 106 } 107 default: 108 goto text; 109 } 110 } 111 112textdone: 113 state->ptr = x; 114 *s = 0; 115 return T_TEXT; 116text: 117 state->text = s = x; 118textresume: 119 for (;;) { 120 switch (*x) { 121 case 0: 122 goto textdone; 123 case ' ': 124 case '\t': 125 case '\r': 126 x++; 127 goto textdone; 128 case '\n': 129 state->nexttoken = T_NEWLINE; 130 x++; 131 goto textdone; 132 case '"': 133 x++; 134 for (;;) { 135 switch (*x) { 136 case 0: 137 /* unterminated quoted thing */ 138 state->ptr = x; 139 return T_EOF; 140 case '"': 141 x++; 142 goto textresume; 143 default: 144 *s++ = *x++; 145 } 146 } 147 break; 148 case '\\': 149 x++; 150 switch (*x) { 151 case 0: 152 goto textdone; 153 case 'n': 154 *s++ = '\n'; 155 break; 156 case 'r': 157 *s++ = '\r'; 158 break; 159 case 't': 160 *s++ = '\t'; 161 break; 162 case '\\': 163 *s++ = '\\'; 164 break; 165 case '\r': 166 /* \ <cr> <lf> -> line continuation */ 167 if (x[1] != '\n') { 168 x++; 169 continue; 170 } 171 case '\n': 172 /* \ <lf> -> line continuation */ 173 state->line++; 174 x++; 175 /* eat any extra whitespace */ 176 while((*x == ' ') || (*x == '\t')) x++; 177 continue; 178 default: 179 /* unknown escape -- just copy */ 180 *s++ = *x++; 181 } 182 continue; 183 default: 184 *s++ = *x++; 185 } 186 } 187 return T_EOF; 188} 189