10a9064fbSMasahiro Yamada %option nostdinit noyywrap never-interactive full ecs
20a9064fbSMasahiro Yamada %option 8bit nodefault perf-report perf-report
30a9064fbSMasahiro Yamada %option noinput
40a9064fbSMasahiro Yamada %x COMMAND HELP STRING PARAM
50a9064fbSMasahiro Yamada %{
60a9064fbSMasahiro Yamada /*
70a9064fbSMasahiro Yamada * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
80a9064fbSMasahiro Yamada * Released under the terms of the GNU GPL v2.0.
90a9064fbSMasahiro Yamada */
100a9064fbSMasahiro Yamada
110a9064fbSMasahiro Yamada #include <limits.h>
120a9064fbSMasahiro Yamada #include <stdio.h>
130a9064fbSMasahiro Yamada #include <stdlib.h>
140a9064fbSMasahiro Yamada #include <string.h>
150a9064fbSMasahiro Yamada #include <unistd.h>
160a9064fbSMasahiro Yamada
170a9064fbSMasahiro Yamada #include "lkc.h"
180a9064fbSMasahiro Yamada
190a9064fbSMasahiro Yamada #define START_STRSIZE 16
200a9064fbSMasahiro Yamada
210a9064fbSMasahiro Yamada static struct {
220a9064fbSMasahiro Yamada struct file *file;
230a9064fbSMasahiro Yamada int lineno;
240a9064fbSMasahiro Yamada } current_pos;
250a9064fbSMasahiro Yamada
260a9064fbSMasahiro Yamada static char *text;
270a9064fbSMasahiro Yamada static int text_size, text_asize;
280a9064fbSMasahiro Yamada
290a9064fbSMasahiro Yamada struct buffer {
300a9064fbSMasahiro Yamada struct buffer *parent;
310a9064fbSMasahiro Yamada YY_BUFFER_STATE state;
320a9064fbSMasahiro Yamada };
330a9064fbSMasahiro Yamada
340a9064fbSMasahiro Yamada struct buffer *current_buf;
350a9064fbSMasahiro Yamada
360a9064fbSMasahiro Yamada static int last_ts, first_ts;
370a9064fbSMasahiro Yamada
380a9064fbSMasahiro Yamada static void zconf_endhelp(void);
390a9064fbSMasahiro Yamada static void zconf_endfile(void);
400a9064fbSMasahiro Yamada
new_string(void)410a9064fbSMasahiro Yamada static void new_string(void)
420a9064fbSMasahiro Yamada {
430a9064fbSMasahiro Yamada text = xmalloc(START_STRSIZE);
440a9064fbSMasahiro Yamada text_asize = START_STRSIZE;
450a9064fbSMasahiro Yamada text_size = 0;
460a9064fbSMasahiro Yamada *text = 0;
470a9064fbSMasahiro Yamada }
480a9064fbSMasahiro Yamada
append_string(const char * str,int size)490a9064fbSMasahiro Yamada static void append_string(const char *str, int size)
500a9064fbSMasahiro Yamada {
510a9064fbSMasahiro Yamada int new_size = text_size + size + 1;
520a9064fbSMasahiro Yamada if (new_size > text_asize) {
530a9064fbSMasahiro Yamada new_size += START_STRSIZE - 1;
540a9064fbSMasahiro Yamada new_size &= -START_STRSIZE;
550a9064fbSMasahiro Yamada text = realloc(text, new_size);
560a9064fbSMasahiro Yamada text_asize = new_size;
570a9064fbSMasahiro Yamada }
580a9064fbSMasahiro Yamada memcpy(text + text_size, str, size);
590a9064fbSMasahiro Yamada text_size += size;
600a9064fbSMasahiro Yamada text[text_size] = 0;
610a9064fbSMasahiro Yamada }
620a9064fbSMasahiro Yamada
alloc_string(const char * str,int size)630a9064fbSMasahiro Yamada static void alloc_string(const char *str, int size)
640a9064fbSMasahiro Yamada {
650a9064fbSMasahiro Yamada text = xmalloc(size + 1);
660a9064fbSMasahiro Yamada memcpy(text, str, size);
670a9064fbSMasahiro Yamada text[size] = 0;
680a9064fbSMasahiro Yamada }
69*bf7ab1e7SMasahiro Yamada
warn_ignored_character(char chr)70*bf7ab1e7SMasahiro Yamada static void warn_ignored_character(char chr)
71*bf7ab1e7SMasahiro Yamada {
72*bf7ab1e7SMasahiro Yamada fprintf(stderr,
73*bf7ab1e7SMasahiro Yamada "%s:%d:warning: ignoring unsupported character '%c'\n",
74*bf7ab1e7SMasahiro Yamada zconf_curname(), zconf_lineno(), chr);
75*bf7ab1e7SMasahiro Yamada }
760a9064fbSMasahiro Yamada %}
770a9064fbSMasahiro Yamada
78*bf7ab1e7SMasahiro Yamada n [A-Za-z0-9_-]
790a9064fbSMasahiro Yamada
800a9064fbSMasahiro Yamada %%
810a9064fbSMasahiro Yamada int str = 0;
820a9064fbSMasahiro Yamada int ts, i;
830a9064fbSMasahiro Yamada
840a9064fbSMasahiro Yamada [ \t]*#.*\n |
850a9064fbSMasahiro Yamada [ \t]*\n {
860a9064fbSMasahiro Yamada current_file->lineno++;
870a9064fbSMasahiro Yamada return T_EOL;
880a9064fbSMasahiro Yamada }
890a9064fbSMasahiro Yamada [ \t]*#.*
900a9064fbSMasahiro Yamada
910a9064fbSMasahiro Yamada
920a9064fbSMasahiro Yamada [ \t]+ {
930a9064fbSMasahiro Yamada BEGIN(COMMAND);
940a9064fbSMasahiro Yamada }
950a9064fbSMasahiro Yamada
960a9064fbSMasahiro Yamada . {
970a9064fbSMasahiro Yamada unput(yytext[0]);
980a9064fbSMasahiro Yamada BEGIN(COMMAND);
990a9064fbSMasahiro Yamada }
1000a9064fbSMasahiro Yamada
1010a9064fbSMasahiro Yamada
1020a9064fbSMasahiro Yamada <COMMAND>{
1030a9064fbSMasahiro Yamada {n}+ {
1040a9064fbSMasahiro Yamada const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
1050a9064fbSMasahiro Yamada BEGIN(PARAM);
1060a9064fbSMasahiro Yamada current_pos.file = current_file;
1070a9064fbSMasahiro Yamada current_pos.lineno = current_file->lineno;
1080a9064fbSMasahiro Yamada if (id && id->flags & TF_COMMAND) {
1090a9064fbSMasahiro Yamada zconflval.id = id;
1100a9064fbSMasahiro Yamada return id->token;
1110a9064fbSMasahiro Yamada }
1120a9064fbSMasahiro Yamada alloc_string(yytext, yyleng);
1130a9064fbSMasahiro Yamada zconflval.string = text;
1140a9064fbSMasahiro Yamada return T_WORD;
1150a9064fbSMasahiro Yamada }
116*bf7ab1e7SMasahiro Yamada . warn_ignored_character(*yytext);
1170a9064fbSMasahiro Yamada \n {
1180a9064fbSMasahiro Yamada BEGIN(INITIAL);
1190a9064fbSMasahiro Yamada current_file->lineno++;
1200a9064fbSMasahiro Yamada return T_EOL;
1210a9064fbSMasahiro Yamada }
1220a9064fbSMasahiro Yamada }
1230a9064fbSMasahiro Yamada
1240a9064fbSMasahiro Yamada <PARAM>{
1250a9064fbSMasahiro Yamada "&&" return T_AND;
1260a9064fbSMasahiro Yamada "||" return T_OR;
1270a9064fbSMasahiro Yamada "(" return T_OPEN_PAREN;
1280a9064fbSMasahiro Yamada ")" return T_CLOSE_PAREN;
1290a9064fbSMasahiro Yamada "!" return T_NOT;
1300a9064fbSMasahiro Yamada "=" return T_EQUAL;
1310a9064fbSMasahiro Yamada "!=" return T_UNEQUAL;
132*bf7ab1e7SMasahiro Yamada "<=" return T_LESS_EQUAL;
133*bf7ab1e7SMasahiro Yamada ">=" return T_GREATER_EQUAL;
134*bf7ab1e7SMasahiro Yamada "<" return T_LESS;
135*bf7ab1e7SMasahiro Yamada ">" return T_GREATER;
1360a9064fbSMasahiro Yamada \"|\' {
1370a9064fbSMasahiro Yamada str = yytext[0];
1380a9064fbSMasahiro Yamada new_string();
1390a9064fbSMasahiro Yamada BEGIN(STRING);
1400a9064fbSMasahiro Yamada }
1410a9064fbSMasahiro Yamada \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
142*bf7ab1e7SMasahiro Yamada ({n}|[/.])+ {
1430a9064fbSMasahiro Yamada const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
1440a9064fbSMasahiro Yamada if (id && id->flags & TF_PARAM) {
1450a9064fbSMasahiro Yamada zconflval.id = id;
1460a9064fbSMasahiro Yamada return id->token;
1470a9064fbSMasahiro Yamada }
1480a9064fbSMasahiro Yamada alloc_string(yytext, yyleng);
1490a9064fbSMasahiro Yamada zconflval.string = text;
1500a9064fbSMasahiro Yamada return T_WORD;
1510a9064fbSMasahiro Yamada }
1520a9064fbSMasahiro Yamada #.* /* comment */
1530a9064fbSMasahiro Yamada \\\n current_file->lineno++;
154*bf7ab1e7SMasahiro Yamada [[:blank:]]+
155*bf7ab1e7SMasahiro Yamada . warn_ignored_character(*yytext);
1560a9064fbSMasahiro Yamada <<EOF>> {
1570a9064fbSMasahiro Yamada BEGIN(INITIAL);
1580a9064fbSMasahiro Yamada }
1590a9064fbSMasahiro Yamada }
1600a9064fbSMasahiro Yamada
1610a9064fbSMasahiro Yamada <STRING>{
1620a9064fbSMasahiro Yamada [^'"\\\n]+/\n {
1630a9064fbSMasahiro Yamada append_string(yytext, yyleng);
1640a9064fbSMasahiro Yamada zconflval.string = text;
1650a9064fbSMasahiro Yamada return T_WORD_QUOTE;
1660a9064fbSMasahiro Yamada }
1670a9064fbSMasahiro Yamada [^'"\\\n]+ {
1680a9064fbSMasahiro Yamada append_string(yytext, yyleng);
1690a9064fbSMasahiro Yamada }
1700a9064fbSMasahiro Yamada \\.?/\n {
1710a9064fbSMasahiro Yamada append_string(yytext + 1, yyleng - 1);
1720a9064fbSMasahiro Yamada zconflval.string = text;
1730a9064fbSMasahiro Yamada return T_WORD_QUOTE;
1740a9064fbSMasahiro Yamada }
1750a9064fbSMasahiro Yamada \\.? {
1760a9064fbSMasahiro Yamada append_string(yytext + 1, yyleng - 1);
1770a9064fbSMasahiro Yamada }
1780a9064fbSMasahiro Yamada \'|\" {
1790a9064fbSMasahiro Yamada if (str == yytext[0]) {
1800a9064fbSMasahiro Yamada BEGIN(PARAM);
1810a9064fbSMasahiro Yamada zconflval.string = text;
1820a9064fbSMasahiro Yamada return T_WORD_QUOTE;
1830a9064fbSMasahiro Yamada } else
1840a9064fbSMasahiro Yamada append_string(yytext, 1);
1850a9064fbSMasahiro Yamada }
1860a9064fbSMasahiro Yamada \n {
1870a9064fbSMasahiro Yamada printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
1880a9064fbSMasahiro Yamada current_file->lineno++;
1890a9064fbSMasahiro Yamada BEGIN(INITIAL);
1900a9064fbSMasahiro Yamada return T_EOL;
1910a9064fbSMasahiro Yamada }
1920a9064fbSMasahiro Yamada <<EOF>> {
1930a9064fbSMasahiro Yamada BEGIN(INITIAL);
1940a9064fbSMasahiro Yamada }
1950a9064fbSMasahiro Yamada }
1960a9064fbSMasahiro Yamada
1970a9064fbSMasahiro Yamada <HELP>{
1980a9064fbSMasahiro Yamada [ \t]+ {
1990a9064fbSMasahiro Yamada ts = 0;
2000a9064fbSMasahiro Yamada for (i = 0; i < yyleng; i++) {
2010a9064fbSMasahiro Yamada if (yytext[i] == '\t')
2020a9064fbSMasahiro Yamada ts = (ts & ~7) + 8;
2030a9064fbSMasahiro Yamada else
2040a9064fbSMasahiro Yamada ts++;
2050a9064fbSMasahiro Yamada }
2060a9064fbSMasahiro Yamada last_ts = ts;
2070a9064fbSMasahiro Yamada if (first_ts) {
2080a9064fbSMasahiro Yamada if (ts < first_ts) {
2090a9064fbSMasahiro Yamada zconf_endhelp();
2100a9064fbSMasahiro Yamada return T_HELPTEXT;
2110a9064fbSMasahiro Yamada }
2120a9064fbSMasahiro Yamada ts -= first_ts;
2130a9064fbSMasahiro Yamada while (ts > 8) {
2140a9064fbSMasahiro Yamada append_string(" ", 8);
2150a9064fbSMasahiro Yamada ts -= 8;
2160a9064fbSMasahiro Yamada }
2170a9064fbSMasahiro Yamada append_string(" ", ts);
2180a9064fbSMasahiro Yamada }
2190a9064fbSMasahiro Yamada }
2200a9064fbSMasahiro Yamada [ \t]*\n/[^ \t\n] {
2210a9064fbSMasahiro Yamada current_file->lineno++;
2220a9064fbSMasahiro Yamada zconf_endhelp();
2230a9064fbSMasahiro Yamada return T_HELPTEXT;
2240a9064fbSMasahiro Yamada }
2250a9064fbSMasahiro Yamada [ \t]*\n {
2260a9064fbSMasahiro Yamada current_file->lineno++;
2270a9064fbSMasahiro Yamada append_string("\n", 1);
2280a9064fbSMasahiro Yamada }
2290a9064fbSMasahiro Yamada [^ \t\n].* {
2300a9064fbSMasahiro Yamada while (yyleng) {
2310a9064fbSMasahiro Yamada if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
2320a9064fbSMasahiro Yamada break;
2330a9064fbSMasahiro Yamada yyleng--;
2340a9064fbSMasahiro Yamada }
2350a9064fbSMasahiro Yamada append_string(yytext, yyleng);
2360a9064fbSMasahiro Yamada if (!first_ts)
2370a9064fbSMasahiro Yamada first_ts = last_ts;
2380a9064fbSMasahiro Yamada }
2390a9064fbSMasahiro Yamada <<EOF>> {
2400a9064fbSMasahiro Yamada zconf_endhelp();
2410a9064fbSMasahiro Yamada return T_HELPTEXT;
2420a9064fbSMasahiro Yamada }
2430a9064fbSMasahiro Yamada }
2440a9064fbSMasahiro Yamada
2450a9064fbSMasahiro Yamada <<EOF>> {
2460a9064fbSMasahiro Yamada if (current_file) {
2470a9064fbSMasahiro Yamada zconf_endfile();
2480a9064fbSMasahiro Yamada return T_EOL;
2490a9064fbSMasahiro Yamada }
2500a9064fbSMasahiro Yamada fclose(yyin);
2510a9064fbSMasahiro Yamada yyterminate();
2520a9064fbSMasahiro Yamada }
2530a9064fbSMasahiro Yamada
2540a9064fbSMasahiro Yamada %%
2550a9064fbSMasahiro Yamada void zconf_starthelp(void)
2560a9064fbSMasahiro Yamada {
2570a9064fbSMasahiro Yamada new_string();
2580a9064fbSMasahiro Yamada last_ts = first_ts = 0;
2590a9064fbSMasahiro Yamada BEGIN(HELP);
2600a9064fbSMasahiro Yamada }
2610a9064fbSMasahiro Yamada
2620a9064fbSMasahiro Yamada static void zconf_endhelp(void)
2630a9064fbSMasahiro Yamada {
2640a9064fbSMasahiro Yamada zconflval.string = text;
2650a9064fbSMasahiro Yamada BEGIN(INITIAL);
2660a9064fbSMasahiro Yamada }
2670a9064fbSMasahiro Yamada
2680a9064fbSMasahiro Yamada
2690a9064fbSMasahiro Yamada /*
2700a9064fbSMasahiro Yamada * Try to open specified file with following names:
2710a9064fbSMasahiro Yamada * ./name
2720a9064fbSMasahiro Yamada * $(srctree)/name
2730a9064fbSMasahiro Yamada * The latter is used when srctree is separate from objtree
2740a9064fbSMasahiro Yamada * when compiling the kernel.
2750a9064fbSMasahiro Yamada * Return NULL if file is not found.
2760a9064fbSMasahiro Yamada */
2770a9064fbSMasahiro Yamada FILE *zconf_fopen(const char *name)
2780a9064fbSMasahiro Yamada {
2790a9064fbSMasahiro Yamada char *env, fullname[PATH_MAX+1];
2800a9064fbSMasahiro Yamada FILE *f;
2810a9064fbSMasahiro Yamada
2820a9064fbSMasahiro Yamada f = fopen(name, "r");
2830a9064fbSMasahiro Yamada if (!f && name != NULL && name[0] != '/') {
2840a9064fbSMasahiro Yamada env = getenv(SRCTREE);
2850a9064fbSMasahiro Yamada if (env) {
2860a9064fbSMasahiro Yamada sprintf(fullname, "%s/%s", env, name);
2870a9064fbSMasahiro Yamada f = fopen(fullname, "r");
2880a9064fbSMasahiro Yamada }
2890a9064fbSMasahiro Yamada }
2900a9064fbSMasahiro Yamada return f;
2910a9064fbSMasahiro Yamada }
2920a9064fbSMasahiro Yamada
2930a9064fbSMasahiro Yamada void zconf_initscan(const char *name)
2940a9064fbSMasahiro Yamada {
2950a9064fbSMasahiro Yamada yyin = zconf_fopen(name);
2960a9064fbSMasahiro Yamada if (!yyin) {
2970a9064fbSMasahiro Yamada printf("can't find file %s\n", name);
2980a9064fbSMasahiro Yamada exit(1);
2990a9064fbSMasahiro Yamada }
3000a9064fbSMasahiro Yamada
3010a9064fbSMasahiro Yamada current_buf = xmalloc(sizeof(*current_buf));
3020a9064fbSMasahiro Yamada memset(current_buf, 0, sizeof(*current_buf));
3030a9064fbSMasahiro Yamada
3040a9064fbSMasahiro Yamada current_file = file_lookup(name);
3050a9064fbSMasahiro Yamada current_file->lineno = 1;
3060a9064fbSMasahiro Yamada }
3070a9064fbSMasahiro Yamada
3080a9064fbSMasahiro Yamada void zconf_nextfile(const char *name)
3090a9064fbSMasahiro Yamada {
3100a9064fbSMasahiro Yamada struct file *iter;
3110a9064fbSMasahiro Yamada struct file *file = file_lookup(name);
3120a9064fbSMasahiro Yamada struct buffer *buf = xmalloc(sizeof(*buf));
3130a9064fbSMasahiro Yamada memset(buf, 0, sizeof(*buf));
3140a9064fbSMasahiro Yamada
3150a9064fbSMasahiro Yamada current_buf->state = YY_CURRENT_BUFFER;
3160a9064fbSMasahiro Yamada yyin = zconf_fopen(file->name);
3170a9064fbSMasahiro Yamada if (!yyin) {
3180a9064fbSMasahiro Yamada printf("%s:%d: can't open file \"%s\"\n",
3190a9064fbSMasahiro Yamada zconf_curname(), zconf_lineno(), file->name);
3200a9064fbSMasahiro Yamada exit(1);
3210a9064fbSMasahiro Yamada }
3220a9064fbSMasahiro Yamada yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
3230a9064fbSMasahiro Yamada buf->parent = current_buf;
3240a9064fbSMasahiro Yamada current_buf = buf;
3250a9064fbSMasahiro Yamada
3260a9064fbSMasahiro Yamada for (iter = current_file->parent; iter; iter = iter->parent ) {
3270a9064fbSMasahiro Yamada if (!strcmp(current_file->name,iter->name) ) {
3280a9064fbSMasahiro Yamada printf("%s:%d: recursive inclusion detected. "
3290a9064fbSMasahiro Yamada "Inclusion path:\n current file : '%s'\n",
3300a9064fbSMasahiro Yamada zconf_curname(), zconf_lineno(),
3310a9064fbSMasahiro Yamada zconf_curname());
3320a9064fbSMasahiro Yamada iter = current_file->parent;
3330a9064fbSMasahiro Yamada while (iter && \
3340a9064fbSMasahiro Yamada strcmp(iter->name,current_file->name)) {
3350a9064fbSMasahiro Yamada printf(" included from: '%s:%d'\n",
3360a9064fbSMasahiro Yamada iter->name, iter->lineno-1);
3370a9064fbSMasahiro Yamada iter = iter->parent;
3380a9064fbSMasahiro Yamada }
3390a9064fbSMasahiro Yamada if (iter)
3400a9064fbSMasahiro Yamada printf(" included from: '%s:%d'\n",
3410a9064fbSMasahiro Yamada iter->name, iter->lineno+1);
3420a9064fbSMasahiro Yamada exit(1);
3430a9064fbSMasahiro Yamada }
3440a9064fbSMasahiro Yamada }
3450a9064fbSMasahiro Yamada file->lineno = 1;
3460a9064fbSMasahiro Yamada file->parent = current_file;
3470a9064fbSMasahiro Yamada current_file = file;
3480a9064fbSMasahiro Yamada }
3490a9064fbSMasahiro Yamada
3500a9064fbSMasahiro Yamada static void zconf_endfile(void)
3510a9064fbSMasahiro Yamada {
3520a9064fbSMasahiro Yamada struct buffer *parent;
3530a9064fbSMasahiro Yamada
3540a9064fbSMasahiro Yamada current_file = current_file->parent;
3550a9064fbSMasahiro Yamada
3560a9064fbSMasahiro Yamada parent = current_buf->parent;
3570a9064fbSMasahiro Yamada if (parent) {
3580a9064fbSMasahiro Yamada fclose(yyin);
3590a9064fbSMasahiro Yamada yy_delete_buffer(YY_CURRENT_BUFFER);
3600a9064fbSMasahiro Yamada yy_switch_to_buffer(parent->state);
3610a9064fbSMasahiro Yamada }
3620a9064fbSMasahiro Yamada free(current_buf);
3630a9064fbSMasahiro Yamada current_buf = parent;
3640a9064fbSMasahiro Yamada }
3650a9064fbSMasahiro Yamada
3660a9064fbSMasahiro Yamada int zconf_lineno(void)
3670a9064fbSMasahiro Yamada {
3680a9064fbSMasahiro Yamada return current_pos.lineno;
3690a9064fbSMasahiro Yamada }
3700a9064fbSMasahiro Yamada
3710a9064fbSMasahiro Yamada const char *zconf_curname(void)
3720a9064fbSMasahiro Yamada {
3730a9064fbSMasahiro Yamada return current_pos.file ? current_pos.file->name : "<none>";
3740a9064fbSMasahiro Yamada }
375