~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/kconfig/lexer.l

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
  4  */
  5 %option nostdinit noyywrap never-interactive full ecs
  6 %option 8bit nodefault yylineno
  7 %x ASSIGN_VAL HELP STRING
  8 %{
  9 
 10 #include <assert.h>
 11 #include <limits.h>
 12 #include <stdio.h>
 13 #include <stdlib.h>
 14 #include <string.h>
 15 
 16 #include "lkc.h"
 17 #include "preprocess.h"
 18 
 19 #include "parser.tab.h"
 20 
 21 #define YY_DECL         static int yylex1(void)
 22 
 23 #define START_STRSIZE   16
 24 
 25 /* The Kconfig file currently being parsed.  */
 26 const char *cur_filename;
 27 
 28 /*
 29  * The line number of the current statement. This does not match yylineno.
 30  * yylineno is used by the lexer, while cur_lineno is used by the parser.
 31  */
 32 int cur_lineno;
 33 
 34 static int prev_prev_token = T_EOL;
 35 static int prev_token = T_EOL;
 36 static char *text;
 37 static int text_size, text_asize;
 38 
 39 struct buffer {
 40         struct buffer *parent;
 41         YY_BUFFER_STATE state;
 42         int yylineno;
 43         const char *filename;
 44         int source_lineno;
 45 };
 46 
 47 static struct buffer *current_buf;
 48 
 49 static int last_ts, first_ts;
 50 
 51 static char *expand_token(const char *in, size_t n);
 52 static void append_expanded_string(const char *in);
 53 static void zconf_endhelp(void);
 54 static void zconf_endfile(void);
 55 
 56 static void new_string(void)
 57 {
 58         text = xmalloc(START_STRSIZE);
 59         text_asize = START_STRSIZE;
 60         text_size = 0;
 61         *text = 0;
 62 }
 63 
 64 static void append_string(const char *str, int size)
 65 {
 66         int new_size = text_size + size + 1;
 67         if (new_size > text_asize) {
 68                 new_size += START_STRSIZE - 1;
 69                 new_size &= -START_STRSIZE;
 70                 text = xrealloc(text, new_size);
 71                 text_asize = new_size;
 72         }
 73         memcpy(text + text_size, str, size);
 74         text_size += size;
 75         text[text_size] = 0;
 76 }
 77 
 78 static void alloc_string(const char *str, int size)
 79 {
 80         text = xmalloc(size + 1);
 81         memcpy(text, str, size);
 82         text[size] = 0;
 83 }
 84 
 85 static void warn_ignored_character(char chr)
 86 {
 87         fprintf(stderr,
 88                 "%s:%d:warning: ignoring unsupported character '%c'\n",
 89                 cur_filename, yylineno, chr);
 90 }
 91 %}
 92 
 93 n       [A-Za-z0-9_-]
 94 
 95 %%
 96         char open_quote = 0;
 97 
 98 #.*                     /* ignore comment */
 99 [ \t]*                  /* whitespaces */
100 \\\n                    /* escaped new line */
101 \n                      return T_EOL;
102 "bool"                  return T_BOOL;
103 "choice"                return T_CHOICE;
104 "comment"               return T_COMMENT;
105 "config"                return T_CONFIG;
106 "def_bool"              return T_DEF_BOOL;
107 "def_tristate"          return T_DEF_TRISTATE;
108 "default"               return T_DEFAULT;
109 "depends"               return T_DEPENDS;
110 "endchoice"             return T_ENDCHOICE;
111 "endif"                 return T_ENDIF;
112 "endmenu"               return T_ENDMENU;
113 "help"                  return T_HELP;
114 "hex"                   return T_HEX;
115 "if"                    return T_IF;
116 "imply"                 return T_IMPLY;
117 "int"                   return T_INT;
118 "mainmenu"              return T_MAINMENU;
119 "menu"                  return T_MENU;
120 "menuconfig"            return T_MENUCONFIG;
121 "modules"               return T_MODULES;
122 "on"                    return T_ON;
123 "prompt"                return T_PROMPT;
124 "range"                 return T_RANGE;
125 "select"                return T_SELECT;
126 "source"                return T_SOURCE;
127 "string"                return T_STRING;
128 "tristate"              return T_TRISTATE;
129 "visible"               return T_VISIBLE;
130 "||"                    return T_OR;
131 "&&"                    return T_AND;
132 "="                     return T_EQUAL;
133 "!="                    return T_UNEQUAL;
134 "<"                     return T_LESS;
135 "<="                    return T_LESS_EQUAL;
136 ">"                     return T_GREATER;
137 ">="                    return T_GREATER_EQUAL;
138 "!"                     return T_NOT;
139 "("                     return T_OPEN_PAREN;
140 ")"                     return T_CLOSE_PAREN;
141 ":="                    return T_COLON_EQUAL;
142 "+="                    return T_PLUS_EQUAL;
143 \"|\'                   {
144                                 open_quote = yytext[0];
145                                 new_string();
146                                 BEGIN(STRING);
147                         }
148 {n}+                    {
149                                 alloc_string(yytext, yyleng);
150                                 yylval.string = text;
151                                 return T_WORD;
152                         }
153 ({n}|$)+                {
154                                 /* this token includes at least one '$' */
155                                 yylval.string = expand_token(yytext, yyleng);
156                                 if (strlen(yylval.string))
157                                         return T_WORD;
158                                 free(yylval.string);
159                         }
160 .                       warn_ignored_character(*yytext);
161 
162 <ASSIGN_VAL>{
163         [^[:blank:]\n]+.*       {
164                 alloc_string(yytext, yyleng);
165                 yylval.string = text;
166                 return T_ASSIGN_VAL;
167         }
168         \n      { BEGIN(INITIAL); return T_EOL; }
169         .
170 }
171 
172 <STRING>{
173         "$".*   append_expanded_string(yytext);
174         [^$'"\\\n]+     {
175                 append_string(yytext, yyleng);
176         }
177         \\.?    {
178                 append_string(yytext + 1, yyleng - 1);
179         }
180         \'|\"   {
181                 if (open_quote == yytext[0]) {
182                         BEGIN(INITIAL);
183                         yylval.string = text;
184                         return T_WORD_QUOTE;
185                 } else
186                         append_string(yytext, 1);
187         }
188         \n      {
189                 fprintf(stderr,
190                         "%s:%d:warning: multi-line strings not supported\n",
191                         cur_filename, cur_lineno);
192                 unput('\n');
193                 BEGIN(INITIAL);
194                 yylval.string = text;
195                 return T_WORD_QUOTE;
196         }
197         <<EOF>> {
198                 BEGIN(INITIAL);
199                 yylval.string = text;
200                 return T_WORD_QUOTE;
201         }
202 }
203 
204 <HELP>{
205         [ \t]+  {
206                 int ts, i;
207 
208                 ts = 0;
209                 for (i = 0; i < yyleng; i++) {
210                         if (yytext[i] == '\t')
211                                 ts = (ts & ~7) + 8;
212                         else
213                                 ts++;
214                 }
215                 last_ts = ts;
216                 if (first_ts) {
217                         if (ts < first_ts) {
218                                 zconf_endhelp();
219                                 return T_HELPTEXT;
220                         }
221                         ts -= first_ts;
222                         while (ts > 8) {
223                                 append_string("        ", 8);
224                                 ts -= 8;
225                         }
226                         append_string("        ", ts);
227                 }
228         }
229         [ \t]*\n/[^ \t\n] {
230                 zconf_endhelp();
231                 return T_HELPTEXT;
232         }
233         [ \t]*\n        {
234                 append_string("\n", 1);
235         }
236         [^ \t\n].* {
237                 while (yyleng) {
238                         if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
239                                 break;
240                         yyleng--;
241                 }
242                 append_string(yytext, yyleng);
243                 if (!first_ts)
244                         first_ts = last_ts;
245         }
246         <<EOF>> {
247                 zconf_endhelp();
248                 return T_HELPTEXT;
249         }
250 }
251 
252 <<EOF>> {
253         BEGIN(INITIAL);
254 
255         if (prev_token != T_EOL && prev_token != T_HELPTEXT)
256                 fprintf(stderr, "%s:%d:warning: no new line at end of file\n",
257                         cur_filename, yylineno);
258 
259         if (current_buf) {
260                 zconf_endfile();
261                 return T_EOL;
262         }
263         fclose(yyin);
264         yyterminate();
265 }
266 
267 %%
268 
269 /* second stage lexer */
270 int yylex(void)
271 {
272         int token;
273 
274 repeat:
275         token = yylex1();
276 
277         if (prev_token == T_EOL || prev_token == T_HELPTEXT) {
278                 if (token == T_EOL)
279                         /* Do not pass unneeded T_EOL to the parser. */
280                         goto repeat;
281                 else
282                         /*
283                          * For the parser, update lineno at the first token
284                          * of each statement. Generally, \n is a statement
285                          * terminator in Kconfig, but it is not always true
286                          * because \n could be escaped by a backslash.
287                          */
288                         cur_lineno = yylineno;
289         }
290 
291         if (prev_prev_token == T_EOL && prev_token == T_WORD &&
292             (token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL))
293                 BEGIN(ASSIGN_VAL);
294 
295         prev_prev_token = prev_token;
296         prev_token = token;
297 
298         return token;
299 }
300 
301 static char *expand_token(const char *in, size_t n)
302 {
303         char *out;
304         int c;
305         char c2;
306         const char *rest, *end;
307 
308         new_string();
309         append_string(in, n);
310 
311         /*
312          * get the whole line because we do not know the end of token.
313          * input() returns 0 (not EOF!) when it reachs the end of file.
314          */
315         while ((c = input()) != 0) {
316                 if (c == '\n') {
317                         unput(c);
318                         break;
319                 }
320                 c2 = c;
321                 append_string(&c2, 1);
322         }
323 
324         rest = text;
325         out = expand_one_token(&rest);
326 
327         /* push back unused characters to the input stream */
328         end = rest + strlen(rest);
329         while (end > rest)
330                 unput(*--end);
331 
332         free(text);
333 
334         return out;
335 }
336 
337 static void append_expanded_string(const char *str)
338 {
339         const char *end;
340         char *res;
341 
342         str++;
343 
344         res = expand_dollar(&str);
345 
346         /* push back unused characters to the input stream */
347         end = str + strlen(str);
348         while (end > str)
349                 unput(*--end);
350 
351         append_string(res, strlen(res));
352 
353         free(res);
354 }
355 
356 void zconf_starthelp(void)
357 {
358         new_string();
359         last_ts = first_ts = 0;
360         BEGIN(HELP);
361 }
362 
363 static void zconf_endhelp(void)
364 {
365         yylval.string = text;
366         BEGIN(INITIAL);
367 }
368 
369 
370 /*
371  * Try to open specified file with following names:
372  * ./name
373  * $(srctree)/name
374  * The latter is used when srctree is separate from objtree
375  * when compiling the kernel.
376  * Return NULL if file is not found.
377  */
378 FILE *zconf_fopen(const char *name)
379 {
380         char *env, fullname[PATH_MAX+1];
381         FILE *f;
382 
383         f = fopen(name, "r");
384         if (!f && name != NULL && name[0] != '/') {
385                 env = getenv(SRCTREE);
386                 if (env) {
387                         snprintf(fullname, sizeof(fullname),
388                                  "%s/%s", env, name);
389                         f = fopen(fullname, "r");
390                 }
391         }
392         return f;
393 }
394 
395 void zconf_initscan(const char *name)
396 {
397         yyin = zconf_fopen(name);
398         if (!yyin) {
399                 fprintf(stderr, "can't find file %s\n", name);
400                 exit(1);
401         }
402 
403         cur_filename = file_lookup(name);
404         yylineno = 1;
405 }
406 
407 void zconf_nextfile(const char *name)
408 {
409         struct buffer *buf = xmalloc(sizeof(*buf));
410         bool recur_include = false;
411 
412         buf->state = YY_CURRENT_BUFFER;
413         buf->yylineno = yylineno;
414         buf->filename = cur_filename;
415         buf->source_lineno = cur_lineno;
416         buf->parent = current_buf;
417         current_buf = buf;
418         yyin = zconf_fopen(name);
419         if (!yyin) {
420                 fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
421                         cur_filename, cur_lineno, name);
422                 exit(1);
423         }
424         yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
425 
426         for (buf = current_buf; buf; buf = buf->parent) {
427                 if (!strcmp(buf->filename, name))
428                         recur_include = true;
429         }
430 
431         if (recur_include) {
432                 fprintf(stderr,
433                         "Recursive inclusion detected.\n"
434                         "Inclusion path:\n"
435                         "  current file : %s\n", name);
436 
437                 for (buf = current_buf; buf; buf = buf->parent)
438                         fprintf(stderr, "  included from: %s:%d\n",
439                                 buf->filename, buf->source_lineno);
440                 exit(1);
441         }
442 
443         yylineno = 1;
444         cur_filename = file_lookup(name);
445 }
446 
447 static void zconf_endfile(void)
448 {
449         struct buffer *tmp;
450 
451         fclose(yyin);
452         yy_delete_buffer(YY_CURRENT_BUFFER);
453         yy_switch_to_buffer(current_buf->state);
454         yylineno = current_buf->yylineno;
455         cur_filename = current_buf->filename;
456         tmp = current_buf;
457         current_buf = current_buf->parent;
458         free(tmp);
459 }

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php