kconfig: Sync with upstream v4.18

This commit introduces the following upstream changes:

73d1c580f92b kconfig: loop boundary condition fix
ecd53ac2f2c6 kconfig: handle P_SYMBOL in print_symbol()
b2d00d7c61c8 kconfig: fix line numbers for if-entries in menu tree
8593080c0fcf kconfig: fix localmodconfig
2ae89c7a82ea kconfig: Avoid format overflow warning from GCC 8.1
bb6d83dde191 kbuild: Move last word of nconfig help to the previous line
d6a0c8a1326b kconfig: Add testconfig into make help output
2bece88f89fa kconfig: test: add Kconfig macro language tests
915f64901eb3 kconfig: error out if a recursive variable references itself
a702a6176e2f kconfig: add 'filename' and 'lineno' built-in variables
1d6272e6fe43 kconfig: add 'info', 'warning-if', and 'error-if' built-in functions
82bc8bd82e5c kconfig: expand lefthand side of assignment statement
ed2a22f277c6 kconfig: support append assignment operator
1175c02506ff kconfig: support simply expanded variable
9ced3bddec08 kconfig: support user-defined function and recursively expanded variable
9de071536c87 kconfig: begin PARAM state only when seeing a command keyword
2fd5b09c201e kconfig: add 'shell' built-in function
e298f3b49def kconfig: add built-in function support
137c0118a900 kconfig: make default prompt of mainmenu less specific
5b31a9746756 kconfig: remove sym_expand_string_value()
96d8e48da55a kconfig: remove string expansion for mainmenu after yyparse()
bb222ceeb327 kconfig: remove string expansion in file_lookup()
104daea149c4 kconfig: reference environment variables directly and remove 'option env='
694c49a7c01c kconfig: drop localization support
1c5af5cf9308 kconfig: refactor ncurses package checks for building mconf and nconf
b464ef583dc7 kconfig: refactor GTK+ package checks for building gconf
0b669a5076fd kconfig: refactor Qt package checks for building qconf

Signed-off-by: Chris Packham <judge.packham@gmail.com>
This commit is contained in:
Chris Packham 2020-12-09 21:24:45 +13:00
parent 689dc60f21
commit bbc4db1337
23 changed files with 918 additions and 530 deletions

View File

@ -1,14 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Needed for systems without gettext
$* -x c -o /dev/null - > /dev/null 2>&1 << EOF
#include <libintl.h>
int main()
{
gettext("");
return 0;
}
EOF
if [ ! "$?" -eq "0" ]; then
echo -DKBUILD_NO_NLS;
fi

View File

@ -3,7 +3,6 @@
* Released under the terms of the GNU GPL v2.0. * Released under the terms of the GNU GPL v2.0.
*/ */
#include <locale.h>
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
@ -86,7 +85,7 @@ static int conf_askvalue(struct symbol *sym, const char *def)
enum symbol_type type = sym_get_type(sym); enum symbol_type type = sym_get_type(sym);
if (!sym_has_value(sym)) if (!sym_has_value(sym))
printf(_("(NEW) ")); printf("(NEW) ");
line[0] = '\n'; line[0] = '\n';
line[1] = 0; line[1] = 0;
@ -133,7 +132,7 @@ static int conf_string(struct menu *menu)
const char *def; const char *def;
while (1) { while (1) {
printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); printf("%*s%s ", indent - 1, "", menu->prompt->text);
printf("(%s) ", sym->name); printf("(%s) ", sym->name);
def = sym_get_string_value(sym); def = sym_get_string_value(sym);
if (sym_get_string_value(sym)) if (sym_get_string_value(sym))
@ -166,7 +165,7 @@ static int conf_sym(struct menu *menu)
tristate oldval, newval; tristate oldval, newval;
while (1) { while (1) {
printf("%*s%s ", indent - 1, "", _(menu->prompt->text)); printf("%*s%s ", indent - 1, "", menu->prompt->text);
if (sym->name) if (sym->name)
printf("(%s) ", sym->name); printf("(%s) ", sym->name);
putchar('['); putchar('[');
@ -251,7 +250,7 @@ static int conf_choice(struct menu *menu)
case no: case no:
return 1; return 1;
case mod: case mod:
printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
return 0; return 0;
case yes: case yes:
break; break;
@ -261,7 +260,7 @@ static int conf_choice(struct menu *menu)
while (1) { while (1) {
int cnt, def; int cnt, def;
printf("%*s%s\n", indent - 1, "", _(menu_get_prompt(menu))); printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
def_sym = sym_get_choice_value(sym); def_sym = sym_get_choice_value(sym);
cnt = def = 0; cnt = def = 0;
line[0] = 0; line[0] = 0;
@ -269,7 +268,7 @@ static int conf_choice(struct menu *menu)
if (!menu_is_visible(child)) if (!menu_is_visible(child))
continue; continue;
if (!child->sym) { if (!child->sym) {
printf("%*c %s\n", indent, '*', _(menu_get_prompt(child))); printf("%*c %s\n", indent, '*', menu_get_prompt(child));
continue; continue;
} }
cnt++; cnt++;
@ -278,14 +277,14 @@ static int conf_choice(struct menu *menu)
printf("%*c", indent, '>'); printf("%*c", indent, '>');
} else } else
printf("%*c", indent, ' '); printf("%*c", indent, ' ');
printf(" %d. %s", cnt, _(menu_get_prompt(child))); printf(" %d. %s", cnt, menu_get_prompt(child));
if (child->sym->name) if (child->sym->name)
printf(" (%s)", child->sym->name); printf(" (%s)", child->sym->name);
if (!sym_has_value(child->sym)) if (!sym_has_value(child->sym))
printf(_(" (NEW)")); printf(" (NEW)");
printf("\n"); printf("\n");
} }
printf(_("%*schoice"), indent - 1, ""); printf("%*schoice", indent - 1, "");
if (cnt == 1) { if (cnt == 1) {
printf("[1]: 1\n"); printf("[1]: 1\n");
goto conf_childs; goto conf_childs;
@ -372,7 +371,7 @@ static void conf(struct menu *menu)
if (prompt) if (prompt)
printf("%*c\n%*c %s\n%*c\n", printf("%*c\n%*c %s\n%*c\n",
indent, '*', indent, '*',
indent, '*', _(prompt), indent, '*', prompt,
indent, '*'); indent, '*');
default: default:
; ;
@ -437,7 +436,7 @@ static void check_conf(struct menu *menu)
} }
} else { } else {
if (!conf_cnt++) if (!conf_cnt++)
printf(_("*\n* Restart config...\n*\n")); printf("*\n* Restart config...\n*\n");
rootEntry = menu_get_parent_menu(menu); rootEntry = menu_get_parent_menu(menu);
conf(rootEntry); conf(rootEntry);
} }
@ -477,10 +476,6 @@ int main(int ac, char **av)
const char *name, *defconfig_file = NULL /* gcc uninit */; const char *name, *defconfig_file = NULL /* gcc uninit */;
struct stat tmpstat; struct stat tmpstat;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
tty_stdio = isatty(0) && isatty(1); tty_stdio = isatty(0) && isatty(1);
while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) { while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {
@ -532,14 +527,14 @@ int main(int ac, char **av)
case olddefconfig: case olddefconfig:
break; break;
case '?': case '?':
fprintf(stderr, _("See README for usage info\n")); fprintf(stderr, "See README for usage info\n");
exit(1); exit(1);
break; break;
} }
} }
if (ac == optind) { if (ac == optind) {
fprintf(stderr, _("%s: Kconfig file missing\n"), av[0]); fprintf(stderr, "%s: Kconfig file missing\n", av[0]);
fprintf(stderr, _("See README for usage info\n")); fprintf(stderr, "See README for usage info\n");
exit(1); exit(1);
} }
name = av[optind]; name = av[optind];
@ -548,12 +543,12 @@ int main(int ac, char **av)
if (sync_kconfig) { if (sync_kconfig) {
name = conf_get_configname(); name = conf_get_configname();
if (stat(name, &tmpstat)) { if (stat(name, &tmpstat)) {
fprintf(stderr, _("***\n" fprintf(stderr, "***\n"
"*** Configuration file \"%s\" not found!\n" "*** Configuration file \"%s\" not found!\n"
"***\n" "***\n"
"*** Please configure with \"menuconfig\", or use a\n" "*** Please configure with \"menuconfig\", or use a\n"
"*** pre-existing sample (see list with \"list-samples\").\n" "*** pre-existing sample (see list with \"list-samples\").\n"
"***\n"), name); "***\n", name);
exit(1); exit(1);
} }
} }
@ -564,9 +559,9 @@ int main(int ac, char **av)
defconfig_file = conf_get_default_confname(); defconfig_file = conf_get_default_confname();
if (conf_read(defconfig_file)) { if (conf_read(defconfig_file)) {
fprintf(stderr, fprintf(stderr,
_("***\n" "***\n"
"*** Can't find default configuration \"%s\"!\n" "*** Can't find default configuration \"%s\"!\n"
"***\n"), "***\n",
defconfig_file); defconfig_file);
exit(1); exit(1);
} }
@ -590,7 +585,7 @@ int main(int ac, char **av)
if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) { if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
if (conf_read_simple(name, S_DEF_USER)) { if (conf_read_simple(name, S_DEF_USER)) {
fprintf(stderr, fprintf(stderr,
_("*** Can't read seed configuration \"%s\"!\n"), "*** Can't read seed configuration \"%s\"!\n",
name); name);
exit(1); exit(1);
} }
@ -607,7 +602,7 @@ int main(int ac, char **av)
if (conf_read_simple(name, S_DEF_USER) && if (conf_read_simple(name, S_DEF_USER) &&
conf_read_simple("all.config", S_DEF_USER)) { conf_read_simple("all.config", S_DEF_USER)) {
fprintf(stderr, fprintf(stderr,
_("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"), "*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n",
name); name);
exit(1); exit(1);
} }
@ -621,7 +616,7 @@ int main(int ac, char **av)
name = getenv("KCONFIG_NOSILENTUPDATE"); name = getenv("KCONFIG_NOSILENTUPDATE");
if (name && *name) { if (name && *name) {
fprintf(stderr, fprintf(stderr,
_("\n*** The configuration requires explicit update.\n\n")); "\n*** The configuration requires explicit update.\n\n");
return 1; return 1;
} }
} }
@ -673,23 +668,23 @@ int main(int ac, char **av)
* All other commands are only used to generate a config. * All other commands are only used to generate a config.
*/ */
if (conf_get_changed() && conf_write(NULL)) { if (conf_get_changed() && conf_write(NULL)) {
fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
exit(1); exit(1);
} }
/* In crosstool-NG, we do not use the autoconf stuff /* In crosstool-NG, we do not use the autoconf stuff
if (conf_write_autoconf()) { if (conf_write_autoconf()) {
fprintf(stderr, _("\n*** Error during update of the configuration.\n\n")); fprintf(stderr, "\n*** Error during update of the configuration.\n\n");
return 1; return 1;
} */ } */
} else if (input_mode == savedefconfig) { } else if (input_mode == savedefconfig) {
if (conf_write_defconfig(defconfig_file)) { if (conf_write_defconfig(defconfig_file)) {
fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"), fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
defconfig_file); defconfig_file);
return 1; return 1;
} }
} else if (input_mode != listnewconfig) { } else if (input_mode != listnewconfig) {
if (conf_write(NULL)) { if (conf_write(NULL)) {
fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n")); fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
exit(1); exit(1);
} }
} }

View File

@ -30,7 +30,7 @@ static void conf_message(const char *fmt, ...)
static const char *conf_filename; static const char *conf_filename;
static int conf_lineno, conf_warnings; static int conf_lineno, conf_warnings;
const char conf_defname[] = "arch/$ARCH/defconfig"; const char conf_defname[] = "arch/$(ARCH)/defconfig";
static void conf_warning(const char *fmt, ...) static void conf_warning(const char *fmt, ...)
{ {
@ -81,39 +81,13 @@ const char *conf_get_autoconfig_name(void)
return name ? name : "include/config/auto.conf"; return name ? name : "include/config/auto.conf";
} }
static char *conf_expand_value(const char *in)
{
struct symbol *sym;
const char *src;
static char res_value[SYMBOL_MAXLENGTH];
char *dst, name[SYMBOL_MAXLENGTH];
res_value[0] = 0;
dst = name;
while ((src = strchr(in, '$'))) {
strncat(res_value, in, src - in);
src++;
dst = name;
while (isalnum(*src) || *src == '_')
*dst++ = *src++;
*dst = 0;
sym = sym_lookup(name, 0);
sym_calc_value(sym);
strcat(res_value, sym_get_string_value(sym));
in = src;
}
strcat(res_value, in);
return res_value;
}
char *conf_get_default_confname(void) char *conf_get_default_confname(void)
{ {
struct stat buf; struct stat buf;
static char fullname[PATH_MAX+1]; static char fullname[PATH_MAX+1];
char *env, *name; char *env, *name;
name = conf_expand_value(conf_defname); name = expand_string(conf_defname);
env = getenv(SRCTREE); env = getenv(SRCTREE);
if (env) { if (env) {
sprintf(fullname, "%s/%s", env, name); sprintf(fullname, "%s/%s", env, name);
@ -274,10 +248,11 @@ int conf_read_simple(const char *name, int def)
if (expr_calc_value(prop->visible.expr) == no || if (expr_calc_value(prop->visible.expr) == no ||
prop->expr->type != E_SYMBOL) prop->expr->type != E_SYMBOL)
continue; continue;
name = conf_expand_value(prop->expr->left.sym->name); sym_calc_value(prop->expr->left.sym);
name = sym_get_string_value(prop->expr->left.sym);
in = zconf_fopen(name); in = zconf_fopen(name);
if (in) { if (in) {
conf_message(_("using defaults found in %s"), conf_message("using defaults found in %s",
name); name);
goto load; goto load;
} }
@ -745,7 +720,7 @@ int conf_write(const char *name)
struct menu *menu; struct menu *menu;
const char *basename; const char *basename;
const char *str; const char *str;
char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8];
char *env; char *env;
dirname[0] = 0; dirname[0] = 0;
@ -831,7 +806,7 @@ next:
return 1; return 1;
} }
conf_message(_("configuration written to %s"), newname); conf_message("configuration written to %s", newname);
sym_set_change_count(0); sym_set_change_count(0);

View File

@ -171,6 +171,9 @@ struct symbol {
* config BAZ * config BAZ
* int "BAZ Value" * int "BAZ Value"
* range 1..255 * range 1..255
*
* Please, also check zconf.y:print_symbol() when modifying the
* list of property types!
*/ */
enum prop_type { enum prop_type {
P_UNKNOWN, P_UNKNOWN,

View File

@ -32,7 +32,6 @@ static struct kconf_id kconf_id_array[] = {
{ "on", T_ON, TF_PARAM }, { "on", T_ON, TF_PARAM },
{ "modules", T_OPT_MODULES, TF_OPTION }, { "modules", T_OPT_MODULES, TF_OPTION },
{ "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION }, { "defconfig_list", T_OPT_DEFCONFIG_LIST, TF_OPTION },
{ "env", T_OPT_ENV, TF_OPTION },
{ "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION }, { "allnoconfig_y", T_OPT_ALLNOCONFIG_Y, TF_OPTION },
}; };

View File

@ -8,15 +8,6 @@
#include "expr.h" #include "expr.h"
#ifndef KBUILD_NO_NLS
# include <libintl.h>
#else
static inline const char *gettext(const char *txt) { return txt; }
static inline void textdomain(const char *domainname) {}
static inline void bindtextdomain(const char *name, const char *dir) {}
static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; }
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -29,11 +20,6 @@ extern "C" {
#define PACKAGE "linux" #define PACKAGE "linux"
#endif #endif
#define LOCALEDIR "/usr/share/locale"
#define _(text) gettext(text)
#define N_(text) (text)
#ifndef CONFIG_ #ifndef CONFIG_
#define CONFIG_ "CONFIG_" #define CONFIG_ "CONFIG_"
#endif #endif
@ -58,7 +44,6 @@ enum conf_def_mode {
#define T_OPT_MODULES 1 #define T_OPT_MODULES 1
#define T_OPT_DEFCONFIG_LIST 2 #define T_OPT_DEFCONFIG_LIST 2
#define T_OPT_ENV 3
#define T_OPT_ALLNOCONFIG_Y 4 #define T_OPT_ALLNOCONFIG_Y 4
struct kconf_id { struct kconf_id {
@ -117,6 +102,7 @@ void *xmalloc(size_t size);
void *xcalloc(size_t nmemb, size_t size); void *xcalloc(size_t nmemb, size_t size);
void *xrealloc(void *p, size_t size); void *xrealloc(void *p, size_t size);
char *xstrdup(const char *s); char *xstrdup(const char *s);
char *xstrndup(const char *s, size_t n);
struct gstr { struct gstr {
size_t len; size_t len;
@ -134,9 +120,6 @@ void str_printf(struct gstr *gs, const char *fmt, ...);
const char *str_get(struct gstr *gs); const char *str_get(struct gstr *gs);
/* symbol.c */ /* symbol.c */
extern struct expr *sym_env_list;
void sym_init(void);
void sym_clear_all_valid(void); void sym_clear_all_valid(void);
struct symbol *sym_choice_default(struct symbol *sym); struct symbol *sym_choice_default(struct symbol *sym);
const char *sym_get_string_default(struct symbol *sym); const char *sym_get_string_default(struct symbol *sym);

View File

@ -31,7 +31,6 @@ extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
struct symbol * sym_lookup(const char *name, int flags); struct symbol * sym_lookup(const char *name, int flags);
struct symbol * sym_find(const char *name); struct symbol * sym_find(const char *name);
char *sym_expand_string_value(const char *in);
const char * sym_escape_string_value(const char *in); const char * sym_escape_string_value(const char *in);
struct symbol ** sym_re_search(const char *pattern); struct symbol ** sym_re_search(const char *pattern);
const char * sym_type_name(enum symbol_type type); const char * sym_type_name(enum symbol_type type);
@ -49,5 +48,19 @@ const char * sym_get_string_value(struct symbol *sym);
const char * prop_get_type_name(enum prop_type type); const char * prop_get_type_name(enum prop_type type);
/* preprocess.c */
enum variable_flavor {
VAR_SIMPLE,
VAR_RECURSIVE,
VAR_APPEND,
};
void env_write_dep(FILE *f, const char *auto_conf_name);
void variable_add(const char *name, const char *value,
enum variable_flavor flavor);
void variable_all_del(void);
char *expand_string(const char *in);
char *expand_dollar(const char **str);
char *expand_one_token(const char **str);
/* expr.c */ /* expr.c */
void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);

View File

@ -1,93 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# Check ncurses compatibility
# What library to link
ldflags()
{
pkg-config --libs ncursesw 2>/dev/null && exit
pkg-config --libs ncurses 2>/dev/null && exit
for ext in so a dll.a dylib ; do
for lib in ncursesw ncurses curses ; do
$cc -print-file-name=lib${lib}.${ext} | grep -q /
if [ $? -eq 0 ]; then
echo "-l${lib}"
exit
fi
done
done
exit 1
}
# Where is ncurses.h?
ccflags()
{
if pkg-config --cflags ncursesw 2>/dev/null; then
echo '-DCURSES_LOC="<ncurses.h>" -DNCURSES_WIDECHAR=1'
elif pkg-config --cflags ncurses 2>/dev/null; then
echo '-DCURSES_LOC="<ncurses.h>"'
elif [ -f /usr/include/ncursesw/curses.h ]; then
echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"'
echo ' -DNCURSES_WIDECHAR=1'
elif [ -f /usr/include/ncurses/ncurses.h ]; then
echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
elif [ -f /usr/include/ncurses/curses.h ]; then
echo '-I/usr/include/ncurses -DCURSES_LOC="<curses.h>"'
elif [ -f /usr/include/ncurses.h ]; then
echo '-DCURSES_LOC="<ncurses.h>"'
else
echo '-DCURSES_LOC="<curses.h>"'
fi
}
# Temp file, try to clean up after us
tmp=.lxdialog.tmp
trap "rm -f $tmp" 0 1 2 3 15
# Check if we can link to ncurses
check() {
$cc -x c - -o $tmp 2>/dev/null <<'EOF'
#include CURSES_LOC
main() {}
EOF
if [ $? != 0 ]; then
echo " *** Unable to find the ncurses libraries or the" 1>&2
echo " *** required header files." 1>&2
echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2
echo " *** " 1>&2
echo " *** Install ncurses (ncurses-devel or libncurses-dev " 1>&2
echo " *** depending on your distribution) and try again." 1>&2
echo " *** " 1>&2
exit 1
fi
}
usage() {
printf "Usage: $0 [-check compiler options|-ccflags|-ldflags compiler options]\n"
}
if [ $# -eq 0 ]; then
usage
exit 1
fi
cc=""
case "$1" in
"-check")
shift
cc="$@"
check
;;
"-ccflags")
ccflags
;;
"-ldflags")
shift
cc="$@"
ldflags
;;
"*")
usage
exit 1
;;
esac

View File

@ -103,8 +103,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
int x = width / 2 - 11; int x = width / 2 - 11;
int y = height - 2; int y = height - 2;
print_button(dialog, gettext("Select"), y, x, selected == 0); print_button(dialog, "Select", y, x, selected == 0);
print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); print_button(dialog, " Help ", y, x + 14, selected == 1);
wmove(dialog, y, x + 1 + 14 * selected); wmove(dialog, y, x + 1 + 14 * selected);
wrefresh(dialog); wrefresh(dialog);

View File

@ -26,16 +26,10 @@
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#ifndef KBUILD_NO_NLS
# include <libintl.h>
#else
# define gettext(Msgid) ((const char *) (Msgid))
#endif
#ifdef __sun__ #ifdef __sun__
#define CURS_MACROS #define CURS_MACROS
#endif #endif
#include CURSES_LOC #include <ncurses.h>
/* /*
* Colors in ncurses 1.9.9e do not work properly since foreground and * Colors in ncurses 1.9.9e do not work properly since foreground and

View File

@ -31,8 +31,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
int x = width / 2 - 11; int x = width / 2 - 11;
int y = height - 2; int y = height - 2;
print_button(dialog, gettext(" Ok "), y, x, selected == 0); print_button(dialog, " Ok ", y, x, selected == 0);
print_button(dialog, gettext(" Help "), y, x + 14, selected == 1); print_button(dialog, " Help ", y, x + 14, selected == 1);
wmove(dialog, y, x + 1 + 14 * selected); wmove(dialog, y, x + 1 + 14 * selected);
wrefresh(dialog); wrefresh(dialog);

View File

@ -157,11 +157,11 @@ static void print_buttons(WINDOW * win, int height, int width, int selected)
int x = width / 2 - 28; int x = width / 2 - 28;
int y = height - 2; int y = height - 2;
print_button(win, gettext("Select"), y, x, selected == 0); print_button(win, "Select", y, x, selected == 0);
print_button(win, gettext(" Exit "), y, x + 12, selected == 1); print_button(win, " Exit ", y, x + 12, selected == 1);
print_button(win, gettext(" Help "), y, x + 24, selected == 2); print_button(win, " Help ", y, x + 24, selected == 2);
print_button(win, gettext(" Save "), y, x + 36, selected == 3); print_button(win, " Save ", y, x + 36, selected == 3);
print_button(win, gettext(" Load "), y, x + 48, selected == 4); print_button(win, " Load ", y, x + 48, selected == 4);
wmove(win, y, x + 1 + 12 * selected); wmove(win, y, x + 1 + 12 * selected);
wrefresh(win); wrefresh(win);

View File

@ -129,7 +129,7 @@ do_resize:
print_title(dialog, title, width); print_title(dialog, title, width);
print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE); print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
wnoutrefresh(dialog); wnoutrefresh(dialog);
getyx(dialog, cur_y, cur_x); /* Save cursor position */ getyx(dialog, cur_y, cur_x); /* Save cursor position */

View File

@ -29,8 +29,8 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
int x = width / 2 - 10; int x = width / 2 - 10;
int y = height - 2; int y = height - 2;
print_button(dialog, gettext(" Yes "), y, x, selected == 0); print_button(dialog, " Yes ", y, x, selected == 0);
print_button(dialog, gettext(" No "), y, x + 13, selected == 1); print_button(dialog, " No ", y, x + 13, selected == 1);
wmove(dialog, y, x + 1 + 13 * selected); wmove(dialog, y, x + 1 + 13 * selected);
wrefresh(dialog); wrefresh(dialog);

View File

@ -17,12 +17,11 @@
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <locale.h>
#include "lkc.h" #include "lkc.h"
#include "lxdialog/dialog.h" #include "lxdialog/dialog.h"
static const char mconf_readme[] = N_( static const char mconf_readme[] =
"Overview\n" "Overview\n"
"--------\n" "--------\n"
"This interface lets you select features and parameters for the build.\n" "This interface lets you select features and parameters for the build.\n"
@ -171,37 +170,37 @@ static const char mconf_readme[] = N_(
" blackbg => selects a color scheme with black background\n" " blackbg => selects a color scheme with black background\n"
" classic => theme with blue background. The classic look\n" " classic => theme with blue background. The classic look\n"
" bluetitle => an LCD friendly version of classic. (default)\n" " bluetitle => an LCD friendly version of classic. (default)\n"
"\n"), "\n",
menu_instructions[] = N_( menu_instructions[] =
"Arrow keys navigate the menu. " "Arrow keys navigate the menu. "
"<Enter> selects submenus ---> (or empty submenus ----). " "<Enter> selects submenus ---> (or empty submenus ----). "
"Highlighted letters are hotkeys. " "Highlighted letters are hotkeys. "
"Pressing <Y> includes, <N> excludes, <M> modularizes features. " "Pressing <Y> includes, <N> excludes, <M> modularizes features. "
"Press <Esc><Esc> to exit, <?> for Help, </> for Search. " "Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
"Legend: [*] built-in [ ] excluded <M> module < > module capable"), "Legend: [*] built-in [ ] excluded <M> module < > module capable",
radiolist_instructions[] = N_( radiolist_instructions[] =
"Use the arrow keys to navigate this window or " "Use the arrow keys to navigate this window or "
"press the hotkey of the item you wish to select " "press the hotkey of the item you wish to select "
"followed by the <SPACE BAR>. " "followed by the <SPACE BAR>. "
"Press <?> for additional information about this option."), "Press <?> for additional information about this option.",
inputbox_instructions_int[] = N_( inputbox_instructions_int[] =
"Please enter a decimal value. " "Please enter a decimal value. "
"Fractions will not be accepted. " "Fractions will not be accepted. "
"Use the <TAB> key to move from the input field to the buttons below it."), "Use the <TAB> key to move from the input field to the buttons below it.",
inputbox_instructions_hex[] = N_( inputbox_instructions_hex[] =
"Please enter a hexadecimal value. " "Please enter a hexadecimal value. "
"Use the <TAB> key to move from the input field to the buttons below it."), "Use the <TAB> key to move from the input field to the buttons below it.",
inputbox_instructions_string[] = N_( inputbox_instructions_string[] =
"Please enter a string value. " "Please enter a string value. "
"Use the <TAB> key to move from the input field to the buttons below it."), "Use the <TAB> key to move from the input field to the buttons below it.",
setmod_text[] = N_( setmod_text[] =
"This feature depends on another which has been configured as a module.\n" "This feature depends on another which has been configured as a module.\n"
"As a result, this feature will be built as a module."), "As a result, this feature will be built as a module.",
load_config_text[] = N_( load_config_text[] =
"Enter the name of the configuration file you wish to load. " "Enter the name of the configuration file you wish to load. "
"Accept the name shown to restore the configuration you " "Accept the name shown to restore the configuration you "
"last retrieved. Leave blank to abort."), "last retrieved. Leave blank to abort.",
load_config_help[] = N_( load_config_help[] =
"\n" "\n"
"For various reasons, one may wish to keep several different\n" "For various reasons, one may wish to keep several different\n"
"configurations available on a single machine.\n" "configurations available on a single machine.\n"
@ -211,11 +210,11 @@ load_config_help[] = N_(
"configuration.\n" "configuration.\n"
"\n" "\n"
"If you are uncertain, then you have probably never used alternate\n" "If you are uncertain, then you have probably never used alternate\n"
"configuration files. You should therefore leave this blank to abort.\n"), "configuration files. You should therefore leave this blank to abort.\n",
save_config_text[] = N_( save_config_text[] =
"Enter a filename to which this configuration should be saved " "Enter a filename to which this configuration should be saved "
"as an alternate. Leave blank to abort."), "as an alternate. Leave blank to abort.",
save_config_help[] = N_( save_config_help[] =
"\n" "\n"
"For various reasons, one may wish to keep different configurations\n" "For various reasons, one may wish to keep different configurations\n"
"available on a single machine.\n" "available on a single machine.\n"
@ -225,8 +224,8 @@ save_config_help[] = N_(
"configuration options you have selected at that time.\n" "configuration options you have selected at that time.\n"
"\n" "\n"
"If you are uncertain what all this means then you should probably\n" "If you are uncertain what all this means then you should probably\n"
"leave this blank.\n"), "leave this blank.\n",
search_help[] = N_( search_help[] =
"\n" "\n"
"Search for symbols and display their relations.\n" "Search for symbols and display their relations.\n"
"Regular expressions are allowed.\n" "Regular expressions are allowed.\n"
@ -271,7 +270,7 @@ search_help[] = N_(
"Examples: USB => find all symbols containing USB\n" "Examples: USB => find all symbols containing USB\n"
" ^USB => find all symbols starting with USB\n" " ^USB => find all symbols starting with USB\n"
" USB$ => find all symbols ending with USB\n" " USB$ => find all symbols ending with USB\n"
"\n"); "\n";
static int indent; static int indent;
static struct menu *current_menu; static struct menu *current_menu;
@ -400,19 +399,19 @@ static void search_conf(void)
struct subtitle_part stpart; struct subtitle_part stpart;
title = str_new(); title = str_new();
str_printf( &title, _("Enter (sub)string or regexp to search for " str_printf( &title, "Enter (sub)string or regexp to search for "
"(with or without \"%s\")"), CONFIG_); "(with or without \"%s\")", CONFIG_);
again: again:
dialog_clear(); dialog_clear();
dres = dialog_inputbox(_("Search Configuration Parameter"), dres = dialog_inputbox("Search Configuration Parameter",
str_get(&title), str_get(&title),
10, 75, ""); 10, 75, "");
switch (dres) { switch (dres) {
case 0: case 0:
break; break;
case 1: case 1:
show_helptext(_("Search Configuration"), search_help); show_helptext("Search Configuration", search_help);
goto again; goto again;
default: default:
str_free(&title); str_free(&title);
@ -443,7 +442,7 @@ again:
res = get_relations_str(sym_arr, &head); res = get_relations_str(sym_arr, &head);
set_subtitle(); set_subtitle();
dres = show_textbox_ext(_("Search Results"), (char *) dres = show_textbox_ext("Search Results", (char *)
str_get(&res), 0, 0, keys, &vscroll, str_get(&res), 0, 0, keys, &vscroll,
&hscroll, &update_text, (void *) &hscroll, &update_text, (void *)
&data); &data);
@ -491,7 +490,7 @@ static void build_conf(struct menu *menu)
switch (prop->type) { switch (prop->type) {
case P_MENU: case P_MENU:
child_count++; child_count++;
prompt = _(prompt); prompt = prompt;
if (single_menu_mode) { if (single_menu_mode) {
item_make("%s%*c%s", item_make("%s%*c%s",
menu->data ? "-->" : "++>", menu->data ? "-->" : "++>",
@ -508,7 +507,7 @@ static void build_conf(struct menu *menu)
case P_COMMENT: case P_COMMENT:
if (prompt) { if (prompt) {
child_count++; child_count++;
item_make(" %*c*** %s ***", indent + 1, ' ', _(prompt)); item_make(" %*c*** %s ***", indent + 1, ' ', prompt);
item_set_tag(':'); item_set_tag(':');
item_set_data(menu); item_set_data(menu);
} }
@ -516,7 +515,7 @@ static void build_conf(struct menu *menu)
default: default:
if (prompt) { if (prompt) {
child_count++; child_count++;
item_make("---%*c%s", indent + 1, ' ', _(prompt)); item_make("---%*c%s", indent + 1, ' ', prompt);
item_set_tag(':'); item_set_tag(':');
item_set_data(menu); item_set_data(menu);
} }
@ -560,10 +559,10 @@ static void build_conf(struct menu *menu)
item_set_data(menu); item_set_data(menu);
} }
item_add_str("%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); item_add_str("%*c%s", indent + 1, ' ', menu_get_prompt(menu));
if (val == yes) { if (val == yes) {
if (def_menu) { if (def_menu) {
item_add_str(" (%s)", _(menu_get_prompt(def_menu))); item_add_str(" (%s)", menu_get_prompt(def_menu));
item_add_str(" --->"); item_add_str(" --->");
if (def_menu->list) { if (def_menu->list) {
indent += 2; indent += 2;
@ -575,7 +574,7 @@ static void build_conf(struct menu *menu)
} }
} else { } else {
if (menu == current_menu) { if (menu == current_menu) {
item_make("---%*c%s", indent + 1, ' ', _(menu_get_prompt(menu))); item_make("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
item_set_tag(':'); item_set_tag(':');
item_set_data(menu); item_set_data(menu);
goto conf_childs; goto conf_childs;
@ -618,17 +617,17 @@ static void build_conf(struct menu *menu)
tmp = indent - tmp + 4; tmp = indent - tmp + 4;
if (tmp < 0) if (tmp < 0)
tmp = 0; tmp = 0;
item_add_str("%*c%s%s", tmp, ' ', _(menu_get_prompt(menu)), item_add_str("%*c%s%s", tmp, ' ', menu_get_prompt(menu),
(sym_has_value(sym) || !sym_is_changable(sym)) ? (sym_has_value(sym) || !sym_is_changable(sym)) ?
"" : _(" (NEW)")); "" : " (NEW)");
item_set_tag('s'); item_set_tag('s');
item_set_data(menu); item_set_data(menu);
goto conf_childs; goto conf_childs;
} }
} }
item_add_str("%*c%s%s", indent + 1, ' ', _(menu_get_prompt(menu)), item_add_str("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu),
(sym_has_value(sym) || !sym_is_changable(sym)) ? (sym_has_value(sym) || !sym_is_changable(sym)) ?
"" : _(" (NEW)")); "" : " (NEW)");
if (menu->prompt->type == P_MENU) { if (menu->prompt->type == P_MENU) {
item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
return; return;
@ -665,8 +664,8 @@ static void conf(struct menu *menu, struct menu *active_menu)
break; break;
set_subtitle(); set_subtitle();
dialog_clear(); dialog_clear();
res = dialog_menu(prompt ? _(prompt) : _("Main Menu"), res = dialog_menu(prompt ? prompt : "Main Menu",
_(menu_instructions), menu_instructions,
active_menu, &s_scroll); active_menu, &s_scroll);
if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
break; break;
@ -708,7 +707,7 @@ static void conf(struct menu *menu, struct menu *active_menu)
show_help(submenu); show_help(submenu);
else { else {
reset_subtitle(); reset_subtitle();
show_helptext(_("README"), _(mconf_readme)); show_helptext("README", mconf_readme);
} }
break; break;
case 3: case 3:
@ -793,13 +792,13 @@ static void show_help(struct menu *menu)
help.max_width = getmaxx(stdscr) - 10; help.max_width = getmaxx(stdscr) - 10;
menu_get_ext_help(menu, &help); menu_get_ext_help(menu, &help);
show_helptext(_(menu_get_prompt(menu)), str_get(&help)); show_helptext(menu_get_prompt(menu), str_get(&help));
str_free(&help); str_free(&help);
} }
static void conf_choice(struct menu *menu) static void conf_choice(struct menu *menu)
{ {
const char *prompt = _(menu_get_prompt(menu)); const char *prompt = menu_get_prompt(menu);
struct menu *child; struct menu *child;
struct symbol *active; struct symbol *active;
@ -814,9 +813,9 @@ static void conf_choice(struct menu *menu)
if (!menu_is_visible(child)) if (!menu_is_visible(child))
continue; continue;
if (child->sym) if (child->sym)
item_make("%s", _(menu_get_prompt(child))); item_make("%s", menu_get_prompt(child));
else { else {
item_make("*** %s ***", _(menu_get_prompt(child))); item_make("*** %s ***", menu_get_prompt(child));
item_set_tag(':'); item_set_tag(':');
} }
item_set_data(child); item_set_data(child);
@ -826,8 +825,8 @@ static void conf_choice(struct menu *menu)
item_set_tag('X'); item_set_tag('X');
} }
dialog_clear(); dialog_clear();
res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"), res = dialog_checklist(prompt ? prompt : "Main Menu",
_(radiolist_instructions), radiolist_instructions,
MENUBOX_HEIGTH_MIN, MENUBOX_HEIGTH_MIN,
MENUBOX_WIDTH_MIN, MENUBOX_WIDTH_MIN,
CHECKLIST_HEIGTH_MIN); CHECKLIST_HEIGTH_MIN);
@ -868,26 +867,26 @@ static void conf_string(struct menu *menu)
switch (sym_get_type(menu->sym)) { switch (sym_get_type(menu->sym)) {
case S_INT: case S_INT:
heading = _(inputbox_instructions_int); heading = inputbox_instructions_int;
break; break;
case S_HEX: case S_HEX:
heading = _(inputbox_instructions_hex); heading = inputbox_instructions_hex;
break; break;
case S_STRING: case S_STRING:
heading = _(inputbox_instructions_string); heading = inputbox_instructions_string;
break; break;
default: default:
heading = _("Internal mconf error!"); heading = "Internal mconf error!";
} }
dialog_clear(); dialog_clear();
res = dialog_inputbox(prompt ? _(prompt) : _("Main Menu"), res = dialog_inputbox(prompt ? prompt : "Main Menu",
heading, 10, 75, heading, 10, 75,
sym_get_string_value(menu->sym)); sym_get_string_value(menu->sym));
switch (res) { switch (res) {
case 0: case 0:
if (sym_set_string_value(menu->sym, dialog_input_result)) if (sym_set_string_value(menu->sym, dialog_input_result))
return; return;
show_textbox(NULL, _("You have made an invalid entry."), 5, 43); show_textbox(NULL, "You have made an invalid entry.", 5, 43);
break; break;
case 1: case 1:
show_help(menu); show_help(menu);
@ -915,10 +914,10 @@ static void conf_load(void)
sym_set_change_count(1); sym_set_change_count(1);
return; return;
} }
show_textbox(NULL, _("File does not exist!"), 5, 38); show_textbox(NULL, "File does not exist!", 5, 38);
break; break;
case 1: case 1:
show_helptext(_("Load Alternate Configuration"), load_config_help); show_helptext("Load Alternate Configuration", load_config_help);
break; break;
case KEY_ESC: case KEY_ESC:
return; return;
@ -941,10 +940,10 @@ static void conf_save(void)
set_config_filename(dialog_input_result); set_config_filename(dialog_input_result);
return; return;
} }
show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60); show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60);
break; break;
case 1: case 1:
show_helptext(_("Save Alternate Configuration"), save_config_help); show_helptext("Save Alternate Configuration", save_config_help);
break; break;
case KEY_ESC: case KEY_ESC:
return; return;
@ -961,8 +960,8 @@ static int handle_exit(void)
dialog_clear(); dialog_clear();
if (conf_get_changed()) if (conf_get_changed())
res = dialog_yesno(NULL, res = dialog_yesno(NULL,
_("Do you wish to save your new configuration?\n" "Do you wish to save your new configuration?\n"
"(Press <ESC><ESC> to continue Crosstool-NG configuration.)"), "(Press <ESC><ESC> to continue Crosstool-NG configuration.)",
6, 60); 6, 60);
else else
res = -1; res = -1;
@ -972,26 +971,26 @@ static int handle_exit(void)
switch (res) { switch (res) {
case 0: case 0:
if (conf_write(filename)) { if (conf_write(filename)) {
fprintf(stderr, _("\n\n" fprintf(stderr, "\n\n"
"Error while writing of the configuration.\n" "Error while writing of the configuration.\n"
"Your configuration changes were NOT saved." "Your configuration changes were NOT saved."
"\n\n")); "\n\n");
return 1; return 1;
} }
/* fall through */ /* fall through */
case -1: case -1:
if (!silent) if (!silent)
printf(_("\n\n" printf("\n\n"
"*** End of the configuration.\n" "*** End of the configuration.\n"
"*** Execute 'ct-ng build' to start the build or try 'ct-ng help'." "*** Execute 'ct-ng build' to start the build or try 'ct-ng help'."
"\n\n")); "\n\n");
res = 0; res = 0;
break; break;
default: default:
if (!silent) if (!silent)
fprintf(stderr, _("\n\n" fprintf(stderr, "\n\n"
"Your configuration changes were NOT saved." "Your configuration changes were NOT saved."
"\n\n")); "\n\n");
if (res != KEY_ESC) if (res != KEY_ESC)
res = 0; res = 0;
} }
@ -1009,10 +1008,6 @@ int main(int ac, char **av)
char *mode; char *mode;
int res; int res;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
signal(SIGINT, sig_handler); signal(SIGINT, sig_handler);
if (ac > 1 && strcmp(av[1], "-s") == 0) { if (ac > 1 && strcmp(av[1], "-s") == 0) {
@ -1031,8 +1026,8 @@ int main(int ac, char **av)
} }
if (init_dialog(NULL)) { if (init_dialog(NULL)) {
fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); fprintf(stderr, "Your display is too small to run Menuconfig!\n");
fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n")); fprintf(stderr, "It must be at least 19 lines by 80 columns.\n");
return 1; return 1;
} }

View File

@ -220,9 +220,6 @@ void menu_add_option(int token, char *arg)
zconf_error("trying to redefine defconfig symbol"); zconf_error("trying to redefine defconfig symbol");
sym_defconfig_list->flags |= SYMBOL_AUTO; sym_defconfig_list->flags |= SYMBOL_AUTO;
break; break;
case T_OPT_ENV:
prop_add_env(arg);
break;
case T_OPT_ALLNOCONFIG_Y: case T_OPT_ALLNOCONFIG_Y:
current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y; current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y;
break; break;
@ -717,7 +714,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
struct menu *submenu[8], *menu, *location = NULL; struct menu *submenu[8], *menu, *location = NULL;
struct jump_key *jump = NULL; struct jump_key *jump = NULL;
str_printf(r, _("Prompt: %s\n"), _(prop->text)); str_printf(r, "Prompt: %s\n", prop->text);
menu = prop->menu->parent; menu = prop->menu->parent;
for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) { for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
bool accessible = menu_is_visible(menu); bool accessible = menu_is_visible(menu);
@ -750,16 +747,16 @@ static void get_prompt_str(struct gstr *r, struct property *prop,
} }
if (i > 0) { if (i > 0) {
str_printf(r, _(" Location:\n")); str_printf(r, " Location:\n");
for (j = 4; --i >= 0; j += 2) { for (j = 4; --i >= 0; j += 2) {
menu = submenu[i]; menu = submenu[i];
if (jump && menu == location) if (jump && menu == location)
jump->offset = strlen(r->s); jump->offset = strlen(r->s);
str_printf(r, "%*c-> %s", j, ' ', str_printf(r, "%*c-> %s", j, ' ',
_(menu_get_prompt(menu))); menu_get_prompt(menu));
if (menu->sym) { if (menu->sym) {
str_printf(r, " (%s [=%s])", menu->sym->name ? str_printf(r, " (%s [=%s])", menu->sym->name ?
menu->sym->name : _("<choice>"), menu->sym->name : "<choice>",
sym_get_string_value(menu->sym)); sym_get_string_value(menu->sym));
} }
str_append(r, "\n"); str_append(r, "\n");
@ -823,23 +820,23 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
prop = get_symbol_prop(sym); prop = get_symbol_prop(sym);
if (prop) { if (prop) {
str_printf(r, _(" Defined at %s:%d\n"), prop->menu->file->name, str_printf(r, " Defined at %s:%d\n", prop->menu->file->name,
prop->menu->lineno); prop->menu->lineno);
if (!expr_is_yes(prop->visible.expr)) { if (!expr_is_yes(prop->visible.expr)) {
str_append(r, _(" Depends on: ")); str_append(r, " Depends on: ");
expr_gstr_print(prop->visible.expr, r); expr_gstr_print(prop->visible.expr, r);
str_append(r, "\n"); str_append(r, "\n");
} }
} }
get_symbol_props_str(r, sym, P_SELECT, _(" Selects: ")); get_symbol_props_str(r, sym, P_SELECT, " Selects: ");
if (sym->rev_dep.expr) { if (sym->rev_dep.expr) {
expr_gstr_print_revdep(sym->rev_dep.expr, r, yes, " Selected by [y]:\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, mod, " Selected by [m]:\n");
expr_gstr_print_revdep(sym->rev_dep.expr, r, no, " Selected by [n]:\n"); expr_gstr_print_revdep(sym->rev_dep.expr, r, no, " Selected by [n]:\n");
} }
get_symbol_props_str(r, sym, P_IMPLY, _(" Implies: ")); get_symbol_props_str(r, sym, P_IMPLY, " Implies: ");
if (sym->implied.expr) { if (sym->implied.expr) {
expr_gstr_print_revdep(sym->implied.expr, r, yes, " Implied by [y]:\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, mod, " Implied by [m]:\n");
@ -858,7 +855,7 @@ struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head)
for (i = 0; sym_arr && (sym = sym_arr[i]); i++) for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
get_symbol_str(&res, sym, head); get_symbol_str(&res, sym, head);
if (!i) if (!i)
str_append(&res, _("No matches found.\n")); str_append(&res, "No matches found.\n");
return res; return res;
} }
@ -873,7 +870,7 @@ void menu_get_ext_help(struct menu *menu, struct gstr *help)
str_printf(help, "%s%s:\n\n", CONFIG_, sym->name); str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
help_text = menu_get_help(menu); help_text = menu_get_help(menu);
} }
str_printf(help, "%s\n", _(help_text)); str_printf(help, "%s\n", help_text);
if (sym) if (sym)
get_symbol_str(help, sym, NULL); get_symbol_str(help, sym, NULL);
} }

View File

@ -15,7 +15,7 @@
#include "nconf.h" #include "nconf.h"
#include <ctype.h> #include <ctype.h>
static const char nconf_global_help[] = N_( static const char nconf_global_help[] =
"Help windows\n" "Help windows\n"
"------------\n" "------------\n"
"o Global help: Unless in a data entry window, pressing <F1> will give \n" "o Global help: Unless in a data entry window, pressing <F1> will give \n"
@ -133,8 +133,8 @@ static const char nconf_global_help[] = N_(
"\n" "\n"
"Note that this mode can eventually be a little more CPU expensive than\n" "Note that this mode can eventually be a little more CPU expensive than\n"
"the default mode, especially with a larger number of unfolded submenus.\n" "the default mode, especially with a larger number of unfolded submenus.\n"
"\n"), "\n",
menu_no_f_instructions[] = N_( menu_no_f_instructions[] =
"Legend: [*] built-in [ ] excluded <M> automatic < > automatic capable.\n" "Legend: [*] built-in [ ] excluded <M> automatic < > automatic capable.\n"
"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
"\n" "\n"
@ -150,8 +150,8 @@ menu_no_f_instructions[] = N_(
"You do not have function keys support.\n" "You do not have function keys support.\n"
"Press <1> instead of <F1>, <2> instead of <F2>, etc.\n" "Press <1> instead of <F1>, <2> instead of <F2>, etc.\n"
"For verbose global help use key <1>.\n" "For verbose global help use key <1>.\n"
"For help related to the current menu entry press <?> or <h>.\n"), "For help related to the current menu entry press <?> or <h>.\n",
menu_instructions[] = N_( menu_instructions[] =
"Legend: [*] built-in [ ] excluded <M> automatic < > automatic capable.\n" "Legend: [*] built-in [ ] excluded <M> automatic < > automatic capable.\n"
"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n" "Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
"\n" "\n"
@ -166,30 +166,30 @@ menu_instructions[] = N_(
"\n" "\n"
"Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n" "Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n"
"For verbose global help press <F1>.\n" "For verbose global help press <F1>.\n"
"For help related to the current menu entry press <?> or <h>.\n"), "For help related to the current menu entry press <?> or <h>.\n",
radiolist_instructions[] = N_( radiolist_instructions[] =
"Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n" "Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n"
"with <Space>.\n" "with <Space>.\n"
"For help related to the current entry press <?> or <h>.\n" "For help related to the current entry press <?> or <h>.\n"
"For global help press <F1>.\n"), "For global help press <F1>.\n",
inputbox_instructions_int[] = N_( inputbox_instructions_int[] =
"Please enter a decimal value.\n" "Please enter a decimal value.\n"
"Fractions will not be accepted.\n" "Fractions will not be accepted.\n"
"Press <Enter> to apply, <Esc> to cancel."), "Press <Enter> to apply, <Esc> to cancel.",
inputbox_instructions_hex[] = N_( inputbox_instructions_hex[] =
"Please enter a hexadecimal value.\n" "Please enter a hexadecimal value.\n"
"Press <Enter> to apply, <Esc> to cancel."), "Press <Enter> to apply, <Esc> to cancel.",
inputbox_instructions_string[] = N_( inputbox_instructions_string[] =
"Please enter a string value.\n" "Please enter a string value.\n"
"Press <Enter> to apply, <Esc> to cancel."), "Press <Enter> to apply, <Esc> to cancel.",
setmod_text[] = N_( setmod_text[] =
"This feature depends on another feature which has been configured as\n" "This feature depends on another feature which has been configured as\n"
"automatic. As a result, the current feature will be built as automatic too."), "automatic. As a result, the current feature will be built as automatic too.",
load_config_text[] = N_( load_config_text[] =
"Enter the name of the configuration file you wish to load.\n" "Enter the name of the configuration file you wish to load.\n"
"Accept the name shown to restore the configuration you last\n" "Accept the name shown to restore the configuration you last\n"
"retrieved. Leave empty to abort."), "retrieved. Leave empty to abort.",
load_config_help[] = N_( load_config_help[] =
"For various reasons, one may wish to keep several different\n" "For various reasons, one may wish to keep several different\n"
"configurations available on a single machine.\n" "configurations available on a single machine.\n"
"\n" "\n"
@ -197,11 +197,11 @@ load_config_help[] = N_(
"default one, entering its name here will allow you to load and modify\n" "default one, entering its name here will allow you to load and modify\n"
"that configuration.\n" "that configuration.\n"
"\n" "\n"
"Leave empty to abort.\n"), "Leave empty to abort.\n",
save_config_text[] = N_( save_config_text[] =
"Enter a filename to which this configuration should be saved\n" "Enter a filename to which this configuration should be saved\n"
"as an alternate. Leave empty to abort."), "as an alternate. Leave empty to abort.",
save_config_help[] = N_( save_config_help[] =
"For various reasons, one may wish to keep several different\n" "For various reasons, one may wish to keep several different\n"
"configurations available on a single machine.\n" "configurations available on a single machine.\n"
"\n" "\n"
@ -209,8 +209,8 @@ save_config_help[] = N_(
"and use the current configuration as an alternate to whatever\n" "and use the current configuration as an alternate to whatever\n"
"configuration options you have selected at that time.\n" "configuration options you have selected at that time.\n"
"\n" "\n"
"Leave empty to abort.\n"), "Leave empty to abort.\n",
search_help[] = N_( search_help[] =
"Search for symbols (configuration variable names CONFIG_*) and display\n" "Search for symbols (configuration variable names CONFIG_*) and display\n"
"their relations. Regular expressions are supported.\n" "their relations. Regular expressions are supported.\n"
"Example: Search for \"^FOO\".\n" "Example: Search for \"^FOO\".\n"
@ -247,7 +247,7 @@ search_help[] = N_(
"USB => find all symbols containing USB\n" "USB => find all symbols containing USB\n"
"^USB => find all symbols starting with USB\n" "^USB => find all symbols starting with USB\n"
"USB$ => find all symbols ending with USB\n" "USB$ => find all symbols ending with USB\n"
"\n"); "\n";
struct mitem { struct mitem {
char str[256]; char str[256];
@ -391,7 +391,7 @@ static void print_function_line(void)
static void handle_f1(int *key, struct menu *current_item) static void handle_f1(int *key, struct menu *current_item)
{ {
show_scroll_win(main_window, show_scroll_win(main_window,
_("Global help"), _(nconf_global_help)); "Global help", nconf_global_help);
return; return;
} }
@ -406,8 +406,8 @@ static void handle_f2(int *key, struct menu *current_item)
static void handle_f3(int *key, struct menu *current_item) static void handle_f3(int *key, struct menu *current_item)
{ {
show_scroll_win(main_window, show_scroll_win(main_window,
_("Short help"), "Short help",
_(current_instructions)); current_instructions);
return; return;
} }
@ -415,7 +415,7 @@ static void handle_f3(int *key, struct menu *current_item)
static void handle_f4(int *key, struct menu *current_item) static void handle_f4(int *key, struct menu *current_item)
{ {
int res = btn_dialog(main_window, int res = btn_dialog(main_window,
_("Show all symbols?"), "Show all symbols?",
2, 2,
" <Show All> ", " <Show All> ",
"<Don't show all>"); "<Don't show all>");
@ -656,8 +656,8 @@ static int do_exit(void)
return 0; return 0;
} }
res = btn_dialog(main_window, res = btn_dialog(main_window,
_("Do you wish to save your new configuration?\n" "Do you wish to save your new configuration?\n"
"<ESC> to cancel and resume nconfig."), "<ESC> to cancel and resume nconfig.",
2, 2,
" <save> ", " <save> ",
"<don't save>"); "<don't save>");
@ -673,15 +673,15 @@ static int do_exit(void)
if (res) if (res)
btn_dialog( btn_dialog(
main_window, main_window,
_("Error during writing of configuration.\n" "Error during writing of configuration.\n"
"Your configuration changes were NOT saved."), "Your configuration changes were NOT saved.",
1, 1,
"<OK>"); "<OK>");
break; break;
default: default:
btn_dialog( btn_dialog(
main_window, main_window,
_("Your configuration changes were NOT saved."), "Your configuration changes were NOT saved.",
1, 1,
"<OK>"); "<OK>");
break; break;
@ -700,12 +700,12 @@ static void search_conf(void)
int dres; int dres;
title = str_new(); title = str_new();
str_printf( &title, _("Enter (sub)string or regexp to search for " str_printf( &title, "Enter (sub)string or regexp to search for "
"(with or without \"%s\")"), CONFIG_); "(with or without \"%s\")", CONFIG_);
again: again:
dres = dialog_inputbox(main_window, dres = dialog_inputbox(main_window,
_("Search Configuration Parameter"), "Search Configuration Parameter",
str_get(&title), str_get(&title),
"", &dialog_input_result, &dialog_input_result_len); "", &dialog_input_result, &dialog_input_result_len);
switch (dres) { switch (dres) {
@ -713,7 +713,7 @@ again:
break; break;
case 1: case 1:
show_scroll_win(main_window, show_scroll_win(main_window,
_("Search Configuration"), search_help); "Search Configuration", search_help);
goto again; goto again;
default: default:
str_free(&title); str_free(&title);
@ -729,7 +729,7 @@ again:
res = get_relations_str(sym_arr, NULL); res = get_relations_str(sym_arr, NULL);
free(sym_arr); free(sym_arr);
show_scroll_win(main_window, show_scroll_win(main_window,
_("Search Results"), str_get(&res)); "Search Results", str_get(&res));
str_free(&res); str_free(&res);
str_free(&title); str_free(&title);
} }
@ -757,7 +757,7 @@ static void build_conf(struct menu *menu)
switch (ptype) { switch (ptype) {
case P_MENU: case P_MENU:
child_count++; child_count++;
prompt = _(prompt); prompt = prompt;
if (single_menu_mode) { if (single_menu_mode) {
item_make(menu, 'm', item_make(menu, 'm',
"%s%*c%s", "%s%*c%s",
@ -778,7 +778,7 @@ static void build_conf(struct menu *menu)
item_make(menu, ':', item_make(menu, ':',
" %*c*** %s ***", " %*c*** %s ***",
indent + 1, ' ', indent + 1, ' ',
_(prompt)); prompt);
} }
break; break;
default: default:
@ -786,7 +786,7 @@ static void build_conf(struct menu *menu)
child_count++; child_count++;
item_make(menu, ':', "---%*c%s", item_make(menu, ':', "---%*c%s",
indent + 1, ' ', indent + 1, ' ',
_(prompt)); prompt);
} }
} }
} else } else
@ -832,11 +832,11 @@ static void build_conf(struct menu *menu)
} }
item_add_str("%*c%s", indent + 1, item_add_str("%*c%s", indent + 1,
' ', _(menu_get_prompt(menu))); ' ', menu_get_prompt(menu));
if (val == yes) { if (val == yes) {
if (def_menu) { if (def_menu) {
item_add_str(" (%s)", item_add_str(" (%s)",
_(menu_get_prompt(def_menu))); menu_get_prompt(def_menu));
item_add_str(" --->"); item_add_str(" --->");
if (def_menu->list) { if (def_menu->list) {
indent += 2; indent += 2;
@ -850,7 +850,7 @@ static void build_conf(struct menu *menu)
if (menu == current_menu) { if (menu == current_menu) {
item_make(menu, ':', item_make(menu, ':',
"---%*c%s", indent + 1, "---%*c%s", indent + 1,
' ', _(menu_get_prompt(menu))); ' ', menu_get_prompt(menu));
goto conf_childs; goto conf_childs;
} }
child_count++; child_count++;
@ -897,17 +897,17 @@ static void build_conf(struct menu *menu)
if (tmp < 0) if (tmp < 0)
tmp = 0; tmp = 0;
item_add_str("%*c%s%s", tmp, ' ', item_add_str("%*c%s%s", tmp, ' ',
_(menu_get_prompt(menu)), menu_get_prompt(menu),
(sym_has_value(sym) || (sym_has_value(sym) ||
!sym_is_changable(sym)) ? "" : !sym_is_changable(sym)) ? "" :
_(" (NEW)")); " (NEW)");
goto conf_childs; goto conf_childs;
} }
} }
item_add_str("%*c%s%s", indent + 1, ' ', item_add_str("%*c%s%s", indent + 1, ' ',
_(menu_get_prompt(menu)), menu_get_prompt(menu),
(sym_has_value(sym) || !sym_is_changable(sym)) ? (sym_has_value(sym) || !sym_is_changable(sym)) ?
"" : _(" (NEW)")); "" : " (NEW)");
if (menu->prompt && menu->prompt->type == P_MENU) { if (menu->prompt && menu->prompt->type == P_MENU) {
item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->"); item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
return; return;
@ -1089,8 +1089,8 @@ static void conf(struct menu *menu)
if (!child_count) if (!child_count)
break; break;
show_menu(prompt ? _(prompt) : _("Main Menu"), show_menu(prompt ? prompt : "Main Menu",
_(menu_instructions), menu_instructions,
current_index, &last_top_row); current_index, &last_top_row);
keypad((menu_win(curses_menu)), TRUE); keypad((menu_win(curses_menu)), TRUE);
while (!global_exit) { while (!global_exit) {
@ -1230,13 +1230,13 @@ static void show_help(struct menu *menu)
help = str_new(); help = str_new();
menu_get_ext_help(menu, &help); menu_get_ext_help(menu, &help);
show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help)); show_scroll_win(main_window, menu_get_prompt(menu), str_get(&help));
str_free(&help); str_free(&help);
} }
static void conf_choice(struct menu *menu) static void conf_choice(struct menu *menu)
{ {
const char *prompt = _(menu_get_prompt(menu)); const char *prompt = menu_get_prompt(menu);
struct menu *child = NULL; struct menu *child = NULL;
struct symbol *active; struct symbol *active;
int selected_index = 0; int selected_index = 0;
@ -1259,13 +1259,13 @@ static void conf_choice(struct menu *menu)
if (child->sym == sym_get_choice_value(menu->sym)) if (child->sym == sym_get_choice_value(menu->sym))
item_make(child, ':', "<X> %s", item_make(child, ':', "<X> %s",
_(menu_get_prompt(child))); menu_get_prompt(child));
else if (child->sym) else if (child->sym)
item_make(child, ':', " %s", item_make(child, ':', " %s",
_(menu_get_prompt(child))); menu_get_prompt(child));
else else
item_make(child, ':', "*** %s ***", item_make(child, ':', "*** %s ***",
_(menu_get_prompt(child))); menu_get_prompt(child));
if (child->sym == active){ if (child->sym == active){
last_top_row = top_row(curses_menu); last_top_row = top_row(curses_menu);
@ -1273,8 +1273,8 @@ static void conf_choice(struct menu *menu)
} }
i++; i++;
} }
show_menu(prompt ? _(prompt) : _("Choice Menu"), show_menu(prompt ? prompt : "Choice Menu",
_(radiolist_instructions), radiolist_instructions,
selected_index, selected_index,
&last_top_row); &last_top_row);
while (!global_exit) { while (!global_exit) {
@ -1361,19 +1361,19 @@ static void conf_string(struct menu *menu)
switch (sym_get_type(menu->sym)) { switch (sym_get_type(menu->sym)) {
case S_INT: case S_INT:
heading = _(inputbox_instructions_int); heading = inputbox_instructions_int;
break; break;
case S_HEX: case S_HEX:
heading = _(inputbox_instructions_hex); heading = inputbox_instructions_hex;
break; break;
case S_STRING: case S_STRING:
heading = _(inputbox_instructions_string); heading = inputbox_instructions_string;
break; break;
default: default:
heading = _("Internal nconf error!"); heading = "Internal nconf error!";
} }
res = dialog_inputbox(main_window, res = dialog_inputbox(main_window,
prompt ? _(prompt) : _("Main Menu"), prompt ? prompt : "Main Menu",
heading, heading,
sym_get_string_value(menu->sym), sym_get_string_value(menu->sym),
&dialog_input_result, &dialog_input_result,
@ -1384,7 +1384,7 @@ static void conf_string(struct menu *menu)
dialog_input_result)) dialog_input_result))
return; return;
btn_dialog(main_window, btn_dialog(main_window,
_("You have made an invalid entry."), 0); "You have made an invalid entry.", 0);
break; break;
case 1: case 1:
show_help(menu); show_help(menu);
@ -1413,11 +1413,11 @@ static void conf_load(void)
sym_set_change_count(1); sym_set_change_count(1);
return; return;
} }
btn_dialog(main_window, _("File does not exist!"), 0); btn_dialog(main_window, "File does not exist!", 0);
break; break;
case 1: case 1:
show_scroll_win(main_window, show_scroll_win(main_window,
_("Load Alternate Configuration"), "Load Alternate Configuration",
load_config_help); load_config_help);
break; break;
case KEY_EXIT: case KEY_EXIT:
@ -1444,13 +1444,13 @@ static void conf_save(void)
set_config_filename(dialog_input_result); set_config_filename(dialog_input_result);
return; return;
} }
btn_dialog(main_window, _("Can't create file! " btn_dialog(main_window, "Can't create file! "
"Probably a nonexistent directory."), "Probably a nonexistent directory.",
1, "<OK>"); 1, "<OK>");
break; break;
case 1: case 1:
show_scroll_win(main_window, show_scroll_win(main_window,
_("Save Alternate Configuration"), "Save Alternate Configuration",
save_config_help); save_config_help);
break; break;
case KEY_EXIT: case KEY_EXIT:
@ -1483,10 +1483,6 @@ int main(int ac, char **av)
int lines, columns; int lines, columns;
char *mode; char *mode;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
if (ac > 1 && strcmp(av[1], "-s") == 0) { if (ac > 1 && strcmp(av[1], "-s") == 0) {
/* Silence conf_read() until the real callback is set up */ /* Silence conf_read() until the real callback is set up */
conf_set_message_callback(NULL); conf_set_message_callback(NULL);
@ -1544,8 +1540,8 @@ int main(int ac, char **av)
/* check for KEY_FUNC(1) */ /* check for KEY_FUNC(1) */
if (has_key(KEY_F(1)) == FALSE) { if (has_key(KEY_F(1)) == FALSE) {
show_scroll_win(main_window, show_scroll_win(main_window,
_("Instructions"), "Instructions",
_(menu_no_f_instructions)); menu_no_f_instructions);
} }
conf_set_message_callback(conf_message_callback); conf_set_message_callback(conf_message_callback);

View File

@ -14,7 +14,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <locale.h>
#include <ncurses.h> #include <ncurses.h>
#include <menu.h> #include <menu.h>
#include <panel.h> #include <panel.h>

572
kconfig/preprocess.c Normal file
View File

@ -0,0 +1,572 @@
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
static char *expand_string_with_args(const char *in, int argc, char *argv[]);
static void __attribute__((noreturn)) pperror(const char *format, ...)
{
va_list ap;
fprintf(stderr, "%s:%d: ", current_file->name, yylineno);
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fprintf(stderr, "\n");
exit(1);
}
/*
* Environment variables
*/
static LIST_HEAD(env_list);
struct env {
char *name;
char *value;
struct list_head node;
};
static void env_add(const char *name, const char *value)
{
struct env *e;
e = xmalloc(sizeof(*e));
e->name = xstrdup(name);
e->value = xstrdup(value);
list_add_tail(&e->node, &env_list);
}
static void env_del(struct env *e)
{
list_del(&e->node);
free(e->name);
free(e->value);
free(e);
}
/* The returned pointer must be freed when done */
static char *env_expand(const char *name)
{
struct env *e;
const char *value;
if (!*name)
return NULL;
list_for_each_entry(e, &env_list, node) {
if (!strcmp(name, e->name))
return xstrdup(e->value);
}
value = getenv(name);
if (!value)
return NULL;
/*
* We need to remember all referenced environment variables.
* They will be written out to include/config/auto.conf.cmd
*/
env_add(name, value);
return xstrdup(value);
}
void env_write_dep(FILE *f, const char *autoconfig_name)
{
struct env *e, *tmp;
list_for_each_entry_safe(e, tmp, &env_list, node) {
fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value);
fprintf(f, "%s: FORCE\n", autoconfig_name);
fprintf(f, "endif\n");
env_del(e);
}
}
/*
* Built-in functions
*/
struct function {
const char *name;
unsigned int min_args;
unsigned int max_args;
char *(*func)(int argc, char *argv[]);
};
static char *do_error_if(int argc, char *argv[])
{
if (!strcmp(argv[0], "y"))
pperror("%s", argv[1]);
return NULL;
}
static char *do_filename(int argc, char *argv[])
{
return xstrdup(current_file->name);
}
static char *do_info(int argc, char *argv[])
{
printf("%s\n", argv[0]);
return xstrdup("");
}
static char *do_lineno(int argc, char *argv[])
{
char buf[16];
sprintf(buf, "%d", yylineno);
return xstrdup(buf);
}
static char *do_shell(int argc, char *argv[])
{
FILE *p;
char buf[256];
char *cmd;
size_t nread;
int i;
cmd = argv[0];
p = popen(cmd, "r");
if (!p) {
perror(cmd);
exit(1);
}
nread = fread(buf, 1, sizeof(buf), p);
if (nread == sizeof(buf))
nread--;
/* remove trailing new lines */
while (nread > 0 && buf[nread - 1] == '\n')
nread--;
buf[nread] = 0;
/* replace a new line with a space */
for (i = 0; i < nread; i++) {
if (buf[i] == '\n')
buf[i] = ' ';
}
if (pclose(p) == -1) {
perror(cmd);
exit(1);
}
return xstrdup(buf);
}
static char *do_warning_if(int argc, char *argv[])
{
if (!strcmp(argv[0], "y"))
fprintf(stderr, "%s:%d: %s\n",
current_file->name, yylineno, argv[1]);
return xstrdup("");
}
static const struct function function_table[] = {
/* Name MIN MAX Function */
{ "error-if", 2, 2, do_error_if },
{ "filename", 0, 0, do_filename },
{ "info", 1, 1, do_info },
{ "lineno", 0, 0, do_lineno },
{ "shell", 1, 1, do_shell },
{ "warning-if", 2, 2, do_warning_if },
};
#define FUNCTION_MAX_ARGS 16
static char *function_expand(const char *name, int argc, char *argv[])
{
const struct function *f;
int i;
for (i = 0; i < ARRAY_SIZE(function_table); i++) {
f = &function_table[i];
if (strcmp(f->name, name))
continue;
if (argc < f->min_args)
pperror("too few function arguments passed to '%s'",
name);
if (argc > f->max_args)
pperror("too many function arguments passed to '%s'",
name);
return f->func(argc, argv);
}
return NULL;
}
/*
* Variables (and user-defined functions)
*/
static LIST_HEAD(variable_list);
struct variable {
char *name;
char *value;
enum variable_flavor flavor;
int exp_count;
struct list_head node;
};
static struct variable *variable_lookup(const char *name)
{
struct variable *v;
list_for_each_entry(v, &variable_list, node) {
if (!strcmp(name, v->name))
return v;
}
return NULL;
}
static char *variable_expand(const char *name, int argc, char *argv[])
{
struct variable *v;
char *res;
v = variable_lookup(name);
if (!v)
return NULL;
if (argc == 0 && v->exp_count)
pperror("Recursive variable '%s' references itself (eventually)",
name);
if (v->exp_count > 1000)
pperror("Too deep recursive expansion");
v->exp_count++;
if (v->flavor == VAR_RECURSIVE)
res = expand_string_with_args(v->value, argc, argv);
else
res = xstrdup(v->value);
v->exp_count--;
return res;
}
void variable_add(const char *name, const char *value,
enum variable_flavor flavor)
{
struct variable *v;
char *new_value;
bool append = false;
v = variable_lookup(name);
if (v) {
/* For defined variables, += inherits the existing flavor */
if (flavor == VAR_APPEND) {
flavor = v->flavor;
append = true;
} else {
free(v->value);
}
} else {
/* For undefined variables, += assumes the recursive flavor */
if (flavor == VAR_APPEND)
flavor = VAR_RECURSIVE;
v = xmalloc(sizeof(*v));
v->name = xstrdup(name);
v->exp_count = 0;
list_add_tail(&v->node, &variable_list);
}
v->flavor = flavor;
if (flavor == VAR_SIMPLE)
new_value = expand_string(value);
else
new_value = xstrdup(value);
if (append) {
v->value = xrealloc(v->value,
strlen(v->value) + strlen(new_value) + 2);
strcat(v->value, " ");
strcat(v->value, new_value);
free(new_value);
} else {
v->value = new_value;
}
}
static void variable_del(struct variable *v)
{
list_del(&v->node);
free(v->name);
free(v->value);
free(v);
}
void variable_all_del(void)
{
struct variable *v, *tmp;
list_for_each_entry_safe(v, tmp, &variable_list, node)
variable_del(v);
}
/*
* Evaluate a clause with arguments. argc/argv are arguments from the upper
* function call.
*
* Returned string must be freed when done
*/
static char *eval_clause(const char *str, size_t len, int argc, char *argv[])
{
char *tmp, *name, *res, *endptr, *prev, *p;
int new_argc = 0;
char *new_argv[FUNCTION_MAX_ARGS];
int nest = 0;
int i;
unsigned long n;
tmp = xstrndup(str, len);
/*
* If variable name is '1', '2', etc. It is generally an argument
* from a user-function call (i.e. local-scope variable). If not
* available, then look-up global-scope variables.
*/
n = strtoul(tmp, &endptr, 10);
if (!*endptr && n > 0 && n <= argc) {
res = xstrdup(argv[n - 1]);
goto free_tmp;
}
prev = p = tmp;
/*
* Split into tokens
* The function name and arguments are separated by a comma.
* For example, if the function call is like this:
* $(foo,$(x),$(y))
*
* The input string for this helper should be:
* foo,$(x),$(y)
*
* and split into:
* new_argv[0] = 'foo'
* new_argv[1] = '$(x)'
* new_argv[2] = '$(y)'
*/
while (*p) {
if (nest == 0 && *p == ',') {
*p = 0;
if (new_argc >= FUNCTION_MAX_ARGS)
pperror("too many function arguments");
new_argv[new_argc++] = prev;
prev = p + 1;
} else if (*p == '(') {
nest++;
} else if (*p == ')') {
nest--;
}
p++;
}
new_argv[new_argc++] = prev;
/*
* Shift arguments
* new_argv[0] represents a function name or a variable name. Put it
* into 'name', then shift the rest of the arguments. This simplifies
* 'const' handling.
*/
name = expand_string_with_args(new_argv[0], argc, argv);
new_argc--;
for (i = 0; i < new_argc; i++)
new_argv[i] = expand_string_with_args(new_argv[i + 1],
argc, argv);
/* Search for variables */
res = variable_expand(name, new_argc, new_argv);
if (res)
goto free;
/* Look for built-in functions */
res = function_expand(name, new_argc, new_argv);
if (res)
goto free;
/* Last, try environment variable */
if (new_argc == 0) {
res = env_expand(name);
if (res)
goto free;
}
res = xstrdup("");
free:
for (i = 0; i < new_argc; i++)
free(new_argv[i]);
free(name);
free_tmp:
free(tmp);
return res;
}
/*
* Expand a string that follows '$'
*
* For example, if the input string is
* ($(FOO)$($(BAR)))$(BAZ)
* this helper evaluates
* $($(FOO)$($(BAR)))
* and returns a new string containing the expansion (note that the string is
* recursively expanded), also advancing 'str' to point to the next character
* after the corresponding closing parenthesis, in this case, *str will be
* $(BAR)
*/
static char *expand_dollar_with_args(const char **str, int argc, char *argv[])
{
const char *p = *str;
const char *q;
int nest = 0;
/*
* In Kconfig, variable/function references always start with "$(".
* Neither single-letter variables as in $A nor curly braces as in ${CC}
* are supported. '$' not followed by '(' loses its special meaning.
*/
if (*p != '(') {
*str = p;
return xstrdup("$");
}
p++;
q = p;
while (*q) {
if (*q == '(') {
nest++;
} else if (*q == ')') {
if (nest-- == 0)
break;
}
q++;
}
if (!*q)
pperror("unterminated reference to '%s': missing ')'", p);
/* Advance 'str' to after the expanded initial portion of the string */
*str = q + 1;
return eval_clause(p, q - p, argc, argv);
}
char *expand_dollar(const char **str)
{
return expand_dollar_with_args(str, 0, NULL);
}
static char *__expand_string(const char **str, bool (*is_end)(char c),
int argc, char *argv[])
{
const char *in, *p;
char *expansion, *out;
size_t in_len, out_len;
out = xmalloc(1);
*out = 0;
out_len = 1;
p = in = *str;
while (1) {
if (*p == '$') {
in_len = p - in;
p++;
expansion = expand_dollar_with_args(&p, argc, argv);
out_len += in_len + strlen(expansion);
out = xrealloc(out, out_len);
strncat(out, in, in_len);
strcat(out, expansion);
free(expansion);
in = p;
continue;
}
if (is_end(*p))
break;
p++;
}
in_len = p - in;
out_len += in_len;
out = xrealloc(out, out_len);
strncat(out, in, in_len);
/* Advance 'str' to the end character */
*str = p;
return out;
}
static bool is_end_of_str(char c)
{
return !c;
}
/*
* Expand variables and functions in the given string. Undefined variables
* expand to an empty string.
* The returned string must be freed when done.
*/
static char *expand_string_with_args(const char *in, int argc, char *argv[])
{
return __expand_string(&in, is_end_of_str, argc, argv);
}
char *expand_string(const char *in)
{
return expand_string_with_args(in, 0, NULL);
}
static bool is_end_of_token(char c)
{
/* Why are '.' and '/' valid characters for symbols? */
return !(isalnum(c) || c == '_' || c == '-' || c == '.' || c == '/');
}
/*
* Expand variables in a token. The parsing stops when a token separater
* (in most cases, it is a whitespace) is encountered. 'str' is updated to
* point to the next character.
*
* The returned string must be freed when done.
*/
char *expand_one_token(const char **str)
{
return __expand_string(str, is_end_of_token, 0, NULL);
}

View File

@ -33,33 +33,6 @@ struct symbol *sym_defconfig_list;
struct symbol *modules_sym; struct symbol *modules_sym;
tristate modules_val; tristate modules_val;
struct expr *sym_env_list;
static void sym_add_default(struct symbol *sym, const char *def)
{
struct property *prop = prop_alloc(P_DEFAULT, sym);
prop->expr = expr_alloc_symbol(sym_lookup(def, SYMBOL_CONST));
}
void sym_init(void)
{
struct symbol *sym;
struct utsname uts;
static bool inited = false;
if (inited)
return;
inited = true;
uname(&uts);
sym = sym_lookup("UNAME_RELEASE", 0);
sym->type = S_STRING;
sym->flags |= SYMBOL_AUTO;
sym_add_default(sym, uts.release);
}
enum symbol_type sym_get_type(struct symbol *sym) enum symbol_type sym_get_type(struct symbol *sym)
{ {
enum symbol_type type = sym->type; enum symbol_type type = sym->type;
@ -906,59 +879,6 @@ struct symbol *sym_find(const char *name)
return symbol; return symbol;
} }
/*
* Expand symbol's names embedded in the string given in argument. Symbols'
* name to be expanded shall be prefixed by a '$'. Unknown symbol expands to
* the empty string.
*/
char *sym_expand_string_value(const char *in)
{
const char *src;
char *res;
size_t reslen;
/*
* Note: 'in' might come from a token that's about to be
* freed, so make sure to always allocate a new string
*/
reslen = strlen(in) + 1;
res = xmalloc(reslen);
res[0] = '\0';
while ((src = strchr(in, '$'))) {
char *p, name[SYMBOL_MAXLENGTH];
const char *symval = "";
struct symbol *sym;
size_t newlen;
strncat(res, in, src - in);
src++;
p = name;
while (isalnum(*src) || *src == '_')
*p++ = *src++;
*p = '\0';
sym = sym_find(name);
if (sym != NULL) {
sym_calc_value(sym);
symval = sym_get_string_value(sym);
}
newlen = strlen(res) + strlen(symval) + strlen(src) + 1;
if (newlen > reslen) {
reslen = newlen;
res = xrealloc(res, reslen);
}
strcat(res, symval);
in = src;
}
strcat(res, in);
return res;
}
const char *sym_escape_string_value(const char *in) const char *sym_escape_string_value(const char *in)
{ {
const char *p; const char *p;
@ -1401,32 +1321,3 @@ const char *prop_get_type_name(enum prop_type type)
} }
return "unknown"; return "unknown";
} }
static void prop_add_env(const char *env)
{
struct symbol *sym, *sym2;
struct property *prop;
char *p;
sym = current_entry->sym;
sym->flags |= SYMBOL_AUTO;
for_all_properties(sym, prop, P_ENV) {
sym2 = prop_get_symbol(prop);
if (strcmp(sym2->name, env))
menu_warn(current_entry, "redefining environment symbol from %s",
sym2->name);
return;
}
prop = prop_alloc(P_ENV, sym);
prop->expr = expr_alloc_symbol(sym_lookup(env, SYMBOL_CONST));
sym_env_list = expr_alloc_one(E_LIST, sym_env_list);
sym_env_list->right.sym = sym;
p = getenv(env);
if (p)
sym_add_default(sym, p);
else
menu_warn(current_entry, "environment variable %s undefined", env);
}

View File

@ -14,18 +14,16 @@
struct file *file_lookup(const char *name) struct file *file_lookup(const char *name)
{ {
struct file *file; struct file *file;
char *file_name = sym_expand_string_value(name);
for (file = file_list; file; file = file->next) { for (file = file_list; file; file = file->next) {
if (!strcmp(name, file->name)) { if (!strcmp(name, file->name)) {
free(file_name);
return file; return file;
} }
} }
file = xmalloc(sizeof(*file)); file = xmalloc(sizeof(*file));
memset(file, 0, sizeof(*file)); memset(file, 0, sizeof(*file));
file->name = file_name; file->name = xstrdup(name);
file->next = file_list; file->next = file_list;
file_list = file; file_list = file;
return file; return file;
@ -34,8 +32,6 @@ struct file *file_lookup(const char *name)
/* write a dependency file as used by kbuild to track dependencies */ /* write a dependency file as used by kbuild to track dependencies */
int file_write_dep(const char *name) int file_write_dep(const char *name)
{ {
struct symbol *sym, *env_sym;
struct expr *e;
struct file *file; struct file *file;
FILE *out; FILE *out;
@ -54,21 +50,7 @@ int file_write_dep(const char *name)
fprintf(out, "\n%s: \\\n" fprintf(out, "\n%s: \\\n"
"\t$(deps_config)\n\n", conf_get_autoconfig_name()); "\t$(deps_config)\n\n", conf_get_autoconfig_name());
expr_list_for_each_sym(sym_env_list, e, sym) { env_write_dep(out, conf_get_autoconfig_name());
struct property *prop;
const char *value;
prop = sym_get_env_prop(sym);
env_sym = prop_get_symbol(prop);
if (!env_sym)
continue;
value = getenv(env_sym->name);
if (!value)
value = "";
fprintf(out, "ifneq \"$(%s)\" \"%s\"\n", env_sym->name, value);
fprintf(out, "%s: FORCE\n", conf_get_autoconfig_name());
fprintf(out, "endif\n");
}
fprintf(out, "\n$(deps_config): ;\n"); fprintf(out, "\n$(deps_config): ;\n");
fclose(out); fclose(out);
@ -165,3 +147,14 @@ char *xstrdup(const char *s)
fprintf(stderr, "Out of memory.\n"); fprintf(stderr, "Out of memory.\n");
exit(1); exit(1);
} }
char *xstrndup(const char *s, size_t n)
{
char *p;
p = strndup(s, n);
if (p)
return p;
fprintf(stderr, "Out of memory.\n");
exit(1);
}

View File

@ -1,13 +1,13 @@
%option nostdinit noyywrap never-interactive full ecs %option nostdinit noyywrap never-interactive full ecs
%option 8bit nodefault yylineno %option 8bit nodefault yylineno
%option noinput %x COMMAND HELP STRING PARAM ASSIGN_VAL
%x COMMAND HELP STRING PARAM
%{ %{
/* /*
* Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
* Released under the terms of the GNU GPL v2.0. * Released under the terms of the GNU GPL v2.0.
*/ */
#include <assert.h>
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -35,6 +35,8 @@ struct buffer *current_buf;
static int last_ts, first_ts; static int last_ts, first_ts;
static char *expand_token(const char *in, size_t n);
static void append_expanded_string(const char *in);
static void zconf_endhelp(void); static void zconf_endhelp(void);
static void zconf_endfile(void); static void zconf_endfile(void);
@ -101,17 +103,28 @@ n [A-Za-z0-9_-]
<COMMAND>{ <COMMAND>{
{n}+ { {n}+ {
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng); const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
BEGIN(PARAM);
current_pos.file = current_file; current_pos.file = current_file;
current_pos.lineno = yylineno; current_pos.lineno = yylineno;
if (id && id->flags & TF_COMMAND) { if (id && id->flags & TF_COMMAND) {
BEGIN(PARAM);
yylval.id = id; yylval.id = id;
return id->token; return id->token;
} }
alloc_string(yytext, yyleng); alloc_string(yytext, yyleng);
yylval.string = text; yylval.string = text;
return T_WORD; return T_VARIABLE;
} }
({n}|$)+ {
/* this token includes at least one '$' */
yylval.string = expand_token(yytext, yyleng);
if (strlen(yylval.string))
return T_VARIABLE;
free(yylval.string);
}
"=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_RECURSIVE; return T_ASSIGN; }
":=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_SIMPLE; return T_ASSIGN; }
"+=" { BEGIN(ASSIGN_VAL); yylval.flavor = VAR_APPEND; return T_ASSIGN; }
[[:blank:]]+
. warn_ignored_character(*yytext); . warn_ignored_character(*yytext);
\n { \n {
BEGIN(INITIAL); BEGIN(INITIAL);
@ -119,6 +132,16 @@ n [A-Za-z0-9_-]
} }
} }
<ASSIGN_VAL>{
[^[:blank:]\n]+.* {
alloc_string(yytext, yyleng);
yylval.string = text;
return T_ASSIGN_VAL;
}
\n { BEGIN(INITIAL); return T_EOL; }
.
}
<PARAM>{ <PARAM>{
"&&" return T_AND; "&&" return T_AND;
"||" return T_OR; "||" return T_OR;
@ -147,6 +170,13 @@ n [A-Za-z0-9_-]
yylval.string = text; yylval.string = text;
return T_WORD; return T_WORD;
} }
({n}|[/.$])+ {
/* this token includes at least one '$' */
yylval.string = expand_token(yytext, yyleng);
if (strlen(yylval.string))
return T_WORD;
free(yylval.string);
}
#.* /* comment */ #.* /* comment */
\\\n ; \\\n ;
[[:blank:]]+ [[:blank:]]+
@ -157,12 +187,13 @@ n [A-Za-z0-9_-]
} }
<STRING>{ <STRING>{
[^'"\\\n]+/\n { "$".* append_expanded_string(yytext);
[^$'"\\\n]+/\n {
append_string(yytext, yyleng); append_string(yytext, yyleng);
yylval.string = text; yylval.string = text;
return T_WORD_QUOTE; return T_WORD_QUOTE;
} }
[^'"\\\n]+ { [^$'"\\\n]+ {
append_string(yytext, yyleng); append_string(yytext, yyleng);
} }
\\.?/\n { \\.?/\n {
@ -249,6 +280,58 @@ n [A-Za-z0-9_-]
} }
%% %%
static char *expand_token(const char *in, size_t n)
{
char *out;
int c;
char c2;
const char *rest, *end;
new_string();
append_string(in, n);
/* get the whole line because we do not know the end of token. */
while ((c = input()) != EOF) {
if (c == '\n') {
unput(c);
break;
}
c2 = c;
append_string(&c2, 1);
}
rest = text;
out = expand_one_token(&rest);
/* push back unused characters to the input stream */
end = rest + strlen(rest);
while (end > rest)
unput(*--end);
free(text);
return out;
}
static void append_expanded_string(const char *str)
{
const char *end;
char *res;
str++;
res = expand_dollar(&str);
/* push back unused characters to the input stream */
end = str + strlen(str);
while (end > str)
unput(*--end);
append_string(res, strlen(res));
free(res);
}
void zconf_starthelp(void) void zconf_starthelp(void)
{ {
new_string(); new_string();

View File

@ -31,7 +31,7 @@ struct symbol *symbol_hash[SYMBOL_HASHSIZE];
static struct menu *current_menu, *current_entry; static struct menu *current_menu, *current_entry;
%} %}
%expect 32 %expect 31
%union %union
{ {
@ -41,6 +41,7 @@ static struct menu *current_menu, *current_entry;
struct expr *expr; struct expr *expr;
struct menu *menu; struct menu *menu;
const struct kconf_id *id; const struct kconf_id *id;
enum variable_flavor flavor;
} }
%token <id>T_MAINMENU %token <id>T_MAINMENU
@ -77,6 +78,9 @@ static struct menu *current_menu, *current_entry;
%token T_CLOSE_PAREN %token T_CLOSE_PAREN
%token T_OPEN_PAREN %token T_OPEN_PAREN
%token T_EOL %token T_EOL
%token <string> T_VARIABLE
%token <flavor> T_ASSIGN
%token <string> T_ASSIGN_VAL
%left T_OR %left T_OR
%left T_AND %left T_AND
@ -92,7 +96,7 @@ static struct menu *current_menu, *current_entry;
%type <id> end %type <id> end
%type <id> option_name %type <id> option_name
%type <menu> if_entry menu_entry choice_entry %type <menu> if_entry menu_entry choice_entry
%type <string> symbol_option_arg word_opt %type <string> symbol_option_arg word_opt assign_val
%destructor { %destructor {
fprintf(stderr, "%s:%d: missing end statement for this entry\n", fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@ -109,7 +113,7 @@ static struct menu *current_menu, *current_entry;
%% %%
input: nl start | start; input: nl start | start;
start: mainmenu_stmt stmt_list | no_mainmenu_stmt stmt_list; start: mainmenu_stmt stmt_list | stmt_list;
/* mainmenu entry */ /* mainmenu entry */
@ -118,19 +122,6 @@ mainmenu_stmt: T_MAINMENU prompt nl
menu_add_prompt(P_MENU, $2, NULL); menu_add_prompt(P_MENU, $2, NULL);
}; };
/* Default main menu, if there's no mainmenu entry */
no_mainmenu_stmt: /* empty */
{
/*
* Hack: Keep the main menu title on the heap so we can safely free it
* later regardless of whether it comes from the 'prompt' in
* mainmenu_stmt or here
*/
menu_add_prompt(P_MENU, xstrdup("Linux Kernel Configuration"), NULL);
};
stmt_list: stmt_list:
/* empty */ /* empty */
| stmt_list common_stmt | stmt_list common_stmt
@ -156,6 +147,7 @@ common_stmt:
| config_stmt | config_stmt
| menuconfig_stmt | menuconfig_stmt
| source_stmt | source_stmt
| assignment_stmt
; ;
option_error: option_error:
@ -345,7 +337,7 @@ choice_block:
/* if entry */ /* if entry */
if_entry: T_IF expr nl if_entry: T_IF expr T_EOL
{ {
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
menu_add_entry(NULL); menu_add_entry(NULL);
@ -524,33 +516,43 @@ symbol: nonconst_symbol
word_opt: /* empty */ { $$ = NULL; } word_opt: /* empty */ { $$ = NULL; }
| T_WORD | T_WORD
/* assignment statement */
assignment_stmt: T_VARIABLE T_ASSIGN assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); }
assign_val:
/* empty */ { $$ = xstrdup(""); };
| T_ASSIGN_VAL
;
%% %%
void conf_parse(const char *name) void conf_parse(const char *name)
{ {
const char *tmp;
struct symbol *sym; struct symbol *sym;
int i; int i;
zconf_initscan(name); zconf_initscan(name);
sym_init();
_menu_init(); _menu_init();
#if YYDEBUG #if YYDEBUG
if (getenv("ZCONF_DEBUG")) if (getenv("ZCONF_DEBUG"))
yydebug = 1; yydebug = 1;
#endif #endif
yyparse(); yyparse();
/* Variables are expanded in the parse phase. We can free them here. */
variable_all_del();
if (yynerrs) if (yynerrs)
exit(1); exit(1);
if (!modules_sym) if (!modules_sym)
modules_sym = sym_find( "n" ); modules_sym = sym_find( "n" );
tmp = rootmenu.prompt->text; if (!menu_has_prompt(&rootmenu)) {
rootmenu.prompt->text = _(rootmenu.prompt->text); current_entry = &rootmenu;
rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text); menu_add_prompt(P_MENU, "Main menu", NULL);
free((char*)tmp); }
menu_finalize(&rootmenu); menu_finalize(&rootmenu);
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
@ -716,6 +718,10 @@ static void print_symbol(FILE *out, struct menu *menu)
print_quoted_string(out, prop->text); print_quoted_string(out, prop->text);
fputc('\n', out); fputc('\n', out);
break; break;
case P_SYMBOL:
fputs( " symbol ", out);
fprintf(out, "%s\n", prop->sym->name);
break;
default: default:
fprintf(out, " unknown prop %d!\n", prop->type); fprintf(out, " unknown prop %d!\n", prop->type);
break; break;
@ -782,3 +788,4 @@ void zconfdump(FILE *out)
#include "expr.c" #include "expr.c"
#include "symbol.c" #include "symbol.c"
#include "menu.c" #include "menu.c"
#include "preprocess.c"