Updated to match trunk/uClibc/extra/config as of r10132, and thus Linux 2.6.11.
No binary (build failed)
—
(log yok)
| @@ -9,7 +9,11 @@ include $(top_builddir)/Rules.mak | |
| all: ncurses conf mconf | |
| + | ifeq ($(shell uname),SunOS) |
| + | LIBS = -lcurses |
| + | else |
| LIBS = -lncurses | |
| + | endif |
| ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h)) | |
| HOSTNCURSES += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>" | |
| else | |
| @@ -32,14 +36,17 @@ endif | |
| endif | |
| endif | |
| - | CONF_SRC =conf.c |
| - | MCONF_SRC =mconf.c checklist.c menubox.c textbox.c yesno.c inputbox.c util.c msgbox.c |
| - | SHARED_SRC=zconf.tab.c |
| - | SHARED_DEPS:=$(srcdir)/lkc.h $(srcdir)/lkc_proto.h \ |
| - | lkc_defs.h $(srcdir)/expr.h zconf.tab.h |
| - | CONF_OBJS =$(patsubst %.c,%.o, $(CONF_SRC)) |
| - | MCONF_OBJS=$(patsubst %.c,%.o, $(MCONF_SRC)) |
| - | SHARED_OBJS=$(patsubst %.c,%.o, $(SHARED_SRC)) |
| + | CONF_SRC = conf.c |
| + | MCONF_SRC = mconf.c |
| + | LXD_SRC = lxdialog/checklist.c lxdialog/menubox.c lxdialog/textbox.c \ |
| + | lxdialog/yesno.c lxdialog/inputbox.c lxdialog/util.c \ |
| + | lxdialog/msgbox.c |
| + | SHARED_SRC = zconf.tab.c |
| + | SHARED_DEPS := $(srcdir)/lkc.h $(srcdir)/lkc_proto.h \ |
| + | lkc_defs.h $(srcdir)/expr.h zconf.tab.h |
| + | CONF_OBJS = $(patsubst %.c,%.o, $(CONF_SRC)) |
| + | MCONF_OBJS = $(patsubst %.c,%.o, $(MCONF_SRC) $(LXD_SRC)) |
| + | SHARED_OBJS = $(patsubst %.c,%.o, $(SHARED_SRC)) |
| conf: $(CONF_OBJS) $(SHARED_OBJS) | |
| $(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@ | |
| @@ -31,14 +31,14 @@ char *defconfig_file; | |
| static int indent = 1; | |
| static int valid_stdin = 1; | |
| static int conf_cnt; | |
| - | static char line[128]; |
| + | static signed char line[128]; |
| static struct menu *rootEntry; | |
| static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; | |
| - | static void strip(char *str) |
| + | static void strip(signed char *str) |
| { | |
| - | char *p = str; |
| + | signed char *p = str; |
| int l; | |
| while ((isspace(*p))) | |
| @@ -23,10 +23,10 @@ const char *conf_confnames[] = { | |
| NULL, | |
| }; | |
| - | static char *conf_expand_value(const char *in) |
| + | static char *conf_expand_value(const signed char *in) |
| { | |
| struct symbol *sym; | |
| - | const char *src; |
| + | const signed char *src; |
| static char res_value[SYMBOL_MAXLENGTH]; | |
| char *dst, name[SYMBOL_MAXLENGTH]; | |
| @@ -287,7 +287,7 @@ int conf_write(const char *name) | |
| } else | |
| basename = conf_def_filename; | |
| - | sprintf(newname, "%s.tmpconfig.%d", dirname, getpid()); |
| + | sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid()); |
| out = fopen(newname, "w"); | |
| if (!out) | |
| return 1; | |
| @@ -1087,3 +1087,13 @@ void expr_fprint(struct expr *e, FILE *out) | |
| { | |
| expr_print(e, expr_print_file_helper, out, E_NONE); | |
| } | |
| + | |
| + | static void expr_print_gstr_helper(void *data, const char *str) |
| + | { |
| + | str_append((struct gstr*)data, str); |
| + | } |
| + | |
| + | void expr_gstr_print(struct expr *e, struct gstr *gs) |
| + | { |
| + | expr_print(e, expr_print_gstr_helper, gs, E_NONE); |
| + | } |
| @@ -174,6 +174,8 @@ void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, s | |
| struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); | |
| void expr_fprint(struct expr *e, FILE *out); | |
| + | struct gstr; /* forward */ |
| + | void expr_gstr_print(struct expr *e, struct gstr *gs); |
| static inline int expr_is_yes(struct expr *e) | |
| { | |
| @@ -56,11 +56,21 @@ void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); | |
| void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); | |
| void menu_finalize(struct menu *parent); | |
| void menu_set_type(int type); | |
| + | |
| + | /* util.c */ |
| struct file *file_lookup(const char *name); | |
| int file_write_dep(const char *name); | |
| - | extern struct menu *current_entry; |
| - | extern struct menu *current_menu; |
| + | struct gstr { |
| + | size_t len; |
| + | char *s; |
| + | }; |
| + | struct gstr str_new(void); |
| + | struct gstr str_assign(const char *s); |
| + | void str_free(struct gstr *gs); |
| + | void str_append(struct gstr *gs, const char *s); |
| + | void str_printf(struct gstr *gs, const char *fmt, ...); |
| + | const char *str_get(struct gstr *gs); |
| /* symbol.c */ | |
| void sym_init(void); | |
| @@ -18,6 +18,7 @@ P(sym_change_count,int,); | |
| P(sym_lookup,struct symbol *,(const char *name, int isconst)); | |
| P(sym_find,struct symbol *,(const char *name)); | |
| + | P(sym_re_search,struct symbol **,(const char *pattern)); |
| P(sym_type_name,const char *,(enum symbol_type type)); | |
| P(sym_calc_value,void,(struct symbol *sym)); | |
| P(sym_get_type,enum symbol_type,(struct symbol *sym)); | |
| @@ -0,0 +1,4 @@ | |
| + | This is NOT the official version of dialog. This version has been |
| + | significantly modified from the original. It is for use by the Linux |
| + | kernel configuration script. Please do not bother Savio Lam with |
| + | questions about this program. |
| @@ -120,7 +120,7 @@ int | |
| dialog_checklist (const char *title, const char *prompt, int height, int width, | |
| int list_height, int item_no, struct dialog_list_item ** items, | |
| int flag) | |
| - | |
| + | |
| { | |
| int i, x, y, box_x, box_y; | |
| int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; | |
| @@ -197,7 +197,7 @@ dialog_checklist (const char *title, const char *prompt, int height, int width, | |
| /* Find length of longest item in order to center checklist */ | |
| check_x = 0; | |
| - | for (i = 0; i < item_no; i++) |
| + | for (i = 0; i < item_no; i++) |
| check_x = MAX (check_x, + strlen (items[i]->name) + 4); | |
| check_x = (list_width - check_x) / 2; | |
| @@ -231,7 +231,7 @@ dialog_checklist (const char *title, const char *prompt, int height, int width, | |
| break; | |
| - | if ( i < max_choice || key == KEY_UP || key == KEY_DOWN || |
| + | if ( i < max_choice || key == KEY_UP || key == KEY_DOWN || |
| key == '+' || key == '-' ) { | |
| if (key == KEY_UP || key == '-') { | |
| if (!choice) { | |
| @@ -342,7 +342,7 @@ dialog_checklist (const char *title, const char *prompt, int height, int width, | |
| } | |
| wnoutrefresh (list); | |
| wrefresh (dialog); | |
| - | |
| + | |
| for (i = 0; i < item_no; i++) { | |
| items[i]->selected = status[i]; | |
| } | |
| @@ -364,7 +364,7 @@ dialog_checklist (const char *title, const char *prompt, int height, int width, | |
| /* Now, update everything... */ | |
| doupdate (); | |
| } | |
| - | |
| + | |
| delwin (dialog); | |
| free (status); | |
| @@ -27,6 +27,9 @@ | |
| #include <string.h> | |
| #ifdef CURSES_LOC | |
| + | #ifdef __sun__ |
| + | #define CURS_MACROS |
| + | #endif |
| #include CURSES_LOC | |
| /* | |
| @@ -86,7 +89,7 @@ | |
| #define ACS_DARROW 'v' | |
| #endif | |
| - | /* |
| + | /* |
| * Attribute names | |
| */ | |
| #define screen_attr attributes[0] | |
| @@ -130,7 +133,7 @@ extern bool use_colors; | |
| extern chtype attributes[]; | |
| #endif | |
| - | extern char *backtitle; |
| + | extern const char *backtitle; |
| struct dialog_list_item { | |
| char *name; | |
| @@ -162,7 +165,7 @@ int dialog_msgbox (const char *title, const char *prompt, int height, | |
| int width, int pause); | |
| int dialog_textbox (const char *title, const char *file, int height, int width); | |
| int dialog_menu (const char *title, const char *prompt, int height, int width, | |
| - | int menu_height, const char *choice, int item_no, |
| + | int menu_height, const char *choice, int item_no, |
| struct dialog_list_item ** items); | |
| int dialog_checklist (const char *title, const char *prompt, int height, | |
| int width, int list_height, int item_no, | |
| @@ -26,7 +26,7 @@ | |
| * | |
| * *) A bugfix for the Page-Down problem | |
| * | |
| - | * *) Formerly when I used Page Down and Page Up, the cursor would be set |
| + | * *) Formerly when I used Page Down and Page Up, the cursor would be set |
| * to the first position in the menu box. Now lxdialog is a bit | |
| * smarter and works more like other menu systems (just have a look at | |
| * it). | |
| @@ -71,7 +71,7 @@ print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey | |
| strncpy(menu_item, item, menu_width); | |
| menu_item[menu_width] = 0; | |
| - | j = first_alpha(menu_item, "YyNnMm"); |
| + | j = first_alpha(menu_item, "YyNnMmHh"); |
| /* Clear 'residue' of last item */ | |
| wattrset (win, menubox_attr); | |
| @@ -225,7 +225,7 @@ dialog_menu (const char *title, const char *prompt, int height, int width, | |
| /* | |
| * Find length of longest item in order to center menu. | |
| - | * Set 'choice' to default item. |
| + | * Set 'choice' to default item. |
| */ | |
| item_x = 0; | |
| for (i = 0; i < item_no; i++) { | |
| @@ -278,23 +278,23 @@ dialog_menu (const char *title, const char *prompt, int height, int width, | |
| if (key < 256 && isalpha(key)) key = tolower(key); | |
| - | if (strchr("ynm", key)) |
| + | if (strchr("ynmh", key)) |
| i = max_choice; | |
| else { | |
| for (i = choice+1; i < max_choice; i++) { | |
| - | j = first_alpha(items[scroll + i]->name, "YyNnMm>"); |
| + | j = first_alpha(items[scroll + i]->name, "YyNnMmHh"); |
| if (key == tolower(items[scroll + i]->name[j])) | |
| break; | |
| } | |
| if (i == max_choice) | |
| for (i = 0; i < max_choice; i++) { | |
| - | j = first_alpha(items[scroll + i]->name, "YyNnMm>"); |
| + | j = first_alpha(items[scroll + i]->name, "YyNnMmHh"); |
| if (key == tolower(items[scroll + i]->name[j])) | |
| break; | |
| } | |
| } | |
| - | if (i < max_choice || |
| + | if (i < max_choice || |
| key == KEY_UP || key == KEY_DOWN || | |
| key == '-' || key == '+' || | |
| key == KEY_PPAGE || key == KEY_NPAGE) { | |
| @@ -398,6 +398,7 @@ dialog_menu (const char *title, const char *prompt, int height, int width, | |
| case 'y': | |
| case 'n': | |
| case 'm': | |
| + | case '/': |
| /* save scroll info */ | |
| if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) { | |
| fprintf(f,"%d\n",scroll); | |
| @@ -411,6 +412,7 @@ dialog_menu (const char *title, const char *prompt, int height, int width, | |
| case 'n': return 4; | |
| case 'm': return 5; | |
| case ' ': return 6; | |
| + | case '/': return 7; |
| } | |
| return 0; | |
| case 'h': | |
| @@ -0,0 +1,375 @@ | |
| + | /* |
| + | * util.c |
| + | * |
| + | * ORIGINAL AUTHOR: Savio Lam ([email protected]) |
| + | * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap ([email protected]) |
| + | * |
| + | * This program is free software; you can redistribute it and/or |
| + | * modify it under the terms of the GNU General Public License |
| + | * as published by the Free Software Foundation; either version 2 |
| + | * of the License, or (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| + | */ |
| + | |
| + | #include "dialog.h" |
| + | |
| + | |
| + | /* use colors by default? */ |
| + | bool use_colors = 1; |
| + | |
| + | const char *backtitle = NULL; |
| + | |
| + | const char *dialog_result; |
| + | |
| + | /* |
| + | * Attribute values, default is for mono display |
| + | */ |
| + | chtype attributes[] = |
| + | { |
| + | A_NORMAL, /* screen_attr */ |
| + | A_NORMAL, /* shadow_attr */ |
| + | A_NORMAL, /* dialog_attr */ |
| + | A_BOLD, /* title_attr */ |
| + | A_NORMAL, /* border_attr */ |
| + | A_REVERSE, /* button_active_attr */ |
| + | A_DIM, /* button_inactive_attr */ |
| + | A_REVERSE, /* button_key_active_attr */ |
| + | A_BOLD, /* button_key_inactive_attr */ |
| + | A_REVERSE, /* button_label_active_attr */ |
| + | A_NORMAL, /* button_label_inactive_attr */ |
| + | A_NORMAL, /* inputbox_attr */ |
| + | A_NORMAL, /* inputbox_border_attr */ |
| + | A_NORMAL, /* searchbox_attr */ |
| + | A_BOLD, /* searchbox_title_attr */ |
| + | A_NORMAL, /* searchbox_border_attr */ |
| + | A_BOLD, /* position_indicator_attr */ |
| + | A_NORMAL, /* menubox_attr */ |
| + | A_NORMAL, /* menubox_border_attr */ |
| + | A_NORMAL, /* item_attr */ |
| + | A_REVERSE, /* item_selected_attr */ |
| + | A_BOLD, /* tag_attr */ |
| + | A_REVERSE, /* tag_selected_attr */ |
| + | A_BOLD, /* tag_key_attr */ |
| + | A_REVERSE, /* tag_key_selected_attr */ |
| + | A_BOLD, /* check_attr */ |
| + | A_REVERSE, /* check_selected_attr */ |
| + | A_BOLD, /* uarrow_attr */ |
| + | A_BOLD /* darrow_attr */ |
| + | }; |
| + | |
| + | |
| + | #include "colors.h" |
| + | |
| + | /* |
| + | * Table of color values |
| + | */ |
| + | int color_table[][3] = |
| + | { |
| + | {SCREEN_FG, SCREEN_BG, SCREEN_HL}, |
| + | {SHADOW_FG, SHADOW_BG, SHADOW_HL}, |
| + | {DIALOG_FG, DIALOG_BG, DIALOG_HL}, |
| + | {TITLE_FG, TITLE_BG, TITLE_HL}, |
| + | {BORDER_FG, BORDER_BG, BORDER_HL}, |
| + | {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL}, |
| + | {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL}, |
| + | {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL}, |
| + | {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL}, |
| + | {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL}, |
| + | {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG, |
| + | BUTTON_LABEL_INACTIVE_HL}, |
| + | {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL}, |
| + | {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL}, |
| + | {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL}, |
| + | {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL}, |
| + | {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL}, |
| + | {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL}, |
| + | {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL}, |
| + | {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL}, |
| + | {ITEM_FG, ITEM_BG, ITEM_HL}, |
| + | {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL}, |
| + | {TAG_FG, TAG_BG, TAG_HL}, |
| + | {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL}, |
| + | {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL}, |
| + | {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL}, |
| + | {CHECK_FG, CHECK_BG, CHECK_HL}, |
| + | {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL}, |
| + | {UARROW_FG, UARROW_BG, UARROW_HL}, |
| + | {DARROW_FG, DARROW_BG, DARROW_HL}, |
| + | }; /* color_table */ |
| + | |
| + | /* |
| + | * Set window to attribute 'attr' |
| + | */ |
| + | void |
| + | attr_clear (WINDOW * win, int height, int width, chtype attr) |
| + | { |
| + | int i, j; |
| + | |
| + | wattrset (win, attr); |
| + | for (i = 0; i < height; i++) { |
| + | wmove (win, i, 0); |
| + | for (j = 0; j < width; j++) |
| + | waddch (win, ' '); |
| + | } |
| + | touchwin (win); |
| + | } |
| + | |
| + | void dialog_clear (void) |
| + | { |
| + | attr_clear (stdscr, LINES, COLS, screen_attr); |
| + | /* Display background title if it exists ... - SLH */ |
| + | if (backtitle != NULL) { |
| + | int i; |
| + | |
| + | wattrset (stdscr, screen_attr); |
| + | mvwaddstr (stdscr, 0, 1, (char *)backtitle); |
| + | wmove (stdscr, 1, 1); |
| + | for (i = 1; i < COLS - 1; i++) |
| + | waddch (stdscr, ACS_HLINE); |
| + | } |
| + | wnoutrefresh (stdscr); |
| + | } |
| + | |
| + | /* |
| + | * Do some initialization for dialog |
| + | */ |
| + | void |
| + | init_dialog (void) |
| + | { |
| + | initscr (); /* Init curses */ |
| + | keypad (stdscr, TRUE); |
| + | cbreak (); |
| + | noecho (); |
| + | |
| + | |
| + | if (use_colors) /* Set up colors */ |
| + | color_setup (); |
| + | |
| + | |
| + | dialog_clear (); |
| + | } |
| + | |
| + | /* |
| + | * Setup for color display |
| + | */ |
| + | void |
| + | color_setup (void) |
| + | { |
| + | int i; |
| + | |
| + | if (has_colors ()) { /* Terminal supports color? */ |
| + | start_color (); |
| + | |
| + | /* Initialize color pairs */ |
| + | for (i = 0; i < ATTRIBUTE_COUNT; i++) |
| + | init_pair (i + 1, color_table[i][0], color_table[i][1]); |
| + | |
| + | /* Setup color attributes */ |
| + | for (i = 0; i < ATTRIBUTE_COUNT; i++) |
| + | attributes[i] = C_ATTR (color_table[i][2], i + 1); |
| + | } |
| + | } |
| + | |
| + | /* |
| + | * End using dialog functions. |
| + | */ |
| + | void |
| + | end_dialog (void) |
| + | { |
| + | endwin (); |
| + | } |
| + | |
| + | |
| + | /* |
| + | * Print a string of text in a window, automatically wrap around to the |
| + | * next line if the string is too long to fit on one line. Newline |
| + | * characters '\n' are replaced by spaces. We start on a new line |
| + | * if there is no room for at least 4 nonblanks following a double-space. |
| + | */ |
| + | void |
| + | print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x) |
| + | { |
| + | int newl, cur_x, cur_y; |
| + | int i, prompt_len, room, wlen; |
| + | char tempstr[MAX_LEN + 1], *word, *sp, *sp2; |
| + | |
| + | strcpy (tempstr, prompt); |
| + | |
| + | prompt_len = strlen(tempstr); |
| + | |
| + | /* |
| + | * Remove newlines |
| + | */ |
| + | for(i=0; i<prompt_len; i++) { |
| + | if(tempstr[i] == '\n') tempstr[i] = ' '; |
| + | } |
| + | |
| + | if (prompt_len <= width - x * 2) { /* If prompt is short */ |
| + | wmove (win, y, (width - prompt_len) / 2); |
| + | waddstr (win, tempstr); |
| + | } else { |
| + | cur_x = x; |
| + | cur_y = y; |
| + | newl = 1; |
| + | word = tempstr; |
| + | while (word && *word) { |
| + | sp = index(word, ' '); |
| + | if (sp) |
| + | *sp++ = 0; |
| + | |
| + | /* Wrap to next line if either the word does not fit, |
| + | or it is the first word of a new sentence, and it is |
| + | short, and the next word does not fit. */ |
| + | room = width - cur_x; |
| + | wlen = strlen(word); |
| + | if (wlen > room || |
| + | (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room |
| + | && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) { |
| + | cur_y++; |
| + | cur_x = x; |
| + | } |
| + | wmove (win, cur_y, cur_x); |
| + | waddstr (win, word); |
| + | getyx (win, cur_y, cur_x); |
| + | cur_x++; |
| + | if (sp && *sp == ' ') { |
| + | cur_x++; /* double space */ |
| + | while (*++sp == ' '); |
| + | newl = 1; |
| + | } else |
| + | newl = 0; |
| + | word = sp; |
| + | } |
| + | } |
| + | } |
| + | |
| + | /* |
| + | * Print a button |
| + | */ |
| + | void |
| + | print_button (WINDOW * win, const char *label, int y, int x, int selected) |
| + | { |
| + | int i, temp; |
| + | |
| + | wmove (win, y, x); |
| + | wattrset (win, selected ? button_active_attr : button_inactive_attr); |
| + | waddstr (win, "<"); |
| + | temp = strspn (label, " "); |
| + | label += temp; |
| + | wattrset (win, selected ? button_label_active_attr |
| + | : button_label_inactive_attr); |
| + | for (i = 0; i < temp; i++) |
| + | waddch (win, ' '); |
| + | wattrset (win, selected ? button_key_active_attr |
| + | : button_key_inactive_attr); |
| + | waddch (win, label[0]); |
| + | wattrset (win, selected ? button_label_active_attr |
| + | : button_label_inactive_attr); |
| + | waddstr (win, (char *)label + 1); |
| + | wattrset (win, selected ? button_active_attr : button_inactive_attr); |
| + | waddstr (win, ">"); |
| + | wmove (win, y, x + temp + 1); |
| + | } |
| + | |
| + | /* |
| + | * Draw a rectangular box with line drawing characters |
| + | */ |
| + | void |
| + | draw_box (WINDOW * win, int y, int x, int height, int width, |
| + | chtype box, chtype border) |
| + | { |
| + | int i, j; |
| + | |
| + | wattrset (win, 0); |
| + | for (i = 0; i < height; i++) { |
| + | wmove (win, y + i, x); |
| + | for (j = 0; j < width; j++) |
| + | if (!i && !j) |
| + | waddch (win, border | ACS_ULCORNER); |
| + | else if (i == height - 1 && !j) |
| + | waddch (win, border | ACS_LLCORNER); |
| + | else if (!i && j == width - 1) |
| + | waddch (win, box | ACS_URCORNER); |
| + | else if (i == height - 1 && j == width - 1) |
| + | waddch (win, box | ACS_LRCORNER); |
| + | else if (!i) |
| + | waddch (win, border | ACS_HLINE); |
| + | else if (i == height - 1) |
| + | waddch (win, box | ACS_HLINE); |
| + | else if (!j) |
| + | waddch (win, border | ACS_VLINE); |
| + | else if (j == width - 1) |
| + | waddch (win, box | ACS_VLINE); |
| + | else |
| + | waddch (win, box | ' '); |
| + | } |
| + | } |
| + | |
| + | /* |
| + | * Draw shadows along the right and bottom edge to give a more 3D look |
| + | * to the boxes |
| + | */ |
| + | void |
| + | draw_shadow (WINDOW * win, int y, int x, int height, int width) |
| + | { |
| + | int i; |
| + | |
| + | if (has_colors ()) { /* Whether terminal supports color? */ |
| + | wattrset (win, shadow_attr); |
| + | wmove (win, y + height, x + 2); |
| + | for (i = 0; i < width; i++) |
| + | waddch (win, winch (win) & A_CHARTEXT); |
| + | for (i = y + 1; i < y + height + 1; i++) { |
| + | wmove (win, i, x + width); |
| + | waddch (win, winch (win) & A_CHARTEXT); |
| + | waddch (win, winch (win) & A_CHARTEXT); |
| + | } |
| + | wnoutrefresh (win); |
| + | } |
| + | } |
| + | |
| + | /* |
| + | * Return the position of the first alphabetic character in a string. |
| + | */ |
| + | int |
| + | first_alpha(const char *string, const char *exempt) |
| + | { |
| + | int i, in_paren=0, c; |
| + | |
| + | for (i = 0; i < strlen(string); i++) { |
| + | c = tolower(string[i]); |
| + | |
| + | if (strchr("<[(", c)) ++in_paren; |
| + | if (strchr(">])", c) && in_paren > 0) --in_paren; |
| + | |
| + | if ((! in_paren) && isalpha(c) && |
| + | strchr(exempt, c) == 0) |
| + | return i; |
| + | } |
| + | |
| + | return 0; |
| + | } |
| + | |
| + | /* |
| + | * Get the first selected item in the dialog_list_item list. |
| + | */ |
| + | struct dialog_list_item * |
| + | first_sel_item(int item_no, struct dialog_list_item ** items) |
| + | { |
| + | int i; |
| + | |
| + | for (i = 0; i < item_no; i++) { |
| + | if (items[i]->selected) |
| + | return items[i]; |
| + | } |
| + | |
| + | return NULL; |
| + | } |
| @@ -23,18 +23,150 @@ | |
| #include <termios.h> | |
| #include <unistd.h> | |
| - | #include "dialog.h" |
| + | #include "lxdialog/dialog.h" |
| #define LKC_DIRECT_LINK | |
| #include "lkc.h" | |
| static char menu_backtitle[128]; | |
| - | static const char menu_instructions[] = |
| + | static const char mconf_readme[] = |
| + | "Overview\n" |
| + | "--------\n" |
| + | "Some features may be built directly into BusyBox. Some features\n" |
| + | "may be completely removed altogether. There are also certain\n" |
| + | "parameters which are not really features, but must be\n" |
| + | "entered in as decimal or hexadecimal numbers or possibly text.\n" |
| + | "\n" |
| + | "Menu items beginning with [*] or [ ] represent features\n" |
| + | "configured to be built in or removed respectively.\n" |
| + | "\n" |
| + | "To change any of these features, highlight it with the cursor\n" |
| + | "keys and press <Y> to build it in or <N> to removed it.\n" |
| + | "You may also press the <Space Bar> to cycle\n" |
| + | "through the available options (ie. Y->N->Y).\n" |
| + | "\n" |
| + | "Some additional keyboard hints:\n" |
| + | "\n" |
| + | "Menus\n" |
| + | "----------\n" |
| + | "o Use the Up/Down arrow keys (cursor keys) to highlight the item\n" |
| + | " you wish to change or submenu wish to select and press <Enter>.\n" |
| + | " Submenus are designated by \"--->\".\n" |
| + | "\n" |
| + | " Shortcut: Press the option's highlighted letter (hotkey).\n" |
| + | " Pressing a hotkey more than once will sequence\n" |
| + | " through all visible items which use that hotkey.\n" |
| + | "\n" |
| + | " You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" |
| + | " unseen options into view.\n" |
| + | "\n" |
| + | "o To exit a menu use the cursor keys to highlight the <Exit> button\n" |
| + | " and press <ENTER>.\n" |
| + | "\n" |
| + | " Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n" |
| + | " using those letters. You may press a single <ESC>, but\n" |
| + | " there is a delayed response which you may find annoying.\n" |
| + | "\n" |
| + | " Also, the <TAB> and cursor keys will cycle between <Select>,\n" |
| + | " <Exit> and <Help>\n" |
| + | "\n" |
| + | "o To get help with an item, use the cursor keys to highlight <Help>\n" |
| + | " and Press <ENTER>.\n" |
| + | "\n" |
| + | " Shortcut: Press <H> or <?>.\n" |
| + | "\n" |
| + | "\n" |
| + | "Radiolists (Choice lists)\n" |
| + | "-----------\n" |
| + | "o Use the cursor keys to select the option you wish to set and press\n" |
| + | " <S> or the <SPACE BAR>.\n" |
| + | "\n" |
| + | " Shortcut: Press the first letter of the option you wish to set then\n" |
| + | " press <S> or <SPACE BAR>.\n" |
| + | "\n" |
| + | "o To see available help for the item, use the cursor keys to highlight\n" |
| + | " <Help> and Press <ENTER>.\n" |
| + | "\n" |
| + | " Shortcut: Press <H> or <?>.\n" |
| + | "\n" |
| + | " Also, the <TAB> and cursor keys will cycle between <Select> and\n" |
| + | " <Help>\n" |
| + | "\n" |
| + | "\n" |
| + | "Data Entry\n" |
| + | "-----------\n" |
| + | "o Enter the requested information and press <ENTER>\n" |
| + | " If you are entering hexadecimal values, it is not necessary to\n" |
| + | " add the '0x' prefix to the entry.\n" |
| + | "\n" |
| + | "o For help, use the <TAB> or cursor keys to highlight the help option\n" |
| + | " and press <ENTER>. You can try <TAB><H> as well.\n" |
| + | "\n" |
| + | "\n" |
| + | "Text Box (Help Window)\n" |
| + | "--------\n" |
| + | "o Use the cursor keys to scroll up/down/left/right. The VI editor\n" |
| + | " keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n" |
| + | " who are familiar with less and lynx.\n" |
| + | "\n" |
| + | "o Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n" |
| + | "\n" |
| + | "\n" |
| + | "Alternate Configuration Files\n" |
| + | "-----------------------------\n" |
| + | "Menuconfig supports the use of alternate configuration files for\n" |
| + | "those who, for various reasons, find it necessary to switch\n" |
| + | "between different configurations.\n" |
| + | "\n" |
| + | "At the end of the main menu you will find two options. One is\n" |
| + | "for saving the current configuration to a file of your choosing.\n" |
| + | "The other option is for loading a previously saved alternate\n" |
| + | "configuration.\n" |
| + | "\n" |
| + | "Even if you don't use alternate configuration files, but you\n" |
| + | "find during a Menuconfig session that you have completely messed\n" |
| + | "up your settings, you may use the \"Load Alternate...\" option to\n" |
| + | "restore your previously saved settings from \".config\" without\n" |
| + | "restarting Menuconfig.\n" |
| + | "\n" |
| + | "Other information\n" |
| + | "-----------------\n" |
| + | "If you use Menuconfig in an XTERM window make sure you have your\n" |
| + | "$TERM variable set to point to a xterm definition which supports color.\n" |
| + | "Otherwise, Menuconfig will look rather bad. Menuconfig will not\n" |
| + | "display correctly in a RXVT window because rxvt displays only one\n" |
| + | "intensity of color, bright.\n" |
| + | "\n" |
| + | "Menuconfig will display larger menus on screens or xterms which are\n" |
| + | "set to display more than the standard 25 row by 80 column geometry.\n" |
| + | "In order for this to work, the \"stty size\" command must be able to\n" |
| + | "display the screen's current row and column geometry. I STRONGLY\n" |
| + | "RECOMMEND that you make sure you do NOT have the shell variables\n" |
| + | "LINES and COLUMNS exported into your environment. Some distributions\n" |
| + | "export those variables via /etc/profile. Some ncurses programs can\n" |
| + | "become confused when those variables (LINES & COLUMNS) don't reflect\n" |
| + | "the true screen size.\n" |
| + | "\n" |
| + | "Optional personality available\n" |
| + | "------------------------------\n" |
| + | "If you prefer to have all of the options listed in a single\n" |
| + | "menu, rather than the default multimenu hierarchy, run the menuconfig\n" |
| + | "with MENUCONFIG_MODE environment variable set to single_menu. Example:\n" |
| + | "\n" |
| + | "make MENUCONFIG_MODE=single_menu menuconfig\n" |
| + | "\n" |
| + | "<Enter> will then unroll the appropriate category, or enfold it if it\n" |
| + | "is already unrolled.\n" |
| + | "\n" |
| + | "Note that this mode can eventually be a little more CPU expensive\n" |
| + | "(especially with a larger number of unrolled categories) than the\n" |
| + | "default mode.\n", |
| + | menu_instructions[] = |
| "Arrow keys navigate the menu. " | |
| "<Enter> selects submenus --->. " | |
| "Highlighted letters are hotkeys. " | |
| "Pressing <Y> selectes a feature, while <N> will exclude a feature. " | |
| - | "Press <Esc><Esc> to exit, <?> for Help. " |
| + | "Press <Esc><Esc> to exit, <?> for Help, </> for Search. " |
| "Legend: [*] feature is selected [ ] feature is excluded", | |
| radiolist_instructions[] = | |
| "Use the arrow keys to navigate this window or " | |
| @@ -85,23 +217,50 @@ save_config_help[] = | |
| "\n" | |
| "If you are uncertain what all this means then you should probably\n" | |
| "leave this blank.\n", | |
| - | top_menu_help[] = |
| + | search_help[] = |
| "\n" | |
| - | "Use the Up/Down arrow keys (cursor keys) to highlight the item\n" |
| - | "you wish to change or submenu wish to select and press <Enter>.\n" |
| - | "Submenus are designated by \"--->\".\n" |
| + | "Search for CONFIG_ symbols and display their relations.\n" |
| + | "Example: search for \"^FOO\"\n" |
| + | "Result:\n" |
| + | "-----------------------------------------------------------------\n" |
| + | "Symbol: FOO [=m]\n" |
| + | "Prompt: Foo bus is used to drive the bar HW\n" |
| + | "Defined at drivers/pci/Kconfig:47\n" |
| + | "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" |
| + | "Location:\n" |
| + | " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" |
| + | " -> PCI support (PCI [=y])\n" |
| + | " -> PCI access mode (<choice> [=y])\n" |
| + | "Selects: LIBCRC32\n" |
| + | "Selected by: BAR\n" |
| + | "-----------------------------------------------------------------\n" |
| + | "o The line 'Prompt:' shows the text used in the menu structure for\n" |
| + | " this CONFIG_ symbol\n" |
| + | "o The 'Defined at' line tell at what file / line number the symbol\n" |
| + | " is defined\n" |
| + | "o The 'Depends on:' line tell what symbols needs to be defined for\n" |
| + | " this symbol to be visible in the menu (selectable)\n" |
| + | "o The 'Location:' lines tell where in the menu structure this symbol\n" |
| + | " is located\n" |
| + | " A location followed by a [=y] indicate that this is a selectable\n" |
| + | " menu item - and current value is displayed inside brackets.\n" |
| + | "o The 'Selects:' line tell what symbol will be automatically\n" |
| + | " selected if this symbol is selected (y or m)\n" |
| + | "o The 'Selected by' line tell what symbol has selected this symbol\n" |
| "\n" | |
| - | "Shortcut: Press the option's highlighted letter (hotkey).\n" |
| - | "\n" |
| - | "You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" |
| - | "unseen options into view.\n" |
| - | ; |
| + | "Only relevant lines are shown.\n" |
| + | "\n\n" |
| + | "Search examples:\n" |
| + | "Examples: USB => find all CONFIG_ symbols containing USB\n" |
| + | " ^USB => find all CONFIG_ symbols starting with USB\n" |
| + | " USB$ => find all CONFIG_ symbols ending with USB\n" |
| + | "\n"; |
| static char filename[PATH_MAX+1] = ".config"; | |
| - | static int indent = 0; |
| + | static int indent; |
| static struct termios ios_org; | |
| - | static int rows, cols; |
| - | struct menu *current_menu; |
| + | static int rows = 0, cols = 0; |
| + | static struct menu *current_menu; |
| static int child_count; | |
| static int single_menu_mode; | |
| @@ -116,33 +275,31 @@ static void conf_save(void); | |
| static void show_textbox(const char *title, const char *text, int r, int c); | |
| static void show_helptext(const char *title, const char *text); | |
| static void show_help(struct menu *menu); | |
| - | static void show_readme(void); |
| + | static void show_file(const char *filename, const char *title, int r, int c); |
| static void init_wsize(void) | |
| { | |
| struct winsize ws; | |
| char *env; | |
| - | if (ioctl(1, TIOCGWINSZ, &ws) == -1) { |
| - | rows = 24; |
| - | cols = 80; |
| - | } else { |
| + | if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) { |
| rows = ws.ws_row; | |
| cols = ws.ws_col; | |
| - | if (!rows) { |
| - | env = getenv("LINES"); |
| - | if (env) |
| - | rows = atoi(env); |
| - | if (!rows) |
| - | rows = 24; |
| - | } |
| - | if (!cols) { |
| - | env = getenv("COLUMNS"); |
| - | if (env) |
| - | cols = atoi(env); |
| - | if (!cols) |
| - | cols = 80; |
| - | } |
| + | } |
| + | |
| + | if (!rows) { |
| + | env = getenv("LINES"); |
| + | if (env) |
| + | rows = atoi(env); |
| + | if (!rows) |
| + | rows = 24; |
| + | } |
| + | if (!cols) { |
| + | env = getenv("COLUMNS"); |
| + | if (env) |
| + | cols = atoi(env); |
| + | if (!cols) |
| + | cols = 80; |
| } | |
| if (rows < 19 || cols < 80) { | |
| @@ -214,6 +371,103 @@ static void cdone(void) | |
| item_no = 0; | |
| } | |
| + | static void get_prompt_str(struct gstr *r, struct property *prop) |
| + | { |
| + | int i, j; |
| + | struct menu *submenu[8], *menu; |
| + | |
| + | str_printf(r, "Prompt: %s\n", prop->text); |
| + | str_printf(r, " Defined at %s:%d\n", prop->menu->file->name, |
| + | prop->menu->lineno); |
| + | if (!expr_is_yes(prop->visible.expr)) { |
| + | str_append(r, " Depends on: "); |
| + | expr_gstr_print(prop->visible.expr, r); |
| + | str_append(r, "\n"); |
| + | } |
| + | menu = prop->menu->parent; |
| + | for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) |
| + | submenu[i++] = menu; |
| + | if (i > 0) { |
| + | str_printf(r, " Location:\n"); |
| + | for (j = 4; --i >= 0; j += 2) { |
| + | menu = submenu[i]; |
| + | str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu)); |
| + | if (menu->sym) { |
| + | str_printf(r, " (%s [=%s])", menu->sym->name ? |
| + | menu->sym->name : "<choice>", |
| + | sym_get_string_value(menu->sym)); |
| + | } |
| + | str_append(r, "\n"); |
| + | } |
| + | } |
| + | } |
| + | |
| + | static void get_symbol_str(struct gstr *r, struct symbol *sym) |
| + | { |
| + | bool hit; |
| + | struct property *prop; |
| + | |
| + | str_printf(r, "Symbol: %s [=%s]\n", sym->name, |
| + | sym_get_string_value(sym)); |
| + | for_all_prompts(sym, prop) |
| + | get_prompt_str(r, prop); |
| + | hit = false; |
| + | for_all_properties(sym, prop, P_SELECT) { |
| + | if (!hit) { |
| + | str_append(r, " Selects: "); |
| + | hit = true; |
| + | } else |
| + | str_printf(r, " && "); |
| + | expr_gstr_print(prop->expr, r); |
| + | } |
| + | if (hit) |
| + | str_append(r, "\n"); |
| + | if (sym->rev_dep.expr) { |
| + | str_append(r, " Selected by: "); |
| + | expr_gstr_print(sym->rev_dep.expr, r); |
| + | str_append(r, "\n"); |
| + | } |
| + | str_append(r, "\n\n"); |
| + | } |
| + | |
| + | static struct gstr get_relations_str(struct symbol **sym_arr) |
| + | { |
| + | struct symbol *sym; |
| + | struct gstr res = str_new(); |
| + | int i; |
| + | |
| + | for (i = 0; sym_arr && (sym = sym_arr[i]); i++) |
| + | get_symbol_str(&res, sym); |
| + | if (!i) |
| + | str_append(&res, "No matches found.\n"); |
| + | return res; |
| + | } |
| + | |
| + | static void search_conf(void) |
| + | { |
| + | struct symbol **sym_arr; |
| + | struct gstr res; |
| + | |
| + | again: |
| + | switch (dialog_inputbox("Search Configuration Parameter", |
| + | "Enter Keyword", 10, 75, |
| + | NULL)) { |
| + | case 0: |
| + | break; |
| + | case 1: |
| + | show_helptext("Search Configuration", search_help); |
| + | goto again; |
| + | default: |
| + | return; |
| + | } |
| + | |
| + | sym_arr = sym_re_search(dialog_input_result); |
| + | res = get_relations_str(sym_arr); |
| + | free(sym_arr); |
| + | show_textbox("Search Results", str_get(&res), 0, 0); |
| + | str_free(&res); |
| + | } |
| + | |
| static void build_conf(struct menu *menu) | |
| { | |
| struct symbol *sym; | |
| @@ -308,6 +562,11 @@ static void build_conf(struct menu *menu) | |
| return; | |
| } | |
| } else { | |
| + | if (menu == current_menu) { |
| + | cprint_tag(":%p", menu); |
| + | cprint_name("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); |
| + | goto conf_childs; |
| + | } |
| child_count++; | |
| val = sym_get_tristate_value(sym); | |
| if (sym_is_choice_value(sym) && val == yes) { | |
| @@ -376,7 +635,7 @@ static void conf(struct menu *menu) | |
| while (1) { | |
| indent = 0; | |
| child_count = 0; | |
| - | current_menu = menu; |
| + | current_menu = menu; |
| cdone(); cinit(); | |
| build_conf(menu); | |
| if (!child_count) | |
| @@ -441,7 +700,7 @@ static void conf(struct menu *menu) | |
| if (sym) | |
| show_help(submenu); | |
| else | |
| - | show_readme(); |
| + | show_helptext("README", mconf_readme); |
| break; | |
| case 3: | |
| if (type == 't') { | |
| @@ -465,6 +724,9 @@ static void conf(struct menu *menu) | |
| else if (type == 'm') | |
| conf(submenu); | |
| break; | |
| + | case 7: |
| + | search_conf(); |
| + | break; |
| } | |
| } | |
| } | |
| @@ -476,37 +738,39 @@ static void show_textbox(const char *title, const char *text, int r, int c) | |
| fd = creat(".help.tmp", 0777); | |
| write(fd, text, strlen(text)); | |
| close(fd); | |
| - | while (dialog_textbox(title, ".help.tmp", r, c) < 0) |
| - | ; |
| + | show_file(".help.tmp", title, r, c); |
| unlink(".help.tmp"); | |
| } | |
| static void show_helptext(const char *title, const char *text) | |
| { | |
| - | show_textbox(title, text, rows, cols); |
| + | show_textbox(title, text, 0, 0); |
| } | |
| static void show_help(struct menu *menu) | |
| { | |
| - | const char *help; |
| - | char *helptext; |
| + | struct gstr help = str_new(); |
| struct symbol *sym = menu->sym; | |
| - | help = sym->help; |
| - | if (!help) |
| - | help = nohelp_text; |
| - | if (sym->name) { |
| - | helptext = malloc(strlen(sym->name) + strlen(help) + 16); |
| - | sprintf(helptext, "%s:\n\n%s", sym->name, help); |
| - | show_helptext(menu_get_prompt(menu), helptext); |
| - | free(helptext); |
| - | } else |
| - | show_helptext(menu_get_prompt(menu), help); |
| + | if (sym->help) |
| + | { |
| + | if (sym->name) { |
| + | str_printf(&help, "%s:\n\n", sym->name); |
| + | str_append(&help, sym->help); |
| + | str_append(&help, "\n"); |
| + | } |
| + | } else { |
| + | str_append(&help, nohelp_text); |
| + | } |
| + | get_symbol_str(&help, sym); |
| + | show_helptext(menu_get_prompt(menu), str_get(&help)); |
| + | str_free(&help); |
| } | |
| - | static void show_readme(void) |
| + | static void show_file(const char *filename, const char *title, int r, int c) |
| { | |
| - | show_helptext("Help", top_menu_help); |
| + | while (dialog_textbox(title, filename, r ? r : rows, c ? c : cols) < 0) |
| + | ; |
| } | |
| static void conf_choice(struct menu *menu) | |
| @@ -667,9 +931,9 @@ static void winch_handler(int sig) | |
| int main(int ac, char **av) | |
| { | |
| - | int stat; |
| - | char *mode; |
| struct symbol *sym; | |
| + | char *mode; |
| + | int stat; |
| conf_parse(av[1]); | |
| conf_read(NULL); | |
| @@ -697,7 +961,7 @@ int main(int ac, char **av) | |
| init_dialog(); | |
| do { | |
| stat = dialog_yesno(NULL, | |
| - | "Do you wish to save your new BusyBox configuration?", 5, 60); |
| + | "Do you wish to save your new BusyBox configuration?", 5, 60); |
| } while (stat < 0); | |
| end_dialog(); | |
| @@ -10,7 +10,6 @@ | |
| #include "lkc.h" | |
| struct menu rootmenu; | |
| - | struct menu *current_menu, *current_entry; |
| static struct menu **last_entry_ptr; | |
| struct file *file_list; | |
| @@ -389,43 +388,3 @@ struct menu *menu_get_parent_menu(struct menu *menu) | |
| return menu; | |
| } | |
| - | struct file *file_lookup(const char *name) |
| - | { |
| - | struct file *file; |
| - | |
| - | for (file = file_list; file; file = file->next) { |
| - | if (!strcmp(name, file->name)) |
| - | return file; |
| - | } |
| - | |
| - | file = malloc(sizeof(*file)); |
| - | memset(file, 0, sizeof(*file)); |
| - | file->name = strdup(name); |
| - | file->next = file_list; |
| - | file_list = file; |
| - | return file; |
| - | } |
| - | |
| - | int file_write_dep(const char *name) |
| - | { |
| - | struct file *file; |
| - | FILE *out; |
| - | |
| - | if (!name) |
| - | name = ".config.cmd"; |
| - | out = fopen(".config.tmp", "w"); |
| - | if (!out) |
| - | return 1; |
| - | fprintf(out, "deps_config := \\\n"); |
| - | for (file = file_list; file; file = file->next) { |
| - | if (file->next) |
| - | fprintf(out, "\t%s \\\n", file->name); |
| - | else |
| - | fprintf(out, "\t%s\n", file->name); |
| - | } |
| - | fprintf(out, "\n.config include/config.h: $(deps_config)\n\n$(deps_config):\n"); |
| - | fclose(out); |
| - | rename(".config.tmp", name); |
| - | return 0; |
| - | } |
| - | |
| @@ -6,6 +6,7 @@ | |
| #include <ctype.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| + | #include <regex.h> |
| #include <sys/utsname.h> | |
| #define LKC_DIRECT_LINK | |
| @@ -414,7 +415,7 @@ tristate sym_toggle_tristate_value(struct symbol *sym) | |
| bool sym_string_valid(struct symbol *sym, const char *str) | |
| { | |
| - | char ch; |
| + | signed char ch; |
| switch (sym->type) { | |
| case S_STRING: | |
| @@ -649,6 +650,43 @@ struct symbol *sym_find(const char *name) | |
| return symbol; | |
| } | |
| + | struct symbol **sym_re_search(const char *pattern) |
| + | { |
| + | struct symbol *sym, **sym_arr = NULL; |
| + | int i, cnt, size; |
| + | regex_t re; |
| + | |
| + | cnt = size = 0; |
| + | /* Skip if empty */ |
| + | if (strlen(pattern) == 0) |
| + | return NULL; |
| + | if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) |
| + | return NULL; |
| + | |
| + | for_all_symbols(i, sym) { |
| + | if (sym->flags & SYMBOL_CONST || !sym->name) |
| + | continue; |
| + | if (regexec(&re, sym->name, 0, NULL, 0)) |
| + | continue; |
| + | if (cnt + 1 >= size) { |
| + | void *tmp = sym_arr; |
| + | size += 16; |
| + | sym_arr = realloc(sym_arr, size * sizeof(struct symbol *)); |
| + | if (!sym_arr) { |
| + | free(tmp); |
| + | return NULL; |
| + | } |
| + | } |
| + | sym_arr[cnt++] = sym; |
| + | } |
| + | if (sym_arr) |
| + | sym_arr[cnt] = NULL; |
| + | regfree(&re); |
| + | |
| + | return sym_arr; |
| + | } |
| + | |
| + | |
| struct symbol *sym_check_deps(struct symbol *sym); | |
| static struct symbol *sym_check_expr_deps(struct expr *e) | |
| @@ -1,375 +1,109 @@ | |
| /* | |
| - | * util.c |
| + | * Copyright (C) 2002-2005 Roman Zippel <[email protected]> |
| + | * Copyright (C) 2002-2005 Sam Ravnborg <[email protected]> |
| * | |
| - | * ORIGINAL AUTHOR: Savio Lam ([email protected]) |
| - | * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap ([email protected]) |
| - | * |
| - | * This program is free software; you can redistribute it and/or |
| - | * modify it under the terms of the GNU General Public License |
| - | * as published by the Free Software Foundation; either version 2 |
| - | * of the License, or (at your option) any later version. |
| - | * |
| - | * This program is distributed in the hope that it will be useful, |
| - | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| - | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| - | * GNU General Public License for more details. |
| - | * |
| - | * You should have received a copy of the GNU General Public License |
| - | * along with this program; if not, write to the Free Software |
| - | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| - | */ |
| - | |
| - | #include "dialog.h" |
| - | |
| - | |
| - | /* use colors by default? */ |
| - | bool use_colors = 1; |
| - | |
| - | char *backtitle = NULL; |
| - | |
| - | const char *dialog_result; |
| - | |
| - | /* |
| - | * Attribute values, default is for mono display |
| - | */ |
| - | chtype attributes[] = |
| - | { |
| - | A_NORMAL, /* screen_attr */ |
| - | A_NORMAL, /* shadow_attr */ |
| - | A_NORMAL, /* dialog_attr */ |
| - | A_BOLD, /* title_attr */ |
| - | A_NORMAL, /* border_attr */ |
| - | A_REVERSE, /* button_active_attr */ |
| - | A_DIM, /* button_inactive_attr */ |
| - | A_REVERSE, /* button_key_active_attr */ |
| - | A_BOLD, /* button_key_inactive_attr */ |
| - | A_REVERSE, /* button_label_active_attr */ |
| - | A_NORMAL, /* button_label_inactive_attr */ |
| - | A_NORMAL, /* inputbox_attr */ |
| - | A_NORMAL, /* inputbox_border_attr */ |
| - | A_NORMAL, /* searchbox_attr */ |
| - | A_BOLD, /* searchbox_title_attr */ |
| - | A_NORMAL, /* searchbox_border_attr */ |
| - | A_BOLD, /* position_indicator_attr */ |
| - | A_NORMAL, /* menubox_attr */ |
| - | A_NORMAL, /* menubox_border_attr */ |
| - | A_NORMAL, /* item_attr */ |
| - | A_REVERSE, /* item_selected_attr */ |
| - | A_BOLD, /* tag_attr */ |
| - | A_REVERSE, /* tag_selected_attr */ |
| - | A_BOLD, /* tag_key_attr */ |
| - | A_REVERSE, /* tag_key_selected_attr */ |
| - | A_BOLD, /* check_attr */ |
| - | A_REVERSE, /* check_selected_attr */ |
| - | A_BOLD, /* uarrow_attr */ |
| - | A_BOLD /* darrow_attr */ |
| - | }; |
| - | |
| - | |
| - | #include "colors.h" |
| - | |
| - | /* |
| - | * Table of color values |
| - | */ |
| - | int color_table[][3] = |
| - | { |
| - | {SCREEN_FG, SCREEN_BG, SCREEN_HL}, |
| - | {SHADOW_FG, SHADOW_BG, SHADOW_HL}, |
| - | {DIALOG_FG, DIALOG_BG, DIALOG_HL}, |
| - | {TITLE_FG, TITLE_BG, TITLE_HL}, |
| - | {BORDER_FG, BORDER_BG, BORDER_HL}, |
| - | {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL}, |
| - | {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL}, |
| - | {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL}, |
| - | {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL}, |
| - | {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL}, |
| - | {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG, |
| - | BUTTON_LABEL_INACTIVE_HL}, |
| - | {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL}, |
| - | {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL}, |
| - | {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL}, |
| - | {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL}, |
| - | {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL}, |
| - | {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL}, |
| - | {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL}, |
| - | {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL}, |
| - | {ITEM_FG, ITEM_BG, ITEM_HL}, |
| - | {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL}, |
| - | {TAG_FG, TAG_BG, TAG_HL}, |
| - | {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL}, |
| - | {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL}, |
| - | {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL}, |
| - | {CHECK_FG, CHECK_BG, CHECK_HL}, |
| - | {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL}, |
| - | {UARROW_FG, UARROW_BG, UARROW_HL}, |
| - | {DARROW_FG, DARROW_BG, DARROW_HL}, |
| - | }; /* color_table */ |
| - | |
| - | /* |
| - | * Set window to attribute 'attr' |
| + | * Released under the terms of the GNU GPL v2.0. |
| */ | |
| - | void |
| - | attr_clear (WINDOW * win, int height, int width, chtype attr) |
| - | { |
| - | int i, j; |
| - | |
| - | wattrset (win, attr); |
| - | for (i = 0; i < height; i++) { |
| - | wmove (win, i, 0); |
| - | for (j = 0; j < width; j++) |
| - | waddch (win, ' '); |
| - | } |
| - | touchwin (win); |
| - | } |
| - | void dialog_clear (void) |
| - | { |
| - | attr_clear (stdscr, LINES, COLS, screen_attr); |
| - | /* Display background title if it exists ... - SLH */ |
| - | if (backtitle != NULL) { |
| - | int i; |
| - | |
| - | wattrset (stdscr, screen_attr); |
| - | mvwaddstr (stdscr, 0, 1, (char *)backtitle); |
| - | wmove (stdscr, 1, 1); |
| - | for (i = 1; i < COLS - 1; i++) |
| - | waddch (stdscr, ACS_HLINE); |
| - | } |
| - | wnoutrefresh (stdscr); |
| - | } |
| + | #include <string.h> |
| + | #include "lkc.h" |
| - | /* |
| - | * Do some initialization for dialog |
| - | */ |
| - | void |
| - | init_dialog (void) |
| - | { |
| - | initscr (); /* Init curses */ |
| - | keypad (stdscr, TRUE); |
| - | cbreak (); |
| - | noecho (); |
| - | |
| - | |
| - | if (use_colors) /* Set up colors */ |
| - | color_setup (); |
| - | |
| - | |
| - | dialog_clear (); |
| - | } |
| - | |
| - | /* |
| - | * Setup for color display |
| - | */ |
| - | void |
| - | color_setup (void) |
| + | /* file already present in list? If not add it */ |
| + | struct file *file_lookup(const char *name) |
| { | |
| - | int i; |
| + | struct file *file; |
| - | if (has_colors ()) { /* Terminal supports color? */ |
| - | start_color (); |
| - | |
| - | /* Initialize color pairs */ |
| - | for (i = 0; i < ATTRIBUTE_COUNT; i++) |
| - | init_pair (i + 1, color_table[i][0], color_table[i][1]); |
| + | for (file = file_list; file; file = file->next) { |
| + | if (!strcmp(name, file->name)) |
| + | return file; |
| + | } |
| - | /* Setup color attributes */ |
| - | for (i = 0; i < ATTRIBUTE_COUNT; i++) |
| - | attributes[i] = C_ATTR (color_table[i][2], i + 1); |
| - | } |
| + | file = malloc(sizeof(*file)); |
| + | memset(file, 0, sizeof(*file)); |
| + | file->name = strdup(name); |
| + | file->next = file_list; |
| + | file_list = file; |
| + | return file; |
| } | |
| - | /* |
| - | * End using dialog functions. |
| - | */ |
| - | void |
| - | end_dialog (void) |
| + | /* write a dependency file as used by kbuild to track dependencies */ |
| + | int file_write_dep(const char *name) |
| { | |
| - | endwin (); |
| + | struct file *file; |
| + | FILE *out; |
| + | |
| + | if (!name) |
| + | name = ".config.cmd"; |
| + | out = fopen(".config.tmp", "w"); |
| + | if (!out) |
| + | return 1; |
| + | fprintf(out, "deps_config := \\\n"); |
| + | for (file = file_list; file; file = file->next) { |
| + | if (file->next) |
| + | fprintf(out, "\t%s \\\n", file->name); |
| + | else |
| + | fprintf(out, "\t%s\n", file->name); |
| + | } |
| + | fprintf(out, "\n.config include/config.h: $(deps_config)\n\n$(deps_config):\n"); |
| + | fclose(out); |
| + | rename(".config.tmp", name); |
| + | return 0; |
| } | |
| - | /* |
| - | * Print a string of text in a window, automatically wrap around to the |
| - | * next line if the string is too long to fit on one line. Newline |
| - | * characters '\n' are replaced by spaces. We start on a new line |
| - | * if there is no room for at least 4 nonblanks following a double-space. |
| - | */ |
| - | void |
| - | print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x) |
| + | /* Allocate initial growable sting */ |
| + | struct gstr str_new(void) |
| { | |
| - | int newl, cur_x, cur_y; |
| - | int i, prompt_len, room, wlen; |
| - | char tempstr[MAX_LEN + 1], *word, *sp, *sp2; |
| - | |
| - | strcpy (tempstr, prompt); |
| - | |
| - | prompt_len = strlen(tempstr); |
| - | |
| - | /* |
| - | * Remove newlines |
| - | */ |
| - | for(i=0; i<prompt_len; i++) { |
| - | if(tempstr[i] == '\n') tempstr[i] = ' '; |
| - | } |
| - | |
| - | if (prompt_len <= width - x * 2) { /* If prompt is short */ |
| - | wmove (win, y, (width - prompt_len) / 2); |
| - | waddstr (win, tempstr); |
| - | } else { |
| - | cur_x = x; |
| - | cur_y = y; |
| - | newl = 1; |
| - | word = tempstr; |
| - | while (word && *word) { |
| - | sp = index(word, ' '); |
| - | if (sp) |
| - | *sp++ = 0; |
| - | |
| - | /* Wrap to next line if either the word does not fit, |
| - | or it is the first word of a new sentence, and it is |
| - | short, and the next word does not fit. */ |
| - | room = width - cur_x; |
| - | wlen = strlen(word); |
| - | if (wlen > room || |
| - | (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room |
| - | && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) { |
| - | cur_y++; |
| - | cur_x = x; |
| - | } |
| - | wmove (win, cur_y, cur_x); |
| - | waddstr (win, word); |
| - | getyx (win, cur_y, cur_x); |
| - | cur_x++; |
| - | if (sp && *sp == ' ') { |
| - | cur_x++; /* double space */ |
| - | while (*++sp == ' '); |
| - | newl = 1; |
| - | } else |
| - | newl = 0; |
| - | word = sp; |
| - | } |
| - | } |
| + | struct gstr gs; |
| + | gs.s = malloc(sizeof(char) * 64); |
| + | gs.len = 16; |
| + | strcpy(gs.s, "\0"); |
| + | return gs; |
| } | |
| - | /* |
| - | * Print a button |
| - | */ |
| - | void |
| - | print_button (WINDOW * win, const char *label, int y, int x, int selected) |
| + | /* Allocate and assign growable string */ |
| + | struct gstr str_assign(const char *s) |
| { | |
| - | int i, temp; |
| - | |
| - | wmove (win, y, x); |
| - | wattrset (win, selected ? button_active_attr : button_inactive_attr); |
| - | waddstr (win, "<"); |
| - | temp = strspn (label, " "); |
| - | label += temp; |
| - | wattrset (win, selected ? button_label_active_attr |
| - | : button_label_inactive_attr); |
| - | for (i = 0; i < temp; i++) |
| - | waddch (win, ' '); |
| - | wattrset (win, selected ? button_key_active_attr |
| - | : button_key_inactive_attr); |
| - | waddch (win, label[0]); |
| - | wattrset (win, selected ? button_label_active_attr |
| - | : button_label_inactive_attr); |
| - | waddstr (win, (char *)label + 1); |
| - | wattrset (win, selected ? button_active_attr : button_inactive_attr); |
| - | waddstr (win, ">"); |
| - | wmove (win, y, x + temp + 1); |
| + | struct gstr gs; |
| + | gs.s = strdup(s); |
| + | gs.len = strlen(s) + 1; |
| + | return gs; |
| } | |
| - | /* |
| - | * Draw a rectangular box with line drawing characters |
| - | */ |
| - | void |
| - | draw_box (WINDOW * win, int y, int x, int height, int width, |
| - | chtype box, chtype border) |
| + | /* Free storage for growable string */ |
| + | void str_free(struct gstr *gs) |
| { | |
| - | int i, j; |
| - | |
| - | wattrset (win, 0); |
| - | for (i = 0; i < height; i++) { |
| - | wmove (win, y + i, x); |
| - | for (j = 0; j < width; j++) |
| - | if (!i && !j) |
| - | waddch (win, border | ACS_ULCORNER); |
| - | else if (i == height - 1 && !j) |
| - | waddch (win, border | ACS_LLCORNER); |
| - | else if (!i && j == width - 1) |
| - | waddch (win, box | ACS_URCORNER); |
| - | else if (i == height - 1 && j == width - 1) |
| - | waddch (win, box | ACS_LRCORNER); |
| - | else if (!i) |
| - | waddch (win, border | ACS_HLINE); |
| - | else if (i == height - 1) |
| - | waddch (win, box | ACS_HLINE); |
| - | else if (!j) |
| - | waddch (win, border | ACS_VLINE); |
| - | else if (j == width - 1) |
| - | waddch (win, box | ACS_VLINE); |
| - | else |
| - | waddch (win, box | ' '); |
| - | } |
| + | if (gs->s) |
| + | free(gs->s); |
| + | gs->s = NULL; |
| + | gs->len = 0; |
| } | |
| - | /* |
| - | * Draw shadows along the right and bottom edge to give a more 3D look |
| - | * to the boxes |
| - | */ |
| - | void |
| - | draw_shadow (WINDOW * win, int y, int x, int height, int width) |
| + | /* Append to growable string */ |
| + | void str_append(struct gstr *gs, const char *s) |
| { | |
| - | int i; |
| - | |
| - | if (has_colors ()) { /* Whether terminal supports color? */ |
| - | wattrset (win, shadow_attr); |
| - | wmove (win, y + height, x + 2); |
| - | for (i = 0; i < width; i++) |
| - | waddch (win, winch (win) & A_CHARTEXT); |
| - | for (i = y + 1; i < y + height + 1; i++) { |
| - | wmove (win, i, x + width); |
| - | waddch (win, winch (win) & A_CHARTEXT); |
| - | waddch (win, winch (win) & A_CHARTEXT); |
| + | size_t l = strlen(gs->s) + strlen(s) + 1; |
| + | if (l > gs->len) { |
| + | gs->s = realloc(gs->s, l); |
| + | gs->len = l; |
| } | |
| - | wnoutrefresh (win); |
| - | } |
| + | strcat(gs->s, s); |
| } | |
| - | /* |
| - | * Return the position of the first alphabetic character in a string. |
| - | */ |
| - | int |
| - | first_alpha(const char *string, const char *exempt) |
| + | /* Append printf formatted string to growable string */ |
| + | void str_printf(struct gstr *gs, const char *fmt, ...) |
| { | |
| - | int i, in_paren=0, c; |
| - | |
| - | for (i = 0; i < strlen(string); i++) { |
| - | c = tolower(string[i]); |
| - | |
| - | if (strchr("<[(", c)) ++in_paren; |
| - | if (strchr(">])", c) && in_paren > 0) --in_paren; |
| - | |
| - | if ((! in_paren) && isalpha(c) && |
| - | strchr(exempt, c) == 0) |
| - | return i; |
| - | } |
| - | |
| - | return 0; |
| + | va_list ap; |
| + | char s[10000]; /* big enough... */ |
| + | va_start(ap, fmt); |
| + | vsnprintf(s, sizeof(s), fmt, ap); |
| + | str_append(gs, s); |
| + | va_end(ap); |
| } | |
| - | /* |
| - | * Get the first selected item in the dialog_list_item list. |
| - | */ |
| - | struct dialog_list_item * |
| - | first_sel_item(int item_no, struct dialog_list_item ** items) |
| + | /* Retreive value of growable string */ |
| + | const char *str_get(struct gstr *gs) |
| { | |
| - | int i; |
| - | |
| - | for (i = 0; i < item_no; i++) { |
| - | if (items[i]->selected) |
| - | return items[i]; |
| - | } |
| - | |
| - | return NULL; |
| + | return gs->s; |
| } | |
| + | |
| @@ -175,6 +175,8 @@ static bool zconf_endtoken(int token, int starttoken, int endtoken); | |
| struct symbol *symbol_hash[257]; | |
| + | static struct menu *current_menu, *current_entry; |
| + | |
| #define YYERROR_VERBOSE | |
| @@ -2119,6 +2121,7 @@ void zconfdump(FILE *out) | |
| } | |
| #include "lex.zconf.c" | |
| + | #include "util.c" |
| #include "confdata.c" | |
| #include "expr.c" | |
| #include "symbol.c" | |
| @@ -25,6 +25,8 @@ static bool zconf_endtoken(int token, int starttoken, int endtoken); | |
| struct symbol *symbol_hash[257]; | |
| + | static struct menu *current_menu, *current_entry; |
| + | |
| #define YYERROR_VERBOSE | |
| %} | |
| %expect 40 | |
| @@ -681,6 +683,7 @@ void zconfdump(FILE *out) | |
| } | |
| #include "lex.zconf.c" | |
| + | #include "util.c" |
| #include "confdata.c" | |
| #include "expr.c" | |
| #include "symbol.c" | |