18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci%option nostdinit noyywrap never-interactive full ecs 68c2ecf20Sopenharmony_ci%option 8bit nodefault yylineno 78c2ecf20Sopenharmony_ci%x ASSIGN_VAL HELP STRING 88c2ecf20Sopenharmony_ci%{ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <assert.h> 118c2ecf20Sopenharmony_ci#include <limits.h> 128c2ecf20Sopenharmony_ci#include <stdio.h> 138c2ecf20Sopenharmony_ci#include <stdlib.h> 148c2ecf20Sopenharmony_ci#include <string.h> 158c2ecf20Sopenharmony_ci#include <unistd.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include "lkc.h" 188c2ecf20Sopenharmony_ci#include "parser.tab.h" 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define YY_DECL static int yylex1(void) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define START_STRSIZE 16 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistatic const char *kconfig_white_list[] = { 258c2ecf20Sopenharmony_ci "vendor/Kconfig", 268c2ecf20Sopenharmony_ci "net/newip/Kconfig", 278c2ecf20Sopenharmony_ci "drivers/tzdriver/Kconfig", 288c2ecf20Sopenharmony_ci "security/xpm/Kconfig", 298c2ecf20Sopenharmony_ci "drivers/auth_ctl/Kconfig", 308c2ecf20Sopenharmony_ci "drivers/staging/ucollection/Kconfig", 318c2ecf20Sopenharmony_ci "fs/proc/memory_security/Kconfig", 328c2ecf20Sopenharmony_ci "fs/code_sign/Kconfig", 338c2ecf20Sopenharmony_ci "fs/dec/Kconfig", 348c2ecf20Sopenharmony_ci "security/container_escape_detection/Kconfig", 358c2ecf20Sopenharmony_ci}; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cistatic struct { 388c2ecf20Sopenharmony_ci struct file *file; 398c2ecf20Sopenharmony_ci int lineno; 408c2ecf20Sopenharmony_ci} current_pos; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic int prev_prev_token = T_EOL; 438c2ecf20Sopenharmony_cistatic int prev_token = T_EOL; 448c2ecf20Sopenharmony_cistatic char *text; 458c2ecf20Sopenharmony_cistatic int text_size, text_asize; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistruct buffer { 488c2ecf20Sopenharmony_ci struct buffer *parent; 498c2ecf20Sopenharmony_ci YY_BUFFER_STATE state; 508c2ecf20Sopenharmony_ci}; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cistatic struct buffer *current_buf; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistatic int last_ts, first_ts; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic char *expand_token(const char *in, size_t n); 578c2ecf20Sopenharmony_cistatic void append_expanded_string(const char *in); 588c2ecf20Sopenharmony_cistatic void zconf_endhelp(void); 598c2ecf20Sopenharmony_cistatic void zconf_endfile(void); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic void new_string(void) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci text = xmalloc(START_STRSIZE); 648c2ecf20Sopenharmony_ci text_asize = START_STRSIZE; 658c2ecf20Sopenharmony_ci text_size = 0; 668c2ecf20Sopenharmony_ci *text = 0; 678c2ecf20Sopenharmony_ci} 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistatic void append_string(const char *str, int size) 708c2ecf20Sopenharmony_ci{ 718c2ecf20Sopenharmony_ci int new_size = text_size + size + 1; 728c2ecf20Sopenharmony_ci if (new_size > text_asize) { 738c2ecf20Sopenharmony_ci new_size += START_STRSIZE - 1; 748c2ecf20Sopenharmony_ci new_size &= -START_STRSIZE; 758c2ecf20Sopenharmony_ci text = xrealloc(text, new_size); 768c2ecf20Sopenharmony_ci text_asize = new_size; 778c2ecf20Sopenharmony_ci } 788c2ecf20Sopenharmony_ci memcpy(text + text_size, str, size); 798c2ecf20Sopenharmony_ci text_size += size; 808c2ecf20Sopenharmony_ci text[text_size] = 0; 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic void alloc_string(const char *str, int size) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci text = xmalloc(size + 1); 868c2ecf20Sopenharmony_ci memcpy(text, str, size); 878c2ecf20Sopenharmony_ci text[size] = 0; 888c2ecf20Sopenharmony_ci} 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cistatic void warn_ignored_character(char chr) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci fprintf(stderr, 938c2ecf20Sopenharmony_ci "%s:%d:warning: ignoring unsupported character '%c'\n", 948c2ecf20Sopenharmony_ci current_file->name, yylineno, chr); 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ci%} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cin [A-Za-z0-9_-] 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci%% 1018c2ecf20Sopenharmony_ci int str = 0; 1028c2ecf20Sopenharmony_ci int ts, i; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci#.* /* ignore comment */ 1058c2ecf20Sopenharmony_ci[ \t]* /* whitespaces */ 1068c2ecf20Sopenharmony_ci\\\n /* escaped new line */ 1078c2ecf20Sopenharmony_ci\n return T_EOL; 1088c2ecf20Sopenharmony_ci"allnoconfig_y" return T_ALLNOCONFIG_Y; 1098c2ecf20Sopenharmony_ci"bool" return T_BOOL; 1108c2ecf20Sopenharmony_ci"choice" return T_CHOICE; 1118c2ecf20Sopenharmony_ci"comment" return T_COMMENT; 1128c2ecf20Sopenharmony_ci"config" return T_CONFIG; 1138c2ecf20Sopenharmony_ci"def_bool" return T_DEF_BOOL; 1148c2ecf20Sopenharmony_ci"def_tristate" return T_DEF_TRISTATE; 1158c2ecf20Sopenharmony_ci"default" return T_DEFAULT; 1168c2ecf20Sopenharmony_ci"defconfig_list" return T_DEFCONFIG_LIST; 1178c2ecf20Sopenharmony_ci"depends" return T_DEPENDS; 1188c2ecf20Sopenharmony_ci"endchoice" return T_ENDCHOICE; 1198c2ecf20Sopenharmony_ci"endif" return T_ENDIF; 1208c2ecf20Sopenharmony_ci"endmenu" return T_ENDMENU; 1218c2ecf20Sopenharmony_ci"help" return T_HELP; 1228c2ecf20Sopenharmony_ci"hex" return T_HEX; 1238c2ecf20Sopenharmony_ci"if" return T_IF; 1248c2ecf20Sopenharmony_ci"imply" return T_IMPLY; 1258c2ecf20Sopenharmony_ci"int" return T_INT; 1268c2ecf20Sopenharmony_ci"mainmenu" return T_MAINMENU; 1278c2ecf20Sopenharmony_ci"menu" return T_MENU; 1288c2ecf20Sopenharmony_ci"menuconfig" return T_MENUCONFIG; 1298c2ecf20Sopenharmony_ci"modules" return T_MODULES; 1308c2ecf20Sopenharmony_ci"on" return T_ON; 1318c2ecf20Sopenharmony_ci"option" return T_OPTION; 1328c2ecf20Sopenharmony_ci"optional" return T_OPTIONAL; 1338c2ecf20Sopenharmony_ci"prompt" return T_PROMPT; 1348c2ecf20Sopenharmony_ci"range" return T_RANGE; 1358c2ecf20Sopenharmony_ci"select" return T_SELECT; 1368c2ecf20Sopenharmony_ci"source" return T_SOURCE; 1378c2ecf20Sopenharmony_ci"string" return T_STRING; 1388c2ecf20Sopenharmony_ci"tristate" return T_TRISTATE; 1398c2ecf20Sopenharmony_ci"visible" return T_VISIBLE; 1408c2ecf20Sopenharmony_ci"||" return T_OR; 1418c2ecf20Sopenharmony_ci"&&" return T_AND; 1428c2ecf20Sopenharmony_ci"=" return T_EQUAL; 1438c2ecf20Sopenharmony_ci"!=" return T_UNEQUAL; 1448c2ecf20Sopenharmony_ci"<" return T_LESS; 1458c2ecf20Sopenharmony_ci"<=" return T_LESS_EQUAL; 1468c2ecf20Sopenharmony_ci">" return T_GREATER; 1478c2ecf20Sopenharmony_ci">=" return T_GREATER_EQUAL; 1488c2ecf20Sopenharmony_ci"!" return T_NOT; 1498c2ecf20Sopenharmony_ci"(" return T_OPEN_PAREN; 1508c2ecf20Sopenharmony_ci")" return T_CLOSE_PAREN; 1518c2ecf20Sopenharmony_ci":=" return T_COLON_EQUAL; 1528c2ecf20Sopenharmony_ci"+=" return T_PLUS_EQUAL; 1538c2ecf20Sopenharmony_ci\"|\' { 1548c2ecf20Sopenharmony_ci str = yytext[0]; 1558c2ecf20Sopenharmony_ci new_string(); 1568c2ecf20Sopenharmony_ci BEGIN(STRING); 1578c2ecf20Sopenharmony_ci } 1588c2ecf20Sopenharmony_ci{n}+ { 1598c2ecf20Sopenharmony_ci alloc_string(yytext, yyleng); 1608c2ecf20Sopenharmony_ci yylval.string = text; 1618c2ecf20Sopenharmony_ci return T_WORD; 1628c2ecf20Sopenharmony_ci } 1638c2ecf20Sopenharmony_ci({n}|$)+ { 1648c2ecf20Sopenharmony_ci /* this token includes at least one '$' */ 1658c2ecf20Sopenharmony_ci yylval.string = expand_token(yytext, yyleng); 1668c2ecf20Sopenharmony_ci if (strlen(yylval.string)) 1678c2ecf20Sopenharmony_ci return T_WORD; 1688c2ecf20Sopenharmony_ci free(yylval.string); 1698c2ecf20Sopenharmony_ci } 1708c2ecf20Sopenharmony_ci. warn_ignored_character(*yytext); 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci<ASSIGN_VAL>{ 1738c2ecf20Sopenharmony_ci [^[:blank:]\n]+.* { 1748c2ecf20Sopenharmony_ci alloc_string(yytext, yyleng); 1758c2ecf20Sopenharmony_ci yylval.string = text; 1768c2ecf20Sopenharmony_ci return T_ASSIGN_VAL; 1778c2ecf20Sopenharmony_ci } 1788c2ecf20Sopenharmony_ci \n { BEGIN(INITIAL); return T_EOL; } 1798c2ecf20Sopenharmony_ci . 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci<STRING>{ 1838c2ecf20Sopenharmony_ci "$".* append_expanded_string(yytext); 1848c2ecf20Sopenharmony_ci [^$'"\\\n]+ { 1858c2ecf20Sopenharmony_ci append_string(yytext, yyleng); 1868c2ecf20Sopenharmony_ci } 1878c2ecf20Sopenharmony_ci \\.? { 1888c2ecf20Sopenharmony_ci append_string(yytext + 1, yyleng - 1); 1898c2ecf20Sopenharmony_ci } 1908c2ecf20Sopenharmony_ci \'|\" { 1918c2ecf20Sopenharmony_ci if (str == yytext[0]) { 1928c2ecf20Sopenharmony_ci BEGIN(INITIAL); 1938c2ecf20Sopenharmony_ci yylval.string = text; 1948c2ecf20Sopenharmony_ci return T_WORD_QUOTE; 1958c2ecf20Sopenharmony_ci } else 1968c2ecf20Sopenharmony_ci append_string(yytext, 1); 1978c2ecf20Sopenharmony_ci } 1988c2ecf20Sopenharmony_ci \n { 1998c2ecf20Sopenharmony_ci fprintf(stderr, 2008c2ecf20Sopenharmony_ci "%s:%d:warning: multi-line strings not supported\n", 2018c2ecf20Sopenharmony_ci zconf_curname(), zconf_lineno()); 2028c2ecf20Sopenharmony_ci unput('\n'); 2038c2ecf20Sopenharmony_ci BEGIN(INITIAL); 2048c2ecf20Sopenharmony_ci yylval.string = text; 2058c2ecf20Sopenharmony_ci return T_WORD_QUOTE; 2068c2ecf20Sopenharmony_ci } 2078c2ecf20Sopenharmony_ci <<EOF>> { 2088c2ecf20Sopenharmony_ci BEGIN(INITIAL); 2098c2ecf20Sopenharmony_ci yylval.string = text; 2108c2ecf20Sopenharmony_ci return T_WORD_QUOTE; 2118c2ecf20Sopenharmony_ci } 2128c2ecf20Sopenharmony_ci} 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci<HELP>{ 2158c2ecf20Sopenharmony_ci [ \t]+ { 2168c2ecf20Sopenharmony_ci ts = 0; 2178c2ecf20Sopenharmony_ci for (i = 0; i < yyleng; i++) { 2188c2ecf20Sopenharmony_ci if (yytext[i] == '\t') 2198c2ecf20Sopenharmony_ci ts = (ts & ~7) + 8; 2208c2ecf20Sopenharmony_ci else 2218c2ecf20Sopenharmony_ci ts++; 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci last_ts = ts; 2248c2ecf20Sopenharmony_ci if (first_ts) { 2258c2ecf20Sopenharmony_ci if (ts < first_ts) { 2268c2ecf20Sopenharmony_ci zconf_endhelp(); 2278c2ecf20Sopenharmony_ci return T_HELPTEXT; 2288c2ecf20Sopenharmony_ci } 2298c2ecf20Sopenharmony_ci ts -= first_ts; 2308c2ecf20Sopenharmony_ci while (ts > 8) { 2318c2ecf20Sopenharmony_ci append_string(" ", 8); 2328c2ecf20Sopenharmony_ci ts -= 8; 2338c2ecf20Sopenharmony_ci } 2348c2ecf20Sopenharmony_ci append_string(" ", ts); 2358c2ecf20Sopenharmony_ci } 2368c2ecf20Sopenharmony_ci } 2378c2ecf20Sopenharmony_ci [ \t]*\n/[^ \t\n] { 2388c2ecf20Sopenharmony_ci zconf_endhelp(); 2398c2ecf20Sopenharmony_ci return T_HELPTEXT; 2408c2ecf20Sopenharmony_ci } 2418c2ecf20Sopenharmony_ci [ \t]*\n { 2428c2ecf20Sopenharmony_ci append_string("\n", 1); 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci [^ \t\n].* { 2458c2ecf20Sopenharmony_ci while (yyleng) { 2468c2ecf20Sopenharmony_ci if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t')) 2478c2ecf20Sopenharmony_ci break; 2488c2ecf20Sopenharmony_ci yyleng--; 2498c2ecf20Sopenharmony_ci } 2508c2ecf20Sopenharmony_ci append_string(yytext, yyleng); 2518c2ecf20Sopenharmony_ci if (!first_ts) 2528c2ecf20Sopenharmony_ci first_ts = last_ts; 2538c2ecf20Sopenharmony_ci } 2548c2ecf20Sopenharmony_ci <<EOF>> { 2558c2ecf20Sopenharmony_ci zconf_endhelp(); 2568c2ecf20Sopenharmony_ci return T_HELPTEXT; 2578c2ecf20Sopenharmony_ci } 2588c2ecf20Sopenharmony_ci} 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci<<EOF>> { 2618c2ecf20Sopenharmony_ci BEGIN(INITIAL); 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci if (prev_token != T_EOL && prev_token != T_HELPTEXT) 2648c2ecf20Sopenharmony_ci fprintf(stderr, "%s:%d:warning: no new line at end of file\n", 2658c2ecf20Sopenharmony_ci current_file->name, yylineno); 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci if (current_file) { 2688c2ecf20Sopenharmony_ci zconf_endfile(); 2698c2ecf20Sopenharmony_ci return T_EOL; 2708c2ecf20Sopenharmony_ci } 2718c2ecf20Sopenharmony_ci fclose(yyin); 2728c2ecf20Sopenharmony_ci yyterminate(); 2738c2ecf20Sopenharmony_ci} 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci%% 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci/* second stage lexer */ 2788c2ecf20Sopenharmony_ciint yylex(void) 2798c2ecf20Sopenharmony_ci{ 2808c2ecf20Sopenharmony_ci int token; 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_cirepeat: 2838c2ecf20Sopenharmony_ci token = yylex1(); 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci if (prev_token == T_EOL || prev_token == T_HELPTEXT) { 2868c2ecf20Sopenharmony_ci if (token == T_EOL) { 2878c2ecf20Sopenharmony_ci /* Do not pass unneeded T_EOL to the parser. */ 2888c2ecf20Sopenharmony_ci goto repeat; 2898c2ecf20Sopenharmony_ci } else { 2908c2ecf20Sopenharmony_ci /* 2918c2ecf20Sopenharmony_ci * For the parser, update file/lineno at the first token 2928c2ecf20Sopenharmony_ci * of each statement. Generally, \n is a statement 2938c2ecf20Sopenharmony_ci * terminator in Kconfig, but it is not always true 2948c2ecf20Sopenharmony_ci * because \n could be escaped by a backslash. 2958c2ecf20Sopenharmony_ci */ 2968c2ecf20Sopenharmony_ci current_pos.file = current_file; 2978c2ecf20Sopenharmony_ci current_pos.lineno = yylineno; 2988c2ecf20Sopenharmony_ci } 2998c2ecf20Sopenharmony_ci } 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci if (prev_prev_token == T_EOL && prev_token == T_WORD && 3028c2ecf20Sopenharmony_ci (token == T_EQUAL || token == T_COLON_EQUAL || token == T_PLUS_EQUAL)) 3038c2ecf20Sopenharmony_ci BEGIN(ASSIGN_VAL); 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci prev_prev_token = prev_token; 3068c2ecf20Sopenharmony_ci prev_token = token; 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci return token; 3098c2ecf20Sopenharmony_ci} 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_cistatic char *expand_token(const char *in, size_t n) 3128c2ecf20Sopenharmony_ci{ 3138c2ecf20Sopenharmony_ci char *out; 3148c2ecf20Sopenharmony_ci int c; 3158c2ecf20Sopenharmony_ci char c2; 3168c2ecf20Sopenharmony_ci const char *rest, *end; 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci new_string(); 3198c2ecf20Sopenharmony_ci append_string(in, n); 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci /* get the whole line because we do not know the end of token. */ 3228c2ecf20Sopenharmony_ci while ((c = input()) != EOF) { 3238c2ecf20Sopenharmony_ci if (c == '\n') { 3248c2ecf20Sopenharmony_ci unput(c); 3258c2ecf20Sopenharmony_ci break; 3268c2ecf20Sopenharmony_ci } 3278c2ecf20Sopenharmony_ci c2 = c; 3288c2ecf20Sopenharmony_ci append_string(&c2, 1); 3298c2ecf20Sopenharmony_ci } 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci rest = text; 3328c2ecf20Sopenharmony_ci out = expand_one_token(&rest); 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci /* push back unused characters to the input stream */ 3358c2ecf20Sopenharmony_ci end = rest + strlen(rest); 3368c2ecf20Sopenharmony_ci while (end > rest) 3378c2ecf20Sopenharmony_ci unput(*--end); 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci free(text); 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci return out; 3428c2ecf20Sopenharmony_ci} 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_cistatic void append_expanded_string(const char *str) 3458c2ecf20Sopenharmony_ci{ 3468c2ecf20Sopenharmony_ci const char *end; 3478c2ecf20Sopenharmony_ci char *res; 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci str++; 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci res = expand_dollar(&str); 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci /* push back unused characters to the input stream */ 3548c2ecf20Sopenharmony_ci end = str + strlen(str); 3558c2ecf20Sopenharmony_ci while (end > str) 3568c2ecf20Sopenharmony_ci unput(*--end); 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci append_string(res, strlen(res)); 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci free(res); 3618c2ecf20Sopenharmony_ci} 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_civoid zconf_starthelp(void) 3648c2ecf20Sopenharmony_ci{ 3658c2ecf20Sopenharmony_ci new_string(); 3668c2ecf20Sopenharmony_ci last_ts = first_ts = 0; 3678c2ecf20Sopenharmony_ci BEGIN(HELP); 3688c2ecf20Sopenharmony_ci} 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_cistatic void zconf_endhelp(void) 3718c2ecf20Sopenharmony_ci{ 3728c2ecf20Sopenharmony_ci yylval.string = text; 3738c2ecf20Sopenharmony_ci BEGIN(INITIAL); 3748c2ecf20Sopenharmony_ci} 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci/* 3788c2ecf20Sopenharmony_ci * Try to open specified file with following names: 3798c2ecf20Sopenharmony_ci * ./name 3808c2ecf20Sopenharmony_ci * $(srctree)/name 3818c2ecf20Sopenharmony_ci * The latter is used when srctree is separate from objtree 3828c2ecf20Sopenharmony_ci * when compiling the kernel. 3838c2ecf20Sopenharmony_ci * Return NULL if file is not found. 3848c2ecf20Sopenharmony_ci */ 3858c2ecf20Sopenharmony_ciFILE *zconf_fopen(const char *name) 3868c2ecf20Sopenharmony_ci{ 3878c2ecf20Sopenharmony_ci char *env, fullname[PATH_MAX+1]; 3888c2ecf20Sopenharmony_ci FILE *f; 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci f = fopen(name, "r"); 3918c2ecf20Sopenharmony_ci if (!f && name != NULL && name[0] != '/') { 3928c2ecf20Sopenharmony_ci env = getenv(SRCTREE); 3938c2ecf20Sopenharmony_ci if (env) { 3948c2ecf20Sopenharmony_ci snprintf(fullname, sizeof(fullname), 3958c2ecf20Sopenharmony_ci "%s/%s", env, name); 3968c2ecf20Sopenharmony_ci f = fopen(fullname, "r"); 3978c2ecf20Sopenharmony_ci } 3988c2ecf20Sopenharmony_ci } 3998c2ecf20Sopenharmony_ci return f; 4008c2ecf20Sopenharmony_ci} 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_civoid zconf_initscan(const char *name) 4038c2ecf20Sopenharmony_ci{ 4048c2ecf20Sopenharmony_ci yyin = zconf_fopen(name); 4058c2ecf20Sopenharmony_ci if (!yyin) { 4068c2ecf20Sopenharmony_ci fprintf(stderr, "can't find file %s\n", name); 4078c2ecf20Sopenharmony_ci exit(1); 4088c2ecf20Sopenharmony_ci } 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci current_buf = xmalloc(sizeof(*current_buf)); 4118c2ecf20Sopenharmony_ci memset(current_buf, 0, sizeof(*current_buf)); 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci current_file = file_lookup(name); 4148c2ecf20Sopenharmony_ci yylineno = 1; 4158c2ecf20Sopenharmony_ci} 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_cistatic bool zconf_in_whitelist(const char *path) 4188c2ecf20Sopenharmony_ci{ 4198c2ecf20Sopenharmony_ci int i; 4208c2ecf20Sopenharmony_ci for (i = 0; i < sizeof(kconfig_white_list) / sizeof(kconfig_white_list[0]); i++) { 4218c2ecf20Sopenharmony_ci if(strcmp(kconfig_white_list[i], path) == 0) 4228c2ecf20Sopenharmony_ci return true; 4238c2ecf20Sopenharmony_ci } 4248c2ecf20Sopenharmony_ci return false; 4258c2ecf20Sopenharmony_ci} 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_civoid zconf_nextfile(const char *name) 4288c2ecf20Sopenharmony_ci{ 4298c2ecf20Sopenharmony_ci struct file *iter; 4308c2ecf20Sopenharmony_ci struct file *file = file_lookup(name); 4318c2ecf20Sopenharmony_ci struct buffer *buf = NULL; 4328c2ecf20Sopenharmony_ci FILE *yyin_tmp = zconf_fopen(file->name); 4338c2ecf20Sopenharmony_ci if (!yyin_tmp) { 4348c2ecf20Sopenharmony_ci if (zconf_in_whitelist(name) == true) 4358c2ecf20Sopenharmony_ci return; 4368c2ecf20Sopenharmony_ci fprintf(stderr, "%s:%d: can't open file \"%s\"\n", 4378c2ecf20Sopenharmony_ci zconf_curname(), zconf_lineno(), file->name); 4388c2ecf20Sopenharmony_ci exit(1); 4398c2ecf20Sopenharmony_ci } 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci buf = xmalloc(sizeof(*buf)); 4428c2ecf20Sopenharmony_ci memset(buf, 0, sizeof(*buf)); 4438c2ecf20Sopenharmony_ci current_buf->state = YY_CURRENT_BUFFER; 4448c2ecf20Sopenharmony_ci yyin = yyin_tmp; 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); 4478c2ecf20Sopenharmony_ci buf->parent = current_buf; 4488c2ecf20Sopenharmony_ci current_buf = buf; 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci current_file->lineno = yylineno; 4518c2ecf20Sopenharmony_ci file->parent = current_file; 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci for (iter = current_file; iter; iter = iter->parent) { 4548c2ecf20Sopenharmony_ci if (!strcmp(iter->name, file->name)) { 4558c2ecf20Sopenharmony_ci fprintf(stderr, 4568c2ecf20Sopenharmony_ci "Recursive inclusion detected.\n" 4578c2ecf20Sopenharmony_ci "Inclusion path:\n" 4588c2ecf20Sopenharmony_ci " current file : %s\n", file->name); 4598c2ecf20Sopenharmony_ci iter = file; 4608c2ecf20Sopenharmony_ci do { 4618c2ecf20Sopenharmony_ci iter = iter->parent; 4628c2ecf20Sopenharmony_ci fprintf(stderr, " included from: %s:%d\n", 4638c2ecf20Sopenharmony_ci iter->name, iter->lineno - 1); 4648c2ecf20Sopenharmony_ci } while (strcmp(iter->name, file->name)); 4658c2ecf20Sopenharmony_ci exit(1); 4668c2ecf20Sopenharmony_ci } 4678c2ecf20Sopenharmony_ci } 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci yylineno = 1; 4708c2ecf20Sopenharmony_ci current_file = file; 4718c2ecf20Sopenharmony_ci} 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_cistatic void zconf_endfile(void) 4748c2ecf20Sopenharmony_ci{ 4758c2ecf20Sopenharmony_ci struct buffer *parent; 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_ci current_file = current_file->parent; 4788c2ecf20Sopenharmony_ci if (current_file) 4798c2ecf20Sopenharmony_ci yylineno = current_file->lineno; 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_ci parent = current_buf->parent; 4828c2ecf20Sopenharmony_ci if (parent) { 4838c2ecf20Sopenharmony_ci fclose(yyin); 4848c2ecf20Sopenharmony_ci yy_delete_buffer(YY_CURRENT_BUFFER); 4858c2ecf20Sopenharmony_ci yy_switch_to_buffer(parent->state); 4868c2ecf20Sopenharmony_ci } 4878c2ecf20Sopenharmony_ci free(current_buf); 4888c2ecf20Sopenharmony_ci current_buf = parent; 4898c2ecf20Sopenharmony_ci} 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ciint zconf_lineno(void) 4928c2ecf20Sopenharmony_ci{ 4938c2ecf20Sopenharmony_ci return current_pos.lineno; 4948c2ecf20Sopenharmony_ci} 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ciconst char *zconf_curname(void) 4978c2ecf20Sopenharmony_ci{ 4988c2ecf20Sopenharmony_ci return current_pos.file ? current_pos.file->name : "<none>"; 4998c2ecf20Sopenharmony_ci} 500