cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

lexer.l (9214B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
      4 */
      5%option nostdinit noyywrap never-interactive full ecs
      6%option 8bit nodefault yylineno
      7%x ASSIGN_VAL HELP STRING
      8%{
      9
     10#include <assert.h>
     11#include <limits.h>
     12#include <stdio.h>
     13#include <stdlib.h>
     14#include <string.h>
     15
     16#include "lkc.h"
     17#include "parser.tab.h"
     18
     19#define YY_DECL		static int yylex1(void)
     20
     21#define START_STRSIZE	16
     22
     23static struct {
     24	struct file *file;
     25	int lineno;
     26} current_pos;
     27
     28static int prev_prev_token = T_EOL;
     29static int prev_token = T_EOL;
     30static char *text;
     31static int text_size, text_asize;
     32
     33struct buffer {
     34	struct buffer *parent;
     35	YY_BUFFER_STATE state;
     36};
     37
     38static struct buffer *current_buf;
     39
     40static int last_ts, first_ts;
     41
     42static char *expand_token(const char *in, size_t n);
     43static void append_expanded_string(const char *in);
     44static void zconf_endhelp(void);
     45static void zconf_endfile(void);
     46
     47static void new_string(void)
     48{
     49	text = xmalloc(START_STRSIZE);
     50	text_asize = START_STRSIZE;
     51	text_size = 0;
     52	*text = 0;
     53}
     54
     55static void append_string(const char *str, int size)
     56{
     57	int new_size = text_size + size + 1;
     58	if (new_size > text_asize) {
     59		new_size += START_STRSIZE - 1;
     60		new_size &= -START_STRSIZE;
     61		text = xrealloc(text, new_size);
     62		text_asize = new_size;
     63	}
     64	memcpy(text + text_size, str, size);
     65	text_size += size;
     66	text[text_size] = 0;
     67}
     68
     69static void alloc_string(const char *str, int size)
     70{
     71	text = xmalloc(size + 1);
     72	memcpy(text, str, size);
     73	text[size] = 0;
     74}
     75
     76static void warn_ignored_character(char chr)
     77{
     78	fprintf(stderr,
     79	        "%s:%d:warning: ignoring unsupported character '%c'\n",
     80	        current_file->name, yylineno, chr);
     81}
     82%}
     83
     84n	[A-Za-z0-9_-]
     85
     86%%
     87	char open_quote = 0;
     88
     89#.*			/* ignore comment */
     90[ \t]*			/* whitespaces */
     91\\\n			/* escaped new line */
     92\n			return T_EOL;
     93"bool"			return T_BOOL;
     94"choice"		return T_CHOICE;
     95"comment"		return T_COMMENT;
     96"config"		return T_CONFIG;
     97"def_bool"		return T_DEF_BOOL;
     98"def_tristate"		return T_DEF_TRISTATE;
     99"default"		return T_DEFAULT;
    100"depends"		return T_DEPENDS;
    101"endchoice"		return T_ENDCHOICE;
    102"endif"			return T_ENDIF;
    103"endmenu"		return T_ENDMENU;
    104"help"			return T_HELP;
    105"hex"			return T_HEX;
    106"if"			return T_IF;
    107"imply"			return T_IMPLY;
    108"int"			return T_INT;
    109"mainmenu"		return T_MAINMENU;
    110"menu"			return T_MENU;
    111"menuconfig"		return T_MENUCONFIG;
    112"modules"		return T_MODULES;
    113"on"			return T_ON;
    114"optional"		return T_OPTIONAL;
    115"prompt"		return T_PROMPT;
    116"range"			return T_RANGE;
    117"select"		return T_SELECT;
    118"source"		return T_SOURCE;
    119"string"		return T_STRING;
    120"tristate"		return T_TRISTATE;
    121"visible"		return T_VISIBLE;
    122"||"			return T_OR;
    123"&&"			return T_AND;
    124"="			return T_EQUAL;
    125"!="			return T_UNEQUAL;
    126"<"			return T_LESS;
    127"<="			return T_LESS_EQUAL;
    128">"			return T_GREATER;
    129">="			return T_GREATER_EQUAL;
    130"!"			return T_NOT;
    131"("			return T_OPEN_PAREN;
    132")"			return T_CLOSE_PAREN;
    133":="			return T_COLON_EQUAL;
    134"+="			return T_PLUS_EQUAL;
    135\"|\'			{
    136				open_quote = yytext[0];
    137				new_string();
    138				BEGIN(STRING);
    139			}
    140{n}+			{
    141				alloc_string(yytext, yyleng);
    142				yylval.string = text;
    143				return T_WORD;
    144			}
    145({n}|$)+		{
    146				/* this token includes at least one '$' */
    147				yylval.string = expand_token(yytext, yyleng);
    148				if (strlen(yylval.string))
    149					return T_WORD;
    150				free(yylval.string);
    151			}
    152.			warn_ignored_character(*yytext);
    153
    154<ASSIGN_VAL>{
    155	[^[:blank:]\n]+.*	{
    156		alloc_string(yytext, yyleng);
    157		yylval.string = text;
    158		return T_ASSIGN_VAL;
    159	}
    160	\n	{ BEGIN(INITIAL); return T_EOL; }
    161	.
    162}
    163
    164<STRING>{
    165	"$".*	append_expanded_string(yytext);
    166	[^$'"\\\n]+	{
    167		append_string(yytext, yyleng);
    168	}
    169	\\.?	{
    170		append_string(yytext + 1, yyleng - 1);
    171	}
    172	\'|\"	{
    173		if (open_quote == yytext[0]) {
    174			BEGIN(INITIAL);
    175			yylval.string = text;
    176			return T_WORD_QUOTE;
    177		} else
    178			append_string(yytext, 1);
    179	}
    180	\n	{
    181		fprintf(stderr,
    182			"%s:%d:warning: multi-line strings not supported\n",
    183			zconf_curname(), zconf_lineno());
    184		unput('\n');
    185		BEGIN(INITIAL);
    186		yylval.string = text;
    187		return T_WORD_QUOTE;
    188	}
    189	<<EOF>>	{
    190		BEGIN(INITIAL);
    191		yylval.string = text;
    192		return T_WORD_QUOTE;
    193	}
    194}
    195
    196<HELP>{
    197	[ \t]+	{
    198		int ts, i;
    199
    200		ts = 0;
    201		for (i = 0; i < yyleng; i++) {
    202			if (yytext[i] == '\t')
    203				ts = (ts & ~7) + 8;
    204			else
    205				ts++;
    206		}
    207		last_ts = ts;
    208		if (first_ts) {
    209			if (ts < first_ts) {
    210				zconf_endhelp();
    211				return T_HELPTEXT;
    212			}
    213			ts -= first_ts;
    214			while (ts > 8) {
    215				append_string("        ", 8);
    216				ts -= 8;
    217			}
    218			append_string("        ", ts);
    219		}
    220	}
    221	[ \t]*\n/[^ \t\n] {
    222		zconf_endhelp();
    223		return T_HELPTEXT;
    224	}
    225	[ \t]*\n	{
    226		append_string("\n", 1);
    227	}
    228	[^ \t\n].* {
    229		while (yyleng) {
    230			if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
    231				break;
    232			yyleng--;
    233		}
    234		append_string(yytext, yyleng);
    235		if (!first_ts)
    236			first_ts = last_ts;
    237	}
    238	<<EOF>>	{
    239		zconf_endhelp();
    240		return T_HELPTEXT;
    241	}
    242}
    243
    244<<EOF>>	{
    245	BEGIN(INITIAL);
    246
    247	if (prev_token != T_EOL && prev_token != T_HELPTEXT)
    248		fprintf(stderr, "%s:%d:warning: no new line at end of file\n",
    249			current_file->name, yylineno);
    250
    251	if (current_file) {
    252		zconf_endfile();
    253		return T_EOL;
    254	}
    255	fclose(yyin);
    256	yyterminate();
    257}
    258
    259%%
    260
    261/* second stage lexer */
    262int yylex(void)
    263{
    264	int token;
    265
    266repeat:
    267	token = yylex1();
    268
    269	if (prev_token == T_EOL || prev_token == T_HELPTEXT) {
    270		if (token == T_EOL) {
    271			/* Do not pass unneeded T_EOL to the parser. */
    272			goto repeat;
    273		} else {
    274			/*
    275			 * For the parser, update file/lineno at the first token
    276			 * of each statement. Generally, \n is a statement
    277			 * terminator in Kconfig, but it is not always true
    278			 * because \n could be escaped by a backslash.
    279			 */
    280			current_pos.file = current_file;
    281			current_pos.lineno = yylineno;
    282		}
    283	}
    284
    285	if (prev_prev_token == T_EOL && prev_token == T_WORD &&
    286	    (token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL))
    287		BEGIN(ASSIGN_VAL);
    288
    289	prev_prev_token = prev_token;
    290	prev_token = token;
    291
    292	return token;
    293}
    294
    295static char *expand_token(const char *in, size_t n)
    296{
    297	char *out;
    298	int c;
    299	char c2;
    300	const char *rest, *end;
    301
    302	new_string();
    303	append_string(in, n);
    304
    305	/* get the whole line because we do not know the end of token. */
    306	while ((c = input()) != EOF) {
    307		if (c == '\n') {
    308			unput(c);
    309			break;
    310		}
    311		c2 = c;
    312		append_string(&c2, 1);
    313	}
    314
    315	rest = text;
    316	out = expand_one_token(&rest);
    317
    318	/* push back unused characters to the input stream */
    319	end = rest + strlen(rest);
    320	while (end > rest)
    321		unput(*--end);
    322
    323	free(text);
    324
    325	return out;
    326}
    327
    328static void append_expanded_string(const char *str)
    329{
    330	const char *end;
    331	char *res;
    332
    333	str++;
    334
    335	res = expand_dollar(&str);
    336
    337	/* push back unused characters to the input stream */
    338	end = str + strlen(str);
    339	while (end > str)
    340		unput(*--end);
    341
    342	append_string(res, strlen(res));
    343
    344	free(res);
    345}
    346
    347void zconf_starthelp(void)
    348{
    349	new_string();
    350	last_ts = first_ts = 0;
    351	BEGIN(HELP);
    352}
    353
    354static void zconf_endhelp(void)
    355{
    356	yylval.string = text;
    357	BEGIN(INITIAL);
    358}
    359
    360
    361/*
    362 * Try to open specified file with following names:
    363 * ./name
    364 * $(srctree)/name
    365 * The latter is used when srctree is separate from objtree
    366 * when compiling the kernel.
    367 * Return NULL if file is not found.
    368 */
    369FILE *zconf_fopen(const char *name)
    370{
    371	char *env, fullname[PATH_MAX+1];
    372	FILE *f;
    373
    374	f = fopen(name, "r");
    375	if (!f && name != NULL && name[0] != '/') {
    376		env = getenv(SRCTREE);
    377		if (env) {
    378			snprintf(fullname, sizeof(fullname),
    379				 "%s/%s", env, name);
    380			f = fopen(fullname, "r");
    381		}
    382	}
    383	return f;
    384}
    385
    386void zconf_initscan(const char *name)
    387{
    388	yyin = zconf_fopen(name);
    389	if (!yyin) {
    390		fprintf(stderr, "can't find file %s\n", name);
    391		exit(1);
    392	}
    393
    394	current_buf = xmalloc(sizeof(*current_buf));
    395	memset(current_buf, 0, sizeof(*current_buf));
    396
    397	current_file = file_lookup(name);
    398	yylineno = 1;
    399}
    400
    401void zconf_nextfile(const char *name)
    402{
    403	struct file *iter;
    404	struct file *file = file_lookup(name);
    405	struct buffer *buf = xmalloc(sizeof(*buf));
    406	memset(buf, 0, sizeof(*buf));
    407
    408	current_buf->state = YY_CURRENT_BUFFER;
    409	yyin = zconf_fopen(file->name);
    410	if (!yyin) {
    411		fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
    412			zconf_curname(), zconf_lineno(), file->name);
    413		exit(1);
    414	}
    415	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
    416	buf->parent = current_buf;
    417	current_buf = buf;
    418
    419	current_file->lineno = yylineno;
    420	file->parent = current_file;
    421
    422	for (iter = current_file; iter; iter = iter->parent) {
    423		if (!strcmp(iter->name, file->name)) {
    424			fprintf(stderr,
    425				"Recursive inclusion detected.\n"
    426				"Inclusion path:\n"
    427				"  current file : %s\n", file->name);
    428			iter = file;
    429			do {
    430				iter = iter->parent;
    431				fprintf(stderr, "  included from: %s:%d\n",
    432					iter->name, iter->lineno - 1);
    433			} while (strcmp(iter->name, file->name));
    434			exit(1);
    435		}
    436	}
    437
    438	yylineno = 1;
    439	current_file = file;
    440}
    441
    442static void zconf_endfile(void)
    443{
    444	struct buffer *parent;
    445
    446	current_file = current_file->parent;
    447	if (current_file)
    448		yylineno = current_file->lineno;
    449
    450	parent = current_buf->parent;
    451	if (parent) {
    452		fclose(yyin);
    453		yy_delete_buffer(YY_CURRENT_BUFFER);
    454		yy_switch_to_buffer(parent->state);
    455	}
    456	free(current_buf);
    457	current_buf = parent;
    458}
    459
    460int zconf_lineno(void)
    461{
    462	return current_pos.lineno;
    463}
    464
    465const char *zconf_curname(void)
    466{
    467	return current_pos.file ? current_pos.file->name : "<none>";
    468}