-rw-r--r-- | scripts/kconfig/cml1.l | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/scripts/kconfig/cml1.l b/scripts/kconfig/cml1.l new file mode 100644 index 0000000..d6c33a0 --- a/dev/null +++ b/scripts/kconfig/cml1.l @@ -0,0 +1,213 @@ +%option nounput backup nostdinit noyywrap full ecs +%option 8bit backup nodefault perf-report perf-report +%x STRING +%{ +/* + * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> + * Released under the terms of the GNU GPL v2.0. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "cml1.h" + +char *text; +static char *text_ptr; +static int text_size, text_asize; + +struct buffer { + struct buffer *parent; + YY_BUFFER_STATE state; +}; + +struct buffer *current_buf; + +int lineno(void) +{ + if (current_buf) + return current_file->lineno; + else + return 0; +} + +void scan_init(char *file) +{ + struct buffer *buf = malloc(sizeof(*buf)); + memset(buf, 0, sizeof(*buf)); + + yyin = fopen(file, "r"); + if (!yyin) { + printf("can't find file %s\n", file); + exit(1); + } + current_buf = buf; + + current_file = lookup_file(file); + current_file->lineno = 0; + current_file->flags = FILE_BUSY; +} + +void scan_nextfile(char *name) +{ + struct file *file = lookup_file(name); + struct buffer *buf = malloc(sizeof(*buf)); + memset(buf, 0, sizeof(*buf)); + + current_buf->state = YY_CURRENT_BUFFER; + yyin = fopen(name, "r"); + if (!yyin) { + printf("can't find file %s\n", name); + exit(1); + } + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + buf->parent = current_buf; + current_buf = buf; + + if (file->flags & FILE_BUSY) { + printf("recursive scan (%s)?\n", name); + exit(1); + } + file->flags |= FILE_BUSY; + file->lineno = 0; + file->parent = current_file; + current_file = file; +} + +#define START_STRSIZE 16 + +void new_string(void) +{ + text = malloc(START_STRSIZE); + text_asize = START_STRSIZE; + text_ptr = text; + text_size = 0; + *text_ptr = 0; +} + +void append_string(const char *str, int size) +{ + int new_size = text_size + size + 1; + if (new_size > text_asize) { + text = realloc(text, new_size); + text_asize = new_size; + text_ptr = text + text_size; + } + memcpy(text_ptr, str, size); + text_ptr += size; + text_size += size; + *text_ptr = 0; +} + +void alloc_string(const char *str, int size) +{ + text = malloc(size + 1); + memcpy(text, str, size); + text[size] = 0; +} + +%} +%% + int str = 0; + +\"|\' { + str = yytext[0]; + new_string(); + BEGIN(STRING); +} +<STRING>{ + [^'"\n\\]+ { + append_string(yytext, yyleng); + } + \'|\" { + if (str == yytext[0]) { + BEGIN(INITIAL); + cml1lval.string = text; + //printf("s:%s", text); + return str == '"' ? T_WORD_DQUOTE : T_WORD_QUOTE; + } else + append_string(yytext, 1); + } + \\[ \t]*\n append_string(yytext+yyleng-1, 1); current_file->lineno++; + \\[ \t]* append_string(yytext+1, yyleng-1); + \\. append_string(yytext+1, 1); + \n { + printf(":%d: open string!\n", current_file->lineno+1); + exit(0); + } + <<EOF>> { + printf(":%d: open string!\n", current_file->lineno+1); + exit(0); + } +} +mainmenu_name[ \t] return T_MAINMENU_NAME; +mainmenu_option[ \t] return T_MAINMENU_OPTION; +next_comment/[ \t\n] return T_NEXT_COMMENT; +endmenu/[ \t\n] return T_ENDMENU; +comment[ \t] return T_COMMENT; +bool[ \t] return T_BOOL; +hex[ \t] return T_HEX; +int[ \t] return T_INT; +string[ \t] return T_STRING; +tristate[ \t] return T_TRISTATE; +define_bool[ \t] return T_DEFINE_BOOL; +define_hex[ \t] return T_DEFINE_HEX; +define_int[ \t] return T_DEFINE_INT; +define_string[ \t] return T_DEFINE_STRING; +define_tristate[ \t] return T_DEFINE_TRISTATE; +dep_bool[ \t] return T_DEP_BOOL; +dep_mbool[ \t] return T_DEP_MBOOL; +dep_tristate[ \t] return T_DEP_TRISTATE; +unset[ \t] return T_UNSET; +choice[ \t] return T_CHOICE; +source[ \t] return T_SOURCE; +if[ \t] return T_IF; +else/[ \t\n] return T_ELSE; +fi/[ \t\n] return T_FI; +then/[ \t\n] return T_THEN; +\[ return '['; +\] return ']'; +; return ';'; +!= return T_UNEQUAL; += return '='; +! return '!'; +-a return T_AND; +-o return T_OR; +#[^\n]* { + /* comment */ + current_file->lineno++; + alloc_string(yytext, yyleng); + cml1lval.string = text; + return T_SH_COMMENT; +} +[ \t]+ /* space */ +\\\n current_file->lineno++; /* ignore */ +\n { + current_file->lineno++; + return '\n'; +} +[[:alnum:]$/][[:graph:]]* { + alloc_string(yytext, yyleng); + cml1lval.string = text; + //printf("w:%s", text); + return T_WORD; +} +. { + printf("%s:%d: invalid character 0x%x(%c)\n", current_file->name, current_file->lineno+1, yytext[0], yytext[0]); + exit(1); +} +<<EOF>> { + if (current_buf->parent) { + struct buffer *buf = current_buf; + current_buf = buf->parent; + current_file->flags |= FILE_SCANNED; + current_file->flags &= ~FILE_BUSY; + current_file = current_file->parent; + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(current_buf->state); + free(buf); + } else + yyterminate(); +} +%% |