blob: 3dbaec185cc486d183ed5ba87cfe848635e4b968 [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
Adrian Bunkbe2be1d2008-07-17 02:07:59 +03003%option noinput
Linus Torvalds1da177e2005-04-16 15:20:36 -07004%x COMMAND HELP STRING PARAM
5%{
6/*
7 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
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
Roman Zippela02f0572005-11-08 21:34:53 -080022static struct {
23 struct file *file;
24 int lineno;
25} current_pos;
26
Roman Zippel7a884882005-11-08 21:34:51 -080027static char *text;
Linus Torvalds1da177e2005-04-16 15:20:36 -070028static 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);
Roman Zippela02f0572005-11-08 21:34:53 -080040static void zconf_endfile(void);
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
Josh Triplett65166572009-10-15 12:13:36 -070042static void new_string(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070043{
44 text = malloc(START_STRSIZE);
45 text_asize = START_STRSIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046 text_size = 0;
Roman Zippel7a884882005-11-08 21:34:51 -080047 *text = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070048}
49
Josh Triplett65166572009-10-15 12:13:36 -070050static void append_string(const char *str, int size)
Linus Torvalds1da177e2005-04-16 15:20:36 -070051{
52 int new_size = text_size + size + 1;
53 if (new_size > text_asize) {
Roman Zippel7a884882005-11-08 21:34:51 -080054 new_size += START_STRSIZE - 1;
55 new_size &= -START_STRSIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 text = realloc(text, new_size);
57 text_asize = new_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 }
Roman Zippel7a884882005-11-08 21:34:51 -080059 memcpy(text + text_size, str, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -070060 text_size += size;
Roman Zippel7a884882005-11-08 21:34:51 -080061 text[text_size] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070062}
63
Josh Triplett65166572009-10-15 12:13:36 -070064static void alloc_string(const char *str, int size)
Linus Torvalds1da177e2005-04-16 15:20:36 -070065{
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
Roman Zippela02f0572005-11-08 21:34:53 -080079[ \t]*#.*\n |
80[ \t]*\n {
81 current_file->lineno++;
82 return T_EOL;
83}
Linus Torvalds1da177e2005-04-16 15:20:36 -070084[ \t]*#.*
85
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
87[ \t]+ {
88 BEGIN(COMMAND);
89}
90
91. {
92 unput(yytext[0]);
93 BEGIN(COMMAND);
94}
95
96
97<COMMAND>{
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 {n}+ {
Roman Zippel7a884882005-11-08 21:34:51 -080099 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
Roman Zippela02f0572005-11-08 21:34:53 -0800100 BEGIN(PARAM);
101 current_pos.file = current_file;
102 current_pos.lineno = current_file->lineno;
Roman Zippel7a884882005-11-08 21:34:51 -0800103 if (id && id->flags & TF_COMMAND) {
Roman Zippel3370f9f2005-11-08 21:34:52 -0800104 zconflval.id = id;
Roman Zippel7a884882005-11-08 21:34:51 -0800105 return id->token;
106 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 alloc_string(yytext, yyleng);
108 zconflval.string = text;
109 return T_WORD;
110 }
111 .
Roman Zippela02f0572005-11-08 21:34:53 -0800112 \n {
113 BEGIN(INITIAL);
114 current_file->lineno++;
115 return T_EOL;
116 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117}
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;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 \"|\' {
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}|[-/.])+ {
Roman Zippel7a884882005-11-08 21:34:51 -0800135 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
Roman Zippel3370f9f2005-11-08 21:34:52 -0800136 if (id && id->flags & TF_PARAM) {
137 zconflval.id = id;
Roman Zippel7a884882005-11-08 21:34:51 -0800138 return id->token;
Roman Zippel3370f9f2005-11-08 21:34:52 -0800139 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 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].* {
EGRY Gaborf7a4b4c2008-01-11 23:55:20 +0100221 while (yyleng) {
222 if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
223 break;
224 yyleng--;
225 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226 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>> {
Roman Zippela02f0572005-11-08 21:34:53 -0800237 if (current_file) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238 zconf_endfile();
Roman Zippela02f0572005-11-08 21:34:53 -0800239 return T_EOL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 }
241 fclose(yyin);
242 yyterminate();
243}
244
245%%
246void zconf_starthelp(void)
247{
248 new_string();
249 last_ts = first_ts = 0;
250 BEGIN(HELP);
251}
252
253static 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 */
268FILE *zconf_fopen(const char *name)
269{
270 char *env, fullname[PATH_MAX+1];
271 FILE *f;
272
273 f = fopen(name, "r");
Marcin Garski11de39e2007-05-05 22:49:00 +0200274 if (!f && name != NULL && name[0] != '/') {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 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
284void 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
300void 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;
Arnaud Lacombee82dae92010-09-04 16:09:26 -0400307 yyin = zconf_fopen(file->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 if (!yyin) {
Arnaud Lacombee82dae92010-09-04 16:09:26 -0400309 printf("%s:%d: can't open file \"%s\"\n",
310 zconf_curname(), zconf_lineno(), file->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311 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) {
Sam Ravnborg78260052008-12-27 21:51:59 +0100318 printf("%s:%d: do not source '%s' from itself\n",
319 zconf_curname(), zconf_lineno(), name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 exit(1);
321 }
322 if (file->flags & FILE_SCANNED) {
Sam Ravnborg78260052008-12-27 21:51:59 +0100323 printf("%s:%d: file '%s' is already sourced from '%s'\n",
324 zconf_curname(), zconf_lineno(), name,
325 file->parent->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 exit(1);
327 }
328 file->flags |= FILE_BUSY;
329 file->lineno = 1;
330 file->parent = current_file;
331 current_file = file;
332}
333
Roman Zippela02f0572005-11-08 21:34:53 -0800334static void zconf_endfile(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335{
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;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350}
351
352int zconf_lineno(void)
353{
Roman Zippela02f0572005-11-08 21:34:53 -0800354 return current_pos.lineno;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355}
356
Arnaud Lacombe2e7a0912010-09-04 16:03:30 -0400357const char *zconf_curname(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358{
Roman Zippela02f0572005-11-08 21:34:53 -0800359 return current_pos.file ? current_pos.file->name : "<none>";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360}