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