blob: 2f36ac76a496c23854158a5c32e52e812d28e7ef [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001#include <stdio.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002#include <stdarg.h>
3#include <string.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08004
Colin Crossca7648d2010-04-13 19:29:51 -07005#include "parser.h"
Colin Crossed8a7d82010-04-19 17:05:34 -07006#include "list.h"
7#include "log.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08008
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08009#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
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080052void 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
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080069int 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}