add initial version of a package feeds management script
[openwrt.git] / scripts / config / zconf.l
1 %option backup nostdinit noyywrap never-interactive full ecs
2 %option 8bit backup nodefault perf-report perf-report
3 %x COMMAND HELP STRING PARAM
4 %{
5 /*
6 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
7 * Released under the terms of the GNU GPL v2.0.
8 */
9
10 #include <limits.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <glob.h>
16
17 #define LKC_DIRECT_LINK
18 #include "lkc.h"
19
20 #define START_STRSIZE 16
21
22 static struct {
23 struct file *file;
24 int lineno;
25 } current_pos;
26
27 static char *text;
28 static int text_size, text_asize;
29
30 struct buffer {
31 struct buffer *parent;
32 YY_BUFFER_STATE state;
33 };
34
35 struct buffer *current_buf;
36
37 static int last_ts, first_ts;
38
39 static void zconf_endhelp(void);
40 static void zconf_endfile(void);
41
42 void new_string(void)
43 {
44 text = malloc(START_STRSIZE);
45 text_asize = START_STRSIZE;
46 text_size = 0;
47 *text = 0;
48 }
49
50 void append_string(const char *str, int size)
51 {
52 int new_size = text_size + size + 1;
53 if (new_size > text_asize) {
54 new_size += START_STRSIZE - 1;
55 new_size &= -START_STRSIZE;
56 text = realloc(text, new_size);
57 text_asize = new_size;
58 }
59 memcpy(text + text_size, str, size);
60 text_size += size;
61 text[text_size] = 0;
62 }
63
64 void alloc_string(const char *str, int size)
65 {
66 text = malloc(size + 1);
67 memcpy(text, str, size);
68 text[size] = 0;
69 }
70 %}
71
72 ws [ \n\t]
73 n [A-Za-z0-9_]
74
75 %%
76 int str = 0;
77 int ts, i;
78
79 [ \t]*#.*\n |
80 [ \t]*\n {
81 current_file->lineno++;
82 return T_EOL;
83 }
84 [ \t]*#.*
85
86
87 [ \t]+ {
88 BEGIN(COMMAND);
89 }
90
91 . {
92 unput(yytext[0]);
93 BEGIN(COMMAND);
94 }
95
96
97 <COMMAND>{
98 {n}+ {
99 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
100 BEGIN(PARAM);
101 current_pos.file = current_file;
102 current_pos.lineno = current_file->lineno;
103 if (id && id->flags & TF_COMMAND) {
104 zconflval.id = id;
105 return id->token;
106 }
107 alloc_string(yytext, yyleng);
108 zconflval.string = text;
109 return T_WORD;
110 }
111 .
112 \n {
113 BEGIN(INITIAL);
114 current_file->lineno++;
115 return T_EOL;
116 }
117 }
118
119 <PARAM>{
120 "&&" return T_AND;
121 "||" return T_OR;
122 "(" return T_OPEN_PAREN;
123 ")" return T_CLOSE_PAREN;
124 "!" return T_NOT;
125 "=" return T_EQUAL;
126 "!=" return T_UNEQUAL;
127 \"|\' {
128 str = yytext[0];
129 new_string();
130 BEGIN(STRING);
131 }
132 \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
133 --- /* ignore */
134 ({n}|[-/.])+ {
135 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
136 if (id && id->flags & TF_PARAM) {
137 zconflval.id = id;
138 return id->token;
139 }
140 alloc_string(yytext, yyleng);
141 zconflval.string = text;
142 return T_WORD;
143 }
144 #.* /* comment */
145 \\\n current_file->lineno++;
146 .
147 <<EOF>> {
148 BEGIN(INITIAL);
149 }
150 }
151
152 <STRING>{
153 [^'"\\\n]+/\n {
154 append_string(yytext, yyleng);
155 zconflval.string = text;
156 return T_WORD_QUOTE;
157 }
158 [^'"\\\n]+ {
159 append_string(yytext, yyleng);
160 }
161 \\.?/\n {
162 append_string(yytext + 1, yyleng - 1);
163 zconflval.string = text;
164 return T_WORD_QUOTE;
165 }
166 \\.? {
167 append_string(yytext + 1, yyleng - 1);
168 }
169 \'|\" {
170 if (str == yytext[0]) {
171 BEGIN(PARAM);
172 zconflval.string = text;
173 return T_WORD_QUOTE;
174 } else
175 append_string(yytext, 1);
176 }
177 \n {
178 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
179 current_file->lineno++;
180 BEGIN(INITIAL);
181 return T_EOL;
182 }
183 <<EOF>> {
184 BEGIN(INITIAL);
185 }
186 }
187
188 <HELP>{
189 [ \t]+ {
190 ts = 0;
191 for (i = 0; i < yyleng; i++) {
192 if (yytext[i] == '\t')
193 ts = (ts & ~7) + 8;
194 else
195 ts++;
196 }
197 last_ts = ts;
198 if (first_ts) {
199 if (ts < first_ts) {
200 zconf_endhelp();
201 return T_HELPTEXT;
202 }
203 ts -= first_ts;
204 while (ts > 8) {
205 append_string(" ", 8);
206 ts -= 8;
207 }
208 append_string(" ", ts);
209 }
210 }
211 [ \t]*\n/[^ \t\n] {
212 current_file->lineno++;
213 zconf_endhelp();
214 return T_HELPTEXT;
215 }
216 [ \t]*\n {
217 current_file->lineno++;
218 append_string("\n", 1);
219 }
220 [^ \t\n].* {
221 append_string(yytext, yyleng);
222 if (!first_ts)
223 first_ts = last_ts;
224 }
225 <<EOF>> {
226 zconf_endhelp();
227 return T_HELPTEXT;
228 }
229 }
230
231 <<EOF>> {
232 if (current_file) {
233 zconf_endfile();
234 return T_EOL;
235 }
236 fclose(yyin);
237 yyterminate();
238 }
239
240 %%
241 void zconf_starthelp(void)
242 {
243 new_string();
244 last_ts = first_ts = 0;
245 BEGIN(HELP);
246 }
247
248 static void zconf_endhelp(void)
249 {
250 zconflval.string = text;
251 BEGIN(INITIAL);
252 }
253
254
255 /*
256 * Try to open specified file with following names:
257 * ./name
258 * $(srctree)/name
259 * The latter is used when srctree is separate from objtree
260 * when compiling the kernel.
261 * Return NULL if file is not found.
262 */
263 FILE *zconf_fopen(const char *name)
264 {
265 char *env, fullname[PATH_MAX+1];
266 FILE *f;
267
268 f = fopen(name, "r");
269 if (!f && name[0] != '/') {
270 env = getenv(SRCTREE);
271 if (env) {
272 sprintf(fullname, "%s/%s", env, name);
273 f = fopen(fullname, "r");
274 }
275 }
276 return f;
277 }
278
279 void zconf_initscan(const char *name)
280 {
281 yyin = zconf_fopen(name);
282 if (!yyin) {
283 printf("can't find file %s\n", name);
284 exit(1);
285 }
286
287 current_buf = malloc(sizeof(*current_buf));
288 memset(current_buf, 0, sizeof(*current_buf));
289
290 current_file = file_lookup(name);
291 current_file->lineno = 1;
292 current_file->flags = FILE_BUSY;
293 }
294
295 void zconf_nextfile(const char *name)
296 {
297 size_t i;
298 int retval;
299 glob_t files;
300 char *filename;
301 struct file *file;
302 struct buffer *buf;
303
304 retval = glob(name, GLOB_ERR | GLOB_MARK, NULL, &files);
305 if (retval == GLOB_NOSPACE || retval == GLOB_ABORTED || retval == GLOB_NOMATCH) {
306 printf("%s:%d: glob failed: %s \"%s\"\n", zconf_curname(), zconf_lineno(),
307 retval == GLOB_NOSPACE ? "failed to allocate memory" :
308 retval == GLOB_ABORTED ? "read error" : "no match",
309 name);
310 exit(1);
311 }
312
313 for (i = files.gl_pathc-1; i != (size_t)-1; --i) {
314 filename = files.gl_pathv[i];
315
316 file = file_lookup(filename);
317 buf = malloc(sizeof(*buf));
318 memset(buf, 0, sizeof(*buf));
319 current_buf->state = YY_CURRENT_BUFFER;
320 zconfin = zconf_fopen(filename);
321 if (!zconfin) {
322 printf("%s:%d: can't open file \"%s\"\n",
323 zconf_curname(), zconf_lineno(), filename);
324 exit(1);
325 }
326 zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
327 buf->parent = current_buf;
328 current_buf = buf;
329
330 if (file->flags & FILE_BUSY) {
331 printf("recursive scan (%s)?\n", filename);
332 exit(1);
333 }
334 if (file->flags & FILE_SCANNED) {
335 printf("file %s already scanned?\n", filename);
336 exit(1);
337 }
338 file->flags |= FILE_BUSY;
339 file->lineno = 1;
340 file->parent = current_file;
341 current_file = file;
342 }
343 }
344
345 static void zconf_endfile(void)
346 {
347 struct buffer *parent;
348
349 current_file->flags |= FILE_SCANNED;
350 current_file->flags &= ~FILE_BUSY;
351 current_file = current_file->parent;
352
353 parent = current_buf->parent;
354 if (parent) {
355 fclose(yyin);
356 yy_delete_buffer(YY_CURRENT_BUFFER);
357 yy_switch_to_buffer(parent->state);
358 }
359 free(current_buf);
360 current_buf = parent;
361 }
362
363 int zconf_lineno(void)
364 {
365 return current_pos.lineno;
366 }
367
368 char *zconf_curname(void)
369 {
370 return current_pos.file ? current_pos.file->name : "<none>";
371 }
This page took 0.058297 seconds and 5 git commands to generate.