mirror of
https://github.com/crosstool-ng/crosstool-ng.git
synced 2025-02-20 17:12:55 +00:00
kconfig: Sync with upstream v4.17
This commit introduces the following upstream changes: 17baab68d337 kconfig: extend output of 'listnewconfig' b23d1a241f4e kbuild: add %.lex.c and %.tab.[ch] to 'targets' automatically 9a8dfb394c04 kbuild: clean up *.lex.c and *.tab.[ch] patterns from top-level Makefile 598893002745 .gitignore: move *.lex.c *.tab.[ch] patterns to the top-level .gitignore 18492685e479 kconfig: use yylineno option instead of manual lineno increments 379a8eb8eb1a kconfig: detect recursive inclusion earlier 32a94b8b0c3e kconfig: remove duplicated file name and lineno of recursive inclusion 26561514cc9d kconfig: do not include both curses.h and ncurses.h for nconfig f8f69dc0b4e0 kconfig: make unmet dependency warnings readable f622f8279581 kconfig: warn unmet direct dependency of tristate symbols selected by y e2c75e7667c7 kconfig: tests: test if recursive inclusion is detected 29c434f367ea kconfig: tests: test if recursive dependencies are detected 3e4888c2e3d7 kconfig: tests: test randconfig for choice in choice beaaddb62540 kconfig: tests: test defconfig when two choices interact ee236610653e kconfig: tests: check visibility of tristate choice values in y choice 930c429a656f kconfig: tests: check unneeded "is not set" with unmet dependency b76960c0f6b2 kconfig: tests: test if new symbols in choice are asked 49ac3c0c3aa3 kconfig: tests: test automatic submenu creation 1903c5119059 kconfig: tests: add basic choice tests 022a4bf6b59d kconfig: tests: add framework for Kconfig unit testing 2a61625835c7 kconfig: remove redundant streamline_config.pl prerequisite 911a91c39cab kconfig: rename silentoldconfig to syncconfig 81d2bc227305 kconfig: invoke oldconfig instead of silentoldconfig from local*config 2aad9b896213 kconfig: hide irrelevant sub-menus for oldconfig 99f0b6578bab kconfig: remove redundant input_mode test for check_conf() loop 4bb3a5b085cd kconfig: remove unneeded input_mode test in conf() 59a80b5e892d kconfig: do not call check_conf() for olddefconfig f467c5640c29 kconfig: only write '# CONFIG_FOO is not set' for visible symbols d9119b5925a0 kconfig: Print reverse dependencies in groups 9a47ceec543b kconfig: clean-up reverse dependency help implementation 07a422bb213a kbuild: restore autoksyms.h touch to the top Makefile Signed-off-by: Chris Packham <judge.packham@gmail.com>
This commit is contained in:
parent
07ae8dd48d
commit
689dc60f21
3
kconfig/.gitignore
vendored
3
kconfig/.gitignore
vendored
@ -1,9 +1,6 @@
|
||||
#
|
||||
# Generated files
|
||||
#
|
||||
*.lex.c
|
||||
*.tab.c
|
||||
*.tab.h
|
||||
.deps
|
||||
Makefile
|
||||
|
||||
|
@ -23,7 +23,7 @@ static void check_conf(struct menu *menu);
|
||||
|
||||
enum input_mode {
|
||||
oldaskconfig,
|
||||
silentoldconfig,
|
||||
syncconfig,
|
||||
oldconfig,
|
||||
allnoconfig,
|
||||
allyesconfig,
|
||||
@ -100,7 +100,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
|
||||
|
||||
switch (input_mode) {
|
||||
case oldconfig:
|
||||
case silentoldconfig:
|
||||
case syncconfig:
|
||||
if (sym_has_value(sym)) {
|
||||
printf("%s\n", def);
|
||||
return 0;
|
||||
@ -293,7 +293,7 @@ static int conf_choice(struct menu *menu)
|
||||
printf("[1-%d?]: ", cnt);
|
||||
switch (input_mode) {
|
||||
case oldconfig:
|
||||
case silentoldconfig:
|
||||
case syncconfig:
|
||||
if (!is_new) {
|
||||
cnt = def;
|
||||
printf("%d\n", cnt);
|
||||
@ -358,10 +358,11 @@ static void conf(struct menu *menu)
|
||||
|
||||
switch (prop->type) {
|
||||
case P_MENU:
|
||||
if ((input_mode == silentoldconfig ||
|
||||
input_mode == listnewconfig ||
|
||||
input_mode == olddefconfig) &&
|
||||
rootEntry != menu) {
|
||||
/*
|
||||
* Except in oldaskconfig mode, we show only menus that
|
||||
* contain new symbols.
|
||||
*/
|
||||
if (input_mode != oldaskconfig && rootEntry != menu) {
|
||||
check_conf(menu);
|
||||
return;
|
||||
}
|
||||
@ -421,10 +422,20 @@ static void check_conf(struct menu *menu)
|
||||
if (sym_is_changable(sym) ||
|
||||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
|
||||
if (input_mode == listnewconfig) {
|
||||
if (sym->name && !sym_is_choice_value(sym)) {
|
||||
printf("%s%s\n", CONFIG_, sym->name);
|
||||
if (sym->name) {
|
||||
const char *str;
|
||||
|
||||
if (sym->type == S_STRING) {
|
||||
str = sym_get_string_value(sym);
|
||||
str = sym_escape_string_value(str);
|
||||
printf("%s%s=%s\n", CONFIG_, sym->name, str);
|
||||
free((void *)str);
|
||||
} else {
|
||||
str = sym_get_string_value(sym);
|
||||
printf("%s%s=%s\n", CONFIG_, sym->name, str);
|
||||
}
|
||||
}
|
||||
} else if (input_mode != olddefconfig) {
|
||||
} else {
|
||||
if (!conf_cnt++)
|
||||
printf(_("*\n* Restart config...\n*\n"));
|
||||
rootEntry = menu_get_parent_menu(menu);
|
||||
@ -440,7 +451,7 @@ static void check_conf(struct menu *menu)
|
||||
static struct option long_opts[] = {
|
||||
{"oldaskconfig", no_argument, NULL, oldaskconfig},
|
||||
{"oldconfig", no_argument, NULL, oldconfig},
|
||||
{"silentoldconfig", no_argument, NULL, silentoldconfig},
|
||||
{"syncconfig", no_argument, NULL, syncconfig},
|
||||
{"defconfig", optional_argument, NULL, defconfig},
|
||||
{"savedefconfig", required_argument, NULL, savedefconfig},
|
||||
{"allnoconfig", no_argument, NULL, allnoconfig},
|
||||
@ -479,7 +490,7 @@ int main(int ac, char **av)
|
||||
}
|
||||
input_mode = (enum input_mode)opt;
|
||||
switch (opt) {
|
||||
case silentoldconfig:
|
||||
case syncconfig:
|
||||
sync_kconfig = 1;
|
||||
break;
|
||||
case defconfig:
|
||||
@ -561,7 +572,7 @@ int main(int ac, char **av)
|
||||
}
|
||||
break;
|
||||
case savedefconfig:
|
||||
case silentoldconfig:
|
||||
case syncconfig:
|
||||
case oldaskconfig:
|
||||
case oldconfig:
|
||||
case listnewconfig:
|
||||
@ -641,24 +652,24 @@ int main(int ac, char **av)
|
||||
case oldaskconfig:
|
||||
rootEntry = &rootmenu;
|
||||
conf(&rootmenu);
|
||||
input_mode = silentoldconfig;
|
||||
input_mode = oldconfig;
|
||||
/* fall through */
|
||||
case oldconfig:
|
||||
case listnewconfig:
|
||||
case olddefconfig:
|
||||
case silentoldconfig:
|
||||
case syncconfig:
|
||||
/* Update until a loop caused no more changes */
|
||||
do {
|
||||
conf_cnt = 0;
|
||||
check_conf(&rootmenu);
|
||||
} while (conf_cnt &&
|
||||
(input_mode != listnewconfig &&
|
||||
input_mode != olddefconfig));
|
||||
} while (conf_cnt);
|
||||
break;
|
||||
case olddefconfig:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (sync_kconfig) {
|
||||
/* silentoldconfig is used during the build so we shall update autoconf.
|
||||
/* syncconfig is used during the build so we shall update autoconf.
|
||||
* All other commands are only used to generate a config.
|
||||
*/
|
||||
if (conf_get_changed() && conf_write(NULL)) {
|
||||
|
@ -1137,49 +1137,9 @@ static int expr_compare_type(enum expr_type t1, enum expr_type t2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct expr *
|
||||
expr_get_leftmost_symbol(const struct expr *e)
|
||||
{
|
||||
|
||||
if (e == NULL)
|
||||
return NULL;
|
||||
|
||||
while (e->type != E_SYMBOL)
|
||||
e = e->left.expr;
|
||||
|
||||
return expr_copy(e);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given expression `e1' and `e2', returns the leaf of the longest
|
||||
* sub-expression of `e1' not containing 'e2.
|
||||
*/
|
||||
struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
|
||||
{
|
||||
struct expr *ret;
|
||||
|
||||
switch (e1->type) {
|
||||
case E_OR:
|
||||
return expr_alloc_and(
|
||||
expr_simplify_unmet_dep(e1->left.expr, e2),
|
||||
expr_simplify_unmet_dep(e1->right.expr, e2));
|
||||
case E_AND: {
|
||||
struct expr *e;
|
||||
e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
|
||||
e = expr_eliminate_dups(e);
|
||||
ret = (!expr_eq(e, e1)) ? e1 : NULL;
|
||||
expr_free(e);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = e1;
|
||||
break;
|
||||
}
|
||||
|
||||
return expr_get_leftmost_symbol(ret);
|
||||
}
|
||||
|
||||
static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken, bool revdep)
|
||||
void expr_print(struct expr *e,
|
||||
void (*fn)(void *, struct symbol *, const char *),
|
||||
void *data, int prevtoken)
|
||||
{
|
||||
if (!e) {
|
||||
fn(data, NULL, "y");
|
||||
@ -1234,14 +1194,9 @@ static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, con
|
||||
fn(data, e->right.sym, e->right.sym->name);
|
||||
break;
|
||||
case E_OR:
|
||||
if (revdep && e->left.expr->type != E_OR)
|
||||
fn(data, NULL, "\n - ");
|
||||
__expr_print(e->left.expr, fn, data, E_OR, revdep);
|
||||
if (revdep)
|
||||
fn(data, NULL, "\n - ");
|
||||
else
|
||||
fn(data, NULL, " || ");
|
||||
__expr_print(e->right.expr, fn, data, E_OR, revdep);
|
||||
expr_print(e->left.expr, fn, data, E_OR);
|
||||
fn(data, NULL, " || ");
|
||||
expr_print(e->right.expr, fn, data, E_OR);
|
||||
break;
|
||||
case E_AND:
|
||||
expr_print(e->left.expr, fn, data, E_AND);
|
||||
@ -1274,11 +1229,6 @@ static void __expr_print(struct expr *e, void (*fn)(void *, struct symbol *, con
|
||||
fn(data, NULL, ")");
|
||||
}
|
||||
|
||||
void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
|
||||
{
|
||||
__expr_print(e, fn, data, prevtoken, false);
|
||||
}
|
||||
|
||||
static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
|
||||
{
|
||||
xfwrite(str, strlen(str), 1, data);
|
||||
@ -1329,7 +1279,27 @@ void expr_gstr_print(struct expr *e, struct gstr *gs)
|
||||
* line with a minus. This makes expressions much easier to read.
|
||||
* Suitable for reverse dependency expressions.
|
||||
*/
|
||||
void expr_gstr_print_revdep(struct expr *e, struct gstr *gs)
|
||||
static void expr_print_revdep(struct expr *e,
|
||||
void (*fn)(void *, struct symbol *, const char *),
|
||||
void *data, tristate pr_type, const char **title)
|
||||
{
|
||||
__expr_print(e, expr_print_gstr_helper, gs, E_NONE, true);
|
||||
if (e->type == E_OR) {
|
||||
expr_print_revdep(e->left.expr, fn, data, pr_type, title);
|
||||
expr_print_revdep(e->right.expr, fn, data, pr_type, title);
|
||||
} else if (expr_calc_value(e) == pr_type) {
|
||||
if (*title) {
|
||||
fn(data, NULL, *title);
|
||||
*title = NULL;
|
||||
}
|
||||
|
||||
fn(data, NULL, " - ");
|
||||
expr_print(e, fn, data, E_NONE);
|
||||
fn(data, NULL, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
|
||||
tristate pr_type, const char *title)
|
||||
{
|
||||
expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);
|
||||
}
|
||||
|
@ -305,12 +305,12 @@ struct expr *expr_transform(struct expr *e);
|
||||
int expr_contains_symbol(struct expr *dep, struct symbol *sym);
|
||||
bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
|
||||
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
|
||||
struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2);
|
||||
|
||||
void expr_fprint(struct expr *e, FILE *out);
|
||||
struct gstr; /* forward */
|
||||
void expr_gstr_print(struct expr *e, struct gstr *gs);
|
||||
void expr_gstr_print_revdep(struct expr *e, struct gstr *gs);
|
||||
void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
|
||||
tristate pr_type, const char *title);
|
||||
|
||||
static inline int expr_is_yes(struct expr *e)
|
||||
{
|
||||
|
@ -68,6 +68,7 @@ struct kconf_id {
|
||||
enum symbol_type stype;
|
||||
};
|
||||
|
||||
extern int yylineno;
|
||||
void zconfdump(FILE *out);
|
||||
void zconf_starthelp(void);
|
||||
FILE *zconf_fopen(const char *name);
|
||||
|
@ -834,16 +834,16 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
|
||||
|
||||
get_symbol_props_str(r, sym, P_SELECT, _(" Selects: "));
|
||||
if (sym->rev_dep.expr) {
|
||||
str_append(r, _(" Selected by: "));
|
||||
expr_gstr_print_revdep(sym->rev_dep.expr, r);
|
||||
str_append(r, "\n");
|
||||
expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, " Selected by [y]:\n");
|
||||
expr_gstr_print_revdep(sym->rev_dep.expr, r, mod, " Selected by [m]:\n");
|
||||
expr_gstr_print_revdep(sym->rev_dep.expr, r, no, " Selected by [n]:\n");
|
||||
}
|
||||
|
||||
get_symbol_props_str(r, sym, P_IMPLY, _(" Implies: "));
|
||||
if (sym->implied.expr) {
|
||||
str_append(r, _(" Implied by: "));
|
||||
expr_gstr_print_revdep(sym->implied.expr, r);
|
||||
str_append(r, "\n");
|
||||
expr_gstr_print_revdep(sym->implied.expr, r, yes, " Implied by [y]:\n");
|
||||
expr_gstr_print_revdep(sym->implied.expr, r, mod, " Implied by [m]:\n");
|
||||
expr_gstr_print_revdep(sym->implied.expr, r, no, " Implied by [n]:\n");
|
||||
}
|
||||
|
||||
str_append(r, "\n\n");
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <locale.h>
|
||||
#include <curses.h>
|
||||
#include <ncurses.h>
|
||||
#include <menu.h>
|
||||
#include <panel.h>
|
||||
#include <form.h>
|
||||
@ -24,8 +24,6 @@
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "ncurses.h"
|
||||
|
||||
#define max(a, b) ({\
|
||||
typeof(a) _a = a;\
|
||||
typeof(b) _b = b;\
|
||||
|
@ -243,7 +243,7 @@ static void sym_calc_visibility(struct symbol *sym)
|
||||
tri = yes;
|
||||
if (sym->dir_dep.expr)
|
||||
tri = expr_calc_value(sym->dir_dep.expr);
|
||||
if (tri == mod)
|
||||
if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
|
||||
tri = yes;
|
||||
if (sym->dir_dep.tri != tri) {
|
||||
sym->dir_dep.tri = tri;
|
||||
@ -333,6 +333,27 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
|
||||
return def_sym;
|
||||
}
|
||||
|
||||
static void sym_warn_unmet_dep(struct symbol *sym)
|
||||
{
|
||||
struct gstr gs = str_new();
|
||||
|
||||
str_printf(&gs,
|
||||
"\nWARNING: unmet direct dependencies detected for %s\n",
|
||||
sym->name);
|
||||
str_printf(&gs,
|
||||
" Depends on [%c]: ",
|
||||
sym->dir_dep.tri == mod ? 'm' : 'n');
|
||||
expr_gstr_print(sym->dir_dep.expr, &gs);
|
||||
str_printf(&gs, "\n");
|
||||
|
||||
expr_gstr_print_revdep(sym->rev_dep.expr, &gs, yes,
|
||||
" Selected by [y]:\n");
|
||||
expr_gstr_print_revdep(sym->rev_dep.expr, &gs, mod,
|
||||
" Selected by [m]:\n");
|
||||
|
||||
fputs(str_get(&gs), stderr);
|
||||
}
|
||||
|
||||
void sym_calc_value(struct symbol *sym)
|
||||
{
|
||||
struct symbol_value newval, oldval;
|
||||
@ -403,9 +424,10 @@ void sym_calc_value(struct symbol *sym)
|
||||
if (!sym_is_choice(sym)) {
|
||||
prop = sym_get_default_prop(sym);
|
||||
if (prop) {
|
||||
sym->flags |= SYMBOL_WRITE;
|
||||
newval.tri = EXPR_AND(expr_calc_value(prop->expr),
|
||||
prop->visible.tri);
|
||||
if (newval.tri != no)
|
||||
sym->flags |= SYMBOL_WRITE;
|
||||
}
|
||||
if (sym->implied.tri != no) {
|
||||
sym->flags |= SYMBOL_WRITE;
|
||||
@ -413,18 +435,8 @@ void sym_calc_value(struct symbol *sym)
|
||||
}
|
||||
}
|
||||
calc_newval:
|
||||
if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
|
||||
struct expr *e;
|
||||
e = expr_simplify_unmet_dep(sym->rev_dep.expr,
|
||||
sym->dir_dep.expr);
|
||||
fprintf(stderr, "warning: (");
|
||||
expr_fprint(e, stderr);
|
||||
fprintf(stderr, ") selects %s which has unmet direct dependencies (",
|
||||
sym->name);
|
||||
expr_fprint(sym->dir_dep.expr, stderr);
|
||||
fprintf(stderr, ")\n");
|
||||
expr_free(e);
|
||||
}
|
||||
if (sym->dir_dep.tri < sym->rev_dep.tri)
|
||||
sym_warn_unmet_dep(sym);
|
||||
newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
|
||||
}
|
||||
if (newval.tri == mod &&
|
||||
|
@ -1,5 +1,5 @@
|
||||
%option nostdinit noyywrap never-interactive full ecs
|
||||
%option 8bit nodefault perf-report perf-report
|
||||
%option 8bit nodefault yylineno
|
||||
%option noinput
|
||||
%x COMMAND HELP STRING PARAM
|
||||
%{
|
||||
@ -83,7 +83,6 @@ n [A-Za-z0-9_-]
|
||||
|
||||
[ \t]*#.*\n |
|
||||
[ \t]*\n {
|
||||
current_file->lineno++;
|
||||
return T_EOL;
|
||||
}
|
||||
[ \t]*#.*
|
||||
@ -104,7 +103,7 @@ n [A-Za-z0-9_-]
|
||||
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
|
||||
BEGIN(PARAM);
|
||||
current_pos.file = current_file;
|
||||
current_pos.lineno = current_file->lineno;
|
||||
current_pos.lineno = yylineno;
|
||||
if (id && id->flags & TF_COMMAND) {
|
||||
yylval.id = id;
|
||||
return id->token;
|
||||
@ -116,7 +115,6 @@ n [A-Za-z0-9_-]
|
||||
. warn_ignored_character(*yytext);
|
||||
\n {
|
||||
BEGIN(INITIAL);
|
||||
current_file->lineno++;
|
||||
return T_EOL;
|
||||
}
|
||||
}
|
||||
@ -138,7 +136,7 @@ n [A-Za-z0-9_-]
|
||||
new_string();
|
||||
BEGIN(STRING);
|
||||
}
|
||||
\n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
|
||||
\n BEGIN(INITIAL); return T_EOL;
|
||||
({n}|[/.])+ {
|
||||
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
|
||||
if (id && id->flags & TF_PARAM) {
|
||||
@ -150,7 +148,7 @@ n [A-Za-z0-9_-]
|
||||
return T_WORD;
|
||||
}
|
||||
#.* /* comment */
|
||||
\\\n current_file->lineno++;
|
||||
\\\n ;
|
||||
[[:blank:]]+
|
||||
. warn_ignored_character(*yytext);
|
||||
<<EOF>> {
|
||||
@ -187,7 +185,6 @@ n [A-Za-z0-9_-]
|
||||
fprintf(stderr,
|
||||
"%s:%d:warning: multi-line strings not supported\n",
|
||||
zconf_curname(), zconf_lineno());
|
||||
current_file->lineno++;
|
||||
BEGIN(INITIAL);
|
||||
return T_EOL;
|
||||
}
|
||||
@ -220,12 +217,10 @@ n [A-Za-z0-9_-]
|
||||
}
|
||||
}
|
||||
[ \t]*\n/[^ \t\n] {
|
||||
current_file->lineno++;
|
||||
zconf_endhelp();
|
||||
return T_HELPTEXT;
|
||||
}
|
||||
[ \t]*\n {
|
||||
current_file->lineno++;
|
||||
append_string("\n", 1);
|
||||
}
|
||||
[^ \t\n].* {
|
||||
@ -304,7 +299,7 @@ void zconf_initscan(const char *name)
|
||||
memset(current_buf, 0, sizeof(*current_buf));
|
||||
|
||||
current_file = file_lookup(name);
|
||||
current_file->lineno = 1;
|
||||
yylineno = 1;
|
||||
}
|
||||
|
||||
void zconf_nextfile(const char *name)
|
||||
@ -325,24 +320,26 @@ void zconf_nextfile(const char *name)
|
||||
buf->parent = current_buf;
|
||||
current_buf = buf;
|
||||
|
||||
for (iter = current_file->parent; iter; iter = iter->parent ) {
|
||||
if (!strcmp(current_file->name,iter->name) ) {
|
||||
current_file->lineno = yylineno;
|
||||
file->parent = current_file;
|
||||
|
||||
for (iter = current_file; iter; iter = iter->parent) {
|
||||
if (!strcmp(iter->name, file->name)) {
|
||||
fprintf(stderr,
|
||||
"%s:%d: recursive inclusion detected. "
|
||||
"Inclusion path:\n current file : '%s'\n",
|
||||
zconf_curname(), zconf_lineno(),
|
||||
zconf_curname());
|
||||
iter = current_file;
|
||||
"Recursive inclusion detected.\n"
|
||||
"Inclusion path:\n"
|
||||
" current file : %s\n", file->name);
|
||||
iter = file;
|
||||
do {
|
||||
iter = iter->parent;
|
||||
fprintf(stderr, " included from: '%s:%d'\n",
|
||||
fprintf(stderr, " included from: %s:%d\n",
|
||||
iter->name, iter->lineno - 1);
|
||||
} while (strcmp(iter->name, current_file->name));
|
||||
} while (strcmp(iter->name, file->name));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
file->lineno = 1;
|
||||
file->parent = current_file;
|
||||
|
||||
yylineno = 1;
|
||||
current_file = file;
|
||||
}
|
||||
|
||||
@ -351,6 +348,8 @@ static void zconf_endfile(void)
|
||||
struct buffer *parent;
|
||||
|
||||
current_file = current_file->parent;
|
||||
if (current_file)
|
||||
yylineno = current_file->lineno;
|
||||
|
||||
parent = current_buf->parent;
|
||||
if (parent) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user