summaryrefslogtreecommitdiff
path: root/scripts/kconfig/cml1.l
Side-by-side diff
Diffstat (limited to 'scripts/kconfig/cml1.l') (more/less context) (ignore whitespace changes)
-rw-r--r--scripts/kconfig/cml1.l213
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();
+}
+%%