blob: 376af6cf2f65e8d9a00c036cd277496f1386133a [file] [log] [blame]
Arnaud Lacombe674eed82011-06-07 13:34:05 -04001%option nostdinit noyywrap never-interactive full ecs
Masahiro Yamada18492682018-03-23 02:00:14 +09002%option 8bit nodefault yylineno
Masahiro Yamada9ced3bd2018-05-28 18:21:49 +09003%x COMMAND HELP STRING PARAM ASSIGN_VAL
Linus Torvalds1da177e2005-04-16 15:20:36 -07004%{
5/*
6 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
7 * Released under the terms of the GNU GPL v2.0.
8 */
9
Masahiro Yamada9ced3bd2018-05-28 18:21:49 +090010#include <assert.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011#include <limits.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <unistd.h>
16
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include "lkc.h"
18
19#define START_STRSIZE 16
20
Roman Zippela02f0572005-11-08 21:34:53 -080021static struct {
22 struct file *file;
23 int lineno;
24} current_pos;
25
Roman Zippel7a884882005-11-08 21:34:51 -080026static char *text;
Linus Torvalds1da177e2005-04-16 15:20:36 -070027static int text_size, text_asize;
28
29struct buffer {
Masahiro Yamadabb66fc62014-06-10 19:08:13 +090030 struct buffer *parent;
31 YY_BUFFER_STATE state;
Linus Torvalds1da177e2005-04-16 15:20:36 -070032};
33
34struct buffer *current_buf;
35
36static int last_ts, first_ts;
37
Masahiro Yamada104daea2018-05-28 18:21:40 +090038static char *expand_token(const char *in, size_t n);
39static void append_expanded_string(const char *in);
Linus Torvalds1da177e2005-04-16 15:20:36 -070040static void zconf_endhelp(void);
Roman Zippela02f0572005-11-08 21:34:53 -080041static void zconf_endfile(void);
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Josh Triplett65166572009-10-15 12:13:36 -070043static void new_string(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -070044{
Alan Cox177acf72012-11-06 14:32:08 +000045 text = xmalloc(START_STRSIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -070046 text_asize = START_STRSIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -070047 text_size = 0;
Roman Zippel7a884882005-11-08 21:34:51 -080048 *text = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070049}
50
Josh Triplett65166572009-10-15 12:13:36 -070051static void append_string(const char *str, int size)
Linus Torvalds1da177e2005-04-16 15:20:36 -070052{
53 int new_size = text_size + size + 1;
54 if (new_size > text_asize) {
Roman Zippel7a884882005-11-08 21:34:51 -080055 new_size += START_STRSIZE - 1;
56 new_size &= -START_STRSIZE;
Masahiro Yamadad717f242018-02-09 01:19:07 +090057 text = xrealloc(text, new_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 text_asize = new_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -070059 }
Roman Zippel7a884882005-11-08 21:34:51 -080060 memcpy(text + text_size, str, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -070061 text_size += size;
Roman Zippel7a884882005-11-08 21:34:51 -080062 text[text_size] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070063}
64
Josh Triplett65166572009-10-15 12:13:36 -070065static void alloc_string(const char *str, int size)
Linus Torvalds1da177e2005-04-16 15:20:36 -070066{
Alan Cox177acf72012-11-06 14:32:08 +000067 text = xmalloc(size + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 memcpy(text, str, size);
69 text[size] = 0;
70}
Andreas Ruprechtc2264562015-07-12 09:41:50 +020071
72static void warn_ignored_character(char chr)
73{
74 fprintf(stderr,
75 "%s:%d:warning: ignoring unsupported character '%c'\n",
76 zconf_curname(), zconf_lineno(), chr);
77}
Linus Torvalds1da177e2005-04-16 15:20:36 -070078%}
79
Andreas Ruprechtc2264562015-07-12 09:41:50 +020080n [A-Za-z0-9_-]
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
82%%
83 int str = 0;
84 int ts, i;
85
Roman Zippela02f0572005-11-08 21:34:53 -080086[ \t]*#.*\n |
87[ \t]*\n {
Roman Zippela02f0572005-11-08 21:34:53 -080088 return T_EOL;
89}
Linus Torvalds1da177e2005-04-16 15:20:36 -070090[ \t]*#.*
91
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
93[ \t]+ {
94 BEGIN(COMMAND);
95}
96
97. {
98 unput(yytext[0]);
99 BEGIN(COMMAND);
100}
101
102
103<COMMAND>{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 {n}+ {
Arnaud Lacombe61f956f2011-05-04 21:14:44 -0400105 const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
Roman Zippela02f0572005-11-08 21:34:53 -0800106 current_pos.file = current_file;
Masahiro Yamada18492682018-03-23 02:00:14 +0900107 current_pos.lineno = yylineno;
Roman Zippel7a884882005-11-08 21:34:51 -0800108 if (id && id->flags & TF_COMMAND) {
Masahiro Yamada9de07152018-05-28 18:21:48 +0900109 BEGIN(PARAM);
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900110 yylval.id = id;
Roman Zippel7a884882005-11-08 21:34:51 -0800111 return id->token;
112 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113 alloc_string(yytext, yyleng);
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900114 yylval.string = text;
Masahiro Yamada9ced3bd2018-05-28 18:21:49 +0900115 return T_VARIABLE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 }
Masahiro Yamada1175c022018-05-28 18:21:50 +0900117 "=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_RECURSIVE; return T_ASSIGN; }
118 ":=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_SIMPLE; return T_ASSIGN; }
Masahiro Yamada9ced3bd2018-05-28 18:21:49 +0900119 [[:blank:]]+
Andreas Ruprechtc2264562015-07-12 09:41:50 +0200120 . warn_ignored_character(*yytext);
Roman Zippela02f0572005-11-08 21:34:53 -0800121 \n {
122 BEGIN(INITIAL);
Roman Zippela02f0572005-11-08 21:34:53 -0800123 return T_EOL;
124 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125}
126
Masahiro Yamada9ced3bd2018-05-28 18:21:49 +0900127<ASSIGN_VAL>{
128 [^[:blank:]\n]+.* {
129 alloc_string(yytext, yyleng);
130 yylval.string = text;
131 return T_ASSIGN_VAL;
132 }
133 \n { BEGIN(INITIAL); return T_EOL; }
134 .
135}
136
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137<PARAM>{
138 "&&" return T_AND;
139 "||" return T_OR;
140 "(" return T_OPEN_PAREN;
141 ")" return T_CLOSE_PAREN;
142 "!" return T_NOT;
143 "=" return T_EQUAL;
144 "!=" return T_UNEQUAL;
Jan Beulich31847b62015-06-15 13:00:21 +0100145 "<=" return T_LESS_EQUAL;
146 ">=" return T_GREATER_EQUAL;
147 "<" return T_LESS;
148 ">" return T_GREATER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 \"|\' {
150 str = yytext[0];
151 new_string();
152 BEGIN(STRING);
153 }
Masahiro Yamada18492682018-03-23 02:00:14 +0900154 \n BEGIN(INITIAL); return T_EOL;
Andreas Ruprechtc2264562015-07-12 09:41:50 +0200155 ({n}|[/.])+ {
Arnaud Lacombe61f956f2011-05-04 21:14:44 -0400156 const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
Roman Zippel3370f9f2005-11-08 21:34:52 -0800157 if (id && id->flags & TF_PARAM) {
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900158 yylval.id = id;
Roman Zippel7a884882005-11-08 21:34:51 -0800159 return id->token;
Roman Zippel3370f9f2005-11-08 21:34:52 -0800160 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 alloc_string(yytext, yyleng);
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900162 yylval.string = text;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 return T_WORD;
164 }
Masahiro Yamada104daea2018-05-28 18:21:40 +0900165 ({n}|[/.$])+ {
166 /* this token includes at least one '$' */
167 yylval.string = expand_token(yytext, yyleng);
168 if (strlen(yylval.string))
169 return T_WORD;
170 free(yylval.string);
171 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 #.* /* comment */
Masahiro Yamada18492682018-03-23 02:00:14 +0900173 \\\n ;
Jan Beulich2e0d7372015-01-20 12:52:48 +0000174 [[:blank:]]+
Andreas Ruprechtc2264562015-07-12 09:41:50 +0200175 . warn_ignored_character(*yytext);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 <<EOF>> {
177 BEGIN(INITIAL);
178 }
179}
180
181<STRING>{
Masahiro Yamada104daea2018-05-28 18:21:40 +0900182 "$".* append_expanded_string(yytext);
183 [^$'"\\\n]+/\n {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 append_string(yytext, yyleng);
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900185 yylval.string = text;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 return T_WORD_QUOTE;
187 }
Masahiro Yamada104daea2018-05-28 18:21:40 +0900188 [^$'"\\\n]+ {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 append_string(yytext, yyleng);
190 }
191 \\.?/\n {
192 append_string(yytext + 1, yyleng - 1);
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900193 yylval.string = text;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 return T_WORD_QUOTE;
195 }
196 \\.? {
197 append_string(yytext + 1, yyleng - 1);
198 }
199 \'|\" {
200 if (str == yytext[0]) {
201 BEGIN(PARAM);
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900202 yylval.string = text;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 return T_WORD_QUOTE;
204 } else
205 append_string(yytext, 1);
206 }
207 \n {
Masahiro Yamada9e3e10c2018-02-06 09:34:41 +0900208 fprintf(stderr,
209 "%s:%d:warning: multi-line strings not supported\n",
210 zconf_curname(), zconf_lineno());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 BEGIN(INITIAL);
212 return T_EOL;
213 }
214 <<EOF>> {
215 BEGIN(INITIAL);
216 }
217}
218
219<HELP>{
220 [ \t]+ {
221 ts = 0;
222 for (i = 0; i < yyleng; i++) {
223 if (yytext[i] == '\t')
224 ts = (ts & ~7) + 8;
225 else
226 ts++;
227 }
228 last_ts = ts;
229 if (first_ts) {
230 if (ts < first_ts) {
231 zconf_endhelp();
232 return T_HELPTEXT;
233 }
234 ts -= first_ts;
235 while (ts > 8) {
236 append_string(" ", 8);
237 ts -= 8;
238 }
239 append_string(" ", ts);
240 }
241 }
242 [ \t]*\n/[^ \t\n] {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 zconf_endhelp();
244 return T_HELPTEXT;
245 }
246 [ \t]*\n {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 append_string("\n", 1);
248 }
249 [^ \t\n].* {
EGRY Gaborf7a4b4c2008-01-11 23:55:20 +0100250 while (yyleng) {
251 if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
252 break;
253 yyleng--;
254 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 append_string(yytext, yyleng);
256 if (!first_ts)
257 first_ts = last_ts;
258 }
259 <<EOF>> {
260 zconf_endhelp();
261 return T_HELPTEXT;
262 }
263}
264
265<<EOF>> {
Roman Zippela02f0572005-11-08 21:34:53 -0800266 if (current_file) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 zconf_endfile();
Roman Zippela02f0572005-11-08 21:34:53 -0800268 return T_EOL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 }
270 fclose(yyin);
271 yyterminate();
272}
273
274%%
Masahiro Yamada104daea2018-05-28 18:21:40 +0900275static char *expand_token(const char *in, size_t n)
276{
277 char *out;
278 int c;
279 char c2;
280 const char *rest, *end;
281
282 new_string();
283 append_string(in, n);
284
285 /* get the whole line because we do not know the end of token. */
286 while ((c = input()) != EOF) {
287 if (c == '\n') {
288 unput(c);
289 break;
290 }
291 c2 = c;
292 append_string(&c2, 1);
293 }
294
295 rest = text;
296 out = expand_one_token(&rest);
297
298 /* push back unused characters to the input stream */
299 end = rest + strlen(rest);
300 while (end > rest)
301 unput(*--end);
302
303 free(text);
304
305 return out;
306}
307
308static void append_expanded_string(const char *str)
309{
310 const char *end;
311 char *res;
312
313 str++;
314
315 res = expand_dollar(&str);
316
317 /* push back unused characters to the input stream */
318 end = str + strlen(str);
319 while (end > str)
320 unput(*--end);
321
322 append_string(res, strlen(res));
323
324 free(res);
325}
326
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327void zconf_starthelp(void)
328{
329 new_string();
330 last_ts = first_ts = 0;
331 BEGIN(HELP);
332}
333
334static void zconf_endhelp(void)
335{
Masahiro Yamada765f4cd2018-01-12 00:50:50 +0900336 yylval.string = text;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337 BEGIN(INITIAL);
338}
339
340
341/*
342 * Try to open specified file with following names:
343 * ./name
344 * $(srctree)/name
345 * The latter is used when srctree is separate from objtree
346 * when compiling the kernel.
347 * Return NULL if file is not found.
348 */
349FILE *zconf_fopen(const char *name)
350{
351 char *env, fullname[PATH_MAX+1];
352 FILE *f;
353
354 f = fopen(name, "r");
Marcin Garski11de39e2007-05-05 22:49:00 +0200355 if (!f && name != NULL && name[0] != '/') {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 env = getenv(SRCTREE);
357 if (env) {
358 sprintf(fullname, "%s/%s", env, name);
359 f = fopen(fullname, "r");
360 }
361 }
362 return f;
363}
364
365void zconf_initscan(const char *name)
366{
367 yyin = zconf_fopen(name);
368 if (!yyin) {
Masahiro Yamada9e3e10c2018-02-06 09:34:41 +0900369 fprintf(stderr, "can't find file %s\n", name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 exit(1);
371 }
372
Alan Cox177acf72012-11-06 14:32:08 +0000373 current_buf = xmalloc(sizeof(*current_buf));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 memset(current_buf, 0, sizeof(*current_buf));
375
376 current_file = file_lookup(name);
Masahiro Yamada18492682018-03-23 02:00:14 +0900377 yylineno = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378}
379
380void zconf_nextfile(const char *name)
381{
Yann E. MORINf094f8a2011-02-24 19:36:42 +0100382 struct file *iter;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 struct file *file = file_lookup(name);
Alan Cox177acf72012-11-06 14:32:08 +0000384 struct buffer *buf = xmalloc(sizeof(*buf));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 memset(buf, 0, sizeof(*buf));
386
387 current_buf->state = YY_CURRENT_BUFFER;
Arnaud Lacombee82dae92010-09-04 16:09:26 -0400388 yyin = zconf_fopen(file->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 if (!yyin) {
Masahiro Yamada9e3e10c2018-02-06 09:34:41 +0900390 fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
391 zconf_curname(), zconf_lineno(), file->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 exit(1);
393 }
394 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
395 buf->parent = current_buf;
396 current_buf = buf;
397
Masahiro Yamada18492682018-03-23 02:00:14 +0900398 current_file->lineno = yylineno;
Masahiro Yamada379a8eb2018-03-23 02:00:13 +0900399 file->parent = current_file;
400
401 for (iter = current_file; iter; iter = iter->parent) {
402 if (!strcmp(iter->name, file->name)) {
Masahiro Yamada9e3e10c2018-02-06 09:34:41 +0900403 fprintf(stderr,
Masahiro Yamada32a94b82018-03-23 02:00:12 +0900404 "Recursive inclusion detected.\n"
405 "Inclusion path:\n"
Masahiro Yamada379a8eb2018-03-23 02:00:13 +0900406 " current file : %s\n", file->name);
407 iter = file;
Masahiro Yamada5ae6fcc2018-03-02 16:05:12 +0900408 do {
Yann E. MORINf094f8a2011-02-24 19:36:42 +0100409 iter = iter->parent;
Masahiro Yamada32a94b82018-03-23 02:00:12 +0900410 fprintf(stderr, " included from: %s:%d\n",
Masahiro Yamada5ae6fcc2018-03-02 16:05:12 +0900411 iter->name, iter->lineno - 1);
Masahiro Yamada379a8eb2018-03-23 02:00:13 +0900412 } while (strcmp(iter->name, file->name));
Yann E. MORINf094f8a2011-02-24 19:36:42 +0100413 exit(1);
414 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 }
Masahiro Yamada379a8eb2018-03-23 02:00:13 +0900416
Masahiro Yamada18492682018-03-23 02:00:14 +0900417 yylineno = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 current_file = file;
419}
420
Roman Zippela02f0572005-11-08 21:34:53 -0800421static void zconf_endfile(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422{
423 struct buffer *parent;
424
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 current_file = current_file->parent;
Masahiro Yamada18492682018-03-23 02:00:14 +0900426 if (current_file)
427 yylineno = current_file->lineno;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428
429 parent = current_buf->parent;
430 if (parent) {
431 fclose(yyin);
432 yy_delete_buffer(YY_CURRENT_BUFFER);
433 yy_switch_to_buffer(parent->state);
434 }
435 free(current_buf);
436 current_buf = parent;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437}
438
439int zconf_lineno(void)
440{
Roman Zippela02f0572005-11-08 21:34:53 -0800441 return current_pos.lineno;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442}
443
Arnaud Lacombe2e7a0912010-09-04 16:03:30 -0400444const char *zconf_curname(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445{
Roman Zippela02f0572005-11-08 21:34:53 -0800446 return current_pos.file ? current_pos.file->name : "<none>";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447}