blob: 80bfb095fb203f75adcc9cba7666967e10821297 [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 "log.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08007
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08008#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;
Badhri Jagan Sridharan0b415122014-10-10 23:19:06 -070018 char name_str[256] = "";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080019 struct socketinfo *si;
20 int n;
Badhri Jagan Sridharan0b415122014-10-10 23:19:06 -070021
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080022 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);
Badhri Jagan Sridharan0b415122014-10-10 23:19:06 -070038 RAW("on ");
39 build_triggers_string(name_str, sizeof(name_str), act);
40 RAW("%s", name_str);
41 RAW("\n");
42
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080043 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
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080056void 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
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080073int 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':
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080090 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++;
Bruce Beare1be69682010-12-26 09:55:10 -0800100 if (*x == '\n') {
101 state->ptr = x+1;
102 return T_NEWLINE;
103 } else {
104 state->ptr = x;
105 return T_EOF;
106 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800107 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}