Root/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
22static struct {
23    struct file *file;
24    int lineno;
25} current_pos;
26
27static char *text;
28static int text_size, text_asize;
29
30struct buffer {
31        struct buffer *parent;
32        YY_BUFFER_STATE state;
33};
34
35struct buffer *current_buf;
36
37static int last_ts, first_ts;
38
39static void zconf_endhelp(void);
40static void zconf_endfile(void);
41
42void new_string(void)
43{
44    text = malloc(START_STRSIZE);
45    text_asize = START_STRSIZE;
46    text_size = 0;
47    *text = 0;
48}
49
50void 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
64void 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
72ws [ \n\t]
73n [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%%
241void zconf_starthelp(void)
242{
243    new_string();
244    last_ts = first_ts = 0;
245    BEGIN(HELP);
246}
247
248static 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 */
263FILE *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
279void 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
295void 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_NOMATCH)
306        return;
307
308    if (retval == GLOB_NOSPACE || retval == GLOB_ABORTED) {
309        printf("%s:%d: glob failed: %s \"%s\"\n", zconf_curname(), zconf_lineno(),
310            retval == GLOB_NOSPACE ? "failed to allocate memory" :
311                retval == GLOB_ABORTED ? "read error" : "no match",
312            name);
313        exit(1);
314    }
315
316    for (i = files.gl_pathc-1; i != (size_t)-1; --i) {
317        filename = files.gl_pathv[i];
318
319        file = file_lookup(filename);
320        buf = malloc(sizeof(*buf));
321        memset(buf, 0, sizeof(*buf));
322        current_buf->state = YY_CURRENT_BUFFER;
323        zconfin = zconf_fopen(filename);
324        if (!zconfin) {
325            printf("%s:%d: can't open file \"%s\"\n",
326                zconf_curname(), zconf_lineno(), filename);
327            exit(1);
328        }
329        zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
330        buf->parent = current_buf;
331        current_buf = buf;
332
333        if (file->flags & FILE_BUSY) {
334            printf("recursive scan (%s)?\n", filename);
335            exit(1);
336        }
337        if (file->flags & FILE_SCANNED) {
338            printf("file %s already scanned?\n", filename);
339            exit(1);
340        }
341        file->flags |= FILE_BUSY;
342        file->lineno = 1;
343        file->parent = current_file;
344        current_file = file;
345    }
346}
347
348static void zconf_endfile(void)
349{
350    struct buffer *parent;
351
352    current_file->flags |= FILE_SCANNED;
353    current_file->flags &= ~FILE_BUSY;
354    current_file = current_file->parent;
355
356    parent = current_buf->parent;
357    if (parent) {
358        fclose(yyin);
359        yy_delete_buffer(YY_CURRENT_BUFFER);
360        yy_switch_to_buffer(parent->state);
361    }
362    free(current_buf);
363    current_buf = parent;
364}
365
366int zconf_lineno(void)
367{
368    return current_pos.lineno;
369}
370
371char *zconf_curname(void)
372{
373    return current_pos.file ? current_pos.file->name : "<none>";
374}
375

Archive Download this file



interactive