blob: cfcfabd7a069eaa4f5c1ec61ea67c92eeab83f1d [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);
Roman Zippel3370f9f2005-11-08 21:34:52 -080093 zconflval.id = id;
Roman Zippel7a884882005-11-08 21:34:51 -080094 return id->token;
95 }
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 alloc_string(yytext, yyleng);
97 zconflval.string = text;
98 return T_WORD;
99 }
100 .
101 \n current_file->lineno++; BEGIN(INITIAL);
102}
103
104<PARAM>{
105 "&&" return T_AND;
106 "||" return T_OR;
107 "(" return T_OPEN_PAREN;
108 ")" return T_CLOSE_PAREN;
109 "!" return T_NOT;
110 "=" return T_EQUAL;
111 "!=" return T_UNEQUAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 \"|\' {
113 str = yytext[0];
114 new_string();
115 BEGIN(STRING);
116 }
117 \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
118 --- /* ignore */
119 ({n}|[-/.])+ {
Roman Zippel7a884882005-11-08 21:34:51 -0800120 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
Roman Zippel3370f9f2005-11-08 21:34:52 -0800121 if (id && id->flags & TF_PARAM) {
122 zconflval.id = id;
Roman Zippel7a884882005-11-08 21:34:51 -0800123 return id->token;
Roman Zippel3370f9f2005-11-08 21:34:52 -0800124 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 alloc_string(yytext, yyleng);
126 zconflval.string = text;
127 return T_WORD;
128 }
129 #.* /* comment */
130 \\\n current_file->lineno++;
131 .
132 <<EOF>> {
133 BEGIN(INITIAL);
134 }
135}
136
137<STRING>{
138 [^'"\\\n]+/\n {
139 append_string(yytext, yyleng);
140 zconflval.string = text;
141 return T_WORD_QUOTE;
142 }
143 [^'"\\\n]+ {
144 append_string(yytext, yyleng);
145 }
146 \\.?/\n {
147 append_string(yytext + 1, yyleng - 1);
148 zconflval.string = text;
149 return T_WORD_QUOTE;
150 }
151 \\.? {
152 append_string(yytext + 1, yyleng - 1);
153 }
154 \'|\" {
155 if (str == yytext[0]) {
156 BEGIN(PARAM);
157 zconflval.string = text;
158 return T_WORD_QUOTE;
159 } else
160 append_string(yytext, 1);
161 }
162 \n {
163 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
164 current_file->lineno++;
165 BEGIN(INITIAL);
166 return T_EOL;
167 }
168 <<EOF>> {
169 BEGIN(INITIAL);
170 }
171}
172
173<HELP>{
174 [ \t]+ {
175 ts = 0;
176 for (i = 0; i < yyleng; i++) {
177 if (yytext[i] == '\t')
178 ts = (ts & ~7) + 8;
179 else
180 ts++;
181 }
182 last_ts = ts;
183 if (first_ts) {
184 if (ts < first_ts) {
185 zconf_endhelp();
186 return T_HELPTEXT;
187 }
188 ts -= first_ts;
189 while (ts > 8) {
190 append_string(" ", 8);
191 ts -= 8;
192 }
193 append_string(" ", ts);
194 }
195 }
196 [ \t]*\n/[^ \t\n] {
197 current_file->lineno++;
198 zconf_endhelp();
199 return T_HELPTEXT;
200 }
201 [ \t]*\n {
202 current_file->lineno++;
203 append_string("\n", 1);
204 }
205 [^ \t\n].* {
206 append_string(yytext, yyleng);
207 if (!first_ts)
208 first_ts = last_ts;
209 }
210 <<EOF>> {
211 zconf_endhelp();
212 return T_HELPTEXT;
213 }
214}
215
216<<EOF>> {
217 if (current_buf) {
218 zconf_endfile();
219 return T_EOF;
220 }
221 fclose(yyin);
222 yyterminate();
223}
224
225%%
226void zconf_starthelp(void)
227{
228 new_string();
229 last_ts = first_ts = 0;
230 BEGIN(HELP);
231}
232
233static void zconf_endhelp(void)
234{
235 zconflval.string = text;
236 BEGIN(INITIAL);
237}
238
239
240/*
241 * Try to open specified file with following names:
242 * ./name
243 * $(srctree)/name
244 * The latter is used when srctree is separate from objtree
245 * when compiling the kernel.
246 * Return NULL if file is not found.
247 */
248FILE *zconf_fopen(const char *name)
249{
250 char *env, fullname[PATH_MAX+1];
251 FILE *f;
252
253 f = fopen(name, "r");
254 if (!f && name[0] != '/') {
255 env = getenv(SRCTREE);
256 if (env) {
257 sprintf(fullname, "%s/%s", env, name);
258 f = fopen(fullname, "r");
259 }
260 }
261 return f;
262}
263
264void zconf_initscan(const char *name)
265{
266 yyin = zconf_fopen(name);
267 if (!yyin) {
268 printf("can't find file %s\n", name);
269 exit(1);
270 }
271
272 current_buf = malloc(sizeof(*current_buf));
273 memset(current_buf, 0, sizeof(*current_buf));
274
275 current_file = file_lookup(name);
276 current_file->lineno = 1;
277 current_file->flags = FILE_BUSY;
278}
279
280void zconf_nextfile(const char *name)
281{
282 struct file *file = file_lookup(name);
283 struct buffer *buf = malloc(sizeof(*buf));
284 memset(buf, 0, sizeof(*buf));
285
286 current_buf->state = YY_CURRENT_BUFFER;
287 yyin = zconf_fopen(name);
288 if (!yyin) {
289 printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
290 exit(1);
291 }
292 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
293 buf->parent = current_buf;
294 current_buf = buf;
295
296 if (file->flags & FILE_BUSY) {
297 printf("recursive scan (%s)?\n", name);
298 exit(1);
299 }
300 if (file->flags & FILE_SCANNED) {
301 printf("file %s already scanned?\n", name);
302 exit(1);
303 }
304 file->flags |= FILE_BUSY;
305 file->lineno = 1;
306 file->parent = current_file;
307 current_file = file;
308}
309
310static struct buffer *zconf_endfile(void)
311{
312 struct buffer *parent;
313
314 current_file->flags |= FILE_SCANNED;
315 current_file->flags &= ~FILE_BUSY;
316 current_file = current_file->parent;
317
318 parent = current_buf->parent;
319 if (parent) {
320 fclose(yyin);
321 yy_delete_buffer(YY_CURRENT_BUFFER);
322 yy_switch_to_buffer(parent->state);
323 }
324 free(current_buf);
325 current_buf = parent;
326
327 return parent;
328}
329
330int zconf_lineno(void)
331{
332 if (current_buf)
333 return current_file->lineno - 1;
334 else
335 return 0;
336}
337
338char *zconf_curname(void)
339{
340 if (current_buf)
341 return current_file->name;
342 else
343 return "<none>";
344}