blob: 3c2ec00b4996b0d99df75c460ca200b392a535cc [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':
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080086 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++;
Bruce Beare1be69682010-12-26 09:55:10 -080096 if (*x == '\n') {
97 state->ptr = x+1;
98 return T_NEWLINE;
99 } else {
100 state->ptr = x;
101 return T_EOF;
102 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800103 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}