1981e545aSMasahiro Yamada /* SPDX-License-Identifier: GPL-2.0 */
2981e545aSMasahiro Yamada /*
3981e545aSMasahiro Yamada * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
4981e545aSMasahiro Yamada */
5981e545aSMasahiro Yamada %option nostdinit noyywrap never-interactive full ecs
6981e545aSMasahiro Yamada %option 8bit nodefault yylineno
7981e545aSMasahiro Yamada %x ASSIGN_VAL HELP STRING
8981e545aSMasahiro Yamada %{
9981e545aSMasahiro Yamada
10981e545aSMasahiro Yamada #include <assert.h>
11981e545aSMasahiro Yamada #include <limits.h>
12981e545aSMasahiro Yamada #include <stdio.h>
13981e545aSMasahiro Yamada #include <stdlib.h>
14981e545aSMasahiro Yamada #include <string.h>
15981e545aSMasahiro Yamada
16981e545aSMasahiro Yamada #include "lkc.h"
17769a1c02SMasahiro Yamada #include "parser.tab.h"
18981e545aSMasahiro Yamada
19981e545aSMasahiro Yamada #define YY_DECL static int yylex1(void)
20981e545aSMasahiro Yamada
21981e545aSMasahiro Yamada #define START_STRSIZE 16
22981e545aSMasahiro Yamada
23981e545aSMasahiro Yamada static struct {
24981e545aSMasahiro Yamada struct file *file;
25981e545aSMasahiro Yamada int lineno;
26981e545aSMasahiro Yamada } current_pos;
27981e545aSMasahiro Yamada
28981e545aSMasahiro Yamada static int prev_prev_token = T_EOL;
29981e545aSMasahiro Yamada static int prev_token = T_EOL;
30981e545aSMasahiro Yamada static char *text;
31981e545aSMasahiro Yamada static int text_size, text_asize;
32981e545aSMasahiro Yamada
33981e545aSMasahiro Yamada struct buffer {
34981e545aSMasahiro Yamada struct buffer *parent;
35981e545aSMasahiro Yamada YY_BUFFER_STATE state;
36981e545aSMasahiro Yamada };
37981e545aSMasahiro Yamada
38d41809ffSMasahiro Yamada static struct buffer *current_buf;
39981e545aSMasahiro Yamada
40981e545aSMasahiro Yamada static int last_ts, first_ts;
41981e545aSMasahiro Yamada
42981e545aSMasahiro Yamada static char *expand_token(const char *in, size_t n);
43981e545aSMasahiro Yamada static void append_expanded_string(const char *in);
44981e545aSMasahiro Yamada static void zconf_endhelp(void);
45981e545aSMasahiro Yamada static void zconf_endfile(void);
46981e545aSMasahiro Yamada
new_string(void)47981e545aSMasahiro Yamada static void new_string(void)
48981e545aSMasahiro Yamada {
49981e545aSMasahiro Yamada text = xmalloc(START_STRSIZE);
50981e545aSMasahiro Yamada text_asize = START_STRSIZE;
51981e545aSMasahiro Yamada text_size = 0;
52981e545aSMasahiro Yamada *text = 0;
53981e545aSMasahiro Yamada }
54981e545aSMasahiro Yamada
append_string(const char * str,int size)55981e545aSMasahiro Yamada static void append_string(const char *str, int size)
56981e545aSMasahiro Yamada {
57981e545aSMasahiro Yamada int new_size = text_size + size + 1;
58981e545aSMasahiro Yamada if (new_size > text_asize) {
59981e545aSMasahiro Yamada new_size += START_STRSIZE - 1;
60981e545aSMasahiro Yamada new_size &= -START_STRSIZE;
61981e545aSMasahiro Yamada text = xrealloc(text, new_size);
62981e545aSMasahiro Yamada text_asize = new_size;
63981e545aSMasahiro Yamada }
64981e545aSMasahiro Yamada memcpy(text + text_size, str, size);
65981e545aSMasahiro Yamada text_size += size;
66981e545aSMasahiro Yamada text[text_size] = 0;
67981e545aSMasahiro Yamada }
68981e545aSMasahiro Yamada
alloc_string(const char * str,int size)69981e545aSMasahiro Yamada static void alloc_string(const char *str, int size)
70981e545aSMasahiro Yamada {
71981e545aSMasahiro Yamada text = xmalloc(size + 1);
72981e545aSMasahiro Yamada memcpy(text, str, size);
73981e545aSMasahiro Yamada text[size] = 0;
74981e545aSMasahiro Yamada }
75981e545aSMasahiro Yamada
warn_ignored_character(char chr)76981e545aSMasahiro Yamada static void warn_ignored_character(char chr)
77981e545aSMasahiro Yamada {
78981e545aSMasahiro Yamada fprintf(stderr,
79981e545aSMasahiro Yamada "%s:%d:warning: ignoring unsupported character '%c'\n",
80981e545aSMasahiro Yamada current_file->name, yylineno, chr);
81981e545aSMasahiro Yamada }
82981e545aSMasahiro Yamada %}
83981e545aSMasahiro Yamada
84981e545aSMasahiro Yamada n [A-Za-z0-9_-]
85981e545aSMasahiro Yamada
86981e545aSMasahiro Yamada %%
876988f70cSMasahiro Yamada char open_quote = 0;
88981e545aSMasahiro Yamada
89981e545aSMasahiro Yamada #.* /* ignore comment */
90981e545aSMasahiro Yamada [ \t]* /* whitespaces */
91981e545aSMasahiro Yamada \\\n /* escaped new line */
92981e545aSMasahiro Yamada \n return T_EOL;
93981e545aSMasahiro Yamada "bool" return T_BOOL;
94981e545aSMasahiro Yamada "choice" return T_CHOICE;
95981e545aSMasahiro Yamada "comment" return T_COMMENT;
96981e545aSMasahiro Yamada "config" return T_CONFIG;
97981e545aSMasahiro Yamada "def_bool" return T_DEF_BOOL;
98981e545aSMasahiro Yamada "def_tristate" return T_DEF_TRISTATE;
99981e545aSMasahiro Yamada "default" return T_DEFAULT;
100981e545aSMasahiro Yamada "depends" return T_DEPENDS;
101981e545aSMasahiro Yamada "endchoice" return T_ENDCHOICE;
102981e545aSMasahiro Yamada "endif" return T_ENDIF;
103981e545aSMasahiro Yamada "endmenu" return T_ENDMENU;
104f70f74d1SMasahiro Yamada "help" return T_HELP;
105981e545aSMasahiro Yamada "hex" return T_HEX;
106981e545aSMasahiro Yamada "if" return T_IF;
107981e545aSMasahiro Yamada "imply" return T_IMPLY;
108981e545aSMasahiro Yamada "int" return T_INT;
109981e545aSMasahiro Yamada "mainmenu" return T_MAINMENU;
110981e545aSMasahiro Yamada "menu" return T_MENU;
111981e545aSMasahiro Yamada "menuconfig" return T_MENUCONFIG;
112981e545aSMasahiro Yamada "modules" return T_MODULES;
113981e545aSMasahiro Yamada "on" return T_ON;
114981e545aSMasahiro Yamada "optional" return T_OPTIONAL;
115981e545aSMasahiro Yamada "prompt" return T_PROMPT;
116981e545aSMasahiro Yamada "range" return T_RANGE;
117981e545aSMasahiro Yamada "select" return T_SELECT;
118981e545aSMasahiro Yamada "source" return T_SOURCE;
119981e545aSMasahiro Yamada "string" return T_STRING;
120981e545aSMasahiro Yamada "tristate" return T_TRISTATE;
121981e545aSMasahiro Yamada "visible" return T_VISIBLE;
122981e545aSMasahiro Yamada "||" return T_OR;
123981e545aSMasahiro Yamada "&&" return T_AND;
124981e545aSMasahiro Yamada "=" return T_EQUAL;
125981e545aSMasahiro Yamada "!=" return T_UNEQUAL;
126981e545aSMasahiro Yamada "<" return T_LESS;
127981e545aSMasahiro Yamada "<=" return T_LESS_EQUAL;
128981e545aSMasahiro Yamada ">" return T_GREATER;
129981e545aSMasahiro Yamada ">=" return T_GREATER_EQUAL;
130981e545aSMasahiro Yamada "!" return T_NOT;
131981e545aSMasahiro Yamada "(" return T_OPEN_PAREN;
132981e545aSMasahiro Yamada ")" return T_CLOSE_PAREN;
133981e545aSMasahiro Yamada ":=" return T_COLON_EQUAL;
134981e545aSMasahiro Yamada "+=" return T_PLUS_EQUAL;
135981e545aSMasahiro Yamada \"|\' {
1366988f70cSMasahiro Yamada open_quote = yytext[0];
137981e545aSMasahiro Yamada new_string();
138981e545aSMasahiro Yamada BEGIN(STRING);
139981e545aSMasahiro Yamada }
140981e545aSMasahiro Yamada {n}+ {
141981e545aSMasahiro Yamada alloc_string(yytext, yyleng);
142981e545aSMasahiro Yamada yylval.string = text;
143981e545aSMasahiro Yamada return T_WORD;
144981e545aSMasahiro Yamada }
145981e545aSMasahiro Yamada ({n}|$)+ {
146981e545aSMasahiro Yamada /* this token includes at least one '$' */
147981e545aSMasahiro Yamada yylval.string = expand_token(yytext, yyleng);
148981e545aSMasahiro Yamada if (strlen(yylval.string))
149981e545aSMasahiro Yamada return T_WORD;
150981e545aSMasahiro Yamada free(yylval.string);
151981e545aSMasahiro Yamada }
152981e545aSMasahiro Yamada . warn_ignored_character(*yytext);
153981e545aSMasahiro Yamada
154981e545aSMasahiro Yamada <ASSIGN_VAL>{
155981e545aSMasahiro Yamada [^[:blank:]\n]+.* {
156981e545aSMasahiro Yamada alloc_string(yytext, yyleng);
157981e545aSMasahiro Yamada yylval.string = text;
158981e545aSMasahiro Yamada return T_ASSIGN_VAL;
159981e545aSMasahiro Yamada }
160981e545aSMasahiro Yamada \n { BEGIN(INITIAL); return T_EOL; }
161981e545aSMasahiro Yamada .
162981e545aSMasahiro Yamada }
163981e545aSMasahiro Yamada
164981e545aSMasahiro Yamada <STRING>{
165981e545aSMasahiro Yamada "$".* append_expanded_string(yytext);
166981e545aSMasahiro Yamada [^$'"\\\n]+ {
167981e545aSMasahiro Yamada append_string(yytext, yyleng);
168981e545aSMasahiro Yamada }
169981e545aSMasahiro Yamada \\.? {
170981e545aSMasahiro Yamada append_string(yytext + 1, yyleng - 1);
171981e545aSMasahiro Yamada }
172981e545aSMasahiro Yamada \'|\" {
1736988f70cSMasahiro Yamada if (open_quote == yytext[0]) {
174981e545aSMasahiro Yamada BEGIN(INITIAL);
175981e545aSMasahiro Yamada yylval.string = text;
176981e545aSMasahiro Yamada return T_WORD_QUOTE;
177981e545aSMasahiro Yamada } else
178981e545aSMasahiro Yamada append_string(yytext, 1);
179981e545aSMasahiro Yamada }
180981e545aSMasahiro Yamada \n {
181981e545aSMasahiro Yamada fprintf(stderr,
182981e545aSMasahiro Yamada "%s:%d:warning: multi-line strings not supported\n",
183981e545aSMasahiro Yamada zconf_curname(), zconf_lineno());
184981e545aSMasahiro Yamada unput('\n');
185981e545aSMasahiro Yamada BEGIN(INITIAL);
186981e545aSMasahiro Yamada yylval.string = text;
187981e545aSMasahiro Yamada return T_WORD_QUOTE;
188981e545aSMasahiro Yamada }
189981e545aSMasahiro Yamada <<EOF>> {
190981e545aSMasahiro Yamada BEGIN(INITIAL);
191981e545aSMasahiro Yamada yylval.string = text;
192981e545aSMasahiro Yamada return T_WORD_QUOTE;
193981e545aSMasahiro Yamada }
194981e545aSMasahiro Yamada }
195981e545aSMasahiro Yamada
196981e545aSMasahiro Yamada <HELP>{
197981e545aSMasahiro Yamada [ \t]+ {
19865017d83SMasahiro Yamada int ts, i;
19965017d83SMasahiro Yamada
200981e545aSMasahiro Yamada ts = 0;
201981e545aSMasahiro Yamada for (i = 0; i < yyleng; i++) {
202981e545aSMasahiro Yamada if (yytext[i] == '\t')
203981e545aSMasahiro Yamada ts = (ts & ~7) + 8;
204981e545aSMasahiro Yamada else
205981e545aSMasahiro Yamada ts++;
206981e545aSMasahiro Yamada }
207981e545aSMasahiro Yamada last_ts = ts;
208981e545aSMasahiro Yamada if (first_ts) {
209981e545aSMasahiro Yamada if (ts < first_ts) {
210981e545aSMasahiro Yamada zconf_endhelp();
211981e545aSMasahiro Yamada return T_HELPTEXT;
212981e545aSMasahiro Yamada }
213981e545aSMasahiro Yamada ts -= first_ts;
214981e545aSMasahiro Yamada while (ts > 8) {
215981e545aSMasahiro Yamada append_string(" ", 8);
216981e545aSMasahiro Yamada ts -= 8;
217981e545aSMasahiro Yamada }
218981e545aSMasahiro Yamada append_string(" ", ts);
219981e545aSMasahiro Yamada }
220981e545aSMasahiro Yamada }
221981e545aSMasahiro Yamada [ \t]*\n/[^ \t\n] {
222981e545aSMasahiro Yamada zconf_endhelp();
223981e545aSMasahiro Yamada return T_HELPTEXT;
224981e545aSMasahiro Yamada }
225981e545aSMasahiro Yamada [ \t]*\n {
226981e545aSMasahiro Yamada append_string("\n", 1);
227981e545aSMasahiro Yamada }
228981e545aSMasahiro Yamada [^ \t\n].* {
229981e545aSMasahiro Yamada while (yyleng) {
230981e545aSMasahiro Yamada if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
231981e545aSMasahiro Yamada break;
232981e545aSMasahiro Yamada yyleng--;
233981e545aSMasahiro Yamada }
234981e545aSMasahiro Yamada append_string(yytext, yyleng);
235981e545aSMasahiro Yamada if (!first_ts)
236981e545aSMasahiro Yamada first_ts = last_ts;
237981e545aSMasahiro Yamada }
238981e545aSMasahiro Yamada <<EOF>> {
239981e545aSMasahiro Yamada zconf_endhelp();
240981e545aSMasahiro Yamada return T_HELPTEXT;
241981e545aSMasahiro Yamada }
242981e545aSMasahiro Yamada }
243981e545aSMasahiro Yamada
244981e545aSMasahiro Yamada <<EOF>> {
245981e545aSMasahiro Yamada BEGIN(INITIAL);
246981e545aSMasahiro Yamada
247981e545aSMasahiro Yamada if (prev_token != T_EOL && prev_token != T_HELPTEXT)
248981e545aSMasahiro Yamada fprintf(stderr, "%s:%d:warning: no new line at end of file\n",
249981e545aSMasahiro Yamada current_file->name, yylineno);
250981e545aSMasahiro Yamada
251981e545aSMasahiro Yamada if (current_file) {
252981e545aSMasahiro Yamada zconf_endfile();
253981e545aSMasahiro Yamada return T_EOL;
254981e545aSMasahiro Yamada }
255981e545aSMasahiro Yamada fclose(yyin);
256981e545aSMasahiro Yamada yyterminate();
257981e545aSMasahiro Yamada }
258981e545aSMasahiro Yamada
259981e545aSMasahiro Yamada %%
260981e545aSMasahiro Yamada
261981e545aSMasahiro Yamada /* second stage lexer */
262981e545aSMasahiro Yamada int yylex(void)
263981e545aSMasahiro Yamada {
264981e545aSMasahiro Yamada int token;
265981e545aSMasahiro Yamada
266981e545aSMasahiro Yamada repeat:
267981e545aSMasahiro Yamada token = yylex1();
268981e545aSMasahiro Yamada
269981e545aSMasahiro Yamada if (prev_token == T_EOL || prev_token == T_HELPTEXT) {
270981e545aSMasahiro Yamada if (token == T_EOL) {
271981e545aSMasahiro Yamada /* Do not pass unneeded T_EOL to the parser. */
272981e545aSMasahiro Yamada goto repeat;
273981e545aSMasahiro Yamada } else {
274981e545aSMasahiro Yamada /*
275981e545aSMasahiro Yamada * For the parser, update file/lineno at the first token
276981e545aSMasahiro Yamada * of each statement. Generally, \n is a statement
277981e545aSMasahiro Yamada * terminator in Kconfig, but it is not always true
278981e545aSMasahiro Yamada * because \n could be escaped by a backslash.
279981e545aSMasahiro Yamada */
280981e545aSMasahiro Yamada current_pos.file = current_file;
281981e545aSMasahiro Yamada current_pos.lineno = yylineno;
282981e545aSMasahiro Yamada }
283981e545aSMasahiro Yamada }
284981e545aSMasahiro Yamada
285981e545aSMasahiro Yamada if (prev_prev_token == T_EOL && prev_token == T_WORD &&
286981e545aSMasahiro Yamada (token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL))
287981e545aSMasahiro Yamada BEGIN(ASSIGN_VAL);
288981e545aSMasahiro Yamada
289981e545aSMasahiro Yamada prev_prev_token = prev_token;
290981e545aSMasahiro Yamada prev_token = token;
291981e545aSMasahiro Yamada
292981e545aSMasahiro Yamada return token;
293981e545aSMasahiro Yamada }
294981e545aSMasahiro Yamada
295981e545aSMasahiro Yamada static char *expand_token(const char *in, size_t n)
296981e545aSMasahiro Yamada {
297981e545aSMasahiro Yamada char *out;
298981e545aSMasahiro Yamada int c;
299981e545aSMasahiro Yamada char c2;
300981e545aSMasahiro Yamada const char *rest, *end;
301981e545aSMasahiro Yamada
302981e545aSMasahiro Yamada new_string();
303981e545aSMasahiro Yamada append_string(in, n);
304981e545aSMasahiro Yamada
305*3328ff75SMasahiro Yamada /*
306*3328ff75SMasahiro Yamada * get the whole line because we do not know the end of token.
307*3328ff75SMasahiro Yamada * input() returns 0 (not EOF!) when it reachs the end of file.
308*3328ff75SMasahiro Yamada */
309*3328ff75SMasahiro Yamada while ((c = input()) != 0) {
310981e545aSMasahiro Yamada if (c == '\n') {
311981e545aSMasahiro Yamada unput(c);
312981e545aSMasahiro Yamada break;
313981e545aSMasahiro Yamada }
314981e545aSMasahiro Yamada c2 = c;
315981e545aSMasahiro Yamada append_string(&c2, 1);
316981e545aSMasahiro Yamada }
317981e545aSMasahiro Yamada
318981e545aSMasahiro Yamada rest = text;
319981e545aSMasahiro Yamada out = expand_one_token(&rest);
320981e545aSMasahiro Yamada
321981e545aSMasahiro Yamada /* push back unused characters to the input stream */
322981e545aSMasahiro Yamada end = rest + strlen(rest);
323981e545aSMasahiro Yamada while (end > rest)
324981e545aSMasahiro Yamada unput(*--end);
325981e545aSMasahiro Yamada
326981e545aSMasahiro Yamada free(text);
327981e545aSMasahiro Yamada
328981e545aSMasahiro Yamada return out;
329981e545aSMasahiro Yamada }
330981e545aSMasahiro Yamada
331981e545aSMasahiro Yamada static void append_expanded_string(const char *str)
332981e545aSMasahiro Yamada {
333981e545aSMasahiro Yamada const char *end;
334981e545aSMasahiro Yamada char *res;
335981e545aSMasahiro Yamada
336981e545aSMasahiro Yamada str++;
337981e545aSMasahiro Yamada
338981e545aSMasahiro Yamada res = expand_dollar(&str);
339981e545aSMasahiro Yamada
340981e545aSMasahiro Yamada /* push back unused characters to the input stream */
341981e545aSMasahiro Yamada end = str + strlen(str);
342981e545aSMasahiro Yamada while (end > str)
343981e545aSMasahiro Yamada unput(*--end);
344981e545aSMasahiro Yamada
345981e545aSMasahiro Yamada append_string(res, strlen(res));
346981e545aSMasahiro Yamada
347981e545aSMasahiro Yamada free(res);
348981e545aSMasahiro Yamada }
349981e545aSMasahiro Yamada
350981e545aSMasahiro Yamada void zconf_starthelp(void)
351981e545aSMasahiro Yamada {
352981e545aSMasahiro Yamada new_string();
353981e545aSMasahiro Yamada last_ts = first_ts = 0;
354981e545aSMasahiro Yamada BEGIN(HELP);
355981e545aSMasahiro Yamada }
356981e545aSMasahiro Yamada
357981e545aSMasahiro Yamada static void zconf_endhelp(void)
358981e545aSMasahiro Yamada {
359981e545aSMasahiro Yamada yylval.string = text;
360981e545aSMasahiro Yamada BEGIN(INITIAL);
361981e545aSMasahiro Yamada }
362981e545aSMasahiro Yamada
363981e545aSMasahiro Yamada
364981e545aSMasahiro Yamada /*
365981e545aSMasahiro Yamada * Try to open specified file with following names:
366981e545aSMasahiro Yamada * ./name
367981e545aSMasahiro Yamada * $(srctree)/name
368981e545aSMasahiro Yamada * The latter is used when srctree is separate from objtree
369981e545aSMasahiro Yamada * when compiling the kernel.
370981e545aSMasahiro Yamada * Return NULL if file is not found.
371981e545aSMasahiro Yamada */
372981e545aSMasahiro Yamada FILE *zconf_fopen(const char *name)
373981e545aSMasahiro Yamada {
374981e545aSMasahiro Yamada char *env, fullname[PATH_MAX+1];
375981e545aSMasahiro Yamada FILE *f;
376981e545aSMasahiro Yamada
377981e545aSMasahiro Yamada f = fopen(name, "r");
378981e545aSMasahiro Yamada if (!f && name != NULL && name[0] != '/') {
379981e545aSMasahiro Yamada env = getenv(SRCTREE);
380981e545aSMasahiro Yamada if (env) {
381b9d1a8e9SJacob Garber snprintf(fullname, sizeof(fullname),
382b9d1a8e9SJacob Garber "%s/%s", env, name);
383981e545aSMasahiro Yamada f = fopen(fullname, "r");
384981e545aSMasahiro Yamada }
385981e545aSMasahiro Yamada }
386981e545aSMasahiro Yamada return f;
387981e545aSMasahiro Yamada }
388981e545aSMasahiro Yamada
389981e545aSMasahiro Yamada void zconf_initscan(const char *name)
390981e545aSMasahiro Yamada {
391981e545aSMasahiro Yamada yyin = zconf_fopen(name);
392981e545aSMasahiro Yamada if (!yyin) {
393981e545aSMasahiro Yamada fprintf(stderr, "can't find file %s\n", name);
394981e545aSMasahiro Yamada exit(1);
395981e545aSMasahiro Yamada }
396981e545aSMasahiro Yamada
397981e545aSMasahiro Yamada current_buf = xmalloc(sizeof(*current_buf));
398981e545aSMasahiro Yamada memset(current_buf, 0, sizeof(*current_buf));
399981e545aSMasahiro Yamada
400981e545aSMasahiro Yamada current_file = file_lookup(name);
401981e545aSMasahiro Yamada yylineno = 1;
402981e545aSMasahiro Yamada }
403981e545aSMasahiro Yamada
404981e545aSMasahiro Yamada void zconf_nextfile(const char *name)
405981e545aSMasahiro Yamada {
406981e545aSMasahiro Yamada struct file *iter;
407981e545aSMasahiro Yamada struct file *file = file_lookup(name);
408981e545aSMasahiro Yamada struct buffer *buf = xmalloc(sizeof(*buf));
409981e545aSMasahiro Yamada memset(buf, 0, sizeof(*buf));
410981e545aSMasahiro Yamada
411981e545aSMasahiro Yamada current_buf->state = YY_CURRENT_BUFFER;
412981e545aSMasahiro Yamada yyin = zconf_fopen(file->name);
413981e545aSMasahiro Yamada if (!yyin) {
414981e545aSMasahiro Yamada fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
415981e545aSMasahiro Yamada zconf_curname(), zconf_lineno(), file->name);
416981e545aSMasahiro Yamada exit(1);
417981e545aSMasahiro Yamada }
418981e545aSMasahiro Yamada yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
419981e545aSMasahiro Yamada buf->parent = current_buf;
420981e545aSMasahiro Yamada current_buf = buf;
421981e545aSMasahiro Yamada
422981e545aSMasahiro Yamada current_file->lineno = yylineno;
423981e545aSMasahiro Yamada file->parent = current_file;
424981e545aSMasahiro Yamada
425981e545aSMasahiro Yamada for (iter = current_file; iter; iter = iter->parent) {
426981e545aSMasahiro Yamada if (!strcmp(iter->name, file->name)) {
427981e545aSMasahiro Yamada fprintf(stderr,
428981e545aSMasahiro Yamada "Recursive inclusion detected.\n"
429981e545aSMasahiro Yamada "Inclusion path:\n"
430981e545aSMasahiro Yamada " current file : %s\n", file->name);
431981e545aSMasahiro Yamada iter = file;
432981e545aSMasahiro Yamada do {
433981e545aSMasahiro Yamada iter = iter->parent;
434981e545aSMasahiro Yamada fprintf(stderr, " included from: %s:%d\n",
435981e545aSMasahiro Yamada iter->name, iter->lineno - 1);
436981e545aSMasahiro Yamada } while (strcmp(iter->name, file->name));
437981e545aSMasahiro Yamada exit(1);
438981e545aSMasahiro Yamada }
439981e545aSMasahiro Yamada }
440981e545aSMasahiro Yamada
441981e545aSMasahiro Yamada yylineno = 1;
442981e545aSMasahiro Yamada current_file = file;
443981e545aSMasahiro Yamada }
444981e545aSMasahiro Yamada
445981e545aSMasahiro Yamada static void zconf_endfile(void)
446981e545aSMasahiro Yamada {
447981e545aSMasahiro Yamada struct buffer *parent;
448981e545aSMasahiro Yamada
449981e545aSMasahiro Yamada current_file = current_file->parent;
450981e545aSMasahiro Yamada if (current_file)
451981e545aSMasahiro Yamada yylineno = current_file->lineno;
452981e545aSMasahiro Yamada
453981e545aSMasahiro Yamada parent = current_buf->parent;
454981e545aSMasahiro Yamada if (parent) {
455981e545aSMasahiro Yamada fclose(yyin);
456981e545aSMasahiro Yamada yy_delete_buffer(YY_CURRENT_BUFFER);
457981e545aSMasahiro Yamada yy_switch_to_buffer(parent->state);
458981e545aSMasahiro Yamada }
459981e545aSMasahiro Yamada free(current_buf);
460981e545aSMasahiro Yamada current_buf = parent;
461981e545aSMasahiro Yamada }
462981e545aSMasahiro Yamada
463981e545aSMasahiro Yamada int zconf_lineno(void)
464981e545aSMasahiro Yamada {
465981e545aSMasahiro Yamada return current_pos.lineno;
466981e545aSMasahiro Yamada }
467981e545aSMasahiro Yamada
468981e545aSMasahiro Yamada const char *zconf_curname(void)
469981e545aSMasahiro Yamada {
470981e545aSMasahiro Yamada return current_pos.file ? current_pos.file->name : "<none>";
471981e545aSMasahiro Yamada }
472