kconfig/zconf.l
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue Aug 23 21:11:26 2011 +0200 (2011-08-23)
changeset 2891 f176fee535a0
permissions -rw-r--r--
cc/gcc: add 'cflags' paramater to the core backend

As the core backend is used to generate the bare-metal compiler,
we need to pass it the host CFLAGS.

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
     1 %option backup nostdinit noyywrap never-interactive full ecs
     2 %option 8bit backup nodefault perf-report perf-report
     3 %option noinput
     4 %x COMMAND HELP STRING PARAM
     5 %{
     6 /*
     7  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
     8  * Released under the terms of the GNU GPL v2.0.
     9  */
    10 
    11 #include <limits.h>
    12 #include <stdio.h>
    13 #include <stdlib.h>
    14 #include <string.h>
    15 #include <unistd.h>
    16 
    17 #define LKC_DIRECT_LINK
    18 #include "lkc.h"
    19 
    20 #define START_STRSIZE	16
    21 
    22 static struct {
    23 	struct file *file;
    24 	int lineno;
    25 } current_pos;
    26 
    27 static char *text;
    28 static int text_size, text_asize;
    29 
    30 struct buffer {
    31         struct buffer *parent;
    32         YY_BUFFER_STATE state;
    33 };
    34 
    35 struct buffer *current_buf;
    36 
    37 static int last_ts, first_ts;
    38 
    39 static void zconf_endhelp(void);
    40 static void zconf_endfile(void);
    41 
    42 static void new_string(void)
    43 {
    44 	text = malloc(START_STRSIZE);
    45 	text_asize = START_STRSIZE;
    46 	text_size = 0;
    47 	*text = 0;
    48 }
    49 
    50 static void append_string(const char *str, int size)
    51 {
    52 	int new_size = text_size + size + 1;
    53 	if (new_size > text_asize) {
    54 		new_size += START_STRSIZE - 1;
    55 		new_size &= -START_STRSIZE;
    56 		text = realloc(text, new_size);
    57 		text_asize = new_size;
    58 	}
    59 	memcpy(text + text_size, str, size);
    60 	text_size += size;
    61 	text[text_size] = 0;
    62 }
    63 
    64 static void alloc_string(const char *str, int size)
    65 {
    66 	text = malloc(size + 1);
    67 	memcpy(text, str, size);
    68 	text[size] = 0;
    69 }
    70 %}
    71 
    72 ws	[ \n\t]
    73 n	[A-Za-z0-9_]
    74 
    75 %%
    76 	int str = 0;
    77 	int ts, i;
    78 
    79 [ \t]*#.*\n	|
    80 [ \t]*\n	{
    81 	current_file->lineno++;
    82 	return T_EOL;
    83 }
    84 [ \t]*#.*
    85 
    86 
    87 [ \t]+	{
    88 	BEGIN(COMMAND);
    89 }
    90 
    91 .	{
    92 	unput(yytext[0]);
    93 	BEGIN(COMMAND);
    94 }
    95 
    96 
    97 <COMMAND>{
    98 	{n}+	{
    99 		struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
   100 		BEGIN(PARAM);
   101 		current_pos.file = current_file;
   102 		current_pos.lineno = current_file->lineno;
   103 		if (id && id->flags & TF_COMMAND) {
   104 			zconflval.id = id;
   105 			return id->token;
   106 		}
   107 		alloc_string(yytext, yyleng);
   108 		zconflval.string = text;
   109 		return T_WORD;
   110 	}
   111 	.
   112 	\n	{
   113 		BEGIN(INITIAL);
   114 		current_file->lineno++;
   115 		return T_EOL;
   116 	}
   117 }
   118 
   119 <PARAM>{
   120 	"&&"	return T_AND;
   121 	"||"	return T_OR;
   122 	"("	return T_OPEN_PAREN;
   123 	")"	return T_CLOSE_PAREN;
   124 	"!"	return T_NOT;
   125 	"="	return T_EQUAL;
   126 	"!="	return T_UNEQUAL;
   127 	\"|\'	{
   128 		str = yytext[0];
   129 		new_string();
   130 		BEGIN(STRING);
   131 	}
   132 	\n	BEGIN(INITIAL); current_file->lineno++; return T_EOL;
   133 	---	/* ignore */
   134 	({n}|[-/.])+	{
   135 		struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
   136 		if (id && id->flags & TF_PARAM) {
   137 			zconflval.id = id;
   138 			return id->token;
   139 		}
   140 		alloc_string(yytext, yyleng);
   141 		zconflval.string = text;
   142 		return T_WORD;
   143 	}
   144 	#.*	/* comment */
   145 	\\\n	current_file->lineno++;
   146 	.
   147 	<<EOF>> {
   148 		BEGIN(INITIAL);
   149 	}
   150 }
   151 
   152 <STRING>{
   153 	[^'"\\\n]+/\n	{
   154 		append_string(yytext, yyleng);
   155 		zconflval.string = text;
   156 		return T_WORD_QUOTE;
   157 	}
   158 	[^'"\\\n]+	{
   159 		append_string(yytext, yyleng);
   160 	}
   161 	\\.?/\n	{
   162 		append_string(yytext + 1, yyleng - 1);
   163 		zconflval.string = text;
   164 		return T_WORD_QUOTE;
   165 	}
   166 	\\.?	{
   167 		append_string(yytext + 1, yyleng - 1);
   168 	}
   169 	\'|\"	{
   170 		if (str == yytext[0]) {
   171 			BEGIN(PARAM);
   172 			zconflval.string = text;
   173 			return T_WORD_QUOTE;
   174 		} else
   175 			append_string(yytext, 1);
   176 	}
   177 	\n	{
   178 		printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
   179 		current_file->lineno++;
   180 		BEGIN(INITIAL);
   181 		return T_EOL;
   182 	}
   183 	<<EOF>>	{
   184 		BEGIN(INITIAL);
   185 	}
   186 }
   187 
   188 <HELP>{
   189 	[ \t]+	{
   190 		ts = 0;
   191 		for (i = 0; i < yyleng; i++) {
   192 			if (yytext[i] == '\t')
   193 				ts = (ts & ~7) + 8;
   194 			else
   195 				ts++;
   196 		}
   197 		last_ts = ts;
   198 		if (first_ts) {
   199 			if (ts < first_ts) {
   200 				zconf_endhelp();
   201 				return T_HELPTEXT;
   202 			}
   203 			ts -= first_ts;
   204 			while (ts > 8) {
   205 				append_string("        ", 8);
   206 				ts -= 8;
   207 			}
   208 			append_string("        ", ts);
   209 		}
   210 	}
   211 	[ \t]*\n/[^ \t\n] {
   212 		current_file->lineno++;
   213 		zconf_endhelp();
   214 		return T_HELPTEXT;
   215 	}
   216 	[ \t]*\n	{
   217 		current_file->lineno++;
   218 		append_string("\n", 1);
   219 	}
   220 	[^ \t\n].* {
   221 		while (yyleng) {
   222 			if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
   223 				break;
   224 			yyleng--;
   225 		}
   226 		append_string(yytext, yyleng);
   227 		if (!first_ts)
   228 			first_ts = last_ts;
   229 	}
   230 	<<EOF>>	{
   231 		zconf_endhelp();
   232 		return T_HELPTEXT;
   233 	}
   234 }
   235 
   236 <<EOF>>	{
   237 	if (current_file) {
   238 		zconf_endfile();
   239 		return T_EOL;
   240 	}
   241 	fclose(yyin);
   242 	yyterminate();
   243 }
   244 
   245 %%
   246 void zconf_starthelp(void)
   247 {
   248 	new_string();
   249 	last_ts = first_ts = 0;
   250 	BEGIN(HELP);
   251 }
   252 
   253 static void zconf_endhelp(void)
   254 {
   255 	zconflval.string = text;
   256 	BEGIN(INITIAL);
   257 }
   258 
   259 
   260 /*
   261  * Try to open specified file with following names:
   262  * ./name
   263  * $(srctree)/name
   264  * The latter is used when srctree is separate from objtree
   265  * when compiling the kernel.
   266  * Return NULL if file is not found.
   267  */
   268 FILE *zconf_fopen(const char *name)
   269 {
   270 	char *env, fullname[PATH_MAX+1];
   271 	FILE *f;
   272 
   273 	f = fopen(name, "r");
   274 	if (!f && name != NULL && name[0] != '/') {
   275 		env = getenv(SRCTREE);
   276 		if (env) {
   277 			sprintf(fullname, "%s/%s", env, name);
   278 			f = fopen(fullname, "r");
   279 		}
   280 	}
   281 	return f;
   282 }
   283 
   284 void zconf_initscan(const char *name)
   285 {
   286 	yyin = zconf_fopen(name);
   287 	if (!yyin) {
   288 		printf("can't find file %s\n", name);
   289 		exit(1);
   290 	}
   291 
   292 	current_buf = malloc(sizeof(*current_buf));
   293 	memset(current_buf, 0, sizeof(*current_buf));
   294 
   295 	current_file = file_lookup(name);
   296 	current_file->lineno = 1;
   297 }
   298 
   299 void zconf_nextfile(const char *name)
   300 {
   301 	struct file *iter;
   302 	struct file *file = file_lookup(name);
   303 	struct buffer *buf = malloc(sizeof(*buf));
   304 	memset(buf, 0, sizeof(*buf));
   305 
   306 	current_buf->state = YY_CURRENT_BUFFER;
   307 	yyin = zconf_fopen(file->name);
   308 	if (!yyin) {
   309 		printf("%s:%d: can't open file \"%s\"\n",
   310 		    zconf_curname(), zconf_lineno(), file->name);
   311 		exit(1);
   312 	}
   313 	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
   314 	buf->parent = current_buf;
   315 	current_buf = buf;
   316 
   317 	for (iter = current_file->parent; iter; iter = iter->parent ) {
   318 		if (!strcmp(current_file->name,iter->name) ) {
   319 			printf("%s:%d: recursive inclusion detected. "
   320 			       "Inclusion path:\n  current file : '%s'\n",
   321 			       zconf_curname(), zconf_lineno(),
   322 			       zconf_curname());
   323 			iter = current_file->parent;
   324 			while (iter && \
   325 			       strcmp(iter->name,current_file->name)) {
   326 				printf("  included from: '%s:%d'\n",
   327 				       iter->name, iter->lineno-1);
   328 				iter = iter->parent;
   329 			}
   330 			if (iter)
   331 				printf("  included from: '%s:%d'\n",
   332 				       iter->name, iter->lineno+1);
   333 			exit(1);
   334 		}
   335 	}
   336 	file->lineno = 1;
   337 	file->parent = current_file;
   338 	current_file = file;
   339 }
   340 
   341 static void zconf_endfile(void)
   342 {
   343 	struct buffer *parent;
   344 
   345 	current_file = current_file->parent;
   346 
   347 	parent = current_buf->parent;
   348 	if (parent) {
   349 		fclose(yyin);
   350 		yy_delete_buffer(YY_CURRENT_BUFFER);
   351 		yy_switch_to_buffer(parent->state);
   352 	}
   353 	free(current_buf);
   354 	current_buf = parent;
   355 }
   356 
   357 int zconf_lineno(void)
   358 {
   359 	return current_pos.lineno;
   360 }
   361 
   362 const char *zconf_curname(void)
   363 {
   364 	return current_pos.file ? current_pos.file->name : "<none>";
   365 }