Merge/rework config system per the latest from linux-2.6.0-test2.
Fix the config bugs revealed by the updated config system.
 -Erik
diff --git a/scripts/config/zconf.y b/scripts/config/zconf.y
index 301d7a8..459b690 100644
--- a/scripts/config/zconf.y
+++ b/scripts/config/zconf.y
@@ -27,7 +27,7 @@
 
 #define YYERROR_VERBOSE
 %}
-%expect 36
+%expect 40
 
 %union
 {
@@ -46,6 +46,7 @@
 %token T_ENDCHOICE
 %token T_COMMENT
 %token T_CONFIG
+%token T_MENUCONFIG
 %token T_HELP
 %token <string> T_HELPTEXT
 %token T_IF
@@ -56,17 +57,22 @@
 %token T_PROMPT
 %token T_DEFAULT
 %token T_TRISTATE
+%token T_DEF_TRISTATE
 %token T_BOOLEAN
+%token T_DEF_BOOLEAN
+%token T_STRING
 %token T_INT
 %token T_HEX
 %token <string> T_WORD
-%token <string> T_STRING
+%token <string> T_WORD_QUOTE
 %token T_UNEQUAL
 %token T_EOF
 %token T_EOL
 %token T_CLOSE_PAREN
 %token T_OPEN_PAREN
 %token T_ON
+%token T_SELECT
+%token T_RANGE
 
 %left T_OR
 %left T_AND
@@ -103,14 +109,15 @@
 	  if_stmt
 	| comment_stmt
 	| config_stmt
+	| menuconfig_stmt
 	| source_stmt
 	| nl_or_eof
 ;
 
 
-/* config entry */
+/* config/menuconfig entry */
 
-config_entry_start: T_CONFIG T_WORD
+config_entry_start: T_CONFIG T_WORD T_EOL
 {
 	struct symbol *sym = sym_lookup($2, 0);
 	sym->flags |= SYMBOL_OPTIONAL;
@@ -118,74 +125,118 @@
 	printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
 };
 
-config_stmt: config_entry_start T_EOL config_option_list
+config_stmt: config_entry_start config_option_list
 {
 	menu_end_entry();
 	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
 };
 
+menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
+{
+	struct symbol *sym = sym_lookup($2, 0);
+	sym->flags |= SYMBOL_OPTIONAL;
+	menu_add_entry(sym);
+	printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
+};
+
+menuconfig_stmt: menuconfig_entry_start config_option_list
+{
+	if (current_entry->prompt)
+		current_entry->prompt->type = P_MENU;
+	else
+		zconfprint("warning: menuconfig statement without prompt");
+	menu_end_entry();
+	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+};
+
 config_option_list:
 	  /* empty */
-	| config_option_list config_option T_EOL
-	| config_option_list depends T_EOL
+	| config_option_list config_option
+	| config_option_list depends
 	| config_option_list help
 	| config_option_list T_EOL
-{ };
+;
 
-config_option: T_TRISTATE prompt_stmt_opt
+config_option: T_TRISTATE prompt_stmt_opt T_EOL
 {
 	menu_set_type(S_TRISTATE);
 	printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
 };
 
-config_option: T_BOOLEAN prompt_stmt_opt
+config_option: T_DEF_TRISTATE expr if_expr T_EOL
+{
+	menu_add_expr(P_DEFAULT, $2, $3);
+	menu_set_type(S_TRISTATE);
+	printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_BOOLEAN prompt_stmt_opt T_EOL
 {
 	menu_set_type(S_BOOLEAN);
 	printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
 };
 
-config_option: T_INT prompt_stmt_opt
+config_option: T_DEF_BOOLEAN expr if_expr T_EOL
+{
+	menu_add_expr(P_DEFAULT, $2, $3);
+	menu_set_type(S_BOOLEAN);
+	printd(DEBUG_PARSE, "%s:%d:def_boolean\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_INT prompt_stmt_opt T_EOL
 {
 	menu_set_type(S_INT);
 	printd(DEBUG_PARSE, "%s:%d:int\n", zconf_curname(), zconf_lineno());
 };
 
-config_option: T_HEX prompt_stmt_opt
+config_option: T_HEX prompt_stmt_opt T_EOL
 {
 	menu_set_type(S_HEX);
 	printd(DEBUG_PARSE, "%s:%d:hex\n", zconf_curname(), zconf_lineno());
 };
 
-config_option: T_STRING prompt_stmt_opt
+config_option: T_STRING prompt_stmt_opt T_EOL
 {
 	menu_set_type(S_STRING);
 	printd(DEBUG_PARSE, "%s:%d:string\n", zconf_curname(), zconf_lineno());
 };
 
-config_option: T_PROMPT prompt if_expr
+config_option: T_PROMPT prompt if_expr T_EOL
 {
-	menu_add_prop(P_PROMPT, $2, NULL, $3);
+	menu_add_prompt(P_PROMPT, $2, $3);
 	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
 };
 
-config_option: T_DEFAULT symbol if_expr
+config_option: T_DEFAULT expr if_expr T_EOL
 {
-	menu_add_prop(P_DEFAULT, NULL, $2, $3);
+	menu_add_expr(P_DEFAULT, $2, $3);
 	printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
 };
 
+config_option: T_SELECT T_WORD if_expr T_EOL
+{
+	menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
+	printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
+};
+
+config_option: T_RANGE symbol symbol if_expr T_EOL
+{
+	menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
+	printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
+};
+
 /* choice entry */
 
-choice: T_CHOICE
+choice: T_CHOICE T_EOL
 {
 	struct symbol *sym = sym_lookup(NULL, 0);
 	sym->flags |= SYMBOL_CHOICE;
 	menu_add_entry(sym);
-	menu_add_prop(P_CHOICE, NULL, NULL, NULL);
+	menu_add_expr(P_CHOICE, NULL, NULL);
 	printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
 };
 
-choice_entry: choice T_EOL choice_option_list
+choice_entry: choice choice_option_list
 {
 	menu_end_entry();
 	menu_add_menu();
@@ -200,7 +251,7 @@
 };
 
 choice_stmt:
-	  choice_entry choice_block choice_end T_EOL
+	  choice_entry choice_block choice_end
 	| choice_entry choice_block
 {
 	printf("%s:%d: missing 'endchoice' for this 'choice' statement\n", current_menu->file->name, current_menu->lineno);
@@ -209,28 +260,39 @@
 
 choice_option_list:
 	  /* empty */
-	| choice_option_list choice_option T_EOL
-	| choice_option_list depends T_EOL
+	| choice_option_list choice_option
+	| choice_option_list depends
 	| choice_option_list help
 	| choice_option_list T_EOL
 ;
 
-choice_option: T_PROMPT prompt if_expr
+choice_option: T_PROMPT prompt if_expr T_EOL
 {
-	menu_add_prop(P_PROMPT, $2, NULL, $3);
+	menu_add_prompt(P_PROMPT, $2, $3);
 	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
 };
 
-choice_option: T_OPTIONAL
+choice_option: T_TRISTATE prompt_stmt_opt T_EOL
+{
+	menu_set_type(S_TRISTATE);
+	printd(DEBUG_PARSE, "%s:%d:tristate\n", zconf_curname(), zconf_lineno());
+};
+
+choice_option: T_BOOLEAN prompt_stmt_opt T_EOL
+{
+	menu_set_type(S_BOOLEAN);
+	printd(DEBUG_PARSE, "%s:%d:boolean\n", zconf_curname(), zconf_lineno());
+};
+
+choice_option: T_OPTIONAL T_EOL
 {
 	current_entry->sym->flags |= SYMBOL_OPTIONAL;
 	printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
 };
 
-choice_option: T_DEFAULT symbol
+choice_option: T_DEFAULT T_WORD if_expr T_EOL
 {
-	menu_add_prop(P_DEFAULT, NULL, $2, NULL);
-	//current_choice->prop->def = $2;
+	menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
 	printd(DEBUG_PARSE, "%s:%d:default\n", zconf_curname(), zconf_lineno());
 };
 
@@ -241,11 +303,10 @@
 
 /* if entry */
 
-if: T_IF expr
+if: T_IF expr T_EOL
 {
 	printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
 	menu_add_entry(NULL);
-	//current_entry->prompt = menu_add_prop(T_IF, NULL, NULL, $2);
 	menu_add_dep($2);
 	menu_end_entry();
 	menu_add_menu();
@@ -260,8 +321,8 @@
 };
 
 if_stmt:
-	  if T_EOL if_block if_end T_EOL
-	| if T_EOL if_block
+	  if if_block if_end
+	| if if_block
 {
 	printf("%s:%d: missing 'endif' for this 'if' statement\n", current_menu->file->name, current_menu->lineno);
 	zconfnerrs++;
@@ -276,14 +337,14 @@
 
 /* menu entry */
 
-menu: T_MENU prompt
+menu: T_MENU prompt T_EOL
 {
 	menu_add_entry(NULL);
 	menu_add_prop(P_MENU, $2, NULL, NULL);
 	printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
 };
 
-menu_entry: menu T_EOL depends_list
+menu_entry: menu depends_list
 {
 	menu_end_entry();
 	menu_add_menu();
@@ -298,7 +359,7 @@
 };
 
 menu_stmt:
-	  menu_entry menu_block menu_end T_EOL
+	  menu_entry menu_block menu_end
 	| menu_entry menu_block
 {
 	printf("%s:%d: missing 'endmenu' for this 'menu' statement\n", current_menu->file->name, current_menu->lineno);
@@ -313,27 +374,27 @@
 	| menu_block error T_EOL		{ zconfprint("invalid menu option"); yyerrok; }
 ;
 
-source: T_SOURCE prompt
+source: T_SOURCE prompt T_EOL
 {
 	$$ = $2;
 	printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
 };
 
-source_stmt: source T_EOL
+source_stmt: source
 {
 	zconf_nextfile($1);
 };
 
 /* comment entry */
 
-comment: T_COMMENT prompt
+comment: T_COMMENT prompt T_EOL
 {
 	menu_add_entry(NULL);
 	menu_add_prop(P_COMMENT, $2, NULL, NULL);
 	printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
 };
 
-comment_stmt: comment T_EOL depends_list
+comment_stmt: comment depends_list
 {
 	menu_end_entry();
 };
@@ -354,21 +415,21 @@
 /* depends option */
 
 depends_list:	  /* empty */
-		| depends_list depends T_EOL
+		| depends_list depends
 		| depends_list T_EOL
-{ };
+;
 
-depends: T_DEPENDS T_ON expr
+depends: T_DEPENDS T_ON expr T_EOL
 {
 	menu_add_dep($3);
 	printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
 }
-	| T_DEPENDS expr
+	| T_DEPENDS expr T_EOL
 {
 	menu_add_dep($2);
 	printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
 }
-	| T_REQUIRES expr
+	| T_REQUIRES expr T_EOL
 {
 	menu_add_dep($2);
 	printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
@@ -378,22 +439,18 @@
 
 prompt_stmt_opt:
 	  /* empty */
-	| prompt
+	| prompt if_expr
 {
-	menu_add_prop(P_PROMPT, $1, NULL, NULL);
-}
-	| prompt T_IF expr
-{
-	menu_add_prop(P_PROMPT, $1, NULL, $3);
+	menu_add_prop(P_PROMPT, $1, NULL, $2);
 };
 
 prompt:	  T_WORD
-	| T_STRING
+	| T_WORD_QUOTE
 ;
 
-end:	  T_ENDMENU		{ $$ = T_ENDMENU; }
-	| T_ENDCHOICE		{ $$ = T_ENDCHOICE; }
-	| T_ENDIF		{ $$ = T_ENDIF; }
+end:	  T_ENDMENU nl_or_eof	{ $$ = T_ENDMENU; }
+	| T_ENDCHOICE nl_or_eof	{ $$ = T_ENDCHOICE; }
+	| T_ENDIF nl_or_eof	{ $$ = T_ENDIF; }
 ;
 
 nl_or_eof:
@@ -413,26 +470,34 @@
 ;
 
 symbol:	  T_WORD	{ $$ = sym_lookup($1, 0); free($1); }
-	| T_STRING	{ $$ = sym_lookup($1, 1); free($1); }
+	| T_WORD_QUOTE	{ $$ = sym_lookup($1, 1); free($1); }
 ;
 
 %%
 
 void conf_parse(const char *name)
 {
+	struct symbol *sym;
+	int i;
+
 	zconf_initscan(name);
 
 	sym_init();
 	menu_init();
-	rootmenu.prompt = menu_add_prop(P_MENU, "BusyBox Configuration", NULL, NULL);
+	modules_sym = sym_lookup("MODULES", 0);
+	rootmenu.prompt = menu_add_prop(P_MENU, "Linux Kernel Configuration", NULL, NULL);
 
 	//zconfdebug = 1;
 	zconfparse();
 	if (zconfnerrs)
 		exit(1);
 	menu_finalize(&rootmenu);
-
-	modules_sym = sym_lookup("MODULES", 0);
+	for_all_symbols(i, sym) {
+                if (!(sym->flags & SYMBOL_CHECKED) && sym_check_deps(sym))
+                        printf("\n");
+		else
+			sym->flags |= SYMBOL_CHECK_DONE;
+        }
 
 	sym_change_count = 1;
 }
@@ -448,7 +513,7 @@
 	case T_ENDIF:		return "endif";
 	}
 	return "<token>";
-} 
+}
 
 static bool zconf_endtoken(int token, int starttoken, int endtoken)
 {
@@ -470,7 +535,7 @@
 {
 	va_list ap;
 
-	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
+	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno() + 1);
 	va_start(ap, err);
 	vfprintf(stderr, err, ap);
 	va_end(ap);
@@ -479,7 +544,7 @@
 
 static void zconferror(const char *err)
 {
-	fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno(), err);
+	fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
 }
 
 void print_quoted_string(FILE *out, const char *str)
@@ -504,8 +569,6 @@
 	struct symbol *sym = menu->sym;
 	struct property *prop;
 
-	//sym->flags |= SYMBOL_PRINTED;
-
 	if (sym_is_choice(sym))
 		fprintf(out, "choice\n");
 	else
@@ -530,13 +593,6 @@
 		fputs("  ???\n", out);
 		break;
 	}
-#if 0
-	if (!expr_is_yes(sym->dep)) {
-		fputs("  depends ", out);
-		expr_fprint(sym->dep, out);
-		fputc('\n', out);
-	}
-#endif
 	for (prop = sym->prop; prop; prop = prop->next) {
 		if (prop->menu != menu)
 			continue;
@@ -544,25 +600,18 @@
 		case P_PROMPT:
 			fputs("  prompt ", out);
 			print_quoted_string(out, prop->text);
-			if (prop->def) {
-				fputc(' ', out);
-				if (prop->def->flags & SYMBOL_CONST)
-					print_quoted_string(out, prop->def->name);
-				else
-					fputs(prop->def->name, out);
-			}
-			if (!expr_is_yes(E_EXPR(prop->visible))) {
+			if (!expr_is_yes(prop->visible.expr)) {
 				fputs(" if ", out);
-				expr_fprint(E_EXPR(prop->visible), out);
+				expr_fprint(prop->visible.expr, out);
 			}
 			fputc('\n', out);
 			break;
 		case P_DEFAULT:
 			fputs( "  default ", out);
-			print_quoted_string(out, prop->def->name);
-			if (!expr_is_yes(E_EXPR(prop->visible))) {
+			expr_fprint(prop->expr, out);
+			if (!expr_is_yes(prop->visible.expr)) {
 				fputs(" if ", out);
-				expr_fprint(E_EXPR(prop->visible), out);
+				expr_fprint(prop->visible.expr, out);
 			}
 			fputc('\n', out);
 			break;
@@ -585,7 +634,6 @@
 
 void zconfdump(FILE *out)
 {
-	//struct file *file;
 	struct property *prop;
 	struct symbol *sym;
 	struct menu *menu;
@@ -596,11 +644,6 @@
 			print_symbol(out, menu);
 		else if ((prop = menu->prompt)) {
 			switch (prop->type) {
-			//case T_MAINMENU:
-			//	fputs("\nmainmenu ", out);
-			//	print_quoted_string(out, prop->text);
-			//	fputs("\n", out);
-			//	break;
 			case P_COMMENT:
 				fputs("\ncomment ", out);
 				print_quoted_string(out, prop->text);
@@ -611,19 +654,12 @@
 				print_quoted_string(out, prop->text);
 				fputs("\n", out);
 				break;
-			//case T_SOURCE:
-			//	fputs("\nsource ", out);
-			//	print_quoted_string(out, prop->text);
-			//	fputs("\n", out);
-			//	break;
-			//case T_IF:
-			//	fputs("\nif\n", out);
 			default:
 				;
 			}
-			if (!expr_is_yes(E_EXPR(prop->visible))) {
+			if (!expr_is_yes(prop->visible.expr)) {
 				fputs("  depends ", out);
-				expr_fprint(E_EXPR(prop->visible), out);
+				expr_fprint(prop->visible.expr, out);
 				fputc('\n', out);
 			}
 			fputs("\n", out);