diff -uNr kernelconf-0.1.3/conf/header.tk kernelconf-0.1.3.new/conf/header.tk
--- kernelconf-0.1.3/conf/header.tk	Thu Jan  1 01:00:00 1970
+++ kernelconf-0.1.3.new/conf/header.tk	Mon Feb 18 22:09:30 2002
@@ -0,0 +1,244 @@
+proc sym_setvalue { symname value } {
+	puts stdout "SYM_SET $symname $value"
+}
+
+proc menu_update_depends { w symvaly symvalm } {
+
+	catch {
+		if { $symvaly == "n" } {
+			$w.sy configure -state disabled
+		} else {
+			$w.sy configure -state normal
+		}
+		puts stderr "$w $symval"
+	}
+	catch {
+		if { $symvalm == "n" } {
+			$w.sm configure -state disabled
+		} else {
+			$w.sm configure -state normal
+		}
+		puts stderr "$w $symval"
+	}
+	catch {
+		if { $symvalm == "n" && $symvaly == "n" } {
+			$w.sn configure -state disabled
+		} else {
+			$w.sn configure -state normal
+		}
+		puts stderr "$w $symval"
+	}
+	catch {
+		if { $symvalm == "n" && $symvaly == "n" } {
+			$w.c configure -state disabled
+		} else {
+			$w.c configure -state normal
+		}
+		puts stderr "$w $symval"
+	}
+}
+
+proc config_option { w line text symname symtype havesym help havehelp child havechild } {
+
+	frame $w.f$line
+
+	if { $havesym & 4 } {
+		radiobutton $w.f$line.sy -text "y" -variable $symname -value y \
+			-relief groove -width 2 -command "sym_setvalue $symname y"
+		if { $symtype != "SYM_BOOL" && $symtype != "SYM_TRI" && $symtype != "SYM_OPTION" } {
+			$w.f$line.sy configure -text "-" -state disabled
+		} elseif { $symtype == "SYM_OPTION" } {
+			$w.f$line.sy configure -text ""
+		}
+		pack $w.f$line.sy -side left -fill y
+	}
+
+	if { $havesym & 2 } {
+		radiobutton $w.f$line.sm -text "m" -variable $symname -value m \
+			 -relief groove -width 2 -command "sym_setvalue $symname m"
+
+		if { $symtype != "SYM_MODULE" && $symtype != "SYM_TRI" } {
+			$w.f$line.sm configure -text "-" -state disabled
+		}
+		pack $w.f$line.sm -side left -fill y
+	}
+
+	if { $havesym & 1 } {
+		radiobutton $w.f$line.sn -text "n"  -variable $symname -value n \
+			-relief groove -width 2 -command "sym_setvalue $symname n"
+		if { $symtype != "SYM_BOOL" && $symtype != "SYM_TRI" } {
+			$w.f$line.sn configure -text "-" -state disabled
+		}
+		pack $w.f$line.sn -side left -fill y
+	}
+
+	message $w.f$line.m -text "$text" -anchor w -width 10000
+	pack $w.f$line.m -side left -fill both -expand on
+
+	if { $havehelp } {
+		if { $help != "" } {
+			button $w.f$line.h -text "?" -command $help
+		} else {
+			button $w.f$line.h -text "?" -state disabled -relief flat
+		}
+		pack $w.f$line.h -side left -fill y
+	}
+
+	if { $havechild } {
+		if { $child != "" } {
+			button $w.f$line.c
+			child_button_on $w $line "$text" "$child"
+		} else {
+			button $w.f$line.c -text "->" -state disabled -relief flat
+		}
+		pack $w.f$line.c -side left -fill y
+	}
+
+	pack $w.f$line -anchor w -fill both -expand y -in $w.canvas.sbf
+
+	puts stdout "MENU_DEPENDS $symname"
+}
+
+proc child_button_on { w line text child } {
+	$w.f$line.c configure -text "->"
+	$w.f$line.c configure -command "create_window $w $line \"$text\" \"$child\";$child;create_scrollbar $w.c$line"
+	$w.f$line.c configure -relief raised
+}
+
+proc child_button_off { w line } {
+	$w.f$line.c configure -text "<-"
+	$w.f$line.c configure -command "destroy $w.c$line"
+	$w.f$line.c configure -relief flat
+}
+
+proc init_window { w text } {
+
+	scrollbar $w.vscroll -command "$w.canvas yview"
+	pack $w.vscroll -side right -fill y
+
+	canvas $w.canvas -relief flat -borderwidth 0 -yscrollcommand "$w.vscroll set"
+	frame $w.canvas.sbf
+	pack $w.canvas -side right -fill y -expand on
+}
+
+proc calwi { cmd w } {
+	if { [ winfo parent $w ] != "" } {
+		return [ expr [ calwi $cmd [ winfo parent $w ] ] + [ winfo $cmd $w ] ]
+	} else {
+		return [ winfo $cmd $w ]
+	}
+}
+
+proc maxwi { cmd w } {
+	if { [ winfo parent $w ] != "" } {
+		return [ max [ maxwi $cmd [ winfo parent $w ] ]  [ winfo $cmd $w ] ]
+	} else {
+		return [ winfo $cmd $w ]
+	}
+}
+
+proc create_window { w line text child } {
+
+	toplevel $w.c$line -class Dialog
+	wm title $w.c$line $text
+
+	init_window $w.c$line $text
+
+	eval "bind $w.c$line <Destroy> { child_button_on $w $line \"$text\" \"$child\" }"
+	child_button_off $w $line
+
+#	button $w.c$line.close -text "<-" -command "destroy $w.c$line"
+#	pack $w.c$line.close -side left -anchor n
+
+#	set posx [ maxwi reqw $w ]
+#	set posy [ expr [ calwi y $w.f$line.c ] - [ calwi y $w.c$line.close ] ]
+#	set posy [ calwi y $w.f$line.c ]
+
+#	wm geometry $w.c$line +$posx+$posy
+}
+
+proc create_scrollbar { w } {
+
+	set sizok 0
+	#[expr [winfo reqheight $w.f2.ok] + 12]
+	#pack $w.canvas.sbf
+	update idletasks
+	set maxy [expr [winfo screenheight .] * 3 / 4]
+	set canvtotal [winfo reqheight $w.canvas.sbf]
+	if [expr $sizok + $canvtotal < $maxy] {
+		set sizy $canvtotal
+	} else {
+		set sizy [expr $maxy - $sizok]
+	}
+
+	$w.canvas configure -width [winfo reqw $w.canvas.sbf] -height $sizy \
+		-scrollregion "0 0 [winfo reqw $w.canvas.sbf] [winfo reqh $w.canvas.sbf]"
+	$w.canvas configure -yscrollincrement 10
+	$w.canvas create window 0 0 -anchor nw -window $w.canvas.sbf
+	pack $w.canvas -side right -fill y -expand on
+	# update idletasks
+
+}
+
+proc dohelp { w parent filename start length } {
+	catch {destroy $w }
+	toplevel $w -class Dialog
+	set filefound 0
+	if { [file readable $filename] == 1} then {
+		set filefound 1
+		set id [open $filename]
+		seek $id $start
+		set message [read $id $length]
+		close $id
+	}
+	frame $w.f1
+	pack $w.f1 -fill both -expand on
+	set oldFocus [focus]
+	frame $w.f2
+	button $w.f2.ok -text "OK" -width 10 -command "destroy $w; catch {focus $oldFocus}"
+	pack $w.f2.ok -side bottom -pady 6 -anchor n
+	pack $w.f2 -side bottom -padx 10 -anchor s
+	scrollbar $w.f1.vscroll -command "$w.f1.canvas yview"
+	pack $w.f1.vscroll -side right -fill y
+
+	canvas $w.f1.canvas -relief flat -borderwidth 0 -yscrollcommand "$w.f1.vscroll set"
+	frame $w.f1.f
+	pack $w.f1.canvas -side right -fill y -expand on
+	if { $filefound == 0 } then {
+		message $w.f1.f.m -width 750 -aspect 300 -relief flat -text \
+			"No help available - unable to open file $filename.  This file should have come with your kernel."
+		label $w.f1.bm -bitmap error
+		wm title $w "RTFM"
+	} else {
+		text $w.f1.f.m -width 73 -relief flat -wrap word
+		$w.f1.f.m insert 0.0 $message
+		$w.f1.f.m conf -state disabled -height [$w.f1.f.m index end]
+		label $w.f1.bm -bitmap info
+		wm title $w "Configuration help"
+	}
+	pack $w.f1.f.m -side left
+	pack $w.f1.bm $w.f1.f -side left -padx 10
+	focus $w
+	set winx [expr [winfo x $parent]+20]
+	set winy [expr [winfo y $parent]+20]
+	wm geometry $w +$winx+$winy
+	set sizok [expr [winfo reqheight $w.f2.ok] + 12]
+	set maxy [expr [winfo screenheight .] * 3 / 4]
+	set canvtotal [winfo reqheight $w.f1.f.m]
+	if [expr $sizok + $canvtotal < $maxy] {
+		set sizy $canvtotal
+	} else {
+		set sizy [expr $maxy - $sizok]
+	}
+	$w.f1.canvas configure -height $sizy -width [winfo reqwidth $w.f1.f.m] \
+		-scrollregion "0 0 [winfo reqwidth $w.f1.f.m] [winfo reqheight $w.f1.f.m]"
+	$w.f1.canvas create window 0 0 -anchor nw -window $w.f1.f
+	update idletasks
+	set maxy [winfo screenheight .]
+	if [expr $sizok + $canvtotal < $maxy] {
+		set sizy [expr $sizok + $canvtotal]
+	} else {
+		set sizy $maxy
+	}
+	wm maxsize $w [winfo width $w] $sizy
+}
diff -uNr kernelconf-0.1.3/conf/xconfig.c kernelconf-0.1.3.new/conf/xconfig.c
--- kernelconf-0.1.3/conf/xconfig.c	Sat Feb  9 08:53:37 2002
+++ kernelconf-0.1.3.new/conf/xconfig.c	Mon Feb 18 23:14:08 2002
@@ -6,9 +6,454 @@
  * Copyright (C) 2002 by Anuradha Ratnaweera
  */

+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "expressions.h"
+
+#include "deps.h"
+#include "help.h"
+#include "id.h"
+#include "readconfig.h"
+#include "readsymbols.h"
+#include "tokens.h"
+#include "writeconfig.h"
+#include "symbols.h"
+
+#include "sys/wait.h"
+
+#define MAX_MENU_NAME		256
+#define MAX_VALUE_SIZE	256
+
+extern IdPtr root_menu;
+
+FILE *tclf_in, *tclf_out;
+
+int type2xsize(Type type)
+{
+	switch (type) {
+	case TYPE_OPTION:
+		return 4; break;
+	case TYPE_BOOL:
+		return 5; break;
+	case TYPE_TRI:
+	case TYPE_INT:
+	case TYPE_HEX:
+	case TYPE_CHAR:
+	case TYPE_STR:
+		return 7; break;
+	default:
+		return 0;
+	}
+}
+
+void fprintf_type2name(FILE *f,Type type)
+{
+	switch (type) {
+	case TYPE_NULL:
+		fprintf(f,"SYM_NULL"); break;
+		case TYPE_BOOL:
+			fprintf(f,"SYM_BOOL"); break;
+		case TYPE_TRI:
+			fprintf(f,"SYM_TRI"); break;
+		case TYPE_INT:
+			fprintf(f,"SYM_INT"); break;
+		case TYPE_HEX:
+			fprintf(f,"SYM_HEX"); break;
+		case TYPE_CHAR:
+			fprintf(f,"SYM_CHAR"); break;
+		case TYPE_STR:
+			fprintf(f,"SYM_STR"); break;
+		case TYPE_OPTION:
+			fprintf(f,"SYM_OPTION"); break;
+		case TYPE_UNKNOWN:
+			fprintf(f,"SYM_UNKNOWN"); break;
+		case TYPE_DEPENDS:
+			fprintf(f,"SYM_DEPENDS"); break;
+		case TYPE_DERIVED:
+			fprintf(f,"SYM_DERIVED"); break;
+		case TYPE_OR:
+			fprintf(f,"SYM_OR"); break;
+		case TYPE_AND:
+			fprintf(f,"SYM_AND"); break;
+		case TYPE_EQUAL:
+			fprintf(f,"SYM_EQUAL"); break;
+		case TYPE_NOT_EQUAL:
+			fprintf(f,"SYM_NOT_EQUAL"); break;
+		case TYPE_LT:
+			fprintf(f,"SYM_LT"); break;
+		case TYPE_GT:
+			fprintf(f,"SYM_GT"); break;
+		case TYPE_LTE:
+			fprintf(f,"SYM_LTE"); break;
+		case TYPE_GTE:
+			fprintf(f,"SYM_GTE"); break;
+		case TYPE_NOT:
+			fprintf(f,"SYM_NOT"); break;
+		case TYPE_LEFT_PARA:
+			fprintf(f,"SYM_LEFT_PARA"); break;
+		case TYPE_RIGHT_PARA:
+			fprintf(f,"SYM_RIGHT_PARA"); break;
+		case TYPE_SYMBOL:
+			fprintf(f,"SYM_SYMBOLE"); break;
+		case TYPE_VALUE:
+			fprintf(f,"SYM_VALUE"); break;
+	}
+}
+
+void fprintf_prec2tk(Precedence prec)
+{
+	switch (prec) {
+		case PRE_NULL:
+			fprintf(tclf_out,"PRE_NULL"); break;
+		case PRE_ASSIGN:
+			fprintf(tclf_out,"PRE_ASSIGN"); break;
+		case PRE_OR:
+			fprintf(tclf_out,"PRE_OR"); break;
+		case PRE_AND:
+			fprintf(tclf_out,"PRE_AND"); break;
+		case PRE_EQUAL:
+			fprintf(tclf_out,"PRE_EQUAL"); break;
+		case PRE_REL:
+			fprintf(tclf_out,"PRE_REL"); break;
+		case PRE_NOT:
+			fprintf(tclf_out,"PRE_NOT"); break;
+	}
+}
+
+void fprintf_menu_name(FILE *f, IdPtr menu, int root)
+{
+	int tclidx = 0;
+	int childidx = 0;
+	IdPtr cur_menu;
+
+	if(menu->menu->parent) {
+		fprintf_menu_name(f,menu->menu->parent, 0);
+		cur_menu = menu->menu->parent->menu->first_child;
+		for(;cur_menu && (strcmp(cur_menu->name,menu->name) != 0);cur_menu = cur_menu->menu->next)
+			if(cur_menu->menu) {
+			tclidx++;
+			if(cur_menu->menu->first_child)
+				childidx++;
+			}
+		if(root)
+			fprintf(f,".f%d",tclidx);
+		else
+			fprintf(f,".c%d",childidx);
+	} else
+		fprintf(f,".f0");
+}
+
+void do_xmenu(IdPtr menu, char *name)
+{
+	char sub_name[MAX_MENU_NAME];
+	int sub_index,tclidx;
+	int have_sym		= 0;
+	int have_desc		= 0;
+	int have_child	= 0;
+	IdPtr cur_menu;
+
+	sub_index = 0;
+	for(cur_menu = menu;cur_menu;cur_menu = cur_menu->menu->next) {
+		if(cur_menu->symbol)
+			have_sym |= type2xsize(cur_menu->symbol->type);
+
+		if(cur_menu->menu->first_child) {
+			sprintf(sub_name,"%s_%d",name,sub_index++);
+			do_xmenu(cur_menu->menu->first_child,&sub_name[0]);
+			have_child = 1;
+		}
+
+		if(cur_menu->desc_length)
+			have_desc = 1;
+	}
+
+	fprintf(tclf_out,"\n");
+	fprintf(tclf_out, "proc %s { w } {\n",name);
+	sub_index = 0;
+	tclidx = 0;
+	for(cur_menu = menu;cur_menu;cur_menu = cur_menu->menu->next) {
+		/*if (cur_menu->flags & MENU_FLAG_VISIBLE) */{
+			fprintf(tclf_out, "\tconfig_option $w %d \"%s\" %s ",
+				tclidx,cur_menu->menu->caption,cur_menu->name);
+
+			if(cur_menu->symbol) {
+				fprintf_type2name(tclf_out,cur_menu->symbol->type);
+				fprintf(tclf_out, " %d ",have_sym);
+			} else {
+				fprintf(tclf_out, "SYM_NONE %d ",have_sym);
+			}
+
+			if(cur_menu->desc_length) {
+				fprintf(tclf_out, "\"dohelp .dohelp . \\\"%s\\\" %ld %ld\" true ",
+					cur_menu->config_file,
+					cur_menu->desc_start,cur_menu->desc_length);
+			} else {
+				fprintf(tclf_out, "\"\" %s ", have_desc ? "true" : "false");
+			}
+
+			if(cur_menu->menu->first_child) {
+				sprintf(sub_name,"%s_%d",name,sub_index);
+				fprintf(tclf_out, "\"%s $w.c%d\" true\n",&sub_name[0],tclidx);
+				sub_index++;
+			} else {
+				fprintf(tclf_out, "\"\" %s\n", have_child ? "true" : "false");
+			}
+
+			fprintf(tclf_out,"\n");
+			tclidx++;
+		}
+	}
+	fprintf(tclf_out, "}\n\n");
+
+}
+
+void fprintf_value2tcl(FILE *f, SymbolPtr sym)
+{
+	switch (sym->type) {
+	case TYPE_TRI:
+	case TYPE_BOOL:
+	case TYPE_OPTION:
+		fprintf(f,"%c",sym->value.char_val); break;
+	case TYPE_INT:
+	case TYPE_HEX:
+	case TYPE_CHAR:
+		fprintf(f,"%d",sym->value.int_val);	break;
+	case TYPE_SYMBOL:
+		fprintf(f,"CONFIG_%s",sym->value.id_val->name);	break;
+	case TYPE_STR:
+	case TYPE_VALUE:
+		fprintf(f,"%s",sym->value.str_val); break;
+	default:
+		break;
+	}
+}
+
+static TokenPtr tcl2value(IdPtr sym, char *value)
+{
+	TokenPtr token;
+
+	if ((sym == NULL) || (sym->symbol == NULL))
+		return NULL;
+
+	token = new_token();
+	token->type = sym->symbol->type;
+
+	switch (token->type) {
+	case TYPE_TRI:
+	case TYPE_BOOL:
+	case TYPE_OPTION:
+		token->value.char_val = value[0]; break;
+	case TYPE_INT:
+	case TYPE_HEX:
+	case TYPE_CHAR:
+		sscanf(&value[0],"%d",&token->value.int_val); break;
+	case TYPE_STR:
+	case TYPE_VALUE:
+		token->value.str_val = strdup(value); break;
+	default:
+		free(token);
+		return NULL;
+		break;
+	}
+	return token;
+}
+
+int do_xsym(IdPtr cur_sym)
+{
+	fprintf(tclf_out,"set %s ",cur_sym->name);
+	fprintf_value2tcl(tclf_out,cur_sym->symbol);
+	fprintf(tclf_out,"\n");
+	return 0;
+}
+
+void fprintf_menu_update_depends(IdPtr id)
+{
+	char resulty = 'y';
+	char resultm = 'y';
+	char orgvalue;
+
+	fprintf(tclf_out,"menu_update_depends ");
+	fprintf_menu_name(tclf_out,id,1);
+
+	if(id->symbol)
+		if(id->symbol->type == TYPE_BOOL || id->symbol->type == TYPE_TRI) {
+
+			orgvalue = id->symbol->value.char_val;
+
+			id->symbol->value.char_val = 'y';
+			if (evaluate_all_expressions(id->symbol->depends))
+				resulty = 'n';
+
+			if(id->symbol->type == TYPE_TRI) {
+				id->symbol->value.char_val = 'm';
+				if (evaluate_all_expressions(id->symbol->depends))
+					resultm = 'n';
+			} else
+					resultm = 'n';
+
+			id->symbol->value.char_val = orgvalue;
+
+		}
+
+	if(id->menu && id->menu->depends && evaluate_all_expressions(id->menu->depends)) {
+		resulty = 'n';
+		resultm = 'n';
+	}
+
+//	fprintf(stderr,"Testing %s\t%c %c\n",id->name,resulty,resultm);
+	fprintf(tclf_out," %c %c\n",resulty,resultm);
+}
+
+void do_xio()
+{
+	char *param[3];
+	int pcount,i;
+	char buffer[256];
+
+	while (fgets(&buffer[0],sizeof buffer,tclf_in)) {
+
+		pcount = sscanf(&buffer[0],"%as %as %as\n",&param[0],&param[1],&param[2]);
+
+		if (strcmp(param[0],"SYM_SET") == 0) {
+
+			IdPtr sym = search_id(param[1],ID_SEARCH);
+			IdListPtr aff;
+
+			if(sym && sym->symbol) {
+				set_symbol_value(sym,tcl2value(sym, param[2]));
+				for(aff = sym->symbol->affects; aff; aff = aff->next) {
+					if (aff->id->menu)
+						fprintf_menu_update_depends(aff->id);
+				}
+			}
+
+		} else if (strcmp(param[0],"MENU_DEPENDS") == 0) {
+
+			IdPtr menu = search_id(param[1],ID_SEARCH);
+			fprintf_menu_update_depends(menu);
+
+		}
+
+		fflush(tclf_out);
+		for(i=0;i<pcount;i++) {
+//			fprintf(stderr,"%s ",param[i]);
+			free(param[i]);
+		}
+//		fprintf(stderr,"\n");
+	}
+}
+
+pid_t do_wish()
+{
+	int x2cfiledes[2];
+	int c2xfiledes[2];
+	pid_t pid = 0;
+
+	if(pipe(&x2cfiledes[0])<0)
+		exit(1);
+
+	if(pipe(&c2xfiledes[0])<0)
+		exit(1);
+
+	pid = fork();
+
+	if(pid < 0)
+		exit(1);
+
+	if(pid==0) {
+
+		if(dup2(c2xfiledes[0],0) < 0)
+			exit(1);
+
+		if(dup2(x2cfiledes[1],1) < 0)
+			exit(1);
+
+		close(c2xfiledes[0]);
+		close(c2xfiledes[1]);
+		close(x2cfiledes[0]);
+		close(x2cfiledes[1]);
+
+		execl("/usr/bin/wish",0);
+		exit(1);
+	} else {
+		close(c2xfiledes[0]);
+		close(x2cfiledes[1]);
+
+		tclf_in = fdopen(x2cfiledes[0],"r");
+		if(!tclf_in)
+			exit(1);
+		tclf_out = fdopen(c2xfiledes[1],"w");
+		if(!tclf_out)
+			exit(1);
+	}
+
+	return pid;
+}
 
 int do_xconfig()
 {
-    return 1;
+	pid_t pid;
+
+	pid = do_wish();
+
+	fprintf(tclf_out,"source \"conf/header.tk\"\n");
+
+	traverse_symbols(do_xsym);
+	do_xmenu(root_menu->menu->first_child,"domenu");
+
+	fprintf(tclf_out,"frame .f0\n");
+	fprintf(tclf_out,"init_window .f0 \"%s\"\n",root_menu->menu->caption);
+	fprintf(tclf_out,"domenu .f0\n");
+	fprintf(tclf_out,"create_scrollbar .f0\n");
+	fprintf(tclf_out,"pack .f0\n");
+	fprintf(tclf_out,"button .save -text \"Save\" -command \"write_config\"\n");
+	fprintf(tclf_out,"pack .save\n");
+	fprintf(tclf_out,"button .load -text \"Load\" -command \"read_config\"\n");
+	fprintf(tclf_out,"pack .load\n");
+
+	fflush(tclf_out);
+	do_xio();
+	waitpid(pid,NULL,0);
+	fclose(tclf_out);
+	fclose(tclf_in);
+	return 0;
 }
 
+int main(int argc, char *argv[])
+{
+	int retval = 0;
+
+	set_precedences();
+	if ((retval = read_symbols(argv[1])))
+		return retval;
+	post_process_symbols();
+
+	read_config("arch/i386/defconfig");
+	read_config(".config");
+
+	retval = do_xconfig();
+
+	return retval;
+}
+
+int resolv_derived(IdPtr id, ExpressionPtr derived)
+{
+	return 0;
+}
+
+int resolv_depends(IdPtr id, ExpressionPtr depends)
+{
+/*Ouch This screams: Please Please FIX ME!!! */
+	set_symbol_value(id,tcl2value(id, "n"));
+	do_xsym(id);
+	return 0;
+}
+
+int resolv_depends_with_derived(IdPtr id, ExpressionPtr depends, ExpressionPtr derived)
+{
+	return 0;
+}
