First commit

Signed-off-by:  <inaky.perez-gonzalez@intel.com>
diff --git a/host/src/Makefile b/host/src/Makefile
new file mode 100644
index 0000000..4b7259c
--- /dev/null
+++ b/host/src/Makefile
@@ -0,0 +1,35 @@
+# Makefile - build all subdirectories containing [mM]akefiles
+
+# Copyright (c) 2011-2014 Wind River Systems, Inc.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1) Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2) Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3) Neither the name of Wind River Systems nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+# ensure lib is built first
+DIRS := $(filter-out lib,$(subst /,,$(sort $(dir $(wildcard */[mM]akefile)))))
+DEPS = lib
+
+include ${VXMICRO_BASE}/make/host/dir.rules
diff --git a/host/src/dec2hex/Makefile b/host/src/dec2hex/Makefile
new file mode 100644
index 0000000..22b11b0
--- /dev/null
+++ b/host/src/dec2hex/Makefile
@@ -0,0 +1,35 @@
+#
+# Makefile - builds decimal number to hexadecimal converter
+#
+
+# Copyright (c) 2013-2014 Wind River Systems, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1) Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2) Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3) Neither the name of Wind River Systems nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+EXE_NAME = dec2hex
+
+include ${VXMICRO_BASE}/make/host/exe.build
diff --git a/host/src/dec2hex/dec2hex.c b/host/src/dec2hex/dec2hex.c
new file mode 100644
index 0000000..a190465
--- /dev/null
+++ b/host/src/dec2hex/dec2hex.c
@@ -0,0 +1,56 @@
+/* dec2hex.c - convert decimal number to hexadecimal */
+
+/*
+ * Copyright (c) 2013-2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void usage (
+	char* progname /* name of the program to use */
+	)
+	{
+	fprintf (stderr, "Utility converts decimal numbers to hexadecimal\n");
+	fprintf (stderr, "Usage: %s <decimal number>\n", progname);
+	}
+
+int main (
+	int argc,
+	char* argv[]
+	)
+	{
+	if (argc != 2)
+	{
+	usage (argv[0]);
+	return -1;
+	}
+	printf ("%X\n", atoi(argv[1]));
+	return 0;
+	}
diff --git a/host/src/genIdt/Makefile b/host/src/genIdt/Makefile
new file mode 100644
index 0000000..011d826
--- /dev/null
+++ b/host/src/genIdt/Makefile
@@ -0,0 +1,34 @@
+# Makefile - generates IDT generator tool
+
+# Copyright (c) 2013-2014 Wind River Systems, Inc.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1) Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2) Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3) Neither the name of Wind River Systems nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+EXE_NAME = genIdt
+EXTRA_CFLAGS = -I${VXMICRO_BASE}/shared/include
+
+include ${VXMICRO_BASE}/make/host/exe.build
diff --git a/host/src/genIdt/genIdt.c b/host/src/genIdt/genIdt.c
new file mode 100644
index 0000000..a423ca7
--- /dev/null
+++ b/host/src/genIdt/genIdt.c
@@ -0,0 +1,339 @@
+/* genIdt.c - Create static IDT */
+
+/*
+ * Copyright (c) 2012-2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+DESCRIPTION
+Creates a static IA-32 Interrupt Descriptor Table (IDT).
+
+This program expects to be invoked as follows:
+    genIdt <file name> <number of interrupt vectors>
+All parameters are required.
+
+<file name> is assumed to be a binary file containing the intList section from
+the VxMicro ELF image (microkernel.elf, nanokernel.elf, etc.)
+
+<number of interrupt vectors> is the same as CONFIG_IDT_NUM_VECTORS.
+
+No help on usage is provided as it is expected that this program is invoked
+from within the VxMicro build system during the link stage.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <vxmicro/version.h>
+
+/* These come from the shared directory */
+#include "segselect.h"
+#include "idtEnt.h"
+
+/* Define the following macro to see a verbose or debug output from the tool */
+/*#define DEBUG_GENIDT*/
+
+#ifdef DEBUG_GENIDT
+#define PRINTF(...) printf(__VA_ARGS__)
+#else
+#define PRINTF(...) do {} while (0)
+#endif
+
+#if !defined(WINDOWS)
+  #define O_BINARY 0
+#endif
+
+static void get_exec_name(char *pathname);
+static void usage(const int len);
+static void get_options(int argc, char *argv[]);
+static void open_files(void);
+static void close_files(void);
+static void genIdt(void);
+static void clean_exit(const int exit_code);
+
+typedef struct s_isrList
+	{
+	void * fnc;
+	unsigned int dpl;
+	} ISR_LIST;
+
+static ISR_LIST idt[256];
+
+enum
+	{
+	IFILE=0,             /* input file */
+	OFILE,               /* output file */
+	NUSERFILES,          /* number of user-provided file names */
+	EXECFILE=NUSERFILES, /* for name of executable */
+	NFILES               /* total number of files open */
+	};
+enum { SHORT_USAGE, LONG_USAGE };
+
+static int fds[NUSERFILES] = {-1, -1};
+static char *filenames[NFILES];
+static unsigned int numVecs = (unsigned int)-1;
+static struct version version = {KERNEL_VERSION, 1, 1, 0};
+
+int main(int argc, char *argv[])
+	{
+	get_exec_name(argv[0]);
+	get_options(argc, argv); /* may exit */
+	open_files();	     /* may exit */
+	genIdt();
+	close_files();
+	return 0;
+	}
+
+static void get_options(int argc, char *argv[])
+	{
+	char *endptr;
+	int ii, opt;
+	while ((opt = getopt(argc, argv, "hi:o:n:v")) != -1)
+	{
+	switch(opt)
+	    {
+	    case 'i':
+		filenames[IFILE] = optarg;
+		break;
+	    case 'o':
+		{
+		filenames[OFILE] = optarg;
+		break;
+		}
+	    case 'h':
+		usage(LONG_USAGE);
+		exit(0);
+	    case 'n':
+		numVecs = (unsigned int)strtoul(optarg, &endptr, 10);
+		if (*optarg == '\0' || *endptr != '\0') {
+		    usage(SHORT_USAGE);
+		    exit(-1);
+		    }
+		break;
+	    case 'v':
+		show_version(filenames[EXECFILE], &version);
+		exit(0);
+	    default:
+		usage(SHORT_USAGE);
+		exit(-1);
+	    }
+	}
+
+	if ((unsigned int)-1 == numVecs)
+	{
+	usage(SHORT_USAGE);
+	exit(-1);
+	}
+
+	for(ii = IFILE; ii < NUSERFILES; ii++)
+	{
+	if (!filenames[ii])
+	    {
+	    usage(SHORT_USAGE);
+	    exit(-1);
+	    }
+	}
+	}
+
+static void get_exec_name(char *pathname)
+	{
+	int end = strlen(pathname)-1;
+	while(end != -1)
+	{
+    #if defined (WINDOWS) /* Might have both slashes in path */
+	if (pathname[end] == '/' || pathname[end] == '\\')
+    #else
+	if (pathname[end] == '/')
+    #endif
+	    {
+	    if (0 == end || pathname[end-1] != '\\') {
+		++end;
+		break;
+		}
+	    }
+	--end;
+	}
+	filenames[EXECFILE] = &pathname[end];
+	}
+
+static void open_files(void)
+	{
+	int ii;
+	fds[IFILE] = open(filenames[IFILE], O_RDONLY|O_BINARY);
+	fds[OFILE] = open(filenames[OFILE], O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
+		                                S_IWUSR|S_IRUSR);
+	for(ii = 0; ii < NUSERFILES; ii++)
+	{
+	int invalid = fds[ii] == -1;
+	if (invalid)
+	    {
+	    char *invalid = filenames[ii];
+	    fprintf(stderr, "invalid file %s\n", invalid);
+	    for(--ii; ii >= 0; ii--)
+		{
+		close(fds[ii]);
+		}
+	    exit (-1);
+	    }
+	}
+	}
+
+static void genIdt(void)
+	{
+	unsigned int i;
+	unsigned int size;
+	void * spurAddr;
+	void * spurNoErrAddr;
+
+    /*
+     * First find the address of the spurious interrupt handlers. They are the
+     * contained in the first 8 bytes of the input file.
+     */
+	if (read (fds[IFILE], &spurAddr, 4) < 4)
+	goto readError;
+
+	if (read (fds[IFILE], &spurNoErrAddr, 4) < 4)
+	goto readError;
+
+	PRINTF ("Spurious int handlers found at %p and %p\n",
+		    spurAddr, spurNoErrAddr);
+
+    /* Initially fill in the IDT array with the spurious handlers */
+	for (i = 0; i < numVecs; i++)
+	{
+	if ((((1 << i) & _EXC_ERROR_CODE_FAULTS)) && (i < 32))
+	    idt[i].fnc = spurAddr;
+	else
+	    idt[i].fnc = spurNoErrAddr;
+	}
+
+    /*
+     * Now parse the rest of the input file for the other ISRs. The number of
+     * entries is the next 4 bytes
+     */
+
+	if (read (fds[IFILE], &size, 4) < 4)
+	goto readError;
+
+	PRINTF ("There are %d ISR(s)\n", size);
+
+	if (size > numVecs)
+	{
+	fprintf (stderr, "Too many ISRs found. Got %u. Expected less than %u."
+	                 " Malformed input file?\n", size, numVecs);
+	clean_exit(-1);
+	}
+
+	while (size--)
+	{
+	void * addr;
+	unsigned int vec;
+	unsigned int dpl;
+
+	/* Get address */
+	if (read (fds[IFILE], &addr, 4) < 4)
+	    goto readError;
+	/* Get vector */
+	if (read (fds[IFILE], &vec, 4) < 4)
+	    goto readError;
+	/* Get dpl */
+	if (read (fds[IFILE], &dpl, 4) < 4)
+	    goto readError;
+
+	PRINTF ("ISR @ %p on Vector %d: dpl %d\n", addr, vec, dpl);
+	idt[vec].fnc = addr;
+	idt[vec].dpl = dpl;
+	}
+
+    /*
+     * We now have the address of all ISR stub/functions captured in idt[].
+     * Now construct the actual idt.
+     */
+
+	for (i = 0; i < numVecs; i++)
+	{
+	unsigned long long idtEnt;
+
+	 _IdtEntCreate (&idtEnt, idt[i].fnc, idt[i].dpl);
+
+	write (fds[OFILE], &idtEnt, 8);
+	}
+
+	return;
+
+readError:
+	fprintf(stderr, "Error occured while reading input file. Aborting...\n");
+	clean_exit(-1);
+	}
+
+static void close_files(void)
+	{
+	int ii;
+	for(ii = 0; ii < NUSERFILES; ii++)
+	{
+	close(fds[ii]);
+	}
+	}
+
+static void clean_exit(const int exit_code)
+	{
+	close_files();
+	exit(exit_code);
+	}
+
+static void usage(const int len)
+	{
+	fprintf(stderr,
+	    "\n%s -i <input file> -n <n>\n",
+	    filenames[EXECFILE]);
+
+	if (len == SHORT_USAGE)
+	{
+	return;
+	}
+
+	fprintf(stderr,
+	    "\n"
+	    " options\n"
+	    "\n"
+	    "    -i <binary file>\n\n"
+	    "        [Mandatory] The input file in binary format.\n\n"
+	    "    -o <output file>\n\n"
+	    "        [Mandatory] The output file.\n\n"
+	    "    -n <n>\n\n"
+	    "        [Mandatory] Number of vectors\n\n"
+	    "    -v  Display version.\n\n"
+	    "    -h  Display this help.\n\n"
+	    "\nReturns -1 on error, 0 on success\n\n");
+	}
diff --git a/host/src/genIdt/idtEnt.h b/host/src/genIdt/idtEnt.h
new file mode 120000
index 0000000..6a07a1d
--- /dev/null
+++ b/host/src/genIdt/idtEnt.h
@@ -0,0 +1 @@
+../../../shared/include/nanokernel/x86/idtEnt.h
\ No newline at end of file
diff --git a/host/src/genIdt/segselect.h b/host/src/genIdt/segselect.h
new file mode 120000
index 0000000..93a8255
--- /dev/null
+++ b/host/src/genIdt/segselect.h
@@ -0,0 +1 @@
+../../../shared/include/nanokernel/x86/segselect.h
\ No newline at end of file
diff --git a/host/src/genOffsetHeader/Makefile b/host/src/genOffsetHeader/Makefile
new file mode 100644
index 0000000..ba65350d
--- /dev/null
+++ b/host/src/genOffsetHeader/Makefile
@@ -0,0 +1,33 @@
+# Makefile - build offsets.h generation tool
+
+# Copyright (c) 2013-2014 Wind River Systems, Inc.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1) Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2) Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3) Neither the name of Wind River Systems nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+EXE_NAME = genOffsetHeader
+
+include ${VXMICRO_BASE}/make/host/exe.build
diff --git a/host/src/genOffsetHeader/elf.h b/host/src/genOffsetHeader/elf.h
new file mode 100644
index 0000000..2cd326a
--- /dev/null
+++ b/host/src/genOffsetHeader/elf.h
@@ -0,0 +1,389 @@
+/* elf.h - Executable and Linking Format (ELF) definitions */
+
+/*
+ * Copyright (c) 2010, 2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+DESCRIPTION
+The definitions in this header conform to the "Tool Interface Standard (TIS)
+Executable and Linking Format (ELF) Specification Version 1.2"
+*/
+
+#ifndef _ELF_H
+#define _ELF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned int    Elf32_Addr;
+typedef unsigned short  Elf32_Half;
+typedef unsigned int    Elf32_Off;
+typedef int             Elf32_Sword;
+typedef unsigned int    Elf32_Word;
+
+
+/*
+ * Elf header
+ */
+
+#define EI_NIDENT	16
+
+typedef struct
+	{
+	unsigned char e_ident[EI_NIDENT];
+	Elf32_Half	e_type;
+	Elf32_Half	e_machine;
+	Elf32_Word	e_version;
+	Elf32_Addr	e_entry;
+	Elf32_Off	e_phoff;
+	Elf32_Off	e_shoff;
+	Elf32_Word	e_flags;
+	Elf32_Half	e_ehsize;
+	Elf32_Half	e_phentsize;
+	Elf32_Half	e_phnum;
+	Elf32_Half	e_shentsize;
+	Elf32_Half	e_shnum;
+	Elf32_Half	e_shstrndx;
+	} Elf32_Ehdr;
+
+#define EHDRSZ sizeof(Elf32_Ehdr)
+
+/*
+ * e_ident[] values
+ */
+#define EI_MAG0		0
+#define EI_MAG1		1
+#define EI_MAG2		2
+#define EI_MAG3		3
+#define EI_CLASS	4
+#define EI_DATA		5
+#define EI_VERSION	6
+#define EI_PAD		7
+
+#define ELFMAG0		0x7f
+#define ELFMAG1		'E'
+#define ELFMAG2		'L'
+#define ELFMAG3		'F'
+#define ELFMAG		"\177ELF"
+#define SELFMAG		4
+
+/*
+ * EI_CLASS
+ */
+#define ELFCLASSNONE	0
+#define ELFCLASS32	1
+#define ELFCLASS64	2
+
+/*
+ * EI_DATA
+ */
+#define ELFDATANONE	0
+#define ELFDATA2LSB	1
+#define ELFDATA2MSB	2
+
+/*
+ * e_type
+ */
+#define ET_NONE		0
+#define ET_REL		1
+#define ET_EXEC		2
+#define ET_DYN		3
+#define ET_CORE		4
+#define ET_LOPROC	0xff00
+#define ET_HIPROC	0xffff
+
+/*
+ * e_machine
+ */
+#define EM_NONE		0		/* No machine */
+#define EM_M32		1		/* AT&T WE 32100 */
+#define EM_SPARC	2		/* SPARC */
+#define EM_386		3		/* Intel 80386 */
+#define EM_68K		4		/* Motorola 68000 */
+#define EM_88K		5		/* Motorola 88000 */
+#define EM_486		6		/* Intel 80486 */
+#define EM_860		7		/* Intel 80860 */
+#define EM_MIPS		8		/* MIPS RS3000 Big-Endian */
+#define EM_MIPS_RS4_BE	10		/* MIPS RS4000 Big-Endian */
+#define EM_PPC_OLD	17		/* PowerPC - old */
+#define EM_PPC		20		/* PowerPC */
+#define EM_RCE_OLD	25		/* RCE - old */
+#define EM_NEC_830	36		/* NEC 830 series */
+#define EM_RCE		39		/* RCE */
+#define EM_MCORE	39		/* MCORE */
+#define EM_ARM          40              /* ARM  */
+#define EM_SH		42		/* SH */
+#define EM_COLDFIRE	52		/* Motorola ColdFire */
+#define EM_SC		58		/* SC */
+#define EM_M32R		36929		/* M32R */
+#define EM_NEC		36992		/* NEC 850 series */
+
+/*
+ * e_flags
+ */
+#define EF_PPC_EMB		0x80000000
+
+#define EF_MIPS_NOREORDER	0x00000001
+#define EF_MIPS_PIC		0x00000002
+#define EF_MIPS_CPIC		0x00000004
+#define EF_MIPS_ARCH		0xf0000000
+#define EF_MIPS_ARCH_MIPS_2	0x10000000
+#define	EF_MIPS_ARCH_MIPS_3	0x20000000
+
+/*
+ * e_version and EI_VERSION
+ */
+#define EV_NONE		0
+#define EV_CURRENT	1
+
+/*
+ * Special section indexes
+ */
+#define SHN_UNDEF	0
+#define SHN_LORESERVE	0xff00
+#define SHN_LOPROC	0xff00
+#define SHN_HIPROC	0xff1f
+#define SHN_ABS		0xfff1
+#define SHN_COMMON	0xfff2
+#define SHN_HIRESERVE	0xffff
+
+#define SHN_GHCOMMON	0xff00
+/*
+ * Section header
+ */
+typedef struct
+	{
+	Elf32_Word	sh_name;
+	Elf32_Word	sh_type;	/* SHT_... */
+	Elf32_Word	sh_flags;	/* SHF_... */
+	Elf32_Addr	sh_addr;
+	Elf32_Off	sh_offset;
+	Elf32_Word	sh_size;
+	Elf32_Word	sh_link;
+	Elf32_Word	sh_info;
+	Elf32_Word	sh_addralign;
+	Elf32_Word	sh_entsize;
+} Elf32_Shdr;
+
+#define SHDRSZ sizeof(Elf32_Shdr)
+
+/*
+ * sh_type
+ */
+#define SHT_NULL	    0
+#define SHT_PROGBITS	    1
+#define SHT_SYMTAB	    2
+#define SHT_STRTAB	    3
+#define SHT_RELA	    4
+#define SHT_HASH	    5
+#define SHT_DYNAMIC	    6
+#define SHT_NOTE	    7
+#define SHT_NOBITS	    8
+#define SHT_REL		    9
+#define SHT_SHLIB	    10
+#define SHT_DYNSYM	    11
+#define SHT_COMDAT	    12
+#define SHT_LOPROC	    0x70000000
+#define SHT_HIPROC	    0x7fffffff
+#define SHT_LOUSER	    0x80000000
+#define SHT_HIUSER	    0xffffffff
+#define SHT_INIT_ARRAY	    14
+#define SHT_FINI_ARRAY	    15
+#define SHT_PREINIT_ARRAY   16
+#define SHT_GROUP	    17
+#define SHT_SYMTAB_SHNDX    18
+#define SHT_NUM		    19
+
+/*
+ * sh_flags
+ */
+#define SHF_WRITE		0x1
+#define SHF_ALLOC		0x2
+#define SHF_EXECINSTR		0x4
+#define SHF_MASKPROC		0xf0000000
+#define SHF_MERGE		0x10  /* not part of all ELF ABI docs */
+#define SHF_STRINGS		0x20  /* not part of all ELF ABI docs */
+#define SHF_INFO_LINK		0x40
+#define SHF_LINK_ORDER		0x80
+#define SHF_OS_NONCONFORMING	0x100
+#define SHF_GROUP		0x200
+#define SHF_TLS			0x400
+
+/*
+ * Symbol table
+ */
+typedef struct
+	{
+	Elf32_Word	st_name;
+	Elf32_Addr	st_value;
+	Elf32_Word	st_size;
+	unsigned char	st_info;
+	unsigned char	st_other;
+	Elf32_Half	st_shndx;
+	} Elf32_Sym;
+
+#define STN_UNDEF	0
+
+#define STB_LOCAL	0
+#define STB_GLOBAL	1
+#define STB_WEAK	2
+#define STB_LOPROC	13
+#define STB_HIPROC	15
+
+#define STT_NOTYPE	0
+#define STT_OBJECT	1
+#define STT_FUNC	2
+#define STT_SECTION	3
+#define STT_FILE	4
+#define STT_COMMON	5
+#define STT_TLS		6
+#define STT_LOOS	10
+#define STT_HIOS	12
+#define STT_LOPROC	13
+#define STT_HIPROC	15
+
+#define ELF_ST_BIND(x)          ((x) >> 4)
+#define ELF_ST_TYPE(x)          (((unsigned int) x) & 0xf)
+#define ELF32_ST_BIND(x)        ELF_ST_BIND(x)
+#define ELF32_ST_TYPE(x)        ELF_ST_TYPE(x)
+
+
+/*
+ * The STT_ARM_TFUNC type is used by the gnu compiler to mark Thumb
+ * functions.  The STT_ARM_16BIT type is the thumb equivalent of an
+ * object.  They are not part of the ARM ABI or EABI - they come from gnu.
+ */
+
+#define STT_ARM_TFUNC   STT_LOPROC      /* GNU Thumb function */
+#define STT_ARM_16BIT   STT_HIPROC      /* GNU Thumb label    */
+
+
+/*
+ * Relocation
+ */
+typedef struct
+	{
+	Elf32_Addr	r_offset;
+	Elf32_Word	r_info;
+	} Elf32_Rel;
+
+typedef struct
+	{
+	Elf32_Addr	r_offset;
+	Elf32_Word	r_info;
+	Elf32_Sword	r_addend;
+	} Elf32_Rela;
+
+#define ELF32_R_SYM(info)	((info)>>8)
+#define ELF32_R_TYPE(info)	((unsigned char)(info))
+#define ELF32_R_INFO(sym,type)	(((sym)<<8)+(unsigned char)(type))
+
+/*
+ * Program header
+ */
+typedef struct
+	{
+	Elf32_Word	p_type;
+	Elf32_Off	p_offset;
+	Elf32_Addr	p_vaddr;
+	Elf32_Addr	p_paddr;
+	Elf32_Word	p_filesz;
+	Elf32_Word	p_memsz;
+	Elf32_Word	p_flags;
+	Elf32_Word	p_align;
+	} Elf32_Phdr;
+
+#define PHDRSZ sizeof(Elf32_Phdr)
+
+/*
+ * p_type
+ */
+#define PT_NULL		0
+#define PT_LOAD		1
+#define PT_DYNAMIC	2
+#define PT_INTERP	3
+#define PT_NOTE		4
+#define PT_SHLIB	5
+#define PT_PHDR		6
+#define PT_LOPROC	0x70000000
+#define PT_HIPROC	0x7fffffff
+
+/*
+ * p_flags
+ */
+#define PF_X		0x1
+#define PF_W		0x2
+#define PF_R		0x4
+#define PF_MASKPROC	0xf0000000
+
+typedef struct
+	{
+	Elf32_Sword	d_tag;
+	union
+		{
+	Elf32_Word  d_val;
+	Elf32_Addr  d_ptr;
+		} d_un;
+	} Elf32_Dyn;
+
+#define DT_NULL		0
+#define DT_NEEDED	1
+#define DT_PLTRELSZ	2
+#define DT_PLTGOT	3
+#define DT_HASH		4
+#define DT_STRTAB	5
+#define DT_SYMTAB	6
+#define DT_RELA		7
+#define DT_RELASZ	8
+#define DT_RELAENT	9
+#define DT_STRSZ	10
+#define DT_SYMENT	11
+#define DT_INIT		12
+#define DT_FINI		13
+#define DT_SONAME	14
+#define DT_RPATH	15
+#define DT_SYMBOLIC	16
+#define DT_REL		17
+#define DT_RELSZ	18
+#define DT_RELENT	19
+#define DT_PLTREL	20
+#define DT_DEBUG	21
+#define DT_TEXTREL	22
+#define DT_JMPREL	23
+#define DT_LOPROC   0x70000000
+#define DT_HIPROC   0x7fffffff
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ELF_H */
diff --git a/host/src/genOffsetHeader/genOffsetHeader.c b/host/src/genOffsetHeader/genOffsetHeader.c
new file mode 100644
index 0000000..66357c3
--- /dev/null
+++ b/host/src/genOffsetHeader/genOffsetHeader.c
@@ -0,0 +1,716 @@
+/* genOffsetHeader.c - generate offset definition header file */
+
+/*
+ * Copyright (c) 2010-2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+SYNOPSIS
+.tS
+genOffsetHeader -i <objectModule> -o <outputHeaderName>
+.tE
+
+DESCRIPTION
+This VxMicro development host utility will process an ELF object module that
+consists of a series of absolute symbols representing the byte offset of a
+structure member and the size of the structure.  Each absolute symbol will
+be translated into a C preprocessor '#define' directive.  For example,
+assuming that the module offsets.o contains the following absolute symbols:
+
+  $ nm offsets.o
+  00000010 A __tNANO_common_isp_OFFSET
+  00000008 A __tNANO_current_OFFSET
+  0000000c A __tNANO_nested_OFFSET
+  00000000 A __tNANO_fiber_OFFSET
+  00000004 A __tNANO_task_OFFSET
+
+... the following C preprocessor code will be generated:
+
+  #define   __tNANO_common_isp_OFFSET  0x10
+  #define   __tNANO_current_OFFSET     0x8
+  #define   __tNANO_nested_OFFSET      0xC
+  #define   __tNANO_fiber_OFFSET       0x0
+  #define   __tNANO_task_OFFSET        0x4
+*/
+
+/* includes */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "elf.h"
+#include <stdlib.h>		/* for malloc()/free()/exit() */
+#include <string.h>		/* for strstr() */
+#include <getopt.h>
+#include <errno.h>
+
+/* defines */
+
+#undef DEBUG
+
+/* the symbol name suffix used to denote structure member offsets */
+
+#define STRUCT_OFF_SUFFIX "_OFFSET"
+#define STRUCT_SIZ_SUFFIX "_SIZEOF"
+
+#ifdef DEBUG
+#define DBG_PRINT(args...) printf(args)
+#else
+#define DBG_PRINT(args...)
+#endif
+
+
+/* byte swapping macros */
+
+#define SWAB_Elf32_Half(x)	((x >> 8) | (x << 8))
+#define SWAB_Elf32_Word(x)	(((x >> 24) & 0xff) |		\
+				((x << 8)  & 0xff0000) |	\
+		                ((x >> 8)  & 0xff00) |		\
+	                        ((x << 24) & 0xff000000))
+
+#define SWAB_Elf32_Addr	  SWAB_Elf32_Word
+#define SWAB_Elf32_Off    SWAB_Elf32_Word
+#define SWAB_Elf32_Sword  SWAB_Elf32_Word
+
+#if defined(WINDOWS)
+  #define OPEN_FLAGS (O_RDONLY|O_BINARY)
+#else
+  #define OPEN_FLAGS (O_RDONLY)
+#endif
+
+/* locals */
+
+/* global indicating whether ELF structures need to be byte swapped */
+
+static char swabRequired;
+
+
+/* usage information */
+
+static char usage[] = "usage: %s -i <objectModule> -o <outputHeaderName>\n";
+
+
+/* output header file preamble */
+
+static char preamble1[] = "\
+/* %s - structure member offsets definition header */\n\
+\n\
+/*\n\
+ * Copyright (c) 2010-2014 Wind River Systems, Inc.\n\
+ *\n\
+ * Redistribution and use in source and binary forms, with or without\n\
+ * modification, are permitted provided that the following conditions are met:\n\
+ *\n\
+ * 1) Redistributions of source code must retain the above copyright notice,\n\
+ * this list of conditions and the following disclaimer.\n\
+ *\n\
+ * 2) Redistributions in binary form must reproduce the above copyright notice,\n\
+ * this list of conditions and the following disclaimer in the documentation\n\
+ * and/or other materials provided with the distribution.\n\
+ *\n\
+ * 3) Neither the name of Wind River Systems nor the names of its contributors\n\
+ * may be used to endorse or promote products derived from this software without\n\
+ * specific prior written permission.\n\
+ *\n\
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n\
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n\
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n\
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n\
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n\
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n\
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n\
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n\
+ * POSSIBILITY OF SUCH DAMAGE.\n\
+ */\n\
+\n\
+/* THIS FILE IS AUTO GENERATED.  PLEASE DO NOT EDIT */\n\
+\n\
+/*\n\
+ * This header file provides macros for the offsets of various structure\n\
+ * members.  These offset macros are primarily intended to be used in\n\
+ * assembly code.\n\
+ */\n\n";
+
+static char preamble2[] = "\
+/*\n\
+ * Auto-generated header guard.\n\
+ */\n\
+#ifndef %s\n\
+#define %s\n\
+ \n\
+#ifdef __cplusplus\n\
+extern \"C\" {\n\
+#endif\n\
+\n\
+/* defines */\n\n";
+
+
+/* output header file postscript */
+
+static char postscript[] = "\
+\n\
+#ifdef __cplusplus\n\
+}\n\
+#endif\n\
+\n\
+#endif /* _HGUARD_ */\n";
+
+static Elf32_Ehdr	ehdr;    /* ELF header */
+static Elf32_Shdr *	shdr;    /* pointer to array ELF section headers */
+
+/*******************************************************************************
+*
+* swabElfHdr - byte swap the Elf32_Ehdr structure
+*
+* RETURNS: N/A
+*/
+
+static void swabElfHdr(Elf32_Ehdr *pHdrToSwab)
+{
+	if (swabRequired == 0)
+	   {
+	   return;  /* do nothing */
+	   }
+
+	pHdrToSwab->e_type		= SWAB_Elf32_Half (pHdrToSwab->e_type);
+	pHdrToSwab->e_machine	= SWAB_Elf32_Half (pHdrToSwab->e_machine);
+	pHdrToSwab->e_version	= SWAB_Elf32_Word (pHdrToSwab->e_version);
+	pHdrToSwab->e_entry		= SWAB_Elf32_Addr (pHdrToSwab->e_entry);
+	pHdrToSwab->e_phoff		= SWAB_Elf32_Off  (pHdrToSwab->e_phoff);
+	pHdrToSwab->e_shoff		= SWAB_Elf32_Off  (pHdrToSwab->e_shoff);
+	pHdrToSwab->e_flags		= SWAB_Elf32_Word (pHdrToSwab->e_flags);
+	pHdrToSwab->e_ehsize	= SWAB_Elf32_Half (pHdrToSwab->e_ehsize);
+	pHdrToSwab->e_phentsize	= SWAB_Elf32_Half (pHdrToSwab->e_phentsize);
+	pHdrToSwab->e_phnum		= SWAB_Elf32_Half (pHdrToSwab->e_phnum);
+	pHdrToSwab->e_shentsize	= SWAB_Elf32_Half (pHdrToSwab->e_shentsize);
+	pHdrToSwab->e_shnum		= SWAB_Elf32_Half (pHdrToSwab->e_shnum);
+	pHdrToSwab->e_shstrndx	= SWAB_Elf32_Half (pHdrToSwab->e_shstrndx);
+}
+
+/*******************************************************************************
+*
+* swabElfSectionHdr - byte swap the Elf32_Shdr structure
+*
+* RETURNS: N/A
+*/
+
+static void swabElfSectionHdr(Elf32_Shdr *pHdrToSwab)
+{
+	if (swabRequired == 0)
+	   {
+	   return;  /* do nothing */
+	   }
+
+	pHdrToSwab->sh_name		= SWAB_Elf32_Word (pHdrToSwab->sh_name);
+	pHdrToSwab->sh_type		= SWAB_Elf32_Word (pHdrToSwab->sh_type);
+	pHdrToSwab->sh_flags	= SWAB_Elf32_Word (pHdrToSwab->sh_flags);
+	pHdrToSwab->sh_addr		= SWAB_Elf32_Addr (pHdrToSwab->sh_addr);
+	pHdrToSwab->sh_offset	= SWAB_Elf32_Off  (pHdrToSwab->sh_offset);
+	pHdrToSwab->sh_size		= SWAB_Elf32_Word (pHdrToSwab->sh_size);
+	pHdrToSwab->sh_link		= SWAB_Elf32_Word (pHdrToSwab->sh_link);
+	pHdrToSwab->sh_info		= SWAB_Elf32_Word (pHdrToSwab->sh_info);
+	pHdrToSwab->sh_addralign	= SWAB_Elf32_Word (pHdrToSwab->sh_addralign);
+	pHdrToSwab->sh_addralign	= SWAB_Elf32_Word (pHdrToSwab->sh_addralign);
+}
+
+
+/*******************************************************************************
+*
+* swabElfSym - byte swap the Elf32_Sym structure
+*
+* RETURNS: N/A
+*/
+
+static void swabElfSym(Elf32_Sym *pHdrToSwab)
+{
+	if (swabRequired == 0)
+	   {
+	   return;  /* do nothing */
+	   }
+
+	pHdrToSwab->st_name		= SWAB_Elf32_Word (pHdrToSwab->st_name);
+	pHdrToSwab->st_value	= SWAB_Elf32_Addr (pHdrToSwab->st_value);
+	pHdrToSwab->st_size		= SWAB_Elf32_Word (pHdrToSwab->st_size);
+	pHdrToSwab->st_shndx	= SWAB_Elf32_Half (pHdrToSwab->st_shndx);
+}
+
+/*******************************************************************************
+*
+* ehdrLoad - load the ELF header
+*
+* RETURNS: 0 on success, -1 on failure
+*/
+
+static int ehdrLoad(int fd  /* file descriptor of file from which to read */
+					)
+{
+	unsigned  ix = 0x12345678;  /* used to auto-detect endian-ness */
+	size_t    nBytes;           /* number of bytes read from file */
+
+	lseek (fd, 0, SEEK_SET);
+
+	nBytes = read (fd, &ehdr, sizeof (ehdr));
+	if (nBytes != sizeof (ehdr))
+		{
+		fprintf (stderr, "Failed to read ELF header\n");
+		return -1;
+		}
+
+    /* perform some rudimentary ELF file validation */
+
+	if (strncmp ((char *)ehdr.e_ident, ELFMAG, 4) != 0)
+	{
+	fprintf (stderr, "Input object module not ELF format\n");
+	return -1;
+	}
+
+    /* 64-bit ELF module not supported (for now) */
+
+	if (ehdr.e_ident[EI_CLASS] != ELFCLASS32)
+		{
+	fprintf (stderr, "ELF64 class not supported\n");
+	return -1;
+	}
+
+    /*
+     * Dynamically determine the endianess of the host (in the absence of
+     * a compile time macro ala _BYTE_ORDER).  The ELF structures will require
+     * byte swapping if the host and target have different byte ordering.
+     */
+
+	if (((*(char*)&ix == 0x78) && (ehdr.e_ident[EI_DATA] == ELFDATA2MSB)) ||
+		((*(char*)&ix == 0x12) && (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)))
+		{
+	swabRequired = 1;
+	DBG_PRINT ("Swab required\n");
+	}
+
+	swabElfHdr (&ehdr);   /* swap bytes (if required) */
+
+    /* debugging: dump some important ELF header fields */
+
+	DBG_PRINT ("Elf header Magic = %s\n", ehdr.e_ident);
+	DBG_PRINT ("Elf header e_type = %d\n", ehdr.e_type);
+	DBG_PRINT ("Elf header e_shstrndx = %d\n", ehdr.e_shstrndx);
+	DBG_PRINT ("Elf header e_shnum = %d\n", ehdr.e_shnum);
+
+	return 0;
+}
+
+/*******************************************************************************
+*
+* shdrsLoad - load the section headers
+*
+* RETURNS: 0 on success, -1 on failure
+*/
+
+int shdrsLoad(int fd  /* file descriptor of file from which to read */
+			  )
+{
+	size_t    nBytes;    /* number of bytes read from file */
+	unsigned  ix;        /* loop index */
+
+	shdr = malloc (ehdr.e_shnum * sizeof (Elf32_Shdr));
+	if (shdr == NULL)
+		{
+		fprintf (stderr, "No memory for section headers!\n");
+		return -1;
+		}
+
+    /* Seek to the start of the table of section headers */
+	lseek (fd, ehdr.e_shoff, SEEK_SET);
+
+	for (ix = 0; ix < ehdr.e_shnum; ix++)
+		{
+	nBytes = read (fd, &shdr[ix], sizeof (Elf32_Shdr));
+	if (nBytes != sizeof (Elf32_Shdr))
+	    {
+	    fprintf (stderr, "Unable to read entire section header (#%d)\n",
+		             ix);
+	    return -1;
+		    }
+
+	swabElfSectionHdr (&shdr[ix]);   /* swap bytes (if required) */
+		}
+
+	return 0;
+}
+
+/*******************************************************************************
+*
+* symTblFind - search the section headers for the symbol table
+*
+* This routine searches the section headers for the symbol table.  There is
+* expected to be only one symbol table in the section headers.
+*
+* RETURNS: 0 if found, -1 if not
+*/
+
+int symTblFind(unsigned *pSymTblOffset,  /* ptr to symbol table offset */
+			   unsigned *pSymTblSize     /* ptr to symbol table size */
+			   )
+{
+	unsigned  ix;    /* loop index */
+
+	for (ix = 0; ix < ehdr.e_shnum; ++ix)
+		{
+	if (shdr[ix].sh_type == SHT_SYMTAB)
+	    {
+	    *pSymTblOffset = shdr[ix].sh_offset;
+	    *pSymTblSize   = shdr[ix].sh_size;
+
+		    return 0;
+	    }
+		}
+
+	fprintf (stderr, "Object module missing symbol table!\n");
+
+	return -1;
+}
+
+/*******************************************************************************
+*
+* strTblFind - search the section headers for the string table
+*
+* This routine searches the section headers for the string table associated
+* with the symbol names.
+*
+* Typically, there are two string tables defined in the section headers.  These
+* are ".shstrtbl" and ".strtbl" for section header names and symbol names
+* respectively.  It has been observed with the DIAB compiler (but not with
+* either the GCC nor ICC compilers) that the two tables may be mashed together
+* into one.  Consequently, the following algorithm is used to select the
+* appropriate string table.
+*
+* 1. Assume that the first found string table is valid.
+* 2. If another string table is found, use that only if its section header
+*    index does not match the index for ".shstrtbl" stored in the ELF header.
+*
+* RETURNS 0 if found, -1 if not
+*/
+
+int strTblFind(unsigned *pStrTblIx  /* ptr to string table's index */
+			   )
+{
+	unsigned  strTblIx = 0xffffffff;
+	unsigned  ix;
+
+	for (ix = 0; ix < ehdr.e_shnum; ++ix)
+		{
+		if (shdr[ix].sh_type == SHT_STRTAB)
+		    {
+		    if ((strTblIx == 0xffffffff) ||
+		        (ix != ehdr.e_shstrndx))
+		        {
+		        strTblIx = ix;
+		        }
+		    }
+		}
+
+	if (strTblIx == 0xffffffff)
+		{
+		fprintf (stderr, "Object module missing string table!\n");
+		return -1;
+		}
+
+	*pStrTblIx = strTblIx;
+
+	return 0;
+}
+
+/*******************************************************************************
+*
+* strTblLoad - load the string table
+*
+* RETURNS: 0 on success, -1 on failure
+*/
+
+int strTblLoad(int fd, /* file descriptor of file from which to read */
+			   unsigned strTblIx, /* string table's index */
+			   char **ppStringTable /* ptr to ptr to string table */
+			   )
+{
+	char *  pTable;
+	int     nBytes;
+
+	DBG_PRINT ("Allocating %d bytes for string table\n",
+		       shdr[strTblIx].sh_size);
+
+	pTable = malloc (shdr[strTblIx].sh_size);
+	if (pTable == NULL)
+		{
+		fprintf (stderr, "No memory for string table!");
+		return -1;
+		}
+
+	lseek (fd, shdr[strTblIx].sh_offset, SEEK_SET);
+
+	nBytes = read (fd, pTable, shdr[strTblIx].sh_size);
+	if (nBytes != shdr[strTblIx].sh_size)
+		{
+		free (pTable);
+		fprintf (stderr, "Unable to read entire string table!\n");
+		return -1;
+		}
+
+	*ppStringTable = pTable;
+
+	return 0;
+}
+
+/*******************************************************************************
+*
+* headerPreambleDump - dump the header preamble to the header file
+*
+* RETURNS: N/A
+*/
+
+void headerPreambleDump(FILE *fp,       /* file pointer to which to write */
+						char *filename  /* name of the output file */
+						)
+{
+	unsigned hash = 5381;      /* hash value */
+	size_t   ix;               /* loop counter */
+	char     fileNameHash[20]; /* '_HGUARD_' + 8 character hash + '\0' */
+
+    /* dump header file preamble1[] */
+
+	fprintf (fp, preamble1, filename, filename, filename);
+
+    /*
+     * Dump header file preamble2[]. Hash file name into something that
+     * is small enough to be a C macro name and does not have invalid
+     * characters for a macro name to use as a header guard. The result
+     * of the hash should be unique enough for our purposes.
+     */
+
+	for (ix = 0; ix < sizeof(filename); ++ix)
+		{
+		hash = (hash * 33) + (unsigned int) filename[ix];
+		}
+
+	sprintf(fileNameHash, "_HGUARD_%08x", hash);
+	fprintf (fp, preamble2, fileNameHash, fileNameHash);
+}
+
+/*******************************************************************************
+*
+* headerAbsoluteSymbolsDump - dump the absolute symbols to the header file
+*
+* RETURNS: N/A
+*/
+
+void headerAbsoluteSymbolsDump(int fd,   /* file descriptor of file from which to read */
+							   FILE *fp, /* file pointer to which to write */
+							   Elf32_Off symTblOffset, /* symbol table offset */
+							   Elf32_Word symTblSize,  /* size of the symbol table */
+							   char *pStringTable      /* ptr to the string table */
+							   )
+{
+	Elf32_Sym  aSym;     /* absolute symbol */
+	unsigned   ix;       /* loop counter */
+	unsigned   numSyms;  /* number of symbols in the symbol table */
+
+    /* context the symbol table: pick out absolute syms */
+
+	numSyms = symTblSize / sizeof(Elf32_Sym);
+	lseek (fd, symTblOffset, SEEK_SET);
+
+	for (ix = 0; ix < numSyms; ++ix)
+	{
+	/* read in a single symbol structure */
+
+	read (fd, &aSym, sizeof(Elf32_Sym));
+
+	swabElfSym (&aSym);    /* swap bytes (if required) */
+
+	/*
+	 * Only generate definitions for global absolute symbols
+	 * of the form *_OFFSET
+	 */
+
+	if ((aSym.st_shndx == SHN_ABS) &&
+	    (ELF_ST_BIND(aSym.st_info) == STB_GLOBAL))
+	    {
+	    if ((strstr (&pStringTable[aSym.st_name],
+		                 STRUCT_OFF_SUFFIX) != NULL) ||
+	        (strstr (&pStringTable[aSym.st_name],
+		                 STRUCT_SIZ_SUFFIX) != NULL))
+		        {
+		fprintf (fp, "#define\t%s\t0x%X\n",
+		                 &pStringTable[aSym.st_name], aSym.st_value);
+	        }
+	   }
+	}
+}
+
+/*******************************************************************************
+*
+* headerPostscriptDump - dump the header postscript to the header file
+*
+* RETURNS: N/A
+*/
+
+void headerPostscriptDump(FILE *fp  /* file pointer to which to write */
+						  )
+{
+	fputs (postscript, fp);
+}
+
+/*******************************************************************************
+*
+* main - entry point for the genOffsetHeader utility
+*
+* usage: $ genOffsetHeader -i <objectModule> -o <outputHeaderName>
+*
+* RETURNS: 0 on success, 1 on failure
+*/
+
+int main(int argc, char *argv[])
+{
+	Elf32_Off	symTblOffset = 0;
+	Elf32_Word	symTblSize;		/* in bytes */
+	char *	pStringTable = NULL;
+	char *	inFileName;
+	char *	outFileName;
+	int		option;
+	int		inFd = -1;
+	FILE *	outFile = NULL;
+	unsigned    strTblIx;
+
+    /* argument parsing */
+
+	if (argc != 5)
+		{
+		fprintf (stderr, usage, argv[0]);
+	goto errorReturn;
+	}
+
+	while ((option = getopt (argc, argv, "i:o:")) != -1)
+		{
+	switch (option)
+	    {
+	    case 'i':
+	        inFileName = optarg;
+		break;
+	    case 'o':
+		outFileName = optarg;
+		break;
+	    default:
+		fprintf (stderr, usage, argv[0]);
+		goto errorReturn;
+	    }
+	}
+
+    /* open input object ELF module and output header file */
+
+	inFd = open (inFileName, OPEN_FLAGS);
+
+	if (inFd == -1)
+		{
+	fprintf (stderr, "Cannot open input object module");
+	goto errorReturn;
+	}
+
+	outFile = fopen (outFileName, "w");
+
+	if (outFile == NULL)
+		{
+	fprintf (stderr, "Cannot open output header file");
+	goto errorReturn;
+	}
+
+    /*
+     * In the following order, attempt to ...
+     *  1. Load the ELF header
+     *  2. Load the section headers
+     *  3. Find the symbol table
+     *  4. Find the string table
+     *  5. Load the string table
+     * Bail if any of those steps fail.
+     */
+
+	if ((ehdrLoad (inFd) != 0) ||
+		(shdrsLoad (inFd) != 0) ||
+		(symTblFind (&symTblOffset, &symTblSize) != 0) ||
+		(strTblFind (&strTblIx) != 0) ||
+		(strTblLoad (inFd, strTblIx, &pStringTable) != 0))
+		{
+		goto errorReturn;
+		}
+
+
+    /*
+     * Dump the following to the header file ...
+     *  1. Header file preamble
+     *  2. Absolute symbols
+     *  3. Header file postscript
+     */
+
+	headerPreambleDump (outFile, outFileName);
+	headerAbsoluteSymbolsDump (inFd, outFile,
+		                       symTblOffset, symTblSize, pStringTable);
+	headerPostscriptDump (outFile);
+
+    /* done: cleanup */
+
+	close (inFd);
+	fclose (outFile);
+	free (shdr);
+	free (pStringTable);
+
+	return 0;
+
+errorReturn:
+	if (inFd != -1)
+		{
+		close (inFd);
+		}
+
+	if (outFile != NULL)
+		{
+		fclose (outFile);
+		}
+
+	if (shdr != NULL)
+		{
+		free (shdr);
+		}
+
+	if (pStringTable != NULL)
+		{
+		free (pStringTable);
+		}
+
+	return 1;
+}
diff --git a/host/src/gen_config_abssym/Makefile b/host/src/gen_config_abssym/Makefile
new file mode 100644
index 0000000..885c9d6
--- /dev/null
+++ b/host/src/gen_config_abssym/Makefile
@@ -0,0 +1,33 @@
+# Makefile - build configs.c absolute symbols generator
+
+# Copyright (c) 2014 Wind River Systems, Inc.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1) Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2) Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3) Neither the name of Wind River Systems nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+EXE_NAME = gen_config_abssym
+
+include ${VXMICRO_BASE}/make/host/exe.build
diff --git a/host/src/gen_config_abssym/gen_config_abssym.c b/host/src/gen_config_abssym/gen_config_abssym.c
new file mode 100644
index 0000000..d4f029f
--- /dev/null
+++ b/host/src/gen_config_abssym/gen_config_abssym.c
@@ -0,0 +1,261 @@
+/* gen_config_abssym.c - generate configs.c from autoconf.h
+*/
+
+/*
+ * Copyright (c) 2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+DESCRIPTION
+
+Generate configs.c file containing absolute symbols for kconfig options from
+autoconf.h.
+
+configs.c is responsible for the generation of the absolute symbols whose
+value represents the settings of various CONFIG configuration options.
+These symbols can be used by the VxMicro host tools to determine the
+configuration options in effect when the microkernel or nanokernel was built.
+
+If a configuration macro is defined, a corresponding absolute symbol should
+be generated.  The absolute symbol should have the same name as the
+configuration macro.  The symbol value should be:
+ - the integer 1 for configuration macros of type "bool" (which is the value
+   assigned to these macros in <autoconf.h>)
+ - the macro value for configuration macros of type "int" or "hex"
+ - the integer 1 for configuration macros of type "string", as it is not
+   possible to represent the actual value of the configuration macro.
+
+No corresponding symbol should be generated when a macro is not defined.
+
+All of the absolute symbols defined by configs.c will be present in the
+final microkernel or nanokernel ELF image (due to the linker's reference to
+the _ConfigAbsSyms symbol).
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <vxmicro.h>
+
+static void usage(const int len);
+static void get_options(int argc, char *argv[]);
+static void open_files(void);
+static void close_files(void);
+static void generate_files(void);
+static void clean_exit(const int exit_code);
+
+enum {
+	IFILE=0,		/* input file */
+	OFILE,			/* C output file */
+	NUSERFILES,		/* number of user-provided file names */
+	EXECFILE=NUSERFILES,	/* for name of executable */
+	NFILES			/* total number of files open */
+};
+enum { SHORT_USAGE, LONG_USAGE };
+
+static int fds[NUSERFILES] = {-1, -1};
+static const char *filenames[NFILES];
+static struct version version = {KERNEL_VERSION, 1, 0, 0};
+
+int main(int argc, char *argv[])
+{
+	filenames[EXECFILE] = basename(argv[0]);
+	get_options(argc, argv); /* may exit */
+	open_files();		 /* may exit */
+	generate_files();
+	close_files();
+	return 0;
+}
+
+static void get_options(int argc, char *argv[])
+{
+	int ii, opt;
+	while ((opt = getopt(argc, argv, "hi:o:v")) != -1) {
+		switch(opt) {
+		case 'i':
+			filenames[IFILE] = optarg;
+			break;
+		case 'o':
+			filenames[OFILE] = optarg;
+			break;
+		case 'h':
+			usage(LONG_USAGE);
+			exit(0);
+		case 'v':
+			show_version(filenames[EXECFILE], &version);
+			exit(0);
+		default:
+			usage(SHORT_USAGE);
+			exit(-1);
+		}
+	}
+	for(ii = IFILE; ii < NUSERFILES; ii++) {
+		if (!filenames[ii]) {
+			usage(SHORT_USAGE);
+			exit(-1);
+		}
+	}
+}
+
+static void open_files(void)
+{
+	const int open_w_flags = O_WRONLY|O_CREAT|O_TRUNC;
+	const mode_t open_mode = S_IWUSR|S_IRUSR;
+	int ii;
+
+	fds[IFILE] = open_binary(filenames[IFILE], O_RDONLY);
+	fds[OFILE] = open(filenames[OFILE], open_w_flags, open_mode);
+
+	for(ii = 0; ii < NUSERFILES; ii++) {
+		int invalid = fds[ii] == -1;
+		if (invalid) {
+			const char *invalid = filenames[ii];
+			fprintf(stderr, "invalid file %s\n", invalid);
+			for(--ii; ii >= 0; ii--) {
+				close(fds[ii]);
+			}
+			exit (-1);
+		}
+	}
+}
+
+static void write_str(const char *str)
+{
+	int len = strlen(str);
+	if (write(fds[OFILE], str, len) != len) {
+		perror("write");
+		clean_exit(-1);
+	}
+}
+
+static void generate_files(void)
+{
+	char *buf, *pBuf;
+	struct stat autoconf_h_stat;
+	off_t size;
+
+	if (stat(filenames[IFILE], &autoconf_h_stat) == -1) {
+		perror("stat");
+		clean_exit(-1);
+	}
+
+	buf = malloc(autoconf_h_stat.st_size);
+	if (!buf) {
+		perror("out-of-memory");
+		clean_exit(-1);
+	}
+
+	size = read(fds[IFILE], buf, autoconf_h_stat.st_size);
+	if (autoconf_h_stat.st_size != size) {
+		perror("read");
+		clean_exit(-1);
+	}
+
+	pBuf = buf;
+	pBuf = strstr(pBuf, "#define AUTOCONF_INCLUDED");
+
+	write_str("/* file is auto-generated, do not modify ! */\n\n");
+	write_str("#include <absSym.h>\n\n");
+	write_str("GEN_ABS_SYM_BEGIN (_ConfigAbsSyms)\n\n");
+
+	for (;;) {
+		char *sym, *val, *endl, *str = "1";
+
+		pBuf = strstr(pBuf, "#");
+		if (!strncmp(pBuf, "#endif", strlen("#endif"))) {
+			break;
+		}
+
+		sym = strstr(pBuf, "CONFIG");
+		val = strstr(sym, " ") + 1;
+		endl = strstr(val, ENDL);
+
+		val[-1] = 0;
+		endl[0] = 0;
+
+		if (val[0] == '\"') {
+			val = str;
+		}
+
+		write_str("GEN_ABSOLUTE_SYM(");
+		write_str(sym);
+		write_str(", ");
+		write_str(val);
+		write_str(");\n");
+
+		pBuf = endl + 1;
+	}
+
+	write_str("\nGEN_ABS_SYM_END\n");
+
+	free(buf);
+}
+
+static void close_files(void)
+{
+	int ii;
+	for(ii = 0; ii < NUSERFILES; ii++) {
+		close(fds[ii]);
+	}
+}
+
+static void clean_exit(const int exit_code)
+{
+	close_files();
+	exit(exit_code);
+}
+
+static void usage(const int len)
+{
+	fprintf(stderr,
+		"\n%s -i <autoconf.h> -o <output>\n",
+		filenames[EXECFILE]);
+
+	if (len == SHORT_USAGE) {
+		return;
+	}
+
+	fprintf(stderr,
+		"\n"
+		" options\n"
+		"\n"
+		"    -i <autoconf.h>\n\n"
+		"        [Mandatory] The pathname of autoconf.h.\n\n"
+		"    -o <output>\n\n"
+		"        [Mandatory] The pathname of output configs.c.\n"
+		"    -v  Display version.\n\n"
+		"    -h  Display this help.\n\n"
+		"\nReturns -1 on error, 0 on success\n\n");
+}
diff --git a/host/src/include/vxmicro.h b/host/src/include/vxmicro.h
new file mode 100644
index 0000000..deee1a7
--- /dev/null
+++ b/host/src/include/vxmicro.h
@@ -0,0 +1,35 @@
+/* vxmicro.h - master header file for vxmicro host tools libraries */
+
+/*
+ * Copyright (c) 2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <vxmicro/version.h>
+#include <vxmicro/os.h>
+#include <vxmicro/util.h>
diff --git a/host/src/include/vxmicro/os.h b/host/src/include/vxmicro/os.h
new file mode 100644
index 0000000..66e2082
--- /dev/null
+++ b/host/src/include/vxmicro/os.h
@@ -0,0 +1,59 @@
+/* os.h - OS abstraction library */
+
+/*
+ * Copyright (c) 2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _os__h_
+#define _os__h_
+
+#if defined (WINDOWS)
+  #define ENDL "\r\n"
+#else
+  #define ENDL "\n"
+#endif
+
+#if defined (WINDOWS)
+static inline
+int is_path_separator(const char c)
+{
+	/* Might have both '/' and '\' in path */
+	return c == '/' || c == '\\';
+}
+#else
+static inline
+int is_path_separator(const char c)
+{
+	return c == '/';
+}
+#endif
+
+extern int open_binary(const char *pathname, int flags, ...);
+
+#endif /* _os__h_ */
diff --git a/host/src/include/vxmicro/util.h b/host/src/include/vxmicro/util.h
new file mode 100644
index 0000000..2b516c4
--- /dev/null
+++ b/host/src/include/vxmicro/util.h
@@ -0,0 +1,46 @@
+/* util.h - misc utilities for build host tools */
+
+/*
+ * Copyright (c) 2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _UTIL__H_
+#define _UTIL__H_
+
+#define ALIAS(fn,fn_alias,ret) ret fn_alias() __attribute__((alias(#fn)));
+
+extern const char * basename(const char *pathname);
+
+static inline
+unsigned long round_up(unsigned long x, unsigned long align)
+{
+	return ((x + (align - 1)) & ~(align - 1));
+}
+
+#endif /* _UTIL__H_ */
diff --git a/host/src/include/vxmicro/version.h b/host/src/include/vxmicro/version.h
new file mode 100644
index 0000000..68e444a
--- /dev/null
+++ b/host/src/include/vxmicro/version.h
@@ -0,0 +1,40 @@
+/* version.h - version number library */
+
+/*
+ * Copyright (c) 2013-2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+struct version {
+	int kernel;
+	int major;
+	int minor;
+	int maintenance;
+};
+
+extern void show_version(const char *name, const struct version *ver);
diff --git a/host/src/lib/Makefile b/host/src/lib/Makefile
new file mode 100644
index 0000000..6dd4608
--- /dev/null
+++ b/host/src/lib/Makefile
@@ -0,0 +1,33 @@
+# Makefile - build vxmicro library
+
+# Copyright (c) 2013-2014 Wind River Systems, Inc.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1) Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2) Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3) Neither the name of Wind River Systems nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+LIB_NAME = vxmicro
+
+include ${VXMICRO_BASE}/make/host/lib.build
diff --git a/host/src/lib/os.c b/host/src/lib/os.c
new file mode 100644
index 0000000..800e1c7
--- /dev/null
+++ b/host/src/lib/os.c
@@ -0,0 +1,56 @@
+/* os.c - OS abstraction library */
+
+/*
+ * Copyright (c) 2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+
+#include <vxmicro.h>
+
+#if defined (WINDOWS)
+  #define WITH_BINARY(x) (x | O_BINARY)
+#else
+  #define WITH_BINARY(x) (x)
+#endif
+
+int open_binary(const char *pathname, int flags, ...)
+{
+	va_list ap;
+	int fd;
+
+	va_start(ap, flags);
+	fd = open(pathname, WITH_BINARY(flags), va_arg(ap, int));
+	va_end(ap);
+
+	return fd;
+}
diff --git a/host/src/lib/util.c b/host/src/lib/util.c
new file mode 100644
index 0000000..ef8491d
--- /dev/null
+++ b/host/src/lib/util.c
@@ -0,0 +1,49 @@
+/* util.c - misc utilities library */
+
+/*
+ * Copyright (c) 2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <vxmicro/os.h>
+
+const char * basename(const char *pathname)
+{
+	int end = strlen(pathname)-1;
+	while(end != -1) {
+		if (is_path_separator(pathname[end])) {
+			if (0 == end || pathname[end-1] != '\\') {
+				++end;
+				break;
+			}
+		}
+		--end;
+	}
+	return &pathname[end];
+}
diff --git a/host/src/lib/version.c b/host/src/lib/version.c
new file mode 100644
index 0000000..56345c7
--- /dev/null
+++ b/host/src/lib/version.c
@@ -0,0 +1,45 @@
+/* version.c - version number library */
+
+/*
+ * Copyright (c) 2013-2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <vxmicro/version.h>
+
+void show_version(const char *name, const struct version *ver)
+{
+	fprintf(stdout,
+		"\n%s"
+		" %4d.%d.%d.%3.3d, (c) Wind River Systems, Inc.\n"
+		" Built on %s at %s\n\n",
+		name,
+		ver->kernel, ver->major, ver->minor, ver->maintenance,
+		__DATE__, __TIME__);
+}
diff --git a/host/src/mkEvents/Makefile b/host/src/mkEvents/Makefile
new file mode 100644
index 0000000..e3155f0
--- /dev/null
+++ b/host/src/mkEvents/Makefile
@@ -0,0 +1,35 @@
+#
+# Makefile
+#
+
+# Copyright (c) 2013-2014 Wind River Systems, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1) Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2) Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3) Neither the name of Wind River Systems nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+EXE_NAME = mkevents
+
+include ${VXMICRO_BASE}/make/host/exe.build
diff --git a/host/src/mkEvents/mkevents.c b/host/src/mkEvents/mkevents.c
new file mode 100644
index 0000000..81e5d79
--- /dev/null
+++ b/host/src/mkEvents/mkevents.c
@@ -0,0 +1,71 @@
+/* mkevents.c - Create A VPF Event */
+
+/*
+ * Copyright (c) 2013-2014 Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+DESCRIPTION
+Creates event object line(s) suitable for inclusion in a VPF file.
+The number of events to create is passed in on the command line
+in decimal notation. Each event object is outputted on stdout.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void usage (
+	char* progname /* name of the program to use */
+	)
+	{
+	fprintf (stderr, "Utility creates a series of microkernel VPF event objects. Output is sent to stdout.\n");
+	fprintf (stderr, "Usage: %s <decimal number>\n", progname);
+	}
+
+#define EVENT_STR "  EVENT    _TaskIrqEvt%d  NULL\n"
+
+int main (
+	int argc,
+	char* argv[]
+	)
+	{
+	int i, j;
+
+	if (argc != 2)
+	{
+	usage (argv[0]);
+	return -1;
+	}
+
+	j = atoi(argv[1]);
+	for (i = 0; i < j; i++)
+	printf (EVENT_STR, i);
+
+	return 0;
+	}
diff --git a/host/src/wrsconfig/COPYING-GPL-2.0.txt b/host/src/wrsconfig/COPYING-GPL-2.0.txt
new file mode 100755
index 0000000..fbdd65f
--- /dev/null
+++ b/host/src/wrsconfig/COPYING-GPL-2.0.txt
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE

+		       Version 2, June 1991

+

+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.

+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+ Everyone is permitted to copy and distribute verbatim copies

+ of this license document, but changing it is not allowed.

+

+			    Preamble

+

+  The licenses for most software are designed to take away your

+freedom to share and change it.  By contrast, the GNU General Public

+License is intended to guarantee your freedom to share and change free

+software--to make sure the software is free for all its users.  This

+General Public License applies to most of the Free Software

+Foundation's software and to any other program whose authors commit to

+using it.  (Some other Free Software Foundation software is covered by

+the GNU Library General Public License instead.)  You can apply it to

+your programs, too.

+

+  When we speak of free software, we are referring to freedom, not

+price.  Our General Public Licenses are designed to make sure that you

+have the freedom to distribute copies of free software (and charge for

+this service if you wish), that you receive source code or can get it

+if you want it, that you can change the software or use pieces of it

+in new free programs; and that you know you can do these things.

+

+  To protect your rights, we need to make restrictions that forbid

+anyone to deny you these rights or to ask you to surrender the rights.

+These restrictions translate to certain responsibilities for you if you

+distribute copies of the software, or if you modify it.

+

+  For example, if you distribute copies of such a program, whether

+gratis or for a fee, you must give the recipients all the rights that

+you have.  You must make sure that they, too, receive or can get the

+source code.  And you must show them these terms so they know their

+rights.

+

+  We protect your rights with two steps: (1) copyright the software, and

+(2) offer you this license which gives you legal permission to copy,

+distribute and/or modify the software.

+

+  Also, for each author's protection and ours, we want to make certain

+that everyone understands that there is no warranty for this free

+software.  If the software is modified by someone else and passed on, we

+want its recipients to know that what they have is not the original, so

+that any problems introduced by others will not reflect on the original

+authors' reputations.

+

+  Finally, any free program is threatened constantly by software

+patents.  We wish to avoid the danger that redistributors of a free

+program will individually obtain patent licenses, in effect making the

+program proprietary.  To prevent this, we have made it clear that any

+patent must be licensed for everyone's free use or not licensed at all.

+

+  The precise terms and conditions for copying, distribution and

+modification follow.

+

+		    GNU GENERAL PUBLIC LICENSE

+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+

+  0. This License applies to any program or other work which contains

+a notice placed by the copyright holder saying it may be distributed

+under the terms of this General Public License.  The "Program", below,

+refers to any such program or work, and a "work based on the Program"

+means either the Program or any derivative work under copyright law:

+that is to say, a work containing the Program or a portion of it,

+either verbatim or with modifications and/or translated into another

+language.  (Hereinafter, translation is included without limitation in

+the term "modification".)  Each licensee is addressed as "you".

+

+Activities other than copying, distribution and modification are not

+covered by this License; they are outside its scope.  The act of

+running the Program is not restricted, and the output from the Program

+is covered only if its contents constitute a work based on the

+Program (independent of having been made by running the Program).

+Whether that is true depends on what the Program does.

+

+  1. You may copy and distribute verbatim copies of the Program's

+source code as you receive it, in any medium, provided that you

+conspicuously and appropriately publish on each copy an appropriate

+copyright notice and disclaimer of warranty; keep intact all the

+notices that refer to this License and to the absence of any warranty;

+and give any other recipients of the Program a copy of this License

+along with the Program.

+

+You may charge a fee for the physical act of transferring a copy, and

+you may at your option offer warranty protection in exchange for a fee.

+

+  2. You may modify your copy or copies of the Program or any portion

+of it, thus forming a work based on the Program, and copy and

+distribute such modifications or work under the terms of Section 1

+above, provided that you also meet all of these conditions:

+

+    a) You must cause the modified files to carry prominent notices

+    stating that you changed the files and the date of any change.

+

+    b) You must cause any work that you distribute or publish, that in

+    whole or in part contains or is derived from the Program or any

+    part thereof, to be licensed as a whole at no charge to all third

+    parties under the terms of this License.

+

+    c) If the modified program normally reads commands interactively

+    when run, you must cause it, when started running for such

+    interactive use in the most ordinary way, to print or display an

+    announcement including an appropriate copyright notice and a

+    notice that there is no warranty (or else, saying that you provide

+    a warranty) and that users may redistribute the program under

+    these conditions, and telling the user how to view a copy of this

+    License.  (Exception: if the Program itself is interactive but

+    does not normally print such an announcement, your work based on

+    the Program is not required to print an announcement.)

+

+These requirements apply to the modified work as a whole.  If

+identifiable sections of that work are not derived from the Program,

+and can be reasonably considered independent and separate works in

+themselves, then this License, and its terms, do not apply to those

+sections when you distribute them as separate works.  But when you

+distribute the same sections as part of a whole which is a work based

+on the Program, the distribution of the whole must be on the terms of

+this License, whose permissions for other licensees extend to the

+entire whole, and thus to each and every part regardless of who wrote it.

+

+Thus, it is not the intent of this section to claim rights or contest

+your rights to work written entirely by you; rather, the intent is to

+exercise the right to control the distribution of derivative or

+collective works based on the Program.

+

+In addition, mere aggregation of another work not based on the Program

+with the Program (or with a work based on the Program) on a volume of

+a storage or distribution medium does not bring the other work under

+the scope of this License.

+

+  3. You may copy and distribute the Program (or a work based on it,

+under Section 2) in object code or executable form under the terms of

+Sections 1 and 2 above provided that you also do one of the following:

+

+    a) Accompany it with the complete corresponding machine-readable

+    source code, which must be distributed under the terms of Sections

+    1 and 2 above on a medium customarily used for software interchange; or,

+

+    b) Accompany it with a written offer, valid for at least three

+    years, to give any third party, for a charge no more than your

+    cost of physically performing source distribution, a complete

+    machine-readable copy of the corresponding source code, to be

+    distributed under the terms of Sections 1 and 2 above on a medium

+    customarily used for software interchange; or,

+

+    c) Accompany it with the information you received as to the offer

+    to distribute corresponding source code.  (This alternative is

+    allowed only for noncommercial distribution and only if you

+    received the program in object code or executable form with such

+    an offer, in accord with Subsection b above.)

+

+The source code for a work means the preferred form of the work for

+making modifications to it.  For an executable work, complete source

+code means all the source code for all modules it contains, plus any

+associated interface definition files, plus the scripts used to

+control compilation and installation of the executable.  However, as a

+special exception, the source code distributed need not include

+anything that is normally distributed (in either source or binary

+form) with the major components (compiler, kernel, and so on) of the

+operating system on which the executable runs, unless that component

+itself accompanies the executable.

+

+If distribution of executable or object code is made by offering

+access to copy from a designated place, then offering equivalent

+access to copy the source code from the same place counts as

+distribution of the source code, even though third parties are not

+compelled to copy the source along with the object code.

+

+  4. You may not copy, modify, sublicense, or distribute the Program

+except as expressly provided under this License.  Any attempt

+otherwise to copy, modify, sublicense or distribute the Program is

+void, and will automatically terminate your rights under this License.

+However, parties who have received copies, or rights, from you under

+this License will not have their licenses terminated so long as such

+parties remain in full compliance.

+

+  5. You are not required to accept this License, since you have not

+signed it.  However, nothing else grants you permission to modify or

+distribute the Program or its derivative works.  These actions are

+prohibited by law if you do not accept this License.  Therefore, by

+modifying or distributing the Program (or any work based on the

+Program), you indicate your acceptance of this License to do so, and

+all its terms and conditions for copying, distributing or modifying

+the Program or works based on it.

+

+  6. Each time you redistribute the Program (or any work based on the

+Program), the recipient automatically receives a license from the

+original licensor to copy, distribute or modify the Program subject to

+these terms and conditions.  You may not impose any further

+restrictions on the recipients' exercise of the rights granted herein.

+You are not responsible for enforcing compliance by third parties to

+this License.

+

+  7. If, as a consequence of a court judgment or allegation of patent

+infringement or for any other reason (not limited to patent issues),

+conditions are imposed on you (whether by court order, agreement or

+otherwise) that contradict the conditions of this License, they do not

+excuse you from the conditions of this License.  If you cannot

+distribute so as to satisfy simultaneously your obligations under this

+License and any other pertinent obligations, then as a consequence you

+may not distribute the Program at all.  For example, if a patent

+license would not permit royalty-free redistribution of the Program by

+all those who receive copies directly or indirectly through you, then

+the only way you could satisfy both it and this License would be to

+refrain entirely from distribution of the Program.

+

+If any portion of this section is held invalid or unenforceable under

+any particular circumstance, the balance of the section is intended to

+apply and the section as a whole is intended to apply in other

+circumstances.

+

+It is not the purpose of this section to induce you to infringe any

+patents or other property right claims or to contest validity of any

+such claims; this section has the sole purpose of protecting the

+integrity of the free software distribution system, which is

+implemented by public license practices.  Many people have made

+generous contributions to the wide range of software distributed

+through that system in reliance on consistent application of that

+system; it is up to the author/donor to decide if he or she is willing

+to distribute software through any other system and a licensee cannot

+impose that choice.

+

+This section is intended to make thoroughly clear what is believed to

+be a consequence of the rest of this License.

+

+  8. If the distribution and/or use of the Program is restricted in

+certain countries either by patents or by copyrighted interfaces, the

+original copyright holder who places the Program under this License

+may add an explicit geographical distribution limitation excluding

+those countries, so that distribution is permitted only in or among

+countries not thus excluded.  In such case, this License incorporates

+the limitation as if written in the body of this License.

+

+  9. The Free Software Foundation may publish revised and/or new versions

+of the General Public License from time to time.  Such new versions will

+be similar in spirit to the present version, but may differ in detail to

+address new problems or concerns.

+

+Each version is given a distinguishing version number.  If the Program

+specifies a version number of this License which applies to it and "any

+later version", you have the option of following the terms and conditions

+either of that version or of any later version published by the Free

+Software Foundation.  If the Program does not specify a version number of

+this License, you may choose any version ever published by the Free Software

+Foundation.

+

+  10. If you wish to incorporate parts of the Program into other free

+programs whose distribution conditions are different, write to the author

+to ask for permission.  For software which is copyrighted by the Free

+Software Foundation, write to the Free Software Foundation; we sometimes

+make exceptions for this.  Our decision will be guided by the two goals

+of preserving the free status of all derivatives of our free software and

+of promoting the sharing and reuse of software generally.

+

+			    NO WARRANTY

+

+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY

+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN

+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES

+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED

+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS

+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE

+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,

+REPAIR OR CORRECTION.

+

+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING

+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR

+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,

+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING

+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED

+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY

+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER

+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE

+POSSIBILITY OF SUCH DAMAGES.

+

+		     END OF TERMS AND CONDITIONS

+

+	    How to Apply These Terms to Your New Programs

+

+  If you develop a new program, and you want it to be of the greatest

+possible use to the public, the best way to achieve this is to make it

+free software which everyone can redistribute and change under these terms.

+

+  To do so, attach the following notices to the program.  It is safest

+to attach them to the start of each source file to most effectively

+convey the exclusion of warranty; and each file should have at least

+the "copyright" line and a pointer to where the full notice is found.

+

+    <one line to give the program's name and a brief idea of what it does.>

+    Copyright (C) <year>  <name of author>

+

+    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

+

+

+Also add information on how to contact you by electronic and paper mail.

+

+If the program is interactive, make it output a short notice like this

+when it starts in an interactive mode:

+

+    Gnomovision version 69, Copyright (C) year  name of author

+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.

+    This is free software, and you are welcome to redistribute it

+    under certain conditions; type `show c' for details.

+

+The hypothetical commands `show w' and `show c' should show the appropriate

+parts of the General Public License.  Of course, the commands you use may

+be called something other than `show w' and `show c'; they could even be

+mouse-clicks or menu items--whatever suits your program.

+

+You should also get your employer (if you work as a programmer) or your

+school, if any, to sign a "copyright disclaimer" for the program, if

+necessary.  Here is a sample; alter the names:

+

+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program

+  `Gnomovision' (which makes passes at compilers) written by James Hacker.

+

+  <signature of Ty Coon>, 1 April 1989

+  Ty Coon, President of Vice

+

+This General Public License does not permit incorporating your program into

+proprietary programs.  If your program is a subroutine library, you may

+consider it more useful to permit linking proprietary applications with the

+library.  If this is what you want to do, use the GNU Library General

+Public License instead of this License.

diff --git a/host/src/wrsconfig/Makefile b/host/src/wrsconfig/Makefile
new file mode 100644
index 0000000..a582329
--- /dev/null
+++ b/host/src/wrsconfig/Makefile
@@ -0,0 +1,37 @@
+# Makefile - build wrsconfig tool
+
+# Copyright (c) 2011-2014 Wind River Systems, Inc.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1) Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2) Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3) Neither the name of Wind River Systems nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+EXE_NAME = wrsconfig
+SOURCES = conf.c zconf.tab.c
+
+EXTRA_CFLAGS  = -DKBUILD_NO_NLS=no -DNO_REGEX -DNO_UNAME
+EXTRA_CFLAGS_win32 = -DHOST_WIN32
+
+include ${VXMICRO_BASE}/make/host/exe.build
diff --git a/host/src/wrsconfig/conf.c b/host/src/wrsconfig/conf.c
new file mode 100755
index 0000000..e906351
--- /dev/null
+++ b/host/src/wrsconfig/conf.c
@@ -0,0 +1,695 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/stat.h>
+
+#ifdef HOST_WIN32
+  extern long int random(void);
+  extern void srandom(unsigned int seed);
+#endif
+
+extern int conf_warnings;
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+/* undef SYMNAME to hide the name of the component being set */
+#define SYMNAME
+/* define PREFIX to get the full name of the component */
+/*#define PREFIX */
+
+char *myName; /* name of the program taken from argv[0] */
+
+static void conf(struct menu *menu);
+static void check_conf(struct menu *menu);
+
+enum {
+	ask_all,
+	ask_new,
+	ask_silent,
+	set_default,
+	set_yes,
+	set_mod,
+	set_no,
+	set_random,
+	set_new_default
+} input_mode = ask_all;
+char *defconfig_file;
+
+static int indent = 1;
+static int valid_stdin = 1;
+static int quiet = 0;
+static int conf_cnt;
+static char line[512];
+static struct menu *rootEntry;
+
+#define print_nq(arg...) do {if (quiet == 0){printf(arg);}} while (quiet < 0)
+
+static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
+
+static const char *get_help(struct menu *menu)
+{
+	if (menu_has_help(menu))
+		return menu_get_help(menu);
+	else
+		return nohelp_text;
+}
+
+static void strip(char *str)
+{
+	char *p = str;
+	int l;
+
+	while ((isspace(*p)))
+		p++;
+	l = strlen(p);
+	if (p != str)
+		memmove(str, p, l + 1);
+	if (!l)
+		return;
+	p = str + l - 1;
+	while ((isspace(*p)))
+		*p-- = 0;
+}
+
+static void check_stdin(void)
+{
+	if (!valid_stdin && input_mode == ask_silent) {
+		printf(_("aborted!\n\n"));
+		printf(_("Console input/output is redirected. \n\n"));
+		exit(1);
+	}
+}
+
+static int conf_askvalue(struct symbol *sym, const char *def)
+{
+	enum symbol_type type = sym_get_type(sym);
+	tristate val;
+
+#ifdef IDENTIFY_NEW
+	if (!sym_has_value(sym))
+		print_nq("(NEW) ");
+#endif
+	line[0] = '\n';
+	line[1] = 0;
+
+	if (!sym_is_changable(sym)) {
+		print_nq("%s\n", def);
+		line[0] = '\n';
+		line[1] = 0;
+		return 0;
+	}
+
+	switch (input_mode) {
+	case set_no:
+	case set_mod:
+	case set_yes:
+	case set_random:
+	case set_new_default:
+		if (sym_has_value(sym)) {
+			print_nq("%s\n", def);
+			return 0;
+		}
+		break;
+	case ask_new:
+	case ask_silent:
+		if (sym_has_value(sym)) {
+			print_nq("%s\n", def);
+			return 0;
+		}
+		check_stdin();
+	case ask_all:
+		fflush(stdout);
+		fgets(line, sizeof(line), stdin);
+		return 1;
+	case set_default:
+		print_nq("%s\n", def);
+		return 1;
+	default:
+		break;
+	}
+
+	switch (type) {
+	case S_INT:
+	case S_HEX:
+	case S_STRING:
+		print_nq("%s\n", def);
+		return 1;
+	default:
+		;
+	}
+	switch (input_mode) {
+	case set_yes:
+		if (sym_tristate_within_range(sym, yes)) {
+			line[0] = 'y';
+			line[1] = '\n';
+			line[2] = 0;
+			break;
+		}
+	case set_mod:
+		if (type == S_TRISTATE) {
+			if (sym_tristate_within_range(sym, mod)) {
+				line[0] = 'm';
+				line[1] = '\n';
+				line[2] = 0;
+				break;
+			}
+		} else {
+			if (sym_tristate_within_range(sym, yes)) {
+				line[0] = 'y';
+				line[1] = '\n';
+				line[2] = 0;
+				break;
+			}
+		}
+	case set_no:
+		if (sym_tristate_within_range(sym, no)) {
+			line[0] = 'n';
+			line[1] = '\n';
+			line[2] = 0;
+			break;
+		}
+	case set_random:
+		do {
+			val = (tristate)(random() % 3);
+		} while (!sym_tristate_within_range(sym, val));
+
+		switch (val) {
+		case no: line[0] = 'n'; break;
+		/*case mod: line[0] = 'm'; break;*/
+		/*case yes: line[0] = 'y'; break;*/
+            /* since we are not supporting the m mode anything that is not n is y */
+		default: line[0] = 'y'; break;
+		}
+		line[1] = '\n';
+		line[2] = 0;
+		break;
+	case set_new_default:
+		line[0] = *def;
+		line[1] = '\n';
+		line[2] = 0;
+		break;
+	default:
+		break;
+	}
+	print_nq("%s", line);
+	return 1;
+}
+
+int conf_string(struct menu *menu)
+{
+	struct symbol *sym = menu->sym;
+	const char *def;
+
+	while (1) {
+		print_nq("%*s%s ", indent - 1, "", menu->prompt->text);
+
+#ifdef SYMNAME
+#ifdef PREFIX
+		print_nq(" (CONFIG_%s) ", sym->name);
+#else
+		        print_nq(" (%s) ", sym->name);
+#endif
+#endif
+		def = sym_get_string_value(sym);
+		if (sym_get_string_value(sym))
+			print_nq("[%s] ", def);
+		if (!conf_askvalue(sym, def))
+			return 0;
+		switch (line[0]) {
+		case '\n':
+			break;
+		case '?':
+			/* print help */
+			if (line[1] == '\n') {
+				print_nq("\n%s\n", get_help(menu));
+				def = NULL;
+				break;
+			}
+		default:
+			line[strlen(line)-1] = 0;
+			def = line;
+		}
+		if (def && sym_set_string_value(sym, def))
+			return 0;
+	}
+}
+
+static int conf_sym(struct menu *menu)
+{
+	struct symbol *sym = menu->sym;
+	tristate oldval, newval;
+
+	while (1) {
+		print_nq("%*s%s ", indent - 1, "", menu->prompt->text);
+#ifdef SYMNAME
+		if (sym->name)
+#ifdef PREFIX
+			print_nq(" (CONFIG_%s) ", sym->name);
+#else
+			print_nq(" (%s) ", sym->name);
+#endif
+#endif
+		print_nq("[");
+		oldval = sym_get_tristate_value(sym);
+		switch (oldval) {
+		case no:
+			print_nq("N");
+			break;
+		case mod:
+			print_nq("M");
+			break;
+		case yes:
+			print_nq("Y");
+			break;
+		}
+		if (oldval != no && sym_tristate_within_range(sym, no))
+			print_nq("/n");
+		if (oldval != mod && sym_tristate_within_range(sym, mod))
+			print_nq("/m");
+		if (oldval != yes && sym_tristate_within_range(sym, yes))
+			print_nq("/y");
+		if (menu_has_help(menu))
+			print_nq("/?");
+		print_nq("] ");
+		if (!conf_askvalue(sym, sym_get_string_value(sym)))
+			return 0;
+		strip(line);
+
+		switch (line[0]) {
+		case 'n':
+		case 'N':
+			newval = no;
+			if (!line[1] || !strcmp(&line[1], "o"))
+				break;
+			continue;
+		case 'm':
+		case 'M':
+			newval = mod;
+			if (!line[1])
+				break;
+			continue;
+		case 'y':
+		case 'Y':
+			newval = yes;
+			if (!line[1] || !strcmp(&line[1], "es"))
+				break;
+			continue;
+		case 0:
+			newval = oldval;
+			break;
+		case '?':
+			goto help;
+		default:
+			continue;
+		}
+		if (sym_set_tristate_value(sym, newval))
+			return 0;
+help:
+		print_nq("\n%s\n", get_help(menu));
+	}
+}
+
+static int conf_choice(struct menu *menu)
+{
+	struct symbol *sym, *def_sym;
+	struct menu *child;
+	bool is_new;
+
+	sym = menu->sym;
+	is_new = !sym_has_value(sym);
+	if (sym_is_changable(sym)) {
+		conf_sym(menu);
+		sym_calc_value(sym);
+		switch (sym_get_tristate_value(sym)) {
+		case no:
+			return 1;
+		case mod:
+			return 0;
+		case yes:
+			break;
+		}
+	} else {
+		switch (sym_get_tristate_value(sym)) {
+		case no:
+			return 1;
+		case mod:
+			print_nq("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+			return 0;
+		case yes:
+			break;
+		}
+	}
+
+	while (1) {
+		int cnt, def;
+
+		print_nq("%*s%s\n", indent - 1, "", menu_get_prompt(menu));
+		def_sym = sym_get_choice_value(sym);
+		cnt = def = 0;
+		line[0] = 0;
+		for (child = menu->list; child; child = child->next) {
+			if (!menu_is_visible(child))
+				continue;
+			if (!child->sym) {
+				print_nq("%*c %s\n", indent, '*', menu_get_prompt(child));
+				continue;
+			}
+			cnt++;
+			if (child->sym == def_sym) {
+				def = cnt;
+				print_nq("%*c", indent, '>');
+			} else
+				print_nq("%*c", indent, ' ');
+			print_nq(" %d. %s", cnt, menu_get_prompt(child));
+
+#ifdef SYMNAME
+			if (child->sym->name)
+#ifdef PREFIX
+				print_nq(" (CONFIG_%s)",child->sym->name);
+#else
+				print_nq(" (%s)", child->sym->name);
+#endif
+#endif
+#ifdef IDENTIFY_NEW
+			if (!sym_has_value(child->sym))
+				print_nq(" (NEW)");
+#endif
+			print_nq("\n");
+		}
+		print_nq("%*schoice", indent - 1, "");
+		if (cnt == 1) {
+			print_nq("[1]: 1\n");
+			goto conf_childs;
+		}
+		print_nq("[1-%d", cnt);
+		if (menu_has_help(menu))
+			print_nq("?");
+		print_nq("]: ");
+		switch (input_mode) {
+		case ask_new:
+		case ask_silent:
+			if (!is_new) {
+				cnt = def;
+				print_nq("%d\n", cnt);
+				break;
+			}
+			check_stdin();
+		case ask_all:
+			fflush(stdout);
+			fgets(line, sizeof(line), stdin);
+			strip(line);
+			if (line[0] == '?') {
+				print_nq("\n%s\n", get_help(menu));
+				continue;
+			}
+			if (!line[0])
+				cnt = def;
+			else if (isdigit(line[0]))
+				cnt = atoi(line);
+			else
+				continue;
+			break;
+		case set_random:
+			def = (random() % cnt) + 1;
+		case set_default:
+		case set_yes:
+		case set_mod:
+		case set_no:
+		case set_new_default:
+			cnt = def;
+			print_nq("%d\n", cnt);
+			break;
+		}
+
+conf_childs:
+		for (child = menu->list; child; child = child->next) {
+			if (!child->sym || !menu_is_visible(child))
+				continue;
+			if (!--cnt)
+				break;
+		}
+		if (!child)
+			continue;
+		if (line[strlen(line) - 1] == '?') {
+			print_nq("\n%s\n", get_help(child));
+			continue;
+		}
+		sym_set_choice_value(sym, child->sym);
+		if (child->list) {
+			indent += 2;
+			conf(child->list);
+			indent -= 2;
+		}
+		return 1;
+	}
+}
+
+static void conf(struct menu *menu)
+{
+	struct symbol *sym;
+	struct property *prop;
+	struct menu *child;
+
+	if (!menu_is_visible(menu))
+		return;
+
+	sym = menu->sym;
+	prop = menu->prompt;
+	if (prop) {
+		const char *prompt;
+
+		switch (prop->type) {
+		case P_MENU:
+			if (input_mode == ask_silent && rootEntry != menu) {
+				check_conf(menu);
+				return;
+			}
+		case P_COMMENT:
+			prompt = menu_get_prompt(menu);
+			if (prompt)
+				print_nq("%*c\n%*c %s\n%*c\n",
+					indent, '*',
+					indent, '*', prompt,
+					indent, '*');
+		default:
+			;
+		}
+	}
+
+	if (!sym)
+		goto conf_childs;
+
+	if (sym_is_choice(sym)) {
+		conf_choice(menu);
+		if (sym->curr.tri != mod)
+			return;
+		goto conf_childs;
+	}
+
+	switch (sym->type) {
+	case S_INT:
+	case S_HEX:
+	case S_STRING:
+		conf_string(menu);
+		break;
+	default:
+		conf_sym(menu);
+		break;
+	}
+
+conf_childs:
+	if (sym)
+		indent += 2;
+	for (child = menu->list; child; child = child->next)
+		conf(child);
+	if (sym)
+		indent -= 2;
+}
+
+static void check_conf(struct menu *menu)
+{
+	struct symbol *sym;
+	struct menu *child;
+
+	if (!menu_is_visible(menu))
+		return;
+
+	sym = menu->sym;
+	if (sym && !sym_has_value(sym)) {
+		if (sym_is_changable(sym) ||
+		    (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
+			if (!conf_cnt++)
+				print_nq(_("*\n* Restart config...\n*\n"));
+			rootEntry = menu_get_parent_menu(menu);
+			conf(rootEntry);
+		}
+	}
+
+	for (child = menu->list; child; child = child->next)
+		check_conf(child);
+}
+
+int main(int ac, char **av)
+{
+	int i = 1;
+	const char *name;
+	struct stat tmpstat;
+	quiet = 0;
+
+	myName = av[0];
+
+	if (ac > i && av[i][0] == '-') {
+		switch (av[i++][1]) {
+		case 'o':
+			input_mode = ask_new;
+			break;
+		case 's':
+			input_mode = ask_silent;
+			valid_stdin = isatty(0) && isatty(1) && isatty(2);
+			break;
+		case 'S':
+			input_mode = set_new_default;
+			quiet = 1;
+			break;
+		case 'd':
+			input_mode = set_default;
+			break;
+		case 'D':
+			input_mode = set_default;
+			defconfig_file = av[i++];
+			if (!defconfig_file) {
+				printf(_("%s: No default config file specified\n"),
+					av[0]);
+				exit(1);
+			}
+			break;
+		case 'n':
+			input_mode = set_no;
+			break;
+		case 'm':
+			input_mode = set_mod;
+			break;
+		case 'y':
+			input_mode = set_yes;
+			break;
+		case 'r':
+			input_mode = set_random;
+			srandom(time(NULL));
+			break;
+		case 'h':
+		case '?':
+			fprintf(stderr, "See README for usage info\n");
+			exit(0);
+		}
+	}
+	name = av[i];
+	if (!name) {
+		printf(_("%s: config file name parameter missing\n"), av[0]);
+		exit(1);
+	}
+	conf_parse(name);
+	/* zconfdump(stdout); */
+	switch (input_mode) {
+	case set_default:
+		if (!defconfig_file)
+			defconfig_file = conf_get_default_confname();
+		if (conf_read(defconfig_file)) {
+			printf("***\n"
+				"*** Can't find default configuration \"%s\"!\n"
+				"***\n", defconfig_file);
+			exit(1);
+		}
+		break;
+	case ask_silent:
+#ifdef VXWORKS
+		if (stat("vsb.config", &tmpstat)) {
+#else
+		if (stat(".config", &tmpstat)) {
+#endif
+			printf(_("***\n"
+				"missing configuration file can not run in silent mode"
+				"***\n"));
+			exit(1);
+		}
+	case ask_all:
+	case ask_new:
+		conf_read(NULL);
+		break;
+	case set_no:
+	case set_mod:
+	case set_yes:
+	case set_random:
+	case set_new_default:
+		name = getenv("WRSCONFIG_ALLCONFIG");
+		if (!name) /* check old env name */
+			name = getenv("VCONFIG_ALLCONFIG");
+		if (name && !stat(name, &tmpstat)) {
+			conf_read_simple(name, S_DEF_USER);
+			break;
+		}
+		switch (input_mode) {
+		case set_no:	 name = "allno.config"; break;
+		case set_mod:	 name = "allmod.config"; break;
+		case set_yes:	 name = "allyes.config"; break;
+		case set_random: name = "allrandom.config"; break;
+		case set_new_default: name = "alldef.config"; break;
+		default: break;
+		}
+		if (!stat(name, &tmpstat))
+			conf_read_simple(name, S_DEF_USER);
+		else if (!stat("all.config", &tmpstat))
+			conf_read_simple("all.config", S_DEF_USER);
+		break;
+	default:
+		break;
+	}
+
+	if (conf_warnings) {
+		fprintf(stderr, _("\n*** Configuration warning(s) found\n\n"));
+		return 1;
+	}
+
+	if (input_mode != ask_silent) {
+		rootEntry = &rootmenu;
+		conf(&rootmenu);
+		if (input_mode == ask_all) {
+			input_mode = ask_silent;
+			valid_stdin = 1;
+		}
+	} else if (conf_get_changed()) {
+		name = getenv("WRSCONFIG_NOSILENTUPDATE");
+		if (!name) /* check old env name */
+			name = getenv("VCONFIG_NOSILENTUPDATE");
+		if (name && *name) {
+			fprintf(stderr, _("\n*** configuration requires explicit update.\n\n"));
+			return 1;
+		}
+	} else
+		goto skip_check;
+
+	do {
+		conf_cnt = 0;
+		check_conf(&rootmenu);
+	} while (conf_cnt);
+
+	if (conf_write(NULL)) {
+		fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
+		return 1;
+	}
+
+skip_check:
+	if (conf_write_autoconf()) {
+		fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
+		return 1;
+	}
+
+	return 0;
+}
diff --git a/host/src/wrsconfig/confdata.c b/host/src/wrsconfig/confdata.c
new file mode 100755
index 0000000..700320b
--- /dev/null
+++ b/host/src/wrsconfig/confdata.c
@@ -0,0 +1,915 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <sys/stat.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+extern char *myName;
+
+static void conf_warning(const char *fmt, ...)
+	__attribute__ ((format (printf, 1, 2)));
+
+static const char *conf_filename;
+static int conf_lineno, conf_unsaved;
+int conf_warnings;
+
+static void conf_warning(const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno);
+	vfprintf(stderr, fmt, ap);
+	fprintf(stderr, "\n");
+	va_end(ap);
+	conf_warnings++;
+}
+
+const char *conf_get_configname(void)
+{
+	char *name = getenv("WRSCONFIG_CONFIG");
+	if (!name) /* check old env name */
+		name = getenv("VCONFIG_CONFIG");
+
+#ifdef VXWORKS
+	return name ? name : "vsb.config";
+#else
+	return name ? name : ".config";
+#endif
+}
+
+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)
+{
+	static char fullname[PATH_MAX+1];
+#if 0
+this bogus code turned off.  env is never null so no need for if (env)
+which is always true.  Thus, we generate a /default.vxconfig fullname
+since env is "".  The stat of that always fails so we never return fullname.
+Also, since default.vxconfig has no expansions in it there is no need
+to try expand it.  We can replace all this code with "return conf_defname;".
+However we want to rename vxConfig to wrsConfig so the default config
+filename should be default.wrsConfig.  Thus we generate the default filename
+so it is backwards compatible in case this program is called vxConfig.
+
+	const char conf_defname[] = "default.vxconfig";
+
+	struct stat buf;
+	char *env, *name;
+
+	name = conf_expand_value(conf_defname);
+	env = "";
+	/* env = getenv(SRCTREE); */
+	if (env) {
+		sprintf(fullname, "%s/%s", env, name);
+		if (!stat(fullname, &buf))
+			return fullname;
+	}
+	return name;
+#endif
+
+	if (strcmp (myName, "vxConfig") == 0)
+	    return "default.vxconfig";
+
+	sprintf (fullname, "default.%s", myName);
+
+	return fullname;
+}
+
+int conf_read_simple(const char *name, int def)
+{
+	FILE *in = NULL;
+	char line[1024];
+	char *p, *p2;
+	struct symbol *sym;
+	int i, def_flags;
+	int pfx = strlen("CONFIG_");
+
+	if (name) {
+		in = zconf_fopen(name);
+	} else {
+		struct property *prop;
+
+		name = conf_get_configname();
+		in = zconf_fopen(name);
+
+		if (in)
+			goto load;
+
+		sym_add_change_count(1);
+		if (!sym_defconfig_list)
+			return 1;
+
+		for_all_defaults(sym_defconfig_list, prop) {
+			if (expr_calc_value(prop->visible.expr) == no ||
+			    prop->expr->type != E_SYMBOL)
+				continue;
+			name = conf_expand_value(prop->expr->left.sym->name);
+			in = zconf_fopen(name);
+			if (in) {
+				printf(_("#\n"
+					 "# using defaults found in %s\n"
+					 "#\n"), name);
+				goto load;
+			}
+		}
+	}
+	if (!in)
+		return 1;
+
+load:
+	conf_filename = name;
+	conf_lineno = 0;
+	conf_warnings = 0;
+	conf_unsaved = 0;
+
+	def_flags = SYMBOL_DEF << def;
+	for_all_symbols(i, sym) {
+		sym->flags |= SYMBOL_CHANGED;
+		sym->flags &= ~(def_flags|SYMBOL_VALID);
+		if (sym_is_choice(sym))
+			sym->flags |= def_flags;
+		switch (sym->type) {
+		case S_INT:
+		case S_HEX:
+		case S_STRING:
+			if (sym->def[def].val)
+				free(sym->def[def].val);
+		default:
+			sym->def[def].val = NULL;
+			sym->def[def].tri = no;
+		}
+	}
+
+	while (fgets(line, sizeof(line), in)) {
+		conf_lineno++;
+		sym = NULL;
+		switch (line[0]) {
+		case '#':
+			if (memcmp(line + 2, "CONFIG_", pfx))
+				continue;
+			p = strchr(line + 2 + pfx, ' ');
+			if (!p)
+				continue;
+			*p++ = 0;
+			if (strncmp(p, "is not set", 10))
+				continue;
+			if (def == S_DEF_USER) {
+				sym = sym_find(line + 2 + pfx);
+				if (!sym) {
+					conf_warning("trying to assign nonexistent symbol %s", line + 2 + pfx);
+					break;
+				}
+			} else {
+				sym = sym_lookup(line + 2 + pfx, 0);
+				if (sym->type == S_UNKNOWN)
+					sym->type = S_BOOLEAN;
+			}
+			if (sym->flags & def_flags) {
+				conf_warning("trying to reassign symbol %s", sym->name);
+				break;
+			}
+			switch (sym->type) {
+			case S_BOOLEAN:
+			case S_TRISTATE:
+				sym->def[def].tri = no;
+				sym->flags |= def_flags;
+				break;
+			default:
+				;
+			}
+			break;
+		case 'C':
+			if (memcmp(line, "CONFIG_", pfx)) {
+				conf_warning("unexpected data");
+				continue;
+			}
+			p = strchr(line + pfx, '=');
+			if (!p)
+				continue;
+			*p++ = 0;
+			p2 = strchr(p, '\n');
+			if (p2) {
+				*p2-- = 0;
+				if (*p2 == '\r')
+					*p2 = 0;
+			}
+			if (def == S_DEF_USER) {
+				sym = sym_find(line + pfx);
+				if (!sym) {
+					conf_warning("trying to assign nonexistent symbol %s", line + pfx);
+					break;
+				}
+			} else {
+				sym = sym_lookup(line + pfx, 0);
+				if (sym->type == S_UNKNOWN)
+					sym->type = S_OTHER;
+			}
+			if (sym->flags & def_flags) {
+				conf_warning("trying to reassign symbol %s", sym->name);
+				break;
+			}
+			switch (sym->type) {
+			case S_TRISTATE:
+				if (p[0] == 'm') {
+					sym->def[def].tri = mod;
+					sym->flags |= def_flags;
+					break;
+				}
+			case S_BOOLEAN:
+				if (p[0] == 'y') {
+					sym->def[def].tri = yes;
+					sym->flags |= def_flags;
+					break;
+				}
+				if (p[0] == 'n') {
+					sym->def[def].tri = no;
+					sym->flags |= def_flags;
+					break;
+				}
+				conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+				break;
+			case S_OTHER:
+				if (*p != '"') {
+					for (p2 = p; *p2 && !isspace(*p2); p2++)
+						;
+					sym->type = S_STRING;
+					goto done;
+				}
+			case S_STRING:
+				if (*p++ != '"')
+					break;
+				for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) {
+					if (*p2 == '"') {
+						*p2 = 0;
+						break;
+					}
+					memmove(p2, p2 + 1, strlen(p2));
+				}
+				if (!p2) {
+					conf_warning("invalid string found");
+					continue;
+				}
+			case S_INT:
+			case S_HEX:
+done:
+				if (sym_string_valid(sym, p)) {
+					sym->def[def].val = strdup(p);
+					sym->flags |= def_flags;
+				} else {
+					conf_warning("symbol value '%s' invalid for %s", p, sym->name);
+					continue;
+				}
+				break;
+			default:
+				;
+			}
+			break;
+		case '\r':
+		case '\n':
+			break;
+		default:
+			conf_warning("unexpected data");
+			continue;
+		}
+		if (sym && sym_is_choice_value(sym)) {
+			struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
+			switch (sym->def[def].tri) {
+			case no:
+				break;
+			case mod:
+				if (cs->def[def].tri == yes) {
+					conf_warning("%s creates inconsistent choice state", sym->name);
+					cs->flags &= ~def_flags;
+				}
+				break;
+			case yes:
+				if (cs->def[def].tri != no) {
+					conf_warning("%s creates inconsistent choice state", sym->name);
+					cs->flags &= ~def_flags;
+				} else
+					cs->def[def].val = sym;
+				break;
+			}
+			cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri);
+		}
+	}
+	fclose(in);
+
+	if (modules_sym)
+		sym_calc_value(modules_sym);
+	return 0;
+}
+
+int conf_read(const char *name)
+{
+	struct symbol *sym;
+	struct property *prop;
+	struct expr *e;
+	int i, flags;
+
+	sym_set_change_count(0);
+
+	if (conf_read_simple(name, S_DEF_USER))
+		return 1;
+
+	for_all_symbols(i, sym) {
+		sym_calc_value(sym);
+		if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
+			goto sym_ok;
+		if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
+			/* check that calculated value agrees with saved value */
+			switch (sym->type) {
+			case S_BOOLEAN:
+			case S_TRISTATE:
+				if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
+					break;
+				if (!sym_is_choice(sym))
+					goto sym_ok;
+			default:
+				if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
+					goto sym_ok;
+				break;
+			}
+		} else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
+			/* no previous value and not saved */
+			goto sym_ok;
+		conf_unsaved++;
+		/* maybe print value in verbose mode... */
+sym_ok:
+		if (!sym_is_choice(sym))
+			continue;
+		/* The choice symbol only has a set value (and thus is not new)
+		 * if all its visible childs have values.
+		 */
+		prop = sym_get_choice_prop(sym);
+		flags = sym->flags;
+		for (e = prop->expr; e; e = e->left.expr)
+			if (e->right.sym->visible != no)
+				flags &= e->right.sym->flags;
+		sym->flags &= flags | ~SYMBOL_DEF_USER;
+	}
+
+	for_all_symbols(i, sym) {
+		if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
+			/* Reset values of generates values, so they'll appear
+			 * as new, if they should become visible, but that
+			 * doesn't quite work if the Kconfig and the saved
+			 * configuration disagree.
+			 */
+			if (sym->visible == no && !conf_unsaved)
+				sym->flags &= ~SYMBOL_DEF_USER;
+			switch (sym->type) {
+			case S_STRING:
+			case S_INT:
+			case S_HEX:
+				/* Reset a string value if it's out of range */
+				if (sym_string_within_range(sym, sym->def[S_DEF_USER].val))
+					break;
+				sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
+				conf_unsaved++;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	sym_add_change_count(conf_warnings || conf_unsaved);
+
+	return 0;
+}
+
+int conf_write(const char *name)
+{
+	FILE *out;
+	struct symbol *sym;
+	struct menu *menu;
+	const char *basename;
+	char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
+	int type, l;
+	const char *str;
+	time_t now;
+	int use_timestamp = 1;
+	char *env;
+
+	dirname[0] = 0;
+	if (name && name[0]) {
+		struct stat st;
+		char *slash;
+
+		if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
+			strcpy(dirname, name);
+			strcat(dirname, "/");
+			basename = conf_get_configname();
+		} else if ((slash = strrchr(name, '/'))) {
+			int size = slash - name + 1;
+			memcpy(dirname, name, size);
+			dirname[size] = 0;
+			if (slash[1])
+				basename = slash + 1;
+			else
+				basename = conf_get_configname();
+		} else
+			basename = name;
+	} else
+		basename = conf_get_configname();
+
+	sprintf(newname, "%s%s", dirname, basename);
+	env = getenv("WRSCONFIG_OVERWRITECONFIG");
+	if (!env) /* check old env name */
+		env = getenv("VCONFIG_OVERWRITECONFIG");
+	if (!env || !*env) {
+		sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
+		out = fopen(tmpname, "w");
+	} else {
+		*tmpname = 0;
+		out = fopen(newname, "w");
+	}
+	if (!out)
+		return 1;
+
+   /* sym = sym_lookup("KERNELVERSION", 0);
+	sym_calc_value(sym);    */
+	time(&now);
+	env = getenv("WRSCONFIG_NOTIMESTAMP");
+	if (!env) /* check old env name */
+		env = getenv("VCONFIG_NOTIMESTAMP");
+	if (env && *env)
+		use_timestamp = 0;
+
+	fprintf(out, _("#\n"
+		       "# Automatically generated file: do not edit\n"
+		       "%s%s"
+		       "#\n"),
+		     use_timestamp ? "# " : "",
+		     use_timestamp ? ctime(&now) : "");
+
+	if (!conf_get_changed())
+		sym_clear_all_valid();
+
+	menu = rootmenu.list;
+	while (menu) {
+		sym = menu->sym;
+		if (!sym) {
+			if (!menu_is_visible(menu))
+				goto next;
+			str = menu_get_prompt(menu);
+			fprintf(out, "\n"
+				     "#\n"
+				     "# %s\n"
+				     "#\n", str);
+		} else if (!(sym->flags & SYMBOL_CHOICE)) {
+			sym_calc_value(sym);
+			if (!(sym->flags & SYMBOL_WRITE))
+				goto next;
+			sym->flags &= ~SYMBOL_WRITE;
+			type = sym->type;
+			if (type == S_TRISTATE) {
+				sym_calc_value(modules_sym);
+				if (modules_sym->curr.tri == no)
+					type = S_BOOLEAN;
+			}
+			switch (type) {
+			case S_BOOLEAN:
+			case S_TRISTATE:
+				switch (sym_get_tristate_value(sym)) {
+				case no:
+					fprintf(out, "# CONFIG_%s is not set\n", sym->name);
+					break;
+				case mod:
+					fprintf(out, "CONFIG_%s=m\n", sym->name);
+					break;
+				case yes:
+					fprintf(out, "CONFIG_%s=y\n", sym->name);
+					break;
+		        }
+				break;
+			case S_STRING:
+				str = sym_get_string_value(sym);
+				fprintf(out, "CONFIG_%s=\"", sym->name);
+				while (1) {
+					l = strcspn(str, "\"\\");
+					if (l) {
+						fwrite(str, l, 1, out);
+						str += l;
+					}
+					if (!*str)
+						break;
+					fprintf(out, "\\%c", *str++);
+				}
+				fputs("\"\n", out);
+				break;
+			case S_HEX:
+				str = sym_get_string_value(sym);
+				if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
+					fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
+					break;
+				}
+			case S_INT:
+				str = sym_get_string_value(sym);
+				fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
+				break;
+			}
+		}
+
+next:
+		if (menu->list) {
+			menu = menu->list;
+			continue;
+		}
+		if (menu->next)
+			menu = menu->next;
+		else while ((menu = menu->parent)) {
+			if (menu->next) {
+				menu = menu->next;
+				break;
+			}
+		}
+	}
+	fclose(out);
+
+	if (*tmpname) {
+		strcat(dirname, basename);
+		strcat(dirname, ".old");
+		loc_rename(newname, dirname);
+		if (loc_rename(tmpname, newname))
+			return 1;
+	}
+
+	/* printf(_("#\n"
+		 "# configuration written to %s\n"
+		 "#\n"), newname);  */
+
+	sym_set_change_count(0);
+
+	return 0;
+}
+
+#ifdef VXWORKS
+int conf_split_config(void)
+{
+	char *name, path[PATH_MAX+1], *pathName;
+	char *s, *d, c;
+	struct symbol *sym;
+	struct stat sb;
+	int res, i, fd;
+
+	name = getenv("WRSCONFIG_AUTOCONFIG");
+	if (!name) /* check old env name */
+		name = getenv("VCONFIG_AUTOCONFIG");
+	if (!name)
+		name = "h/config/auto.conf";
+	conf_read_simple(name, S_DEF_AUTO);
+
+
+	if (chdir("h")) {
+		pathName = "h";
+		loc_mkdir(pathName, 0755);
+		if (chdir("h")) {
+		    printf("# mkdir(\"h\") failed\n");
+	    return 1;
+	}
+	}
+	if (chdir("config")) {
+		pathName = "config";
+		loc_mkdir(pathName, 0755);
+		if (chdir("config")) {
+		    printf("# mkdir(\"h/config\") failed\n");
+	    return 1;
+	}
+	}
+	if (chdir(myName)) {
+		pathName = myName;
+		loc_mkdir(pathName, 0755);
+		if (chdir(myName)) {
+		    printf("# mkdir(\"h/config/%s\") failed\n", myName);
+	    return 1;
+	}
+	}
+	if (chdir ("../../..")) {
+		printf("# cd(\"h/config/%s/../../.. test\") failed\n", myName);
+	return 1;
+	}
+
+	file_write_dep("h/config/auto.conf.cmd");
+
+	sprintf (path, "h/config/%s", myName);
+	if (chdir(path)) {
+		printf("# chdir(\"%s\") failed\n", path);
+		return 1;
+	}
+	res = 0;
+	for_all_symbols(i, sym) {
+		sym_calc_value(sym);
+		if ((sym->flags & SYMBOL_AUTO) || !sym->name)
+			continue;
+		if (sym->flags & SYMBOL_WRITE) {
+			if (sym->flags & SYMBOL_DEF_AUTO) {
+				/*
+				 * symbol has old and new value,
+				 * so compare them...
+				 */
+				switch (sym->type) {
+				case S_BOOLEAN:
+				case S_TRISTATE:
+					if (sym_get_tristate_value(sym) ==
+					    sym->def[S_DEF_AUTO].tri)
+						continue;
+					break;
+				case S_STRING:
+				case S_HEX:
+				case S_INT:
+					if (!strcmp(sym_get_string_value(sym),
+						    sym->def[S_DEF_AUTO].val))
+						continue;
+					break;
+				default:
+					break;
+				}
+			} else {
+				/*
+				 * If there is no old value, only 'no' (unset)
+				 * is allowed as new value.
+				 */
+				switch (sym->type) {
+				case S_BOOLEAN:
+				case S_TRISTATE:
+					if (sym_get_tristate_value(sym) == no)
+						continue;
+					break;
+				default:
+					break;
+				}
+			}
+		} else if (!(sym->flags & SYMBOL_DEF_AUTO))
+			/* There is neither an old nor a new value. */
+			continue;
+		/* else
+		 *	There is an old value, but no new value ('no' (unset)
+		 *	isn't saved in auto.conf, so the old value is always
+		 *	different from 'no').
+		 */
+
+		/* Replace all '_' and append ".h" */
+		s = sym->name;
+		d = path;
+		while ((c = *s++)) {
+			c = tolower(c);
+			*d++ = (c == '_') ? '/' : c;
+		}
+		strcpy(d, ".h");
+
+		/* Assume directory path already exists. */
+		fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+		if (fd == -1) {
+			if (errno != ENOENT) {
+				printf("# open1(%s) failed\n", path);
+				res = 1;
+				break;
+			}
+			/*
+			 * Create directory components,
+			 * unless they exist already.
+			 */
+			d = path;
+			while ((d = strchr(d, '/'))) {
+				*d = 0;
+
+				if (stat(path, &sb) && loc_mkdir(path, 0755)) {
+					printf("# stat/mkdir(%s) failed\n", path);
+					res = 1;
+					goto out;
+				}
+				*d++ = '/';
+			}
+			/* Try it again. */
+			fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+			if (fd == -1) {
+				printf("# open2(%s) failed\n", path);
+				res = 1;
+				break;
+			}
+		}
+		close(fd);
+	}
+out:
+	if (chdir("../../..")) {
+		printf("# chdir(../../..) failed\n");
+		return 1;
+	}
+
+	return res;
+}
+#endif
+
+int conf_write_autoconf(void)
+{
+	struct symbol *sym;
+	const char *str;
+	char *name;
+	FILE *out, *out_h;
+	time_t now;
+	int i, l;
+
+	sym_clear_all_valid();
+
+
+#ifdef VVXWORKS
+	if (conf_split_config()) {
+		printf("# conf_split_config failed\n");
+		return 1;
+	}
+#endif
+
+	out = fopen(".tmpconfig", "w");
+	if (!out) {
+		printf("# fopen(.tmpconfig) failed\n");
+		return 1;
+	}
+
+	out_h = fopen(".tmpconfig.h", "w");
+	if (!out_h) {
+		printf("# fopen(.tmpconfig.h) failed\n");
+		fclose(out);
+		return 1;
+	}
+
+	/*sym = sym_lookup("KERNELVERSION", 0);
+	sym_calc_value(sym);   */
+
+	time(&now);
+	fprintf(out, "#\n"
+		     "# Automatically generated make config: don't edit\n"
+		     "# %s"
+		     "#\n",
+		      ctime(&now));
+	fprintf(out_h, "/*\n"
+		       " * Automatically generated C config: don't edit\n"
+		       " * %s"
+		       " */\n"
+		       "\n#ifndef __AUTOCONF_DONT_USE_AUTOCONF\n"
+		       "\n#ifndef AUTOCONF_INCLUDED\n"
+		       "#define AUTOCONF_INCLUDED\n\n",
+		       ctime(&now));
+
+	for_all_symbols(i, sym) {
+		sym_calc_value(sym);
+		if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
+			continue;
+		switch (sym->type) {
+		case S_BOOLEAN:
+		case S_TRISTATE:
+			switch (sym_get_tristate_value(sym)) {
+			case no:
+				break;
+			case mod:
+				fprintf(out, "CONFIG_%s=m\n", sym->name);
+				fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
+				break;
+			case yes:
+				fprintf(out, "CONFIG_%s=y\n", sym->name);
+				fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
+				break;
+			}
+			break;
+		case S_STRING:
+			str = sym_get_string_value(sym);
+			fprintf(out, "CONFIG_%s=", sym->name);
+			fprintf(out_h, "#define CONFIG_%s \"", sym->name);
+			while (1) {
+				l = strcspn(str, "\"\\");
+				if (l) {
+					fwrite(str, l, 1, out);
+					fwrite(str, l, 1, out_h);
+					str += l;
+				}
+				if (!*str)
+					break;
+				fprintf(out, "\\%c", *str);
+				fprintf(out_h, "\\%c", *str);
+				str++;
+			}
+			fputs("\n", out);
+			fputs("\"\n", out_h);
+			break;
+		case S_HEX:
+		    str = sym_get_string_value(sym);
+			if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
+				fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
+				fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
+				break;
+			}
+		case S_INT:
+			str = sym_get_string_value(sym);
+			fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
+			fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
+			break;
+		default:
+			break;
+		}
+	}
+	fprintf(out_h, "\n#endif /* AUTOCONF_INCLUDED */\n\n");
+	fprintf(out_h, "\n#endif /* __AUTOCONF_DONT_USE_AUTOCONF */\n\n");
+
+	fclose(out);
+	fclose(out_h);
+
+
+	name = getenv("WRSCONFIG_AUTOHEADER");
+	if (!name) /* check old env name */
+		name = getenv("VCONFIG_AUTOHEADER");
+
+#ifdef VXWORKS
+	if (!name)
+		name = "h/config/autoconf.h";
+#else
+	if (!name)
+		name = "autoconf.h";
+#endif
+	if (loc_rename(".tmpconfig.h", name)) {
+		printf("# loc_rename(.tmpconfig.h, %s) failed\n", name);
+		return 1;
+	}
+	name = getenv("WRSCONFIG_AUTOCONFIG");
+	if (!name) /* check old env name */
+		name = getenv("VCONFIG_AUTOCONFIG");
+#ifdef VXWORKS
+	if (!name)
+		name = "h/config/auto.conf";
+#else
+	if (!name)
+		name = "auto.conf";
+#endif
+	/*
+	 * This must be the last step, kbuild has a dependency on auto.conf
+	 * and this marks the successful completion of the previous steps.
+	 */
+	if (loc_rename(".tmpconfig", name)) {
+		printf("# loc_rename(.tmpconfig, %s) failed\n", name);
+		return 1;
+	}
+	return 0;
+}
+
+static int sym_change_count;
+static void (*conf_changed_callback)(void);
+
+void sym_set_change_count(int count)
+{
+	int _sym_change_count = sym_change_count;
+	sym_change_count = count;
+	if (conf_changed_callback &&
+	    (bool)_sym_change_count != (bool)count)
+		conf_changed_callback();
+}
+
+void sym_add_change_count(int count)
+{
+	sym_set_change_count(count + sym_change_count);
+}
+
+bool conf_get_changed(void)
+{
+	return sym_change_count;
+}
+
+void conf_set_changed_callback(void (*fn)(void))
+{
+	conf_changed_callback = fn;
+}
diff --git a/host/src/wrsconfig/expr.c b/host/src/wrsconfig/expr.c
new file mode 100755
index 0000000..6ef90c7
--- /dev/null
+++ b/host/src/wrsconfig/expr.c
@@ -0,0 +1,1100 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#define DEBUG_EXPR	0
+
+struct expr *expr_alloc_symbol(struct symbol *sym)
+{
+	struct expr *e = malloc(sizeof(*e));
+	memset(e, 0, sizeof(*e));
+	e->type = E_SYMBOL;
+	e->left.sym = sym;
+	return e;
+}
+
+struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
+{
+	struct expr *e = malloc(sizeof(*e));
+	memset(e, 0, sizeof(*e));
+	e->type = type;
+	e->left.expr = ce;
+	return e;
+}
+
+struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
+{
+	struct expr *e = malloc(sizeof(*e));
+	memset(e, 0, sizeof(*e));
+	e->type = type;
+	e->left.expr = e1;
+	e->right.expr = e2;
+	return e;
+}
+
+struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
+{
+	struct expr *e = malloc(sizeof(*e));
+	memset(e, 0, sizeof(*e));
+	e->type = type;
+	e->left.sym = s1;
+	e->right.sym = s2;
+	return e;
+}
+
+struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
+{
+	if (!e1)
+		return e2;
+	return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
+}
+
+struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
+{
+	if (!e1)
+		return e2;
+	return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
+}
+
+struct expr *expr_copy(struct expr *org)
+{
+	struct expr *e;
+
+	if (!org)
+		return NULL;
+
+	e = malloc(sizeof(*org));
+	memcpy(e, org, sizeof(*org));
+	switch (org->type) {
+	case E_SYMBOL:
+		e->left = org->left;
+		break;
+	case E_NOT:
+		e->left.expr = expr_copy(org->left.expr);
+		break;
+	case E_EQUAL:
+	case E_UNEQUAL:
+		e->left.sym = org->left.sym;
+		e->right.sym = org->right.sym;
+		break;
+	case E_AND:
+	case E_OR:
+	case E_CHOICE:
+		e->left.expr = expr_copy(org->left.expr);
+		e->right.expr = expr_copy(org->right.expr);
+		break;
+	default:
+		printf("can't copy type %d\n", e->type);
+		free(e);
+		e = NULL;
+		break;
+	}
+
+	return e;
+}
+
+void expr_free(struct expr *e)
+{
+	if (!e)
+		return;
+
+	switch (e->type) {
+	case E_SYMBOL:
+		break;
+	case E_NOT:
+		expr_free(e->left.expr);
+		return;
+	case E_EQUAL:
+	case E_UNEQUAL:
+		break;
+	case E_OR:
+	case E_AND:
+		expr_free(e->left.expr);
+		expr_free(e->right.expr);
+		break;
+	default:
+		printf("how to free type %d?\n", e->type);
+		break;
+	}
+	free(e);
+}
+
+static int trans_count;
+
+#define e1 (*ep1)
+#define e2 (*ep2)
+
+static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
+{
+	if (e1->type == type) {
+		__expr_eliminate_eq(type, &e1->left.expr, &e2);
+		__expr_eliminate_eq(type, &e1->right.expr, &e2);
+		return;
+	}
+	if (e2->type == type) {
+		__expr_eliminate_eq(type, &e1, &e2->left.expr);
+		__expr_eliminate_eq(type, &e1, &e2->right.expr);
+		return;
+	}
+	if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
+	    e1->left.sym == e2->left.sym &&
+	    (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
+		return;
+	if (!expr_eq(e1, e2))
+		return;
+	trans_count++;
+	expr_free(e1); expr_free(e2);
+	switch (type) {
+	case E_OR:
+		e1 = expr_alloc_symbol(&symbol_no);
+		e2 = expr_alloc_symbol(&symbol_no);
+		break;
+	case E_AND:
+		e1 = expr_alloc_symbol(&symbol_yes);
+		e2 = expr_alloc_symbol(&symbol_yes);
+		break;
+	default:
+		;
+	}
+}
+
+void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
+{
+	if (!e1 || !e2)
+		return;
+	switch (e1->type) {
+	case E_OR:
+	case E_AND:
+		__expr_eliminate_eq(e1->type, ep1, ep2);
+	default:
+		;
+	}
+	if (e1->type != e2->type) switch (e2->type) {
+	case E_OR:
+	case E_AND:
+		__expr_eliminate_eq(e2->type, ep1, ep2);
+	default:
+		;
+	}
+	e1 = expr_eliminate_yn(e1);
+	e2 = expr_eliminate_yn(e2);
+}
+
+#undef e1
+#undef e2
+
+int expr_eq(struct expr *e1, struct expr *e2)
+{
+	int res, old_count;
+
+	if (e1->type != e2->type)
+		return 0;
+	switch (e1->type) {
+	case E_EQUAL:
+	case E_UNEQUAL:
+		return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
+	case E_SYMBOL:
+		return e1->left.sym == e2->left.sym;
+	case E_NOT:
+		return expr_eq(e1->left.expr, e2->left.expr);
+	case E_AND:
+	case E_OR:
+		e1 = expr_copy(e1);
+		e2 = expr_copy(e2);
+		old_count = trans_count;
+		expr_eliminate_eq(&e1, &e2);
+		res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
+		       e1->left.sym == e2->left.sym);
+		expr_free(e1);
+		expr_free(e2);
+		trans_count = old_count;
+		return res;
+	case E_CHOICE:
+	case E_RANGE:
+	case E_NONE:
+		/* panic */;
+	}
+
+	if (DEBUG_EXPR) {
+		expr_fprint(e1, stdout);
+		printf(" = ");
+		expr_fprint(e2, stdout);
+		printf(" ?\n");
+	}
+
+	return 0;
+}
+
+struct expr *expr_eliminate_yn(struct expr *e)
+{
+	struct expr *tmp;
+
+	if (e) switch (e->type) {
+	case E_AND:
+		e->left.expr = expr_eliminate_yn(e->left.expr);
+		e->right.expr = expr_eliminate_yn(e->right.expr);
+		if (e->left.expr->type == E_SYMBOL) {
+			if (e->left.expr->left.sym == &symbol_no) {
+				expr_free(e->left.expr);
+				expr_free(e->right.expr);
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_no;
+				e->right.expr = NULL;
+				return e;
+			} else if (e->left.expr->left.sym == &symbol_yes) {
+				free(e->left.expr);
+				tmp = e->right.expr;
+				*e = *(e->right.expr);
+				free(tmp);
+				return e;
+			}
+		}
+		if (e->right.expr->type == E_SYMBOL) {
+			if (e->right.expr->left.sym == &symbol_no) {
+				expr_free(e->left.expr);
+				expr_free(e->right.expr);
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_no;
+				e->right.expr = NULL;
+				return e;
+			} else if (e->right.expr->left.sym == &symbol_yes) {
+				free(e->right.expr);
+				tmp = e->left.expr;
+				*e = *(e->left.expr);
+				free(tmp);
+				return e;
+			}
+		}
+		break;
+	case E_OR:
+		e->left.expr = expr_eliminate_yn(e->left.expr);
+		e->right.expr = expr_eliminate_yn(e->right.expr);
+		if (e->left.expr->type == E_SYMBOL) {
+			if (e->left.expr->left.sym == &symbol_no) {
+				free(e->left.expr);
+				tmp = e->right.expr;
+				*e = *(e->right.expr);
+				free(tmp);
+				return e;
+			} else if (e->left.expr->left.sym == &symbol_yes) {
+				expr_free(e->left.expr);
+				expr_free(e->right.expr);
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_yes;
+				e->right.expr = NULL;
+				return e;
+			}
+		}
+		if (e->right.expr->type == E_SYMBOL) {
+			if (e->right.expr->left.sym == &symbol_no) {
+				free(e->right.expr);
+				tmp = e->left.expr;
+				*e = *(e->left.expr);
+				free(tmp);
+				return e;
+			} else if (e->right.expr->left.sym == &symbol_yes) {
+				expr_free(e->left.expr);
+				expr_free(e->right.expr);
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_yes;
+				e->right.expr = NULL;
+				return e;
+			}
+		}
+		break;
+	default:
+		;
+	}
+	return e;
+}
+
+/*
+ * bool FOO!=n => FOO
+ */
+struct expr *expr_trans_bool(struct expr *e)
+{
+	if (!e)
+		return NULL;
+	switch (e->type) {
+	case E_AND:
+	case E_OR:
+	case E_NOT:
+		e->left.expr = expr_trans_bool(e->left.expr);
+		e->right.expr = expr_trans_bool(e->right.expr);
+		break;
+	case E_UNEQUAL:
+		// FOO!=n -> FOO
+		if (e->left.sym->type == S_TRISTATE) {
+			if (e->right.sym == &symbol_no) {
+				e->type = E_SYMBOL;
+				e->right.sym = NULL;
+			}
+		}
+		break;
+	default:
+		;
+	}
+	return e;
+}
+
+/*
+ * e1 || e2 -> ?
+ */
+struct expr *expr_join_or(struct expr *e1, struct expr *e2)
+{
+	struct expr *tmp;
+	struct symbol *sym1, *sym2;
+
+	if (expr_eq(e1, e2))
+		return expr_copy(e1);
+	if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
+		return NULL;
+	if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
+		return NULL;
+	if (e1->type == E_NOT) {
+		tmp = e1->left.expr;
+		if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
+			return NULL;
+		sym1 = tmp->left.sym;
+	} else
+		sym1 = e1->left.sym;
+	if (e2->type == E_NOT) {
+		if (e2->left.expr->type != E_SYMBOL)
+			return NULL;
+		sym2 = e2->left.expr->left.sym;
+	} else
+		sym2 = e2->left.sym;
+	if (sym1 != sym2)
+		return NULL;
+	if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
+		return NULL;
+	if (sym1->type == S_TRISTATE) {
+		if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
+		    ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
+		     (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
+			// (a='y') || (a='m') -> (a!='n')
+			return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
+		}
+		if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
+		    ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
+		     (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
+			// (a='y') || (a='n') -> (a!='m')
+			return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
+		}
+		if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
+		    ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
+		     (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
+			// (a='m') || (a='n') -> (a!='y')
+			return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
+		}
+	}
+	if (sym1->type == S_BOOLEAN && sym1 == sym2) {
+		if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
+		    (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
+			return expr_alloc_symbol(&symbol_yes);
+	}
+
+	if (DEBUG_EXPR) {
+		printf("optimize (");
+		expr_fprint(e1, stdout);
+		printf(") || (");
+		expr_fprint(e2, stdout);
+		printf(")?\n");
+	}
+	return NULL;
+}
+
+struct expr *expr_join_and(struct expr *e1, struct expr *e2)
+{
+	struct expr *tmp;
+	struct symbol *sym1, *sym2;
+
+	if (expr_eq(e1, e2))
+		return expr_copy(e1);
+	if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
+		return NULL;
+	if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
+		return NULL;
+	if (e1->type == E_NOT) {
+		tmp = e1->left.expr;
+		if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
+			return NULL;
+		sym1 = tmp->left.sym;
+	} else
+		sym1 = e1->left.sym;
+	if (e2->type == E_NOT) {
+		if (e2->left.expr->type != E_SYMBOL)
+			return NULL;
+		sym2 = e2->left.expr->left.sym;
+	} else
+		sym2 = e2->left.sym;
+	if (sym1 != sym2)
+		return NULL;
+	if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
+		return NULL;
+
+	if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
+	    (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
+		// (a) && (a='y') -> (a='y')
+		return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
+
+	if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
+	    (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
+		// (a) && (a!='n') -> (a)
+		return expr_alloc_symbol(sym1);
+
+	if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
+	    (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
+		// (a) && (a!='m') -> (a='y')
+		return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
+
+	if (sym1->type == S_TRISTATE) {
+		if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
+			// (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
+			sym2 = e1->right.sym;
+			if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
+				return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
+							     : expr_alloc_symbol(&symbol_no);
+		}
+		if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
+			// (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
+			sym2 = e2->right.sym;
+			if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
+				return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
+							     : expr_alloc_symbol(&symbol_no);
+		}
+		if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
+			   ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
+			    (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
+			// (a!='y') && (a!='n') -> (a='m')
+			return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
+
+		if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
+			   ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
+			    (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
+			// (a!='y') && (a!='m') -> (a='n')
+			return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
+
+		if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
+			   ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
+			    (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
+			// (a!='m') && (a!='n') -> (a='m')
+			return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
+
+		if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
+		    (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
+		    (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
+		    (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
+			return NULL;
+	}
+
+	if (DEBUG_EXPR) {
+		printf("optimize (");
+		expr_fprint(e1, stdout);
+		printf(") && (");
+		expr_fprint(e2, stdout);
+		printf(")?\n");
+	}
+	return NULL;
+}
+
+static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
+{
+#define e1 (*ep1)
+#define e2 (*ep2)
+	struct expr *tmp;
+
+	if (e1->type == type) {
+		expr_eliminate_dups1(type, &e1->left.expr, &e2);
+		expr_eliminate_dups1(type, &e1->right.expr, &e2);
+		return;
+	}
+	if (e2->type == type) {
+		expr_eliminate_dups1(type, &e1, &e2->left.expr);
+		expr_eliminate_dups1(type, &e1, &e2->right.expr);
+		return;
+	}
+	if (e1 == e2)
+		return;
+
+	switch (e1->type) {
+	case E_OR: case E_AND:
+		expr_eliminate_dups1(e1->type, &e1, &e1);
+	default:
+		;
+	}
+
+	switch (type) {
+	case E_OR:
+		tmp = expr_join_or(e1, e2);
+		if (tmp) {
+			expr_free(e1); expr_free(e2);
+			e1 = expr_alloc_symbol(&symbol_no);
+			e2 = tmp;
+			trans_count++;
+		}
+		break;
+	case E_AND:
+		tmp = expr_join_and(e1, e2);
+		if (tmp) {
+			expr_free(e1); expr_free(e2);
+			e1 = expr_alloc_symbol(&symbol_yes);
+			e2 = tmp;
+			trans_count++;
+		}
+		break;
+	default:
+		;
+	}
+#undef e1
+#undef e2
+}
+
+static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
+{
+#define e1 (*ep1)
+#define e2 (*ep2)
+	struct expr *tmp, *tmp1, *tmp2;
+
+	if (e1->type == type) {
+		expr_eliminate_dups2(type, &e1->left.expr, &e2);
+		expr_eliminate_dups2(type, &e1->right.expr, &e2);
+		return;
+	}
+	if (e2->type == type) {
+		expr_eliminate_dups2(type, &e1, &e2->left.expr);
+		expr_eliminate_dups2(type, &e1, &e2->right.expr);
+	}
+	if (e1 == e2)
+		return;
+
+	switch (e1->type) {
+	case E_OR:
+		expr_eliminate_dups2(e1->type, &e1, &e1);
+		// (FOO || BAR) && (!FOO && !BAR) -> n
+		tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
+		tmp2 = expr_copy(e2);
+		tmp = expr_extract_eq_and(&tmp1, &tmp2);
+		if (expr_is_yes(tmp1)) {
+			expr_free(e1);
+			e1 = expr_alloc_symbol(&symbol_no);
+			trans_count++;
+		}
+		expr_free(tmp2);
+		expr_free(tmp1);
+		expr_free(tmp);
+		break;
+	case E_AND:
+		expr_eliminate_dups2(e1->type, &e1, &e1);
+		// (FOO && BAR) || (!FOO || !BAR) -> y
+		tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
+		tmp2 = expr_copy(e2);
+		tmp = expr_extract_eq_or(&tmp1, &tmp2);
+		if (expr_is_no(tmp1)) {
+			expr_free(e1);
+			e1 = expr_alloc_symbol(&symbol_yes);
+			trans_count++;
+		}
+		expr_free(tmp2);
+		expr_free(tmp1);
+		expr_free(tmp);
+		break;
+	default:
+		;
+	}
+#undef e1
+#undef e2
+}
+
+struct expr *expr_eliminate_dups(struct expr *e)
+{
+	int oldcount;
+	if (!e)
+		return e;
+
+	oldcount = trans_count;
+	while (1) {
+		trans_count = 0;
+		switch (e->type) {
+		case E_OR: case E_AND:
+			expr_eliminate_dups1(e->type, &e, &e);
+			expr_eliminate_dups2(e->type, &e, &e);
+		default:
+			;
+		}
+		if (!trans_count)
+			break;
+		e = expr_eliminate_yn(e);
+	}
+	trans_count = oldcount;
+	return e;
+}
+
+struct expr *expr_transform(struct expr *e)
+{
+	struct expr *tmp;
+
+	if (!e)
+		return NULL;
+	switch (e->type) {
+	case E_EQUAL:
+	case E_UNEQUAL:
+	case E_SYMBOL:
+	case E_CHOICE:
+		break;
+	default:
+		e->left.expr = expr_transform(e->left.expr);
+		e->right.expr = expr_transform(e->right.expr);
+	}
+
+	switch (e->type) {
+	case E_EQUAL:
+		if (e->left.sym->type != S_BOOLEAN)
+			break;
+		if (e->right.sym == &symbol_no) {
+			e->type = E_NOT;
+			e->left.expr = expr_alloc_symbol(e->left.sym);
+			e->right.sym = NULL;
+			break;
+		}
+		if (e->right.sym == &symbol_mod) {
+			printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
+			e->type = E_SYMBOL;
+			e->left.sym = &symbol_no;
+			e->right.sym = NULL;
+			break;
+		}
+		if (e->right.sym == &symbol_yes) {
+			e->type = E_SYMBOL;
+			e->right.sym = NULL;
+			break;
+		}
+		break;
+	case E_UNEQUAL:
+		if (e->left.sym->type != S_BOOLEAN)
+			break;
+		if (e->right.sym == &symbol_no) {
+			e->type = E_SYMBOL;
+			e->right.sym = NULL;
+			break;
+		}
+		if (e->right.sym == &symbol_mod) {
+			printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
+			e->type = E_SYMBOL;
+			e->left.sym = &symbol_yes;
+			e->right.sym = NULL;
+			break;
+		}
+		if (e->right.sym == &symbol_yes) {
+			e->type = E_NOT;
+			e->left.expr = expr_alloc_symbol(e->left.sym);
+			e->right.sym = NULL;
+			break;
+		}
+		break;
+	case E_NOT:
+		switch (e->left.expr->type) {
+		case E_NOT:
+			// !!a -> a
+			tmp = e->left.expr->left.expr;
+			free(e->left.expr);
+			free(e);
+			e = tmp;
+			e = expr_transform(e);
+			break;
+		case E_EQUAL:
+		case E_UNEQUAL:
+			// !a='x' -> a!='x'
+			tmp = e->left.expr;
+			free(e);
+			e = tmp;
+			e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
+			break;
+		case E_OR:
+			// !(a || b) -> !a && !b
+			tmp = e->left.expr;
+			e->type = E_AND;
+			e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
+			tmp->type = E_NOT;
+			tmp->right.expr = NULL;
+			e = expr_transform(e);
+			break;
+		case E_AND:
+			// !(a && b) -> !a || !b
+			tmp = e->left.expr;
+			e->type = E_OR;
+			e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
+			tmp->type = E_NOT;
+			tmp->right.expr = NULL;
+			e = expr_transform(e);
+			break;
+		case E_SYMBOL:
+			if (e->left.expr->left.sym == &symbol_yes) {
+				// !'y' -> 'n'
+				tmp = e->left.expr;
+				free(e);
+				e = tmp;
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_no;
+				break;
+			}
+			if (e->left.expr->left.sym == &symbol_mod) {
+				// !'m' -> 'm'
+				tmp = e->left.expr;
+				free(e);
+				e = tmp;
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_mod;
+				break;
+			}
+			if (e->left.expr->left.sym == &symbol_no) {
+				// !'n' -> 'y'
+				tmp = e->left.expr;
+				free(e);
+				e = tmp;
+				e->type = E_SYMBOL;
+				e->left.sym = &symbol_yes;
+				break;
+			}
+			break;
+		default:
+			;
+		}
+		break;
+	default:
+		;
+	}
+	return e;
+}
+
+int expr_contains_symbol(struct expr *dep, struct symbol *sym)
+{
+	if (!dep)
+		return 0;
+
+	switch (dep->type) {
+	case E_AND:
+	case E_OR:
+		return expr_contains_symbol(dep->left.expr, sym) ||
+		       expr_contains_symbol(dep->right.expr, sym);
+	case E_SYMBOL:
+		return dep->left.sym == sym;
+	case E_EQUAL:
+	case E_UNEQUAL:
+		return dep->left.sym == sym ||
+		       dep->right.sym == sym;
+	case E_NOT:
+		return expr_contains_symbol(dep->left.expr, sym);
+	default:
+		;
+	}
+	return 0;
+}
+
+bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
+{
+	if (!dep)
+		return false;
+
+	switch (dep->type) {
+	case E_AND:
+		return expr_depends_symbol(dep->left.expr, sym) ||
+		       expr_depends_symbol(dep->right.expr, sym);
+	case E_SYMBOL:
+		return dep->left.sym == sym;
+	case E_EQUAL:
+		if (dep->left.sym == sym) {
+			if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
+				return true;
+		}
+		break;
+	case E_UNEQUAL:
+		if (dep->left.sym == sym) {
+			if (dep->right.sym == &symbol_no)
+				return true;
+		}
+		break;
+	default:
+		;
+	}
+	return false;
+}
+
+struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
+{
+	struct expr *tmp = NULL;
+	expr_extract_eq(E_AND, &tmp, ep1, ep2);
+	if (tmp) {
+		*ep1 = expr_eliminate_yn(*ep1);
+		*ep2 = expr_eliminate_yn(*ep2);
+	}
+	return tmp;
+}
+
+struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
+{
+	struct expr *tmp = NULL;
+	expr_extract_eq(E_OR, &tmp, ep1, ep2);
+	if (tmp) {
+		*ep1 = expr_eliminate_yn(*ep1);
+		*ep2 = expr_eliminate_yn(*ep2);
+	}
+	return tmp;
+}
+
+void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
+{
+#define e1 (*ep1)
+#define e2 (*ep2)
+	if (e1->type == type) {
+		expr_extract_eq(type, ep, &e1->left.expr, &e2);
+		expr_extract_eq(type, ep, &e1->right.expr, &e2);
+		return;
+	}
+	if (e2->type == type) {
+		expr_extract_eq(type, ep, ep1, &e2->left.expr);
+		expr_extract_eq(type, ep, ep1, &e2->right.expr);
+		return;
+	}
+	if (expr_eq(e1, e2)) {
+		*ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
+		expr_free(e2);
+		if (type == E_AND) {
+			e1 = expr_alloc_symbol(&symbol_yes);
+			e2 = expr_alloc_symbol(&symbol_yes);
+		} else if (type == E_OR) {
+			e1 = expr_alloc_symbol(&symbol_no);
+			e2 = expr_alloc_symbol(&symbol_no);
+		}
+	}
+#undef e1
+#undef e2
+}
+
+struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
+{
+	struct expr *e1, *e2;
+
+	if (!e) {
+		e = expr_alloc_symbol(sym);
+		if (type == E_UNEQUAL)
+			e = expr_alloc_one(E_NOT, e);
+		return e;
+	}
+	switch (e->type) {
+	case E_AND:
+		e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
+		e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
+		if (sym == &symbol_yes)
+			e = expr_alloc_two(E_AND, e1, e2);
+		if (sym == &symbol_no)
+			e = expr_alloc_two(E_OR, e1, e2);
+		if (type == E_UNEQUAL)
+			e = expr_alloc_one(E_NOT, e);
+		return e;
+	case E_OR:
+		e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
+		e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
+		if (sym == &symbol_yes)
+			e = expr_alloc_two(E_OR, e1, e2);
+		if (sym == &symbol_no)
+			e = expr_alloc_two(E_AND, e1, e2);
+		if (type == E_UNEQUAL)
+			e = expr_alloc_one(E_NOT, e);
+		return e;
+	case E_NOT:
+		return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
+	case E_UNEQUAL:
+	case E_EQUAL:
+		if (type == E_EQUAL) {
+			if (sym == &symbol_yes)
+				return expr_copy(e);
+			if (sym == &symbol_mod)
+				return expr_alloc_symbol(&symbol_no);
+			if (sym == &symbol_no)
+				return expr_alloc_one(E_NOT, expr_copy(e));
+		} else {
+			if (sym == &symbol_yes)
+				return expr_alloc_one(E_NOT, expr_copy(e));
+			if (sym == &symbol_mod)
+				return expr_alloc_symbol(&symbol_yes);
+			if (sym == &symbol_no)
+				return expr_copy(e);
+		}
+		break;
+	case E_SYMBOL:
+		return expr_alloc_comp(type, e->left.sym, sym);
+	case E_CHOICE:
+	case E_RANGE:
+	case E_NONE:
+		/* panic */;
+	}
+	return NULL;
+}
+
+tristate expr_calc_value(struct expr *e)
+{
+	tristate val1, val2;
+	const char *str1, *str2;
+
+	if (!e)
+		return yes;
+
+	switch (e->type) {
+	case E_SYMBOL:
+		sym_calc_value(e->left.sym);
+		return e->left.sym->curr.tri;
+	case E_AND:
+		val1 = expr_calc_value(e->left.expr);
+		val2 = expr_calc_value(e->right.expr);
+		return E_AND(val1, val2);
+	case E_OR:
+		val1 = expr_calc_value(e->left.expr);
+		val2 = expr_calc_value(e->right.expr);
+		return E_OR(val1, val2);
+	case E_NOT:
+		val1 = expr_calc_value(e->left.expr);
+		return E_NOT(val1);
+	case E_EQUAL:
+		sym_calc_value(e->left.sym);
+		sym_calc_value(e->right.sym);
+		str1 = sym_get_string_value(e->left.sym);
+		str2 = sym_get_string_value(e->right.sym);
+		return !strcmp(str1, str2) ? yes : no;
+	case E_UNEQUAL:
+		sym_calc_value(e->left.sym);
+		sym_calc_value(e->right.sym);
+		str1 = sym_get_string_value(e->left.sym);
+		str2 = sym_get_string_value(e->right.sym);
+		return !strcmp(str1, str2) ? no : yes;
+	default:
+		printf("expr_calc_value: %d?\n", e->type);
+		return no;
+	}
+}
+
+int expr_compare_type(enum expr_type t1, enum expr_type t2)
+{
+#if 0
+	return 1;
+#else
+	if (t1 == t2)
+		return 0;
+	switch (t1) {
+	case E_EQUAL:
+	case E_UNEQUAL:
+		if (t2 == E_NOT)
+			return 1;
+	case E_NOT:
+		if (t2 == E_AND)
+			return 1;
+	case E_AND:
+		if (t2 == E_OR)
+			return 1;
+	case E_OR:
+		if (t2 == E_CHOICE)
+			return 1;
+	case E_CHOICE:
+		if (t2 == 0)
+			return 1;
+	default:
+		return -1;
+	}
+	printf("[%dgt%d?]", t1, t2);
+	return 0;
+#endif
+}
+
+void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
+{
+	if (!e) {
+		fn(data, NULL, "y");
+		return;
+	}
+
+	if (expr_compare_type(prevtoken, e->type) > 0)
+		fn(data, NULL, "(");
+	switch (e->type) {
+	case E_SYMBOL:
+		if (e->left.sym->name)
+			fn(data, e->left.sym, e->left.sym->name);
+		else
+			fn(data, NULL, "<choice>");
+		break;
+	case E_NOT:
+		fn(data, NULL, "!");
+		expr_print(e->left.expr, fn, data, E_NOT);
+		break;
+	case E_EQUAL:
+		fn(data, e->left.sym, e->left.sym->name);
+		fn(data, NULL, "=");
+		fn(data, e->right.sym, e->right.sym->name);
+		break;
+	case E_UNEQUAL:
+		fn(data, e->left.sym, e->left.sym->name);
+		fn(data, NULL, "!=");
+		fn(data, e->right.sym, e->right.sym->name);
+		break;
+	case E_OR:
+		expr_print(e->left.expr, fn, data, E_OR);
+		fn(data, NULL, " || ");
+		expr_print(e->right.expr, fn, data, E_OR);
+		break;
+	case E_AND:
+		expr_print(e->left.expr, fn, data, E_AND);
+		fn(data, NULL, " && ");
+		expr_print(e->right.expr, fn, data, E_AND);
+		break;
+	case E_CHOICE:
+		fn(data, e->right.sym, e->right.sym->name);
+		if (e->left.expr) {
+			fn(data, NULL, " ^ ");
+			expr_print(e->left.expr, fn, data, E_CHOICE);
+		}
+		break;
+	case E_RANGE:
+		fn(data, NULL, "[");
+		fn(data, e->left.sym, e->left.sym->name);
+		fn(data, NULL, " ");
+		fn(data, e->right.sym, e->right.sym->name);
+		fn(data, NULL, "]");
+		break;
+	default:
+	  {
+		char buf[32];
+		sprintf(buf, "<unknown type %d>", e->type);
+		fn(data, NULL, buf);
+		break;
+	  }
+	}
+	if (expr_compare_type(prevtoken, e->type) > 0)
+		fn(data, NULL, ")");
+}
+
+static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
+{
+	fwrite(str, strlen(str), 1, data);
+}
+
+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, struct symbol *sym, 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);
+}
diff --git a/host/src/wrsconfig/expr.h b/host/src/wrsconfig/expr.h
new file mode 100755
index 0000000..a195986
--- /dev/null
+++ b/host/src/wrsconfig/expr.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#ifndef EXPR_H
+#define EXPR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+struct file {
+	struct file *next;
+	struct file *parent;
+	char *name;
+	int lineno;
+	int flags;
+};
+
+#define FILE_BUSY		0x0001
+#define FILE_SCANNED		0x0002
+#define FILE_PRINTED		0x0004
+
+typedef enum tristate {
+	no, mod, yes
+} tristate;
+
+enum expr_type {
+	E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_CHOICE, E_SYMBOL, E_RANGE
+};
+
+union expr_data {
+	struct expr *expr;
+	struct symbol *sym;
+};
+
+struct expr {
+	enum expr_type type;
+	union expr_data left, right;
+};
+
+#define E_OR(dep1, dep2)	(((dep1)>(dep2))?(dep1):(dep2))
+#define E_AND(dep1, dep2)	(((dep1)<(dep2))?(dep1):(dep2))
+#define E_NOT(dep)		(2-(dep))
+
+struct expr_value {
+	struct expr *expr;
+	tristate tri;
+};
+
+struct symbol_value {
+	void *val;
+	tristate tri;
+};
+
+enum symbol_type {
+	S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
+};
+
+enum {
+	S_DEF_USER,		/* main user value */
+	S_DEF_AUTO,
+};
+
+struct symbol {
+	struct symbol *next;
+	char *name;
+	enum symbol_type type;
+	struct symbol_value curr;
+	struct symbol_value def[4];
+	tristate visible;
+	int flags;
+	struct property *prop;
+	struct expr_value rev_dep;
+};
+
+#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
+
+#define SYMBOL_CONST		0x0001
+#define SYMBOL_CHECK		0x0008
+#define SYMBOL_CHOICE		0x0010
+#define SYMBOL_CHOICEVAL	0x0020
+#define SYMBOL_PRINTED		0x0040
+#define SYMBOL_VALID		0x0080
+#define SYMBOL_OPTIONAL		0x0100
+#define SYMBOL_WRITE		0x0200
+#define SYMBOL_CHANGED		0x0400
+#define SYMBOL_AUTO		0x1000
+#define SYMBOL_CHECKED		0x2000
+#define SYMBOL_WARNED		0x8000
+#define SYMBOL_DEF		0x10000
+#define SYMBOL_DEF_USER		0x10000
+#define SYMBOL_DEF_AUTO		0x20000
+#define SYMBOL_DEF3		0x40000
+#define SYMBOL_DEF4		0x80000
+
+#define SYMBOL_MAXLENGTH	256
+#define SYMBOL_HASHSIZE		257
+#define SYMBOL_HASHMASK		0xff
+
+enum prop_type {
+	P_UNKNOWN, P_PROMPT, P_COMMENT, P_MENU, P_DEFAULT, P_CHOICE, P_SELECT, P_RANGE
+};
+
+struct property {
+	struct property *next;
+	struct symbol *sym;
+	enum prop_type type;
+	const char *text;
+	struct expr_value visible;
+	struct expr *expr;
+	struct menu *menu;
+	struct file *file;
+	int lineno;
+};
+
+#define for_all_properties(sym, st, tok) \
+	for (st = sym->prop; st; st = st->next) \
+		if (st->type == (tok))
+#define for_all_defaults(sym, st) for_all_properties(sym, st, P_DEFAULT)
+#define for_all_choices(sym, st) for_all_properties(sym, st, P_CHOICE)
+#define for_all_prompts(sym, st) \
+	for (st = sym->prop; st; st = st->next) \
+		if (st->text)
+
+struct menu {
+	struct menu *next;
+	struct menu *parent;
+	struct menu *list;
+	struct symbol *sym;
+	struct property *prompt;
+	struct expr *dep;
+	unsigned int flags;
+	char *help;
+	struct file *file;
+	int lineno;
+	void *data;
+};
+
+#define MENU_CHANGED		0x0001
+#define MENU_ROOT		0x0002
+
+#ifndef SWIG
+
+extern struct file *file_list;
+extern struct file *current_file;
+struct file *lookup_file(const char *name);
+
+extern struct symbol symbol_yes, symbol_no, symbol_mod;
+extern struct symbol *modules_sym;
+extern struct symbol *sym_defconfig_list;
+extern int cdebug;
+struct expr *expr_alloc_symbol(struct symbol *sym);
+struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
+struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2);
+struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2);
+struct expr *expr_alloc_and(struct expr *e1, struct expr *e2);
+struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
+struct expr *expr_copy(struct expr *org);
+void expr_free(struct expr *e);
+int expr_eq(struct expr *e1, struct expr *e2);
+void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
+tristate expr_calc_value(struct expr *e);
+struct expr *expr_eliminate_yn(struct expr *e);
+struct expr *expr_trans_bool(struct expr *e);
+struct expr *expr_eliminate_dups(struct expr *e);
+struct expr *expr_transform(struct expr *e);
+int expr_contains_symbol(struct expr *dep, struct symbol *sym);
+bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
+struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
+struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
+void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
+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)
+{
+	return !e || (e->type == E_SYMBOL && e->left.sym == &symbol_yes);
+}
+
+static inline int expr_is_no(struct expr *e)
+{
+	return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EXPR_H */
diff --git a/host/src/wrsconfig/fixdep.c b/host/src/wrsconfig/fixdep.c
new file mode 100755
index 0000000..18bf1b3
--- /dev/null
+++ b/host/src/wrsconfig/fixdep.c
@@ -0,0 +1,399 @@
+/*
+ * "Optimize" a list of dependencies as spit out by gcc -MD
+ * for the kernel build
+ * ===========================================================================
+ *
+ * Author       Kai Germaschewski
+ * Copyright    2002 by Kai Germaschewski  <kai.germaschewski@gmx.de>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ *
+ * Introduction:
+ *
+ * gcc produces a very nice and correct list of dependencies which
+ * tells make when to remake a file.
+ *
+ * To use this list as-is however has the drawback that virtually
+ * every file in the kernel includes <linux/config.h> which then again
+ * includes <linux/autoconf.h>
+ *
+ * If the user re-runs make *config, linux/autoconf.h will be
+ * regenerated.  make notices that and will rebuild every file which
+ * includes autoconf.h, i.e. basically all files. This is extremely
+ * annoying if the user just changed CONFIG_HIS_DRIVER from n to m.
+ *
+ * So we play the same trick that "mkdep" played before. We replace
+ * the dependency on linux/autoconf.h by a dependency on every config
+ * option which is mentioned in any of the listed prequisites.
+ *
+ * kconfig populates a tree in include/config/ with an empty file
+ * for each config symbol and when the configuration is updated
+ * the files representing changed config options are touched
+ * which then let make pick up the changes and the files that use
+ * the config symbols are rebuilt.
+ *
+ * So if the user changes his CONFIG_HIS_DRIVER option, only the objects
+ * which depend on "include/linux/config/his/driver.h" will be rebuilt,
+ * so most likely only his driver ;-)
+ *
+ * The idea above dates, by the way, back to Michael E Chastain, AFAIK.
+ *
+ * So to get dependencies right, there are two issues:
+ * o if any of the files the compiler read changed, we need to rebuild
+ * o if the command line given to the compile the file changed, we
+ *   better rebuild as well.
+ *
+ * The former is handled by using the -MD output, the later by saving
+ * the command line used to compile the old object and comparing it
+ * to the one we would now use.
+ *
+ * Again, also this idea is pretty old and has been discussed on
+ * kbuild-devel a long time ago. I don't have a sensibly working
+ * internet connection right now, so I rather don't mention names
+ * without double checking.
+ *
+ * This code here has been based partially based on mkdep.c, which
+ * says the following about its history:
+ *
+ *   Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>.
+ *   This is a C version of syncdep.pl by Werner Almesberger.
+ *
+ *
+ * It is invoked as
+ *
+ *   fixdep <depfile> <target> <cmdline>
+ *
+ * and will read the dependency file <depfile>
+ *
+ * The transformed dependency snipped is written to stdout.
+ *
+ * It first generates a line
+ *
+ *   cmd_<target> = <cmdline>
+ *
+ * and then basically copies the .<target>.d file to stdout, in the
+ * process filtering out the dependency on linux/autoconf.h and adding
+ * dependencies on include/config/my/option.h for every
+ * CONFIG_MY_OPTION encountered in any of the prequisites.
+ *
+ * It will also filter out all the dependencies on *.ver. We need
+ * to make sure that the generated version checksum are globally up
+ * to date before even starting the recursive build, so it's too late
+ * at this point anyway.
+ *
+ * The algorithm to grep for "CONFIG_..." is bit unusual, but should
+ * be fast ;-) We don't even try to really parse the header files, but
+ * merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will
+ * be picked up as well. It's not a problem with respect to
+ * correctness, since that can only give too many dependencies, thus
+ * we cannot miss a rebuild. Since people tend to not mention totally
+ * unrelated CONFIG_ options all over the place, it's not an
+ * efficiency problem either.
+ *
+ * (Note: it'd be easy to port over the complete mkdep state machine,
+ *  but I don't think the added complexity is worth it)
+ */
+/*
+ * Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto
+ * CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not
+ * fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as
+ * UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h,
+ * through arch/um/include/uml-config.h; this fixdep "bug" makes sure that
+ * those files will have correct dependencies.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <ctype.h>
+#include <arpa/inet.h>
+
+#define INT_CONF ntohl(0x434f4e46)
+#define INT_ONFI ntohl(0x4f4e4649)
+#define INT_NFIG ntohl(0x4e464947)
+#define INT_FIG_ ntohl(0x4649475f)
+
+char *target;
+char *depfile;
+char *cmdline;
+
+void usage(void)
+
+{
+	fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
+	exit(1);
+}
+
+/*
+ * Print out the commandline prefixed with cmd_<target filename> :=
+ */
+void print_cmdline(void)
+{
+	printf("cmd_%s := %s\n\n", target, cmdline);
+}
+
+char * str_config  = NULL;
+int    size_config = 0;
+int    len_config  = 0;
+
+/*
+ * Grow the configuration string to a desired length.
+ * Usually the first growth is plenty.
+ */
+void grow_config(int len)
+{
+	while (len_config + len > size_config) {
+		if (size_config == 0)
+			size_config = 2048;
+		str_config = realloc(str_config, size_config *= 2);
+		if (str_config == NULL)
+			{ perror("fixdep:malloc"); exit(1); }
+	}
+}
+
+
+
+/*
+ * Lookup a value in the configuration string.
+ */
+int is_defined_config(const char * name, int len)
+{
+	const char * pconfig;
+	const char * plast = str_config + len_config - len;
+	for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) {
+		if (pconfig[ -1] == '\n'
+		&&  pconfig[len] == '\n'
+		&&  !memcmp(pconfig, name, len))
+			return 1;
+	}
+	return 0;
+}
+
+/*
+ * Add a new value to the configuration string.
+ */
+void define_config(const char * name, int len)
+{
+	grow_config(len + 1);
+
+	memcpy(str_config+len_config, name, len);
+	len_config += len;
+	str_config[len_config++] = '\n';
+}
+
+/*
+ * Clear the set of configuration strings.
+ */
+void clear_config(void)
+{
+	len_config = 0;
+	define_config("", 0);
+}
+
+/*
+ * Record the use of a CONFIG_* word.
+ */
+void use_config(char *m, int slen)
+{
+	char s[PATH_MAX];
+	char *p;
+
+	if (is_defined_config(m, slen))
+	    return;
+
+	define_config(m, slen);
+
+	memcpy(s, m, slen); s[slen] = 0;
+
+	for (p = s; p < s + slen; p++) {
+		if (*p == '_')
+			*p = '/';
+		else
+			*p = tolower((int)*p);
+	}
+	printf("    $(wildcard include/config/%s.h) \\\n", s);
+}
+
+void parse_config_file(char *map, size_t len)
+{
+	int *end = (int *) (map + len);
+	/* start at +1, so that p can never be < map */
+	int *m   = (int *) map + 1;
+	char *p, *q;
+
+	for (; m < end; m++) {
+		if (*m == INT_CONF) { p = (char *) m  ; goto conf; }
+		if (*m == INT_ONFI) { p = (char *) m-1; goto conf; }
+		if (*m == INT_NFIG) { p = (char *) m-2; goto conf; }
+		if (*m == INT_FIG_) { p = (char *) m-3; goto conf; }
+		continue;
+conf:
+		if (p > map + len - 7)
+			continue;
+		if (memcmp(p, "CONFIG_", 7))
+			continue;
+		for (q = p + 7; q < map + len; q++) {
+			if (!(isalnum(*q) || *q == '_'))
+				goto found;
+		}
+		continue;
+
+found:
+		if (!memcmp(q - 7, "_MODULE", 7))
+			q -= 7;
+		if( (q-p-7) < 0 )
+			continue;
+		use_config(p+7, q-p-7);
+	}
+}
+
+/* test is s ends in sub */
+int strrcmp(char *s, char *sub)
+{
+	int slen = strlen(s);
+	int sublen = strlen(sub);
+
+	if (sublen > slen)
+		return 1;
+
+	return memcmp(s + slen - sublen, sub, sublen);
+}
+
+void do_config_file(char *filename)
+{
+	struct stat st;
+	int fd;
+	void *map;
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0) {
+		fprintf(stderr, "fixdep: ");
+		perror(filename);
+		exit(2);
+	}
+	fstat(fd, &st);
+	if (st.st_size == 0) {
+		close(fd);
+		return;
+	}
+	map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+	if ((long) map == -1) {
+		perror("fixdep: mmap");
+		close(fd);
+		return;
+	}
+
+	parse_config_file(map, st.st_size);
+
+	munmap(map, st.st_size);
+
+	close(fd);
+}
+
+void parse_dep_file(void *map, size_t len)
+{
+	char *m = map;
+	char *end = m + len;
+	char *p;
+	char s[PATH_MAX];
+
+	p = strchr(m, ':');
+	if (!p) {
+		fprintf(stderr, "fixdep: parse error\n");
+		exit(1);
+	}
+	memcpy(s, m, p-m); s[p-m] = 0;
+	printf("deps_%s := \\\n", target);
+	m = p+1;
+
+	clear_config();
+
+	while (m < end) {
+		while (m < end && (*m == ' ' || *m == '\\' || *m == '\n'))
+			m++;
+		p = m;
+		while (p < end && *p != ' ') p++;
+		if (p == end) {
+			do p--; while (!isalnum(*p));
+			p++;
+		}
+		memcpy(s, m, p-m); s[p-m] = 0;
+		if (strrcmp(s, "include/linux/autoconf.h") &&
+		    strrcmp(s, "arch/um/include/uml-config.h") &&
+		    strrcmp(s, ".ver")) {
+			printf("  %s \\\n", s);
+			do_config_file(s);
+		}
+		m = p + 1;
+	}
+	printf("\n%s: $(deps_%s)\n\n", target, target);
+	printf("$(deps_%s):\n", target);
+}
+
+void print_deps(void)
+{
+	struct stat st;
+	int fd;
+	void *map;
+
+	fd = open(depfile, O_RDONLY);
+	if (fd < 0) {
+		fprintf(stderr, "fixdep: ");
+		perror(depfile);
+		exit(2);
+	}
+	fstat(fd, &st);
+	if (st.st_size == 0) {
+		fprintf(stderr,"fixdep: %s is empty\n",depfile);
+		close(fd);
+		return;
+	}
+	map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+	if ((long) map == -1) {
+		perror("fixdep: mmap");
+		close(fd);
+		return;
+	}
+
+	parse_dep_file(map, st.st_size);
+
+	munmap(map, st.st_size);
+
+	close(fd);
+}
+
+void traps(void)
+{
+	static char test[] __attribute__((aligned(sizeof(int)))) = "CONF";
+
+	if (*(int *)test != INT_CONF) {
+		fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianess? %#x\n",
+			*(int *)test);
+		exit(2);
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	traps();
+
+	if (argc != 4)
+		usage();
+
+	depfile = argv[1];
+	target = argv[2];
+	cmdline = argv[3];
+
+	print_cmdline();
+	print_deps();
+
+	return 0;
+}
diff --git a/host/src/wrsconfig/lex.zconf.c b/host/src/wrsconfig/lex.zconf.c
new file mode 100755
index 0000000..0279162
--- /dev/null
+++ b/host/src/wrsconfig/lex.zconf.c
@@ -0,0 +1,2266 @@
+
+#line 3 "lex.zconf.c"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 33
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE zconfrestart(zconfin  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int zconfleng;
+
+extern FILE *zconfin, *zconfout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up zconftext. */ \
+		int yyless_macro_arg = (n); \
+		YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = (yy_hold_char); \
+		YY_RESTORE_YY_MORE_OFFSET \
+		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up zconftext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+	int yy_bs_lineno; /**< The line count. */
+	int yy_bs_column; /**< The column count. */
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via zconfrestart()), so that the user can continue scanning by
+	 * just pointing zconfin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+		                  ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+		                  : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when zconftext is formed. */
+static char yy_hold_char;
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+int zconfleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow zconfwrap()'s to do buffer switches
+ * instead of setting up a fresh zconfin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void zconfrestart (FILE *input_file  );
+void zconf_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE zconf_create_buffer (FILE *file,int size  );
+void zconf_delete_buffer (YY_BUFFER_STATE b  );
+void zconf_flush_buffer (YY_BUFFER_STATE b  );
+void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer  );
+void zconfpop_buffer_state (void );
+
+static void zconfensure_buffer_stack (void );
+static void zconf_load_buffer_state (void );
+static void zconf_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER zconf_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE zconf_scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE zconf_scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE zconf_scan_bytes (yyconst char *bytes,int len  );
+
+void *zconfalloc (yy_size_t  );
+void *zconfrealloc (void *,yy_size_t  );
+void zconffree (void *  );
+
+#define yy_new_buffer zconf_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+		zconfensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+		    zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+		zconfensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+		    zconf_create_buffer(zconfin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define zconfwrap() 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *zconfin = (FILE *) 0, *zconfout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int zconflineno;
+
+int zconflineno = 1;
+
+extern char *zconftext;
+#define yytext_ptr zconftext
+static yyconst flex_int16_t yy_nxt[][17] =
+	{
+	{
+		0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+		0,    0,    0,    0,    0,    0,    0
+	},
+
+	{
+	   11,   12,   13,   14,   12,   12,   15,   12,   12,   12,
+	   12,   12,   12,   12,   12,   12,   12
+	},
+
+	{
+	   11,   12,   13,   14,   12,   12,   15,   12,   12,   12,
+	   12,   12,   12,   12,   12,   12,   12
+	},
+
+	{
+	   11,   16,   16,   17,   16,   16,   16,   16,   16,   16,
+	   16,   16,   16,   18,   16,   16,   16
+	},
+
+	{
+	   11,   16,   16,   17,   16,   16,   16,   16,   16,   16,
+	   16,   16,   16,   18,   16,   16,   16
+
+	},
+
+	{
+	   11,   19,   20,   21,   19,   19,   19,   19,   19,   19,
+	   19,   19,   19,   19,   19,   19,   19
+	},
+
+	{
+	   11,   19,   20,   21,   19,   19,   19,   19,   19,   19,
+	   19,   19,   19,   19,   19,   19,   19
+	},
+
+	{
+	   11,   22,   22,   23,   22,   24,   22,   22,   24,   22,
+	   22,   22,   22,   22,   22,   25,   22
+	},
+
+	{
+	   11,   22,   22,   23,   22,   24,   22,   22,   24,   22,
+	   22,   22,   22,   22,   22,   25,   22
+	},
+
+	{
+	   11,   26,   26,   27,   28,   29,   30,   31,   29,   32,
+	   33,   34,   35,   35,   36,   37,   38
+
+	},
+
+	{
+	   11,   26,   26,   27,   28,   29,   30,   31,   29,   32,
+	   33,   34,   35,   35,   36,   37,   38
+	},
+
+	{
+	  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,  -11,
+	  -11,  -11,  -11,  -11,  -11,  -11,  -11
+	},
+
+	{
+	   11,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,
+	  -12,  -12,  -12,  -12,  -12,  -12,  -12
+	},
+
+	{
+	   11,  -13,   39,   40,  -13,  -13,   41,  -13,  -13,  -13,
+	  -13,  -13,  -13,  -13,  -13,  -13,  -13
+	},
+
+	{
+	   11,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,  -14,
+	  -14,  -14,  -14,  -14,  -14,  -14,  -14
+
+	},
+
+	{
+	   11,   42,   42,   43,   42,   42,   42,   42,   42,   42,
+	   42,   42,   42,   42,   42,   42,   42
+	},
+
+	{
+	   11,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
+	  -16,  -16,  -16,  -16,  -16,  -16,  -16
+	},
+
+	{
+	   11,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,
+	  -17,  -17,  -17,  -17,  -17,  -17,  -17
+	},
+
+	{
+	   11,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,  -18,
+	  -18,  -18,  -18,   44,  -18,  -18,  -18
+	},
+
+	{
+	   11,   45,   45,  -19,   45,   45,   45,   45,   45,   45,
+	   45,   45,   45,   45,   45,   45,   45
+
+	},
+
+	{
+	   11,  -20,   46,   47,  -20,  -20,  -20,  -20,  -20,  -20,
+	  -20,  -20,  -20,  -20,  -20,  -20,  -20
+	},
+
+	{
+	   11,   48,  -21,  -21,   48,   48,   48,   48,   48,   48,
+	   48,   48,   48,   48,   48,   48,   48
+	},
+
+	{
+	   11,   49,   49,   50,   49,  -22,   49,   49,  -22,   49,
+	   49,   49,   49,   49,   49,  -22,   49
+	},
+
+	{
+	   11,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,  -23,
+	  -23,  -23,  -23,  -23,  -23,  -23,  -23
+	},
+
+	{
+	   11,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
+	  -24,  -24,  -24,  -24,  -24,  -24,  -24
+
+	},
+
+	{
+	   11,   51,   51,   52,   51,   51,   51,   51,   51,   51,
+	   51,   51,   51,   51,   51,   51,   51
+	},
+
+	{
+	   11,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
+	  -26,  -26,  -26,  -26,  -26,  -26,  -26
+	},
+
+	{
+	   11,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
+	  -27,  -27,  -27,  -27,  -27,  -27,  -27
+	},
+
+	{
+	   11,  -28,  -28,  -28,  -28,  -28,  -28,  -28,  -28,  -28,
+	  -28,  -28,  -28,  -28,   53,  -28,  -28
+	},
+
+	{
+	   11,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,  -29,
+	  -29,  -29,  -29,  -29,  -29,  -29,  -29
+
+	},
+
+	{
+	   11,   54,   54,  -30,   54,   54,   54,   54,   54,   54,
+	   54,   54,   54,   54,   54,   54,   54
+	},
+
+	{
+	   11,  -31,  -31,  -31,  -31,  -31,  -31,   55,  -31,  -31,
+	  -31,  -31,  -31,  -31,  -31,  -31,  -31
+	},
+
+	{
+	   11,  -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,
+	  -32,  -32,  -32,  -32,  -32,  -32,  -32
+	},
+
+	{
+	   11,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,  -33,
+	  -33,  -33,  -33,  -33,  -33,  -33,  -33
+	},
+
+	{
+	   11,  -34,  -34,  -34,  -34,  -34,  -34,  -34,  -34,  -34,
+	  -34,   56,   57,   57,  -34,  -34,  -34
+
+	},
+
+	{
+	   11,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,
+	  -35,   57,   57,   57,  -35,  -35,  -35
+	},
+
+	{
+	   11,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
+	  -36,  -36,  -36,  -36,  -36,  -36,  -36
+	},
+
+	{
+	   11,  -37,  -37,   58,  -37,  -37,  -37,  -37,  -37,  -37,
+	  -37,  -37,  -37,  -37,  -37,  -37,  -37
+	},
+
+	{
+	   11,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,  -38,
+	  -38,  -38,  -38,  -38,  -38,  -38,   59
+	},
+
+	{
+	   11,  -39,   39,   40,  -39,  -39,   41,  -39,  -39,  -39,
+	  -39,  -39,  -39,  -39,  -39,  -39,  -39
+
+	},
+
+	{
+	   11,  -40,  -40,  -40,  -40,  -40,  -40,  -40,  -40,  -40,
+	  -40,  -40,  -40,  -40,  -40,  -40,  -40
+	},
+
+	{
+	   11,   42,   42,   43,   42,   42,   42,   42,   42,   42,
+	   42,   42,   42,   42,   42,   42,   42
+	},
+
+	{
+	   11,   42,   42,   43,   42,   42,   42,   42,   42,   42,
+	   42,   42,   42,   42,   42,   42,   42
+	},
+
+	{
+	   11,  -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,  -43,
+	  -43,  -43,  -43,  -43,  -43,  -43,  -43
+	},
+
+	{
+	   11,  -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,  -44,
+	  -44,  -44,  -44,   44,  -44,  -44,  -44
+
+	},
+
+	{
+	   11,   45,   45,  -45,   45,   45,   45,   45,   45,   45,
+	   45,   45,   45,   45,   45,   45,   45
+	},
+
+	{
+	   11,  -46,   46,   47,  -46,  -46,  -46,  -46,  -46,  -46,
+	  -46,  -46,  -46,  -46,  -46,  -46,  -46
+	},
+
+	{
+	   11,   48,  -47,  -47,   48,   48,   48,   48,   48,   48,
+	   48,   48,   48,   48,   48,   48,   48
+	},
+
+	{
+	   11,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,
+	  -48,  -48,  -48,  -48,  -48,  -48,  -48
+	},
+
+	{
+	   11,   49,   49,   50,   49,  -49,   49,   49,  -49,   49,
+	   49,   49,   49,   49,   49,  -49,   49
+
+	},
+
+	{
+	   11,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,  -50,
+	  -50,  -50,  -50,  -50,  -50,  -50,  -50
+	},
+
+	{
+	   11,  -51,  -51,   52,  -51,  -51,  -51,  -51,  -51,  -51,
+	  -51,  -51,  -51,  -51,  -51,  -51,  -51
+	},
+
+	{
+	   11,  -52,  -52,  -52,  -52,  -52,  -52,  -52,  -52,  -52,
+	  -52,  -52,  -52,  -52,  -52,  -52,  -52
+	},
+
+	{
+	   11,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,  -53,
+	  -53,  -53,  -53,  -53,  -53,  -53,  -53
+	},
+
+	{
+	   11,   54,   54,  -54,   54,   54,   54,   54,   54,   54,
+	   54,   54,   54,   54,   54,   54,   54
+
+	},
+
+	{
+	   11,  -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,
+	  -55,  -55,  -55,  -55,  -55,  -55,  -55
+	},
+
+	{
+	   11,  -56,  -56,  -56,  -56,  -56,  -56,  -56,  -56,  -56,
+	  -56,   60,   57,   57,  -56,  -56,  -56
+	},
+
+	{
+	   11,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,
+	  -57,   57,   57,   57,  -57,  -57,  -57
+	},
+
+	{
+	   11,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,  -58,
+	  -58,  -58,  -58,  -58,  -58,  -58,  -58
+	},
+
+	{
+	   11,  -59,  -59,  -59,  -59,  -59,  -59,  -59,  -59,  -59,
+	  -59,  -59,  -59,  -59,  -59,  -59,  -59
+
+	},
+
+	{
+	   11,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,  -60,
+	  -60,   57,   57,   57,  -60,  -60,  -60
+	},
+
+	} ;
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up zconftext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	(yytext_ptr) = yy_bp; \
+	zconfleng = (size_t) (yy_cp - yy_bp); \
+	(yy_hold_char) = *yy_cp; \
+	*yy_cp = '\0'; \
+	(yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 33
+#define YY_END_OF_BUFFER 34
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static yyconst flex_int16_t yy_accept[61] =
+	{   0,
+		0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+	   34,    5,    4,    2,    3,    7,    8,    6,   32,   29,
+	   31,   24,   28,   27,   26,   22,   17,   13,   16,   20,
+	   22,   11,   12,   19,   19,   14,   22,   22,    4,    2,
+		3,    3,    1,    6,   32,   29,   31,   30,   24,   23,
+	   26,   25,   15,   20,    9,   19,   19,   21,   10,   18
+	} ;
+
+static yyconst flex_int32_t yy_ec[256] =
+	{   0,
+		1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    2,    4,    5,    6,    1,    1,    7,    8,    9,
+	   10,    1,    1,    1,   11,   12,   12,   13,   13,   13,
+	   13,   13,   13,   13,   13,   13,   13,    1,    1,    1,
+	   14,    1,    1,    1,   13,   13,   13,   13,   13,   13,
+	   13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+	   13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+		1,   15,    1,    1,   13,    1,   13,   13,   13,   13,
+
+	   13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+	   13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+	   13,   13,    1,   16,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+		1,    1,    1,    1,    1
+	} ;
+
+extern int zconf_flex_debug;
+int zconf_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *zconftext;
+
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#define START_STRSIZE	16
+
+static struct {
+	struct file *file;
+	int lineno;
+} current_pos;
+
+static char *text;
+static int text_size, text_asize;
+
+struct buffer {
+		struct buffer *parent;
+		YY_BUFFER_STATE state;
+};
+
+struct buffer *current_buf;
+
+static int last_ts, first_ts;
+
+static void zconf_endhelp(void);
+static void zconf_endfile(void);
+
+void new_string(void)
+{
+	text = malloc(START_STRSIZE);
+	text_asize = START_STRSIZE;
+	text_size = 0;
+	*text = 0;
+}
+
+void append_string(const char *str, int size)
+{
+	int new_size = text_size + size + 1;
+	if (new_size > text_asize) {
+		new_size += START_STRSIZE - 1;
+		new_size &= -START_STRSIZE;
+		text = realloc(text, new_size);
+		text_asize = new_size;
+	}
+	memcpy(text + text_size, str, size);
+	text_size += size;
+	text[text_size] = 0;
+}
+
+void alloc_string(const char *str, int size)
+{
+	text = malloc(size + 1);
+	memcpy(text, str, size);
+	text[size] = 0;
+}
+
+#define INITIAL 0
+#define COMMAND 1
+#define HELP 2
+#define STRING 3
+#define PARAM 4
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int zconfwrap (void );
+#else
+extern int zconfwrap (void );
+#endif
+#endif
+
+	static void yyunput (int c,char *buf_ptr  );
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( zconftext, zconfleng, 1, zconfout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	errno=0; \
+	while ( (result = read( fileno(zconfin), (char *) buf, max_size )) < 0 ) \
+	{ \
+		if( errno != EINTR) \
+		{ \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+			break; \
+		} \
+		errno=0; \
+		clearerr(zconfin); \
+	}\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int zconflex (void);
+
+#define YY_DECL int zconflex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after zconftext and zconfleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+
+	int str = 0;
+	int ts, i;
+
+	if ( !(yy_init) )
+		{
+		(yy_init) = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! (yy_start) )
+			(yy_start) = 1;	/* first start state */
+
+		if ( ! zconfin )
+			zconfin = stdin;
+
+		if ( ! zconfout )
+			zconfout = stdout;
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			zconfensure_buffer_stack ();
+			YY_CURRENT_BUFFER_LVALUE =
+				zconf_create_buffer(zconfin,YY_BUF_SIZE );
+		}
+
+		zconf_load_buffer_state( );
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = (yy_c_buf_p);
+
+		/* Support of zconftext. */
+		*yy_cp = (yy_hold_char);
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = (yy_start);
+yy_match:
+		while ( (yy_current_state = yy_nxt[yy_current_state][ yy_ec[YY_SC_TO_UI(*yy_cp)]  ]) > 0 )
+			++yy_cp;
+
+		yy_current_state = -yy_current_state;
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+
+		YY_DO_BEFORE_ACTION;
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+case 1:
+/* rule 1 can match eol */
+case 2:
+/* rule 2 can match eol */
+YY_RULE_SETUP
+{
+	current_file->lineno++;
+	return T_EOL;
+}
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+{
+	BEGIN(COMMAND);
+}
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+{
+	unput(zconftext[0]);
+	BEGIN(COMMAND);
+}
+	YY_BREAK
+
+case 6:
+YY_RULE_SETUP
+{
+		struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
+		BEGIN(PARAM);
+		current_pos.file = current_file;
+		current_pos.lineno = current_file->lineno;
+		if (id && id->flags & TF_COMMAND) {
+			zconflval.id = id;
+			return id->token;
+		}
+		alloc_string(zconftext, zconfleng);
+		zconflval.string = text;
+		return T_WORD;
+	}
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+
+	YY_BREAK
+case 8:
+/* rule 8 can match eol */
+YY_RULE_SETUP
+{
+		BEGIN(INITIAL);
+		current_file->lineno++;
+		return T_EOL;
+	}
+	YY_BREAK
+
+case 9:
+YY_RULE_SETUP
+return T_AND;
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+return T_OR;
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+return T_OPEN_PAREN;
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+return T_CLOSE_PAREN;
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+return T_NOT;
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+return T_EQUAL;
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+return T_UNEQUAL;
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+{
+		str = zconftext[0];
+		new_string();
+		BEGIN(STRING);
+	}
+	YY_BREAK
+case 17:
+/* rule 17 can match eol */
+YY_RULE_SETUP
+BEGIN(INITIAL); current_file->lineno++; return T_EOL;
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+/* ignore */
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+{
+		struct kconf_id *id = kconf_id_lookup(zconftext, zconfleng);
+		if (id && id->flags & TF_PARAM) {
+			zconflval.id = id;
+			return id->token;
+		}
+		alloc_string(zconftext, zconfleng);
+		zconflval.string = text;
+		return T_WORD;
+	}
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+/* comment */
+	YY_BREAK
+case 21:
+/* rule 21 can match eol */
+YY_RULE_SETUP
+current_file->lineno++;
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+
+	YY_BREAK
+case YY_STATE_EOF(PARAM):
+{
+		BEGIN(INITIAL);
+	}
+	YY_BREAK
+
+case 23:
+/* rule 23 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up zconftext again */
+YY_RULE_SETUP
+{
+		append_string(zconftext, zconfleng);
+		zconflval.string = text;
+		return T_WORD_QUOTE;
+	}
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+{
+		append_string(zconftext, zconfleng);
+	}
+	YY_BREAK
+case 25:
+/* rule 25 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up zconftext again */
+YY_RULE_SETUP
+{
+		append_string(zconftext + 1, zconfleng - 1);
+		zconflval.string = text;
+		return T_WORD_QUOTE;
+	}
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+{
+		append_string(zconftext + 1, zconfleng - 1);
+	}
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+{
+		if (str == zconftext[0]) {
+			BEGIN(PARAM);
+			zconflval.string = text;
+			return T_WORD_QUOTE;
+		} else
+			append_string(zconftext, 1);
+	}
+	YY_BREAK
+case 28:
+/* rule 28 can match eol */
+YY_RULE_SETUP
+{
+		printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
+		current_file->lineno++;
+		BEGIN(INITIAL);
+		return T_EOL;
+	}
+	YY_BREAK
+case YY_STATE_EOF(STRING):
+{
+		BEGIN(INITIAL);
+	}
+	YY_BREAK
+
+case 29:
+YY_RULE_SETUP
+{
+		ts = 0;
+		for (i = 0; i < zconfleng; i++) {
+			if (zconftext[i] == '\t')
+				ts = (ts & ~7) + 8;
+			else
+				ts++;
+		}
+		last_ts = ts;
+		if (first_ts) {
+			if (ts < first_ts) {
+				zconf_endhelp();
+				return T_HELPTEXT;
+			}
+			ts -= first_ts;
+			while (ts > 8) {
+				append_string("        ", 8);
+				ts -= 8;
+			}
+			append_string("        ", ts);
+		}
+	}
+	YY_BREAK
+case 30:
+/* rule 30 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up zconftext */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up zconftext again */
+YY_RULE_SETUP
+{
+		current_file->lineno++;
+		zconf_endhelp();
+		return T_HELPTEXT;
+	}
+	YY_BREAK
+case 31:
+/* rule 31 can match eol */
+YY_RULE_SETUP
+{
+		current_file->lineno++;
+		append_string("\n", 1);
+	}
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+{
+		append_string(zconftext, zconfleng);
+		if (!first_ts)
+			first_ts = last_ts;
+	}
+	YY_BREAK
+case YY_STATE_EOF(HELP):
+{
+		zconf_endhelp();
+		return T_HELPTEXT;
+	}
+	YY_BREAK
+
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(COMMAND):
+{
+	if (current_file) {
+		zconf_endfile();
+		return T_EOL;
+	}
+	fclose(zconfin);
+	yyterminate();
+}
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+YY_FATAL_ERROR( "flex scanner jammed" );
+	YY_BREAK
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = (yy_hold_char);
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed zconfin at a new source and called
+			 * zconflex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = zconfin;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state(  );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++(yy_c_buf_p);
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = (yy_c_buf_p);
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer(  ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				(yy_did_buffer_switch_on_eof) = 0;
+
+				if ( zconfwrap( ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * zconftext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				(yy_c_buf_p) =
+					(yytext_ptr) + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				(yy_c_buf_p) =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+} /* end of zconflex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	register char *source = (yytext_ptr);
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+	else
+		{
+			int num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+			int yy_c_buf_p_offset =
+				(int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					zconfrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			(yy_n_chars), num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	if ( (yy_n_chars) == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			zconfrestart(zconfin  );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	(yy_n_chars) += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+	static yy_state_type yy_get_previous_state (void)
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+
+	yy_current_state = (yy_start);
+
+	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+		{
+		yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1)];
+		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+	static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+	register int yy_is_jam;
+
+	yy_current_state = yy_nxt[yy_current_state][1];
+	yy_is_jam = (yy_current_state <= 0);
+
+	return yy_is_jam ? 0 : yy_current_state;
+}
+
+	static void yyunput (int c, register char * yy_bp )
+{
+	register char *yy_cp;
+
+	yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up zconftext */
+	*yy_cp = (yy_hold_char);
+
+	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = (yy_n_chars) + 2;
+		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+		register char *source =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+	void zconfrestart  (FILE * input_file )
+{
+
+	if ( ! YY_CURRENT_BUFFER ){
+		zconfensure_buffer_stack ();
+		YY_CURRENT_BUFFER_LVALUE =
+		    zconf_create_buffer(zconfin,YY_BUF_SIZE );
+	}
+
+	zconf_init_buffer(YY_CURRENT_BUFFER,input_file );
+	zconf_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+	void zconf_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		zconfpop_buffer_state();
+	 *		zconfpush_buffer_state(new_buffer);
+     */
+	zconfensure_buffer_stack ();
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	zconf_load_buffer_state( );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (zconfwrap()) processing, but the only time this flag
+	 * is looked at is after zconfwrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void zconf_load_buffer_state  (void)
+{
+	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	zconfin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	(yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+	YY_BUFFER_STATE zconf_create_buffer  (FILE * file, int  size )
+{
+	YY_BUFFER_STATE b;
+
+	b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) zconfalloc(b->yy_buf_size + 2  );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in zconf_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	zconf_init_buffer(b,file );
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with zconf_create_buffer()
+ *
+ */
+	void zconf_delete_buffer (YY_BUFFER_STATE  b )
+{
+
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		zconffree((void *) b->yy_ch_buf  );
+
+	zconffree((void *) b  );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a zconfrestart() or at EOF.
+ */
+	static void zconf_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+	int oerrno = errno;
+
+	zconf_flush_buffer(b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then zconf_init_buffer was _probably_
+     * called from zconfrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+	if (b != YY_CURRENT_BUFFER){
+		b->yy_bs_lineno = 1;
+		b->yy_bs_column = 0;
+	}
+
+		b->yy_is_interactive = 0;
+
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+	void zconf_flush_buffer (YY_BUFFER_STATE  b )
+{
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		zconf_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *
+ */
+void zconfpush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+	if (new_buffer == NULL)
+		return;
+
+	zconfensure_buffer_stack();
+
+	/* This block is copied from zconf_switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		(yy_buffer_stack_top)++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from zconf_switch_to_buffer. */
+	zconf_load_buffer_state( );
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *
+ */
+void zconfpop_buffer_state (void)
+{
+	if (!YY_CURRENT_BUFFER)
+		return;
+
+	zconf_delete_buffer(YY_CURRENT_BUFFER );
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if ((yy_buffer_stack_top) > 0)
+		--(yy_buffer_stack_top);
+
+	if (YY_CURRENT_BUFFER) {
+		zconf_load_buffer_state( );
+		(yy_did_buffer_switch_on_eof) = 1;
+	}
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void zconfensure_buffer_stack (void)
+{
+	int num_to_alloc;
+
+	if (!(yy_buffer_stack)) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+		num_to_alloc = 1;
+		(yy_buffer_stack) = (struct yy_buffer_state**)zconfalloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+
+		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+		(yy_buffer_stack_max) = num_to_alloc;
+		(yy_buffer_stack_top) = 0;
+		return;
+	}
+
+	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		int grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = (yy_buffer_stack_max) + grow_size;
+		(yy_buffer_stack) = (struct yy_buffer_state**)zconfrealloc
+								((yy_buffer_stack),
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+
+		/* zero only the new slots.*/
+		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+		(yy_buffer_stack_max) = num_to_alloc;
+	}
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE zconf_scan_buffer  (char * base, yy_size_t  size )
+{
+	YY_BUFFER_STATE b;
+
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) zconfalloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	zconf_switch_to_buffer(b  );
+
+	return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to zconflex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       zconf_scan_bytes() instead.
+ */
+YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr )
+{
+
+	return zconf_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE zconf_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = _yybytes_len + 2;
+	buf = (char *) zconfalloc(n  );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = zconf_scan_buffer(buf,n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in zconf_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up zconftext. */ \
+		int yyless_macro_arg = (n); \
+		YY_LESS_LINENO(yyless_macro_arg);\
+		zconftext[zconfleng] = (yy_hold_char); \
+		(yy_c_buf_p) = zconftext + yyless_macro_arg; \
+		(yy_hold_char) = *(yy_c_buf_p); \
+		*(yy_c_buf_p) = '\0'; \
+		zconfleng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int zconfget_lineno  (void)
+{
+
+	return zconflineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *zconfget_in  (void)
+{
+		return zconfin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *zconfget_out  (void)
+{
+		return zconfout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int zconfget_leng  (void)
+{
+		return zconfleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *zconfget_text  (void)
+{
+		return zconftext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void zconfset_lineno (int  line_number )
+{
+
+	zconflineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see zconf_switch_to_buffer
+ */
+void zconfset_in (FILE *  in_str )
+{
+		zconfin = in_str ;
+}
+
+void zconfset_out (FILE *  out_str )
+{
+		zconfout = out_str ;
+}
+
+int zconfget_debug  (void)
+{
+		return zconf_flex_debug;
+}
+
+void zconfset_debug (int  bdebug )
+{
+		zconf_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from zconflex_destroy(), so don't allocate here.
+     */
+
+	(yy_buffer_stack) = 0;
+	(yy_buffer_stack_top) = 0;
+	(yy_buffer_stack_max) = 0;
+	(yy_c_buf_p) = (char *) 0;
+	(yy_init) = 0;
+	(yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+	zconfin = stdin;
+	zconfout = stdout;
+#else
+	zconfin = (FILE *) 0;
+	zconfout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * zconflex_init()
+     */
+	return 0;
+}
+
+/* zconflex_destroy is for both reentrant and non-reentrant scanners. */
+int zconflex_destroy  (void)
+{
+
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		zconf_delete_buffer(YY_CURRENT_BUFFER  );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		zconfpop_buffer_state();
+	}
+
+	/* Destroy the stack itself. */
+	zconffree((yy_buffer_stack) );
+	(yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * zconflex() is called, initialization will occur. */
+	yy_init_globals( );
+
+	return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *zconfalloc (yy_size_t  size )
+{
+	return (void *) malloc( size );
+}
+
+void *zconfrealloc  (void * ptr, yy_size_t  size )
+{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+}
+
+void zconffree (void * ptr )
+{
+	free( (char *) ptr );	/* see zconfrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+void zconf_starthelp(void)
+{
+	new_string();
+	last_ts = first_ts = 0;
+	BEGIN(HELP);
+}
+
+static void zconf_endhelp(void)
+{
+	zconflval.string = text;
+	BEGIN(INITIAL);
+}
+
+/*
+ * Try to open specified file with following names:
+ * ./name
+ * $(srctree)/name
+ * The latter is used when srctree is separate from objtree
+ * when compiling the kernel.
+ * Return NULL if file is not found.
+ */
+FILE *zconf_fopen(const char *name)
+{
+	char *env, fullname[PATH_MAX+1];
+	FILE *f;
+
+	f = fopen(name, "r");
+	if (!f && name != NULL && name[0] != '/') {
+		env = getenv(SRCTREE);
+		if (env) {
+			sprintf(fullname, "%s/%s", env, name);
+			f = fopen(fullname, "r");
+		}
+	}
+	return f;
+}
+
+void zconf_initscan(const char *name)
+{
+	zconfin = zconf_fopen(name);
+	if (!zconfin) {
+		printf("can't find file %s\n", name);
+		exit(1);
+	}
+
+	current_buf = malloc(sizeof(*current_buf));
+	memset(current_buf, 0, sizeof(*current_buf));
+
+	current_file = file_lookup(name);
+	current_file->lineno = 1;
+	current_file->flags = FILE_BUSY;
+}
+
+void zconf_nextfile(const char *name)
+{
+	struct file *file = file_lookup(name);
+	struct buffer *buf = malloc(sizeof(*buf));
+	memset(buf, 0, sizeof(*buf));
+
+	current_buf->state = YY_CURRENT_BUFFER;
+	zconfin = zconf_fopen(name);
+	if (!zconfin) {
+		printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name);
+		exit(1);
+	}
+	zconf_switch_to_buffer(zconf_create_buffer(zconfin,YY_BUF_SIZE));
+	buf->parent = current_buf;
+	current_buf = buf;
+
+	if (file->flags & FILE_BUSY) {
+		printf("recursive scan (%s)?\n", name);
+		exit(1);
+	}
+	if (file->flags & FILE_SCANNED) {
+		printf("file %s already scanned?\n", name);
+		exit(1);
+	}
+	file->flags |= FILE_BUSY;
+	file->lineno = 1;
+	file->parent = current_file;
+	current_file = file;
+}
+
+static void zconf_endfile(void)
+{
+	struct buffer *parent;
+
+	current_file->flags |= FILE_SCANNED;
+	current_file->flags &= ~FILE_BUSY;
+	current_file = current_file->parent;
+
+	parent = current_buf->parent;
+	if (parent) {
+		fclose(zconfin);
+		zconf_delete_buffer(YY_CURRENT_BUFFER);
+		zconf_switch_to_buffer(parent->state);
+	}
+	free(current_buf);
+	current_buf = parent;
+}
+
+int zconf_lineno(void)
+{
+	return current_pos.lineno;
+}
+
+char *zconf_curname(void)
+{
+	return current_pos.file ? current_pos.file->name : "<none>";
+}
+
diff --git a/host/src/wrsconfig/lkc.h b/host/src/wrsconfig/lkc.h
new file mode 100755
index 0000000..3875480
--- /dev/null
+++ b/host/src/wrsconfig/lkc.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#ifndef LKC_H
+#define LKC_H
+
+#ifdef HOST_WIN32
+  #include <io.h>	/* for mkdir() */
+#endif
+
+#include "expr.h"
+
+#ifndef KBUILD_NO_NLS
+# include <libintl.h>
+#else
+# define gettext(Msgid) ((const char *) (Msgid))
+# define textdomain(Domainname) ((const char *) (Domainname))
+# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef LKC_DIRECT_LINK
+#define P(name,type,arg)	extern type name arg
+#else
+#include "lkc_defs.h"
+#define P(name,type,arg)	extern type (*name ## _p) arg
+#endif
+#include "lkc_proto.h"
+#undef P
+
+#define SRCTREE "srctree"
+
+#define PACKAGE "linux"
+#define LOCALEDIR "/usr/share/locale"
+
+#define _(text) gettext(text)
+#define N_(text) (text)
+
+
+#define TF_COMMAND	0x0001
+#define TF_PARAM	0x0002
+#define TF_OPTION	0x0004
+
+#define T_OPT_MODULES		1
+#define T_OPT_DEFCONFIG_LIST	2
+
+struct kconf_id {
+	int name;
+	int token;
+	unsigned int flags;
+	enum symbol_type stype;
+};
+
+int zconfparse(void);
+void zconfdump(FILE *out);
+
+extern int zconfdebug;
+void zconf_starthelp(void);
+FILE *zconf_fopen(const char *name);
+void zconf_initscan(const char *name);
+void zconf_nextfile(const char *name);
+int zconf_lineno(void);
+char *zconf_curname(void);
+
+/* confdata.c */
+const char *conf_get_configname(void);
+char *conf_get_default_confname(void);
+void sym_set_change_count(int count);
+void sym_add_change_count(int count);
+
+/* kconfig_load.c */
+void kconfig_load(void);
+
+/* menu.c */
+void menu_init(void);
+struct menu *menu_add_menu(void);
+void menu_end_menu(void);
+void menu_add_entry(struct symbol *sym);
+void menu_end_entry(void);
+void menu_add_dep(struct expr *dep);
+struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
+struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
+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_add_option(int token, char *arg);
+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);
+
+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);
+void sym_clear_all_valid(void);
+void sym_set_all_changed(void);
+void sym_set_changed(struct symbol *sym);
+struct symbol *sym_check_deps(struct symbol *sym);
+struct property *prop_alloc(enum prop_type type, struct symbol *sym);
+struct symbol *prop_get_symbol(struct property *prop);
+
+static inline tristate sym_get_tristate_value(struct symbol *sym)
+{
+	return sym->curr.tri;
+}
+
+
+static inline struct symbol *sym_get_choice_value(struct symbol *sym)
+{
+	return (struct symbol *)sym->curr.val;
+}
+
+static inline bool sym_set_choice_value(struct symbol *ch, struct symbol *chval)
+{
+	return sym_set_tristate_value(chval, yes);
+}
+
+static inline bool sym_is_choice(struct symbol *sym)
+{
+	return sym->flags & SYMBOL_CHOICE ? true : false;
+}
+
+static inline bool sym_is_choice_value(struct symbol *sym)
+{
+	return sym->flags & SYMBOL_CHOICEVAL ? true : false;
+}
+
+static inline bool sym_is_optional(struct symbol *sym)
+{
+	return sym->flags & SYMBOL_OPTIONAL ? true : false;
+}
+
+static inline bool sym_has_value(struct symbol *sym)
+{
+	return sym->flags & SYMBOL_DEF_USER ? true : false;
+}
+
+static inline int loc_rename(const char *old, const char *new)
+{
+#ifdef HOST_WIN32
+	unlink(new);
+#endif
+	return rename(old, new);
+}
+
+static inline int loc_mkdir(const char *path, int mode)
+{
+#ifdef HOST_WIN32
+	return mkdir(path);
+#else
+	return mkdir(path, mode);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LKC_H */
diff --git a/host/src/wrsconfig/lkc_proto.h b/host/src/wrsconfig/lkc_proto.h
new file mode 100755
index 0000000..bca8508
--- /dev/null
+++ b/host/src/wrsconfig/lkc_proto.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011, Wind River Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3) Neither the name of Wind River Systems nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* confdata.c */
+P(conf_parse,void,(const char *name));
+P(conf_read,int,(const char *name));
+P(conf_read_simple,int,(const char *name, int));
+P(conf_write,int,(const char *name));
+P(conf_write_autoconf,int,(void));
+P(conf_get_changed,bool,(void));
+P(conf_set_changed_callback, void,(void (*fn)(void)));
+
+/* menu.c */
+P(rootmenu,struct menu,);
+
+P(menu_is_visible,bool,(struct menu *menu));
+P(menu_get_prompt,const char *,(struct menu *menu));
+P(menu_get_root_menu,struct menu *,(struct menu *menu));
+P(menu_get_parent_menu,struct menu *,(struct menu *menu));
+P(menu_has_help,bool,(struct menu *menu));
+P(menu_get_help,const char *,(struct menu *menu));
+
+/* symbol.c */
+P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
+
+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));
+P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri));
+P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri));
+P(sym_toggle_tristate_value,tristate,(struct symbol *sym));
+P(sym_string_valid,bool,(struct symbol *sym, const char *newval));
+P(sym_string_within_range,bool,(struct symbol *sym, const char *str));
+P(sym_set_string_value,bool,(struct symbol *sym, const char *newval));
+P(sym_is_changable,bool,(struct symbol *sym));
+P(sym_get_choice_prop,struct property *,(struct symbol *sym));
+P(sym_get_default_prop,struct property *,(struct symbol *sym));
+P(sym_get_string_value,const char *,(struct symbol *sym));
+
+P(prop_get_type_name,const char *,(enum prop_type type));
+
+/* expr.c */
+P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2));
+P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken));
diff --git a/host/src/wrsconfig/menu.c b/host/src/wrsconfig/menu.c
new file mode 100755
index 0000000..ea7af5c
--- /dev/null
+++ b/host/src/wrsconfig/menu.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+struct menu rootmenu;
+static struct menu **last_entry_ptr;
+
+struct file *file_list;
+struct file *current_file;
+
+static void menu_warn(struct menu *menu, const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno);
+	vfprintf(stderr, fmt, ap);
+	fprintf(stderr, "\n");
+	va_end(ap);
+}
+
+static void prop_warn(struct property *prop, const char *fmt, ...)
+{
+	va_list ap;
+	va_start(ap, fmt);
+	fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno);
+	vfprintf(stderr, fmt, ap);
+	fprintf(stderr, "\n");
+	va_end(ap);
+}
+
+void menu_init(void)
+{
+	current_entry = current_menu = &rootmenu;
+	last_entry_ptr = &rootmenu.list;
+}
+
+void menu_add_entry(struct symbol *sym)
+{
+	struct menu *menu;
+
+	menu = malloc(sizeof(*menu));
+	memset(menu, 0, sizeof(*menu));
+	menu->sym = sym;
+	menu->parent = current_menu;
+	menu->file = current_file;
+	menu->lineno = zconf_lineno();
+
+	*last_entry_ptr = menu;
+	last_entry_ptr = &menu->next;
+	current_entry = menu;
+}
+
+void menu_end_entry(void)
+{
+}
+
+struct menu *menu_add_menu(void)
+{
+	menu_end_entry();
+	last_entry_ptr = &current_entry->list;
+	return current_menu = current_entry;
+}
+
+void menu_end_menu(void)
+{
+	last_entry_ptr = &current_menu->next;
+	current_menu = current_menu->parent;
+}
+
+struct expr *menu_check_dep(struct expr *e)
+{
+	if (!e)
+		return e;
+
+	switch (e->type) {
+	case E_NOT:
+		e->left.expr = menu_check_dep(e->left.expr);
+		break;
+	case E_OR:
+	case E_AND:
+		e->left.expr = menu_check_dep(e->left.expr);
+		e->right.expr = menu_check_dep(e->right.expr);
+		break;
+	case E_SYMBOL:
+		/* change 'm' into 'm' && MODULES */
+		if (e->left.sym == &symbol_mod)
+			return expr_alloc_and(e, expr_alloc_symbol(modules_sym));
+		break;
+	default:
+		break;
+	}
+	return e;
+}
+
+void menu_add_dep(struct expr *dep)
+{
+	current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
+}
+
+void menu_set_type(int type)
+{
+	struct symbol *sym = current_entry->sym;
+
+	if (sym->type == type)
+		return;
+	if (sym->type == S_UNKNOWN) {
+		sym->type = type;
+		return;
+	}
+	menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'",
+	    sym->name ? sym->name : "<choice>",
+	    sym_type_name(sym->type), sym_type_name(type));
+}
+
+struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
+{
+	struct property *prop = prop_alloc(type, current_entry->sym);
+
+	prop->menu = current_entry;
+	prop->expr = expr;
+	prop->visible.expr = menu_check_dep(dep);
+
+	if (prompt) {
+		if (isspace(*prompt)) {
+			prop_warn(prop, "leading whitespace ignored");
+			while (isspace(*prompt))
+				prompt++;
+		}
+		if (current_entry->prompt)
+			prop_warn(prop, "prompt redefined");
+		current_entry->prompt = prop;
+	}
+	prop->text = prompt;
+
+	return prop;
+}
+
+struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep)
+{
+	return menu_add_prop(type, prompt, NULL, dep);
+}
+
+void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep)
+{
+	menu_add_prop(type, NULL, expr, dep);
+}
+
+void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
+{
+	menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
+}
+
+void menu_add_option(int token, char *arg)
+{
+	struct property *prop;
+
+	switch (token) {
+	case T_OPT_MODULES:
+		prop = prop_alloc(P_DEFAULT, modules_sym);
+		prop->expr = expr_alloc_symbol(current_entry->sym);
+		break;
+	case T_OPT_DEFCONFIG_LIST:
+		if (!sym_defconfig_list)
+			sym_defconfig_list = current_entry->sym;
+		else if (sym_defconfig_list != current_entry->sym)
+			zconf_error("trying to redefine defconfig symbol");
+		break;
+	}
+}
+
+static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2)
+{
+	return sym2->type == S_INT || sym2->type == S_HEX ||
+	       (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name));
+}
+
+void sym_check_prop(struct symbol *sym)
+{
+	struct property *prop;
+	struct symbol *sym2;
+	for (prop = sym->prop; prop; prop = prop->next) {
+		switch (prop->type) {
+		case P_DEFAULT:
+			if ((sym->type == S_STRING || sym->type == S_INT || sym->type == S_HEX) &&
+			    prop->expr->type != E_SYMBOL)
+				prop_warn(prop,
+				    "default for config symbol '%'"
+				    " must be a single symbol", sym->name);
+			break;
+		case P_SELECT:
+			sym2 = prop_get_symbol(prop);
+			if (sym->type != S_BOOLEAN && sym->type != S_TRISTATE)
+				prop_warn(prop,
+				    "config symbol '%s' uses select, but is "
+				    "not boolean or tristate", sym->name);
+			else if (sym2->type == S_UNKNOWN)
+				prop_warn(prop,
+				    "'select' used by config symbol '%s' "
+				    "refers to undefined symbol '%s'",
+				    sym->name, sym2->name);
+			else if (sym2->type != S_BOOLEAN && sym2->type != S_TRISTATE)
+				prop_warn(prop,
+				    "'%s' has wrong type. 'select' only "
+				    "accept arguments of boolean and "
+				    "tristate type", sym2->name);
+			break;
+		case P_RANGE:
+			if (sym->type != S_INT && sym->type != S_HEX)
+				prop_warn(prop, "range is only allowed "
+				                "for int or hex symbols");
+			if (!menu_range_valid_sym(sym, prop->expr->left.sym) ||
+			    !menu_range_valid_sym(sym, prop->expr->right.sym))
+				prop_warn(prop, "range is invalid");
+			break;
+		default:
+			;
+		}
+	}
+}
+
+void menu_finalize(struct menu *parent)
+{
+	struct menu *menu, *last_menu;
+	struct symbol *sym;
+	struct property *prop;
+	struct expr *parentdep, *basedep, *dep, *dep2, **ep;
+
+	sym = parent->sym;
+	if (parent->list) {
+		if (sym && sym_is_choice(sym)) {
+			/* find the first choice value and find out choice type */
+			for (menu = parent->list; menu; menu = menu->next) {
+				if (menu->sym) {
+					current_entry = parent;
+					menu_set_type(menu->sym->type);
+					current_entry = menu;
+					menu_set_type(sym->type);
+					break;
+				}
+			}
+			parentdep = expr_alloc_symbol(sym);
+		} else if (parent->prompt)
+			parentdep = parent->prompt->visible.expr;
+		else
+			parentdep = parent->dep;
+
+		for (menu = parent->list; menu; menu = menu->next) {
+			basedep = expr_transform(menu->dep);
+			basedep = expr_alloc_and(expr_copy(parentdep), basedep);
+			basedep = expr_eliminate_dups(basedep);
+			menu->dep = basedep;
+			if (menu->sym)
+				prop = menu->sym->prop;
+			else
+				prop = menu->prompt;
+			for (; prop; prop = prop->next) {
+				if (prop->menu != menu)
+					continue;
+				dep = expr_transform(prop->visible.expr);
+				dep = expr_alloc_and(expr_copy(basedep), dep);
+				dep = expr_eliminate_dups(dep);
+				if (menu->sym && menu->sym->type != S_TRISTATE)
+					dep = expr_trans_bool(dep);
+				prop->visible.expr = dep;
+				if (prop->type == P_SELECT) {
+					struct symbol *es = prop_get_symbol(prop);
+					es->rev_dep.expr = expr_alloc_or(es->rev_dep.expr,
+							expr_alloc_and(expr_alloc_symbol(menu->sym), expr_copy(dep)));
+				}
+			}
+		}
+		for (menu = parent->list; menu; menu = menu->next)
+			menu_finalize(menu);
+	} else if (sym) {
+		basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
+		basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
+		basedep = expr_eliminate_dups(expr_transform(basedep));
+		last_menu = NULL;
+		for (menu = parent->next; menu; menu = menu->next) {
+			dep = menu->prompt ? menu->prompt->visible.expr : menu->dep;
+			if (!expr_contains_symbol(dep, sym))
+				break;
+			if (expr_depends_symbol(dep, sym))
+				goto next;
+			dep = expr_trans_compare(dep, E_UNEQUAL, &symbol_no);
+			dep = expr_eliminate_dups(expr_transform(dep));
+			dep2 = expr_copy(basedep);
+			expr_eliminate_eq(&dep, &dep2);
+			expr_free(dep);
+			if (!expr_is_yes(dep2)) {
+				expr_free(dep2);
+				break;
+			}
+			expr_free(dep2);
+next:
+			menu_finalize(menu);
+			menu->parent = parent;
+			last_menu = menu;
+		}
+		if (last_menu) {
+			parent->list = parent->next;
+			parent->next = last_menu->next;
+			last_menu->next = NULL;
+		}
+	}
+	for (menu = parent->list; menu; menu = menu->next) {
+		if (sym && sym_is_choice(sym) && menu->sym) {
+			menu->sym->flags |= SYMBOL_CHOICEVAL;
+			if (!menu->prompt)
+				menu_warn(menu, "choice value must have a prompt");
+			for (prop = menu->sym->prop; prop; prop = prop->next) {
+				if (prop->type == P_PROMPT && prop->menu != menu) {
+					prop_warn(prop, "choice values "
+					    "currently only support a "
+					    "single prompt");
+				}
+				if (prop->type == P_DEFAULT)
+					prop_warn(prop, "defaults for choice "
+					    "values not supported");
+			}
+			current_entry = menu;
+			menu_set_type(sym->type);
+			menu_add_symbol(P_CHOICE, sym, NULL);
+			prop = sym_get_choice_prop(sym);
+			for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
+				;
+			*ep = expr_alloc_one(E_CHOICE, NULL);
+			(*ep)->right.sym = menu->sym;
+		}
+		if (menu->list && (!menu->prompt || !menu->prompt->text)) {
+			for (last_menu = menu->list; ; last_menu = last_menu->next) {
+				last_menu->parent = parent;
+				if (!last_menu->next)
+					break;
+			}
+			last_menu->next = menu->next;
+			menu->next = menu->list;
+			menu->list = NULL;
+		}
+	}
+
+	if (sym && !(sym->flags & SYMBOL_WARNED)) {
+		if (sym->type == S_UNKNOWN)
+			menu_warn(parent, "config symbol defined without type");
+
+		if (sym_is_choice(sym) && !parent->prompt)
+			menu_warn(parent, "choice must have a prompt");
+
+		/* Check properties connected to this symbol */
+		sym_check_prop(sym);
+		sym->flags |= SYMBOL_WARNED;
+	}
+
+	if (sym && !sym_is_optional(sym) && parent->prompt) {
+		sym->rev_dep.expr = expr_alloc_or(sym->rev_dep.expr,
+				expr_alloc_and(parent->prompt->visible.expr,
+					expr_alloc_symbol(&symbol_mod)));
+	}
+}
+
+bool menu_is_visible(struct menu *menu)
+{
+	struct menu *child;
+	struct symbol *sym;
+	tristate visible;
+
+	if (!menu->prompt)
+		return false;
+	sym = menu->sym;
+	if (sym) {
+		sym_calc_value(sym);
+		visible = menu->prompt->visible.tri;
+	} else
+		visible = menu->prompt->visible.tri = expr_calc_value(menu->prompt->visible.expr);
+
+	if (visible != no)
+		return true;
+	if (!sym || sym_get_tristate_value(menu->sym) == no)
+		return false;
+
+	for (child = menu->list; child; child = child->next)
+		if (menu_is_visible(child))
+			return true;
+	return false;
+}
+
+const char *menu_get_prompt(struct menu *menu)
+{
+	if (menu->prompt)
+		return _(menu->prompt->text);
+	else if (menu->sym)
+		return _(menu->sym->name);
+	return NULL;
+}
+
+struct menu *menu_get_root_menu(struct menu *menu)
+{
+	return &rootmenu;
+}
+
+struct menu *menu_get_parent_menu(struct menu *menu)
+{
+	enum prop_type type;
+
+	for (; menu != &rootmenu; menu = menu->parent) {
+		type = menu->prompt ? menu->prompt->type : 0;
+		if (type == P_MENU)
+			break;
+	}
+	return menu;
+}
+
+bool menu_has_help(struct menu *menu)
+{
+	return menu->help != NULL;
+}
+
+const char *menu_get_help(struct menu *menu)
+{
+	if (menu->help)
+		return menu->help;
+	else
+		return "";
+}
diff --git a/host/src/wrsconfig/symbol.c b/host/src/wrsconfig/symbol.c
new file mode 100755
index 0000000..4a30980
--- /dev/null
+++ b/host/src/wrsconfig/symbol.c
@@ -0,0 +1,887 @@
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef NO_REGEX
+#include <regex.h>
+#endif
+#ifndef NO_UNAME
+#include <sys/utsname.h>
+#endif
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+struct symbol symbol_yes = {
+	.name = "y",
+	.curr = { "y", yes },
+	.flags = SYMBOL_CONST|SYMBOL_VALID,
+}, symbol_mod = {
+	.name = "m",
+	.curr = { "m", mod },
+	.flags = SYMBOL_CONST|SYMBOL_VALID,
+}, symbol_no = {
+	.name = "n",
+	.curr = { "n", no },
+	.flags = SYMBOL_CONST|SYMBOL_VALID,
+}, symbol_empty = {
+	.name = "",
+	.curr = { "", no },
+	.flags = SYMBOL_VALID,
+};
+
+struct symbol *sym_defconfig_list;
+struct symbol *modules_sym;
+tristate modules_val;
+
+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, 1));
+}
+
+void sym_init(void)
+{
+	struct symbol *sym;
+#ifndef NO_UNAME
+	struct utsname uts;
+#endif
+	char *p;
+	static bool inited = false;
+
+	if (inited)
+		return;
+	inited = true;
+
+	sym = sym_lookup("ARCH", 0);
+	sym->type = S_STRING;
+	sym->flags |= SYMBOL_AUTO;
+	p = getenv("ARCH");
+	if (p)
+		sym_add_default(sym, p);
+
+	sym = sym_lookup("KERNELVERSION", 0);
+	sym->type = S_STRING;
+	sym->flags |= SYMBOL_AUTO;
+	p = getenv("KERNELVERSION");
+	if (p)
+		sym_add_default(sym, p);
+
+#ifndef NO_UNAME
+	uname(&uts);
+	sym = sym_lookup("UNAME_RELEASE", 0);
+	sym->type = S_STRING;
+	sym->flags |= SYMBOL_AUTO;
+	sym_add_default(sym, uts.release);
+#endif
+}
+
+enum symbol_type sym_get_type(struct symbol *sym)
+{
+	enum symbol_type type = sym->type;
+
+	if (type == S_TRISTATE) {
+		if (sym_is_choice_value(sym) && sym->visible == yes)
+			type = S_BOOLEAN;
+		else if (modules_val == no)
+			type = S_BOOLEAN;
+	}
+	return type;
+}
+
+const char *sym_type_name(enum symbol_type type)
+{
+	switch (type) {
+	case S_BOOLEAN:
+		return "boolean";
+	case S_TRISTATE:
+		return "tristate";
+	case S_INT:
+		return "integer";
+	case S_HEX:
+		return "hex";
+	case S_STRING:
+		return "string";
+	case S_UNKNOWN:
+		return "unknown";
+	case S_OTHER:
+		break;
+	}
+	return "???";
+}
+
+struct property *sym_get_choice_prop(struct symbol *sym)
+{
+	struct property *prop;
+
+	for_all_choices(sym, prop)
+		return prop;
+	return NULL;
+}
+
+struct property *sym_get_default_prop(struct symbol *sym)
+{
+	struct property *prop;
+
+	for_all_defaults(sym, prop) {
+		prop->visible.tri = expr_calc_value(prop->visible.expr);
+		if (prop->visible.tri != no)
+			return prop;
+	}
+	return NULL;
+}
+
+struct property *sym_get_range_prop(struct symbol *sym)
+{
+	struct property *prop;
+
+	for_all_properties(sym, prop, P_RANGE) {
+		prop->visible.tri = expr_calc_value(prop->visible.expr);
+		if (prop->visible.tri != no)
+			return prop;
+	}
+	return NULL;
+}
+
+static int sym_get_range_val(struct symbol *sym, int base)
+{
+	sym_calc_value(sym);
+	switch (sym->type) {
+	case S_INT:
+		base = 10;
+		break;
+	case S_HEX:
+		base = 16;
+		break;
+	default:
+		break;
+	}
+	return strtol(sym->curr.val, NULL, base);
+}
+
+static void sym_validate_range(struct symbol *sym)
+{
+	struct property *prop;
+	int base, val, val2;
+	char str[64];
+
+	switch (sym->type) {
+	case S_INT:
+		base = 10;
+		break;
+	case S_HEX:
+		base = 16;
+		break;
+	default:
+		return;
+	}
+	prop = sym_get_range_prop(sym);
+	if (!prop)
+		return;
+	val = strtol(sym->curr.val, NULL, base);
+	val2 = sym_get_range_val(prop->expr->left.sym, base);
+	if (val >= val2) {
+		val2 = sym_get_range_val(prop->expr->right.sym, base);
+		if (val <= val2)
+			return;
+	}
+	if (sym->type == S_INT)
+		sprintf(str, "%d", val2);
+	else
+		sprintf(str, "0x%x", val2);
+	sym->curr.val = strdup(str);
+}
+
+static void sym_calc_visibility(struct symbol *sym)
+{
+	struct property *prop;
+	tristate tri;
+
+	/* any prompt visible? */
+	tri = no;
+	for_all_prompts(sym, prop) {
+		prop->visible.tri = expr_calc_value(prop->visible.expr);
+		tri = E_OR(tri, prop->visible.tri);
+	}
+	if (tri == mod && (sym->type != S_TRISTATE || modules_val == no))
+		tri = yes;
+	if (sym->visible != tri) {
+		sym->visible = tri;
+		sym_set_changed(sym);
+	}
+	if (sym_is_choice_value(sym))
+		return;
+	tri = no;
+	if (sym->rev_dep.expr)
+		tri = expr_calc_value(sym->rev_dep.expr);
+	if (tri == mod && sym_get_type(sym) == S_BOOLEAN)
+		tri = yes;
+	if (sym->rev_dep.tri != tri) {
+		sym->rev_dep.tri = tri;
+		sym_set_changed(sym);
+	}
+}
+
+static struct symbol *sym_calc_choice(struct symbol *sym)
+{
+	struct symbol *def_sym;
+	struct property *prop;
+	struct expr *e;
+
+	/* is the user choice visible? */
+	def_sym = sym->def[S_DEF_USER].val;
+	if (def_sym) {
+		sym_calc_visibility(def_sym);
+		if (def_sym->visible != no)
+			return def_sym;
+	}
+
+	/* any of the defaults visible? */
+	for_all_defaults(sym, prop) {
+		prop->visible.tri = expr_calc_value(prop->visible.expr);
+		if (prop->visible.tri == no)
+			continue;
+		def_sym = prop_get_symbol(prop);
+		sym_calc_visibility(def_sym);
+		if (def_sym->visible != no)
+			return def_sym;
+	}
+
+	/* just get the first visible value */
+	prop = sym_get_choice_prop(sym);
+	for (e = prop->expr; e; e = e->left.expr) {
+		def_sym = e->right.sym;
+		sym_calc_visibility(def_sym);
+		if (def_sym->visible != no)
+			return def_sym;
+	}
+
+	/* no choice? reset tristate value */
+	sym->curr.tri = no;
+	return NULL;
+}
+
+void sym_calc_value(struct symbol *sym)
+{
+	struct symbol_value newval, oldval;
+	struct property *prop;
+	struct expr *e;
+
+	if (!sym)
+		return;
+
+	if (sym->flags & SYMBOL_VALID)
+		return;
+	sym->flags |= SYMBOL_VALID;
+
+	oldval = sym->curr;
+
+	switch (sym->type) {
+	case S_INT:
+	case S_HEX:
+	case S_STRING:
+		newval = symbol_empty.curr;
+		break;
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		newval = symbol_no.curr;
+		break;
+	default:
+		sym->curr.val = sym->name;
+		sym->curr.tri = no;
+		return;
+	}
+	if (!sym_is_choice_value(sym))
+		sym->flags &= ~SYMBOL_WRITE;
+
+	sym_calc_visibility(sym);
+
+	/* set default if recursively called */
+	sym->curr = newval;
+
+	switch (sym_get_type(sym)) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		if (sym_is_choice_value(sym) && sym->visible == yes) {
+			prop = sym_get_choice_prop(sym);
+			newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
+		} else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
+			sym->flags |= SYMBOL_WRITE;
+			if (sym_has_value(sym))
+				newval.tri = sym->def[S_DEF_USER].tri;
+			else if (!sym_is_choice(sym)) {
+				prop = sym_get_default_prop(sym);
+				if (prop)
+					newval.tri = expr_calc_value(prop->expr);
+			}
+			newval.tri = E_OR(E_AND(newval.tri, sym->visible), sym->rev_dep.tri);
+		} else if (!sym_is_choice(sym)) {
+			prop = sym_get_default_prop(sym);
+			if (prop) {
+				sym->flags |= SYMBOL_WRITE;
+				newval.tri = expr_calc_value(prop->expr);
+			}
+		}
+		if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
+			newval.tri = yes;
+		break;
+	case S_STRING:
+	case S_HEX:
+	case S_INT:
+		if (sym->visible != no) {
+			sym->flags |= SYMBOL_WRITE;
+			if (sym_has_value(sym)) {
+				newval.val = sym->def[S_DEF_USER].val;
+				break;
+			}
+		}
+		prop = sym_get_default_prop(sym);
+		if (prop) {
+			struct symbol *ds = prop_get_symbol(prop);
+			if (ds) {
+				sym->flags |= SYMBOL_WRITE;
+				sym_calc_value(ds);
+				newval.val = ds->curr.val;
+			}
+		}
+		break;
+	default:
+		;
+	}
+
+	sym->curr = newval;
+	if (sym_is_choice(sym) && newval.tri == yes)
+		sym->curr.val = sym_calc_choice(sym);
+	sym_validate_range(sym);
+
+	if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
+		sym_set_changed(sym);
+		if (modules_sym == sym) {
+			sym_set_all_changed();
+			modules_val = modules_sym->curr.tri;
+		}
+	}
+
+	if (sym_is_choice(sym)) {
+		int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
+		prop = sym_get_choice_prop(sym);
+		for (e = prop->expr; e; e = e->left.expr) {
+			e->right.sym->flags |= flags;
+			if (flags & SYMBOL_CHANGED)
+				sym_set_changed(e->right.sym);
+		}
+	}
+}
+
+void sym_clear_all_valid(void)
+{
+	struct symbol *sym;
+	int i;
+
+	for_all_symbols(i, sym)
+		sym->flags &= ~SYMBOL_VALID;
+	sym_add_change_count(1);
+	if (modules_sym)
+		sym_calc_value(modules_sym);
+}
+
+void sym_set_changed(struct symbol *sym)
+{
+	struct property *prop;
+
+	sym->flags |= SYMBOL_CHANGED;
+	for (prop = sym->prop; prop; prop = prop->next) {
+		if (prop->menu)
+			prop->menu->flags |= MENU_CHANGED;
+	}
+}
+
+void sym_set_all_changed(void)
+{
+	struct symbol *sym;
+	int i;
+
+	for_all_symbols(i, sym)
+		sym_set_changed(sym);
+}
+
+bool sym_tristate_within_range(struct symbol *sym, tristate val)
+{
+	int type = sym_get_type(sym);
+
+	if (sym->visible == no)
+		return false;
+
+	if (type != S_BOOLEAN && type != S_TRISTATE)
+		return false;
+
+	if (type == S_BOOLEAN && val == mod)
+		return false;
+	if (sym->visible <= sym->rev_dep.tri)
+		return false;
+	if (sym_is_choice_value(sym) && sym->visible == yes)
+		return val == yes;
+	return val >= sym->rev_dep.tri && val <= sym->visible;
+}
+
+bool sym_set_tristate_value(struct symbol *sym, tristate val)
+{
+	tristate oldval = sym_get_tristate_value(sym);
+
+	if (oldval != val && !sym_tristate_within_range(sym, val))
+		return false;
+
+	if (!(sym->flags & SYMBOL_DEF_USER)) {
+		sym->flags |= SYMBOL_DEF_USER;
+		sym_set_changed(sym);
+	}
+	/*
+	 * setting a choice value also resets the new flag of the choice
+	 * symbol and all other choice values.
+	 */
+	if (sym_is_choice_value(sym) && val == yes) {
+		struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
+		struct property *prop;
+		struct expr *e;
+
+		cs->def[S_DEF_USER].val = sym;
+		cs->flags |= SYMBOL_DEF_USER;
+		prop = sym_get_choice_prop(cs);
+		for (e = prop->expr; e; e = e->left.expr) {
+			if (e->right.sym->visible != no)
+				e->right.sym->flags |= SYMBOL_DEF_USER;
+		}
+	}
+
+	sym->def[S_DEF_USER].tri = val;
+	if (oldval != val)
+		sym_clear_all_valid();
+
+	return true;
+}
+
+tristate sym_toggle_tristate_value(struct symbol *sym)
+{
+	tristate oldval, newval;
+
+	oldval = newval = sym_get_tristate_value(sym);
+	do {
+		switch (newval) {
+		case no:
+			newval = mod;
+			break;
+		case mod:
+			newval = yes;
+			break;
+		case yes:
+			newval = no;
+			break;
+		}
+		if (sym_set_tristate_value(sym, newval))
+			break;
+	} while (oldval != newval);
+	return newval;
+}
+
+bool sym_string_valid(struct symbol *sym, const char *str)
+{
+	signed char ch;
+
+	switch (sym->type) {
+	case S_STRING:
+		return true;
+	case S_INT:
+		ch = *str++;
+		if (ch == '-')
+			ch = *str++;
+		if (!isdigit(ch))
+			return false;
+		if (ch == '0' && *str != 0)
+			return false;
+		while ((ch = *str++)) {
+			if (!isdigit(ch))
+				return false;
+		}
+		return true;
+	case S_HEX:
+		if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
+			str += 2;
+		ch = *str++;
+		do {
+			if (!isxdigit(ch))
+				return false;
+		} while ((ch = *str++));
+		return true;
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		switch (str[0]) {
+		case 'y': case 'Y':
+		case 'm': case 'M':
+		case 'n': case 'N':
+			return true;
+		}
+		return false;
+	default:
+		return false;
+	}
+}
+
+bool sym_string_within_range(struct symbol *sym, const char *str)
+{
+	struct property *prop;
+	int val;
+
+	switch (sym->type) {
+	case S_STRING:
+		return sym_string_valid(sym, str);
+	case S_INT:
+		if (!sym_string_valid(sym, str))
+			return false;
+		prop = sym_get_range_prop(sym);
+		if (!prop)
+			return true;
+		val = strtol(str, NULL, 10);
+		return val >= sym_get_range_val(prop->expr->left.sym, 10) &&
+		       val <= sym_get_range_val(prop->expr->right.sym, 10);
+	case S_HEX:
+		if (!sym_string_valid(sym, str))
+			return false;
+		prop = sym_get_range_prop(sym);
+		if (!prop)
+			return true;
+		val = strtol(str, NULL, 16);
+		return val >= sym_get_range_val(prop->expr->left.sym, 16) &&
+		       val <= sym_get_range_val(prop->expr->right.sym, 16);
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		switch (str[0]) {
+		case 'y': case 'Y':
+			return sym_tristate_within_range(sym, yes);
+		case 'm': case 'M':
+			return sym_tristate_within_range(sym, mod);
+		case 'n': case 'N':
+			return sym_tristate_within_range(sym, no);
+		}
+		return false;
+	default:
+		return false;
+	}
+}
+
+bool sym_set_string_value(struct symbol *sym, const char *newval)
+{
+	const char *oldval;
+	char *val;
+	int size;
+
+	switch (sym->type) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		switch (newval[0]) {
+		case 'y': case 'Y':
+			return sym_set_tristate_value(sym, yes);
+		case 'm': case 'M':
+			return sym_set_tristate_value(sym, mod);
+		case 'n': case 'N':
+			return sym_set_tristate_value(sym, no);
+		}
+		return false;
+	default:
+		;
+	}
+
+	if (!sym_string_within_range(sym, newval))
+		return false;
+
+	if (!(sym->flags & SYMBOL_DEF_USER)) {
+		sym->flags |= SYMBOL_DEF_USER;
+		sym_set_changed(sym);
+	}
+
+	oldval = sym->def[S_DEF_USER].val;
+	size = strlen(newval) + 1;
+	if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
+		size += 2;
+		sym->def[S_DEF_USER].val = val = malloc(size);
+		*val++ = '0';
+		*val++ = 'x';
+	} else if (!oldval || strcmp(oldval, newval))
+		sym->def[S_DEF_USER].val = val = malloc(size);
+	else
+		return true;
+
+	strcpy(val, newval);
+	free((void *)oldval);
+	sym_clear_all_valid();
+
+	return true;
+}
+
+const char *sym_get_string_value(struct symbol *sym)
+{
+	tristate val;
+
+	switch (sym->type) {
+	case S_BOOLEAN:
+	case S_TRISTATE:
+		val = sym_get_tristate_value(sym);
+		switch (val) {
+		case no:
+			return "n";
+		case mod:
+			return "m";
+		case yes:
+			return "y";
+		}
+		break;
+	default:
+		;
+	}
+	return (const char *)sym->curr.val;
+}
+
+bool sym_is_changable(struct symbol *sym)
+{
+	return sym->visible > sym->rev_dep.tri;
+}
+
+struct symbol *sym_lookup(const char *name, int isconst)
+{
+	struct symbol *symbol;
+	const char *ptr;
+	char *new_name;
+	int hash = 0;
+
+	if (name) {
+		if (name[0] && !name[1]) {
+			switch (name[0]) {
+			case 'y': return &symbol_yes;
+			case 'm': return &symbol_mod;
+			case 'n': return &symbol_no;
+			}
+		}
+		for (ptr = name; *ptr; ptr++)
+			hash += *ptr;
+		hash &= 0xff;
+
+		for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
+			if (!strcmp(symbol->name, name)) {
+				if ((isconst && symbol->flags & SYMBOL_CONST) ||
+				    (!isconst && !(symbol->flags & SYMBOL_CONST)))
+					return symbol;
+			}
+		}
+		new_name = strdup(name);
+	} else {
+		new_name = NULL;
+		hash = 256;
+	}
+
+	symbol = malloc(sizeof(*symbol));
+	memset(symbol, 0, sizeof(*symbol));
+	symbol->name = new_name;
+	symbol->type = S_UNKNOWN;
+	if (isconst)
+		symbol->flags |= SYMBOL_CONST;
+
+	symbol->next = symbol_hash[hash];
+	symbol_hash[hash] = symbol;
+
+	return symbol;
+}
+
+struct symbol *sym_find(const char *name)
+{
+	struct symbol *symbol = NULL;
+	const char *ptr;
+	int hash = 0;
+
+	if (!name)
+		return NULL;
+
+	if (name[0] && !name[1]) {
+		switch (name[0]) {
+		case 'y': return &symbol_yes;
+		case 'm': return &symbol_mod;
+		case 'n': return &symbol_no;
+		}
+	}
+	for (ptr = name; *ptr; ptr++)
+		hash += *ptr;
+	hash &= 0xff;
+
+	for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) {
+		if (!strcmp(symbol->name, name) &&
+		    !(symbol->flags & SYMBOL_CONST))
+				break;
+	}
+
+	return symbol;
+}
+
+#ifndef NO_REGEX
+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;
+}
+#endif
+
+
+struct symbol *sym_check_deps(struct symbol *sym);
+
+static struct symbol *sym_check_expr_deps(struct expr *e)
+{
+	struct symbol *sym;
+
+	if (!e)
+		return NULL;
+	switch (e->type) {
+	case E_OR:
+	case E_AND:
+		sym = sym_check_expr_deps(e->left.expr);
+		if (sym)
+			return sym;
+		return sym_check_expr_deps(e->right.expr);
+	case E_NOT:
+		return sym_check_expr_deps(e->left.expr);
+	case E_EQUAL:
+	case E_UNEQUAL:
+		sym = sym_check_deps(e->left.sym);
+		if (sym)
+			return sym;
+		return sym_check_deps(e->right.sym);
+	case E_SYMBOL:
+		return sym_check_deps(e->left.sym);
+	default:
+		break;
+	}
+	printf("Oops! How to check %d?\n", e->type);
+	return NULL;
+}
+
+/* return NULL when dependencies are OK */
+struct symbol *sym_check_deps(struct symbol *sym)
+{
+	struct symbol *sym2;
+	struct property *prop;
+
+	if (sym->flags & SYMBOL_CHECK) {
+		fprintf(stderr, "%s:%d:error: found recursive dependency: %s",
+		        sym->prop->file->name, sym->prop->lineno, sym->name);
+		return sym;
+	}
+	if (sym->flags & SYMBOL_CHECKED)
+		return NULL;
+
+	sym->flags |= (SYMBOL_CHECK | SYMBOL_CHECKED);
+	sym2 = sym_check_expr_deps(sym->rev_dep.expr);
+	if (sym2)
+		goto out;
+
+	for (prop = sym->prop; prop; prop = prop->next) {
+		if (prop->type == P_CHOICE || prop->type == P_SELECT)
+			continue;
+		sym2 = sym_check_expr_deps(prop->visible.expr);
+		if (sym2)
+			goto out;
+		if (prop->type != P_DEFAULT || sym_is_choice(sym))
+			continue;
+		sym2 = sym_check_expr_deps(prop->expr);
+		if (sym2)
+			goto out;
+	}
+out:
+	if (sym2)
+		fprintf(stderr, " -> %s%s", sym->name, sym2 == sym? "\n": "");
+	sym->flags &= ~SYMBOL_CHECK;
+	return sym2;
+}
+
+struct property *prop_alloc(enum prop_type type, struct symbol *sym)
+{
+	struct property *prop;
+	struct property **propp;
+
+	prop = malloc(sizeof(*prop));
+	memset(prop, 0, sizeof(*prop));
+	prop->type = type;
+	prop->sym = sym;
+	prop->file = current_file;
+	prop->lineno = zconf_lineno();
+
+	/* append property to the prop list of symbol */
+	if (sym) {
+		for (propp = &sym->prop; *propp; propp = &(*propp)->next)
+			;
+		*propp = prop;
+	}
+
+	return prop;
+}
+
+struct symbol *prop_get_symbol(struct property *prop)
+{
+	if (prop->expr && (prop->expr->type == E_SYMBOL ||
+			   prop->expr->type == E_CHOICE))
+		return prop->expr->left.sym;
+	return NULL;
+}
+
+const char *prop_get_type_name(enum prop_type type)
+{
+	switch (type) {
+	case P_PROMPT:
+		return "prompt";
+	case P_COMMENT:
+		return "comment";
+	case P_MENU:
+		return "menu";
+	case P_DEFAULT:
+		return "default";
+	case P_CHOICE:
+		return "choice";
+	case P_SELECT:
+		return "select";
+	case P_RANGE:
+		return "range";
+	case P_UNKNOWN:
+		break;
+	}
+	return "unknown";
+}
diff --git a/host/src/wrsconfig/test/h/config/auto.conf b/host/src/wrsconfig/test/h/config/auto.conf
new file mode 100644
index 0000000..fc3bca8
--- /dev/null
+++ b/host/src/wrsconfig/test/h/config/auto.conf
@@ -0,0 +1,5 @@
+#
+# Automatically generated make config: don't edit
+# Wed Feb  9 17:51:06 2011
+#
+CONFIG_CONFIG_STANDALONE=y
diff --git a/host/src/wrsconfig/test/h/config/auto.conf.cmd b/host/src/wrsconfig/test/h/config/auto.conf.cmd
new file mode 100644
index 0000000..d343c13
--- /dev/null
+++ b/host/src/wrsconfig/test/h/config/auto.conf.cmd
@@ -0,0 +1,7 @@
+deps_config := \
+	vxmicro.wrsconfig
+
+include/config/auto.conf: \
+	$(deps_config)
+
+$(deps_config): ;
diff --git a/host/src/wrsconfig/test/h/config/autoconf.h b/host/src/wrsconfig/test/h/config/autoconf.h
new file mode 100644
index 0000000..ac7b6f2
--- /dev/null
+++ b/host/src/wrsconfig/test/h/config/autoconf.h
@@ -0,0 +1,6 @@
+/*
+ * Automatically generated C config: don't edit
+ * Wed Feb  9 17:51:06 2011
+ */
+#define AUTOCONF_INCLUDED
+#define CONFIG_CONFIG_STANDALONE 1
diff --git a/host/src/wrsconfig/test/h/config/wrsconfig/config/nano/kernel.h b/host/src/wrsconfig/test/h/config/wrsconfig/config/nano/kernel.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/host/src/wrsconfig/test/h/config/wrsconfig/config/nano/kernel.h
diff --git a/host/src/wrsconfig/test/h/config/wrsconfig/config/standalone.h b/host/src/wrsconfig/test/h/config/wrsconfig/config/standalone.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/host/src/wrsconfig/test/h/config/wrsconfig/config/standalone.h
diff --git a/host/src/wrsconfig/test/vsb.config b/host/src/wrsconfig/test/vsb.config
new file mode 100644
index 0000000..a7fe855
--- /dev/null
+++ b/host/src/wrsconfig/test/vsb.config
@@ -0,0 +1,8 @@
+#
+# Automatically generated file: do not edit
+# Wed Feb  9 17:51:06 2011
+#
+# CONFIG_CONFIG_NANO_KERNEL is not set
+CONFIG_CONFIG_STANDALONE=y
+# CONFIG_CONFIG_ROUND_ROBIN is not set
+# CONFIG_CONFIG_MULTIMODE is not set
diff --git a/host/src/wrsconfig/test/vsb.config.old b/host/src/wrsconfig/test/vsb.config.old
new file mode 100644
index 0000000..e79e725
--- /dev/null
+++ b/host/src/wrsconfig/test/vsb.config.old
@@ -0,0 +1,5 @@
+#
+# Automatically generated file: do not edit
+# Wed Feb  9 17:50:13 2011
+#
+CONFIG_CONFIG_NANO_KERNEL=y
diff --git a/host/src/wrsconfig/test/vxmicro.wrsconfig b/host/src/wrsconfig/test/vxmicro.wrsconfig
new file mode 100644
index 0000000..64aa470
--- /dev/null
+++ b/host/src/wrsconfig/test/vxmicro.wrsconfig
@@ -0,0 +1,94 @@
+#

+# Copyright (c) 2013 Wind River Systems, Inc.

+#

+# Redistribution and use in source and binary forms, with or without

+# modification, are permitted provided that the following conditions are met:

+#

+# 1) Redistributions of source code must retain the above copyright notice,

+# this list of conditions and the following disclaimer.

+#

+# 2) Redistributions in binary form must reproduce the above copyright notice,

+# this list of conditions and the following disclaimer in the documentation

+# and/or other materials provided with the distribution.

+#

+# 3) Neither the name of Wind River Systems nor the names of its contributors

+# may be used to endorse or promote products derived from this software without

+# specific prior written permission.

+#

+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE

+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE

+# POSSIBILITY OF SUCH DAMAGE.

+#

+

+                                    

+#CONFIG_NANO_KERNEL                   Enable Nanokernel-only mode

+

+

+#When nanokernel-only mode is set to 'n' then I have the following additional booleans:

+

+

+# CONFIG_STANDALONE       Run without a host server (if set to 'y', this forces  CPU_LOAD, RUNTIME_CTRL and INSTRUMENTATION to be 'n')

+

+# CONFIG_CPU_LOAD         Enable CPU load monitor

+# CONFIG_RUNTIME_CTRL     Enable task runtime Control

+# CONFIG_INSTRUMENTATION  Enable system instrumentation

+# CONFIG_ROUND_ROBIN  Enable round-robin scheduling 

+# CONFIG_MULTIMODE        Choose SP or MP version of the VSP

+

+

+

+config   CONFIG_NANO_KERNEL

+    bool "Nanokernel-only mode"

+    default y

+    help

+       Place your help text here

+    

+config CONFIG_STANDALONE

+    bool "Run without a host server"

+    default n

+    depends on !CONFIG_NANO_KERNEL

+    help

+       Place your help text here

+    

+config CONFIG_CPU_LOAD

+    bool "CPU load monitor"

+    default y

+    depends on !CONFIG_NANO_KERNEL && !CONFIG_STANDALONE

+    help

+       Place your help text here

+    

+config CONFIG_RUNTIME_CTRL

+    bool  "task runtime Control"

+    default y

+    depends on !CONFIG_NANO_KERNEL && !CONFIG_STANDALONE

+    help

+       Place your help text here

+    

+config CONFIG_INSTRUMENTATION

+    bool  "system instrumentation"

+    default y

+    depends on !CONFIG_NANO_KERNEL && !CONFIG_STANDALONE

+    help

+       Place your help text here

+    

+config CONFIG_ROUND_ROBIN

+    bool  "round-robin scheduling"

+    default y

+    depends on !CONFIG_NANO_KERNEL

+    help

+       Place your help text here

+    

+config CONFIG_MULTIMODE

+    bool  "MP version of the VSP"

+    default y

+    depends on !CONFIG_NANO_KERNEL

+    help

+       Place your help text here

diff --git a/host/src/wrsconfig/util.c b/host/src/wrsconfig/util.c
new file mode 100755
index 0000000..f871c61
--- /dev/null
+++ b/host/src/wrsconfig/util.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
+ * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <string.h>
+#include "lkc.h"
+
+/* file already present in list? If not add it */
+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;
+}
+
+/* write a dependency file as used by kbuild to track dependencies */
+int file_write_dep(const char *name)
+{
+	struct file *file;
+	FILE *out;
+
+	if (!name)
+		name = ".kconfig.d";
+	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, "\ninclude/config/auto.conf: \\\n"
+		     "\t$(deps_config)\n\n"
+		     "$(deps_config): ;\n");
+	fclose(out);
+	loc_rename("..config.tmp", name);
+	return 0;
+}
+
+
+/* Allocate initial growable sting */
+struct gstr str_new(void)
+{
+	struct gstr gs;
+	gs.s = malloc(sizeof(char) * 64);
+	gs.len = 16;
+	strcpy(gs.s, "\0");
+	return gs;
+}
+
+/* Allocate and assign growable string */
+struct gstr str_assign(const char *s)
+{
+	struct gstr gs;
+	gs.s = strdup(s);
+	gs.len = strlen(s) + 1;
+	return gs;
+}
+
+/* Free storage for growable string */
+void str_free(struct gstr *gs)
+{
+	if (gs->s)
+		free(gs->s);
+	gs->s = NULL;
+	gs->len = 0;
+}
+
+/* Append to growable string */
+void str_append(struct gstr *gs, const char *s)
+{
+	size_t l = strlen(gs->s) + strlen(s) + 1;
+	if (l > gs->len) {
+		gs->s   = realloc(gs->s, l);
+		gs->len = l;
+	}
+	strcat(gs->s, s);
+}
+
+/* Append printf formatted string to growable string */
+void str_printf(struct gstr *gs, const char *fmt, ...)
+{
+	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);
+}
+
+/* Retrieve value of growable string */
+const char *str_get(struct gstr *gs)
+{
+	return gs->s;
+}
+
diff --git a/host/src/wrsconfig/vxmicro.wrsconfig b/host/src/wrsconfig/vxmicro.wrsconfig
new file mode 100644
index 0000000..64aa470
--- /dev/null
+++ b/host/src/wrsconfig/vxmicro.wrsconfig
@@ -0,0 +1,94 @@
+#

+# Copyright (c) 2013 Wind River Systems, Inc.

+#

+# Redistribution and use in source and binary forms, with or without

+# modification, are permitted provided that the following conditions are met:

+#

+# 1) Redistributions of source code must retain the above copyright notice,

+# this list of conditions and the following disclaimer.

+#

+# 2) Redistributions in binary form must reproduce the above copyright notice,

+# this list of conditions and the following disclaimer in the documentation

+# and/or other materials provided with the distribution.

+#

+# 3) Neither the name of Wind River Systems nor the names of its contributors

+# may be used to endorse or promote products derived from this software without

+# specific prior written permission.

+#

+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE

+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE

+# POSSIBILITY OF SUCH DAMAGE.

+#

+

+                                    

+#CONFIG_NANO_KERNEL                   Enable Nanokernel-only mode

+

+

+#When nanokernel-only mode is set to 'n' then I have the following additional booleans:

+

+

+# CONFIG_STANDALONE       Run without a host server (if set to 'y', this forces  CPU_LOAD, RUNTIME_CTRL and INSTRUMENTATION to be 'n')

+

+# CONFIG_CPU_LOAD         Enable CPU load monitor

+# CONFIG_RUNTIME_CTRL     Enable task runtime Control

+# CONFIG_INSTRUMENTATION  Enable system instrumentation

+# CONFIG_ROUND_ROBIN  Enable round-robin scheduling 

+# CONFIG_MULTIMODE        Choose SP or MP version of the VSP

+

+

+

+config   CONFIG_NANO_KERNEL

+    bool "Nanokernel-only mode"

+    default y

+    help

+       Place your help text here

+    

+config CONFIG_STANDALONE

+    bool "Run without a host server"

+    default n

+    depends on !CONFIG_NANO_KERNEL

+    help

+       Place your help text here

+    

+config CONFIG_CPU_LOAD

+    bool "CPU load monitor"

+    default y

+    depends on !CONFIG_NANO_KERNEL && !CONFIG_STANDALONE

+    help

+       Place your help text here

+    

+config CONFIG_RUNTIME_CTRL

+    bool  "task runtime Control"

+    default y

+    depends on !CONFIG_NANO_KERNEL && !CONFIG_STANDALONE

+    help

+       Place your help text here

+    

+config CONFIG_INSTRUMENTATION

+    bool  "system instrumentation"

+    default y

+    depends on !CONFIG_NANO_KERNEL && !CONFIG_STANDALONE

+    help

+       Place your help text here

+    

+config CONFIG_ROUND_ROBIN

+    bool  "round-robin scheduling"

+    default y

+    depends on !CONFIG_NANO_KERNEL

+    help

+       Place your help text here

+    

+config CONFIG_MULTIMODE

+    bool  "MP version of the VSP"

+    default y

+    depends on !CONFIG_NANO_KERNEL

+    help

+       Place your help text here

diff --git a/host/src/wrsconfig/zconf.hash.c b/host/src/wrsconfig/zconf.hash.c
new file mode 100755
index 0000000..41cb7e4
--- /dev/null
+++ b/host/src/wrsconfig/zconf.hash.c
@@ -0,0 +1,242 @@
+/* ANSI-C code produced by gperf version 3.0.1 */
+/* Command-line: gperf  */
+/* Computed positions: -k'1,3' */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+	  && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+	  && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+	  && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+	  && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+	  && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+	  && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+	  && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+	  && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+	  && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+	  && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+	  && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+	  && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+	  && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+	  && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+	  && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+	  && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+	  && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+	  && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+	  && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+	  && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+	  && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+	  && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646.  */
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+struct kconf_id;
+/* maximum key range = 45, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+kconf_id_hash (register const char *str, register unsigned int len)
+{
+  static unsigned char asso_values[] =
+	{
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 25, 30, 15,
+	   0, 15,  0, 47,  5, 15, 47, 47, 30, 20,
+	   5,  0, 25, 15,  0,  0, 10, 35, 47, 47,
+	   5, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+	  47, 47, 47, 47, 47, 47
+	};
+  register int hval = len;
+
+  switch (hval)
+	{
+      default:
+		hval += asso_values[(unsigned char)str[2]];
+      /*FALLTHROUGH*/
+	  case 2:
+	  case 1:
+		hval += asso_values[(unsigned char)str[0]];
+		break;
+	}
+  return hval;
+}
+
+struct kconf_id_strings_t
+  {
+	char kconf_id_strings_str2[sizeof("on")];
+	char kconf_id_strings_str6[sizeof("string")];
+	char kconf_id_strings_str7[sizeof("default")];
+	char kconf_id_strings_str8[sizeof("def_bool")];
+	char kconf_id_strings_str10[sizeof("range")];
+	char kconf_id_strings_str11[sizeof("def_boolean")];
+	char kconf_id_strings_str12[sizeof("def_tristate")];
+	char kconf_id_strings_str13[sizeof("hex")];
+	char kconf_id_strings_str14[sizeof("defconfig_list")];
+	char kconf_id_strings_str16[sizeof("option")];
+	char kconf_id_strings_str17[sizeof("if")];
+	char kconf_id_strings_str18[sizeof("optional")];
+	char kconf_id_strings_str20[sizeof("endif")];
+	char kconf_id_strings_str21[sizeof("choice")];
+	char kconf_id_strings_str22[sizeof("endmenu")];
+	char kconf_id_strings_str23[sizeof("requires")];
+	char kconf_id_strings_str24[sizeof("endchoice")];
+	char kconf_id_strings_str26[sizeof("config")];
+	char kconf_id_strings_str27[sizeof("modules")];
+	char kconf_id_strings_str28[sizeof("int")];
+	char kconf_id_strings_str29[sizeof("menu")];
+	char kconf_id_strings_str31[sizeof("prompt")];
+	char kconf_id_strings_str32[sizeof("depends")];
+	char kconf_id_strings_str33[sizeof("tristate")];
+	char kconf_id_strings_str34[sizeof("bool")];
+	char kconf_id_strings_str35[sizeof("menuconfig")];
+	char kconf_id_strings_str36[sizeof("select")];
+	char kconf_id_strings_str37[sizeof("boolean")];
+	char kconf_id_strings_str39[sizeof("help")];
+	char kconf_id_strings_str41[sizeof("source")];
+	char kconf_id_strings_str42[sizeof("comment")];
+	char kconf_id_strings_str43[sizeof("mainmenu")];
+	char kconf_id_strings_str46[sizeof("enable")];
+  };
+static struct kconf_id_strings_t kconf_id_strings_contents =
+  {
+	"on",
+	"string",
+	"default",
+	"def_bool",
+	"range",
+	"def_boolean",
+	"def_tristate",
+	"hex",
+	"defconfig_list",
+	"option",
+	"if",
+	"optional",
+	"endif",
+	"choice",
+	"endmenu",
+	"requires",
+	"endchoice",
+	"config",
+	"modules",
+	"int",
+	"menu",
+	"prompt",
+	"depends",
+	"tristate",
+	"bool",
+	"menuconfig",
+	"select",
+	"boolean",
+	"help",
+	"source",
+	"comment",
+	"mainmenu",
+	"enable"
+  };
+#define kconf_id_strings ((const char *) &kconf_id_strings_contents)
+#ifdef __GNUC__
+__inline
+#endif
+struct kconf_id *
+kconf_id_lookup (register const char *str, register unsigned int len)
+{
+  enum
+	{
+	  TOTAL_KEYWORDS = 33,
+	  MIN_WORD_LENGTH = 2,
+	  MAX_WORD_LENGTH = 14,
+	  MIN_HASH_VALUE = 2,
+	  MAX_HASH_VALUE = 46
+	};
+
+  static struct kconf_id wordlist[] =
+	{
+	  {-1}, {-1},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2,		T_ON,		TF_PARAM},
+	  {-1}, {-1}, {-1},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6,		T_TYPE,		TF_COMMAND, S_STRING},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7,	T_DEFAULT,	TF_COMMAND, S_UNKNOWN},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8,	T_DEFAULT,	TF_COMMAND, S_BOOLEAN},
+	  {-1},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10,		T_RANGE,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11,	T_DEFAULT,	TF_COMMAND, S_BOOLEAN},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12,	T_DEFAULT,	TF_COMMAND, S_TRISTATE},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13,		T_TYPE,		TF_COMMAND, S_HEX},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14,	T_OPT_DEFCONFIG_LIST,TF_OPTION},
+	  {-1},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16,		T_OPTION,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17,		T_IF,		TF_COMMAND|TF_PARAM},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18,	T_OPTIONAL,	TF_COMMAND},
+	  {-1},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20,		T_ENDIF,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21,		T_CHOICE,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22,	T_ENDMENU,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23,	T_REQUIRES,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str24,	T_ENDCHOICE,	TF_COMMAND},
+	  {-1},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26,		T_CONFIG,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27,	T_OPT_MODULES,	TF_OPTION},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28,		T_TYPE,		TF_COMMAND, S_INT},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29,		T_MENU,		TF_COMMAND},
+	  {-1},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31,		T_PROMPT,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32,	T_DEPENDS,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33,	T_TYPE,		TF_COMMAND, S_TRISTATE},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34,		T_TYPE,		TF_COMMAND, S_BOOLEAN},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35,	T_MENUCONFIG,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36,		T_SELECT,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37,	T_TYPE,		TF_COMMAND, S_BOOLEAN},
+	  {-1},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39,		T_HELP,		TF_COMMAND},
+	  {-1},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41,		T_SOURCE,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42,	T_COMMENT,	TF_COMMAND},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43,	T_MAINMENU,	TF_COMMAND},
+	  {-1}, {-1},
+	  {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46,		T_SELECT,	TF_COMMAND}
+	};
+
+  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+	{
+	  register int key = kconf_id_hash (str, len);
+
+	  if (key <= MAX_HASH_VALUE && key >= 0)
+		{
+		  register int o = wordlist[key].name;
+		  if (o >= 0)
+		    {
+		      register const char *s = o + kconf_id_strings;
+
+		      if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
+		        return &wordlist[key];
+		    }
+		}
+	}
+  return 0;
+}
+
diff --git a/host/src/wrsconfig/zconf.tab.c b/host/src/wrsconfig/zconf.tab.c
new file mode 100755
index 0000000..544ddf5
--- /dev/null
+++ b/host/src/wrsconfig/zconf.tab.c
@@ -0,0 +1,2348 @@
+/* A Bison parser, made by GNU Bison 2.1.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+   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, 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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Written by Richard Stallman by simplifying the original so called
+   ``semantic'' parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.1"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+/* Substitute the variable and function names.  */
+#define yyparse zconfparse
+#define yylex   zconflex
+#define yyerror zconferror
+#define yylval  zconflval
+#define yychar  zconfchar
+#define yydebug zconfdebug
+#define yynerrs zconfnerrs
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+	 T_MAINMENU = 258,
+	 T_MENU = 259,
+	 T_ENDMENU = 260,
+	 T_SOURCE = 261,
+	 T_CHOICE = 262,
+	 T_ENDCHOICE = 263,
+	 T_COMMENT = 264,
+	 T_CONFIG = 265,
+	 T_MENUCONFIG = 266,
+	 T_HELP = 267,
+	 T_HELPTEXT = 268,
+	 T_IF = 269,
+	 T_ENDIF = 270,
+	 T_DEPENDS = 271,
+	 T_REQUIRES = 272,
+	 T_OPTIONAL = 273,
+	 T_PROMPT = 274,
+	 T_TYPE = 275,
+	 T_DEFAULT = 276,
+	 T_SELECT = 277,
+	 T_RANGE = 278,
+	 T_OPTION = 279,
+	 T_ON = 280,
+	 T_WORD = 281,
+	 T_WORD_QUOTE = 282,
+	 T_UNEQUAL = 283,
+	 T_CLOSE_PAREN = 284,
+	 T_OPEN_PAREN = 285,
+	 T_EOL = 286,
+	 T_OR = 287,
+	 T_AND = 288,
+	 T_EQUAL = 289,
+	 T_NOT = 290
+   };
+#endif
+/* Tokens.  */
+#define T_MAINMENU 258
+#define T_MENU 259
+#define T_ENDMENU 260
+#define T_SOURCE 261
+#define T_CHOICE 262
+#define T_ENDCHOICE 263
+#define T_COMMENT 264
+#define T_CONFIG 265
+#define T_MENUCONFIG 266
+#define T_HELP 267
+#define T_HELPTEXT 268
+#define T_IF 269
+#define T_ENDIF 270
+#define T_DEPENDS 271
+#define T_REQUIRES 272
+#define T_OPTIONAL 273
+#define T_PROMPT 274
+#define T_TYPE 275
+#define T_DEFAULT 276
+#define T_SELECT 277
+#define T_RANGE 278
+#define T_OPTION 279
+#define T_ON 280
+#define T_WORD 281
+#define T_WORD_QUOTE 282
+#define T_UNEQUAL 283
+#define T_CLOSE_PAREN 284
+#define T_OPEN_PAREN 285
+#define T_EOL 286
+#define T_OR 287
+#define T_AND 288
+#define T_EQUAL 289
+#define T_NOT 290
+
+
+
+
+/* Copy the first part of user declarations.  */
+
+
+/*
+ * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Released under the terms of the GNU GPL v2.0.
+ */
+
+#include <sys/stat.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#define LKC_DIRECT_LINK
+#include "lkc.h"
+
+#include "zconf.hash.c"
+
+#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
+
+#define PRINTD		0x0001
+#define DEBUG_PARSE	0x0002
+
+int cdebug = PRINTD;
+
+extern int zconflex(void);
+static void zconfprint(const char *err, ...);
+static void zconf_error(const char *err, ...);
+static void zconferror(const char *err);
+static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
+
+struct symbol *symbol_hash[257];
+
+static struct menu *current_menu, *current_entry;
+
+#define YYDEBUG 0
+#if YYDEBUG
+#define YYERROR_VERBOSE
+#endif
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+
+typedef union YYSTYPE {
+	char *string;
+	struct file *file;
+	struct symbol *symbol;
+	struct expr *expr;
+	struct menu *menu;
+	struct kconf_id *id;
+} YYSTYPE;
+/* Line 196 of yacc.c.  */
+
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 219 of yacc.c.  */
+
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#ifndef YY_
+# if YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if defined (__STDC__) || defined (__cplusplus)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     define YYINCLUDED_STDLIB_H
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
+#  endif
+#  ifdef __cplusplus
+extern "C" {
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
+	&& (defined (__STDC__) || defined (__cplusplus)))
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
+	&& (defined (__STDC__) || defined (__cplusplus)))
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifdef __cplusplus
+}
+#  endif
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+	 && (! defined (__cplusplus) \
+	 || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short int yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+	 ((N) * (sizeof (short int) + sizeof (YYSTYPE))			\
+	  + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined (__GNUC__) && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+	  __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+	  do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+	  while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+	do									\
+	  {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+	  }									\
+	while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+   typedef signed char yysigned_char;
+#else
+   typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL  3
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   275
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS  36
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS  45
+/* YYNRULES -- Number of rules. */
+#define YYNRULES  110
+/* YYNRULES -- Number of states. */
+#define YYNSTATES  183
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   290
+
+#define YYTRANSLATE(YYX)						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const unsigned char yytranslate[] =
+{
+	   0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+	   2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+	   5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+	  15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+	  25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+	  35
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const unsigned short int yyprhs[] =
+{
+	   0,     0,     3,     5,     6,     9,    12,    15,    20,    23,
+	  28,    33,    37,    39,    41,    43,    45,    47,    49,    51,
+	  53,    55,    57,    59,    61,    63,    67,    70,    74,    77,
+	  81,    84,    85,    88,    91,    94,    97,   100,   103,   107,
+	 112,   117,   122,   128,   132,   133,   137,   138,   141,   144,
+	 147,   149,   153,   154,   157,   160,   163,   166,   169,   174,
+	 178,   181,   186,   187,   190,   194,   196,   200,   201,   204,
+	 207,   210,   214,   217,   219,   223,   224,   227,   230,   233,
+	 237,   241,   244,   247,   250,   251,   254,   257,   260,   265,
+	 269,   273,   274,   277,   279,   281,   284,   287,   290,   292,
+	 295,   296,   299,   301,   305,   309,   313,   316,   320,   324,
+	 326
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+	  37,     0,    -1,    38,    -1,    -1,    38,    40,    -1,    38,
+	  54,    -1,    38,    65,    -1,    38,     3,    75,    77,    -1,
+	  38,    76,    -1,    38,    26,     1,    31,    -1,    38,    39,
+	   1,    31,    -1,    38,     1,    31,    -1,    16,    -1,    19,
+	  -1,    20,    -1,    22,    -1,    18,    -1,    23,    -1,    21,
+	  -1,    31,    -1,    60,    -1,    69,    -1,    43,    -1,    45,
+	  -1,    67,    -1,    26,     1,    31,    -1,     1,    31,    -1,
+	  10,    26,    31,    -1,    42,    46,    -1,    11,    26,    31,
+	  -1,    44,    46,    -1,    -1,    46,    47,    -1,    46,    48,
+	  -1,    46,    73,    -1,    46,    71,    -1,    46,    41,    -1,
+	  46,    31,    -1,    20,    74,    31,    -1,    19,    75,    78,
+	  31,    -1,    21,    79,    78,    31,    -1,    22,    26,    78,
+	  31,    -1,    23,    80,    80,    78,    31,    -1,    24,    49,
+	  31,    -1,    -1,    49,    26,    50,    -1,    -1,    34,    75,
+	  -1,     7,    31,    -1,    51,    55,    -1,    76,    -1,    52,
+	  57,    53,    -1,    -1,    55,    56,    -1,    55,    73,    -1,
+	  55,    71,    -1,    55,    31,    -1,    55,    41,    -1,    19,
+	  75,    78,    31,    -1,    20,    74,    31,    -1,    18,    31,
+	  -1,    21,    26,    78,    31,    -1,    -1,    57,    40,    -1,
+	  14,    79,    77,    -1,    76,    -1,    58,    61,    59,    -1,
+	  -1,    61,    40,    -1,    61,    65,    -1,    61,    54,    -1,
+	   4,    75,    31,    -1,    62,    72,    -1,    76,    -1,    63,
+	  66,    64,    -1,    -1,    66,    40,    -1,    66,    65,    -1,
+	  66,    54,    -1,     6,    75,    31,    -1,     9,    75,    31,
+	  -1,    68,    72,    -1,    12,    31,    -1,    70,    13,    -1,
+	  -1,    72,    73,    -1,    72,    31,    -1,    72,    41,    -1,
+	  16,    25,    79,    31,    -1,    16,    79,    31,    -1,    17,
+	  79,    31,    -1,    -1,    75,    78,    -1,    26,    -1,    27,
+	  -1,     5,    31,    -1,     8,    31,    -1,    15,    31,    -1,
+	  31,    -1,    77,    31,    -1,    -1,    14,    79,    -1,    80,
+	  -1,    80,    34,    80,    -1,    80,    28,    80,    -1,    30,
+	  79,    29,    -1,    35,    79,    -1,    79,    32,    79,    -1,
+	  79,    33,    79,    -1,    26,    -1,    27,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const unsigned short int yyrline[] =
+{
+	   0,   105,   105,   107,   109,   110,   111,   112,   113,   114,
+	 115,   119,   123,   123,   123,   123,   123,   123,   123,   127,
+	 128,   129,   130,   131,   132,   136,   137,   143,   151,   157,
+	 165,   175,   177,   178,   179,   180,   181,   182,   185,   193,
+	 199,   209,   215,   221,   224,   226,   237,   238,   243,   252,
+	 257,   265,   268,   270,   271,   272,   273,   274,   277,   283,
+	 294,   300,   310,   312,   317,   325,   333,   336,   338,   339,
+	 340,   345,   352,   357,   365,   368,   370,   371,   372,   375,
+	 383,   390,   397,   403,   410,   412,   413,   414,   417,   422,
+	 427,   435,   437,   442,   443,   446,   447,   448,   452,   453,
+	 456,   457,   460,   461,   462,   463,   464,   465,   466,   469,
+	 470
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "T_MAINMENU", "T_MENU", "T_ENDMENU",
+  "T_SOURCE", "T_CHOICE", "T_ENDCHOICE", "T_COMMENT", "T_CONFIG",
+  "T_MENUCONFIG", "T_HELP", "T_HELPTEXT", "T_IF", "T_ENDIF", "T_DEPENDS",
+  "T_REQUIRES", "T_OPTIONAL", "T_PROMPT", "T_TYPE", "T_DEFAULT",
+  "T_SELECT", "T_RANGE", "T_OPTION", "T_ON", "T_WORD", "T_WORD_QUOTE",
+  "T_UNEQUAL", "T_CLOSE_PAREN", "T_OPEN_PAREN", "T_EOL", "T_OR", "T_AND",
+  "T_EQUAL", "T_NOT", "$accept", "input", "stmt_list", "option_name",
+  "common_stmt", "option_error", "config_entry_start", "config_stmt",
+  "menuconfig_entry_start", "menuconfig_stmt", "config_option_list",
+  "config_option", "symbol_option", "symbol_option_list",
+  "symbol_option_arg", "choice", "choice_entry", "choice_end",
+  "choice_stmt", "choice_option_list", "choice_option", "choice_block",
+  "if_entry", "if_end", "if_stmt", "if_block", "menu", "menu_entry",
+  "menu_end", "menu_stmt", "menu_block", "source_stmt", "comment",
+  "comment_stmt", "help_start", "help", "depends_list", "depends",
+  "prompt_stmt_opt", "prompt", "end", "nl", "if_expr", "expr", "symbol", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const unsigned short int yytoknum[] =
+{
+	   0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+	 265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+	 275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+	 285,   286,   287,   288,   289,   290
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const unsigned char yyr1[] =
+{
+	   0,    36,    37,    38,    38,    38,    38,    38,    38,    38,
+	  38,    38,    39,    39,    39,    39,    39,    39,    39,    40,
+	  40,    40,    40,    40,    40,    41,    41,    42,    43,    44,
+	  45,    46,    46,    46,    46,    46,    46,    46,    47,    47,
+	  47,    47,    47,    48,    49,    49,    50,    50,    51,    52,
+	  53,    54,    55,    55,    55,    55,    55,    55,    56,    56,
+	  56,    56,    57,    57,    58,    59,    60,    61,    61,    61,
+	  61,    62,    63,    64,    65,    66,    66,    66,    66,    67,
+	  68,    69,    70,    71,    72,    72,    72,    72,    73,    73,
+	  73,    74,    74,    75,    75,    76,    76,    76,    77,    77,
+	  78,    78,    79,    79,    79,    79,    79,    79,    79,    80,
+	  80
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const unsigned char yyr2[] =
+{
+	   0,     2,     1,     0,     2,     2,     2,     4,     2,     4,
+	   4,     3,     1,     1,     1,     1,     1,     1,     1,     1,
+	   1,     1,     1,     1,     1,     3,     2,     3,     2,     3,
+	   2,     0,     2,     2,     2,     2,     2,     2,     3,     4,
+	   4,     4,     5,     3,     0,     3,     0,     2,     2,     2,
+	   1,     3,     0,     2,     2,     2,     2,     2,     4,     3,
+	   2,     4,     0,     2,     3,     1,     3,     0,     2,     2,
+	   2,     3,     2,     1,     3,     0,     2,     2,     2,     3,
+	   3,     2,     2,     2,     0,     2,     2,     2,     4,     3,
+	   3,     0,     2,     1,     1,     2,     2,     2,     1,     2,
+	   0,     2,     1,     3,     3,     3,     2,     3,     3,     1,
+	   1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const unsigned char yydefact[] =
+{
+	   3,     0,     0,     1,     0,     0,     0,     0,     0,     0,
+	   0,     0,     0,     0,     0,     0,    12,    16,    13,    14,
+	  18,    15,    17,     0,    19,     0,     4,    31,    22,    31,
+	  23,    52,    62,     5,    67,    20,    84,    75,     6,    24,
+	  84,    21,     8,    11,    93,    94,     0,     0,    95,     0,
+	  48,    96,     0,     0,     0,   109,   110,     0,     0,     0,
+	 102,    97,     0,     0,     0,     0,     0,     0,     0,     0,
+	   0,     0,    98,     7,    71,    79,    80,    27,    29,     0,
+	 106,     0,     0,    64,     0,     0,     9,    10,     0,     0,
+	   0,     0,     0,    91,     0,     0,     0,    44,     0,    37,
+	  36,    32,    33,     0,    35,    34,     0,     0,    91,     0,
+	  56,    57,    53,    55,    54,    63,    51,    50,    68,    70,
+	  66,    69,    65,    86,    87,    85,    76,    78,    74,    77,
+	  73,    99,   105,   107,   108,   104,   103,    26,    82,     0,
+	   0,     0,   100,     0,   100,   100,   100,     0,     0,     0,
+	  83,    60,   100,     0,   100,     0,    89,    90,     0,     0,
+	  38,    92,     0,     0,   100,    46,    43,    25,     0,    59,
+	   0,    88,   101,    39,    40,    41,     0,     0,    45,    58,
+	  61,    42,    47
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short int yydefgoto[] =
+{
+	  -1,     1,     2,    25,    26,   100,    27,    28,    29,    30,
+	  64,   101,   102,   148,   178,    31,    32,   116,    33,    66,
+	 112,    67,    34,   120,    35,    68,    36,    37,   128,    38,
+	  70,    39,    40,    41,   103,   104,    69,   105,   143,   144,
+	  42,    73,   159,    59,    60
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -135
+static const short int yypact[] =
+{
+	-135,     2,   170,  -135,   -14,    56,    56,    -8,    56,    24,
+	  67,    56,     7,    14,    62,    97,  -135,  -135,  -135,  -135,
+	-135,  -135,  -135,   156,  -135,   166,  -135,  -135,  -135,  -135,
+	-135,  -135,  -135,  -135,  -135,  -135,  -135,  -135,  -135,  -135,
+	-135,  -135,  -135,  -135,  -135,  -135,   138,   151,  -135,   152,
+	-135,  -135,   163,   167,   176,  -135,  -135,    62,    62,   185,
+	 -19,  -135,   188,   190,    42,   103,   194,    85,    70,   222,
+	  70,   132,  -135,   191,  -135,  -135,  -135,  -135,  -135,   127,
+	-135,    62,    62,   191,   104,   104,  -135,  -135,   193,   203,
+	   9,    62,    56,    56,    62,   161,   104,  -135,   196,  -135,
+	-135,  -135,  -135,   233,  -135,  -135,   204,    56,    56,   221,
+	-135,  -135,  -135,  -135,  -135,  -135,  -135,  -135,  -135,  -135,
+	-135,  -135,  -135,  -135,  -135,  -135,  -135,  -135,  -135,  -135,
+	-135,  -135,  -135,   219,  -135,  -135,  -135,  -135,  -135,    62,
+	 209,   212,   240,   224,   240,    -1,   240,   104,    41,   225,
+	-135,  -135,   240,   226,   240,   218,  -135,  -135,    62,   227,
+	-135,  -135,   228,   229,   240,   230,  -135,  -135,   231,  -135,
+	 232,  -135,   112,  -135,  -135,  -135,   234,    56,  -135,  -135,
+	-135,  -135,  -135
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const short int yypgoto[] =
+{
+	-135,  -135,  -135,  -135,    94,   -45,  -135,  -135,  -135,  -135,
+	 237,  -135,  -135,  -135,  -135,  -135,  -135,  -135,   -54,  -135,
+	-135,  -135,  -135,  -135,  -135,  -135,  -135,  -135,  -135,     1,
+	-135,  -135,  -135,  -135,  -135,   195,   235,   -44,   159,    -5,
+	  98,   210,  -134,   -53,   -77
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -82
+static const short int yytable[] =
+{
+	  46,    47,     3,    49,    79,    80,    52,   135,   136,    84,
+	 161,   162,   163,   158,   119,    85,   127,    43,   168,   147,
+	 170,   111,   114,    48,   124,   125,   124,   125,   133,   134,
+	 176,    81,    82,    53,   139,    55,    56,   140,   141,    57,
+	  54,   145,   -28,    88,    58,   -28,   -28,   -28,   -28,   -28,
+	 -28,   -28,   -28,   -28,    89,    50,   -28,   -28,    90,    91,
+	 -28,    92,    93,    94,    95,    96,    97,   165,    98,   121,
+	 164,   129,   166,    99,     6,     7,     8,     9,    10,    11,
+	  12,    13,    44,    45,    14,    15,   155,   142,    55,    56,
+	   7,     8,    57,    10,    11,    12,    13,    58,    51,    14,
+	  15,    24,   152,   -30,    88,   172,   -30,   -30,   -30,   -30,
+	 -30,   -30,   -30,   -30,   -30,    89,    24,   -30,   -30,    90,
+	  91,   -30,    92,    93,    94,    95,    96,    97,    61,    98,
+	  55,    56,   -81,    88,    99,   -81,   -81,   -81,   -81,   -81,
+	 -81,   -81,   -81,   -81,    81,    82,   -81,   -81,    90,    91,
+	 -81,   -81,   -81,   -81,   -81,   -81,   132,    62,    98,    81,
+	  82,   115,   118,   123,   126,   117,   122,    63,   130,    72,
+	  -2,     4,   182,     5,     6,     7,     8,     9,    10,    11,
+	  12,    13,    74,    75,    14,    15,    16,   146,    17,    18,
+	  19,    20,    21,    22,    76,    88,    23,   149,    77,   -49,
+	 -49,    24,   -49,   -49,   -49,   -49,    89,    78,   -49,   -49,
+	  90,    91,   106,   107,   108,   109,    72,    81,    82,    86,
+	  98,    87,   131,    88,   137,   110,   -72,   -72,   -72,   -72,
+	 -72,   -72,   -72,   -72,   138,   151,   -72,   -72,    90,    91,
+	 156,    81,    82,   157,    81,    82,   150,   154,    98,   171,
+	  81,    82,    82,   123,   158,   160,   167,   169,   173,   174,
+	 175,   113,   179,   180,   177,   181,    65,   153,     0,    83,
+	   0,     0,     0,     0,     0,    71
+};
+
+static const short int yycheck[] =
+{
+	   5,     6,     0,     8,    57,    58,    11,    84,    85,    28,
+	 144,   145,   146,    14,    68,    34,    70,    31,   152,    96,
+	 154,    66,    66,    31,    69,    69,    71,    71,    81,    82,
+	 164,    32,    33,    26,    25,    26,    27,    90,    91,    30,
+	  26,    94,     0,     1,    35,     3,     4,     5,     6,     7,
+	   8,     9,    10,    11,    12,    31,    14,    15,    16,    17,
+	  18,    19,    20,    21,    22,    23,    24,    26,    26,    68,
+	 147,    70,    31,    31,     4,     5,     6,     7,     8,     9,
+	  10,    11,    26,    27,    14,    15,   139,    92,    26,    27,
+	   5,     6,    30,     8,     9,    10,    11,    35,    31,    14,
+	  15,    31,   107,     0,     1,   158,     3,     4,     5,     6,
+	   7,     8,     9,    10,    11,    12,    31,    14,    15,    16,
+	  17,    18,    19,    20,    21,    22,    23,    24,    31,    26,
+	  26,    27,     0,     1,    31,     3,     4,     5,     6,     7,
+	   8,     9,    10,    11,    32,    33,    14,    15,    16,    17,
+	  18,    19,    20,    21,    22,    23,    29,     1,    26,    32,
+	  33,    67,    68,    31,    70,    67,    68,     1,    70,    31,
+	   0,     1,   177,     3,     4,     5,     6,     7,     8,     9,
+	  10,    11,    31,    31,    14,    15,    16,    26,    18,    19,
+	  20,    21,    22,    23,    31,     1,    26,     1,    31,     5,
+	   6,    31,     8,     9,    10,    11,    12,    31,    14,    15,
+	  16,    17,    18,    19,    20,    21,    31,    32,    33,    31,
+	  26,    31,    31,     1,    31,    31,     4,     5,     6,     7,
+	   8,     9,    10,    11,    31,    31,    14,    15,    16,    17,
+	  31,    32,    33,    31,    32,    33,    13,    26,    26,    31,
+	  32,    33,    33,    31,    14,    31,    31,    31,    31,    31,
+	  31,    66,    31,    31,    34,    31,    29,   108,    -1,    59,
+	  -1,    -1,    -1,    -1,    -1,    40
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const unsigned char yystos[] =
+{
+	   0,    37,    38,     0,     1,     3,     4,     5,     6,     7,
+	   8,     9,    10,    11,    14,    15,    16,    18,    19,    20,
+	  21,    22,    23,    26,    31,    39,    40,    42,    43,    44,
+	  45,    51,    52,    54,    58,    60,    62,    63,    65,    67,
+	  68,    69,    76,    31,    26,    27,    75,    75,    31,    75,
+	  31,    31,    75,    26,    26,    26,    27,    30,    35,    79,
+	  80,    31,     1,     1,    46,    46,    55,    57,    61,    72,
+	  66,    72,    31,    77,    31,    31,    31,    31,    31,    79,
+	  79,    32,    33,    77,    28,    34,    31,    31,     1,    12,
+	  16,    17,    19,    20,    21,    22,    23,    24,    26,    31,
+	  41,    47,    48,    70,    71,    73,    18,    19,    20,    21,
+	  31,    41,    56,    71,    73,    40,    53,    76,    40,    54,
+	  59,    65,    76,    31,    41,    73,    40,    54,    64,    65,
+	  76,    31,    29,    79,    79,    80,    80,    31,    31,    25,
+	  79,    79,    75,    74,    75,    79,    26,    80,    49,     1,
+	  13,    31,    75,    74,    26,    79,    31,    31,    14,    78,
+	  31,    78,    78,    78,    80,    26,    31,    31,    78,    31,
+	  78,    31,    79,    31,    31,    31,    78,    34,    50,    31,
+	  31,    31,    75
+};
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+	{								\
+	  yychar = (Token);						\
+	  yylval = (Value);						\
+	  yytoken = YYTRANSLATE (yychar);				\
+	  YYPOPSTACK;						\
+	  goto yybackup;						\
+	}								\
+  else								\
+	{								\
+	  yyerror (YY_("syntax error: cannot back up")); \
+	  YYERROR;							\
+	}								\
+while (0)
+
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+	do									\
+	  if (N)								\
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+	  else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+	while (0)
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+	 fprintf (File, "%d.%d-%d.%d",			\
+		      (Loc).first_line, (Loc).first_column,	\
+		      (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+	YYFPRINTF Args;				\
+} while (0)
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)		\
+do {								\
+  if (yydebug)							\
+	{								\
+	  YYFPRINTF (stderr, "%s ", Title);				\
+	  yysymprint (stderr,					\
+		          Type, Value);	\
+	  YYFPRINTF (stderr, "\n");					\
+	}								\
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+	short int *bottom;
+	short int *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (/* Nothing. */; bottom <= top; ++bottom)
+	YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+	yy_stack_print ((Bottom), (Top));				\
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+	int yyrule;
+#endif
+{
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ",
+		     yyrule - 1, yylno);
+  /* Print the symbols being reduced, and their result.  */
+  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+	YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+  YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+	yy_reduce_print (Rule);		\
+} while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+	 const char *yystr;
+#   endif
+{
+  const char *yys = yystr;
+
+  while (*yys++ != '\0')
+	continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+	 char *yydest;
+	 const char *yysrc;
+#   endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+	continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+	{
+	  size_t yyn = 0;
+	  char const *yyp = yystr;
+
+	  for (;;)
+	switch (*++yyp)
+	  {
+	  case '\'':
+	  case ',':
+	    goto do_not_strip_quotes;
+
+	  case '\\':
+	    if (*++yyp != '\\')
+	      goto do_not_strip_quotes;
+	    /* Fall through.  */
+	  default:
+	    if (yyres)
+	      yyres[yyn] = *yyp;
+	    yyn++;
+	    break;
+
+	  case '"':
+	    if (yyres)
+	      yyres[yyn] = '\0';
+	    return yyn;
+	  }
+do_not_strip_quotes: ;
+	}
+
+  if (! yyres)
+	return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+#endif /* YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+	FILE *yyoutput;
+	int yytype;
+	YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  if (yytype < YYNTOKENS)
+	YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+	YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+	YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+  switch (yytype)
+	{
+      default:
+		break;
+	}
+  YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+	const char *yymsg;
+	int yytype;
+	YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  if (!yymsg)
+	yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+	{
+	  case 52: /* "choice_entry" */
+
+		{
+	fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+		(yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
+	if (current_menu == (yyvaluep->menu))
+		menu_end_menu();
+};
+
+		break;
+	  case 58: /* "if_entry" */
+
+		{
+	fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+		(yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
+	if (current_menu == (yyvaluep->menu))
+		menu_end_menu();
+};
+
+		break;
+	  case 63: /* "menu_entry" */
+
+		{
+	fprintf(stderr, "%s:%d: missing end statement for this entry\n",
+		(yyvaluep->menu)->file->name, (yyvaluep->menu)->lineno);
+	if (current_menu == (yyvaluep->menu))
+		menu_end_menu();
+};
+
+		break;
+
+      default:
+		break;
+	}
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+  void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+	;
+#endif
+#endif
+{
+
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  short int yyssa[YYINITDEPTH];
+  short int *yyss = yyssa;
+  short int *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule.  */
+  int yylen;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+	{
+      /* Get the current used size of the three stacks, in elements.  */
+	  YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+	  {
+	/* Give user a chance to reallocate the stack. Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	short int *yyss1 = yyss;
+
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow (YY_("memory exhausted"),
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+
+		    &yystacksize);
+
+	yyss = yyss1;
+	yyvs = yyvs1;
+	  }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+	  goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+	  if (YYMAXDEPTH <= yystacksize)
+	goto yyexhaustedlab;
+	  yystacksize *= 2;
+	  if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+	  {
+	short int *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyexhaustedlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+	  }
+# endif
+#endif /* no yyoverflow */
+
+	  yyssp = yyss + yysize - 1;
+	  yyvsp = yyvs + yysize - 1;
+
+
+	  YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+	  if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+	}
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a look-ahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+	goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+	{
+	  YYDPRINTF ((stderr, "Reading a token: "));
+	  yychar = YYLEX;
+	}
+
+  if (yychar <= YYEOF)
+	{
+	  yychar = yytoken = YYEOF;
+	  YYDPRINTF ((stderr, "Now at end of input.\n"));
+	}
+  else
+	{
+	  yytoken = YYTRANSLATE (yychar);
+	  YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+	}
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+	goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+	{
+	  if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+	  yyn = -yyn;
+	  goto yyreduce;
+	}
+
+  if (yyn == YYFINAL)
+	YYACCEPT;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+	yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+	yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+	goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+	{
+		case 8:
+
+	{ zconf_error("unexpected end statement"); ;}
+	break;
+
+  case 9:
+
+	{ zconf_error("unknown statement \"%s\"", (yyvsp[-2].string)); ;}
+	break;
+
+  case 10:
+
+	{
+	zconf_error("unexpected option \"%s\"", kconf_id_strings + (yyvsp[-2].id)->name);
+;}
+	break;
+
+  case 11:
+
+	{ zconf_error("invalid statement"); ;}
+	break;
+
+  case 25:
+
+	{ zconf_error("unknown option \"%s\"", (yyvsp[-2].string)); ;}
+	break;
+
+  case 26:
+
+	{ zconf_error("invalid option"); ;}
+	break;
+
+  case 27:
+
+	{
+	struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
+	sym->flags |= SYMBOL_OPTIONAL;
+	menu_add_entry(sym);
+	printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
+;}
+	break;
+
+  case 28:
+
+	{
+	menu_end_entry();
+	printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
+;}
+	break;
+
+  case 29:
+
+	{
+	struct symbol *sym = sym_lookup((yyvsp[-1].string), 0);
+	sym->flags |= SYMBOL_OPTIONAL;
+	menu_add_entry(sym);
+	printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
+;}
+	break;
+
+  case 30:
+
+	{
+	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());
+;}
+	break;
+
+  case 38:
+
+	{
+	menu_set_type((yyvsp[-2].id)->stype);
+	printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
+		zconf_curname(), zconf_lineno(),
+		(yyvsp[-2].id)->stype);
+;}
+	break;
+
+  case 39:
+
+	{
+	menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+;}
+	break;
+
+  case 40:
+
+	{
+	menu_add_expr(P_DEFAULT, (yyvsp[-2].expr), (yyvsp[-1].expr));
+	if ((yyvsp[-3].id)->stype != S_UNKNOWN)
+		menu_set_type((yyvsp[-3].id)->stype);
+	printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
+		zconf_curname(), zconf_lineno(),
+		(yyvsp[-3].id)->stype);
+;}
+	break;
+
+  case 41:
+
+	{
+	menu_add_symbol(P_SELECT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
+;}
+	break;
+
+  case 42:
+
+	{
+	menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,(yyvsp[-3].symbol), (yyvsp[-2].symbol)), (yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
+;}
+	break;
+
+  case 45:
+
+	{
+	struct kconf_id *id = kconf_id_lookup((yyvsp[-1].string), strlen((yyvsp[-1].string)));
+	if (id && id->flags & TF_OPTION)
+		menu_add_option(id->token, (yyvsp[0].string));
+	else
+		zconfprint("warning: ignoring unknown option %s", (yyvsp[-1].string));
+	free((yyvsp[-1].string));
+;}
+	break;
+
+  case 46:
+
+	{ (yyval.string) = NULL; ;}
+	break;
+
+  case 47:
+
+	{ (yyval.string) = (yyvsp[0].string); ;}
+	break;
+
+  case 48:
+
+	{
+	struct symbol *sym = sym_lookup(NULL, 0);
+	sym->flags |= SYMBOL_CHOICE;
+	menu_add_entry(sym);
+	menu_add_expr(P_CHOICE, NULL, NULL);
+	printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
+;}
+	break;
+
+  case 49:
+
+	{
+	(yyval.menu) = menu_add_menu();
+;}
+	break;
+
+  case 50:
+
+	{
+	if (zconf_endtoken((yyvsp[0].id), T_CHOICE, T_ENDCHOICE)) {
+		menu_end_menu();
+		printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
+	}
+;}
+	break;
+
+  case 58:
+
+	{
+	menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
+;}
+	break;
+
+  case 59:
+
+	{
+	if ((yyvsp[-2].id)->stype == S_BOOLEAN || (yyvsp[-2].id)->stype == S_TRISTATE) {
+		menu_set_type((yyvsp[-2].id)->stype);
+		printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
+			zconf_curname(), zconf_lineno(),
+			(yyvsp[-2].id)->stype);
+	} else
+		YYERROR;
+;}
+	break;
+
+  case 60:
+
+	{
+	current_entry->sym->flags |= SYMBOL_OPTIONAL;
+	printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
+;}
+	break;
+
+  case 61:
+
+	{
+	if ((yyvsp[-3].id)->stype == S_UNKNOWN) {
+		menu_add_symbol(P_DEFAULT, sym_lookup((yyvsp[-2].string), 0), (yyvsp[-1].expr));
+		printd(DEBUG_PARSE, "%s:%d:default\n",
+			zconf_curname(), zconf_lineno());
+	} else
+		YYERROR;
+;}
+	break;
+
+  case 64:
+
+	{
+	printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
+	menu_add_entry(NULL);
+	menu_add_dep((yyvsp[-1].expr));
+	(yyval.menu) = menu_add_menu();
+;}
+	break;
+
+  case 65:
+
+	{
+	if (zconf_endtoken((yyvsp[0].id), T_IF, T_ENDIF)) {
+		menu_end_menu();
+		printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
+	}
+;}
+	break;
+
+  case 71:
+
+	{
+	menu_add_entry(NULL);
+	menu_add_prompt(P_MENU, (yyvsp[-1].string), NULL);
+	printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
+;}
+	break;
+
+  case 72:
+
+	{
+	(yyval.menu) = menu_add_menu();
+;}
+	break;
+
+  case 73:
+
+	{
+	if (zconf_endtoken((yyvsp[0].id), T_MENU, T_ENDMENU)) {
+		menu_end_menu();
+		printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
+	}
+;}
+	break;
+
+  case 79:
+
+	{
+	printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string));
+	zconf_nextfile((yyvsp[-1].string));
+;}
+	break;
+
+  case 80:
+
+	{
+	menu_add_entry(NULL);
+	menu_add_prompt(P_COMMENT, (yyvsp[-1].string), NULL);
+	printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
+;}
+	break;
+
+  case 81:
+
+	{
+	menu_end_entry();
+;}
+	break;
+
+  case 82:
+
+	{
+	printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
+	zconf_starthelp();
+;}
+	break;
+
+  case 83:
+
+	{
+	current_entry->help = (yyvsp[0].string);
+;}
+	break;
+
+  case 88:
+
+	{
+	menu_add_dep((yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
+;}
+	break;
+
+  case 89:
+
+	{
+	menu_add_dep((yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno());
+;}
+	break;
+
+  case 90:
+
+	{
+	menu_add_dep((yyvsp[-1].expr));
+	printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno());
+;}
+	break;
+
+  case 92:
+
+	{
+	menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr));
+;}
+	break;
+
+  case 95:
+
+	{ (yyval.id) = (yyvsp[-1].id); ;}
+	break;
+
+  case 96:
+
+	{ (yyval.id) = (yyvsp[-1].id); ;}
+	break;
+
+  case 97:
+
+	{ (yyval.id) = (yyvsp[-1].id); ;}
+	break;
+
+  case 100:
+
+	{ (yyval.expr) = NULL; ;}
+	break;
+
+  case 101:
+
+	{ (yyval.expr) = (yyvsp[0].expr); ;}
+	break;
+
+  case 102:
+
+	{ (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); ;}
+	break;
+
+  case 103:
+
+	{ (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
+	break;
+
+  case 104:
+
+	{ (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;}
+	break;
+
+  case 105:
+
+	{ (yyval.expr) = (yyvsp[-1].expr); ;}
+	break;
+
+  case 106:
+
+	{ (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); ;}
+	break;
+
+  case 107:
+
+	{ (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+	break;
+
+  case 108:
+
+	{ (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+	break;
+
+  case 109:
+
+	{ (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); ;}
+	break;
+
+  case 110:
+
+	{ (yyval.symbol) = sym_lookup((yyvsp[0].string), 1); free((yyvsp[0].string)); ;}
+	break;
+
+
+      default: break;
+	}
+
+/* Line 1126 of yacc.c.  */
+
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+
+
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+	yystate = yytable[yystate];
+  else
+	yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+	{
+	  ++yynerrs;
+#if YYERROR_VERBOSE
+	  yyn = yypact[yystate];
+
+	  if (YYPACT_NINF < yyn && yyn < YYLAST)
+	{
+	  int yytype = YYTRANSLATE (yychar);
+	  YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+	  YYSIZE_T yysize = yysize0;
+	  YYSIZE_T yysize1;
+	  int yysize_overflow = 0;
+	  char *yymsg = 0;
+#	  define YYERROR_VERBOSE_ARGS_MAXIMUM 5
+	  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+	  int yyx;
+
+#if 0
+	  /* This is so xgettext sees the translatable formats that are
+	     constructed on the fly.  */
+	  YY_("syntax error, unexpected %s");
+	  YY_("syntax error, unexpected %s, expecting %s");
+	  YY_("syntax error, unexpected %s, expecting %s or %s");
+	  YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+	  YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+#endif
+	  char *yyfmt;
+	  char const *yyf;
+	  static char const yyunexpected[] = "syntax error, unexpected %s";
+	  static char const yyexpecting[] = ", expecting %s";
+	  static char const yyor[] = " or %s";
+	  char yyformat[sizeof(yyunexpected)
+			+ sizeof(yyexpecting) - 1
+			+ ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+			   * (sizeof(yyor) - 1))];
+	  char const *yyprefix = yyexpecting;
+
+	  /* Start YYX at -YYN if negative to avoid negative indexes in
+	     YYCHECK.  */
+	  int yyxbegin = yyn < 0 ? -yyn : 0;
+
+	  /* Stay within bounds of both yycheck and yytname.  */
+	  int yychecklim = YYLAST - yyn;
+	  int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+	  int yycount = 1;
+
+	  yyarg[0] = yytname[yytype];
+	  yyfmt = yystpcpy (yyformat, yyunexpected);
+
+	  for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	      {
+		if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+		  {
+		    yycount = 1;
+		    yysize = yysize0;
+		    yyformat[sizeof(yyunexpected) - 1] = '\0';
+		    break;
+		  }
+		yyarg[yycount++] = yytname[yyx];
+		yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+		yysize_overflow |= yysize1 < yysize;
+		yysize = yysize1;
+		yyfmt = yystpcpy (yyfmt, yyprefix);
+		yyprefix = yyor;
+	      }
+
+	  yyf = YY_(yyformat);
+	  yysize1 = yysize + yystrlen (yyf);
+	  yysize_overflow |= yysize1 < yysize;
+	  yysize = yysize1;
+
+	  if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM)
+	    yymsg = (char *) YYSTACK_ALLOC (yysize);
+	  if (yymsg)
+	    {
+	      /* Avoid sprintf, as that infringes on the user's name space.
+		 Don't have undefined behavior even if the translation
+		 produced a string with the wrong number of "%s"s.  */
+	      char *yyp = yymsg;
+	      int yyi = 0;
+	      while ((*yyp = *yyf))
+		{
+		  if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		    {
+		      yyp += yytnamerr (yyp, yyarg[yyi++]);
+		      yyf += 2;
+		    }
+		  else
+		    {
+		      yyp++;
+		      yyf++;
+		    }
+		}
+	      yyerror (yymsg);
+	      YYSTACK_FREE (yymsg);
+	    }
+	  else
+	    {
+	      yyerror (YY_("syntax error"));
+	      goto yyexhaustedlab;
+	    }
+	}
+	  else
+#endif /* YYERROR_VERBOSE */
+	yyerror (YY_("syntax error"));
+	}
+
+
+
+  if (yyerrstatus == 3)
+	{
+      /* If just tried and failed to reuse look-ahead token after an
+	 error, discard it.  */
+
+	  if (yychar <= YYEOF)
+		{
+	  /* Return failure if at end of input.  */
+	  if (yychar == YYEOF)
+	    YYABORT;
+		}
+	  else
+	{
+	  yydestruct ("Error: discarding", yytoken, &yylval);
+	  yychar = YYEMPTY;
+	}
+	}
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (0)
+	 goto yyerrorlab;
+
+yyvsp -= yylen;
+  yyssp -= yylen;
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+	{
+	  yyn = yypact[yystate];
+	  if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+	  if (yyssp == yyss)
+	YYABORT;
+
+
+	  yydestruct ("Error: popping", yystos[yystate], yyvsp);
+	  YYPOPSTACK;
+	  yystate = *yyssp;
+	  YY_STACK_PRINT (yyss, yyssp);
+	}
+
+  if (yyn == YYFINAL)
+	YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* Shift the error token. */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+	 yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval);
+  while (yyssp != yyss)
+	{
+	  yydestruct ("Cleanup: popping",
+		  yystos[*yyssp], yyvsp);
+	  YYPOPSTACK;
+	}
+#ifndef yyoverflow
+  if (yyss != yyssa)
+	YYSTACK_FREE (yyss);
+#endif
+  return yyresult;
+}
+
+
+
+
+
+void conf_parse(const char *name)
+{
+	struct symbol *sym;
+	int i;
+
+	zconf_initscan(name);
+
+	sym_init();
+	menu_init();
+	modules_sym = sym_lookup(NULL, 0);
+	modules_sym->type = S_BOOLEAN;
+	modules_sym->flags |= SYMBOL_AUTO;
+	rootmenu.prompt = menu_add_prompt(P_MENU, "VxMicro 2.2 Project Configuration", NULL);
+
+#if YYDEBUG
+	if (getenv("ZCONF_DEBUG"))
+		zconfdebug = 1;
+#endif
+	zconfparse();
+	if (zconfnerrs)
+		exit(1);
+	if (!modules_sym->prop) {
+		struct property *prop;
+
+		prop = prop_alloc(P_DEFAULT, modules_sym);
+		prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
+	}
+	menu_finalize(&rootmenu);
+	for_all_symbols(i, sym) {
+		if (sym_check_deps(sym))
+			zconfnerrs++;
+		}
+	if (zconfnerrs)
+		exit(1);
+	sym_set_change_count(1);
+}
+
+const char *zconf_tokenname(int token)
+{
+	switch (token) {
+	case T_MENU:		return "menu";
+	case T_ENDMENU:		return "endmenu";
+	case T_CHOICE:		return "choice";
+	case T_ENDCHOICE:	return "endchoice";
+	case T_IF:		return "if";
+	case T_ENDIF:		return "endif";
+	case T_DEPENDS:		return "depends";
+	}
+	return "<token>";
+}
+
+static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
+{
+	if (id->token != endtoken) {
+		zconf_error("unexpected '%s' within %s block",
+			kconf_id_strings + id->name, zconf_tokenname(starttoken));
+		zconfnerrs++;
+		return false;
+	}
+	if (current_menu->file != current_file) {
+		zconf_error("'%s' in different file than '%s'",
+			kconf_id_strings + id->name, zconf_tokenname(starttoken));
+		fprintf(stderr, "%s:%d: location of the '%s'\n",
+			current_menu->file->name, current_menu->lineno,
+			zconf_tokenname(starttoken));
+		zconfnerrs++;
+		return false;
+	}
+	return true;
+}
+
+static void zconfprint(const char *err, ...)
+{
+	va_list ap;
+
+	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
+	va_start(ap, err);
+	vfprintf(stderr, err, ap);
+	va_end(ap);
+	fprintf(stderr, "\n");
+}
+
+static void zconf_error(const char *err, ...)
+{
+	va_list ap;
+
+	zconfnerrs++;
+	fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
+	va_start(ap, err);
+	vfprintf(stderr, err, ap);
+	va_end(ap);
+	fprintf(stderr, "\n");
+}
+
+static void zconferror(const char *err)
+{
+#if YYDEBUG
+	fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
+#endif
+}
+
+void print_quoted_string(FILE *out, const char *str)
+{
+	const char *p;
+	int len;
+
+	putc('"', out);
+	while ((p = strchr(str, '"'))) {
+		len = p - str;
+		if (len)
+			fprintf(out, "%.*s", len, str);
+		fputs("\\\"", out);
+		str = p + 1;
+	}
+	fputs(str, out);
+	putc('"', out);
+}
+
+void print_symbol(FILE *out, struct menu *menu)
+{
+	struct symbol *sym = menu->sym;
+	struct property *prop;
+
+	if (sym_is_choice(sym))
+		fprintf(out, "choice\n");
+	else
+		fprintf(out, "config %s\n", sym->name);
+	switch (sym->type) {
+	case S_BOOLEAN:
+		fputs("  boolean\n", out);
+		break;
+	case S_TRISTATE:
+		fputs("  tristate\n", out);
+		break;
+	case S_STRING:
+		fputs("  string\n", out);
+		break;
+	case S_INT:
+		fputs("  integer\n", out);
+		break;
+	case S_HEX:
+		fputs("  hex\n", out);
+		break;
+	default:
+		fputs("  ???\n", out);
+		break;
+	}
+	for (prop = sym->prop; prop; prop = prop->next) {
+		if (prop->menu != menu)
+			continue;
+		switch (prop->type) {
+		case P_PROMPT:
+			fputs("  prompt ", out);
+			print_quoted_string(out, prop->text);
+			if (!expr_is_yes(prop->visible.expr)) {
+				fputs(" if ", out);
+				expr_fprint(prop->visible.expr, out);
+			}
+			fputc('\n', out);
+			break;
+		case P_DEFAULT:
+			fputs( "  default ", out);
+			expr_fprint(prop->expr, out);
+			if (!expr_is_yes(prop->visible.expr)) {
+				fputs(" if ", out);
+				expr_fprint(prop->visible.expr, out);
+			}
+			fputc('\n', out);
+			break;
+		case P_CHOICE:
+			fputs("  #choice value\n", out);
+			break;
+		default:
+			fprintf(out, "  unknown prop %d!\n", prop->type);
+			break;
+		}
+	}
+	if (menu->help) {
+		int len = strlen(menu->help);
+		while (menu->help[--len] == '\n')
+			menu->help[len] = 0;
+		fprintf(out, "  help\n%s\n", menu->help);
+	}
+	fputc('\n', out);
+}
+
+void zconfdump(FILE *out)
+{
+	struct property *prop;
+	struct symbol *sym;
+	struct menu *menu;
+
+	menu = rootmenu.list;
+	while (menu) {
+		if ((sym = menu->sym))
+			print_symbol(out, menu);
+		else if ((prop = menu->prompt)) {
+			switch (prop->type) {
+			case P_COMMENT:
+				fputs("\ncomment ", out);
+				print_quoted_string(out, prop->text);
+				fputs("\n", out);
+				break;
+			case P_MENU:
+				fputs("\nmenu ", out);
+				print_quoted_string(out, prop->text);
+				fputs("\n", out);
+				break;
+			default:
+				;
+			}
+			if (!expr_is_yes(prop->visible.expr)) {
+				fputs("  depends ", out);
+				expr_fprint(prop->visible.expr, out);
+				fputc('\n', out);
+			}
+			fputs("\n", out);
+		}
+
+		if (menu->list)
+			menu = menu->list;
+		else if (menu->next)
+			menu = menu->next;
+		else while ((menu = menu->parent)) {
+			if (menu->prompt && menu->prompt->type == P_MENU)
+				fputs("\nendmenu\n", out);
+			if (menu->next) {
+				menu = menu->next;
+				break;
+			}
+		}
+	}
+}
+
+#include "lex.zconf.c"
+#include "util.c"
+#include "confdata.c"
+#include "expr.c"
+#include "symbol.c"
+#include "menu.c"
+
+