|
|
1.1 root 1: %option backup nostdinit noyywrap never-interactive full ecs
2: %option 8bit backup nodefault perf-report perf-report
3: %option noinput
4: %x COMMAND HELP STRING PARAM
5: %{
6: /*
7: * Copyright (C) 2002 Roman Zippel <[email protected]>
8: * Released under the terms of the GNU GPL v2.0.
9: */
10:
11: #include <limits.h>
12: #include <stdio.h>
13: #include <stdlib.h>
14: #include <string.h>
15: #include <unistd.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: static 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: static 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: static 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: while (yyleng) {
222: if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
223: break;
224: yyleng--;
225: }
226: append_string(yytext, yyleng);
227: if (!first_ts)
228: first_ts = last_ts;
229: }
230: <<EOF>> {
231: zconf_endhelp();
232: return T_HELPTEXT;
233: }
234: }
235:
236: <<EOF>> {
237: if (current_file) {
238: zconf_endfile();
239: return T_EOL;
240: }
241: fclose(yyin);
242: yyterminate();
243: }
244:
245: %%
246: void zconf_starthelp(void)
247: {
248: new_string();
249: last_ts = first_ts = 0;
250: BEGIN(HELP);
251: }
252:
253: static void zconf_endhelp(void)
254: {
255: zconflval.string = text;
256: BEGIN(INITIAL);
257: }
258:
259:
260: /*
261: * Try to open specified file with following names:
262: * ./name
263: * $(srctree)/name
264: * The latter is used when srctree is separate from objtree
265: * when compiling the kernel.
266: * Return NULL if file is not found.
267: */
268: FILE *zconf_fopen(const char *name)
269: {
270: char *env, fullname[PATH_MAX+1];
271: FILE *f;
272:
273: f = fopen(name, "r");
274: if (!f && name != NULL && name[0] != '/') {
275: env = getenv(SRCTREE);
276: if (env) {
277: sprintf(fullname, "%s/%s", env, name);
278: f = fopen(fullname, "r");
279: }
280: }
281: return f;
282: }
283:
284: void zconf_initscan(const char *name)
285: {
286: yyin = zconf_fopen(name);
287: if (!yyin) {
288: printf("can't find file %s\n", name);
289: exit(1);
290: }
291:
292: current_buf = malloc(sizeof(*current_buf));
293: memset(current_buf, 0, sizeof(*current_buf));
294:
295: current_file = file_lookup(name);
296: current_file->lineno = 1;
297: current_file->flags = FILE_BUSY;
298: }
299:
300: void zconf_nextfile(const char *name)
301: {
302: struct file *file = file_lookup(name);
303: struct buffer *buf = malloc(sizeof(*buf));
304: memset(buf, 0, sizeof(*buf));
305:
306: current_buf->state = YY_CURRENT_BUFFER;
307: yyin = zconf_fopen(file->name);
308: if (!yyin) {
309: printf("%s:%d: can't open file \"%s\"\n",
310: zconf_curname(), zconf_lineno(), file->name);
311: exit(1);
312: }
313: yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
314: buf->parent = current_buf;
315: current_buf = buf;
316:
317: if (file->flags & FILE_BUSY) {
318: printf("%s:%d: do not source '%s' from itself\n",
319: zconf_curname(), zconf_lineno(), name);
320: exit(1);
321: }
322: if (file->flags & FILE_SCANNED) {
323: printf("%s:%d: file '%s' is already sourced from '%s'\n",
324: zconf_curname(), zconf_lineno(), name,
325: file->parent->name);
326: exit(1);
327: }
328: file->flags |= FILE_BUSY;
329: file->lineno = 1;
330: file->parent = current_file;
331: current_file = file;
332: }
333:
334: static void zconf_endfile(void)
335: {
336: struct buffer *parent;
337:
338: current_file->flags |= FILE_SCANNED;
339: current_file->flags &= ~FILE_BUSY;
340: current_file = current_file->parent;
341:
342: parent = current_buf->parent;
343: if (parent) {
344: fclose(yyin);
345: yy_delete_buffer(YY_CURRENT_BUFFER);
346: yy_switch_to_buffer(parent->state);
347: }
348: free(current_buf);
349: current_buf = parent;
350: }
351:
352: int zconf_lineno(void)
353: {
354: return current_pos.lineno;
355: }
356:
357: const char *zconf_curname(void)
358: {
359: return current_pos.file ? current_pos.file->name : "<none>";
360: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.