blob: ec902091be978e496fbc345018f6969e1bfa6ab6 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001%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
16#define LKC_DIRECT_LINK
17#include "lkc.h"
18
19#define START_STRSIZE 16
20
Roman Zippel7a884882005-11-08 21:34:51 -080021static char *text;
Linus Torvalds1da177e2005-04-16 15:20:36 -070022static int text_size, text_asize;
23
24struct buffer {
25 struct buffer *parent;
26 YY_BUFFER_STATE state;
27};
28
29struct buffer *current_buf;
30
31static int last_ts, first_ts;
32
33static void zconf_endhelp(void);
34static struct buffer *zconf_endfile(void);
35
36void new_string(void)
37{
38 text = malloc(START_STRSIZE);
39 text_asize = START_STRSIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -070040 text_size = 0;
Roman Zippel7a884882005-11-08 21:34:51 -080041 *text = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070042}
43
44void append_string(const char *str, int size)
45{
46 int new_size = text_size + size + 1;
47 if (new_size > text_asize) {
Roman Zippel7a884882005-11-08 21:34:51 -080048 new_size += START_STRSIZE - 1;
49 new_size &= -START_STRSIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -070050 text = realloc(text, new_size);
51 text_asize = new_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 }
Roman Zippel7a884882005-11-08 21:34:51 -080053 memcpy(text + text_size, str, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 text_size += size;
Roman Zippel7a884882005-11-08 21:34:51 -080055 text[text_size] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070056}
57
58void alloc_string(const char *str, int size)
59{
60 text = malloc(size + 1);
61 memcpy(text, str, size);
62 text[size] = 0;
63}
64%}
65
66ws [ \n\t]
67n [A-Za-z0-9_]
68
69%%
70 int str = 0;
71 int ts, i;
72
73[ \t]*#.*\n current_file->lineno++;
74[ \t]*#.*
75
76[ \t]*\n current_file->lineno++; return T_EOL;
77
78[ \t]+ {
79 BEGIN(COMMAND);
80}
81
82. {
83 unput(yytext[0]);
84 BEGIN(COMMAND);
85}
86
87
88<COMMAND>{
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 {n}+ {
Roman Zippel7a884882005-11-08 21:34:51 -080090 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
91 if (id && id->flags & TF_COMMAND) {
92 BEGIN(PARAM);
93 return id->token;
94 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 alloc_string(yytext, yyleng);
96 zconflval.string = text;
97 return T_WORD;
98 }
99 .
100 \n current_file->lineno++; BEGIN(INITIAL);
101}
102
103<PARAM>{
104 "&&" return T_AND;
105 "||" return T_OR;
106 "(" return T_OPEN_PAREN;
107 ")" return T_CLOSE_PAREN;
108 "!" return T_NOT;
109 "=" return T_EQUAL;
110 "!=" return T_UNEQUAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 \"|\' {
112 str = yytext[0];
113 new_string();
114 BEGIN(STRING);
115 }
116 \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
117 --- /* ignore */
118 ({n}|[-/.])+ {
Roman Zippel7a884882005-11-08 21:34:51 -0800119 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
120 if (id && id->flags & TF_PARAM)
121 return id->token;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 alloc_string(yytext, yyleng);
123 zconflval.string = text;
124 return T_WORD;
125 }
126 #.* /* comment */
127 \\\n current_file->lineno++;
128 .
129 <<EOF>> {
130 BEGIN(INITIAL);
131 }
132}
133
134<STRING>{
135 [^'"\\\n]+/\n {
136 append_string(yytext, yyleng);
137 zconflval.string = text;
138 return T_WORD_QUOTE;
139 }
140 [^'"\\\n]+ {
141 append_string(yytext, yyleng);
142 }
143 \\.?/\n {
144 append_string(yytext + 1, yyleng - 1);
145 zconflval.string = text;
146 return T_WORD_QUOTE;
147 }
148 \\.? {
149 append_string(yytext + 1, yyleng - 1);
150 }
151 \'|\" {
152 if (str == yytext[0]) {
153 BEGIN(PARAM);
154 zconflval.string = text;
155 return T_WORD_QUOTE;
156 } else
157 append_string(yytext, 1);
158 }
159 \n {
160 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
161 current_file->lineno++;
162 BEGIN(INITIAL);
163 return T_EOL;
164 }
165 <<EOF>> {
166 BEGIN(INITIAL);
167 }
168}
169
170<HELP>{
171 [ \t]+ {
172 ts = 0;
173 for (i = 0; i < yyleng; i++) {
174 if (yytext[i] == '\t')
175 ts = (ts & ~7) + 8;
176 else
177 ts++;
178 }
179 last_ts = ts;
180 if (first_ts) {
181 if (ts < first_ts) {
182 zconf_endhelp();
183 return T_HELPTEXT;
184 }
185 ts -= first_ts;
186 while (ts > 8) {
187 append_string(" ", 8);
188 ts -= 8;
189 }
190 append_string(" ", ts);
191 }
192 }
193 [ \t]*\n/[^ \t\n] {
194 current_file->lineno++;
195 zconf_endhelp();
196 return T_HELPTEXT;
197 }
198 [ \t]*\n {
199 current_file->lineno++;
200 append_string("\n", 1);
201 }
202 [^ \t\n].* {
203 append_string(yytext, yyleng);
204 if (!first_ts)
205 first_ts = last_ts;
206 }
207 <<EOF>> {
208 zconf_endhelp();
209 return T_HELPTEXT;
210 }
211}
212
213<<EOF>> {
214 if (current_buf) {
215 zconf_endfile();
216 return T_EOF;
217 }
218 fclose(yyin);
219 yyterminate();
220}
221
222%%
223void zconf_starthelp(void)
224{
225 new_string();
226 last_ts = first_ts = 0;
227 BEGIN(HELP);
228}
229
230static void zconf_endhelp(void)
231{
232 zconflval.string = text;
233 BEGIN(INITIAL);
234}
235
236
237/*
238 * Try to open specified file with following names:
239 * ./name
240 * $(srctree)/name
241 * The latter is used when srctree is separate from objtree
242 * when compiling the kernel.
243 * Return NULL if file is not found.
244 */
245FILE *zconf_fopen(const char *name)
246{
247 char *env, fullname[PATH_MAX+1];
248 FILE *f;
249
250 f = fopen(name, "r");
251 if (!f && name[0] != '/') {
252 env = getenv(SRCTREE);
253 if (env) {
254 sprintf(fullname, "%s/%s", env, name);
255 f = fopen(fullname, "r");
256 }
257 }
258 return f;
259}
260
261void zconf_initscan(const char *name)
262{
263 yyin = zconf_fopen(name);
264 if (!yyin) {
265 printf("can't find file %s\n", name);
266 exit(1);
267 }
268
269 current_buf = malloc(sizeof(*current_buf));
270 memset(current_buf, 0, sizeof(*current_buf));
271
272 current_file = file_lookup(name);
273 current_file->lineno = 1;
274 current_file->flags = FILE_BUSY;
275}
276
277void zconf_nextfile(const char *name)
278{
279 struct file *file = file_lookup(name);
280 struct buffer *buf = malloc(sizeof(*buf));
281 memset(buf, 0, sizeof(*buf));
282
283 current_buf->state = YY_CURRENT_BUFFER;
284 yyin = zconf_fopen(name);
285 if (!yyin) {
286 printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
287 exit(1);
288 }
289 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
290 buf->parent = current_buf;
291 current_buf = buf;
292
293 if (file->flags & FILE_BUSY) {
294 printf("recursive scan (%s)?\n", name);
295 exit(1);
296 }
297 if (file->flags & FILE_SCANNED) {
298 printf("file %s already scanned?\n", name);
299 exit(1);
300 }
301 file->flags |= FILE_BUSY;
302 file->lineno = 1;
303 file->parent = current_file;
304 current_file = file;
305}
306
307static struct buffer *zconf_endfile(void)
308{
309 struct buffer *parent;
310
311 current_file->flags |= FILE_SCANNED;
312 current_file->flags &= ~FILE_BUSY;
313 current_file = current_file->parent;
314
315 parent = current_buf->parent;
316 if (parent) {
317 fclose(yyin);
318 yy_delete_buffer(YY_CURRENT_BUFFER);
319 yy_switch_to_buffer(parent->state);
320 }
321 free(current_buf);
322 current_buf = parent;
323
324 return parent;
325}
326
327int zconf_lineno(void)
328{
329 if (current_buf)
330 return current_file->lineno - 1;
331 else
332 return 0;
333}
334
335char *zconf_curname(void)
336{
337 if (current_buf)
338 return current_file->name;
339 else
340 return "<none>";
341}