yann@2836: %option backup nostdinit noyywrap never-interactive full ecs yann@2836: %option 8bit backup nodefault perf-report perf-report yann@2836: %option noinput yann@2836: %x COMMAND HELP STRING PARAM yann@2836: %{ yann@2836: /* yann@2836: * Copyright (C) 2002 Roman Zippel yann@2836: * Released under the terms of the GNU GPL v2.0. yann@2836: */ yann@2836: yann@2836: #include yann@2836: #include yann@2836: #include yann@2836: #include yann@2836: #include yann@2836: yann@2836: #define LKC_DIRECT_LINK yann@2836: #include "lkc.h" yann@2836: yann@2836: #define START_STRSIZE 16 yann@2836: yann@2836: static struct { yann@2836: struct file *file; yann@2836: int lineno; yann@2836: } current_pos; yann@2836: yann@2836: static char *text; yann@2836: static int text_size, text_asize; yann@2836: yann@2836: struct buffer { yann@2836: struct buffer *parent; yann@2836: YY_BUFFER_STATE state; yann@2836: }; yann@2836: yann@2836: struct buffer *current_buf; yann@2836: yann@2836: static int last_ts, first_ts; yann@2836: yann@2836: static void zconf_endhelp(void); yann@2836: static void zconf_endfile(void); yann@2836: yann@2836: static void new_string(void) yann@2836: { yann@2836: text = malloc(START_STRSIZE); yann@2836: text_asize = START_STRSIZE; yann@2836: text_size = 0; yann@2836: *text = 0; yann@2836: } yann@2836: yann@2836: static void append_string(const char *str, int size) yann@2836: { yann@2836: int new_size = text_size + size + 1; yann@2836: if (new_size > text_asize) { yann@2836: new_size += START_STRSIZE - 1; yann@2836: new_size &= -START_STRSIZE; yann@2836: text = realloc(text, new_size); yann@2836: text_asize = new_size; yann@2836: } yann@2836: memcpy(text + text_size, str, size); yann@2836: text_size += size; yann@2836: text[text_size] = 0; yann@2836: } yann@2836: yann@2836: static void alloc_string(const char *str, int size) yann@2836: { yann@2836: text = malloc(size + 1); yann@2836: memcpy(text, str, size); yann@2836: text[size] = 0; yann@2836: } yann@2836: %} yann@2836: yann@2836: ws [ \n\t] yann@2836: n [A-Za-z0-9_] yann@2836: yann@2836: %% yann@2836: int str = 0; yann@2836: int ts, i; yann@2836: yann@2836: [ \t]*#.*\n | yann@2836: [ \t]*\n { yann@2836: current_file->lineno++; yann@2836: return T_EOL; yann@2836: } yann@2836: [ \t]*#.* yann@2836: yann@2836: yann@2836: [ \t]+ { yann@2836: BEGIN(COMMAND); yann@2836: } yann@2836: yann@2836: . { yann@2836: unput(yytext[0]); yann@2836: BEGIN(COMMAND); yann@2836: } yann@2836: yann@2836: yann@2836: { yann@2836: {n}+ { yann@2836: struct kconf_id *id = kconf_id_lookup(yytext, yyleng); yann@2836: BEGIN(PARAM); yann@2836: current_pos.file = current_file; yann@2836: current_pos.lineno = current_file->lineno; yann@2836: if (id && id->flags & TF_COMMAND) { yann@2836: zconflval.id = id; yann@2836: return id->token; yann@2836: } yann@2836: alloc_string(yytext, yyleng); yann@2836: zconflval.string = text; yann@2836: return T_WORD; yann@2836: } yann@2836: . yann@2836: \n { yann@2836: BEGIN(INITIAL); yann@2836: current_file->lineno++; yann@2836: return T_EOL; yann@2836: } yann@2836: } yann@2836: yann@2836: { yann@2836: "&&" return T_AND; yann@2836: "||" return T_OR; yann@2836: "(" return T_OPEN_PAREN; yann@2836: ")" return T_CLOSE_PAREN; yann@2836: "!" return T_NOT; yann@2836: "=" return T_EQUAL; yann@2836: "!=" return T_UNEQUAL; yann@2836: \"|\' { yann@2836: str = yytext[0]; yann@2836: new_string(); yann@2836: BEGIN(STRING); yann@2836: } yann@2836: \n BEGIN(INITIAL); current_file->lineno++; return T_EOL; yann@2836: --- /* ignore */ yann@2836: ({n}|[-/.])+ { yann@2836: struct kconf_id *id = kconf_id_lookup(yytext, yyleng); yann@2836: if (id && id->flags & TF_PARAM) { yann@2836: zconflval.id = id; yann@2836: return id->token; yann@2836: } yann@2836: alloc_string(yytext, yyleng); yann@2836: zconflval.string = text; yann@2836: return T_WORD; yann@2836: } yann@2836: #.* /* comment */ yann@2836: \\\n current_file->lineno++; yann@2836: . yann@2836: <> { yann@2836: BEGIN(INITIAL); yann@2836: } yann@2836: } yann@2836: yann@2836: { yann@2836: [^'"\\\n]+/\n { yann@2836: append_string(yytext, yyleng); yann@2836: zconflval.string = text; yann@2836: return T_WORD_QUOTE; yann@2836: } yann@2836: [^'"\\\n]+ { yann@2836: append_string(yytext, yyleng); yann@2836: } yann@2836: \\.?/\n { yann@2836: append_string(yytext + 1, yyleng - 1); yann@2836: zconflval.string = text; yann@2836: return T_WORD_QUOTE; yann@2836: } yann@2836: \\.? { yann@2836: append_string(yytext + 1, yyleng - 1); yann@2836: } yann@2836: \'|\" { yann@2836: if (str == yytext[0]) { yann@2836: BEGIN(PARAM); yann@2836: zconflval.string = text; yann@2836: return T_WORD_QUOTE; yann@2836: } else yann@2836: append_string(yytext, 1); yann@2836: } yann@2836: \n { yann@2836: printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); yann@2836: current_file->lineno++; yann@2836: BEGIN(INITIAL); yann@2836: return T_EOL; yann@2836: } yann@2836: <> { yann@2836: BEGIN(INITIAL); yann@2836: } yann@2836: } yann@2836: yann@2836: { yann@2836: [ \t]+ { yann@2836: ts = 0; yann@2836: for (i = 0; i < yyleng; i++) { yann@2836: if (yytext[i] == '\t') yann@2836: ts = (ts & ~7) + 8; yann@2836: else yann@2836: ts++; yann@2836: } yann@2836: last_ts = ts; yann@2836: if (first_ts) { yann@2836: if (ts < first_ts) { yann@2836: zconf_endhelp(); yann@2836: return T_HELPTEXT; yann@2836: } yann@2836: ts -= first_ts; yann@2836: while (ts > 8) { yann@2836: append_string(" ", 8); yann@2836: ts -= 8; yann@2836: } yann@2836: append_string(" ", ts); yann@2836: } yann@2836: } yann@2836: [ \t]*\n/[^ \t\n] { yann@2836: current_file->lineno++; yann@2836: zconf_endhelp(); yann@2836: return T_HELPTEXT; yann@2836: } yann@2836: [ \t]*\n { yann@2836: current_file->lineno++; yann@2836: append_string("\n", 1); yann@2836: } yann@2836: [^ \t\n].* { yann@2836: while (yyleng) { yann@2836: if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t')) yann@2836: break; yann@2836: yyleng--; yann@2836: } yann@2836: append_string(yytext, yyleng); yann@2836: if (!first_ts) yann@2836: first_ts = last_ts; yann@2836: } yann@2836: <> { yann@2836: zconf_endhelp(); yann@2836: return T_HELPTEXT; yann@2836: } yann@2836: } yann@2836: yann@2836: <> { yann@2836: if (current_file) { yann@2836: zconf_endfile(); yann@2836: return T_EOL; yann@2836: } yann@2836: fclose(yyin); yann@2836: yyterminate(); yann@2836: } yann@2836: yann@2836: %% yann@2836: void zconf_starthelp(void) yann@2836: { yann@2836: new_string(); yann@2836: last_ts = first_ts = 0; yann@2836: BEGIN(HELP); yann@2836: } yann@2836: yann@2836: static void zconf_endhelp(void) yann@2836: { yann@2836: zconflval.string = text; yann@2836: BEGIN(INITIAL); yann@2836: } yann@2836: yann@2836: yann@2836: /* yann@2836: * Try to open specified file with following names: yann@2836: * ./name yann@2836: * $(srctree)/name yann@2836: * The latter is used when srctree is separate from objtree yann@2836: * when compiling the kernel. yann@2836: * Return NULL if file is not found. yann@2836: */ yann@2836: FILE *zconf_fopen(const char *name) yann@2836: { yann@2836: char *env, fullname[PATH_MAX+1]; yann@2836: FILE *f; yann@2836: yann@2836: f = fopen(name, "r"); yann@2836: if (!f && name != NULL && name[0] != '/') { yann@2836: env = getenv(SRCTREE); yann@2836: if (env) { yann@2836: sprintf(fullname, "%s/%s", env, name); yann@2836: f = fopen(fullname, "r"); yann@2836: } yann@2836: } yann@2836: return f; yann@2836: } yann@2836: yann@2836: void zconf_initscan(const char *name) yann@2836: { yann@2836: yyin = zconf_fopen(name); yann@2836: if (!yyin) { yann@2836: printf("can't find file %s\n", name); yann@2836: exit(1); yann@2836: } yann@2836: yann@2836: current_buf = malloc(sizeof(*current_buf)); yann@2836: memset(current_buf, 0, sizeof(*current_buf)); yann@2836: yann@2836: current_file = file_lookup(name); yann@2836: current_file->lineno = 1; yann@2836: } yann@2836: yann@2836: void zconf_nextfile(const char *name) yann@2836: { yann@2836: struct file *iter; yann@2836: struct file *file = file_lookup(name); yann@2836: struct buffer *buf = malloc(sizeof(*buf)); yann@2836: memset(buf, 0, sizeof(*buf)); yann@2836: yann@2836: current_buf->state = YY_CURRENT_BUFFER; yann@2836: yyin = zconf_fopen(file->name); yann@2836: if (!yyin) { yann@2836: printf("%s:%d: can't open file \"%s\"\n", yann@2836: zconf_curname(), zconf_lineno(), file->name); yann@2836: exit(1); yann@2836: } yann@2836: yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); yann@2836: buf->parent = current_buf; yann@2836: current_buf = buf; yann@2836: yann@2836: for (iter = current_file->parent; iter; iter = iter->parent ) { yann@2836: if (!strcmp(current_file->name,iter->name) ) { yann@2836: printf("%s:%d: recursive inclusion detected. " yann@2836: "Inclusion path:\n current file : '%s'\n", yann@2836: zconf_curname(), zconf_lineno(), yann@2836: zconf_curname()); yann@2836: iter = current_file->parent; yann@2836: while (iter && \ yann@2836: strcmp(iter->name,current_file->name)) { yann@2836: printf(" included from: '%s:%d'\n", yann@2836: iter->name, iter->lineno-1); yann@2836: iter = iter->parent; yann@2836: } yann@2836: if (iter) yann@2836: printf(" included from: '%s:%d'\n", yann@2836: iter->name, iter->lineno+1); yann@2836: exit(1); yann@2836: } yann@2836: } yann@2836: file->lineno = 1; yann@2836: file->parent = current_file; yann@2836: current_file = file; yann@2836: } yann@2836: yann@2836: static void zconf_endfile(void) yann@2836: { yann@2836: struct buffer *parent; yann@2836: yann@2836: current_file = current_file->parent; yann@2836: yann@2836: parent = current_buf->parent; yann@2836: if (parent) { yann@2836: fclose(yyin); yann@2836: yy_delete_buffer(YY_CURRENT_BUFFER); yann@2836: yy_switch_to_buffer(parent->state); yann@2836: } yann@2836: free(current_buf); yann@2836: current_buf = parent; yann@2836: } yann@2836: yann@2836: int zconf_lineno(void) yann@2836: { yann@2836: return current_pos.lineno; yann@2836: } yann@2836: yann@2836: const char *zconf_curname(void) yann@2836: { yann@2836: return current_pos.file ? current_pos.file->name : ""; yann@2836: }