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