From: Denis Vlasenko Date: Thu, 5 Oct 2006 10:17:08 +0000 (-0000) Subject: build system overhaul X-Git-Tag: 1_4_0~548 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=7d219aab70e6951ab82c27c202cac05016696723;p=oweals%2Fbusybox.git build system overhaul --- diff --git a/Config.in b/Config.in index d61b6ff89..f888be9ad 100644 --- a/Config.in +++ b/Config.in @@ -13,7 +13,7 @@ menu "Busybox Settings" menu "General Configuration" -config CONFIG_NITPICK +config NITPICK bool "See lots more (probably unnecessary) configuration options." default n help @@ -29,7 +29,7 @@ config CONFIG_NITPICK You have been warned. -config CONFIG_DESKTOP +config DESKTOP bool "Enable options for full-blown desktop systems." default n help @@ -39,8 +39,8 @@ config CONFIG_DESKTOP choice prompt "Buffer allocation policy" - default CONFIG_FEATURE_BUFFERS_USE_MALLOC - depends on CONFIG_NITPICK + default FEATURE_BUFFERS_USE_MALLOC + depends on NITPICK help There are 3 ways BusyBox can handle buffer allocations: - Use malloc. This costs code size for the call to xmalloc. @@ -51,18 +51,18 @@ choice behavior was the only one available for BusyBox versions 0.48 and earlier. -config CONFIG_FEATURE_BUFFERS_USE_MALLOC +config FEATURE_BUFFERS_USE_MALLOC bool "Allocate with Malloc" -config CONFIG_FEATURE_BUFFERS_GO_ON_STACK +config FEATURE_BUFFERS_GO_ON_STACK bool "Allocate on the Stack" -config CONFIG_FEATURE_BUFFERS_GO_IN_BSS +config FEATURE_BUFFERS_GO_IN_BSS bool "Allocate in the .bss section" endchoice -config CONFIG_SHOW_USAGE +config SHOW_USAGE bool "Show terse applet usage messages" default y help @@ -71,20 +71,20 @@ config CONFIG_SHOW_USAGE messages if you say no here. This will save you up to 7k. -config CONFIG_FEATURE_VERBOSE_USAGE +config FEATURE_VERBOSE_USAGE bool "Show verbose applet usage messages" default n - select CONFIG_SHOW_USAGE + select SHOW_USAGE help All BusyBox applets will show more verbose help messages when busybox is invoked with --help. This will add a lot of text to the busybox binary. In the default configuration, this will add about 13k, but it can add much more depending on your configuration. -config CONFIG_FEATURE_COMPRESS_USAGE +config FEATURE_COMPRESS_USAGE bool "Store applet usage messages in compressed form" default y - depends on CONFIG_SHOW_USAGE + depends on SHOW_USAGE help Store usage messages in compressed form, uncompress them on-the-fly when --help is called. @@ -95,7 +95,7 @@ config CONFIG_FEATURE_COMPRESS_USAGE and have very little memory, this might not be a win. Otherwise, you probably want this. -config CONFIG_FEATURE_INSTALLER +config FEATURE_INSTALLER bool "Support --install [-s] to install applet links at runtime" default n help @@ -104,14 +104,14 @@ config CONFIG_FEATURE_INSTALLER applets that are compiled into busybox. This feature requires the /proc filesystem. -config CONFIG_LOCALE_SUPPORT +config LOCALE_SUPPORT bool "Enable locale support (system needs locale for this to work)" default n help Enable this if your system has locale support and you would like busybox to support locale settings. -config CONFIG_GETOPT_LONG +config GETOPT_LONG bool default y # bool "Enable support for --long-options" @@ -120,7 +120,7 @@ config CONFIG_GETOPT_LONG # Enable this if you want busybox applets to use the gnu --long-option # style, in addition to single character -a -b -c style options. -config CONFIG_FEATURE_DEVPTS +config FEATURE_DEVPTS bool "Use the devpts filesystem for Unix98 PTYs" default y help @@ -130,10 +130,10 @@ config CONFIG_FEATURE_DEVPTS /dev/ttyp will be used. To use this option, you should have devpts mounted. -config CONFIG_FEATURE_CLEAN_UP +config FEATURE_CLEAN_UP bool "Clean up all memory before exiting (usually not needed)" default n - depends on CONFIG_NITPICK + depends on NITPICK help As a size optimization, busybox normally exits without explicitly freeing dynamically allocated memory or closing files. This saves @@ -143,7 +143,7 @@ config CONFIG_FEATURE_CLEAN_UP Don't enable this unless you have a really good reason to clean things up manually. -config CONFIG_FEATURE_SUID +config FEATURE_SUID bool "Support for SUID/SGID handling" default n help @@ -158,17 +158,17 @@ config CONFIG_FEATURE_SUID are login, passwd, su, ping, traceroute, crontab, dnsd, ipcrm, ipcs, and vlock. -config CONFIG_FEATURE_SYSLOG +config FEATURE_SYSLOG bool "Support for syslog" default n help This option is auto-selected when you select any applet which may send its output to syslog. You do not need to select it manually. -config CONFIG_FEATURE_SUID_CONFIG +config FEATURE_SUID_CONFIG bool "Runtime SUID/SGID configuration via /etc/busybox.conf" - default n if CONFIG_FEATURE_SUID - depends on CONFIG_FEATURE_SUID + default n if FEATURE_SUID + depends on FEATURE_SUID help Allow the SUID / SGID state of an applet to be determined at runtime by checking /etc/busybox.conf. (This is sort of a poor man's sudo.) @@ -197,15 +197,15 @@ config CONFIG_FEATURE_SUID_CONFIG Robert 'sandman' Griebl has more information here: . -config CONFIG_FEATURE_SUID_CONFIG_QUIET +config FEATURE_SUID_CONFIG_QUIET bool "Suppress warning message if /etc/busybox.conf is not readable" default y - depends on CONFIG_FEATURE_SUID_CONFIG + depends on FEATURE_SUID_CONFIG help /etc/busybox.conf should be readable by the user needing the SUID, check this option to avoid users to be notified about missing permissions. -config CONFIG_SELINUX +config SELINUX bool "Support NSA Security Enhanced Linux" default n help @@ -225,7 +225,7 @@ config CONFIG_SELINUX Most people will leave this set to 'N'. -config CONFIG_BUSYBOX_EXEC_PATH +config BUSYBOX_EXEC_PATH string "Path to BusyBox executable" default "/proc/self/exe" help @@ -239,7 +239,7 @@ endmenu menu 'Build Options' -config CONFIG_STATIC +config STATIC bool "Build BusyBox as a static binary (no shared libs)" default n help @@ -253,7 +253,7 @@ config CONFIG_STATIC Most people will leave this set to 'N'. -config CONFIG_BUILD_LIBBUSYBOX +config BUILD_LIBBUSYBOX bool "Build shared libbusybox" default n help @@ -265,10 +265,10 @@ config CONFIG_BUILD_LIBBUSYBOX binary serves no purpose (and increases the size). You should almost certainly say "no" to this right now. -config CONFIG_FEATURE_FULL_LIBBUSYBOX +config FEATURE_FULL_LIBBUSYBOX bool "Feature-complete libbusybox" - default n if !CONFIG_FEATURE_SHARED_BUSYBOX - depends on CONFIG_BUILD_LIBBUSYBOX + default n if !FEATURE_SHARED_BUSYBOX + depends on BUILD_LIBBUSYBOX help Build a libbusybox with the complete feature-set, disregarding the actually selected config. @@ -284,15 +284,15 @@ config CONFIG_FEATURE_FULL_LIBBUSYBOX Say 'N' if in doubt. -config CONFIG_FEATURE_SHARED_BUSYBOX +config FEATURE_SHARED_BUSYBOX bool "Use shared libbusybox for busybox" - default y if CONFIG_BUILD_LIBBUSYBOX - depends on !CONFIG_STATIC && CONFIG_BUILD_LIBBUSYBOX + default y if BUILD_LIBBUSYBOX + depends on !STATIC && BUILD_LIBBUSYBOX help Use libbusybox.so also for busybox itself. You need to have a working dynamic linker to use this variant. -config CONFIG_LFS +config LFS bool "Build with Large File Support (for accessing files > 2 GB)" default n select FDISK_SUPPORT_LARGE_DISKS @@ -304,7 +304,7 @@ config CONFIG_LFS cp, mount, tar, and many others. If you want to access files larger than 2 Gigabytes, enable this option. Otherwise, leave it set to 'N'. -config CONFIG_BUILD_AT_ONCE +config BUILD_AT_ONCE bool "Compile all sources at once" default n help @@ -327,7 +327,7 @@ endmenu menu 'Debugging Options' -config CONFIG_DEBUG +config DEBUG bool "Build BusyBox with extra Debugging symbols" default n help @@ -338,10 +338,10 @@ config CONFIG_DEBUG Most people should answer N. -config CONFIG_DEBUG_PESSIMIZE +config DEBUG_PESSIMIZE bool "Disable compiler optimizations." default n - depends on CONFIG_DEBUG + depends on DEBUG help The compiler's optimization of source code can eliminate and reorder code, resulting in an executable that's hard to understand when @@ -351,8 +351,8 @@ config CONFIG_DEBUG_PESSIMIZE choice prompt "Additional debugging library" - default CONFIG_NO_DEBUG_LIB - depends on CONFIG_DEBUG + default NO_DEBUG_LIB + depends on DEBUG help Using an additional debugging library will make BusyBox become considerable larger and will cause it to run more slowly. You @@ -380,18 +380,18 @@ choice you are hunting a hard to find memory problem. -config CONFIG_NO_DEBUG_LIB +config NO_DEBUG_LIB bool "None" -config CONFIG_DMALLOC +config DMALLOC bool "Dmalloc" -config CONFIG_EFENCE +config EFENCE bool "Electric-fence" endchoice -config CONFIG_DEBUG_YANK_SUSv2 +config DEBUG_YANK_SUSv2 bool "Disable obsolete features removed before SUSv3?" default y help @@ -404,7 +404,7 @@ endmenu menu 'Installation Options' -config CONFIG_INSTALL_NO_USR +config INSTALL_NO_USR bool "Don't use /usr" default n help @@ -413,27 +413,27 @@ config CONFIG_INSTALL_NO_USR choice prompt "Applets links" - default CONFIG_INSTALL_APPLET_SYMLINKS + default INSTALL_APPLET_SYMLINKS help Choose how you install applets links. -config CONFIG_INSTALL_APPLET_SYMLINKS +config INSTALL_APPLET_SYMLINKS bool "as soft-links" help Install applets as soft-links to the busybox binary. This needs some free inodes on the filesystem, but might help with filesystem generators that can't cope with hard-links. -config CONFIG_INSTALL_APPLET_HARDLINKS +config INSTALL_APPLET_HARDLINKS bool "as hard-links" help Install applets as hard-links to the busybox binary. This might count on a filesystem with few inodes. -config CONFIG_INSTALL_APPLET_DONT +config INSTALL_APPLET_DONT bool prompt "not installed" - depends on CONFIG_FEATURE_INSTALLER || CONFIG_FEATURE_SH_STANDALONE_SHELL + depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE_SHELL help Do not install applets links. Usefull when using the -install feature or a standalone shell for rescue pruposes. diff --git a/Makefile b/Makefile index 83da80c47..4b49208d1 100644 --- a/Makefile +++ b/Makefile @@ -1,521 +1,1281 @@ -# Makefile for busybox +VERSION = 1 +PATCHLEVEL = 2 +SUBLEVEL = 1 +EXTRAVERSION = .svn +NAME=Unnamed + +# *DOCUMENTATION* +# To see a list of typical targets execute "make help" +# More info can be located in ./README +# Comments in this file are targeted only to the developer, do not +# expect to learn how to build the kernel reading this file. + +# Do not print "Entering directory ..." +MAKEFLAGS += --no-print-directory + +# We are using a recursive build, so we need to do a little thinking +# to get the ordering right. # -# Copyright (C) 1999-2004 by Erik Andersen -# -# Licensed under GPLv2, see the file LICENSE in this tarball for details. +# Most importantly: sub-Makefiles should only ever modify files in +# their own directory. If in some directory we have a dependency on +# a file in another dir (which doesn't happen often, but it's often +# unavoidable when linking the built-in.o targets which finally +# turn into busybox), we will call a sub make in that other dir, and +# after that we are sure that everything which is in that other dir +# is now up to date. # +# The only cases where we need to modify files which have global +# effects are thus separated out and done before the recursive +# descending is started. They are now explicitly listed as the +# prepare rule. -# You shouldn't have to edit anything in this file for configuration -# purposes, try "make help" or read http://busybox.net/FAQ.html. +# To put more focus on warnings, be less verbose as default +# Use 'make V=1' to see the full commands -.PHONY: dummy subdirs release distclean clean config oldconfig menuconfig \ - tags check test depend dep buildtree hosttools _all checkhelp \ - sizes bloatcheck baseline objsizes +ifdef V + ifeq ("$(origin V)", "command line") + KBUILD_VERBOSE = $(V) + endif +endif +ifndef KBUILD_VERBOSE + KBUILD_VERBOSE = 0 +endif -noconfig_targets := menuconfig config oldconfig randconfig hosttools \ - defconfig allyesconfig allnoconfig allbareconfig \ - clean distclean help \ - release tags +# Call sparse as part of compilation of C files +# Use 'make C=1' to enable sparse checking -nocheck_targets := clean distclean help release tags +ifdef C + ifeq ("$(origin C)", "command line") + KBUILD_CHECKSRC = $(C) + endif +endif +ifndef KBUILD_CHECKSRC + KBUILD_CHECKSRC = 0 +endif -# the toplevel sourcedir -ifndef top_srcdir -top_srcdir=$(CURDIR) +# Use make M=dir to specify directory of external module to build +# Old syntax make ... SUBDIRS=$PWD is still supported +# Setting the environment variable KBUILD_EXTMOD take precedence +ifdef SUBDIRS + KBUILD_EXTMOD ?= $(SUBDIRS) endif -# toplevel directory of the object-tree -ifndef top_builddir -top_builddir=$(CURDIR) +ifdef M + ifeq ("$(origin M)", "command line") + KBUILD_EXTMOD := $(M) + endif endif -export srctree=$(top_srcdir) -vpath %/Config.in $(srctree) -DIRS:=applets archival archival/libunarchive coreutils console-tools \ - debianutils editors findutils init miscutils modutils networking \ - networking/libiproute networking/udhcp procps loginutils shell \ - sysklogd util-linux e2fsprogs libpwdgrp coreutils/libcoreutils \ - runit libbb +# kbuild supports saving output files in a separate directory. +# To locate output files in a separate directory two syntaxes are supported. +# In both cases the working directory must be the root of the kernel src. +# 1) O= +# Use "make O=dir/to/store/output/files/" +# +# 2) Set KBUILD_OUTPUT +# Set the environment variable KBUILD_OUTPUT to point to the directory +# where the output files shall be placed. +# export KBUILD_OUTPUT=dir/to/store/output/files/ +# make +# +# The O= assignment takes precedence over the KBUILD_OUTPUT environment +# variable. -SRC_DIRS:=$(patsubst %,$(top_srcdir)/%,$(DIRS)) -# That's our default target when none is given on the command line -_all: - -CONFIG_CONFIG_IN = $(top_srcdir)/Config.in +# KBUILD_SRC is set on invocation of make in OBJ directory +# KBUILD_SRC is not intended to be used by the regular user (for now) +ifeq ($(KBUILD_SRC),) -ifeq ($(BUILD_SRC),) +# OK, Make called in directory where kernel src resides +# Do we want to locate output files in a separate directory? ifdef O ifeq ("$(origin O)", "command line") - BUILD_OUTPUT := $(O) - top_builddir := $(O) + KBUILD_OUTPUT := $(O) endif +endif + +# That's our default target when none is given on the command line +PHONY := _all +_all: + +ifneq ($(KBUILD_OUTPUT),) +# Invoke a second make in the output directory, passing relevant variables +# check that the output directory actually exists +saved-output := $(KBUILD_OUTPUT) +KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd) +$(if $(KBUILD_OUTPUT),, \ + $(error output directory "$(saved-output)" does not exist)) + +PHONY += $(MAKECMDGOALS) + +$(filter-out _all,$(MAKECMDGOALS)) _all: + $(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \ + KBUILD_SRC=$(CURDIR) \ + KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $@ + +# Leave processing to above invocation of make +skip-makefile := 1 +endif # ifneq ($(KBUILD_OUTPUT),) +endif # ifeq ($(KBUILD_SRC),) + +# We process the rest of the Makefile if this is the final invocation of make +ifeq ($(skip-makefile),) + +# If building an external module we do not care about the all: rule +# but instead _all depend on modules +PHONY += all +ifeq ($(KBUILD_EXTMOD),) +_all: all else -# If no alternate output-dir was specified, we build in cwd -# We are using BUILD_OUTPUT nevertheless to make sure that we create -# Rules.mak and the toplevel Makefile, in case they don't exist. - BUILD_OUTPUT := $(top_builddir) +_all: modules endif -# see if we are in verbose mode -BUILD_VERBOSE := -ifdef V - ifeq ("$(origin V)", "command line") - BUILD_VERBOSE := $(V) - endif +srctree := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR)) +TOPDIR := $(srctree) +# FIXME - TOPDIR is obsolete, use srctree/objtree +objtree := $(CURDIR) +src := $(srctree) +obj := $(objtree) + +VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD)) + +export srctree objtree VPATH TOPDIR + + +# SUBARCH tells the usermode build what the underlying arch is. That is set +# first, and if a usermode build is happening, the "ARCH=um" on the command +# line overrides the setting of ARCH below. If a native build is happening, +# then ARCH is assigned, getting whatever value it gets normally, and +# SUBARCH is subsequently ignored. + +SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ + -e s/arm.*/arm/ -e s/sa110/arm/ \ + -e s/s390x/s390/ -e s/parisc64/parisc/ \ + -e s/ppc.*/powerpc/ -e s/mips.*/mips/ ) + +# Cross compiling and selecting different set of gcc/bin-utils +# --------------------------------------------------------------------------- +# +# When performing cross compilation for other architectures ARCH shall be set +# to the target architecture. (See arch/* for the possibilities). +# ARCH can be set during invocation of make: +# make ARCH=ia64 +# Another way is to have ARCH set in the environment. +# The default ARCH is the host where make is executed. + +# CROSS_COMPILE specify the prefix used for all executables used +# during compilation. Only gcc and related bin-utils executables +# are prefixed with $(CROSS_COMPILE). +# CROSS_COMPILE can be set on the command line +# make CROSS_COMPILE=ia64-linux- +# Alternatively CROSS_COMPILE can be set in the environment. +# Default value for CROSS_COMPILE is not to prefix executables +# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile + +ARCH ?= $(SUBARCH) +CROSS_COMPILE ?= + +# Architecture as present in compile.h +UTS_MACHINE := $(ARCH) + +# SHELL used by kbuild +CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ + else if [ -x /bin/bash ]; then echo /bin/bash; \ + else echo sh; fi ; fi) + +HOSTCC = gcc +HOSTCXX = g++ +HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer +HOSTCXXFLAGS = -O2 + +# Decide whether to build built-in, modular, or both. +# Normally, just do built-in. + +KBUILD_MODULES := +KBUILD_BUILTIN := 1 + +# If we have only "make modules", don't compile built-in objects. +# When we're building modules with modversions, we need to consider +# the built-in objects during the descend as well, in order to +# make sure the checksums are uptodate before we record them. + +ifeq ($(MAKECMDGOALS),modules) + KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1) endif -ifdef VERBOSE - ifeq ("$(origin VERBOSE)", "command line") - BUILD_VERBOSE := $(VERBOSE) - endif + +# If we have "make modules", compile modules +# in addition to whatever we do anyway. +# Just "make" or "make all" shall build modules as well + +ifneq ($(filter all _all modules,$(MAKECMDGOALS)),) + KBUILD_MODULES := 1 +endif + +ifeq ($(MAKECMDGOALS),) + KBUILD_MODULES := 1 endif -ifneq ($(strip $(BUILD_VERBOSE)),) - export BUILD_VERBOSE - CHECK_VERBOSE := -v -# ARFLAGS+=v +export KBUILD_MODULES KBUILD_BUILTIN +export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD + +# Beautify output +# --------------------------------------------------------------------------- +# +# Normally, we echo the whole command before executing it. By making +# that echo $($(quiet)$(cmd)), we now have the possibility to set +# $(quiet) to choose other forms of output instead, e.g. +# +# quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@ +# cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< +# +# If $(quiet) is empty, the whole command will be printed. +# If it is set to "quiet_", only the short version will be printed. +# If it is set to "silent_", nothing wil be printed at all, since +# the variable $(silent_cmd_cc_o_c) doesn't exist. +# +# A simple variant is to prefix commands with $(Q) - that's useful +# for commands that shall be hidden in non-verbose mode. +# +# $(Q)ln $@ :< +# +# If KBUILD_VERBOSE equals 0 then the above command will be hidden. +# If KBUILD_VERBOSE equals 1 then the above command is displayed. + +ifeq ($(KBUILD_VERBOSE),1) + quiet = + Q = +else + quiet=quiet_ + Q = @ endif -ifneq ($(strip $(HAVE_DOT_CONFIG)),y) -# pull in settings early --include $(top_srcdir)/Rules.mak +# If the user is running make -s (silent mode), suppress echoing of +# commands + +ifneq ($(findstring s,$(MAKEFLAGS)),) + quiet=silent_ endif -# All object directories. -OBJ_DIRS := $(DIRS) -all_tree := $(patsubst %,$(top_builddir)/%,$(OBJ_DIRS) scripts scripts/config include) -all_tree: $(all_tree) -$(all_tree): - @mkdir -p "$@" +export quiet Q KBUILD_VERBOSE + + +# Look for make include files relative to root of kernel src +MAKEFLAGS += --include-dir=$(srctree) + +# We need some generic definitions +include $(srctree)/scripts/Kbuild.include + +# For maximum performance (+ possibly random breakage, uncomment +# the following) + +MAKEFLAGS += -rR + +# Make variables (CC, etc...) + +AS = $(CROSS_COMPILE)as +LD = $(CROSS_COMPILE)ld +CC = $(CROSS_COMPILE)gcc +CPP = $(CC) -E +AR = $(CROSS_COMPILE)ar +NM = $(CROSS_COMPILE)nm +STRIP = $(CROSS_COMPILE)strip +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump +AWK = awk +GENKSYMS = scripts/genksyms/genksyms +DEPMOD = /sbin/depmod +KALLSYMS = scripts/kallsyms +PERL = perl +CHECK = sparse + +CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise $(CF) +MODFLAGS = -DMODULE +CFLAGS_MODULE = $(MODFLAGS) +AFLAGS_MODULE = $(MODFLAGS) +LDFLAGS_MODULE = -r +CFLAGS_KERNEL = +AFLAGS_KERNEL = + + +# Use LINUXINCLUDE when you must reference the include/ directory. +# Needed to be compatible with the O= option +CFLAGS := +CPPFLAGS := +AFLAGS := +include $(srctree)/Makefile.flags + +# Read KERNELRELEASE from .kernelrelease (if it exists) +KERNELRELEASE = $(shell cat .kernelrelease 2> /dev/null) +KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) + +export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION \ + ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \ + CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE \ + HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS + +export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS +export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE +export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE + +# When compiling out-of-tree modules, put MODVERDIR in the module +# tree rather than in the kernel tree. The kernel tree might +# even be read-only. +export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions + +# Files to ignore in find ... statements + +RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o +export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg --exclude .git + +# =========================================================================== +# Rules shared between *config targets and build targets + +# Basic helpers built in scripts/ +PHONY += scripts_basic +scripts_basic: + $(Q)$(MAKE) $(build)=scripts/basic + +# To avoid any implicit rule to kick in, define an empty command. +scripts/basic/%: scripts_basic ; + +PHONY += outputmakefile +# outputmakefile generates a Makefile in the output directory, if using a +# separate output directory. This allows convenient use of make in the +# output directory. +outputmakefile: +ifneq ($(KBUILD_SRC),) + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \ + $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL) +endif -ifneq ($(BUILD_OUTPUT),) -# Invoke a second make in the output directory, passing relevant variables -# Check that the output directory actually exists -saved-output := $(BUILD_OUTPUT) -BUILD_OUTPUT := $(shell cd $(BUILD_OUTPUT) && /bin/pwd) -$(if $(wildcard $(BUILD_OUTPUT)),, \ - $(error output directory "$(saved-output)" does not exist)) +# To make sure we do not include .config for any of the *config targets +# catch them early, and hand them over to scripts/kconfig/Makefile +# It is allowed to specify more targets when calling make, including +# mixing *config targets and build targets. +# For example 'make oldconfig all'. +# Detect when mixed targets is specified, and make a second invocation +# of make so .config is not included in this case either (for *config). + +no-dot-config-targets := clean mrproper distclean \ + cscope TAGS tags help %docs check% + +config-targets := 0 +mixed-targets := 0 +dot-config := 1 + +ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) + ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) + dot-config := 0 + endif +endif -.PHONY: $(MAKECMDGOALS) +ifeq ($(KBUILD_EXTMOD),) + ifneq ($(filter config %config,$(MAKECMDGOALS)),) + config-targets := 1 + ifneq ($(filter-out config %config,$(MAKECMDGOALS)),) + mixed-targets := 1 + endif + endif +endif -$(filter-out _all,$(MAKECMDGOALS)) _all: $(BUILD_OUTPUT)/Rules.mak $(BUILD_OUTPUT)/Makefile all_tree - $(Q)$(MAKE) -C $(BUILD_OUTPUT) \ - top_srcdir=$(top_srcdir) \ - top_builddir=$(top_builddir) \ - BUILD_SRC=$(top_srcdir) \ - -f $(CURDIR)/Makefile $@ +ifeq ($(mixed-targets),1) +# =========================================================================== +# We're called with mixed targets (*config and build targets). +# Handle them one by one. -$(BUILD_OUTPUT)/Rules.mak: - @echo > $@ - @echo top_srcdir=$(top_srcdir) >> $@ - @echo top_builddir=$(BUILD_OUTPUT) >> $@ - @echo include $(top_srcdir)/Rules.mak >> $@ +%:: FORCE + $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@ -$(BUILD_OUTPUT)/Makefile: - @echo > $@ - @echo top_srcdir=$(top_srcdir) >> $@ - @echo top_builddir=$(BUILD_OUTPUT) >> $@ - @echo BUILD_SRC='$$(top_srcdir)' >> $@ - @echo include '$$(BUILD_SRC)'/Makefile >> $@ +else +ifeq ($(config-targets),1) +# =========================================================================== +# *config targets only - make sure prerequisites are updated, and descend +# in scripts/kconfig to make the *config target + +# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed. +# KBUILD_DEFCONFIG may point out an alternative default configuration +# used for 'make defconfig' +-include $(srctree)/arch/$(ARCH)/Makefile +export KBUILD_DEFCONFIG + +config %config: scripts_basic outputmakefile FORCE + $(Q)mkdir -p include/linux + $(Q)$(MAKE) $(build)=scripts/kconfig $@ + $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease -# Leave processing to above invocation of make -skip-makefile := 1 -endif # ifneq ($(BUILD_OUTPUT),) -endif # ifeq ($(BUILD_SRC),) +else +# =========================================================================== +# Build targets only - this includes busybox, arch specific targets, clean +# targets and others. In general all targets except *config targets. + +ifeq ($(KBUILD_EXTMOD),) +# Additional helpers built in scripts/ +# Carefully list dependencies so we do not try to build scripts twice +# in parrallel +PHONY += scripts +scripts: scripts_basic include/config/MARKER + $(Q)$(MAKE) $(build)=$(@) + +scripts_basic: include/autoconf.h + +# Objects we will link into busybox / subdirs we need to visit +core-y := \ + applets/ \ + +libs-y := \ + archival/ \ + archival/libunarchive/ \ + console-tools/ \ + coreutils/ \ + coreutils/libcoreutils/ \ + debianutils/ \ + e2fsprogs/ \ + e2fsprogs/blkid/ \ + e2fsprogs/e2p/ \ + e2fsprogs/ext2fs/ \ + e2fsprogs/uuid/ \ + editors/ \ + findutils/ \ + init/ \ + libbb/ \ + libpwdgrp/ \ + loginutils/ \ + miscutils/ \ + modutils/ \ + networking/ \ + networking/libiproute/ \ + networking/udhcp/ \ + procps/ \ + runit/ \ + shell/ \ + sysklogd/ \ + util-linux/ \ + +endif # KBUILD_EXTMOD + +ifeq ($(dot-config),1) +# In this section, we need .config -ifeq ($(skip-makefile),) +# Read in dependencies to all Kconfig* files, make sure to run +# oldconfig if changes are detected. +-include .kconfig.d -# We only need a copy of the Makefile for the config targets and reuse -# the rest from the source directory, i.e. we do not cp ALL_MAKEFILES. -scripts/config/Makefile: $(top_srcdir)/scripts/config/Makefile - cp $< $@ +include .config -_all: all +# If .config needs to be updated, it will be done via the dependency +# that autoconf has on .config. +# To avoid any implicit rule to kick in, define an empty command +.config .kconfig.d: ; -help: - @echo 'Cleaning:' - @echo ' clean - delete temporary files created by build' - @echo ' distclean - delete all non-source files (including .config)' - @echo - @echo 'Build:' - @echo ' all - Executable and documentation' - @echo ' busybox - the swiss-army executable' - @echo ' doc - docs/BusyBox.{txt,html,1}' - @echo ' html - create html-based cross-reference' - @echo - @echo 'Configuration:' - @echo ' allnoconfig - disable all symbols in .config' - @echo ' allyesconfig - enable all symbols in .config (see defconfig)' - @echo ' allbareconfig - enable all applets without any sub-features' - @echo ' config - text based configurator (of last resort)' - @echo ' defconfig - set .config to largest generic configuration' - @echo ' menuconfig - interactive curses-based configurator' - @echo ' oldconfig - resolve any unresolved symbols in .config' - @echo ' hosttools - build sed for the host.' - @echo ' You can use these commands if the commands on the host' - @echo ' is unusable. Afterwards use it like:' - @echo ' make SED="$(top_builddir)/sed"' - @echo - @echo 'Installation:' - @echo ' install - install busybox into $(PREFIX)' - @echo ' uninstall' - @echo - @echo 'Development:' - @echo ' baseline - create busybox_old for bloatcheck.' - @echo ' bloatcheck - show size difference between old and new versions' - @echo ' check - run the test suite for all applets' - @echo ' checkhelp - check for missing help-entries in Config.in' - @echo ' randconfig - generate a random configuration' - @echo ' release - create a distribution tarball' - @echo ' sizes - show size of all enabled busybox symbols' - @echo ' objsizes - show size of each .o object built' - @echo +# If .config is newer than include/autoconf.h, someone tinkered +# with it and forgot to run make oldconfig. +# If kconfig.d is missing then we are probarly in a cleaned tree so +# we execute the config step to be sure to catch updated Kconfig files +include/autoconf.h: .kconfig.d .config + $(Q)mkdir -p include/linux + $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig +else +# Dummy target needed, because used as prerequisite +include/autoconf.h: ; +endif -include $(top_srcdir)/Rules.mak +# The all: target is the default when no target is given on the +# command line. +# This allow a user to issue only 'make' to build a kernel including modules +# Defaults busybox but it is usually overriden in the arch makefile +all: busybox -ifneq ($(strip $(HAVE_DOT_CONFIG)),y) +-include $(srctree)/arch/$(ARCH)/Makefile -# Default target if none was requested explicitly -all: menuconfig +# arch Makefile may override CC so keep this after arch Makefile is included +#bbox# NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) +CHECKFLAGS += $(NOSTDINC_FLAGS) -# warn if no configuration exists and we are asked to build a non-config target -.config: - @echo "" - @echo "No $(top_builddir)/$@ found!" - @echo "Please refer to 'make help', section Configuration." - @echo "" - @exit 1 +# warn about C99 declaration after statement +CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) + +# disable pointer signedness warnings in gcc 4.0 +CFLAGS += $(call cc-option,-Wno-pointer-sign,) + +# Default kernel image to build when no specific target is given. +# KBUILD_IMAGE may be overruled on the commandline or +# set in the environment +# Also any assignments in arch/$(ARCH)/Makefile take precedence over +# this default value +export KBUILD_IMAGE ?= busybox + +# +# INSTALL_PATH specifies where to place the updated kernel and system map +# images. Default is /boot, but you can set it to other values +export INSTALL_PATH ?= /boot + +# +# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory +# relocations required by build roots. This is not defined in the +# makefile but the arguement can be passed to make if needed. +# + +MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) +export MODLIB + + +ifeq ($(KBUILD_EXTMOD),) +busybox-dirs := $(patsubst %/,%,$(filter %/, $(core-y) $(core-m) $(libs-y) $(libs-m))) + +busybox-alldirs := $(sort $(busybox-dirs) $(patsubst %/,%,$(filter %/, \ + $(core-n) $(core-) $(libs-n) $(libs-) \ + ))) + +core-y := $(patsubst %/, %/built-in.o, $(core-y)) +libs-y1 := $(patsubst %/, %/lib.a, $(libs-y)) +libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y)) +libs-y := $(libs-y1) $(libs-y2) -# configuration + +# Build busybox # --------------------------------------------------------------------------- +# busybox is build from the objects selected by $(busybox-init) and +# $(busybox-main). Most are built-in.o files from top-level directories +# in the kernel tree, others are specified in arch/$(ARCH)Makefile. +# Ordering when linking is important, and $(busybox-init) must be first. +# +# busybox +# ^ +# | +# +-< $(busybox-init) +# | +--< init/version.o + more +# | +# +--< $(busybox-main) +# | +--< driver/built-in.o mm/built-in.o + more +# | +# +-< kallsyms.o (see description in CONFIG_KALLSYMS section) +# +# busybox version (uname -v) cannot be updated during normal +# descending-into-subdirs phase since we do not yet know if we need to +# update busybox. +# Therefore this step is delayed until just before final link of busybox - +# except in the kallsyms case where it is done just before adding the +# symbols to the kernel. +# +# System.map is generated to document addresses of all kernel symbols + +busybox-all := $(core-y) $(libs-y) + +# Rule to link busybox - also used during CONFIG_KALLSYMS +# May be overridden by arch/$(ARCH)/Makefile +quiet_cmd_busybox__ ?= LINK $@ + cmd_busybox__ ?= scripts/trylink $(CC) -o $@ \ + -Wl,--warn-common -Wl,--sort-common -Wl,--gc-sections \ + -Wl,--start-group $(busybox-all) -Wl,--end-group \ + +# Generate System.map +quiet_cmd_sysmap = SYSMAP + cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap + +# Link of busybox +# If CONFIG_KALLSYMS is set .version is already updated +# Generate System.map and verify that the content is consistent +# Use + in front of the busybox_version rule to silent warning with make -j2 +# First command is ':' to allow us to use + in front of the rule +define rule_busybox__ + : + $(call cmd,busybox__) + $(Q)echo 'cmd_$@ := $(cmd_busybox__)' > $(@D)/.$(@F).cmd +endef + + +ifdef CONFIG_KALLSYMS +# Generate section listing all symbols and add it into busybox $(kallsyms.o) +# It's a three stage process: +# o .tmp_busybox1 has all symbols and sections, but __kallsyms is +# empty +# Running kallsyms on that gives us .tmp_kallsyms1.o with +# the right size - busybox version (uname -v) is updated during this step +# o .tmp_busybox2 now has a __kallsyms section of the right size, +# but due to the added section, some addresses have shifted. +# From here, we generate a correct .tmp_kallsyms2.o +# o The correct .tmp_kallsyms2.o is linked into the final busybox. +# o Verify that the System.map from busybox matches the map from +# .tmp_busybox2, just in case we did not generate kallsyms correctly. +# o If CONFIG_KALLSYMS_EXTRA_PASS is set, do an extra pass using +# .tmp_busybox3 and .tmp_kallsyms3.o. This is only meant as a +# temporary bypass to allow the kernel to be built while the +# maintainers work out what went wrong with kallsyms. + +ifdef CONFIG_KALLSYMS_EXTRA_PASS +last_kallsyms := 3 +else +last_kallsyms := 2 +endif -scripts/config/conf: scripts/config/Makefile - $(Q)$(MAKE) -C scripts/config conf - -@if [ ! -f .config ] ; then \ - touch .config; \ - fi +kallsyms.o := .tmp_kallsyms$(last_kallsyms).o -scripts/config/mconf: scripts/config/Makefile - $(Q)$(MAKE) -C scripts/config ncurses conf mconf - -@if [ ! -f .config ] ; then \ - touch .config; \ - fi +define verify_kallsyms + $(Q)$(if $($(quiet)cmd_sysmap), \ + echo ' $($(quiet)cmd_sysmap) .tmp_System.map' &&) \ + $(cmd_sysmap) .tmp_busybox$(last_kallsyms) .tmp_System.map + $(Q)cmp -s System.map .tmp_System.map || \ + (echo Inconsistent kallsyms data; \ + echo Try setting CONFIG_KALLSYMS_EXTRA_PASS; \ + rm .tmp_kallsyms* ; /bin/false ) +endef -menuconfig: scripts/config/mconf - @[ -f .config ] || $(MAKE) $(MAKEFLAGS) defconfig - @./scripts/config/mconf $(CONFIG_CONFIG_IN) +# Update busybox version before link +# Use + in front of this rule to silent warning about make -j1 +# First command is ':' to allow us to use + in front of this rule +cmd_ksym_ld = $(cmd_busybox__) +define rule_ksym_ld + : + +$(call cmd,busybox_version) + $(call cmd,busybox__) + $(Q)echo 'cmd_$@ := $(cmd_busybox__)' > $(@D)/.$(@F).cmd +endef -config: scripts/config/conf - @./scripts/config/conf $(CONFIG_CONFIG_IN) +# Generate .S file with all kernel symbols +quiet_cmd_kallsyms = KSYM $@ + cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \ + $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@ -oldconfig: scripts/config/conf - @./scripts/config/conf -o $(CONFIG_CONFIG_IN) +.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE + $(call if_changed_dep,as_o_S) -randconfig: scripts/config/conf - @./scripts/config/conf -r $(CONFIG_CONFIG_IN) +.tmp_kallsyms%.S: .tmp_busybox% $(KALLSYMS) + $(call cmd,kallsyms) -allyesconfig: scripts/config/conf - @./scripts/config/conf -y $(CONFIG_CONFIG_IN) > /dev/null +# .tmp_busybox1 must be complete except kallsyms, so update busybox version +.tmp_busybox1: $(busybox-lds) $(busybox-all) FORCE + $(call if_changed_rule,ksym_ld) -allnoconfig: scripts/config/conf - @./scripts/config/conf -n $(CONFIG_CONFIG_IN) > /dev/null +.tmp_busybox2: $(busybox-lds) $(busybox-all) .tmp_kallsyms1.o FORCE + $(call if_changed,busybox__) -# defconfig is allyesconfig minus any features that are specialized enough -# or cause enough behavior change that the user really should switch them on -# manually if that's what they want. Sort of "maximum sane config". +.tmp_busybox3: $(busybox-lds) $(busybox-all) .tmp_kallsyms2.o FORCE + $(call if_changed,busybox__) -defconfig: scripts/config/conf - @./scripts/config/conf -y $(CONFIG_CONFIG_IN) > /dev/null - @$(SED) -i -r -e "s/^(CONFIG_(DEBUG.*|STATIC|SELINUX|NITPICK|BUILD_(AT_ONCE|LIBBUSYBOX)|FEATURE_(DEVFS|FULL_LIBBUSYBOX|SHARED_BUSYBOX|MTAB_SUPPORT|CLEAN_UP|UDHCP_DEBUG)|INSTALL_NO_USR))=.*/# \1 is not set/" .config - @./scripts/config/conf -o $(CONFIG_CONFIG_IN) > /dev/null +# Needs to visit scripts/ before $(KALLSYMS) can be used. +$(KALLSYMS): scripts ; +# Generate some data for debugging strange kallsyms problems +debug_kallsyms: .tmp_map$(last_kallsyms) -allbareconfig: scripts/config/conf - @./scripts/config/conf -y $(CONFIG_CONFIG_IN) > /dev/null - @$(SED) -i -r -e "s/^(CONFIG_(DEBUG|STATIC|SELINUX|DEVFSD|NC_GAPING_SECURITY_HOLE|BUILD_AT_ONCE)).*/# \1 is not set/" .config - @$(SED) -i -e "/FEATURE/s/=.*//;/^[^#]/s/.*FEATURE.*/# \0 is not set/;" .config - @echo "CONFIG_FEATURE_BUFFERS_GO_ON_STACK=y" >> .config - @yes n | ./scripts/config/conf -o $(CONFIG_CONFIG_IN) > /dev/null +.tmp_map%: .tmp_busybox% FORCE + ($(OBJDUMP) -h $< | $(AWK) '/^ +[0-9]/{print $$4 " 0 " $$2}'; $(NM) $<) | sort > $@ -hosttools: - $(Q)cp .config .config.bak || noold=yea - $(Q)$(MAKE) CC="$(HOSTCC)" CFLAGS="$(HOSTCFLAGS) $(INCS)" allnoconfig - $(Q)mv .config .config.in - $(Q)(grep -v CONFIG_SED .config.in ; \ - echo "CONFIG_SED=y" ; ) > .config - $(Q)$(MAKE) CC="$(HOSTCC)" CFLAGS="$(HOSTCFLAGS) $(INCS)" oldconfig include/bb_config.h - $(Q)$(MAKE) CC="$(HOSTCC)" CFLAGS="$(HOSTCFLAGS) $(INCS)" busybox - $(Q)[ -f .config.bak ] && mv .config.bak .config || rm .config - mv busybox sed - @echo "Now do: $(MAKE) SED=$(top_builddir)/sed " +.tmp_map3: .tmp_map2 -else # ifneq ($(strip $(HAVE_DOT_CONFIG)),y) +.tmp_map2: .tmp_map1 -all: busybox busybox.links doc +endif # ifdef CONFIG_KALLSYMS -# In this section, we need .config --include $(top_builddir)/.config.cmd -include $(patsubst %,%/Makefile.in, $(SRC_DIRS)) - -endif # ifneq ($(strip $(HAVE_DOT_CONFIG)),y) - --include $(top_builddir)/.config --include $(top_builddir)/.depend - - -ifeq ($(strip $(CONFIG_BUILD_AT_ONCE)),y) -libraries-y:= -# Which parts of the internal libs are requested? -# Per default we only want what was actually selected. -# -a denotes all while -y denotes the selected ones. -ifeq ($(strip $(CONFIG_FEATURE_FULL_LIBBUSYBOX)),y) -LIBRARY_DEFINE:=$(LIBRARY_DEFINE-a) -LIBRARY_SRC :=$(LIBRARY_SRC-a) -else # CONFIG_FEATURE_FULL_LIBBUSYBOX -LIBRARY_DEFINE:=$(LIBRARY_DEFINE-y) -LIBRARY_SRC :=$(LIBRARY_SRC-y) -endif # CONFIG_FEATURE_FULL_LIBBUSYBOX -APPLET_SRC:=$(APPLET_SRC-y) -APPLETS_DEFINE:=$(APPLETS_DEFINE-y) -else # CONFIG_BUILD_AT_ONCE -APPLET_SRC:= -# no --combine, build archives out of the individual .o -# This was the old way the binary was built. -libbusybox-obj:=archival/libunarchive/libunarchive.a \ - networking/libiproute/libiproute.a \ - libpwdgrp/libpwdgrp.a \ - coreutils/libcoreutils/libcoreutils.a \ - libbb/libbb.a -libbusybox-obj:=$(patsubst %,$(top_builddir)/%,$(libbusybox-obj)) - -ifeq ($(strip $(CONFIG_FEATURE_SHARED_BUSYBOX)),y) -# linking against libbusybox, so don't build the .a already contained in the .so -libraries-y:=$(filter-out $(libbusybox-obj),$(libraries-y)) -endif # CONFIG_FEATURE_SHARED_BUSYBOX -endif # CONFIG_BUILD_AT_ONCE - - -ifeq ($(strip $(CONFIG_BUILD_LIBBUSYBOX)),y) -LD_LIBBUSYBOX:=libbusybox.so -LIBBUSYBOX_SONAME:=$(LD_LIBBUSYBOX).$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL_VERSION) -DO_INSTALL_LIBS:=$(LD_LIBBUSYBOX) \ - $(LD_LIBBUSYBOX).$(MAJOR_VERSION) \ - $(LD_LIBBUSYBOX).$(MAJOR_VERSION).$(MINOR_VERSION) -endif # CONFIG_BUILD_LIBBUSYBOX - -ifeq ($(strip $(CONFIG_BUILD_AT_ONCE)),y) -ifneq ($(strip $(CONFIG_FEATURE_SHARED_BUSYBOX)),y) -# --combine but not linking against libbusybox, so compile all -BUSYBOX_SRC := $(LIBRARY_SRC) -BUSYBOX_DEFINE:= $(LIBRARY_DEFINE) -endif # !CONFIG_FEATURE_SHARED_BUSYBOX -$(LIBBUSYBOX_SONAME): $(LIBRARY_SRC) -else # CONFIG_BUILD_AT_ONCE -$(LIBBUSYBOX_SONAME): $(libbusybox-obj) -endif # CONFIG_BUILD_AT_ONCE - -ifeq ($(strip $(CONFIG_FEATURE_SHARED_BUSYBOX)),y) -LDBUSYBOX:=-L$(top_builddir) -lbusybox +# busybox image - including updated kernel symbols +busybox_unstripped: $(busybox-all) FORCE + $(call if_changed_rule,busybox__) + $(Q)rm -f .old_version + +busybox: busybox_unstripped + $(Q)strip -s --remove-section=.note --remove-section=.comment \ + busybox_unstripped -o $@ + +# The actual objects are generated when descending, +# make sure no implicit rule kicks in +$(sort $(busybox-all)): $(busybox-dirs) ; + +# Handle descending into subdirectories listed in $(busybox-dirs) +# Preset locale variables to speed up the build process. Limit locale +# tweaks to this spot to avoid wrong language settings when running +# make menuconfig etc. +# Error messages still appears in the original language + +PHONY += $(busybox-dirs) +$(busybox-dirs): prepare scripts + $(Q)$(MAKE) $(build)=$@ + +# Build the kernel release string +# The KERNELRELEASE is stored in a file named .kernelrelease +# to be used when executing for example make install or make modules_install +# +# Take the contents of any files called localversion* and the config +# variable CONFIG_LOCALVERSION and append them to KERNELRELEASE. +# LOCALVERSION from the command line override all of this + +nullstring := +space := $(nullstring) # end of line + +___localver = $(objtree)/localversion* $(srctree)/localversion* +__localver = $(sort $(wildcard $(___localver))) +# skip backup files (containing '~') +_localver = $(foreach f, $(__localver), $(if $(findstring ~, $(f)),,$(f))) + +localver = $(subst $(space),, \ + $(shell cat /dev/null $(_localver)) \ + $(patsubst "%",%,$(CONFIG_LOCALVERSION))) + +# If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called +# and if the SCM is know a tag from the SCM is appended. +# The appended tag is determinded by the SCM used. +# +# Currently, only git is supported. +# Other SCMs can edit scripts/setlocalversion and add the appropriate +# checks as needed. +ifdef CONFIG_LOCALVERSION_AUTO + _localver-auto = $(shell $(CONFIG_SHELL) \ + $(srctree)/scripts/setlocalversion $(srctree)) + localver-auto = $(LOCALVERSION)$(_localver-auto) endif -ifeq ($(strip $(CONFIG_BUILD_LIBBUSYBOX)),y) -$(LIBBUSYBOX_SONAME): -ifndef MAJOR_VERSION - $(error MAJOR_VERSION needed for $@ is not defined) +localver-full = $(localver)$(localver-auto) + +# Store (new) KERNELRELASE string in .kernelrelease +kernelrelease = $(KERNELVERSION)$(localver-full) +.kernelrelease: FORCE + $(Q)rm -f $@ + $(Q)echo $(kernelrelease) > $@ + + +# Things we need to do before we recursively start building the kernel +# or the modules are listed in "prepare". +# A multi level approach is used. prepareN is processed before prepareN-1. +# archprepare is used in arch Makefiles and when processed asm symlink, +# version.h and scripts_basic is processed / created. + +# Listed in dependency order +PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3 + +# prepare-all is deprecated, use prepare as valid replacement +PHONY += prepare-all + +# prepare3 is used to check if we are building in a separate output directory, +# and if so do: +# 1) Check that make has not been executed in the kernel src $(srctree) +# 2) Create the include2 directory, used for the second asm symlink +prepare3: .kernelrelease +ifneq ($(KBUILD_SRC),) + @echo ' Using $(srctree) as source for kernel' + $(Q)if [ -f $(srctree)/.config ]; then \ + echo " $(srctree) is not clean, please run 'make mrproper'";\ + echo " in the '$(srctree)' directory.";\ + /bin/false; \ + fi; + $(Q)if [ ! -d include2 ]; then mkdir -p include2; fi; + $(Q)ln -fsn $(srctree)/include/asm-$(ARCH) include2/asm endif - $(do_link.so) \ - -Wl,-soname=$(LD_LIBBUSYBOX).$(MAJOR_VERSION) \ - -Wl,-z,combreloc - @rm -f $(DO_INSTALL_LIBS) - @for i in $(DO_INSTALL_LIBS); do ln -s $(@) $$i ; done - $(do_strip) -endif # ifeq ($(strip $(CONFIG_BUILD_LIBBUSYBOX)),y) +# prepare2 creates a makefile if using a separate output directory +prepare2: prepare3 outputmakefile + +prepare1: prepare2 include/config/MARKER +ifneq ($(KBUILD_MODULES),) + $(Q)mkdir -p $(MODVERDIR) + $(Q)rm -f $(MODVERDIR)/* +endif -busybox_unstripped: .depend $(LIBBUSYBOX_SONAME) $(BUSYBOX_SRC) $(APPLET_SRC) $(libraries-y) - $(do_link) +archprepare: prepare1 scripts_basic -busybox: busybox_unstripped - $(Q)cp busybox_unstripped busybox - $(do_strip) +prepare0: archprepare FORCE + $(Q)$(MAKE) $(build)=. -%.bflt: %_unstripped - $(do_elf2flt) +# All the preparing.. +prepare prepare-all: prepare0 -busybox.links: $(top_srcdir)/applets/busybox.mkll include/bb_config.h $(top_srcdir)/include/applets.h - $(Q)-$(SHELL) $^ >$@ +# Leave this as default for preprocessing busybox.lds.S, which is now +# done in arch/$(ARCH)/kernel/Makefile -install: $(top_srcdir)/applets/install.sh busybox busybox.links - $(Q)DO_INSTALL_LIBS="$(strip $(LIBBUSYBOX_SONAME) $(DO_INSTALL_LIBS))" \ - $(SHELL) $< $(PREFIX) $(INSTALL_OPTS) -ifeq ($(strip $(CONFIG_FEATURE_SUID)),y) - @echo +export CPPFLAGS_busybox.lds += -P -C -U$(ARCH) + +# FIXME: The asm symlink changes when $(ARCH) changes. That's +# hard to detect, but I suppose "make mrproper" is a good idea +# before switching between archs anyway. + +#bbox# include/asm: +#bbox# @echo ' SYMLINK $@ -> include/asm-$(ARCH)' +#bbox# $(Q)if [ ! -d include ]; then mkdir -p include; fi; +#bbox# @ln -fsn asm-$(ARCH) $@ + +# Split autoconf.h into include/linux/config/* +#bbox# piggybacked generation of few .h files +include/config/MARKER: scripts/basic/split-include include/autoconf.h + @echo ' SPLIT include/autoconf.h -> include/config/*' + @scripts/basic/split-include include/autoconf.h include/config + @echo ' GEN include/bbconfigopts.h' + @scripts/mkconfigs >include/bbconfigopts.h + @$(MAKE) $(build)=scripts + @echo ' GEN include/usage_compressed.h' + @scripts/usage_compressed include/usage_compressed.h scripts + @touch $@ + +# Generate some files +# --------------------------------------------------------------------------- + +# KERNELRELEASE can change from a few different places, meaning version.h +# needs to be updated, so this check is forced on all builds + +uts_len := 64 + +define filechk_version.h + if [ `echo -n "$(KERNELRELEASE)" | wc -c ` -gt $(uts_len) ]; then \ + echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2; \ + exit 1; \ + fi; \ + (echo \#define UTS_RELEASE \"$(KERNELRELEASE)\"; \ + echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)`; \ + echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))'; \ + ) +endef + +# --------------------------------------------------------------------------- + +PHONY += depend dep +depend dep: + @echo '*** Warning: make $@ is unnecessary now.' + +# --------------------------------------------------------------------------- +# Modules + +ifdef CONFIG_MODULES + +# By default, build modules as well + +all: modules + +# Build modules + +PHONY += modules +modules: $(busybox-dirs) $(if $(KBUILD_BUILTIN),busybox) + @echo ' Building modules, stage 2.'; + $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost + + +# Target to prepare building external modules +PHONY += modules_prepare +modules_prepare: prepare scripts + +# Target to install modules +PHONY += modules_install +modules_install: _modinst_ _modinst_post + +PHONY += _modinst_ +_modinst_: + @if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \ + echo "Warning: you may need to install module-init-tools"; \ + echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt";\ + sleep 1; \ + fi + @rm -rf $(MODLIB)/kernel + @rm -f $(MODLIB)/source + @mkdir -p $(MODLIB)/kernel + @ln -s $(srctree) $(MODLIB)/source + @if [ ! $(objtree) -ef $(MODLIB)/build ]; then \ + rm -f $(MODLIB)/build ; \ + ln -s $(objtree) $(MODLIB)/build ; \ + fi + $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst + +# If System.map exists, run depmod. This deliberately does not have a +# dependency on System.map since that would run the dependency tree on +# busybox. This depmod is only for convenience to give the initial +# boot a modules.dep even before / is mounted read-write. However the +# boot script depmod is the master version. +ifeq "$(strip $(INSTALL_MOD_PATH))" "" +depmod_opts := +else +depmod_opts := -b $(INSTALL_MOD_PATH) -r +endif +PHONY += _modinst_post +_modinst_post: _modinst_ + if [ -r System.map -a -x $(DEPMOD) ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi + +else # CONFIG_MODULES + +# Modules not configured +# --------------------------------------------------------------------------- + +modules modules_install: FORCE @echo - @echo -------------------------------------------------- - @echo You will probably need to make your busybox binary - @echo setuid root to ensure all configured applets will - @echo work properly. - @echo -------------------------------------------------- + @echo "The present kernel configuration has modules disabled." + @echo "Type 'make config' and enable loadable module support." + @echo "Then build a kernel with module support enabled." @echo -endif + @exit 1 -uninstall: busybox.links - rm -f $(PREFIX)/bin/busybox - for i in `cat busybox.links` ; do rm -f $(PREFIX)$$i; done -ifneq ($(strip $(DO_INSTALL_LIBS)),n) - for i in $(LIBBUSYBOX_SONAME) $(DO_INSTALL_LIBS); do \ - rm -f $(PREFIX)$$i; \ - done -endif +endif # CONFIG_MODULES -check test: busybox - bindir=$(top_builddir) srcdir=$(top_srcdir)/testsuite SED="$(SED)" \ - $(SHELL) $(top_srcdir)/testsuite/runtest $(CHECK_VERBOSE) +### +# Cleaning is done on three levels. +# make clean Delete most generated files +# Leave enough to build external modules +# make mrproper Delete the current configuration, and all generated files +# make distclean Remove editor backup files, patch leftover files and the like + +# Directories & files removed with 'make clean' +CLEAN_DIRS += $(MODVERDIR) +CLEAN_FILES += busybox System.map \ + .tmp_kallsyms* .tmp_version .tmp_busybox* .tmp_System.map + +# Directories & files removed with 'make mrproper' +MRPROPER_DIRS += include/config include2 +MRPROPER_FILES += .config .config.old include/asm .version .old_version \ + include/autoconf.h \ + .kernelrelease Module.symvers tags TAGS cscope* + +# clean - Delete most, but leave enough to build external modules +# +clean: rm-dirs := $(CLEAN_DIRS) +clean: rm-files := $(CLEAN_FILES) +clean-dirs := $(addprefix _clean_,$(srctree) $(busybox-alldirs)) + +PHONY += $(clean-dirs) clean archclean +$(clean-dirs): + $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@) + +clean: archclean $(clean-dirs) + $(call cmd,rmdirs) + $(call cmd,rmfiles) + @find . $(RCS_FIND_IGNORE) \ + \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ + -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \ + -type f -print | xargs rm -f + +# mrproper - Delete all generated files, including .config +# +mrproper: rm-dirs := $(wildcard $(MRPROPER_DIRS)) +mrproper: rm-files := $(wildcard $(MRPROPER_FILES)) +mrproper-dirs := $(addprefix _mrproper_,Documentation/DocBook scripts) -checkhelp: - $(Q)$(top_srcdir)/scripts/checkhelp.awk \ - $(wildcard $(patsubst %,%/Config.in,$(SRC_DIRS) ./)) +PHONY += $(mrproper-dirs) mrproper archmrproper +$(mrproper-dirs): + $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@) -sizes: busybox_unstripped - $(NM) --size-sort $(<) +mrproper: clean archmrproper $(mrproper-dirs) + $(call cmd,rmdirs) + $(call cmd,rmfiles) -bloatcheck: busybox_old busybox_unstripped - @$(top_srcdir)/scripts/bloat-o-meter busybox_old busybox_unstripped +# distclean +# +PHONY += distclean -baseline: busybox_unstripped - @mv busybox_unstripped busybox_old +distclean: mrproper + @find $(srctree) $(RCS_FIND_IGNORE) \ + \( -name '*.orig' -o -name '*.rej' -o -name '*~' \ + -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \ + -o -name '.*.rej' -o -size 0 \ + -o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \ + -type f -print | xargs rm -f -objsizes: busybox_unstripped - $(SHELL) $(top_srcdir)/scripts/objsizes -# Documentation Targets -doc: docs/busybox.pod docs/BusyBox.txt docs/BusyBox.1 docs/BusyBox.html +# Packaging of the kernel to various formats +# --------------------------------------------------------------------------- +# rpm target kept for backward compatibility +package-dir := $(srctree)/scripts/package -docs/busybox.pod : $(top_srcdir)/docs/busybox_header.pod $(top_srcdir)/include/usage.h $(top_srcdir)/docs/busybox_footer.pod $(top_srcdir)/docs/autodocifier.pl - $(disp_doc) - $(Q)-mkdir -p docs - $(Q)-( cat $(top_srcdir)/docs/busybox_header.pod ; \ - $(top_srcdir)/docs/autodocifier.pl $(top_srcdir)/include/usage.h ; \ - cat $(top_srcdir)/docs/busybox_footer.pod ; ) > docs/busybox.pod +%pkg: FORCE + $(Q)$(MAKE) $(build)=$(package-dir) $@ +rpm: FORCE + $(Q)$(MAKE) $(build)=$(package-dir) $@ -docs/BusyBox.txt: docs/busybox.pod - $(disp_doc) - $(Q)-mkdir -p docs - $(Q)-pod2text $< > $@ -docs/BusyBox.1: docs/busybox.pod - $(disp_doc) - $(Q)-mkdir -p docs - $(Q)-pod2man --center=BusyBox --release="version $(VERSION)" \ - $< > $@ +# Brief documentation of the typical targets used +# --------------------------------------------------------------------------- -docs/BusyBox.html: docs/busybox.net/BusyBox.html - $(disp_doc) - $(Q)-mkdir -p docs - $(Q)-rm -f docs/BusyBox.html - $(Q)-cp docs/busybox.net/BusyBox.html docs/BusyBox.html +boards := $(wildcard $(srctree)/arch/$(ARCH)/configs/*_defconfig) +boards := $(notdir $(boards)) -docs/busybox.net/BusyBox.html: docs/busybox.pod - $(Q)-mkdir -p docs/busybox.net - $(Q)-pod2html --noindex $< > \ - docs/busybox.net/BusyBox.html - $(Q)-rm -f pod2htm* +-include Makefile.help -# The nifty new dependency stuff -scripts/bb_mkdep: $(top_srcdir)/scripts/bb_mkdep.c - $(do_link.h) +# Documentation targets +# --------------------------------------------------------------------------- +%docs: scripts_basic FORCE + $(Q)$(MAKE) $(build)=Documentation/DocBook $@ + +else # KBUILD_EXTMOD + +### +# External module support. +# When building external modules the kernel used as basis is considered +# read-only, and no consistency checks are made and the make +# system is not used on the basis kernel. If updates are required +# in the basis kernel ordinary make commands (without M=...) must +# be used. +# +# The following are the only valid targets when building external +# modules. +# make M=dir clean Delete all automatically generated files +# make M=dir modules Make all modules in specified dir +# make M=dir Same as 'make M=dir modules' +# make M=dir modules_install +# Install the modules build in the module directory +# Assumes install directory is already created + +# We are always building modules +KBUILD_MODULES := 1 +PHONY += crmodverdir +crmodverdir: + $(Q)mkdir -p $(MODVERDIR) + $(Q)rm -f $(MODVERDIR)/* + +PHONY += $(objtree)/Module.symvers +$(objtree)/Module.symvers: + @test -e $(objtree)/Module.symvers || ( \ + echo; \ + echo " WARNING: Symbol version dump $(objtree)/Module.symvers"; \ + echo " is missing; modules will have no dependencies and modversions."; \ + echo ) + +module-dirs := $(addprefix _module_,$(KBUILD_EXTMOD)) +PHONY += $(module-dirs) modules +$(module-dirs): crmodverdir $(objtree)/Module.symvers + $(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@) + +modules: $(module-dirs) + @echo ' Building modules, stage 2.'; + $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost + +PHONY += modules_install +modules_install: _emodinst_ _emodinst_post + +install-dir := $(if $(INSTALL_MOD_DIR),$(INSTALL_MOD_DIR),extra) +PHONY += _emodinst_ +_emodinst_: + $(Q)mkdir -p $(MODLIB)/$(install-dir) + $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst + +# Run depmod only is we have System.map and depmod is executable +quiet_cmd_depmod = DEPMOD $(KERNELRELEASE) + cmd_depmod = if [ -r System.map -a -x $(DEPMOD) ]; then \ + $(DEPMOD) -ae -F System.map \ + $(if $(strip $(INSTALL_MOD_PATH)), \ + -b $(INSTALL_MOD_PATH) -r) \ + $(KERNELRELEASE); \ + fi + +PHONY += _emodinst_post +_emodinst_post: _emodinst_ + $(call cmd,depmod) + +clean-dirs := $(addprefix _clean_,$(KBUILD_EXTMOD)) + +PHONY += $(clean-dirs) clean +$(clean-dirs): + $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@) + +clean: rm-dirs := $(MODVERDIR) +clean: $(clean-dirs) + $(call cmd,rmdirs) + @find $(KBUILD_EXTMOD) $(RCS_FIND_IGNORE) \ + \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ + -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \ + -type f -print | xargs rm -f -DEP_INCLUDES := include/bb_config.h +help: + @echo ' Building external modules.' + @echo ' Syntax: make -C path/to/kernel/src M=$$PWD target' + @echo '' + @echo ' modules - default target, build the module(s)' + @echo ' modules_install - install the module' + @echo ' clean - remove generated files in module directory only' + @echo '' + +# Dummies... +PHONY += prepare scripts +prepare: ; +scripts: ; +endif # KBUILD_EXTMOD + +# Generate tags for editors +# --------------------------------------------------------------------------- -ifeq ($(strip $(CONFIG_BBCONFIG)),y) -DEP_INCLUDES += include/bbconfigopts.h +#We want __srctree to totally vanish out when KBUILD_OUTPUT is not set +#(which is the most common case IMHO) to avoid unneeded clutter in the big tags file. +#Adding $(srctree) adds about 20M on i386 to the size of the output file! -include/bbconfigopts.h: .config $(top_srcdir)/scripts/config/mkconfigs - $(disp_gen) - $(Q)$(top_srcdir)/scripts/config/mkconfigs > $@ +ifeq ($(src),$(obj)) +__srctree = +else +__srctree = $(srctree)/ endif -ifeq ($(strip $(CONFIG_FEATURE_COMPRESS_USAGE)),y) -USAGE_BIN:=scripts/usage -$(USAGE_BIN): $(top_srcdir)/scripts/usage.c .config \ - $(top_srcdir)/include/usage.h - $(do_link.h) - -DEP_INCLUDES += include/usage_compressed.h - -include/usage_compressed.h: .config $(USAGE_BIN) \ - $(top_srcdir)/scripts/usage_compressed - $(Q)SED="$(SED)" $(SHELL) $(top_srcdir)/scripts/usage_compressed \ - "$(top_builddir)/scripts" > $@ -endif # CONFIG_FEATURE_COMPRESS_USAGE - -depend dep: .depend -.depend: scripts/bb_mkdep $(USAGE_BIN) $(DEP_INCLUDES) - $(disp_gen) - $(Q)rm -f .depend - $(Q)mkdir -p include/config - $(Q)scripts/bb_mkdep -I $(top_srcdir)/include $(top_srcdir) > $@.tmp - $(Q)mv $@.tmp $@ - -include/bb_config.h: .config - @if [ ! -x $(top_builddir)/scripts/config/conf ] ; then \ - $(MAKE) -C scripts/config conf; \ - fi; - @$(top_builddir)/scripts/config/conf -o $(CONFIG_CONFIG_IN) - -clean: - - $(MAKE) -C scripts/config $@ - - rm -f docs/busybox.dvi docs/busybox.ps \ - docs/busybox.pod docs/busybox.net/busybox.html \ - docs/busybox pod2htm* *.gdb *.elf *~ core .*config.log \ - docs/BusyBox.txt docs/BusyBox.1 docs/BusyBox.html \ - docs/busybox.net/BusyBox.html busybox.links \ - libbusybox.so* \ - .config.old busybox busybox_unstripped \ - include/usage_compressed.h scripts/usage - - rm -r -f _install testsuite/links - - find . -name .\*.flags -o -name \*.o -o -name \*.om -o -name \*.syn \ - -o -name \*.os -o -name \*.osm -o -name \*.a | xargs rm -f - -distclean: clean - rm -f scripts/bb_mkdep scripts/usage - rm -r -f include/config include/config.h $(DEP_INCLUDES) - find . -name .depend'*' -print0 | xargs -0 rm -f - find . -name '*.rej' -print0 | xargs -0 rm -f - rm -f .hdepend busybox_old .config .config.old .config.cmd - -release: distclean #doc - cd ..; \ - rm -r -f $(PROG)-$(VERSION); \ - cp -a busybox $(PROG)-$(VERSION); \ - \ - find $(PROG)-$(VERSION)/ -type d \ - -name .svn \ - -print \ - -exec rm -r -f {} \; ; \ - \ - find $(PROG)-$(VERSION)/ -type f \ - -name .\#* \ - -print \ - -exec rm -f {} \; ; \ - \ - tar -cvzf $(PROG)-$(VERSION).tar.gz $(PROG)-$(VERSION)/; - -tags: - ctags -R . - -# documentation, cross-reference -# Modern distributions already ship synopsis packages (e.g. debian) -# If you have an old distribution go to http://synopsis.fresco.org/ -syn_tgt := $(wildcard $(patsubst %,%/*.c,$(SRC_DIRS))) -syn := $(patsubst %.c, %.syn, $(syn_tgt)) - -%.syn: %.c - synopsis -p C -l Comments.SSDFilter,Comments.Previous $(INCS) -Wp,verbose,debug,preprocess,cppflags="'$(CFLAGS) $(EXTRA_CFLAGS) $(LDFLAGS) $(PROG_CFLAGS) $(PROG_LDFLAGS) $(CFLAGS_COMBINE) $(APPLETS_DEFINE) $(BUSYBOX_DEFINE)'" -o $@ $< -html: $(syn) - synopsis -f HTML -Wf,title="'BusyBox Documentation'" -o $@ $^ - - -endif # ifeq ($(skip-makefile),) +ifeq ($(ALLSOURCE_ARCHS),) +ifeq ($(ARCH),um) +ALLINCLUDE_ARCHS := $(ARCH) $(SUBARCH) +else +ALLINCLUDE_ARCHS := $(ARCH) +endif +else +#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behaviour. +ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS) +endif + +ALLSOURCE_ARCHS := $(ARCH) + +define all-sources + ( find $(__srctree) $(RCS_FIND_IGNORE) \ + \( -name include -o -name arch \) -prune -o \ + -name '*.[chS]' -print; \ + for ARCH in $(ALLSOURCE_ARCHS) ; do \ + find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \ + -name '*.[chS]' -print; \ + done ; \ + find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \ + -name '*.[chS]' -print; \ + find $(__srctree)include $(RCS_FIND_IGNORE) \ + \( -name config -o -name 'asm-*' \) -prune \ + -o -name '*.[chS]' -print; \ + for ARCH in $(ALLINCLUDE_ARCHS) ; do \ + find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \ + -name '*.[chS]' -print; \ + done ; \ + find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \ + -name '*.[chS]' -print ) +endef + +quiet_cmd_cscope-file = FILELST cscope.files + cmd_cscope-file = (echo \-k; echo \-q; $(all-sources)) > cscope.files + +quiet_cmd_cscope = MAKE cscope.out + cmd_cscope = cscope -b + +cscope: FORCE + $(call cmd,cscope-file) + $(call cmd,cscope) + +quiet_cmd_TAGS = MAKE $@ +define cmd_TAGS + rm -f $@; \ + ETAGSF=`etags --version | grep -i exuberant >/dev/null && \ + echo "-I __initdata,__exitdata,__acquires,__releases \ + -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ + --extra=+f --c-kinds=+px"`; \ + $(all-sources) | xargs etags $$ETAGSF -a +endef + +TAGS: FORCE + $(call cmd,TAGS) + + +quiet_cmd_tags = MAKE $@ +define cmd_tags + rm -f $@; \ + CTAGSF=`ctags --version | grep -i exuberant >/dev/null && \ + echo "-I __initdata,__exitdata,__acquires,__releases \ + -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ + --extra=+f --c-kinds=+px"`; \ + $(all-sources) | xargs ctags $$CTAGSF -a +endef + +tags: FORCE + $(call cmd,tags) + + +# Scripts to check various things for consistency +# --------------------------------------------------------------------------- + +includecheck: + find * $(RCS_FIND_IGNORE) \ + -name '*.[hcS]' -type f -print | sort \ + | xargs $(PERL) -w scripts/checkincludes.pl + +versioncheck: + find * $(RCS_FIND_IGNORE) \ + -name '*.[hcS]' -type f -print | sort \ + | xargs $(PERL) -w scripts/checkversion.pl + +namespacecheck: + $(PERL) $(srctree)/scripts/namespace.pl + +endif #ifeq ($(config-targets),1) +endif #ifeq ($(mixed-targets),1) + +PHONY += checkstack +checkstack: + $(OBJDUMP) -d busybox $$(find . -name '*.ko') | \ + $(PERL) $(src)/scripts/checkstack.pl $(ARCH) + +kernelrelease: + $(if $(wildcard .kernelrelease), $(Q)echo $(KERNELRELEASE), \ + $(error kernelrelease not valid - run 'make *config' to update it)) +kernelversion: + @echo $(KERNELVERSION) + +# Single targets +# --------------------------------------------------------------------------- +# Single targets are compatible with: +# - build whith mixed source and output +# - build with separate output dir 'make O=...' +# - external modules +# +# target-dir => where to store outputfile +# build-dir => directory in kernel source tree to use + +ifeq ($(KBUILD_EXTMOD),) + build-dir = $(patsubst %/,%,$(dir $@)) + target-dir = $(dir $@) +else + zap-slash=$(filter-out .,$(patsubst %/,%,$(dir $@))) + build-dir = $(KBUILD_EXTMOD)$(if $(zap-slash),/$(zap-slash)) + target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@)) +endif + +%.s: %.c prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +%.i: %.c prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +%.o: %.c prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +%.lst: %.c prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +%.s: %.S prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +%.o: %.S prepare scripts FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) + +# Modules +/ %/: prepare scripts FORCE + $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ + $(build)=$(build-dir) +%.ko: prepare scripts FORCE + $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ + $(build)=$(build-dir) $(@:.ko=.o) + $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost + +# FIXME Should go into a make.lib or something +# =========================================================================== + +quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN $(wildcard $(rm-dirs))) + cmd_rmdirs = rm -rf $(rm-dirs) + +quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files))) + cmd_rmfiles = rm -f $(rm-files) + + +a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) \ + $(NOSTDINC_FLAGS) $(CPPFLAGS) \ + $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o) + +quiet_cmd_as_o_S = AS $@ +cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< + +# read all saved command lines + +targets := $(wildcard $(sort $(targets))) +cmd_files := $(wildcard .*.cmd $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) + +ifneq ($(cmd_files),) + $(cmd_files): ; # Do not try to update included dependency files + include $(cmd_files) +endif + +# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir +# Usage: +# $(Q)$(MAKE) $(clean)=dir +clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj + +endif # skip-makefile + +PHONY += FORCE +FORCE: + +-include Makefile.custom +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable se we can use it in if_changed and friends. +.PHONY: $(PHONY) diff --git a/Makefile.custom b/Makefile.custom new file mode 100644 index 000000000..6880b97d6 --- /dev/null +++ b/Makefile.custom @@ -0,0 +1,131 @@ +### # defconfig is allyesconfig minus any features that are specialized enough +### # or cause enough behavior change that the user really should switch them on +### # manually if that's what they want. Sort of "maximum sane config". + +### defconfig: scripts/config/conf +### @./scripts/config/conf -y $(CONFIG_CONFIG_IN) > /dev/null +### @$(SED) -i -r -e "s/^(CONFIG_(DEBUG.*|STATIC|SELINUX|NITPICK|BUILD_(AT_ONCE|LIBBUSYBOX)|FEATURE_(DEVFS|FULL_LIBBUSYBOX|SHARED_BUSYBOX|MTAB_SUPPORT|CLEAN_UP|UDHCP_DEBUG)|INSTALL_NO_USR))=.*/# \1 is not set/" .config +### @./scripts/config/conf -o $(CONFIG_CONFIG_IN) > /dev/null + +### allbareconfig: scripts/config/conf +### @./scripts/config/conf -y $(CONFIG_CONFIG_IN) > /dev/null +### @$(SED) -i -r -e "s/^(CONFIG_(DEBUG|STATIC|SELINUX|DEVFSD|NC_GAPING_SECURITY_HOLE|BUILD_AT_ONCE)).*/# \1 is not set/" .config +### @$(SED) -i -e "/FEATURE/s/=.*//;/^[^#]/s/.*FEATURE.*/# \0 is not set/;" .config +### @echo "CONFIG_FEATURE_BUFFERS_GO_ON_STACK=y" >> .config +### @yes n | ./scripts/config/conf -o $(CONFIG_CONFIG_IN) > /dev/null + +### hosttools: +### $(Q)cp .config .config.bak || noold=yea +### $(Q)$(MAKE) CC="$(HOSTCC)" CFLAGS="$(HOSTCFLAGS) $(INCS)" allnoconfig +### $(Q)mv .config .config.in +### $(Q)(grep -v CONFIG_SED .config.in ; \ +### echo "CONFIG_SED=y" ; ) > .config +### $(Q)$(MAKE) CC="$(HOSTCC)" CFLAGS="$(HOSTCFLAGS) $(INCS)" oldconfig include/bb_config.h +### $(Q)$(MAKE) CC="$(HOSTCC)" CFLAGS="$(HOSTCFLAGS) $(INCS)" busybox +### $(Q)[ -f .config.bak ] && mv .config.bak .config || rm .config +### mv busybox sed +### @echo "Now do: $(MAKE) SED=$(objtree)/sed " + +%.bflt: %_unstripped + $(CROSS_COMPILE)elf2flt $(ELF2FLTFLAGS) $< -o $@ + +busybox.links: $(srctree)/applets/busybox.mkll include/bb_config.h $(srctree)/include/applets.h + $(Q)-$(SHELL) $^ >$@ + +.PHONY: install +install: $(srctree)/applets/install.sh busybox busybox.links + $(Q)DO_INSTALL_LIBS="$(strip $(LIBBUSYBOX_SONAME) $(DO_INSTALL_LIBS))" \ + $(SHELL) $< $(CONFIG_PREFIX) $(INSTALL_OPTS) +ifeq ($(strip $(CONFIG_FEATURE_SUID)),y) + @echo + @echo + @echo -------------------------------------------------- + @echo You will probably need to make your busybox binary + @echo setuid root to ensure all configured applets will + @echo work properly. + @echo -------------------------------------------------- + @echo +endif + +uninstall: busybox.links + rm -f $(CONFIG_PREFIX)/bin/busybox + for i in `cat busybox.links` ; do rm -f $(CONFIG_PREFIX)$$i; done +ifneq ($(strip $(DO_INSTALL_LIBS)),n) + for i in $(LIBBUSYBOX_SONAME) $(DO_INSTALL_LIBS); do \ + rm -f $(CONFIG_PREFIX)$$i; \ + done +endif + +check test: busybox + bindir=$(objtree) srcdir=$(srctree)/testsuite SED="$(SED)" \ + $(SHELL) $(srctree)/testsuite/runtest $(if $(KBUILD_VERBOSE:1=),-v) + +### checkhelp: +### $(Q)$(srctree)/scripts/checkhelp.awk \ +### $(wildcard $(patsubst %,%/Config.in,$(SRC_DIRS) ./)) + +.PHONY: sizes +sizes: busybox_unstripped + $(NM) --size-sort $(<) + +.PHONY: bloatcheck +bloatcheck: busybox_old busybox_unstripped + @$(srctree)/scripts/bloat-o-meter busybox_old busybox_unstripped + +.PHONY: baseline +baseline: busybox_unstripped + @mv busybox_unstripped busybox_old + +.PHONY: objsizes +objsizes: busybox_unstripped + $(SHELL) $(srctree)/scripts/objsizes + +# Documentation Targets +.PHONY: doc +doc: docs/busybox.pod docs/BusyBox.txt docs/BusyBox.1 docs/BusyBox.html + +docs/busybox.pod: $(srctree)/docs/busybox_header.pod \ + $(srctree)/include/usage.h \ + $(srctree)/docs/busybox_footer.pod \ + $(srctree)/docs/autodocifier.pl + $(disp_doc) + $(Q)-mkdir -p docs + $(Q)-( cat $(srctree)/docs/busybox_header.pod ; \ + $(srctree)/docs/autodocifier.pl $(srctree)/include/usage.h ; \ + cat $(srctree)/docs/busybox_footer.pod ; ) > docs/busybox.pod + +docs/BusyBox.txt: docs/busybox.pod + $(disp_doc) + $(Q)-mkdir -p docs + $(Q)-pod2text $< > $@ + +docs/BusyBox.1: docs/busybox.pod + $(disp_doc) + $(Q)-mkdir -p docs + $(Q)-pod2man --center=BusyBox --release="version $(VERSION)" \ + $< > $@ + +docs/BusyBox.html: docs/busybox.net/BusyBox.html + $(disp_doc) + $(Q)-mkdir -p docs + $(Q)-rm -f docs/BusyBox.html + $(Q)-cp docs/busybox.net/BusyBox.html docs/BusyBox.html + +docs/busybox.net/BusyBox.html: docs/busybox.pod + $(Q)-mkdir -p docs/busybox.net + $(Q)-pod2html --noindex $< > \ + docs/busybox.net/BusyBox.html + $(Q)-rm -f pod2htm* + +# documentation, cross-reference +# Modern distributions already ship synopsis packages (e.g. debian) +# If you have an old distribution go to http://synopsis.fresco.org/ +syn_tgt := $(wildcard $(patsubst %,%/*.c,$(SRC_DIRS))) +syn := $(patsubst %.c, %.syn, $(syn_tgt)) + +%.syn: %.c + synopsis -p C -l Comments.SSDFilter,Comments.Previous $(INCS) -Wp,verbose,debug,preprocess,cppflags="'$(CFLAGS) $(EXTRA_CFLAGS) $(LDFLAGS) $(PROG_CFLAGS) $(PROG_LDFLAGS) $(CFLAGS_COMBINE) $(APPLETS_DEFINE) $(BUSYBOX_DEFINE)'" -o $@ $< + +.PHONY: html +html: $(syn) + synopsis -f HTML -Wf,title="'BusyBox Documentation'" -o $@ $^ diff --git a/Makefile.flags b/Makefile.flags new file mode 100644 index 000000000..39c544e60 --- /dev/null +++ b/Makefile.flags @@ -0,0 +1,19 @@ +# ========================================================================== +# Building +# ========================================================================== + +BB_VER = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) + +CPPFLAGS += \ + -Iinclude -Ilibbb \ + $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) -I$(srctree)/libbb \ + -include include/autoconf.h \ + -D_GNU_SOURCE -DNDEBUG \ + -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 \ + -D"BB_VER=KBUILD_STR($(BB_VER))" -DBB_BT=AUTOCONF_TIMESTAMP \ + -Wall -Wstrict-prototypes -Wshadow -Werror \ + -funsigned-char -fno-builtin-strlen -finline-limit=0 -static-libgcc \ + -Os -march=i386 -mpreferred-stack-boundary=2 \ + -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ + -fomit-frame-pointer -ffunction-sections -fdata-sections \ + -funsigned-char -fno-builtin-strlen \ diff --git a/Makefile.help b/Makefile.help new file mode 100644 index 000000000..3ba68d1e4 --- /dev/null +++ b/Makefile.help @@ -0,0 +1,88 @@ +### Kernel's one: +### help: +### @echo 'Cleaning targets:' +### @echo ' clean - remove most generated files but keep the config' +### @echo ' mrproper - remove all generated files + config + various backup files' +### @echo '' +### @echo 'Configuration targets:' +### @$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help +### @echo '' +### @echo 'Other generic targets:' +### @echo ' all - Build all targets marked with [*]' +### @echo '* busybox - Build the bare kernel' +### @echo '* modules - Build all modules' +### @echo ' modules_install - Install all modules to INSTALL_MOD_PATH (default: /)' +### @echo ' dir/ - Build all files in dir and below' +### @echo ' dir/file.[ois] - Build specified target only' +### @echo ' dir/file.ko - Build module including final link' +### @echo ' rpm - Build a kernel as an RPM package' +### @echo ' tags/TAGS - Generate tags file for editors' +### @echo ' cscope - Generate cscope index' +### @echo ' kernelrelease - Output the release version string' +### @echo ' kernelversion - Output the version stored in Makefile' +### @echo '' +### @echo 'Static analysers' +### @echo ' checkstack - Generate a list of stack hogs' +### @echo ' namespacecheck - Name space analysis on compiled kernel' +### @echo '' +### @echo 'Kernel packaging:' +### @$(MAKE) $(build)=$(package-dir) help +### @echo '' +### @echo 'Documentation targets:' +### @$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp +### @echo '' +### @echo 'Architecture specific targets ($(ARCH)):' +### @$(if $(archhelp),$(archhelp),\ +### echo ' No architecture specific help defined for $(ARCH)') +### @echo '' +### @$(if $(boards), \ +### $(foreach b, $(boards), \ +### printf " %-24s - Build for %s\\n" $(b) $(subst _defconfig,,$(b));) \ +### echo '') +### +### @echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build' +### @echo ' make O=dir [targets] Locate all output files in "dir", including .config' +### @echo ' make C=1 [targets] Check all c source with $$CHECK (sparse)' +### @echo ' make C=2 [targets] Force check of all c source with $$CHECK (sparse)' +### @echo '' +### @echo 'Execute "make" or "make all" to build all targets marked with [*] ' +### @echo 'For further info see the ./README file' + +help: + @echo 'Cleaning:' + @echo ' clean - delete temporary files created by build' + @echo ' distclean - delete all non-source files (including .config)' + @echo + @echo 'Build:' + @echo ' all - Executable and documentation' + @echo ' busybox - the swiss-army executable' + @echo ' doc - docs/BusyBox.{txt,html,1}' + @echo ' html - create html-based cross-reference' + @echo + @echo 'Configuration:' + @echo ' allnoconfig - disable all symbols in .config' + @echo ' allyesconfig - enable all symbols in .config (see defconfig)' + @echo ' allbareconfig - enable all applets without any sub-features' + @echo ' config - text based configurator (of last resort)' + @echo ' defconfig - set .config to largest generic configuration' + @echo ' menuconfig - interactive curses-based configurator' + @echo ' oldconfig - resolve any unresolved symbols in .config' + @echo ' hosttools - build sed for the host.' + @echo ' You can use these commands if the commands on the host' + @echo ' is unusable. Afterwards use it like:' + @echo ' make SED="$(objtree)/sed"' + @echo + @echo 'Installation:' + @echo ' install - install busybox into $(PREFIX)' + @echo ' uninstall' + @echo + @echo 'Development:' + @echo ' baseline - create busybox_old for bloatcheck.' + @echo ' bloatcheck - show size difference between old and new versions' + @echo ' check - run the test suite for all applets' + @echo ' checkhelp - check for missing help-entries in Config.in' + @echo ' randconfig - generate a random configuration' + @echo ' release - create a distribution tarball' + @echo ' sizes - show size of all enabled busybox symbols' + @echo ' objsizes - show size of each .o object built' + @echo diff --git a/Rules.mak b/Rules.mak deleted file mode 100644 index e0704989b..000000000 --- a/Rules.mak +++ /dev/null @@ -1,436 +0,0 @@ -# Rules.make for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under GPLv2, see the file LICENSE in this tarball for details. -# - -# Pull in the user's busybox configuration -ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),) --include $(top_builddir)/.config -endif - -#-------------------------------------------------------- -PROG := busybox -MAJOR_VERSION :=1 -MINOR_VERSION :=2 -SUBLEVEL_VERSION:=0 -EXTRAVERSION :=-svn -VERSION :=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL_VERSION)$(EXTRAVERSION) -BUILDTIME := $(shell TZ=UTC date -u "+%Y.%m.%d-%H:%M%z") - - -#-------------------------------------------------------- -# With a modern GNU make(1) (highly recommended, that's what all the -# developers use), all of the following configuration values can be -# overridden at the command line. For example: -# make CROSS_COMPILE=powerpc-linux- top_srcdir="$HOME/busybox" PREFIX=/mnt/app -#-------------------------------------------------------- - -# If you are running a cross compiler, you will want to set CROSS_COMPILE -# to something more interesting... Target architecture is determined -# by asking the CC compiler what arch it compiles things for, so unless -# your compiler is broken, you should not need to specify TARGET_ARCH -CC = $(CROSS_COMPILE)gcc -AR = $(CROSS_COMPILE)ar -AS = $(CROSS_COMPILE)as -LD = $(CROSS_COMPILE)ld -NM = $(CROSS_COMPILE)nm -STRIP = $(CROSS_COMPILE)strip -ELF2FLT = $(CROSS_COMPILE)elf2flt -CPP = $(CC) -E -SED ?= sed -BZIP2 ?= bzip2 - - -# What OS are you compiling busybox for? This allows you to include -# OS specific things, syscall overrides, etc. -TARGET_OS=linux - -# Ensure consistent sort order, 'gcc -print-search-dirs' behavior, etc. -LC_ALL:= C - -# This must bind late because srcdir is reset for every source subdirectory. -INCS:=-I$(top_builddir)/include -I$(top_srcdir)/include -CFLAGS=$(INCS) -I$(srcdir) -D_GNU_SOURCE -CFLAGS+=$(CHECKED_CFLAGS) -ARFLAGS=cru - -# gcc centric. Perhaps fiddle with findstring gcc,$(CC) for the rest -# get the CC MAJOR/MINOR version -CC_MAJOR:=$(shell printf "%02d" $(shell echo __GNUC__ | $(CC) -E -xc - | tail -n 1)) -CC_MINOR:=$(shell printf "%02d" $(shell echo __GNUC_MINOR__ | $(CC) -E -xc - | tail -n 1)) - -#-------------------------------------------------------- -export VERSION BUILDTIME HOSTCC HOSTCFLAGS CROSS_COMPILE CC AR AS LD NM STRIP CPP -ifeq ($(strip $(TARGET_ARCH)),) -TARGET_ARCH:=$(shell $(CC) -dumpmachine | $(SED) -e s'/-.*//' \ - -e 's/i.86/i386/' \ - -e 's/sparc.*/sparc/' \ - -e 's/arm.*/arm/g' \ - -e 's/m68k.*/m68k/' \ - -e 's/ppc/powerpc/g' \ - -e 's/v850.*/v850/g' \ - -e 's/sh[234]/sh/' \ - -e 's/mips-.*/mips/' \ - -e 's/mipsel-.*/mipsel/' \ - -e 's/cris.*/cris/' \ - ) -endif - -# A nifty macro to make testing gcc features easier, but note that everything -# that uses this _must_ use := or it will be re-evaluated everytime it is -# referenced. -ifeq ($(strip $(BUILD_VERBOSE)),2) -VERBOSE_CHECK_CC=echo CC=\"$(1)\" check_cc $(2) >&2; -endif -check_cc=$(shell \ - $(VERBOSE_CHECK_CC) \ - if [ "x$(1)" != "x" ] && [ "x$(2)" != "x" ]; then \ - echo "int i;" > ./conftest.c; \ - if $(1) $(2) -c -o conftest.o conftest.c > /dev/null 2>&1; \ - then echo "$(2)"; else echo "$(3)"; fi ; \ - rm -f conftest.c conftest.o; \ - fi) - -ifneq ($(filter $(nocheck_targets),$(MAKECMDGOALS)),) -check_cc:= -endif - -# A not very robust macro to check for available ld flags -ifeq ($(strip $(BUILD_VERBOSE)),2) -VERBOSE_CHECK_LD=echo LD=\"$(1)\" check_ld $(2) >&2; -endif -check_ld=$(shell \ - $(VERBOSE_CHECK_LD) \ - if [ "x$(1)" != "x" ] && [ "x$(2)" != "x" ]; then \ - $(1) -o /dev/null -b binary /dev/null > /dev/null 2>&1 && \ - echo "-Wl,$(2)" ; \ - fi) - -ifneq ($(filter $(nocheck_targets),$(MAKECMDGOALS)),) -check_ld:= -endif - -# A not very robust macro to check for available strip flags -ifeq ($(strip $(BUILD_VERBOSE)),2) -VERBOSE_CHECK_STRIP=echo STRIPCMD=\"$(1)\" check_strip $(2) >&2; -endif -check_strip=$(shell \ - $(VERBOSE_CHECK_STRIP) \ - if [ "x$(1)" != "x" ] && [ "x$(2)" != "x" ]; then \ - echo "int i;" > ./conftest.c ; \ - $(CC) -c -o conftest.o conftest.c > /dev/null 2>&1 ; \ - $(1) $(2) conftest.o > /dev/null 2>&1 && \ - echo "$(1) $(2)" || echo "$(3)"; \ - rm -f conftest.c conftest.o > /dev/null 2>&1 ; \ - fi) - -ifneq ($(filter $(nocheck_targets),$(MAKECMDGOALS)),) -check_strip:= -endif - - -# Select the compiler needed to build binaries for your development system -HOSTCC = gcc -HOSTCFLAGS:=$(call check_cc,$(HOSTCC),-Wall,) -HOSTCFLAGS+=$(call check_cc,$(HOSTCC),-Wstrict-prototypes,) -HOSTCFLAGS+=$(call check_cc,$(HOSTCC),-O2,) -HOSTCFLAGS+=$(call check_cc,$(HOSTCC),-fomit-frame-pointer,) - -LD_WHOLE_ARCHIVE:=$(shell echo "int i;" > conftest.c ; \ - $(CC) -c -o conftest.o conftest.c ; \ - echo "int main(void){return 0;}" > conftest_main.c ; \ - $(CC) -c -o conftest_main.o conftest_main.c ; \ - $(AR) $(ARFLAGS) conftest.a conftest.o ; \ - $(CC) -Wl,--whole-archive conftest.a -Wl,--no-whole-archive \ - conftest_main.o -o conftest > /dev/null 2>&1 \ - && echo "-Wl,--whole-archive" ; \ - rm conftest_main.o conftest_main.c conftest.o conftest.c \ - conftest.a conftest > /dev/null 2>&1 ; ) -ifneq ($(findstring whole-archive,$(LD_WHOLE_ARCHIVE)),) -LD_NO_WHOLE_ARCHIVE:= -Wl,--no-whole-archive -endif - -LD_START_GROUP:=$(shell echo "int bar(void){return 0;}" > conftest.c ; \ - $(CC) -c -o conftest.o conftest.c ; \ - echo "int main(void){return bar();}" > conftest_main.c ; \ - $(CC) -c -o conftest_main.o conftest_main.c ; \ - $(AR) $(ARFLAGS) conftest.a conftest.o ; \ - $(CC) -Wl,--start-group conftest.a conftest_main.o -Wl,--end-group \ - -o conftest > /dev/null 2>&1 && echo "-Wl,--start-group" ; \ - rm conftest_main.o conftest_main.c conftest.o conftest.c \ - conftest.a conftest > /dev/null 2>&1 ; ) -ifneq ($(findstring start-group,$(LD_START_GROUP)),) -LD_END_GROUP:= -Wl,--end-group -endif - -CHECKED_LDFLAGS := $(call check_ld,$(LD),--warn-common,) -#CHECKED_LDFLAGS := $(call check_ld,$(LD),-static-libgcc,) - -# Pin CHECKED_CFLAGS with := so it's only evaluated once. -CHECKED_CFLAGS:=$(call check_cc,$(CC),-Wall,) -CHECKED_CFLAGS+=$(call check_cc,$(CC),-Wstrict-prototypes,) -CHECKED_CFLAGS+=$(call check_cc,$(CC),-Wshadow,) -CHECKED_CFLAGS+=$(call check_cc,$(CC),-funsigned-char,) -CHECKED_CFLAGS+=$(call check_cc,$(CC),-fno-builtin-strlen,) -CHECKED_CFLAGS+=$(call check_cc,$(CC),-finline-limit=0,) - -# gcc 2.95 exits with 0 for "unrecognized option" -ifeq ($(strip $(shell [ $(CC_MAJOR) -ge 3 ] ; echo $$?)),0) - CHECKED_CFLAGS+=$(call check_cc,$(CC),-static-libgcc,) -endif - -# Preemptively pin this too. -PROG_CFLAGS:= - - -#-------------------------------------------------------- -# Arch specific compiler optimization stuff should go here. -# Unless you want to override the defaults, do not set anything -# for OPTIMIZATION... - -# use '-Os' optimization if available, else use -O2 -OPTIMIZATION:=$(call check_cc,$(CC),-Os,-O2) - -ifeq ($(CONFIG_BUILD_AT_ONCE),y) -# gcc 2.95 exits with 0 for "unrecognized option" -ifeq ($(strip $(shell [ $(CC_MAJOR) -ge 3 ] ; echo $$?)),0) - CFLAGS_COMBINE:=$(call check_cc,$(CC),--combine,) -endif -OPTIMIZATION+=$(call check_cc,$(CC),-funit-at-a-time,) -OPTIMIZATION+=$(call check_cc,$(CC),-fgcse-after-reload,) -ifneq ($(CONFIG_BUILD_LIBBUSYBOX),y) -# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25795 -# This prevents us from using -fwhole-program when we build the lib -PROG_CFLAGS+=$(call check_cc,$(CC),-fwhole-program,) -endif # CONFIG_BUILD_LIBBUSYBOX -endif # CONFIG_BUILD_AT_ONCE - -LIB_LDFLAGS:=$(call check_ld,$(LD),--enable-new-dtags,) -#LIB_LDFLAGS+=$(call check_ld,$(LD),--reduce-memory-overheads,) -#LIB_LDFLAGS+=$(call check_ld,$(LD),--as-needed,) -#LIB_LDFLAGS+=$(call check_ld,$(LD),--warn-shared-textrel,) - - -# Some nice architecture specific optimizations -ifeq ($(strip $(TARGET_ARCH)),arm) - OPTIMIZATION+=-fstrict-aliasing -endif -ifeq ($(strip $(TARGET_ARCH)),i386) - OPTIMIZATION+=$(call check_cc,$(CC),-march=i386,) -# gcc-4.0 and older seem to benefit from these -ifneq ($(strip $(shell [ $(CC_MAJOR) -ge 4 -a $(CC_MINOR) -ge 1 ] ; echo $$?)),0) - OPTIMIZATION+=$(call check_cc,$(CC),-mpreferred-stack-boundary=2,) - OPTIMIZATION+=$(call check_cc,$(CC),-falign-functions=1 -falign-jumps=1 -falign-loops=1, -malign-functions=0 -malign-jumps=0 -malign-loops=0,) - - # gcc 4.1 produces many broken, totally invalid warnings - CHECKED_CFLAGS+=$(call check_cc,$(CC),-Werror,) -endif # gcc-4.0 and older - -# gcc-4.1 and beyond seem to benefit from these -ifeq ($(strip $(shell [ $(CC_MAJOR) -ge 4 -a $(CC_MINOR) -ge 1 ] ; echo $$?)),0) - # turn off flags which hurt -Os - OPTIMIZATION+=$(call check_cc,$(CC),-fno-tree-loop-optimize,) - OPTIMIZATION+=$(call check_cc,$(CC),-fno-tree-dominator-opts,) - OPTIMIZATION+=$(call check_cc,$(CC),-fno-strength-reduce,) - - OPTIMIZATION+=$(call check_cc,$(CC),-fno-branch-count-reg,) -endif # gcc-4.1 and beyond -endif -OPTIMIZATION+=$(call check_cc,$(CC),-fomit-frame-pointer,) -CHECKED_LDFLAGS += $(call check_ld,$(LD),--sort-common,) - -# -#-------------------------------------------------------- -# If you're going to do a lot of builds with a non-vanilla configuration, -# it makes sense to adjust parameters above, so you can type "make" -# by itself, instead of following it by the same half-dozen overrides -# every time. The stuff below, on the other hand, is probably less -# prone to casual user adjustment. -# - -ifeq ($(strip $(CONFIG_LFS)),y) - # For large file summit support - CFLAGS+=-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -endif -ifeq ($(strip $(CONFIG_DMALLOC)),y) - # For testing mem leaks with dmalloc - CFLAGS+=-DDMALLOC - LIBRARIES:=-ldmalloc -else - ifeq ($(strip $(CONFIG_EFENCE)),y) - LIBRARIES:=-lefence - endif -endif - -# Debugging info - -ifeq ($(strip $(CONFIG_DEBUG)),y) - CFLAGS +=-g -else - CFLAGS +=-DNDEBUG -endif - -ifneq ($(strip $(CONFIG_DEBUG_PESSIMIZE)),y) - CFLAGS += $(OPTIMIZATION) -endif - -# warn a bit more verbosely for non-release versions -ifneq ($(EXTRAVERSION),) - CHECKED_CFLAGS+=$(call check_cc,$(CC),-Wstrict-prototypes,) - CHECKED_CFLAGS+=$(call check_cc,$(CC),-Wmissing-prototypes,) - CHECKED_CFLAGS+=$(call check_cc,$(CC),-Wmissing-declarations,) - CHECKED_CFLAGS+=$(call check_cc,$(CC),-Wunused,) - CHECKED_CFLAGS+=$(call check_cc,$(CC),-Winit-self,) - CHECKED_CFLAGS+=$(call check_cc,$(CC),-Wshadow,) - CHECKED_CFLAGS+=$(call check_cc,$(CC),-Wcast-align,) -endif -STRIPCMD:=$(call check_strip,$(STRIP),-s --remove-section=.note --remove-section=.comment,$(STRIP)) -ifeq ($(strip $(CONFIG_STATIC)),y) - PROG_CFLAGS += $(call check_cc,$(CC),-static,) -else - ifneq ($(strip $(CONFIG_DEBUG)),y) - OPTIMIZATION+=$(call check_cc,$(CC),-ffunction-sections -fdata-sections,) - CHECKED_LDFLAGS += $(call check_ld,$(LD),--gc-sections,) - endif -endif -CFLAGS_SHARED := $(call check_cc,$(CC),-shared,) -LIB_CFLAGS+=$(CFLAGS_SHARED) - -ifeq ($(strip $(CONFIG_BUILD_LIBBUSYBOX)),y) - CFLAGS_PIC:= $(call check_cc,$(CC),-fPIC,) - LIB_CFLAGS+=$(CFLAGS_PIC) -endif - -ifeq ($(strip $(CONFIG_SELINUX)),y) - LIBRARIES += -lselinux -lsepol -endif - -ifeq ($(strip $(PREFIX)),) - PREFIX:=`pwd`/_install -endif - -ifneq ($(strip $(CONFIG_GETOPT_LONG)),y) - CFLAGS += -D__need_getopt -endif - -# Additional complications due to support for pristine source dir. -# Include files in the build directory should take precedence over -# the copy in top_srcdir, both during the compilation phase and the -# shell script that finds the list of object files. -# Work in progress by . - - -OBJECTS:=$(APPLET_SOURCES:.c=.o) busybox.o usage.o applets.o -CFLAGS += $(CHECKED_CFLAGS) $(CROSS_CFLAGS) -LDFLAGS += $(CHECKED_LDFLAGS) - -ifdef BB_INIT_SCRIPT - CFLAGS += -DINIT_SCRIPT='"$(BB_INIT_SCRIPT)"' -endif - -# Put user-supplied flags at the end, where they -# have a chance of winning. --include $(top_builddir)/.config.mak - -#------------------------------------------------------------ -# Installation options -ifeq ($(strip $(CONFIG_INSTALL_APPLET_HARDLINKS)),y) -INSTALL_OPTS=--hardlinks -endif -ifeq ($(strip $(CONFIG_INSTALL_APPLET_SYMLINKS)),y) -INSTALL_OPTS=--symlinks -endif -ifeq ($(strip $(CONFIG_INSTALL_APPLET_DONT)),y) -INSTALL_OPTS= -endif - -#------------------------------------------------------------ -# Make the output nice and tight -MAKEFLAGS += --no-print-directory -export MAKE_IS_SILENT=n -ifneq ($(findstring s,$(MAKEFLAGS)),) -export MAKE_IS_SILENT=y -SECHO := @-false -DISP := sil -Q := @ -else -ifneq ($(BUILD_VERBOSE),) -SECHO := @-false -DISP := ver -Q := -else -SECHO := @echo -DISP := pur -Q := @ -endif -endif - -show_objs = $(subst $(top_builddir)/,,$(subst ../,,$@)) -pur_disp_compile.c = echo " "CC $(show_objs) ; -pur_disp_compile.h = echo " "HOSTCC $(show_objs) ; -pur_disp_strip = echo " "STRIP $(show_objs) ; -pur_disp_link = echo " "LINK $(show_objs) ; -pur_disp_link.h = echo " "HOSTLINK $(show_objs) ; -pur_disp_ar = echo " "AR $(ARFLAGS) $(show_objs) ; -pur_disp_elf2flt = echo " "ELF2FLT $(ELF2FLTFLAGS) $(show_objs) ; -sil_disp_compile.c = -sil_disp_compile.h = -sil_disp_strip = -sil_disp_link = -sil_disp_link.h = -sil_disp_ar = -sil_disp_elf2flt = -ver_disp_compile.c = -ver_disp_compile.h = -ver_disp_strip = -ver_disp_link = -ver_disp_link.h = -ver_disp_ar = -ver_disp_elf2flt = -disp_compile.c = $(Q)$($(DISP)_disp_compile.c) -disp_compile.h = $(Q)$($(DISP)_disp_compile.h) -disp_strip = $(Q)$($(DISP)_disp_strip) -disp_link = $(Q)$($(DISP)_disp_link) -disp_link.h = $(Q)$($(DISP)_disp_link.h) -disp_ar = $(Q)$($(DISP)_disp_ar) -disp_elf2flt = $(Q)$($(DISP)_disp_elf2flt) -disp_gen = $(SECHO) " "GEN $@ ; true -disp_doc = $(SECHO) " "DOC $(subst docs/,,$@) ; true -cmd_compile.c = $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< -cmd_compile.h = $(HOSTCC) $(HOSTCFLAGS) $(INCS) -c -o $@ $< -cmd_strip = $(STRIPCMD) $@ -cmd_link = $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(LDFLAGS) \ - $(PROG_CFLAGS) $(PROG_LDFLAGS) $(CFLAGS_COMBINE) \ - -o $@ $(LD_START_GROUP) \ - $(APPLETS_DEFINE) $(APPLET_SRC) \ - $(BUSYBOX_DEFINE) $(BUSYBOX_SRC) $(libraries-y) \ - $(LDBUSYBOX) $(LIBRARIES) \ - $(LD_END_GROUP) -cmd_link.so = $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(LDFLAGS) \ - $(LIB_CFLAGS) $(CFLAGS_COMBINE) $(LIB_LDFLAGS) \ - -o $(@) $(LD_START_GROUP) $(LD_WHOLE_ARCHIVE) \ - $(LIBRARY_DEFINE) $(^) \ - $(LD_NO_WHOLE_ARCHIVE) $(LD_END_GROUP) -cmd_link.h = $(HOSTCC) $(HOSTCFLAGS) $(INCS) $< -o $@ -cmd_ar = $(AR) $(ARFLAGS) $@ $^ -cmd_elf2flt = $(ELF2FLT) $(ELF2FLTFLAGS) $< -o $@ -compile.c = $(disp_compile.c) $(cmd_compile.c) -compile.h = $(disp_compile.h) $(cmd_compile.h) -do_strip = $(disp_strip) $(cmd_strip) -do_link = $(disp_link) $(cmd_link) -do_link.so = $(disp_link) $(cmd_link.so) -do_link.h = $(disp_link.h) $(cmd_link.h) -do_ar = $(disp_ar) $(cmd_ar) -do_elf2flt = $(disp_elf2flt) $(cmd_elf2flt) - -uppercase = $(shell echo $1 | $(SED) -e "y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/") -%.a: - @if test -z "$($(call uppercase,$*)_DIR)" ; then \ - echo "Invalid target $@" ; \ - exit 1 ; \ - fi - $(Q)$(MAKE) $($(call uppercase,$*)_DIR)$@ - -.PHONY: dummy diff --git a/applets/Kbuild b/applets/Kbuild new file mode 100644 index 000000000..04932eec4 --- /dev/null +++ b/applets/Kbuild @@ -0,0 +1,9 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +obj-y:= +obj-y += applets.o +obj-y += busybox.o diff --git a/applets/Makefile b/applets/Makefile deleted file mode 100644 index 0d892f5e5..000000000 --- a/applets/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/applets -APPLETS_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include $(srcdir)/Makefile.in -all: $(libraries-y) --include $(top_builddir).depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/applets/Makefile.in b/applets/Makefile.in deleted file mode 100644 index 05580b9b4..000000000 --- a/applets/Makefile.in +++ /dev/null @@ -1,26 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -APPLETS_AR:=applets.a -ifndef $(APPLETS_DIR) -APPLETS_DIR:=$(top_builddir)/applets/ -endif -srcdir=$(top_srcdir)/applets - -APPLET_SRC:= $(patsubst %,$(srcdir)/%,applets.c busybox.c) -APPLET_OBJ:= $(patsubst $(srcdir)/%.c,$(APPLETS_DIR)%.o, $(APPLET_SRC)) - -APPLET_SRC-y+=$(APPLET_SRC) -APPLET_SRC-a+=$(APPLET_SRC) - -libraries-y+=$(APPLETS_DIR)$(APPLETS_AR) - -$(APPLETS_DIR)$(APPLETS_AR): $(APPLET_OBJ) - $(do_ar) - -$(APPLET_OBJ): $(top_builddir)/.config -$(APPLET_OBJ): $(APPLETS_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/applets/applets.c b/applets/applets.c index d615ffcd8..b1f580953 100644 --- a/applets/applets.c +++ b/applets/applets.c @@ -42,8 +42,6 @@ const size_t NUM_APPLETS = (sizeof (applets) / sizeof (struct BB_applet) - 1); #ifdef CONFIG_FEATURE_SUID_CONFIG #include -#include "pwd_.h" -#include "grp_.h" #define CONFIG_FILE "/etc/busybox.conf" diff --git a/archival/Config.in b/archival/Config.in index ea8076403..bc87573b1 100644 --- a/archival/Config.in +++ b/archival/Config.in @@ -5,7 +5,7 @@ menu "Archival Utilities" -config CONFIG_AR +config AR bool "ar" default n help @@ -28,17 +28,17 @@ config CONFIG_AR Unless you have a specific application which requires ar, you should probably say N here. -config CONFIG_FEATURE_AR_LONG_FILENAMES +config FEATURE_AR_LONG_FILENAMES bool "Enable support for long filenames (not need for debs)" default n - depends on CONFIG_AR + depends on AR help By default the ar format can only store the first 15 characters of the filename, this option removes that limitation. It supports the GNU ar long filename method which moves multiple long filenames into a the data section of a new ar entry. -config CONFIG_BUNZIP2 +config BUNZIP2 bool "bunzip2" default n help @@ -54,7 +54,7 @@ config CONFIG_BUNZIP2 Unless you have a specific application which requires bunzip2, you should probably say N here. -config CONFIG_CPIO +config CPIO bool "cpio" default n help @@ -68,7 +68,7 @@ config CONFIG_CPIO Unless you have a specific application which requires cpio, you should probably say N here. -config CONFIG_DPKG +config DPKG bool "dpkg" default n help @@ -77,7 +77,7 @@ config CONFIG_DPKG This implementation of dpkg has a number of limitations, you should use the official dpkg if possible. -config CONFIG_DPKG_DEB +config DPKG_DEB bool "dpkg_deb" default n help @@ -88,16 +88,16 @@ config CONFIG_DPKG_DEB Unless you have a specific application which requires dpkg-deb, you should probably say N here. -config CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY +config FEATURE_DPKG_DEB_EXTRACT_ONLY bool "extract only (-x)" default n - depends on CONFIG_DPKG_DEB + depends on DPKG_DEB help This reduces dpkg-deb to the equivalent of "ar -p data.tar.gz | tar -zx". However it saves space as none of the extra dpkg-deb, ar or tar options are needed, they are linked to internally. -config CONFIG_GUNZIP +config GUNZIP bool "gunzip" default n help @@ -105,35 +105,35 @@ config CONFIG_GUNZIP You can use the `-t' option to test the integrity of an archive, without decompressing it. -config CONFIG_FEATURE_GUNZIP_UNCOMPRESS +config FEATURE_GUNZIP_UNCOMPRESS bool "Uncompress support" default n - depends on CONFIG_GUNZIP + depends on GUNZIP help Enable if you want gunzip to have the ability to decompress archives created by the program compress (not much used anymore). -config CONFIG_GZIP +config GZIP bool "gzip" default n help gzip is used to compress files. It's probably the most widely used UNIX compression program. -config CONFIG_RPM2CPIO +config RPM2CPIO bool "rpm2cpio" default n help Converts an RPM file into a CPIO archive. -config CONFIG_RPM +config RPM bool "rpm" default n help Mini RPM applet - queries and extracts -config CONFIG_TAR +config TAR bool "tar" default n help @@ -141,86 +141,86 @@ config CONFIG_TAR create compressed archives. It's probably the most widely used UNIX archive program. -config CONFIG_FEATURE_TAR_CREATE +config FEATURE_TAR_CREATE bool "Enable archive creation" default y - depends on CONFIG_TAR + depends on TAR help If you enable this option you'll be able to create tar archives using the `-c' option. -config CONFIG_FEATURE_TAR_BZIP2 +config FEATURE_TAR_BZIP2 bool "Enable -j option to handle .tar.bz2 files" default n - depends on CONFIG_TAR + depends on TAR help If you enable this option you'll be able to extract archives compressed with bzip2. -config CONFIG_FEATURE_TAR_LZMA +config FEATURE_TAR_LZMA bool "Enable -a option to handle .tar.lzma files" default n - depends on CONFIG_TAR + depends on TAR help If you enable this option you'll be able to extract archives compressed with lzma. -config CONFIG_FEATURE_TAR_FROM +config FEATURE_TAR_FROM bool "Enable -X (exclude from) and -T (include from) options)" default n - depends on CONFIG_TAR + depends on TAR help If you enable this option you'll be able to specify a list of files to include or exclude from an archive. -config CONFIG_FEATURE_TAR_GZIP +config FEATURE_TAR_GZIP bool "Enable -z option" default y - depends on CONFIG_TAR + depends on TAR help If you enable this option tar will be able to call gzip, when creating or extracting tar gziped archives. -config CONFIG_FEATURE_TAR_COMPRESS +config FEATURE_TAR_COMPRESS bool "Enable -Z option" default n - depends on CONFIG_TAR + depends on TAR help If you enable this option tar will be able to call uncompress, when extracting .tar.Z archives. -config CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY +config FEATURE_TAR_OLDGNU_COMPATIBILITY bool "Enable support for old tar header format" default N - depends on CONFIG_TAR + depends on TAR help This option is required to unpack archives created in the old GNU format; help to kill this old format by repacking your ancient archives with the new format. -config CONFIG_FEATURE_TAR_GNU_EXTENSIONS +config FEATURE_TAR_GNU_EXTENSIONS bool "Enable support for some GNU tar extensions" default y - depends on CONFIG_TAR + depends on TAR help With this option busybox supports GNU long filenames and linknames. -config CONFIG_FEATURE_TAR_LONG_OPTIONS +config FEATURE_TAR_LONG_OPTIONS bool "Enable long options" default n - depends on CONFIG_TAR && CONFIG_GETOPT_LONG + depends on TAR && GETOPT_LONG help Enable use of long options, increases size by about 400 Bytes -config CONFIG_UNCOMPRESS +config UNCOMPRESS bool "uncompress" default n help uncompress is used to decompress archives created by compress. Not much used anymore, replaced by gzip/gunzip. -config CONFIG_UNLZMA +config UNLZMA bool "unlzma" default n help @@ -235,15 +235,15 @@ config CONFIG_UNLZMA Unless you have a specific application which requires unlzma, you should probably say N here. -config CONFIG_FEATURE_LZMA_FAST +config FEATURE_LZMA_FAST bool "Optimze unlzma for speed" default n - depends on CONFIG_UNLZMA + depends on UNLZMA help This option reduces decompression time by about 33% at the cost of a 2K bigger binary. -config CONFIG_UNZIP +config UNZIP bool "unzip" default n help @@ -254,31 +254,31 @@ config CONFIG_UNZIP directory of your choice. comment "Common options for cpio and tar" - depends on CONFIG_CPIO || CONFIG_TAR + depends on CPIO || TAR -config CONFIG_FEATURE_UNARCHIVE_TAPE +config FEATURE_UNARCHIVE_TAPE bool "Enable tape drive support" default n - depends on CONFIG_CPIO || CONFIG_TAR + depends on CPIO || TAR help I don't think this is needed anymore. comment "Common options for dpkg and dpkg_deb" - depends on CONFIG_DPKG || CONFIG_DPKG_DEB + depends on DPKG || DPKG_DEB -config CONFIG_FEATURE_DEB_TAR_GZ +config FEATURE_DEB_TAR_GZ bool "gzip debian packages (normal)" - default y if CONFIG_DPKG || CONFIG_DPKG_DEB - depends on CONFIG_DPKG || CONFIG_DPKG_DEB + default y if DPKG || DPKG_DEB + depends on DPKG || DPKG_DEB help This is the default compression method inside the debian ar file. If you want compatibility with standard .deb's you should say yes here. -config CONFIG_FEATURE_DEB_TAR_BZ2 +config FEATURE_DEB_TAR_BZ2 bool "bzip2 debian packages" default n - depends on CONFIG_DPKG || CONFIG_DPKG_DEB + depends on DPKG || DPKG_DEB help This allows dpkg and dpkg-deb to extract deb's that are compressed internally with bzip2 instead of gzip. @@ -286,10 +286,10 @@ config CONFIG_FEATURE_DEB_TAR_BZ2 You only want this if you are creating your own custom debian packages that use an internal control.tar.bz2 or data.tar.bz2. -config CONFIG_FEATURE_DEB_TAR_LZMA +config FEATURE_DEB_TAR_LZMA bool "lzma debian packages" default n - depends on CONFIG_DPKG || CONFIG_DPKG_DEB + depends on DPKG || DPKG_DEB help This allows dpkg and dpkg-deb to extract deb's that are compressed internally with lzma instead of gzip. diff --git a/archival/Kbuild b/archival/Kbuild new file mode 100644 index 000000000..f85e0c2a7 --- /dev/null +++ b/archival/Kbuild @@ -0,0 +1,22 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +libs-y += libunarchive/ + +lib-y:= +lib-$(CONFIG_AR) += ar.o +lib-$(CONFIG_BUNZIP2) += bunzip2.o +lib-$(CONFIG_UNLZMA) += unlzma.o +lib-$(CONFIG_CPIO) += cpio.o +lib-$(CONFIG_DPKG) += dpkg.o +lib-$(CONFIG_DPKG_DEB) += dpkg_deb.o +lib-$(CONFIG_GUNZIP) += gunzip.o +lib-$(CONFIG_GZIP) += gzip.o +lib-$(CONFIG_RPM2CPIO) += rpm2cpio.o +lib-$(CONFIG_RPM) += rpm.o +lib-$(CONFIG_TAR) += tar.o +lib-$(CONFIG_UNCOMPRESS) += uncompress.o +lib-$(CONFIG_UNZIP) += unzip.o diff --git a/archival/Makefile b/archival/Makefile deleted file mode 100644 index 66da4afc1..000000000 --- a/archival/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -ARCHIVAL_DIR:=./ -srcdir=$(top_srcdir)/archival -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include $(srcdir)/Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/archival/Makefile.in b/archival/Makefile.in deleted file mode 100644 index 276ef4127..000000000 --- a/archival/Makefile.in +++ /dev/null @@ -1,41 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ARCHIVAL_AR:=archival.a -ifndef $(ARCHIVAL_DIR) -ARCHIVAL_DIR:=$(top_builddir)/archival/ -endif -srcdir=$(top_srcdir)/archival - -ARCHIVAL-y:= -ARCHIVAL-$(CONFIG_AR) += ar.o -ARCHIVAL-$(CONFIG_BUNZIP2) += bunzip2.o -ARCHIVAL-$(CONFIG_UNLZMA) += unlzma.o -ARCHIVAL-$(CONFIG_CPIO) += cpio.o -ARCHIVAL-$(CONFIG_DPKG) += dpkg.o -ARCHIVAL-$(CONFIG_DPKG_DEB) += dpkg_deb.o -ARCHIVAL-$(CONFIG_GUNZIP) += gunzip.o -ARCHIVAL-$(CONFIG_GZIP) += gzip.o -ARCHIVAL-$(CONFIG_RPM2CPIO) += rpm2cpio.o -ARCHIVAL-$(CONFIG_RPM) += rpm.o -ARCHIVAL-$(CONFIG_TAR) += tar.o -ARCHIVAL-$(CONFIG_UNCOMPRESS) += uncompress.o -ARCHIVAL-$(CONFIG_UNZIP) += unzip.o - -ifneq ($(strip $(ARCHIVAL-y)),) -libraries-y+=$(ARCHIVAL_DIR)$(ARCHIVAL_AR) -endif - -ARCHIVAL_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(ARCHIVAL-y)) -ARCHIVAL_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(ARCHIVAL_SRC-y) -APPLET_SRC-a+=$(ARCHIVAL_SRC-a) - -$(ARCHIVAL_DIR)$(ARCHIVAL_AR): $(patsubst %,$(ARCHIVAL_DIR)%, $(ARCHIVAL-y)) - $(do_ar) - -$(ARCHIVAL_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/archival/libunarchive/Kbuild b/archival/libunarchive/Kbuild new file mode 100644 index 000000000..c5f1bfbfe --- /dev/null +++ b/archival/libunarchive/Kbuild @@ -0,0 +1,59 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2004 by Erik Andersen +# +# Licensed under the GPL v2 or later, see the file LICENSE in this tarball. + +lib-y:= \ +\ + data_skip.o \ + data_extract_all.o \ + data_extract_to_stdout.o \ + data_extract_to_buffer.o \ +\ + filter_accept_all.o \ + filter_accept_list.o \ + filter_accept_reject_list.o \ +\ + header_skip.o \ + header_list.o \ + header_verbose_list.o \ +\ + archive_xread_all_eof.o \ +\ + seek_by_char.o \ + seek_by_jump.o \ +\ + data_align.o \ + find_list_entry.o \ + open_transformer.o \ + init_handle.o + +GUNZIP_FILES:= check_header_gzip.o decompress_unzip.o +DPKG_FILES:= \ + get_header_ar.o \ + unpack_ar_archive.o \ + get_header_tar.o \ + filter_accept_list_reassign.o + +lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o +lib-$(CONFIG_BUNZIP2) += decompress_bunzip2.o +lib-$(CONFIG_UNLZMA) += decompress_unlzma.o +lib-$(CONFIG_CPIO) += get_header_cpio.o +lib-$(CONFIG_DPKG) += $(DPKG_FILES) +lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES) +lib-$(CONFIG_FEATURE_DEB_TAR_GZ) += $(GUNZIP_FILES) get_header_tar_gz.o +lib-$(CONFIG_FEATURE_DEB_TAR_BZ2) += decompress_bunzip2.o get_header_tar_bz2.o +lib-$(CONFIG_FEATURE_DEB_TAR_LZMA) += decompress_unlzma.o get_header_tar_lzma.o +lib-$(CONFIG_GUNZIP) += $(GUNZIP_FILES) +lib-$(CONFIG_FEATURE_GUNZIP_UNCOMPRESS) += decompress_uncompress.o +lib-$(CONFIG_RPM2CPIO) += $(GUNZIP_FILES) get_header_cpio.o +lib-$(CONFIG_RPM) += $(GUNZIP_FILES) get_header_cpio.o +lib-$(CONFIG_TAR) += get_header_tar.o +lib-$(CONFIG_FEATURE_TAR_BZIP2) += decompress_bunzip2.o get_header_tar_bz2.o +lib-$(CONFIG_FEATURE_TAR_LZMA) += decompress_unlzma.o get_header_tar_lzma.o +lib-$(CONFIG_FEATURE_TAR_GZIP) += $(GUNZIP_FILES) get_header_tar_gz.o +lib-$(CONFIG_FEATURE_TAR_COMPRESS) += decompress_uncompress.o +lib-$(CONFIG_UNCOMPRESS) += decompress_uncompress.o +lib-$(CONFIG_UNZIP) += $(GUNZIP_FILES) +lib-$(CONFIG_FEATURE_COMPRESS_USAGE) += decompress_bunzip2.o diff --git a/archival/libunarchive/Makefile b/archival/libunarchive/Makefile deleted file mode 100644 index 9ab1cac81..000000000 --- a/archival/libunarchive/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2004 by Erik Andersen -# -# 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 -# - -ifndef top_srcdir -top_srcdir=../.. -endif -ifndef top_builddir -top_builddir=../.. -endif -srcdir=$(top_srcdir)/archival/libunarchive -LIBUNARCHIVE_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include $(srcdir)/Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/archival/libunarchive/Makefile.in b/archival/libunarchive/Makefile.in deleted file mode 100644 index 46c50f81d..000000000 --- a/archival/libunarchive/Makefile.in +++ /dev/null @@ -1,83 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2004 by Erik Andersen -# -# Licensed under the GPL v2 or later, see the file LICENSE in this tarball. - -LIBUNARCHIVE_AR:=libunarchive.a -ifndef $(LIBUNARCHIVE_DIR) -LIBUNARCHIVE_DIR:=$(top_builddir)/archival/libunarchive -endif -srcdir=$(top_srcdir)/archival/libunarchive - -LIBUNARCHIVE-obj:=$(LIBUNARCHIVE_DIR)/$(LIBUNARCHIVE_AR) - -libraries-y+=$(LIBUNARCHIVE-obj) - -LIBUNARCHIVE-y:= \ -\ - data_skip.o \ - data_extract_all.o \ - data_extract_to_stdout.o \ - data_extract_to_buffer.o \ -\ - filter_accept_all.o \ - filter_accept_list.o \ - filter_accept_reject_list.o \ -\ - header_skip.o \ - header_list.o \ - header_verbose_list.o \ -\ - archive_xread_all_eof.o \ -\ - seek_by_char.o \ - seek_by_jump.o \ -\ - data_align.o \ - find_list_entry.o \ - open_transformer.o \ - init_handle.o - -GUNZIP_FILES:= check_header_gzip.o decompress_unzip.o -DPKG_FILES:= \ - get_header_ar.o \ - unpack_ar_archive.o \ - get_header_tar.o \ - filter_accept_list_reassign.o - -LIBUNARCHIVE-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o -LIBUNARCHIVE-$(CONFIG_BUNZIP2) += decompress_bunzip2.o -LIBUNARCHIVE-$(CONFIG_UNLZMA) += decompress_unlzma.o -LIBUNARCHIVE-$(CONFIG_CPIO) += get_header_cpio.o -LIBUNARCHIVE-$(CONFIG_DPKG) += $(DPKG_FILES) -LIBUNARCHIVE-$(CONFIG_DPKG_DEB) += $(DPKG_FILES) -LIBUNARCHIVE-$(CONFIG_FEATURE_DEB_TAR_GZ) += $(GUNZIP_FILES) get_header_tar_gz.o -LIBUNARCHIVE-$(CONFIG_FEATURE_DEB_TAR_BZ2) += decompress_bunzip2.o get_header_tar_bz2.o -LIBUNARCHIVE-$(CONFIG_FEATURE_DEB_TAR_LZMA) += decompress_unlzma.o get_header_tar_lzma.o -LIBUNARCHIVE-$(CONFIG_GUNZIP) += $(GUNZIP_FILES) -LIBUNARCHIVE-$(CONFIG_FEATURE_GUNZIP_UNCOMPRESS) += decompress_uncompress.o -LIBUNARCHIVE-$(CONFIG_RPM2CPIO) += $(GUNZIP_FILES) get_header_cpio.o -LIBUNARCHIVE-$(CONFIG_RPM) += $(GUNZIP_FILES) get_header_cpio.o -LIBUNARCHIVE-$(CONFIG_TAR) += get_header_tar.o -LIBUNARCHIVE-$(CONFIG_FEATURE_TAR_BZIP2) += decompress_bunzip2.o get_header_tar_bz2.o -LIBUNARCHIVE-$(CONFIG_FEATURE_TAR_LZMA) += decompress_unlzma.o get_header_tar_lzma.o -LIBUNARCHIVE-$(CONFIG_FEATURE_TAR_GZIP) += $(GUNZIP_FILES) get_header_tar_gz.o -LIBUNARCHIVE-$(CONFIG_FEATURE_TAR_COMPRESS) += decompress_uncompress.o -LIBUNARCHIVE-$(CONFIG_UNCOMPRESS) += decompress_uncompress.o -LIBUNARCHIVE-$(CONFIG_UNZIP) += $(GUNZIP_FILES) -LIBUNARCHIVE-$(CONFIG_FEATURE_COMPRESS_USAGE) += decompress_bunzip2.o - - -LIBUNARCHIVE-y:=$(sort $(LIBUNARCHIVE-y)) - -LIBUNARCHIVE_SRC-y:=$(patsubst %,$(srcdir)/%,$(subst .o,.c,$(LIBUNARCHIVE-y))) -LIBUNARCHIVE_SRC-a:=$(wildcard $(srcdir)/*.c) -LIBRARY_SRC-y+=$(LIBUNARCHIVE_SRC-y) -LIBRARY_SRC-a+=$(LIBUNARCHIVE_SRC-a) - -$(LIBUNARCHIVE_DIR)/$(LIBUNARCHIVE_AR): $(patsubst %,$(LIBUNARCHIVE_DIR)/%,$(LIBUNARCHIVE-y)) - $(do_ar) - -$(LIBUNARCHIVE_DIR)/%.o: $(srcdir)/%.c - $(compile.c) diff --git a/console-tools/Config.in b/console-tools/Config.in index ec2273c35..f1dbac531 100644 --- a/console-tools/Config.in +++ b/console-tools/Config.in @@ -5,81 +5,81 @@ menu "Console Utilities" -config CONFIG_CHVT +config CHVT bool "chvt" default n help This program is used to change to another terminal. Example: chvt 4 (change to terminal /dev/tty4) -config CONFIG_CLEAR +config CLEAR bool "clear" default n help This program clears the terminal screen. -config CONFIG_DEALLOCVT +config DEALLOCVT bool "deallocvt" default n help This program deallocates unused virtual consoles. -config CONFIG_DUMPKMAP +config DUMPKMAP bool "dumpkmap" default n help This program dumps the kernel's keyboard translation table to stdout, in binary format. You can then use loadkmap to load it. -config CONFIG_LOADFONT +config LOADFONT bool "loadfont" default n help This program loads a console font from standard input. -config CONFIG_LOADKMAP +config LOADKMAP bool "loadkmap" default n help This program loads a keyboard translation table from standard input. -config CONFIG_OPENVT +config OPENVT bool "openvt" default n help This program is used to start a command on an unused virtual terminal. -config CONFIG_RESET +config RESET bool "reset" default n help This program is used to reset the terminal screen, if it gets messed up. -config CONFIG_SETCONSOLE +config SETCONSOLE bool "setconsole" default n help This program redirects the system console to another device, like the current tty while logged in via telnet. -config CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS +config FEATURE_SETCONSOLE_LONG_OPTIONS bool "Enable long options" default n - depends on CONFIG_SET_CONSOLE && CONFIG_GETOPT_LONG + depends on SET_CONSOLE && GETOPT_LONG help Support long options for the setconsole applet. -config CONFIG_SETKEYCODES +config SETKEYCODES bool "setkeycodes" default n help This program loads entries into the kernel's scancode-to-keycode map, allowing unusual keyboards to generate usable keycodes. -config CONFIG_SETLOGCONS +config SETLOGCONS bool "setlogcons" default n help diff --git a/console-tools/Kbuild b/console-tools/Kbuild new file mode 100644 index 000000000..8e377c559 --- /dev/null +++ b/console-tools/Kbuild @@ -0,0 +1,18 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_CHVT) += chvt.o +lib-$(CONFIG_CLEAR) += clear.o +lib-$(CONFIG_DEALLOCVT) += deallocvt.o +lib-$(CONFIG_DUMPKMAP) += dumpkmap.o +lib-$(CONFIG_SETCONSOLE) += setconsole.o +lib-$(CONFIG_LOADFONT) += loadfont.o +lib-$(CONFIG_LOADKMAP) += loadkmap.o +lib-$(CONFIG_OPENVT) += openvt.o +lib-$(CONFIG_RESET) += reset.o +lib-$(CONFIG_SETKEYCODES) += setkeycodes.o +lib-$(CONFIG_SETLOGCONS) += setlogcons.o diff --git a/console-tools/Makefile b/console-tools/Makefile deleted file mode 100644 index 87a242b51..000000000 --- a/console-tools/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/console/tools -CONSOLETOOLS_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include $(srcdir)/Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/console-tools/Makefile.in b/console-tools/Makefile.in deleted file mode 100644 index 437bcd0ec..000000000 --- a/console-tools/Makefile.in +++ /dev/null @@ -1,38 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -CONSOLETOOLS_AR:=console-tools.a -ifndef $(CONSOLETOOLS_DIR) -CONSOLETOOLS_DIR:=$(top_builddir)/console-tools/ -endif -srcdir=$(top_srcdir)/console-tools - -CONSOLETOOLS-y:= -CONSOLETOOLS-$(CONFIG_CHVT) += chvt.o -CONSOLETOOLS-$(CONFIG_CLEAR) += clear.o -CONSOLETOOLS-$(CONFIG_DEALLOCVT) += deallocvt.o -CONSOLETOOLS-$(CONFIG_DUMPKMAP) += dumpkmap.o -CONSOLETOOLS-$(CONFIG_SETCONSOLE) += setconsole.o -CONSOLETOOLS-$(CONFIG_LOADFONT) += loadfont.o -CONSOLETOOLS-$(CONFIG_LOADKMAP) += loadkmap.o -CONSOLETOOLS-$(CONFIG_OPENVT) += openvt.o -CONSOLETOOLS-$(CONFIG_RESET) += reset.o -CONSOLETOOLS-$(CONFIG_SETKEYCODES) += setkeycodes.o -CONSOLETOOLS-$(CONFIG_SETLOGCONS) += setlogcons.o - -ifneq ($(strip $(CONSOLETOOLS-y)),) -libraries-y+=$(CONSOLETOOLS_DIR)$(CONSOLETOOLS_AR) -endif -CONSOLETOOLS_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(CONSOLETOOLS-y)) -CONSOLETOOLS_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(CONSOLETOOLS_SRC-y) -APPLET_SRC-a+=$(CONSOLETOOLS_SRC-a) - -$(CONSOLETOOLS_DIR)$(CONSOLETOOLS_AR): $(patsubst %,$(CONSOLETOOLS_DIR)%, $(CONSOLETOOLS-y)) - $(do_ar) - -$(CONSOLETOOLS_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/coreutils/Config.in b/coreutils/Config.in index 6598a8d9c..000f3a8af 100644 --- a/coreutils/Config.in +++ b/coreutils/Config.in @@ -5,7 +5,7 @@ menu "Coreutils" -config CONFIG_BASENAME +config BASENAME bool "basename" default n help @@ -13,101 +13,101 @@ config CONFIG_BASENAME leaving just the filename itself. Enable this option if you wish to enable the 'basename' utility. -config CONFIG_CAL +config CAL bool "cal" default n help cal is used to display a monthly calender. -config CONFIG_CAT +config CAT bool "cat" default n help cat is used to concatenate files and print them to the standard output. Enable this option if you wish to enable the 'cat' utility. -config CONFIG_CATV +config CATV bool "catv" default n help Display nonprinting characters as escape sequences (like some implementations' cat -v option). -config CONFIG_CHGRP +config CHGRP bool "chgrp" default n help chgrp is used to change the group ownership of files. -config CONFIG_CHMOD +config CHMOD bool "chmod" default n help chmod is used to change the access permission of files. -config CONFIG_CHOWN +config CHOWN bool "chown" default n help chown is used to change the user and/or group ownership of files. -config CONFIG_CHROOT +config CHROOT bool "chroot" default n help chroot is used to change the root directory and run a command. The default command is `/bin/sh'. -config CONFIG_CKSUM +config CKSUM bool "cksum" default n help cksum is used to calculate the CRC32 checksum of a file. -config CONFIG_CMP +config CMP bool "cmp" default n help cmp is used to compare two files and returns the result to standard output. -config CONFIG_COMM +config COMM bool "comm" default n help comm is used to compare two files line by line and return a three-column output. -config CONFIG_CP +config CP bool "cp" default n help cp is used to copy files and directories. -config CONFIG_CUT +config CUT bool "cut" default n help cut is used to print selected parts of lines from each file to stdout. -config CONFIG_DATE +config DATE bool "date" default n help date is used to set the system date or display the current time in the given format. -config CONFIG_FEATURE_DATE_ISOFMT +config FEATURE_DATE_ISOFMT bool "Enable ISO date format output (-I)" default y - depends on CONFIG_DATE + depends on DATE help Enable option (-I) to output an ISO-8601 compliant date/time string. -config CONFIG_DD +config DD bool "dd" default n help @@ -115,10 +115,10 @@ config CONFIG_DD by default) using specific input and output blocksizes, while optionally performing conversions on it. -config CONFIG_FEATURE_DD_SIGNAL_HANDLING +config FEATURE_DD_SIGNAL_HANDLING bool "Enable DD signal handling for status reporting" default y - depends on CONFIG_DD + depends on DD help sending a SIGUSR1 signal to a running `dd' process makes it print to standard error the number of records read and written @@ -127,22 +127,22 @@ config CONFIG_FEATURE_DD_SIGNAL_HANDLING $ dd if=/dev/zero of=/dev/null& pid=$! $ kill -USR1 $pid; sleep 1; kill $pid 10899206+0 records in 10899206+0 records out -config CONFIG_FEATURE_DD_IBS_OBS +config FEATURE_DD_IBS_OBS bool "Enable ibs, obs and conv options" default n - depends on CONFIG_DD + depends on DD help Enables support for writing a certain number of bytes in and out, at a time, and performing conversions on the data stream. -config CONFIG_DF +config DF bool "df" default n help df reports the amount of disk space used and available on filesystems. -config CONFIG_DIFF +config DIFF bool "diff" default n help @@ -150,81 +150,81 @@ config CONFIG_DIFF differences between them in a form that can be given to the patch command. -config CONFIG_FEATURE_DIFF_BINARY +config FEATURE_DIFF_BINARY bool "Enable checks for binary files" default y - depends on CONFIG_DIFF + depends on DIFF help This option enables support for checking for binary files before a comparison is carried out. -config CONFIG_FEATURE_DIFF_DIR +config FEATURE_DIFF_DIR bool "Enable directory support" default y - depends on CONFIG_DIFF + depends on DIFF help This option enables support for directory and subdirectory comparison. -config CONFIG_FEATURE_DIFF_MINIMAL +config FEATURE_DIFF_MINIMAL bool "Enable -d option to find smaller sets of changes" default n - depends on CONFIG_DIFF + depends on DIFF help Enabling this option allows the use of -d to make diff try hard to find the smallest possible set of changes. -config CONFIG_DIRNAME +config DIRNAME bool "dirname" default n help dirname is used to strip a non-directory suffix from a file name. -config CONFIG_DOS2UNIX +config DOS2UNIX bool "dos2unix/unix2dos" default n help dos2unix is used to convert a text file from DOS format to UNIX format, and vice versa. -config CONFIG_UNIX2DOS +config UNIX2DOS bool default y - depends on CONFIG_DOS2UNIX + depends on DOS2UNIX help unix2dos is used to convert a text file from UNIX format to DOS format, and vice versa. -config CONFIG_DU +config DU bool "du (default blocksize of 512 bytes)" default n help du is used to report the amount of disk space used for specified files. -config CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K +config FEATURE_DU_DEFAULT_BLOCKSIZE_1K bool "Use a default blocksize of 1024 bytes (1K)" default y - depends on CONFIG_DU + depends on DU help Use a blocksize of (1K) instead of the default 512b. -config CONFIG_ECHO +config ECHO bool "echo (basic SuSv3 version taking no options)" default n help echo is used to print a specified string to stdout. # this entry also appears in shell/Config.in, next to the echo builtin -config CONFIG_FEATURE_FANCY_ECHO +config FEATURE_FANCY_ECHO bool "Enable echo options (-n and -e)" default y - depends on CONFIG_ECHO + depends on ECHO help This adds options (-n and -e) to echo. -config CONFIG_ENV +config ENV bool "env" default n help @@ -232,158 +232,158 @@ config CONFIG_ENV a command; without options it displays the current environment. -config CONFIG_FEATURE_ENV_LONG_OPTIONS +config FEATURE_ENV_LONG_OPTIONS bool "Enable long options" default n - depends on CONFIG_ENV && CONFIG_GETOPT_LONG + depends on ENV && GETOPT_LONG help Support long options for the env applet. -config CONFIG_EXPR +config EXPR bool "expr" default n help expr is used to calculate numbers and print the result to standard output. -config CONFIG_EXPR_MATH_SUPPORT_64 +config EXPR_MATH_SUPPORT_64 bool "Extend Posix numbers support to 64 bit" default n - depends on CONFIG_EXPR + depends on EXPR help Enable 64-bit math support in the expr applet. This will make the applet slightly larger, but will allow computation with very large numbers. -config CONFIG_FALSE +config FALSE bool "false" default n help false returns an exit code of FALSE (1). -config CONFIG_FOLD +config FOLD bool "fold" default n help Wrap text to fit a specific width. -config CONFIG_HEAD +config HEAD bool "head" default n help head is used to print the first specified number of lines from files. -config CONFIG_FEATURE_FANCY_HEAD +config FEATURE_FANCY_HEAD bool "Enable head options (-c, -q, and -v)" default n - depends on CONFIG_HEAD + depends on HEAD help This enables the head options (-c, -q, and -v). -config CONFIG_HOSTID +config HOSTID bool "hostid" default n help hostid prints the numeric identifier (in hexadecimal) for the current host. -config CONFIG_ID +config ID bool "id" default n help id displays the current user and group ID names. -config CONFIG_INSTALL +config INSTALL bool "install" default n help Copy files and set attributes. -config CONFIG_FEATURE_INSTALL_LONG_OPTIONS +config FEATURE_INSTALL_LONG_OPTIONS bool "Enable long options" default n - depends on CONFIG_INSTALL && CONFIG_GETOPT_LONG + depends on INSTALL && GETOPT_LONG help Support long options for the install applet. -config CONFIG_LENGTH +config LENGTH bool "length" default n help length is used to print out the length of a specified string. -config CONFIG_LN +config LN bool "ln" default n help ln is used to create hard or soft links between files. -config CONFIG_LOGNAME +config LOGNAME bool "logname" default n help logname is used to print the current user's login name. -config CONFIG_LS +config LS bool "ls" default n help ls is used to list the contents of directories. -config CONFIG_FEATURE_LS_FILETYPES +config FEATURE_LS_FILETYPES bool "Enable filetyping options (-p and -F)" default y - depends on CONFIG_LS + depends on LS help Enable the ls options (-p and -F). -config CONFIG_FEATURE_LS_FOLLOWLINKS +config FEATURE_LS_FOLLOWLINKS bool "Enable symlinks dereferencing (-L)" default y - depends on CONFIG_LS + depends on LS help Enable the ls option (-L). -config CONFIG_FEATURE_LS_RECURSIVE +config FEATURE_LS_RECURSIVE bool "Enable recursion (-R)" default y - depends on CONFIG_LS + depends on LS help Enable the ls option (-R). -config CONFIG_FEATURE_LS_SORTFILES +config FEATURE_LS_SORTFILES bool "Sort the file names" default y - depends on CONFIG_LS + depends on LS help Allow ls to sort file names alphabetically. -config CONFIG_FEATURE_LS_TIMESTAMPS +config FEATURE_LS_TIMESTAMPS bool "Show file timestamps" default y - depends on CONFIG_LS + depends on LS help Allow ls to display timestamps for files. -config CONFIG_FEATURE_LS_USERNAME +config FEATURE_LS_USERNAME bool "Show username/groupnames" default y - depends on CONFIG_LS + depends on LS help Allow ls to display username/groupname for files. -config CONFIG_FEATURE_LS_COLOR +config FEATURE_LS_COLOR bool "Allow use of color to identify file types" default y - depends on CONFIG_LS && CONFIG_GETOPT_LONG + depends on LS && GETOPT_LONG help This enables the --color option to ls. -config CONFIG_FEATURE_LS_COLOR_IS_DEFAULT +config FEATURE_LS_COLOR_IS_DEFAULT bool "Produce colored ls output by default" default n - depends on CONFIG_FEATURE_LS_COLOR + depends on FEATURE_LS_COLOR help Saying yes here will turn coloring on by default, even if no "--color" option is given to the ls command. @@ -391,143 +391,143 @@ config CONFIG_FEATURE_LS_COLOR_IS_DEFAULT configurable, and the output may not be legible on many output screens. -config CONFIG_MD5SUM +config MD5SUM bool "md5sum" default n help md5sum is used to print or check MD5 checksums. -config CONFIG_MKDIR +config MKDIR bool "mkdir" default n help mkdir is used to create directories with the specified names. -config CONFIG_FEATURE_MKDIR_LONG_OPTIONS +config FEATURE_MKDIR_LONG_OPTIONS bool "Enable long options" default n - depends on CONFIG_MKDIR && CONFIG_GETOPT_LONG + depends on MKDIR && GETOPT_LONG help Support long options for the mkdir applet. -config CONFIG_MKFIFO +config MKFIFO bool "mkfifo" default n help mkfifo is used to create FIFOs (named pipes). The `mknod' program can also create FIFOs. -config CONFIG_MKNOD +config MKNOD bool "mknod" default n help mknod is used to create FIFOs or block/character special files with the specified names. -config CONFIG_MV +config MV bool "mv" default n help mv is used to move or rename files or directories. -config CONFIG_FEATURE_MV_LONG_OPTIONS +config FEATURE_MV_LONG_OPTIONS bool "Enable long options" default n - depends on CONFIG_MV && CONFIG_GETOPT_LONG + depends on MV && GETOPT_LONG help Support long options for the mv applet. -config CONFIG_NICE +config NICE bool "nice" default n help nice runs a program with modified scheduling priority. -config CONFIG_NOHUP +config NOHUP bool "nohup" default n help run a command immune to hangups, with output to a non-tty. -config CONFIG_OD +config OD bool "od" default n help od is used to dump binary files in octal and other formats. -config CONFIG_PRINTENV +config PRINTENV bool "printenv" default n help printenv is used to print all or part of environment. -config CONFIG_PRINTF +config PRINTF bool "printf" default n help printf is used to format and print specified strings. It's similar to `echo' except it has more options. -config CONFIG_PWD +config PWD bool "pwd" default n help pwd is used to print the current directory. -config CONFIG_REALPATH +config REALPATH bool "realpath" default n help Return the canonicalized absolute pathname. This isn't provided by GNU shellutils, but where else does it belong. -config CONFIG_RM +config RM bool "rm" default n help rm is used to remove files or directories. -config CONFIG_RMDIR +config RMDIR bool "rmdir" default n help rmdir is used to remove empty directories. -config CONFIG_SEQ +config SEQ bool "seq" default n help print a sequence of numbers -config CONFIG_SHA1SUM +config SHA1SUM bool "sha1sum" default n help Compute and check SHA1 message digest -config CONFIG_SLEEP +config SLEEP bool "sleep (single integer arg with no suffix)" default n help sleep is used to pause for a specified number of seconds, -config CONFIG_FEATURE_FANCY_SLEEP +config FEATURE_FANCY_SLEEP bool "Enable multiple integer args and optional time suffixes" default n - depends on CONFIG_SLEEP + depends on SLEEP help Allow sleep to pause for specified minutes, hours, and days. -config CONFIG_SORT +config SORT bool "sort" default n help sort is used to sort lines of text in specified files. -config CONFIG_FEATURE_SORT_BIG +config FEATURE_SORT_BIG bool "full SuSv3 compliant sort (Support -ktcsbdfiozgM)" default y - depends on CONFIG_SORT + depends on SORT help Without this, sort only supports -r, -u, and an integer version of -n. Selecting this adds sort keys, floating point support, and @@ -536,69 +536,69 @@ config CONFIG_FEATURE_SORT_BIG The SuSv3 sort standard is available at: http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html -config CONFIG_STAT +config STAT bool "stat" default n help display file or filesystem status. -config CONFIG_FEATURE_STAT_FORMAT +config FEATURE_STAT_FORMAT bool "Enable custom formats (-c)" default n - depends on CONFIG_STAT + depends on STAT help Without this, stat will not support the '-c format' option where users can pass a custom format string for output. This adds about 7k to a nonstatic build on amd64. -config CONFIG_STTY +config STTY bool "stty" default n help stty is used to change and print terminal line settings. -config CONFIG_SUM +config SUM bool "sum" default n help checksum and count the blocks in a file -config CONFIG_SYNC +config SYNC bool "sync" default n help sync is used to flush filesystem buffers. -config CONFIG_TAIL +config TAIL bool "tail" default n help tail is used to print the last specified number of lines from files. -config CONFIG_FEATURE_FANCY_TAIL +config FEATURE_FANCY_TAIL bool "Enable extra tail options (-q, -s, and -v)" default y - depends on CONFIG_TAIL + depends on TAIL help The options (-q, -s, and -v) are provided by GNU tail, but are not specific in the SUSv3 standard. -config CONFIG_TEE +config TEE bool "tee" default n help tee is used to read from standard input and write to standard output and files. -config CONFIG_FEATURE_TEE_USE_BLOCK_IO +config FEATURE_TEE_USE_BLOCK_IO bool "Enable block i/o (larger/faster) instead of byte i/o." default n - depends on CONFIG_TEE + depends on TEE help Enable this option for a faster tee, at expense of size. -config CONFIG_TEST +config TEST bool "test" default n help @@ -606,39 +606,39 @@ config CONFIG_TEST returning an appropriate exit code. The bash shell has test built in, ash can build it in optionally. -config CONFIG_FEATURE_TEST_64 +config FEATURE_TEST_64 bool "Extend test to 64 bit" default n - depends on CONFIG_TEST + depends on TEST help Enable 64-bit support in test. -config CONFIG_TOUCH +config TOUCH bool "touch" default n help touch is used to create or change the access and/or modification timestamp of specified files. -config CONFIG_TR +config TR bool "tr" default n help tr is used to squeeze, and/or delete characters from standard input, writing to standard output. -config CONFIG_FEATURE_TR_CLASSES +config FEATURE_TR_CLASSES bool "Enable character classes (such as [:upper:])" default n - depends on CONFIG_TR + depends on TR help Enable character classes, enabling commands such as: tr [:upper:] [:lower:] to convert input into lowercase. -config CONFIG_FEATURE_TR_EQUIV +config FEATURE_TR_EQUIV bool "Enable equivalence classes" default n - depends on CONFIG_TR + depends on TR help Enable equivalence classes, which essentially add the enclosed character to the current set. For instance, tr [=a=] xyz would @@ -646,86 +646,86 @@ config CONFIG_FEATURE_TR_EQUIV useful for cases when no other way of expressing a character is possible. -config CONFIG_TRUE +config TRUE bool "true" default n help true returns an exit code of TRUE (0). -config CONFIG_TTY +config TTY bool "tty" default n help tty is used to print the name of the current terminal to standard output. -config CONFIG_UNAME +config UNAME bool "uname" default n help uname is used to print system information. -config CONFIG_UNIQ +config UNIQ bool "uniq" default n help uniq is used to remove duplicate lines from a sorted file. -config CONFIG_USLEEP +config USLEEP bool "usleep" default n help usleep is used to pause for a specified number of microseconds. -config CONFIG_UUDECODE +config UUDECODE bool "uudecode" default n help uudecode is used to decode a uuencoded file. -config CONFIG_UUENCODE +config UUENCODE bool "uuencode" default n help uuencode is used to uuencode a file. -config CONFIG_WATCH +config WATCH bool "watch" default n - select CONFIG_DATE + select DATE help watch is used to execute a program periodically, showing output to the screen. -config CONFIG_WC +config WC bool "wc" default n help wc is used to print the number of bytes, words, and lines, in specified files. -config CONFIG_FEATURE_WC_LARGE +config FEATURE_WC_LARGE bool "Support very large files in wc" default n - depends on CONFIG_WC + depends on WC help Use "unsigned long long" in wc for count variables -config CONFIG_WHO +config WHO bool "who" default n - select CONFIG_FEATURE_UTMP + select FEATURE_UTMP help who is used to show who is logged on. -config CONFIG_WHOAMI +config WHOAMI bool "whoami" default n help whoami is used to print the username of the current user id (same as id -un). -config CONFIG_YES +config YES bool "yes" default n help @@ -733,22 +733,22 @@ config CONFIG_YES the default string `y'. comment "Common options for cp and mv" - depends on CONFIG_CP || CONFIG_MV + depends on CP || MV -config CONFIG_FEATURE_PRESERVE_HARDLINKS +config FEATURE_PRESERVE_HARDLINKS bool "Preserve hard links" default n - depends on CONFIG_CP || CONFIG_MV + depends on CP || MV help Allow cp and mv to preserve hard links. comment "Common options for ls, more and telnet" - depends on CONFIG_LS || CONFIG_MORE || CONFIG_TELNET + depends on LS || MORE || TELNET -config CONFIG_FEATURE_AUTOWIDTH +config FEATURE_AUTOWIDTH bool "Calculate terminal & column widths" default y - depends on CONFIG_LS || CONFIG_MORE || CONFIG_TELNET + depends on LS || MORE || TELNET help This option allows utilities such as 'ls', 'more' and 'telnet' to determine the width of the screen, which can allow them to @@ -757,22 +757,22 @@ config CONFIG_FEATURE_AUTOWIDTH primitive and will be unable to determine the current screen width. comment "Common options for df, du, ls" - depends on CONFIG_DF || CONFIG_DU || CONFIG_LS + depends on DF || DU || LS -config CONFIG_FEATURE_HUMAN_READABLE +config FEATURE_HUMAN_READABLE bool "Support for human readable output (example 13k, 23M, 235G)" default n - depends on CONFIG_DF || CONFIG_DU || CONFIG_LS + depends on DF || DU || LS help Allow df, du, and ls to have human readable output. comment "Common options for md5sum, sha1sum" - depends on CONFIG_MD5SUM || CONFIG_SHA1SUM + depends on MD5SUM || SHA1SUM -config CONFIG_FEATURE_MD5_SHA1_SUM_CHECK +config FEATURE_MD5_SHA1_SUM_CHECK bool "Enable -c, -s and -w options" default n - depends on CONFIG_MD5SUM || CONFIG_SHA1SUM + depends on MD5SUM || SHA1SUM help Enabling the -c options allows files to be checked against pre-calculated hash values. diff --git a/coreutils/Kbuild b/coreutils/Kbuild new file mode 100644 index 000000000..cf1718419 --- /dev/null +++ b/coreutils/Kbuild @@ -0,0 +1,81 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +libs-y += libcoreutils/ + +lib-y:= +lib-$(CONFIG_BASENAME) += basename.o +lib-$(CONFIG_CAL) += cal.o +lib-$(CONFIG_CAT) += cat.o +lib-$(CONFIG_CATV) += catv.o +lib-$(CONFIG_CHGRP) += chgrp.o +lib-$(CONFIG_CHMOD) += chmod.o +lib-$(CONFIG_CHOWN) += chown.o +lib-$(CONFIG_CHROOT) += chroot.o +lib-$(CONFIG_CKSUM) += cksum.o +lib-$(CONFIG_CMP) += cmp.o +lib-$(CONFIG_COMM) += comm.o +lib-$(CONFIG_CP) += cp.o +lib-$(CONFIG_CUT) += cut.o +lib-$(CONFIG_DATE) += date.o +lib-$(CONFIG_DD) += dd.o +lib-$(CONFIG_DF) += df.o +lib-$(CONFIG_DIFF) += diff.o +lib-$(CONFIG_DIRNAME) += dirname.o +lib-$(CONFIG_DOS2UNIX) += dos2unix.o +lib-$(CONFIG_DU) += du.o +lib-$(CONFIG_ECHO) += echo.o +lib-$(CONFIG_ENV) += env.o +lib-$(CONFIG_EXPR) += expr.o +lib-$(CONFIG_FALSE) += false.o +lib-$(CONFIG_FOLD) += fold.o +lib-$(CONFIG_HEAD) += head.o +lib-$(CONFIG_HOSTID) += hostid.o +lib-$(CONFIG_ID) += id.o +lib-$(CONFIG_INSTALL) += install.o +lib-$(CONFIG_LENGTH) += length.o +lib-$(CONFIG_LN) += ln.o +lib-$(CONFIG_LOGNAME) += logname.o +lib-$(CONFIG_LS) += ls.o +lib-$(CONFIG_MD5SUM) += md5_sha1_sum.o +lib-$(CONFIG_MKDIR) += mkdir.o +lib-$(CONFIG_MKFIFO) += mkfifo.o +lib-$(CONFIG_MKNOD) += mknod.o +lib-$(CONFIG_MV) += mv.o +lib-$(CONFIG_NICE) += nice.o +lib-$(CONFIG_NOHUP) += nohup.o +lib-$(CONFIG_OD) += od.o +lib-$(CONFIG_PRINTENV) += printenv.o +lib-$(CONFIG_PRINTF) += printf.o +lib-$(CONFIG_PWD) += pwd.o +lib-$(CONFIG_REALPATH) += realpath.o +lib-$(CONFIG_RM) += rm.o +lib-$(CONFIG_RMDIR) += rmdir.o +lib-$(CONFIG_SEQ) += seq.o +lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o +lib-$(CONFIG_SLEEP) += sleep.o +lib-$(CONFIG_SORT) += sort.o +lib-$(CONFIG_STAT) += stat.o +lib-$(CONFIG_STTY) += stty.o +lib-$(CONFIG_SUM) += sum.o +lib-$(CONFIG_SYNC) += sync.o +lib-$(CONFIG_TAIL) += tail.o +lib-$(CONFIG_TEE) += tee.o +lib-$(CONFIG_TEST) += test.o +lib-$(CONFIG_TOUCH) += touch.o +lib-$(CONFIG_TR) += tr.o +lib-$(CONFIG_TRUE) += true.o +lib-$(CONFIG_TTY) += tty.o +lib-$(CONFIG_UNAME) += uname.o +lib-$(CONFIG_UNIQ) += uniq.o +lib-$(CONFIG_USLEEP) += usleep.o +lib-$(CONFIG_UUDECODE) += uudecode.o +lib-$(CONFIG_UUENCODE) += uuencode.o +lib-$(CONFIG_WATCH) += watch.o +lib-$(CONFIG_WC) += wc.o +lib-$(CONFIG_WHO) += who.o +lib-$(CONFIG_WHOAMI) += whoami.o +lib-$(CONFIG_YES) += yes.o diff --git a/coreutils/Makefile b/coreutils/Makefile deleted file mode 100644 index c29f3a934..000000000 --- a/coreutils/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/coreutils -SHELLUTILS_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include $(srcdir)/Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/coreutils/Makefile.in b/coreutils/Makefile.in deleted file mode 100644 index 50c090f8d..000000000 --- a/coreutils/Makefile.in +++ /dev/null @@ -1,102 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -COREUTILS_AR:=coreutils.a -ifndef $(COREUTILS_DIR) -COREUTILS_DIR:=$(top_builddir)/coreutils/ -endif -srcdir=$(top_srcdir)/coreutils - -COREUTILS-y:= -COREUTILS-$(CONFIG_BASENAME) += basename.o -COREUTILS-$(CONFIG_CAL) += cal.o -COREUTILS-$(CONFIG_CAT) += cat.o -COREUTILS-$(CONFIG_CATV) += catv.o -COREUTILS-$(CONFIG_CHGRP) += chgrp.o -COREUTILS-$(CONFIG_CHMOD) += chmod.o -COREUTILS-$(CONFIG_CHOWN) += chown.o -COREUTILS-$(CONFIG_CHROOT) += chroot.o -COREUTILS-$(CONFIG_CKSUM) += cksum.o -COREUTILS-$(CONFIG_CMP) += cmp.o -COREUTILS-$(CONFIG_COMM) += comm.o -COREUTILS-$(CONFIG_CP) += cp.o -COREUTILS-$(CONFIG_CUT) += cut.o -COREUTILS-$(CONFIG_DATE) += date.o -COREUTILS-$(CONFIG_DD) += dd.o -COREUTILS-$(CONFIG_DF) += df.o -COREUTILS-$(CONFIG_DIFF) += diff.o -COREUTILS-$(CONFIG_DIRNAME) += dirname.o -COREUTILS-$(CONFIG_DOS2UNIX) += dos2unix.o -COREUTILS-$(CONFIG_DU) += du.o -COREUTILS-$(CONFIG_ECHO) += echo.o -COREUTILS-$(CONFIG_ENV) += env.o -COREUTILS-$(CONFIG_EXPR) += expr.o -COREUTILS-$(CONFIG_FALSE) += false.o -COREUTILS-$(CONFIG_FOLD) += fold.o -COREUTILS-$(CONFIG_HEAD) += head.o -COREUTILS-$(CONFIG_HOSTID) += hostid.o -COREUTILS-$(CONFIG_ID) += id.o -COREUTILS-$(CONFIG_INSTALL) += install.o -COREUTILS-$(CONFIG_LENGTH) += length.o -COREUTILS-$(CONFIG_LN) += ln.o -COREUTILS-$(CONFIG_LOGNAME) += logname.o -COREUTILS-$(CONFIG_LS) += ls.o -COREUTILS-$(CONFIG_MD5SUM) += md5_sha1_sum.o -COREUTILS-$(CONFIG_MKDIR) += mkdir.o -COREUTILS-$(CONFIG_MKFIFO) += mkfifo.o -COREUTILS-$(CONFIG_MKNOD) += mknod.o -COREUTILS-$(CONFIG_MV) += mv.o -COREUTILS-$(CONFIG_NICE) += nice.o -COREUTILS-$(CONFIG_NOHUP) += nohup.o -COREUTILS-$(CONFIG_OD) += od.o -COREUTILS-$(CONFIG_PRINTENV) += printenv.o -COREUTILS-$(CONFIG_PRINTF) += printf.o -COREUTILS-$(CONFIG_PWD) += pwd.o -COREUTILS-$(CONFIG_REALPATH) += realpath.o -COREUTILS-$(CONFIG_RM) += rm.o -COREUTILS-$(CONFIG_RMDIR) += rmdir.o -COREUTILS-$(CONFIG_SEQ) += seq.o -COREUTILS-$(CONFIG_SHA1SUM) += md5_sha1_sum.o -COREUTILS-$(CONFIG_SLEEP) += sleep.o -COREUTILS-$(CONFIG_SORT) += sort.o -COREUTILS-$(CONFIG_STAT) += stat.o -COREUTILS-$(CONFIG_STTY) += stty.o -COREUTILS-$(CONFIG_SUM) += sum.o -COREUTILS-$(CONFIG_SYNC) += sync.o -COREUTILS-$(CONFIG_TAIL) += tail.o -COREUTILS-$(CONFIG_TEE) += tee.o -COREUTILS-$(CONFIG_TEST) += test.o -COREUTILS-$(CONFIG_TOUCH) += touch.o -COREUTILS-$(CONFIG_TR) += tr.o -COREUTILS-$(CONFIG_TRUE) += true.o -COREUTILS-$(CONFIG_TTY) += tty.o -COREUTILS-$(CONFIG_UNAME) += uname.o -COREUTILS-$(CONFIG_UNIQ) += uniq.o -COREUTILS-$(CONFIG_USLEEP) += usleep.o -COREUTILS-$(CONFIG_UUDECODE) += uudecode.o -COREUTILS-$(CONFIG_UUENCODE) += uuencode.o -COREUTILS-$(CONFIG_WATCH) += watch.o -COREUTILS-$(CONFIG_WC) += wc.o -COREUTILS-$(CONFIG_WHO) += who.o -COREUTILS-$(CONFIG_WHOAMI) += whoami.o -COREUTILS-$(CONFIG_YES) += yes.o - -COREUTILS-y:=$(sort $(COREUTILS-y)) - -ifneq ($(strip $(COREUTILS-y)),) -libraries-y+=$(COREUTILS_DIR)$(COREUTILS_AR) -endif - -COREUTILS_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(COREUTILS-y)) -COREUTILS_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(COREUTILS_SRC-y) -APPLET_SRC-a+=$(COREUTILS_SRC-a) - -$(COREUTILS_DIR)$(COREUTILS_AR): $(patsubst %,$(COREUTILS_DIR)%, $(COREUTILS-y)) - $(do_ar) - -$(COREUTILS_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/coreutils/diff.c b/coreutils/diff.c index 2edcd96ca..b30aad5a7 100644 --- a/coreutils/diff.c +++ b/coreutils/diff.c @@ -1165,9 +1165,8 @@ int diff_main(int argc, char **argv) llist_t *L_arg = NULL; opt_complementary = "L::"; - cmd_flags = - getopt32(argc, argv, "abdiL:NqrsS:tTU:wu", &L_arg, &start, - &U_opt); + cmd_flags = getopt32(argc, argv, "abdiL:NqrsS:tTU:wu", + &L_arg, &start, &U_opt); if (cmd_flags & FLAG_L) { while (L_arg) { diff --git a/coreutils/id.c b/coreutils/id.c index dd825ab3c..9e49999cd 100644 --- a/coreutils/id.c +++ b/coreutils/id.c @@ -13,7 +13,6 @@ */ #include "busybox.h" -#include "pwd_.h" #include #include #include diff --git a/coreutils/libcoreutils/Kbuild b/coreutils/libcoreutils/Kbuild new file mode 100644 index 000000000..755d01f86 --- /dev/null +++ b/coreutils/libcoreutils/Kbuild @@ -0,0 +1,12 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2004 by Erik Andersen +# +# Licensed under the GPL v2 or later, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_MKFIFO) += getopt_mk_fifo_nod.o +lib-$(CONFIG_MKNOD) += getopt_mk_fifo_nod.o +lib-$(CONFIG_INSTALL) += cp_mv_stat.o +lib-$(CONFIG_CP) += cp_mv_stat.o +lib-$(CONFIG_MV) += cp_mv_stat.o diff --git a/coreutils/libcoreutils/Makefile b/coreutils/libcoreutils/Makefile deleted file mode 100644 index fabde2d0e..000000000 --- a/coreutils/libcoreutils/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2004 by Erik Andersen -# -# 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 -# - -ifndef top_srcdir -top_srcdir=../.. -endif -ifndef top_builddir -top_builddir=../.. -endif -srcdir=$(top_srcdir)/coreutils/libcoreutils -LIBCOREUTILS_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include $(srcdir)/Makefile.in - -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/coreutils/libcoreutils/Makefile.in b/coreutils/libcoreutils/Makefile.in deleted file mode 100644 index 30a38c9d9..000000000 --- a/coreutils/libcoreutils/Makefile.in +++ /dev/null @@ -1,39 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2004 by Erik Andersen -# -# Licensed under the GPL v2 or later, see the file LICENSE in this tarball. - -LIBCOREUTILS_AR:=libcoreutils.a -ifndef $(LIBCOREUTILS_DIR) -LIBCOREUTILS_DIR:=$(top_builddir)/coreutils/libcoreutils -endif -srcdir=$(top_srcdir)/coreutils/libcoreutils - -LIBCOREUTILS_ALL_SRC:= cp_mv_stat.c getopt_mk_fifo_nod.c - -LIBCOREUTILS-y:= -LIBCOREUTILS-$(CONFIG_MKFIFO) += getopt_mk_fifo_nod.o -LIBCOREUTILS-$(CONFIG_MKNOD) += getopt_mk_fifo_nod.o -LIBCOREUTILS-$(CONFIG_INSTALL) += cp_mv_stat.o -LIBCOREUTILS-$(CONFIG_CP) += cp_mv_stat.o -LIBCOREUTILS-$(CONFIG_MV) += cp_mv_stat.o - -LIBCOREUTILS-y:=$(sort $(LIBCOREUTILS-y)) - -LIBCOREUTILS_SRC-y:=$(patsubst %,$(srcdir)/%,$(subst .o,.c,$(LIBCOREUTILS-y))) -LIBCOREUTILS_SRC-a:=$(wildcard $(srcdir)/*.c) -LIBRARY_SRC-y+=$(LIBCOREUTILS_SRC-y) -LIBRARY_SRC-a+=$(LIBCOREUTILS_SRC-a) - -ifneq ($(strip $(LIBCOREUTILS-y)),) -libraries-y+=$(LIBCOREUTILS_DIR)/$(LIBCOREUTILS_AR) -endif - -LIBCOREUTILS_OBJS=$(patsubst %,$(LIBCOREUTILS_DIR)/%, $(LIBCOREUTILS-y)) - -$(LIBCOREUTILS_DIR)/$(LIBCOREUTILS_AR): $(patsubst %,$(LIBCOREUTILS_DIR)/%,$(LIBCOREUTILS-y)) - $(do_ar) - -$(LIBCOREUTILS_DIR)/%.o: $(srcdir)/%.c - $(compile.c) diff --git a/debianutils/Config.in b/debianutils/Config.in index 3dd2ef61b..3d85999ff 100644 --- a/debianutils/Config.in +++ b/debianutils/Config.in @@ -5,33 +5,33 @@ menu "Debian Utilities" -config CONFIG_MKTEMP +config MKTEMP bool "mktemp" default n help mktemp is used to create unique temporary files -config CONFIG_PIPE_PROGRESS +config PIPE_PROGRESS bool "pipe_progress" default n help Display a dot to indicate pipe activity. -config CONFIG_READLINK +config READLINK bool "readlink" default n help This program reads a symbolic link and returns the name of the file it points to -config CONFIG_FEATURE_READLINK_FOLLOW +config FEATURE_READLINK_FOLLOW bool "Enable canonicalization by following all symlinks (-f)" default n - depends on CONFIG_READLINK + depends on READLINK help Enable the readlink option (-f). -config CONFIG_RUN_PARTS +config RUN_PARTS bool "run-parts" default n help @@ -46,14 +46,14 @@ config CONFIG_RUN_PARTS Unless you know that run-parts is used in some of your scripts you can safely say N here. -config CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS +config FEATURE_RUN_PARTS_LONG_OPTIONS bool "Enable long options" default n - depends on CONFIG_RUN_PARTS && CONFIG_GETOPT_LONG + depends on RUN_PARTS && GETOPT_LONG help Support long options for the run-parts applet. -config CONFIG_START_STOP_DAEMON +config START_STOP_DAEMON bool "start-stop-daemon" default y help @@ -61,23 +61,23 @@ config CONFIG_START_STOP_DAEMON termination of system-level processes, usually the ones started during the startup of the system. -config CONFIG_FEATURE_START_STOP_DAEMON_FANCY +config FEATURE_START_STOP_DAEMON_FANCY bool "Support additional arguments" default y - depends on CONFIG_START_STOP_DAEMON + depends on START_STOP_DAEMON help Support additional arguments. -o|--oknodo ignored since we exit with 0 anyway -v|--verbose -config CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS +config FEATURE_START_STOP_DAEMON_LONG_OPTIONS bool "Enable long options" default n - depends on CONFIG_START_STOP_DAEMON && CONFIG_GETOPT_LONG + depends on START_STOP_DAEMON && GETOPT_LONG help Support long options for the start-stop-daemon applet. -config CONFIG_WHICH +config WHICH bool "which" default n help diff --git a/debianutils/Kbuild b/debianutils/Kbuild new file mode 100644 index 000000000..99df6a536 --- /dev/null +++ b/debianutils/Kbuild @@ -0,0 +1,13 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_MKTEMP) += mktemp.o +lib-$(CONFIG_PIPE_PROGRESS) += pipe_progress.o +lib-$(CONFIG_READLINK) += readlink.o +lib-$(CONFIG_RUN_PARTS) += run_parts.o +lib-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o +lib-$(CONFIG_WHICH) += which.o diff --git a/debianutils/Makefile b/debianutils/Makefile deleted file mode 100644 index 3d240b7bc..000000000 --- a/debianutils/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/debianutils -DEBIANUTILS_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include $(srcdir)/Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/debianutils/Makefile.in b/debianutils/Makefile.in deleted file mode 100644 index 2983565b8..000000000 --- a/debianutils/Makefile.in +++ /dev/null @@ -1,33 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -DEBIANUTILS_AR:=debianutils.a -ifndef $(DEBIANUTILS_DIR) -DEBIANUTILS_DIR:=$(top_builddir)/debianutils/ -endif -srcdir=$(top_srcdir)/debianutils - -DEBIANUTILS-y:= -DEBIANUTILS-$(CONFIG_MKTEMP) += mktemp.o -DEBIANUTILS-$(CONFIG_PIPE_PROGRESS) += pipe_progress.o -DEBIANUTILS-$(CONFIG_READLINK) += readlink.o -DEBIANUTILS-$(CONFIG_RUN_PARTS) += run_parts.o -DEBIANUTILS-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o -DEBIANUTILS-$(CONFIG_WHICH) += which.o - -ifneq ($(strip $(DEBIANUTILS-y)),) -libraries-y+=$(DEBIANUTILS_DIR)$(DEBIANUTILS_AR) -endif -DEBIANUTILS_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(DEBIANUTILS-y)) -DEBIANUTILS_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(DEBIANUTILS_SRC-y) -APPLET_SRC-a+=$(DEBIANUTILS_SRC-a) - -$(DEBIANUTILS_DIR)$(DEBIANUTILS_AR): $(patsubst %,$(DEBIANUTILS_DIR)%, $(DEBIANUTILS-y)) - $(do_ar) - -$(DEBIANUTILS_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/e2fsprogs/Config.in b/e2fsprogs/Config.in index 91e873e3a..0062b2fe3 100644 --- a/e2fsprogs/Config.in +++ b/e2fsprogs/Config.in @@ -5,13 +5,13 @@ menu "Linux Ext2 FS Progs" -config CONFIG_CHATTR +config CHATTR bool "chattr" default n help chattr changes the file attributes on a second extended file system. -config CONFIG_E2FSCK +config E2FSCK bool "e2fsck" default n help @@ -20,7 +20,7 @@ config CONFIG_E2FSCK The normal compat symlinks 'fsck.ext2' and 'fsck.ext3' are also provided. -config CONFIG_FSCK +config FSCK bool "fsck" default n help @@ -28,38 +28,38 @@ config CONFIG_FSCK In actuality, fsck is simply a front-end for the various file system checkers (fsck.fstype) available under Linux. -config CONFIG_LSATTR +config LSATTR bool "lsattr" default n help lsattr lists the file attributes on a second extended file system. -config CONFIG_MKE2FS +config MKE2FS bool "mke2fs" default n help mke2fs is used to create an ext2/ext3 filesystem. The normal compat symlinks 'mkfs.ext2' and 'mkfs.ext3' are also provided. -config CONFIG_TUNE2FS +config TUNE2FS bool "tune2fs" default n help tune2fs allows the system administrator to adjust various tunable filesystem parameters on Linux ext2/ext3 filesystems. -config CONFIG_E2LABEL +config E2LABEL bool "e2label" default n - depends on CONFIG_TUNE2FS + depends on TUNE2FS help e2label will display or change the filesystem label on the ext2 filesystem located on device. -config CONFIG_FINDFS +config FINDFS bool "findfs" default n - depends on CONFIG_TUNE2FS + depends on TUNE2FS help findfs will search the disks in the system looking for a filesystem which has a label matching label or a UUID equal to uuid. diff --git a/e2fsprogs/Kbuild b/e2fsprogs/Kbuild new file mode 100644 index 000000000..f35a1ae32 --- /dev/null +++ b/e2fsprogs/Kbuild @@ -0,0 +1,27 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= + +lib-$(CONFIG_CHATTR) += chattr.o +libs-$(CONFIG_CHATTR) += e2p/ + +lib-$(CONFIG_E2FSCK) += e2fsck.o util.o +libs-$(CONFIG_E2FSCK) += blkid/ ext2fs/ uuid/ + +lib-$(CONFIG_FSCK) += fsck.o util.o +libs-$(CONFIG_FSCK) += blkid/ ext2fs/ uuid/ + +lib-$(CONFIG_LSATTR) += lsattr.o +libs-$(CONFIG_LSATTR) += e2p/ + +lib-$(CONFIG_MKE2FS) += mke2fs.o util.o +libs-$(CONFIG_MKE2FS) += e2p/ blkid/ ext2fs/ uuid/ + +lib-$(CONFIG_TUNE2FS) += tune2fs.o util.o +libs-$(CONFIG_TUNE2FS) += e2p/ blkid/ ext2fs/ uuid/ + +CFLAGS += -include e2fsprogs/e2fsbb.h diff --git a/e2fsprogs/Makefile b/e2fsprogs/Makefile deleted file mode 100644 index 0efa9bb3b..000000000 --- a/e2fsprogs/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/e2fsprogs -E2FSPROGS_DIR:=./ -include $(top_builddir)/.config -include $(top_srcdir)/Rules.mak -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a */*.o $(AR_TARGET) diff --git a/e2fsprogs/Makefile.in b/e2fsprogs/Makefile.in deleted file mode 100644 index 160271686..000000000 --- a/e2fsprogs/Makefile.in +++ /dev/null @@ -1,86 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -E2FSPROGS_AR:=e2fsprogs.a - -E2FSPROGS_DIR:=$(top_builddir)/e2fsprogs -E2FSPROGS_SRC:=$(top_srcdir)/e2fsprogs - -E2FSPROGS_CFLAGS := -include $(E2FSPROGS_SRC)/e2fsbb.h - -BLKID_SRC := cache.c dev.c devname.c devno.c blkid_getsize.c \ - probe.c read.c resolve.c save.c tag.c list.c -BLKID_SRCS := $(patsubst %,blkid/%, $(BLKID_SRC)) -BLKID_OBJS := $(patsubst %.c,%.o, $(BLKID_SRCS)) - -E2P_SRC := fgetsetflags.c fgetsetversion.c pf.c iod.c mntopts.c \ - feature.c ls.c uuid.c pe.c ostype.c ps.c hashstr.c \ - parse_num.c -E2P_SRCS := $(patsubst %,e2p/%, $(E2P_SRC)) -E2P_OBJS := $(patsubst %.c,%.o, $(E2P_SRCS)) - -EXT2FS_SRC := gen_bitmap.c bitops.c ismounted.c mkjournal.c unix_io.c \ - rw_bitmaps.c initialize.c bitmaps.c block.c \ - ind_block.c inode.c freefs.c alloc_stats.c closefs.c \ - openfs.c io_manager.c finddev.c read_bb.c alloc.c badblocks.c \ - getsize.c getsectsize.c alloc_tables.c read_bb_file.c mkdir.c \ - bb_inode.c newdir.c alloc_sb.c lookup.c dirblock.c expanddir.c \ - dir_iterate.c link.c res_gdt.c icount.c get_pathname.c dblist.c \ - dirhash.c version.c flushb.c unlink.c check_desc.c valid_blk.c \ - ext_attr.c bmap.c dblist_dir.c ext2fs_inline.c swapfs.c -EXT2FS_SRCS := $(patsubst %,ext2fs/%, $(EXT2FS_SRC)) -EXT2FS_OBJS := $(patsubst %.c,%.o, $(EXT2FS_SRCS)) - -UUID_SRC := compare.c gen_uuid.c pack.c parse.c unpack.c unparse.c \ - uuid_time.c -UUID_SRCS := $(patsubst %,uuid/%, $(UUID_SRC)) -UUID_OBJS := $(patsubst %.c,%.o, $(UUID_SRCS)) - -E2FSPROGS-y:= -E2FSPROGS-$(CONFIG_CHATTR) += chattr.o $(E2P_OBJS) -E2FSPROGS-$(CONFIG_E2FSCK) += e2fsck.o util.o $(BLKID_OBJS) $(EXT2FS_OBJS) $(UUID_OBJS) -E2FSPROGS-$(CONFIG_FSCK) += fsck.o util.o $(BLKID_OBJS) $(EXT2FS_OBJS) $(UUID_OBJS) -E2FSPROGS-$(CONFIG_LSATTR) += lsattr.o $(E2P_OBJS) -E2FSPROGS-$(CONFIG_MKE2FS) += mke2fs.o util.o $(E2P_OBJS) $(BLKID_OBJS) $(EXT2FS_OBJS) $(UUID_OBJS) -E2FSPROGS-$(CONFIG_TUNE2FS) += tune2fs.o util.o $(E2P_OBJS) $(BLKID_OBJS) $(EXT2FS_OBJS) $(UUID_OBJS) - -E2FSPROGS-y:=$(sort $(E2FSPROGS-y)) - -ifneq ($(strip $(E2FSPROGS-y)),) -libraries-y+=$(E2FSPROGS_DIR)/$(E2FSPROGS_AR) -endif - -E2FSPROGS_SRC-y:=$(patsubst %.o,$(E2FSPROGS_SRC)/%.c,$(E2FSPROGS-y)) -E2FSPROGS_SRC-a:=$(wildcard $(E2FSPROGS_SRC)/*.c) $(patsubst %,$(E2FSPROGS_SRC)/%,$(BLKID_SRCS) $(E2P_SRCS) $(EXT2FS_SRCS) $(UUID_SRCS)) -APPLET_SRC-y+=$(E2FSPROGS_SRC-y) -APPLET_SRC-a+=$(E2FSPROGS_SRC-a) - -# XXX: FIXME: change .c to include their stuff relative to $(E2FSPROGS_SRC) -E2FSPROGS_TMP_KLUDGE:=$(patsubst %,-I$(E2FSPROGS_SRC)/%,blkid e2fsck e2p ext2fs uuid) - -APPLETS_DEFINE-y+=$(E2FSPROGS_CFLAGS) -I$(E2FSPROGS_SRC) $(E2FSPROGS_TMP_KLUDGE) -APPLETS_DEFINE-a+=$(E2FSPROGS_CFLAGS) -I$(E2FSPROGS_SRC) $(E2FSPROGS_TMP_KLUDGE) - -$(E2FSPROGS_DIR)/$(E2FSPROGS_AR): $(patsubst %,$(E2FSPROGS_DIR)/%, $(E2FSPROGS-y)) - $(do_ar) - -$(E2FSPROGS_DIR)/%.o: $(subst $(top_builddir),$(top_srcdir),$(E2FSPROGS_DIR)/%.c) - $(compile.c) $(E2FSPROGS_CFLAGS) - -# for building out-of-tree we need to make sure that the directories to hold -# the object tree are created -$(patsubst %,$(E2FSPROGS_DIR)/%, blkid e2fsck e2p ext2fs uuid): - @mkdir -p "$@" - -# make sure that the directories are order-only prerequisites. Otherwise we -# may have object files created after the timestamp of the directory was -# updated which would lead to spurious rebuilds (as some of the dentries -# may be older than the dir itself). -$(patsubst %,$(E2FSPROGS_DIR)/%, $(BLKID_OBJS)):|$(E2FSPROGS_DIR)/blkid -$(patsubst %,$(E2FSPROGS_DIR)/%, $(E2FSCK_OBJS)):|$(E2FSPROGS_DIR)/e2fsck -$(patsubst %,$(E2FSPROGS_DIR)/%, $(E2P_OBJS)):|$(E2FSPROGS_DIR)/e2p -$(patsubst %,$(E2FSPROGS_DIR)/%, $(EXT2FS_OBJS)):|$(E2FSPROGS_DIR)/ext2fs -$(patsubst %,$(E2FSPROGS_DIR)/%, $(UUID_OBJS)):|$(E2FSPROGS_DIR)/uuid diff --git a/e2fsprogs/blkid/Kbuild b/e2fsprogs/blkid/Kbuild new file mode 100644 index 000000000..ba0bee03d --- /dev/null +++ b/e2fsprogs/blkid/Kbuild @@ -0,0 +1,18 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-y += cache.o dev.o devname.o devno.o blkid_getsize.o \ + probe.o read.o resolve.o save.o tag.o list.o + +CFLAGS_dev.o := -include include/busybox.h +CFLAGS_devname.o := -include include/busybox.h +CFLAGS_devno.o := -include include/busybox.h +CFLAGS_blkid_getsize.o := -include include/busybox.h +CFLAGS_probe.o := -include include/busybox.h +CFLAGS_save.o := -include include/busybox.h +CFLAGS_tag.o := -include include/busybox.h +CFLAGS_list.o := -include include/busybox.h diff --git a/e2fsprogs/blkid/blkid_getsize.c b/e2fsprogs/blkid/blkid_getsize.c index 7a2133f0a..3c5ec5b76 100644 --- a/e2fsprogs/blkid/blkid_getsize.c +++ b/e2fsprogs/blkid/blkid_getsize.c @@ -14,9 +14,7 @@ #include "blkidP.h" #include -#if HAVE_UNISTD_H #include -#endif #if HAVE_ERRNO_H #include #endif diff --git a/e2fsprogs/blkid/devname.c b/e2fsprogs/blkid/devname.c index b5c1bc9a8..7606e400d 100644 --- a/e2fsprogs/blkid/devname.c +++ b/e2fsprogs/blkid/devname.c @@ -23,9 +23,7 @@ #if HAVE_SYS_TYPES_H #include #endif -#if HAVE_SYS_STAT_H #include -#endif #if HAVE_ERRNO_H #include #endif diff --git a/e2fsprogs/blkid/devno.c b/e2fsprogs/blkid/devno.c index 065761fb4..be93666be 100644 --- a/e2fsprogs/blkid/devno.c +++ b/e2fsprogs/blkid/devno.c @@ -21,9 +21,7 @@ #if HAVE_SYS_TYPES_H #include #endif -#if HAVE_SYS_STAT_H #include -#endif #include #if HAVE_ERRNO_H #include diff --git a/e2fsprogs/e2p/Kbuild b/e2fsprogs/e2p/Kbuild new file mode 100644 index 000000000..24a692ea1 --- /dev/null +++ b/e2fsprogs/e2p/Kbuild @@ -0,0 +1,10 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-y += fgetsetflags.o fgetsetversion.o pf.o iod.o mntopts.o \ + feature.o ls.o uuid.o pe.o ostype.o ps.o hashstr.o \ + parse_num.o diff --git a/e2fsprogs/e2p/fgetsetflags.c b/e2fsprogs/e2p/fgetsetflags.c index 86bf65d50..34e40551f 100644 --- a/e2fsprogs/e2p/fgetsetflags.c +++ b/e2fsprogs/e2p/fgetsetflags.c @@ -63,8 +63,8 @@ int fgetsetflags (const char * name, unsigned long * get_flags, unsigned long se if (save_errno) errno = save_errno; return r; -#endif /* HAVE_EXT2_IOCTLS */ notsupp: +#endif /* HAVE_EXT2_IOCTLS */ errno = EOPNOTSUPP; return -1; } diff --git a/e2fsprogs/ext2fs/Kbuild b/e2fsprogs/ext2fs/Kbuild new file mode 100644 index 000000000..dc499348d --- /dev/null +++ b/e2fsprogs/ext2fs/Kbuild @@ -0,0 +1,18 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-y += gen_bitmap.o bitops.o ismounted.o mkjournal.o unix_io.o \ + rw_bitmaps.o initialize.o bitmaps.o block.o \ + ind_block.o inode.o freefs.o alloc_stats.o closefs.o \ + openfs.o io_manager.o finddev.o read_bb.o alloc.o badblocks.o \ + getsize.o getsectsize.o alloc_tables.o read_bb_file.o mkdir.o \ + bb_inode.o newdir.o alloc_sb.o lookup.o dirblock.o expanddir.o \ + dir_iterate.o link.o res_gdt.o icount.o get_pathname.o dblist.o \ + dirhash.o version.o flushb.o unlink.o check_desc.o valid_blk.o \ + ext_attr.o bmap.o dblist_dir.o ext2fs_inline.o swapfs.o + +CFLAGS += -include e2fsprogs/e2fsbb.h diff --git a/e2fsprogs/tune2fs.c b/e2fsprogs/tune2fs.c index 9bd6f4c7e..01ba31c68 100644 --- a/e2fsprogs/tune2fs.c +++ b/e2fsprogs/tune2fs.c @@ -45,8 +45,6 @@ #include "blkid/blkid.h" #include "busybox.h" -#include "grp_.h" -#include "pwd_.h" static char * device_name = NULL; static char * new_label, *new_last_mounted, *new_UUID; diff --git a/e2fsprogs/uuid/Kbuild b/e2fsprogs/uuid/Kbuild new file mode 100644 index 000000000..0ae74aed3 --- /dev/null +++ b/e2fsprogs/uuid/Kbuild @@ -0,0 +1,9 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-y += compare.o gen_uuid.o pack.o parse.o unpack.o unparse.o \ + uuid_time.o diff --git a/e2fsprogs/uuid/gen_uuid.c b/e2fsprogs/uuid/gen_uuid.c index e5c0f0d53..9d700a015 100644 --- a/e2fsprogs/uuid/gen_uuid.c +++ b/e2fsprogs/uuid/gen_uuid.c @@ -41,6 +41,7 @@ #include #include #include +#include #ifdef HAVE_SYS_IOCTL_H #include #endif diff --git a/editors/Config.in b/editors/Config.in index 14c316c08..4ba009019 100644 --- a/editors/Config.in +++ b/editors/Config.in @@ -5,22 +5,22 @@ menu "Editors" -config CONFIG_AWK +config AWK bool "awk" default n help Awk is used as a pattern scanning and processing language. This is the BusyBox implementation of that programming language. -config CONFIG_FEATURE_AWK_MATH +config FEATURE_AWK_MATH bool "Enable math functions (requires libm)" default y - depends on CONFIG_AWK + depends on AWK help Enable math functions of the Awk programming language. NOTE: This will require libm to be present for linking. -config CONFIG_ED +config ED bool "ed" default n help @@ -28,20 +28,20 @@ config CONFIG_ED Small, simple, evil. Part of SUSv3. If you're not already using this, you don't need it. -config CONFIG_PATCH +config PATCH bool "patch" default n help Apply a unified diff formatted patch. -config CONFIG_SED +config SED bool "sed" default n help sed is used to perform text transformations on a file or input from a pipeline. -config CONFIG_VI +config VI bool "vi" default n help @@ -50,79 +50,79 @@ config CONFIG_VI learning curve. If you are not already comfortable with 'vi' you may wish to use something else. -config CONFIG_FEATURE_VI_COLON +config FEATURE_VI_COLON bool "Enable \":\" colon commands (no \"ex\" mode)" default y - depends on CONFIG_VI + depends on VI help Enable a limited set of colon commands for vi. This does not provide an "ex" mode. -config CONFIG_FEATURE_VI_YANKMARK +config FEATURE_VI_YANKMARK bool "Enable yank/put commands and mark cmds" default y - depends on CONFIG_VI + depends on VI help This will enable you to use yank and put, as well as mark in busybox vi. -config CONFIG_FEATURE_VI_SEARCH +config FEATURE_VI_SEARCH bool "Enable search and replace cmds" default y - depends on CONFIG_VI + depends on VI help Select this if you wish to be able to do search and replace in busybox vi. -config CONFIG_FEATURE_VI_USE_SIGNALS +config FEATURE_VI_USE_SIGNALS bool "Catch signals" default y - depends on CONFIG_VI + depends on VI help Selecting this option will make busybox vi signal aware. This will make busybox vi support SIGWINCH to deal with Window Changes, catch Ctrl-Z and Ctrl-C and alarms. -config CONFIG_FEATURE_VI_DOT_CMD +config FEATURE_VI_DOT_CMD bool "Remember previous cmd and \".\" cmd" default y - depends on CONFIG_VI + depends on VI help Make busybox vi remember the last command and be able to repeat it. -config CONFIG_FEATURE_VI_READONLY +config FEATURE_VI_READONLY bool "Enable -R option and \"view\" mode" default y - depends on CONFIG_VI + depends on VI help Enable the read-only command line option, which allows the user to open a file in read-only mode. -config CONFIG_FEATURE_VI_SETOPTS +config FEATURE_VI_SETOPTS bool "Enable set-able options, ai ic showmatch" default y - depends on CONFIG_VI + depends on VI help Enable the editor to set some (ai, ic, showmatch) options. -config CONFIG_FEATURE_VI_SET +config FEATURE_VI_SET bool "Support for :set" default y - depends on CONFIG_VI + depends on VI help Support for ":set". -config CONFIG_FEATURE_VI_WIN_RESIZE +config FEATURE_VI_WIN_RESIZE bool "Handle window resize" default y - depends on CONFIG_VI + depends on VI help Make busybox vi behave nicely with terminals that get resized. -config CONFIG_FEATURE_VI_OPTIMIZE_CURSOR +config FEATURE_VI_OPTIMIZE_CURSOR bool "Optimize cursor movement" default y - depends on CONFIG_VI + depends on VI help This will make the cursor movement faster, but requires more memory and it makes the applet a tiny bit larger. diff --git a/editors/Kbuild b/editors/Kbuild new file mode 100644 index 000000000..d991e1faf --- /dev/null +++ b/editors/Kbuild @@ -0,0 +1,12 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_AWK) += awk.o +lib-$(CONFIG_ED) += ed.o +lib-$(CONFIG_PATCH) += patch.o +lib-$(CONFIG_SED) += sed.o +lib-$(CONFIG_VI) += vi.o diff --git a/editors/Makefile b/editors/Makefile deleted file mode 100644 index 22790095a..000000000 --- a/editors/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/editors -EDITOR_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include $(srcdir)/Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/editors/Makefile.in b/editors/Makefile.in deleted file mode 100644 index 9a46e32c2..000000000 --- a/editors/Makefile.in +++ /dev/null @@ -1,40 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -EDITOR_AR:=editors.a -ifndef $(EDITOR_DIR) -EDITOR_DIR:=$(top_builddir)/editors/ -endif -srcdir=$(top_srcdir)/editors - -EDITOR-y:= -EDITOR-$(CONFIG_AWK) += awk.o -EDITOR-$(CONFIG_ED) += ed.o -EDITOR-$(CONFIG_PATCH) += patch.o -EDITOR-$(CONFIG_SED) += sed.o -EDITOR-$(CONFIG_VI) += vi.o - -ifneq ($(strip $(EDITOR-y)),) -libraries-y+=$(EDITOR_DIR)$(EDITOR_AR) -endif - -EDITOR_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(EDITOR-y)) -EDITOR_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(EDITOR_SRC-y) -APPLET_SRC-a+=$(EDITOR_SRC-a) - -needlibm-y:= -needlibm-$(CONFIG_FEATURE_AWK_MATH) := y - -ifeq ($(needlibm-y),y) - LIBRARIES := -lm $(filter-out -lm,$(LIBRARIES)) -endif - -$(EDITOR_DIR)$(EDITOR_AR): $(patsubst %,$(EDITOR_DIR)%, $(EDITOR-y)) - $(do_ar) - -$(EDITOR_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/findutils/Config.in b/findutils/Config.in index 12387a44e..5a4476a98 100644 --- a/findutils/Config.in +++ b/findutils/Config.in @@ -5,152 +5,152 @@ menu "Finding Utilities" -config CONFIG_FIND +config FIND bool "find" default n help find is used to search your system to find specified files. -config CONFIG_FEATURE_FIND_PRINT0 +config FEATURE_FIND_PRINT0 bool "Enable -print0 option" default y - depends on CONFIG_FIND + depends on FIND help Causes output names to be separated by a null character rather than a newline. This allows names that contain newlines and other whitespace to be more easily interpreted by other programs. -config CONFIG_FEATURE_FIND_MTIME +config FEATURE_FIND_MTIME bool "Enable modified time matching (-mtime) option" default y - depends on CONFIG_FIND + depends on FIND help Allow searching based on the modification time of files, in days. -config CONFIG_FEATURE_FIND_MMIN +config FEATURE_FIND_MMIN bool "Enable modified time matching (-min) option" default y - depends on CONFIG_FIND + depends on FIND help Allow searching based on the modification time of files, in minutes. -config CONFIG_FEATURE_FIND_PERM +config FEATURE_FIND_PERM bool "Enable permissions matching (-perm) option" default y - depends on CONFIG_FIND + depends on FIND help Enable searching based on file permissions. -config CONFIG_FEATURE_FIND_TYPE +config FEATURE_FIND_TYPE bool "Enable filetype matching (-type) option" default y - depends on CONFIG_FIND + depends on FIND help Enable searching based on file type (file, directory, socket, device, etc.). -config CONFIG_FEATURE_FIND_XDEV +config FEATURE_FIND_XDEV bool "Enable stay in filesystem (-xdev) option" default y - depends on CONFIG_FIND + depends on FIND help This option will allow find to restrict searches to a single filesystem. -config CONFIG_FEATURE_FIND_NEWER +config FEATURE_FIND_NEWER bool "Enable -newer option for comparing file mtimes" default y - depends on CONFIG_FIND + depends on FIND help Support the 'find -newer' option for finding any files which have a modified time that is more recent than the specified FILE. -config CONFIG_FEATURE_FIND_INUM +config FEATURE_FIND_INUM bool "Enable inode number matching (-inum) option" default y - depends on CONFIG_FIND + depends on FIND help Support the 'find -inum' option for searching by inode number. -config CONFIG_FEATURE_FIND_EXEC +config FEATURE_FIND_EXEC bool "Enable (-exec) option allowing execution of commands" default y - depends on CONFIG_FIND + depends on FIND help Support the 'find -exec' option for executing commands based upon the files matched. -config CONFIG_GREP +config GREP bool "grep" default n help grep is used to search files for a specified pattern. -config CONFIG_FEATURE_GREP_EGREP_ALIAS +config FEATURE_GREP_EGREP_ALIAS bool "Support extended regular expressions (egrep & grep -E)" default y - depends on CONFIG_GREP + depends on GREP help Enabled support for extended regular expressions. Extended regular expressions allow for alternation (foo|bar), grouping, and various repetition operators. -config CONFIG_FEATURE_GREP_FGREP_ALIAS +config FEATURE_GREP_FGREP_ALIAS bool "Alias fgrep to grep -F" default y - depends on CONFIG_GREP + depends on GREP help fgrep sees the search pattern as a normal string rather than regular expressions. grep -F is always builtin, this just creates the fgrep alias. -config CONFIG_FEATURE_GREP_CONTEXT +config FEATURE_GREP_CONTEXT bool "Enable before and after context flags (-A, -B and -C)" default y - depends on CONFIG_GREP + depends on GREP help Print the specified number of leading (-B) and/or trailing (-A) context surrounding our matching lines. Print the specified number of context lines (-C). -config CONFIG_XARGS +config XARGS bool "xargs" default n help xargs is used to execute a specified command on every item from standard input. -config CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION +config FEATURE_XARGS_SUPPORT_CONFIRMATION bool "Enable prompt and confirmation option -p" default n - depends on CONFIG_XARGS + depends on XARGS help Support prompt the user about whether to run each command line and read a line from the terminal. -config CONFIG_FEATURE_XARGS_SUPPORT_QUOTES +config FEATURE_XARGS_SUPPORT_QUOTES bool "Enable support single and double quotes and backslash" default n - depends on CONFIG_XARGS + depends on XARGS help Default xargs unsupport single and double quotes and backslash for can use aruments with spaces. -config CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT +config FEATURE_XARGS_SUPPORT_TERMOPT bool "Enable support options -x" default n - depends on CONFIG_XARGS + depends on XARGS help Enable support exit if the size (see the -s or -n option) is exceeded. -config CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM +config FEATURE_XARGS_SUPPORT_ZERO_TERM bool "Enable null terminated option -0" default n - depends on CONFIG_XARGS + depends on XARGS help Enable input filenames are terminated by a null character instead of by whitespace, and the quotes and backslash diff --git a/findutils/Kbuild b/findutils/Kbuild new file mode 100644 index 000000000..7b504bacf --- /dev/null +++ b/findutils/Kbuild @@ -0,0 +1,10 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_FIND) += find.o +lib-$(CONFIG_GREP) += grep.o +lib-$(CONFIG_XARGS) += xargs.o diff --git a/findutils/Makefile b/findutils/Makefile deleted file mode 100644 index f152c8126..000000000 --- a/findutils/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/findutils -FINDUTILS_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include $(srcdir)/Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/findutils/Makefile.in b/findutils/Makefile.in deleted file mode 100644 index 25a2d38d3..000000000 --- a/findutils/Makefile.in +++ /dev/null @@ -1,31 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -FINDUTILS_AR:=findutils.a -ifndef $(FINDUTILS_DIR) -FINDUTILS_DIR:=$(top_builddir)/findutils/ -endif -srcdir=$(top_srcdir)/findutils - -FINDUTILS-y:= -FINDUTILS-$(CONFIG_FIND) += find.o -FINDUTILS-$(CONFIG_GREP) += grep.o -FINDUTILS-$(CONFIG_XARGS) += xargs.o - -ifneq ($(strip $(FINDUTILS-y)),) -libraries-y+=$(FINDUTILS_DIR)$(FINDUTILS_AR) -endif - -FINDUTILS_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(FINDUTILS-y)) -FINDUTILS_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(FINDUTILS_SRC-y) -APPLET_SRC-a+=$(FINDUTILS_SRC-a) - -$(FINDUTILS_DIR)$(FINDUTILS_AR): $(patsubst %,$(FINDUTILS_DIR)%, $(FINDUTILS-y)) - $(do_ar) - -$(FINDUTILS_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/include/bb_config.h b/include/bb_config.h new file mode 100644 index 000000000..beec07cba --- /dev/null +++ b/include/bb_config.h @@ -0,0 +1,142 @@ +/* Hack. kbuild will not define needed macros for config symbols + * which depend on other symbols, which themself are off. + * Provide them here by hand. Need a better idea. */ + +#ifndef ENABLE_KILLALL5 +#define ENABLE_KILLALL5 0 +#define USE_KILLALL5(...) +#define SKIP_KILLALL5(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_FEATURE_QUERY_MODULE_INTERFACE +#define ENABLE_FEATURE_QUERY_MODULE_INTERFACE 0 +#define USE_FEATURE_QUERY_MODULE_INTERFACE(...) +#define SKIP_FEATURE_QUERY_MODULE_INTERFACE(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_FEATURE_CLEAN_UP +#define ENABLE_FEATURE_CLEAN_UP 0 +#define USE_FEATURE_CLEAN_UP(...) +#define SKIP_FEATURE_CLEAN_UP(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_FEATURE_SH_STANDALONE_SHELL +#define ENABLE_FEATURE_SH_STANDALONE_SHELL 0 +#define USE_FEATURE_SH_STANDALONE_SHELL(...) +#define SKIP_FEATURE_SH_STANDALONE_SHELL(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_FEATURE_MTAB_SUPPORT +#define ENABLE_FEATURE_MTAB_SUPPORT 0 +#define USE_FEATURE_MTAB_SUPPORT(...) +#define SKIP_FEATURE_MTAB_SUPPORT(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_FEATURE_PRESERVE_HARDLINKS +#define ENABLE_FEATURE_PRESERVE_HARDLINKS 0 +#define USE_FEATURE_PRESERVE_HARDLINKS(...) +#define SKIP_FEATURE_PRESERVE_HARDLINKS(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_FEATURE_AUTOWIDTH +#define ENABLE_FEATURE_AUTOWIDTH 0 +#define USE_FEATURE_AUTOWIDTH(...) +#define SKIP_FEATURE_AUTOWIDTH(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_FEATURE_SUID_CONFIG +#define ENABLE_FEATURE_SUID_CONFIG 0 +#define USE_FEATURE_SUID_CONFIG(...) +#define SKIP_FEATURE_SUID_CONFIG(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_APP_DUMPLEASES +#define ENABLE_APP_DUMPLEASES 0 +#define USE_APP_DUMPLEASES(...) +#define SKIP_APP_DUMPLEASES(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_E2LABEL +#define ENABLE_E2LABEL 0 +#define USE_E2LABEL(...) +#define SKIP_E2LABEL(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_FEATURE_GREP_EGREP_ALIAS +#define ENABLE_FEATURE_GREP_EGREP_ALIAS 0 +#define USE_FEATURE_GREP_EGREP_ALIAS(...) +#define SKIP_FEATURE_GREP_EGREP_ALIAS(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_FEATURE_GREP_FGREP_ALIAS +#define ENABLE_FEATURE_GREP_FGREP_ALIAS 0 +#define USE_FEATURE_GREP_FGREP_ALIAS(...) +#define SKIP_FEATURE_GREP_FGREP_ALIAS(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_FINDFS +#define ENABLE_FINDFS 0 +#define USE_FINDFS(...) +#define SKIP_FINDFS(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_IPADDR +#define ENABLE_IPADDR 0 +#define USE_IPADDR(...) +#define SKIP_IPADDR(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_IPLINK +#define ENABLE_IPLINK 0 +#define USE_IPLINK(...) +#define SKIP_IPLINK(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_IPROUTE + +#define ENABLE_IPROUTE 0 +#define USE_IPROUTE(...) +#define SKIP_IPROUTE(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_IPTUNNEL +#define ENABLE_IPTUNNEL 0 +#define USE_IPTUNNEL(...) +#define SKIP_IPTUNNEL(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_KILLALL +#define ENABLE_KILLALL 0 +#define USE_KILLALL(...) +#define SKIP_KILLALL(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_KLOGD +#define ENABLE_KLOGD 0 +#define USE_KLOGD(...) +#define SKIP_KLOGD(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_FEATURE_INITRD +#define ENABLE_FEATURE_INITRD 0 +#define USE_FEATURE_INITRD(...) +#define SKIP_FEATURE_INITRD(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_LOGREAD +#define ENABLE_LOGREAD 0 +#define USE_LOGREAD(...) +#define SKIP_LOGREAD(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_PING6 +#define ENABLE_PING6 0 +#define USE_PING6(...) +#define SKIP_PING6(...) __VA_ARGS__ +#endif + +#ifndef ENABLE_UNIX2DOS +#define ENABLE_UNIX2DOS 0 +#define USE_UNIX2DOS(...) +#define SKIP_UNIX2DOS(...) __VA_ARGS__ +#endif diff --git a/include/busybox.h b/include/busybox.h index fbda6efcb..d20337ff1 100644 --- a/include/busybox.h +++ b/include/busybox.h @@ -7,8 +7,6 @@ #ifndef _BB_INTERNAL_H_ #define _BB_INTERNAL_H_ 1 -#include "bb_config.h" - #include "libbb.h" /* order matters: used as index into "install_dir[]" in busybox.c */ diff --git a/include/grp_.h b/include/grp_.h index 3ac5c8461..b34addfa2 100644 --- a/include/grp_.h +++ b/include/grp_.h @@ -30,12 +30,10 @@ #ifndef _GRP_H #define _GRP_H 1 - #include #include #include - /* The group structure. */ struct group { diff --git a/include/libbb.h b/include/libbb.h index 88847ac59..ed1d780fd 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -377,7 +377,6 @@ extern const char *applet_name; extern const char bb_msg_full_version[]; extern const char bb_msg_memory_exhausted[]; extern const char bb_msg_invalid_date[]; -extern const char bb_msg_io_error[]; extern const char bb_msg_read_error[]; extern const char bb_msg_write_error[]; extern const char bb_msg_name_longer_than_foo[]; diff --git a/init/Config.in b/init/Config.in index 2a39d50e5..c0ad5263d 100644 --- a/init/Config.in +++ b/init/Config.in @@ -5,32 +5,32 @@ menu "Init Utilities" -config CONFIG_INIT +config INIT bool "init" default n - select CONFIG_FEATURE_SYSLOG + select FEATURE_SYSLOG help init is the first program run when the system boots. -config CONFIG_DEBUG_INIT +config DEBUG_INIT bool "debugging aid" default n - depends on CONFIG_INIT + depends on INIT help Turn this on to disable all the dangerous rebooting stuff when debugging. -config CONFIG_FEATURE_USE_INITTAB +config FEATURE_USE_INITTAB bool "Support reading an inittab file" default y - depends on CONFIG_INIT + depends on INIT help Allow init to read an inittab file when the system boot. -config CONFIG_FEATURE_INIT_SCTTY +config FEATURE_INIT_SCTTY bool "Support running commands with a controlling-tty" default n - depends on CONFIG_INIT + depends on INIT help If this option is enabled a command starting with hyphen (-) is run in its own session (setsid(2)) and possibly with a @@ -38,17 +38,17 @@ config CONFIG_FEATURE_INIT_SCTTY behavour, but is often what you want in an embedded system where the console is only accessed during development or for maintenance. -config CONFIG_FEATURE_EXTRA_QUIET +config FEATURE_EXTRA_QUIET bool "Be _extra_ quiet on boot" default y - depends on CONFIG_INIT + depends on INIT help Prevent init from logging some messages to the console during boot. -config CONFIG_FEATURE_INIT_COREDUMPS +config FEATURE_INIT_COREDUMPS bool "Support dumping core for child processes (debugging only)" default n - depends on CONFIG_INIT + depends on INIT help If this option is enabled and the file /.init_enable_core exists, then init will call setrlimit() to allow unlimited @@ -57,10 +57,10 @@ config CONFIG_FEATURE_INIT_COREDUMPS -config CONFIG_FEATURE_INITRD +config FEATURE_INITRD bool "Support running init from within an initrd (not initramfs)" default y - depends on CONFIG_INIT + depends on INIT help Legacy support for running init under the old-style initrd. Allows the name linuxrc to act as init, and it doesn't assume init is PID 1. @@ -68,13 +68,13 @@ config CONFIG_FEATURE_INITRD This does not apply to initramfs, which runs /init as PID 1 and requires no special support. -config CONFIG_HALT +config HALT bool "poweroff, halt, and reboot" default y help Stop all processes and either halt, reboot, or power off the system. -config CONFIG_MESG +config MESG bool "mesg" default y help diff --git a/init/Kbuild b/init/Kbuild new file mode 100644 index 000000000..e99360241 --- /dev/null +++ b/init/Kbuild @@ -0,0 +1,12 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_HALT) += halt.o +lib-$(CONFIG_INIT) += init.o +lib-$(CONFIG_MESG) += mesg.o +lib-$(CONFIG_INIT) += init_shared.o +lib-$(CONFIG_HALT) += init_shared.o diff --git a/init/Makefile b/init/Makefile deleted file mode 100644 index 63816f6aa..000000000 --- a/init/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/init -INIT_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include $(srcdir)/Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/init/Makefile.in b/init/Makefile.in deleted file mode 100644 index a48ead446..000000000 --- a/init/Makefile.in +++ /dev/null @@ -1,43 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -INIT_AR:=init.a -ifndef $(INIT_DIR) -INIT_DIR:=$(top_builddir)/init/ -endif -srcdir=$(top_srcdir)/init - -INIT-y:= -INIT-$(CONFIG_HALT) += halt.o -INIT-$(CONFIG_INIT) += init.o -INIT-$(CONFIG_MESG) += mesg.o - -ifeq ($(strip $(CONFIG_HALT)),y) -CONFIG_INIT_SHARED=y -else -ifeq ($(strip $(CONFIG_INIT)),y) -CONFIG_INIT_SHARED=y -else -CONFIG_INIT_SHARED=n -endif -endif - -INIT-$(CONFIG_INIT_SHARED) += init_shared.o - -ifneq ($(strip $(INIT-y)),) -libraries-y+=$(INIT_DIR)$(INIT_AR) -endif - -INIT_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(INIT-y)) -INIT_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(INIT_SRC-y) -APPLET_SRC-a+=$(INIT_SRC-a) - -$(INIT_DIR)$(INIT_AR): $(patsubst %,$(INIT_DIR)%, $(INIT-y)) - $(do_ar) - -$(INIT_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/libbb/Config.in b/libbb/Config.in index c5406cbb9..92ee55cbc 100644 --- a/libbb/Config.in +++ b/libbb/Config.in @@ -5,14 +5,14 @@ menu "Busybox Library Tuning" -config CONFIG_PASSWORD_MINLEN +config PASSWORD_MINLEN int "Minimum password length" default 6 range 5 32 help Minimum allowable password length. -config CONFIG_MD5_SIZE_VS_SPEED +config MD5_SIZE_VS_SPEED int " MD5: Trade Bytes for Speed" default 2 range 0 3 diff --git a/libbb/Kbuild b/libbb/Kbuild new file mode 100644 index 000000000..909f527ba --- /dev/null +++ b/libbb/Kbuild @@ -0,0 +1,61 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= \ + ask_confirmation.o change_identity.o chomp.o \ + compare_string_array.o concat_path_file.o copy_file.o copyfd.o \ + crc32.o create_icmp_socket.o create_icmp6_socket.o \ + device_open.o dump.o error_msg.o error_msg_and_die.o \ + find_pid_by_name.o find_root_device.o fgets_str.o full_read.o \ + full_write.o get_last_path_component.o get_line_from_file.o \ + herror_msg.o herror_msg_and_die.o \ + human_readable.o inet_common.o inode_hash.o isdirectory.o \ + kernel_version.o last_char_is.o login.o \ + make_directory.o md5.o mode_string.o mtab_file.o \ + obscure.o parse_mode.o parse_number.o perror_msg.o \ + perror_msg_and_die.o get_console.o \ + process_escape_sequence.o procps.o \ + recursive_action.o remove_file.o \ + restricted_shell.o run_parts.o run_shell.o safe_read.o safe_write.o \ + safe_strncpy.o setup_environment.o sha1.o simplify_path.o \ + trim.o u_signal_names.o vdprintf.o verror_msg.o \ + vherror_msg.o vperror_msg.o wfopen.o xconnect.o xgetcwd.o \ + xgethostbyname.o xgethostbyname2.o xreadlink.o xgetlarg.o \ + fclose_nonstdin.o fflush_stdout_and_exit.o \ + getopt32.o default_error_retval.o wfopen_input.o speed_table.o \ + perror_nomsg_and_die.o perror_nomsg.o skip_whitespace.o bb_askpass.o \ + warn_ignoring_args.o concat_subpath_file.o vfork_daemon_rexec.o \ + bb_do_delay.o uuencode.o info_msg.o vinfo_msg.o + +# conditionally compiled objects: +lib-$(CONFIG_FEATURE_MOUNT_LOOP) += loop.o +lib-$(CONFIG_LOSETUP) += loop.o +lib-$(CONFIG_FEATURE_MTAB_SUPPORT) += mtab.o +lib-$(CONFIG_PASSWD) += pw_encrypt.o +lib-$(CONFIG_SULOGIN) += pw_encrypt.o +lib-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) += pw_encrypt.o +lib-$(CONFIG_VLOCK) += correct_password.o +lib-$(CONFIG_SU) += correct_password.o +lib-$(CONFIG_LOGIN) += correct_password.o +lib-$(CONFIG_DF) += find_mount_point.o +lib-$(CONFIG_EJECT) += find_mount_point.o + +# We shouldn't build xregcomp.c if we don't need it - this ensures we don't +# require regex.h to be in the include dir even if we don't need it thereby +# allowing us to build busybox even if uclibc regex support is disabled. + +lib-$(CONFIG_AWK) += xregcomp.o +lib-$(CONFIG_SED) += xregcomp.o +lib-$(CONFIG_LESS) += xregcomp.o +lib-$(CONFIG_DEVFSD) += xregcomp.o + +lib-y += messages.o +lib-y += xfuncs.o +lib-y += printf.o +lib-y += xgetularg.o +lib-y += safe_strtol.o +lib-y += bb_pwd.o +lib-y += llist.o diff --git a/libbb/Makefile b/libbb/Makefile deleted file mode 100644 index 336398641..000000000 --- a/libbb/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/libbb -LIBBB_DIR:=./ - -# Ensure "all" is still the default target when make is run by itself in -# libbb, even if the files we include define rules for targets. - -all: - -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/libbb/Makefile.in b/libbb/Makefile.in deleted file mode 100644 index ef5c6b97a..000000000 --- a/libbb/Makefile.in +++ /dev/null @@ -1,155 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef $(LIBBB_DIR) -LIBBB_DIR:=$(top_builddir)/libbb -endif -srcdir=$(top_srcdir)/libbb - -LIBBB-n:= -LIBBB-y:= \ - ask_confirmation.c change_identity.c chomp.c \ - compare_string_array.c concat_path_file.c copy_file.c copyfd.c \ - crc32.c create_icmp_socket.c create_icmp6_socket.c \ - device_open.c dump.c error_msg.c error_msg_and_die.c \ - find_pid_by_name.c find_root_device.c fgets_str.c full_read.c \ - full_write.c get_last_path_component.c get_line_from_file.c \ - herror_msg.c herror_msg_and_die.c \ - human_readable.c inet_common.c inode_hash.c isdirectory.c \ - kernel_version.c last_char_is.c login.c \ - make_directory.c md5.c mode_string.c mtab_file.c \ - obscure.c parse_mode.c parse_number.c perror_msg.c \ - perror_msg_and_die.c get_console.c process_escape_sequence.c procps.c \ - recursive_action.c remove_file.c info_msg.c vinfo_msg.c \ - restricted_shell.c run_parts.c run_shell.c safe_read.c safe_write.c \ - safe_strncpy.c setup_environment.c sha1.c simplify_path.c \ - trim.c u_signal_names.c vdprintf.c verror_msg.c \ - vherror_msg.c vperror_msg.c wfopen.c xconnect.c xgetcwd.c \ - xgethostbyname.c xgethostbyname2.c xreadlink.c xgetlarg.c \ - fclose_nonstdin.c fflush_stdout_and_exit.c \ - getopt32.c default_error_retval.c wfopen_input.c speed_table.c \ - perror_nomsg_and_die.c perror_nomsg.c skip_whitespace.c bb_askpass.c \ - warn_ignoring_args.c concat_subpath_file.c vfork_daemon_rexec.c \ - bb_do_delay.c - -# conditionally compiled objects: -LIBBB-$(CONFIG_FEATURE_MOUNT_LOOP)+= loop.c -LIBBB-$(CONFIG_LOSETUP)+= loop.c -LIBBB-$(CONFIG_FEATURE_MTAB_SUPPORT)+= mtab.c -LIBBB-$(CONFIG_PASSWD)+= pw_encrypt.c -LIBBB-$(CONFIG_SULOGIN)+= pw_encrypt.c -LIBBB-$(CONFIG_FEATURE_HTTPD_AUTH_MD5)+= pw_encrypt.c -LIBBB-$(CONFIG_VLOCK)+= correct_password.c -LIBBB-$(CONFIG_SU)+= correct_password.c -LIBBB-$(CONFIG_LOGIN)+= correct_password.c -LIBBB-$(CONFIG_DF)+= find_mount_point.c -LIBBB-$(CONFIG_EJECT)+= find_mount_point.c -LIBBB-$(CONFIG_UUENCODE)+= uuencode.c -LIBBB-$(CONFIG_WGET)+= uuencode.c - -# We shouldn't build xregcomp.c if we don't need it - this ensures we don't -# require regex.h to be in the include dir even if we don't need it thereby -# allowing us to build busybox even if uclibc regex support is disabled. - -regex-y:= -regex-$(CONFIG_AWK) += xregcomp.c -regex-$(CONFIG_SED) += xregcomp.c -regex-$(CONFIG_LESS) += xregcomp.c -regex-$(CONFIG_DEVFSD) += xregcomp.c -regex-$(CONFIG_MDEV) += xregcomp.c -regex-$(CONFIG_GREP) += xregcomp.c - -# Sort has the happy side efect of returning a unique list -LIBBB-y += $(sort $(regex-y)) - -LIBBB-y:=$(patsubst %,$(srcdir)/%,$(LIBBB-y)) - -get-file-subparts = $(addsuffix .o,$(shell sed -n -e "s/^\#ifdef L_//p" ${1})) - -# 1:N objects -LIBBB_MSRC0:=$(srcdir)/messages.c -LIBBB_MOBJ0:=$(call get-file-subparts, ${LIBBB_MSRC0}) -LIBBB_MOBJ0:=$(patsubst %,$(LIBBB_DIR)/%, $(LIBBB_MOBJ0)) -$(LIBBB_MOBJ0):$(LIBBB_MSRC0) - $(compile.c) -DL_$(notdir $*) - -LIBBB_MSRC1:=$(srcdir)/xfuncs.c -LIBBB_MOBJ1:=$(call get-file-subparts, ${LIBBB_MSRC1}) -LIBBB_MOBJ1:=$(patsubst %,$(LIBBB_DIR)/%, $(LIBBB_MOBJ1)) -$(LIBBB_MOBJ1):$(LIBBB_MSRC1) - $(compile.c) -DL_$(notdir $*) - -LIBBB_MSRC2:=$(srcdir)/printf.c -LIBBB_MOBJ2:=$(call get-file-subparts, ${LIBBB_MSRC2}) -LIBBB_MOBJ2:=$(patsubst %,$(LIBBB_DIR)/%, $(LIBBB_MOBJ2)) -$(LIBBB_MOBJ2):$(LIBBB_MSRC2) - $(compile.c) -DL_$(notdir $*) - -LIBBB_MSRC3:=$(srcdir)/xgetularg.c -LIBBB_MOBJ3:=$(call get-file-subparts, ${LIBBB_MSRC3}) -LIBBB_MOBJ3:=$(patsubst %,$(LIBBB_DIR)/%, $(LIBBB_MOBJ3)) -$(LIBBB_MOBJ3):$(LIBBB_MSRC3) - $(compile.c) -DL_$(notdir $*) - -LIBBB_MSRC4:=$(srcdir)/safe_strtol.c -LIBBB_MOBJ4:=$(call get-file-subparts, ${LIBBB_MSRC4}) -LIBBB_MOBJ4:=$(patsubst %,$(LIBBB_DIR)/%, $(LIBBB_MOBJ4)) -$(LIBBB_MOBJ4):$(LIBBB_MSRC4) - $(compile.c) -DL_$(notdir $*) - -LIBBB_MSRC5:=$(srcdir)/bb_pwd.c -LIBBB_MOBJ5:=$(call get-file-subparts, ${LIBBB_MSRC5}) -LIBBB_MOBJ5:=$(patsubst %,$(LIBBB_DIR)/%, $(LIBBB_MOBJ5)) -$(LIBBB_MOBJ5):$(LIBBB_MSRC5) - $(compile.c) -DL_$(notdir $*) - -LIBBB_MSRC6:=$(srcdir)/llist.c -LIBBB_MOBJ6:=$(call get-file-subparts, ${LIBBB_MSRC6}) -LIBBB_MOBJ6:=$(patsubst %,$(LIBBB_DIR)/%, $(LIBBB_MOBJ6)) -$(LIBBB_MOBJ6):$(LIBBB_MSRC6) - $(compile.c) -DL_$(notdir $*) - -# We need the names of the object files built from MSRC for the L_ defines -LIBBB_ALL_MOBJ:=$(LIBBB_MOBJ0) $(LIBBB_MOBJ1) $(LIBBB_MOBJ2) $(LIBBB_MOBJ3) \ - $(LIBBB_MOBJ4) $(LIBBB_MOBJ5) $(LIBBB_MOBJ6) - -LIBBB_ALL_MSRC:=$(LIBBB_MSRC0) $(LIBBB_MSRC1) $(LIBBB_MSRC2) $(LIBBB_MSRC3) \ - $(LIBBB_MSRC4) $(LIBBB_MSRC5) $(LIBBB_MSRC6) - -LIBBB-y:=$(sort $(LIBBB-y) $(LIBBB_ALL_MSRC)) - -LIBBB_AR:=$(LIBBB_DIR)/libbb.a -libraries-y+=$(LIBBB_AR) - -needcrypt-y:= -ifneq ($(filter $(srcdir)/pw_encrypt.c,$(LIBBB-y)),) -needcrypt-y:=y -else -ifneq ($(filter $(srcdir)/correct_password.c,$(LIBBB-y)),) -needcrypt-y:=y -endif -endif - -ifeq ($(needcrypt-y),y) - LIBRARIES := -lcrypt $(filter-out -lcrypt,$(LIBRARIES)) -endif - -# all 1:1 objects -LIBBB_OBJS:=$(patsubst $(srcdir)/%.c,$(LIBBB_DIR)/%.o, $(LIBBB-y)) -$(LIBBB_DIR)/%.o: $(srcdir)/%.c - $(compile.c) - -LIBBB_SRC-a:=$(wildcard $(srcdir)/*.c) -LIBRARY_SRC-y+=$(LIBBB-y) -LIBRARY_SRC-a+=$(LIBBB_SRC-a) - -# all defines needed for 1:N objects -LIBBB_DEFINE-y:=$(patsubst %,-DL_%,$(subst .o,,$(notdir $(LIBBB_ALL_MOBJ)))) -LIBRARY_DEFINE-y+=$(LIBBB_DEFINE-y) -LIBRARY_DEFINE-a+=$(LIBBB_DEFINE-y) - -$(LIBBB_AR): $(LIBBB_OBJS) $(LIBBB_ALL_MOBJ) - $(do_ar) diff --git a/libbb/bb_pwd.c b/libbb/bb_pwd.c index e4d327340..3a214ca33 100644 --- a/libbb/bb_pwd.c +++ b/libbb/bb_pwd.c @@ -7,8 +7,11 @@ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. */ +#include +#include +#include +#include "libbb.h" -#ifdef L_bb_getgrgid /* Hacked by Tito Ragusa (c) 2004 to make it more * flexible : * @@ -26,9 +29,6 @@ * the program exits. */ -#include "libbb.h" -#include "grp_.h" - /* gets a groupname given a gid */ char * bb_getgrgid(char *group, long gid, int bufsize) { @@ -37,15 +37,6 @@ char * bb_getgrgid(char *group, long gid, int bufsize) return bb_getug(group, (mygroup) ? mygroup->gr_name : (char *)mygroup, gid, bufsize, 'g'); } -#endif /* L_bb_getgrgid */ - -#ifdef L_bb_xgetgrnam -#include -#include -#include "libbb.h" -#include "pwd_.h" -#include "grp_.h" - /* returns a gid given a group name */ long bb_xgetgrnam(const char *name) @@ -58,15 +49,6 @@ long bb_xgetgrnam(const char *name) return (mygroup->gr_gid); } -#endif /* L_bb_xgetgrnam */ - -#ifdef L_bb_xgetpwnam -#include -#include -#include "libbb.h" -#include "pwd_.h" -#include "grp_.h" - /* returns a uid given a username */ long bb_xgetpwnam(const char *name) @@ -79,9 +61,7 @@ long bb_xgetpwnam(const char *name) return myuser->pw_uid; } -#endif /* L_bb_xgetpwnam */ -#ifdef L_bb_getpwuid /* Hacked by Tito Ragusa (c) 2004 to make it more * flexible : * @@ -99,9 +79,6 @@ long bb_xgetpwnam(const char *name) * the program exits. */ -#include "libbb.h" -#include "pwd_.h" - /* gets a username given a uid */ char * bb_getpwuid(char *name, long uid, int bufsize) { @@ -110,9 +87,7 @@ char * bb_getpwuid(char *name, long uid, int bufsize) return bb_getug(name, (myuser) ? myuser->pw_name : (char *)myuser , uid, bufsize, 'u'); } -#endif /* L_bb_getpwuid */ -#ifdef L_bb_getug /* * if bufsize is > 0 char *buffer can not be set to NULL. * If idname is not NULL it is written on the static @@ -127,11 +102,6 @@ char * bb_getpwuid(char *name, long uid, int bufsize) * else an error message is printed and the program exits. */ -#include -#include -#include "libbb.h" - - /* internal function for bb_getpwuid and bb_getgrgid */ char * bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix) { @@ -146,13 +116,6 @@ char * bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix) } return idname; } -#endif /* L_bb_getug */ - - -#ifdef L_get_ug_id -/* indirect dispatcher for pwd helpers. */ -#include -#include "libbb.h" unsigned long get_ug_id(const char *s, long (*__bb_getxxnam)(const char *)) @@ -167,4 +130,3 @@ unsigned long get_ug_id(const char *s, return r; } -#endif /* L_get_ug_id */ diff --git a/libbb/llist.c b/libbb/llist.c index 0e727c496..8bf89a595 100644 --- a/libbb/llist.c +++ b/libbb/llist.c @@ -13,7 +13,6 @@ #include #include "libbb.h" -#ifdef L_llist_add_to /* Add data to the start of the linked list. */ void llist_add_to(llist_t **old_head, void *data) { @@ -22,9 +21,7 @@ void llist_add_to(llist_t **old_head, void *data) new_head->link = *old_head; *old_head = new_head; } -#endif -#ifdef L_llist_add_to_end /* Add data to the end of the linked list. */ void llist_add_to_end(llist_t **list_head, void *data) { @@ -39,9 +36,7 @@ void llist_add_to_end(llist_t **list_head, void *data) tail->link = new_item; } } -#endif -#ifdef L_llist_pop /* Remove first element from the list and return it */ void *llist_pop(llist_t **head) { @@ -57,9 +52,7 @@ void *llist_pop(llist_t **head) return data; } -#endif -#ifdef L_llist_free /* Recursively free all elements in the linked list. If freeit != NULL * call it on each datum in the list */ void llist_free(llist_t *elm, void (*freeit)(void *data)) @@ -69,4 +62,3 @@ void llist_free(llist_t *elm, void (*freeit)(void *data)) if (freeit) freeit(data); } } -#endif diff --git a/libbb/messages.c b/libbb/messages.c index 5aba7e693..bd41216a5 100644 --- a/libbb/messages.c +++ b/libbb/messages.c @@ -7,7 +7,6 @@ #include "libbb.h" -#ifdef L_full_version #ifndef BB_EXTRA_VERSION #define BANNER "BusyBox v" BB_VER " (" BB_BT ")" #else @@ -15,92 +14,30 @@ #endif const char BB_BANNER[] = BANNER; const char bb_msg_full_version[] = BANNER " multi-call binary"; -#endif - -#ifdef L_memory_exhausted - const char bb_msg_memory_exhausted[] = "memory exhausted"; -#endif -#ifdef L_invalid_date - const char bb_msg_invalid_date[] = "invalid date `%s'"; -#endif -#ifdef L_io_error - const char bb_msg_io_error[] = "%s: input/output error -- %m"; -#endif -#ifdef L_write_error - const char bb_msg_write_error[] = "write error"; -#endif -#ifdef L_read_error - const char bb_msg_read_error[] = "read error"; -#endif -#ifdef L_name_longer_than_foo - const char bb_msg_name_longer_than_foo[] = "names longer than %d chars not supported"; -#endif -#ifdef L_unknown - const char bb_msg_unknown[] = "(unknown)"; -#endif -#ifdef L_can_not_create_raw_socket - const char bb_msg_can_not_create_raw_socket[] = "can't create raw socket"; -#endif -#ifdef L_perm_denied_are_you_root - const char bb_msg_perm_denied_are_you_root[] = "permission denied. (are you root?)"; -#endif -#ifdef L_msg_requires_arg - const char bb_msg_requires_arg[] = "%s requires an argument"; -#endif -#ifdef L_msg_invalid_arg - const char bb_msg_invalid_arg[] = "invalid argument `%s' to `%s'"; -#endif -#ifdef L_msg_standard_input - const char bb_msg_standard_input[] = "standard input"; -#endif -#ifdef L_msg_standard_output - const char bb_msg_standard_output[] = "standard output"; -#endif - -#ifdef L_passwd_file -#define PASSWD_FILE "/etc/passwd" -const char bb_path_passwd_file[] = PASSWD_FILE; -#endif -#ifdef L_shadow_file -#define SHADOW_FILE "/etc/shadow" -const char bb_path_shadow_file[] = SHADOW_FILE; -#endif - -#ifdef L_group_file -#define GROUP_FILE "/etc/group" -const char bb_path_group_file[] = GROUP_FILE; -#endif - -#ifdef L_gshadow_file -#define GSHADOW_FILE "/etc/gshadow" -const char bb_path_gshadow_file[] = GSHADOW_FILE; -#endif - -#ifdef L_nologin_file -#define NOLOGIN_FILE "/etc/nologin" -const char bb_path_nologin_file[] = NOLOGIN_FILE; -#endif - -#ifdef L_securetty_file -#define SECURETTY_FILE "/etc/securetty" -const char bb_path_securetty_file[] = SECURETTY_FILE; -#endif - -#ifdef L_motd_file -#define MOTD_FILE "/etc/motd" -const char bb_path_motd_file[] = MOTD_FILE; -#endif - -#ifdef L_shell_file +const char bb_msg_memory_exhausted[] = "memory exhausted"; +const char bb_msg_invalid_date[] = "invalid date '%s'"; +const char bb_msg_write_error[] = "write error"; +const char bb_msg_read_error[] = "read error"; +const char bb_msg_name_longer_than_foo[] = "names longer than %d chars not supported"; +const char bb_msg_unknown[] = "(unknown)"; +const char bb_msg_can_not_create_raw_socket[] = "can't create raw socket"; +const char bb_msg_perm_denied_are_you_root[] = "permission denied. (are you root?)"; +const char bb_msg_requires_arg[] = "%s requires an argument"; +const char bb_msg_invalid_arg[] = "invalid argument '%s' to '%s'"; +const char bb_msg_standard_input[] = "standard input"; +const char bb_msg_standard_output[] = "standard output"; + +const char bb_path_passwd_file[] = "/etc/passwd"; +const char bb_path_shadow_file[] = "/etc/shadow"; +const char bb_path_group_file[] = "/etc/group"; +const char bb_path_gshadow_file[] = "/etc/gshadow"; +const char bb_path_nologin_file[] = "/etc/nologin"; +const char bb_path_securetty_file[] = "/etc/securetty"; +const char bb_path_motd_file[] = "/etc/motd"; const char bb_default_login_shell[] = LIBBB_DEFAULT_LOGIN_SHELL; -#endif - -#ifdef L_bb_dev_null const char bb_dev_null[] = "/dev/null"; -#endif -#ifdef L_bb_path_wtmp_file #include /* This is usually something like "/var/adm/wtmp" or "/var/log/wtmp" */ const char bb_path_wtmp_file[] = @@ -111,9 +48,5 @@ WTMP_FILE; #else # error unknown path to wtmp file #endif -#endif - -#ifdef L_bb_common_bufsiz1 char bb_common_bufsiz1[BUFSIZ+1]; -#endif diff --git a/libbb/printf.c b/libbb/printf.c index 2e79555b5..f0ddb862e 100644 --- a/libbb/printf.c +++ b/libbb/printf.c @@ -37,7 +37,6 @@ #include #include "libbb.h" -#ifdef L_bb_vfprintf int bb_vfprintf(FILE * __restrict stream, const char * __restrict format, va_list arg) @@ -65,16 +64,12 @@ int bb_vfprintf(FILE * __restrict stream, return rv; } -#endif -#ifdef L_bb_vprintf int bb_vprintf(const char * __restrict format, va_list arg) { return bb_vfprintf(stdout, format, arg); } -#endif -#ifdef L_bb_fprintf int bb_fprintf(FILE * __restrict stream, const char * __restrict format, ...) { @@ -87,9 +82,7 @@ int bb_fprintf(FILE * __restrict stream, return rv; } -#endif -#ifdef L_bb_printf int bb_printf(const char * __restrict format, ...) { va_list arg; @@ -101,4 +94,3 @@ int bb_printf(const char * __restrict format, ...) return rv; } -#endif diff --git a/libbb/safe_strtol.c b/libbb/safe_strtol.c index 2e8fa9558..027fc1e62 100644 --- a/libbb/safe_strtol.c +++ b/libbb/safe_strtol.c @@ -12,7 +12,6 @@ #include #include "libbb.h" -#ifdef L_safe_strtoi int safe_strtoi(char *arg, int* value) { int error; @@ -21,9 +20,7 @@ int safe_strtoi(char *arg, int* value) *value = (int) lvalue; return error; } -#endif -#ifdef L_safe_strtod int safe_strtod(char *arg, double* value) { char *endptr; @@ -38,9 +35,7 @@ int safe_strtod(char *arg, double* value) errno = errno_save; return 0; } -#endif -#ifdef L_safe_strtol int safe_strtol(char *arg, long* value) { char *endptr; @@ -55,9 +50,7 @@ int safe_strtol(char *arg, long* value) errno = errno_save; return 0; } -#endif -#ifdef L_safe_strtoul int safe_strtoul(char *arg, unsigned long* value) { char *endptr; @@ -72,9 +65,7 @@ int safe_strtoul(char *arg, unsigned long* value) errno = errno_save; return 0; } -#endif -#ifdef L_safe_strtoll int safe_strtoll(char *arg, long long* value) { char *endptr; @@ -89,9 +80,7 @@ int safe_strtoll(char *arg, long long* value) errno = errno_save; return 0; } -#endif -#ifdef L_safe_strtoull int safe_strtoull(char *arg, unsigned long long* value) { char *endptr; @@ -106,5 +95,3 @@ int safe_strtoull(char *arg, unsigned long long* value) errno = errno_save; return 0; } -#endif - diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index f1d4486c3..de765a32d 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c @@ -20,7 +20,6 @@ * Since dmalloc's prototypes overwrite the impls here as they are * included after these prototypes in libbb.h, all is well. */ -#ifdef L_xmalloc // Die if we can't allocate size bytes of memory. void *xmalloc(size_t size) { @@ -29,9 +28,7 @@ void *xmalloc(size_t size) bb_error_msg_and_die(bb_msg_memory_exhausted); return ptr; } -#endif -#ifdef L_xrealloc // Die if we can't resize previously allocated memory. (This returns a pointer // to the new memory, which may or may not be the same as the old memory. // It'll copy the contents to a new chunk and free the old one if necessary.) @@ -42,11 +39,8 @@ void *xrealloc(void *ptr, size_t size) bb_error_msg_and_die(bb_msg_memory_exhausted); return ptr; } -#endif #endif /* DMALLOC */ - -#ifdef L_xzalloc // Die if we can't allocate and zero size bytes of memory. void *xzalloc(size_t size) { @@ -54,9 +48,7 @@ void *xzalloc(size_t size) memset(ptr, 0, size); return ptr; } -#endif -#ifdef L_xstrdup // Die if we can't copy a string to freshly allocated memory. char * xstrdup(const char *s) { @@ -72,9 +64,7 @@ char * xstrdup(const char *s) return t; } -#endif -#ifdef L_xstrndup // Die if we can't allocate n+1 bytes (space for the null terminator) and copy // the (possibly truncated to length n) string into it. char * xstrndup(const char *s, int n) @@ -88,9 +78,7 @@ char * xstrndup(const char *s, int n) return safe_strncpy(t,s,n); } -#endif -#ifdef L_xfopen // Die if we can't open a file and return a FILE * to it. // Notice we haven't got xfread(), This is for use with fscanf() and friends. FILE *xfopen(const char *path, const char *mode) @@ -100,9 +88,7 @@ FILE *xfopen(const char *path, const char *mode) bb_perror_msg_and_die("%s", path); return fp; } -#endif -#ifdef L_xopen // Die if we can't open an existing file and return an fd. int xopen(const char *pathname, int flags) { @@ -111,9 +97,7 @@ int xopen(const char *pathname, int flags) return xopen3(pathname, flags, 0777); } -#endif -#ifdef L_xopen3 // Die if we can't open a new file and return an fd. int xopen3(const char *pathname, int flags, int mode) { @@ -125,9 +109,7 @@ int xopen3(const char *pathname, int flags, int mode) } return ret; } -#endif -#ifdef L_xread // Die with an error message if we can't read the entire buffer. void xread(int fd, void *buf, size_t count) { @@ -140,9 +122,7 @@ void xread(int fd, void *buf, size_t count) buf = ((char *) buf) + size; } } -#endif -#ifdef L_xwrite // Die with an error message if we can't write the entire buffer. void xwrite(int fd, void *buf, size_t count) { @@ -155,17 +135,13 @@ void xwrite(int fd, void *buf, size_t count) buf = ((char *) buf) + size; } } -#endif -#ifdef L_xlseek // Die with an error message if we can't lseek to the right spot. void xlseek(int fd, off_t offset, int whence) { if (offset != lseek(fd, offset, whence)) bb_error_msg_and_die("lseek"); } -#endif -#ifdef L_xread_char // Die with an error message if we can't read one character. unsigned char xread_char(int fd) { @@ -175,9 +151,7 @@ unsigned char xread_char(int fd) return(tmp); } -#endif -#ifdef L_xferror // Die with supplied error message if this FILE * has ferror set. void xferror(FILE *fp, const char *fn) { @@ -185,17 +159,13 @@ void xferror(FILE *fp, const char *fn) bb_error_msg_and_die("%s", fn); } } -#endif -#ifdef L_xferror_stdout // Die with an error message if stdout has ferror set. void xferror_stdout(void) { xferror(stdout, bb_msg_standard_output); } -#endif -#ifdef L_xfflush_stdout // Die with an error message if we have trouble flushing stdout. void xfflush_stdout(void) { @@ -203,9 +173,7 @@ void xfflush_stdout(void) bb_perror_msg_and_die(bb_msg_standard_output); } } -#endif -#ifdef L_spawn // This does a fork/exec in one call, using vfork(). Return PID of new child, // -1 for failure. Runs argv[0], searching path if that has no / in it. pid_t spawn(char **argv) @@ -230,9 +198,7 @@ pid_t spawn(char **argv) } return failed ? failed : pid; } -#endif -#ifdef L_xspawn // Die with an error message if we can't spawn a child process. pid_t xspawn(char **argv) { @@ -240,9 +206,7 @@ pid_t xspawn(char **argv) if (pid < 0) bb_perror_msg_and_die("%s", *argv); return pid; } -#endif -#ifdef L_wait4 // Wait for the specified child PID to exit, returning child's error return. int wait4pid(int pid) { @@ -253,17 +217,13 @@ int wait4pid(int pid) if (WIFSIGNALED(status)) return WTERMSIG(status); return 0; } -#endif -#ifdef L_xsetenv void xsetenv(const char *key, const char *value) { if(setenv(key, value, 1)) bb_error_msg_and_die(bb_msg_memory_exhausted); } -#endif -#ifdef L_itoa // Convert unsigned integer to ascii, writing into supplied buffer. A // truncated result is always null terminated (unless buflen is 0), and // contains the first few digits of the result ala strncpy. @@ -319,9 +279,7 @@ char *itoa(int n) return local_buf; } -#endif -#ifdef L_setuid // Die with an error message if we can't set gid. (Because resource limits may // limit this user to a given number of processes, and if that fills up the // setgid() will fail and we'll _still_be_root_, which is bad.) @@ -335,9 +293,7 @@ void xsetuid(uid_t uid) { if (setuid(uid)) bb_error_msg_and_die("setuid"); } -#endif -#ifdef L_fdlength // Return how long the file at fd is, if there's any way to determine it. off_t fdlength(int fd) { @@ -375,9 +331,7 @@ off_t fdlength(int fd) return pos + 1; } -#endif -#ifdef L_xasprintf // Die with an error message if we can't malloc() enough space and do an // sprintf() into that space. char *xasprintf(const char *format, ...) @@ -405,9 +359,7 @@ char *xasprintf(const char *format, ...) if (r < 0) bb_error_msg_and_die(bb_msg_memory_exhausted); return string_ptr; } -#endif -#ifdef L_xprint_and_close_file // Die with an error message if we can't copy an entire FILE * to stdout, then // close that file. void xprint_and_close_file(FILE *file) @@ -418,18 +370,14 @@ void xprint_and_close_file(FILE *file) fclose(file); } -#endif -#ifdef L_xchdir // Die if we can't chdir to a new path. void xchdir(const char *path) { if (chdir(path)) bb_perror_msg_and_die("chdir(%s)", path); } -#endif -#ifdef L_warn_opendir // Print a warning message if opendir() fails, but don't die. DIR *warn_opendir(const char *path) { @@ -441,9 +389,7 @@ DIR *warn_opendir(const char *path) } return dp; } -#endif -#ifdef L_xopendir // Die with an error message if opendir() fails. DIR *xopendir(const char *path) { @@ -453,9 +399,7 @@ DIR *xopendir(const char *path) bb_perror_msg_and_die("unable to open `%s'", path); return dp; } -#endif -#ifdef L_xdaemon #ifndef BB_NOMMU // Die with an error message if we can't daemonize. void xdaemon(int nochdir, int noclose) @@ -463,9 +407,7 @@ void xdaemon(int nochdir, int noclose) if (daemon(nochdir, noclose)) bb_perror_msg_and_die("daemon"); } #endif -#endif -#ifdef L_xsocket // Die with an error message if we can't open a new socket. int xsocket(int domain, int type, int protocol) { @@ -475,34 +417,26 @@ int xsocket(int domain, int type, int protocol) return r; } -#endif -#ifdef L_xbind // Die with an error message if we can't bind a socket to an address. void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) { if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind"); } -#endif -#ifdef L_xlisten // Die with an error message if we can't listen for connections on a socket. void xlisten(int s, int backlog) { if (listen(s, backlog)) bb_perror_msg_and_die("listen"); } -#endif -#ifdef L_xstat // xstat() - a stat() which dies on failure with meaningful error message void xstat(char *name, struct stat *stat_buf) { if (stat(name, stat_buf)) bb_perror_msg_and_die("can't stat '%s'", name); } -#endif -#ifdef L_get_terminal_width_height /* It is perfectly ok to pass in a NULL for either width or for * * height, in which case that value will not be set. */ int get_terminal_width_height(int fd, int *width, int *height) @@ -524,4 +458,3 @@ int get_terminal_width_height(int fd, int *width, int *height) return ret; } -#endif diff --git a/libbb/xgetularg.c b/libbb/xgetularg.c index 21b0d12f7..17ba581f7 100644 --- a/libbb/xgetularg.c +++ b/libbb/xgetularg.c @@ -15,7 +15,6 @@ #include #include "libbb.h" -#ifdef L_xgetularg_bnd_sfx unsigned long bb_xgetularg_bnd_sfx(const char *arg, int base, unsigned long lower, unsigned long upper, @@ -75,9 +74,7 @@ unsigned long bb_xgetularg_bnd_sfx(const char *arg, int base, return r; } -#endif -#ifdef L_xgetlarg_bnd_sfx long bb_xgetlarg_bnd_sfx(const char *arg, int base, long lower, long upper, @@ -104,36 +101,27 @@ long bb_xgetlarg_bnd_sfx(const char *arg, int base, return r; } -#endif -#ifdef L_getlarg10_sfx long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes) { return bb_xgetlarg_bnd_sfx(arg, 10, LONG_MIN, LONG_MAX, suffixes); } -#endif -#ifdef L_xgetularg_bnd unsigned long bb_xgetularg_bnd(const char *arg, int base, unsigned long lower, unsigned long upper) { return bb_xgetularg_bnd_sfx(arg, base, lower, upper, NULL); } -#endif -#ifdef L_xgetularg10_bnd unsigned long bb_xgetularg10_bnd(const char *arg, unsigned long lower, unsigned long upper) { return bb_xgetularg_bnd(arg, 10, lower, upper); } -#endif -#ifdef L_xgetularg10 unsigned long bb_xgetularg10(const char *arg) { return bb_xgetularg10_bnd(arg, 0, ULONG_MAX); } -#endif diff --git a/libpwdgrp/Kbuild b/libpwdgrp/Kbuild new file mode 100644 index 000000000..36a6ce393 --- /dev/null +++ b/libpwdgrp/Kbuild @@ -0,0 +1,7 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:=pwd_grp.o diff --git a/libpwdgrp/Makefile b/libpwdgrp/Makefile deleted file mode 100644 index 630a7688f..000000000 --- a/libpwdgrp/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/libpwgrp -LIBPWDGRP_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/libpwdgrp/Makefile.in b/libpwdgrp/Makefile.in deleted file mode 100644 index 2511d34ef..000000000 --- a/libpwdgrp/Makefile.in +++ /dev/null @@ -1,51 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -LIBPWDGRP_AR:=libpwdgrp.a -ifndef $(LIBPWDGRP_DIR) -LIBPWDGRP_DIR:=$(top_builddir)/libpwdgrp -endif -srcdir=$(top_srcdir)/libpwdgrp - -LIBPWDGRP-obj:=$(LIBPWDGRP_DIR)/$(LIBPWDGRP_AR) - -libraries-y+=$(LIBPWDGRP_DIR)/$(LIBPWDGRP_AR) - -LIBPWDGRP_MSRC0:=$(srcdir)/pwd_grp.c -LIBPWDGRP_MOBJ0-$(CONFIG_USE_BB_PWD_GRP):= fgetpwent_r.o fgetgrent_r.o \ - fgetpwent.o fgetgrent.o getpwnam_r.o getgrnam_r.o getpwuid_r.o \ - getgrgid_r.o getpwuid.o getgrgid.o getpwnam.o getgrnam.o getpw.o \ - getpwent_r.o getgrent_r.o getpwent.o getgrent.o \ - initgroups.o putpwent.o putgrent.o -LIBPWDGRP_MOBJS0=$(patsubst %,$(LIBPWDGRP_DIR)/%, $(LIBPWDGRP_MOBJ0-y)) - -LIBPWDGRP_MSRC1:=$(srcdir)/pwd_grp.c -LIBPWDGRP_MOBJ1-$(CONFIG_USE_BB_PWD_GRP):= __parsepwent.o __parsegrent.o \ - __pgsreader.o fgetspent_r.o fgetspent.o sgetspent_r.o getspnam_r.o \ - getspnam.o getspent_r.o getspent.o sgetspent.o \ - putspent.o __parsespent.o # getspuid_r.o getspuid.o -LIBPWDGRP_MOBJS1=$(patsubst %,$(LIBPWDGRP_DIR)/%, $(LIBPWDGRP_MOBJ1-y)) - -LIBPWDGRP_DEFINE0-y:=$(patsubst %,-DL_%,$(subst .o,,$(notdir $(LIBPWDGRP_MOBJS0)))) -LIBPWDGRP_DEFINE1-y:=$(patsubst %,-DL_%,$(subst .o,,$(notdir $(LIBPWDGRP_MOBJS1)))) - -LIBPWDGRP_SRC-y:=$(LIBPWDGRP_MSRC0) - -LIBRARY_SRC-y+=$(LIBPWDGRP_SRC-y) -LIBRARY_SRC-a+=$(LIBPWDGRP_SRC-y) - -LIBRARY_DEFINE-y+=$(LIBPWDGRP_DEFINE0-y) $(LIBPWDGRP_DEFINE1-y) -LIBRARY_DEFINE-a+=$(LIBPWDGRP_DEFINE0-y) $(LIBPWDGRP_DEFINE1-y) - - -$(LIBPWDGRP_DIR)/$(LIBPWDGRP_AR): $(LIBPWDGRP_MOBJS0) $(LIBPWDGRP_MOBJS1) - $(do_ar) - -$(LIBPWDGRP_MOBJS0): $(LIBPWDGRP_MSRC0) - $(compile.c) -DL_$(notdir $*) - -$(LIBPWDGRP_MOBJS1): $(LIBPWDGRP_MSRC1) - $(compile.c) -DL_$(notdir $*) diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c index 132ec60be..ac65d4c5b 100644 --- a/libpwdgrp/pwd_grp.c +++ b/libpwdgrp/pwd_grp.c @@ -29,8 +29,6 @@ #include #include -#include "shadow_.h" - #ifndef _PATH_SHADOW #define _PATH_SHADOW "/etc/shadow" #endif @@ -57,7 +55,7 @@ extern int __parsegrent(void *gr, char *line); extern int __parsespent(void *sp, char *line); extern int __pgsreader(int (*__parserfunc)(void *d, char *line), void *data, - char *__restrict line_buff, size_t buflen, FILE *f); + char *__restrict line_buff, size_t buflen, FILE *f); /**********************************************************************/ /* For the various fget??ent_r funcs, return @@ -75,8 +73,6 @@ extern int __pgsreader(int (*__parserfunc)(void *d, char *line), void *data, */ /**********************************************************************/ -#ifdef L_fgetpwent_r - int fgetpwent_r(FILE *__restrict stream, struct passwd *__restrict resultbuf, char *__restrict buffer, size_t buflen, struct passwd **__restrict result) @@ -92,10 +88,6 @@ int fgetpwent_r(FILE *__restrict stream, struct passwd *__restrict resultbuf, return rv; } -#endif -/**********************************************************************/ -#ifdef L_fgetgrent_r - int fgetgrent_r(FILE *__restrict stream, struct group *__restrict resultbuf, char *__restrict buffer, size_t buflen, struct group **__restrict result) @@ -111,10 +103,6 @@ int fgetgrent_r(FILE *__restrict stream, struct group *__restrict resultbuf, return rv; } -#endif -/**********************************************************************/ -#ifdef L_fgetspent_r - int fgetspent_r(FILE *__restrict stream, struct spwd *__restrict resultbuf, char *__restrict buffer, size_t buflen, struct spwd **__restrict result) @@ -130,13 +118,11 @@ int fgetspent_r(FILE *__restrict stream, struct spwd *__restrict resultbuf, return rv; } -#endif /**********************************************************************/ /* For the various fget??ent funcs, return NULL on failure and a * pointer to the appropriate struct (statically allocated) on success. */ /**********************************************************************/ -#ifdef L_fgetpwent struct passwd *fgetpwent(FILE *stream) { @@ -148,10 +134,6 @@ struct passwd *fgetpwent(FILE *stream) return result; } -#endif -/**********************************************************************/ -#ifdef L_fgetgrent - struct group *fgetgrent(FILE *stream) { static char buffer[GRP_BUFFER_SIZE]; @@ -162,10 +144,6 @@ struct group *fgetgrent(FILE *stream) return result; } -#endif -/**********************************************************************/ -#ifdef L_fgetspent - extern int fgetspent_r(FILE *__restrict stream, struct spwd *__restrict resultbuf, char *__restrict buffer, size_t buflen, struct spwd **__restrict result); @@ -179,10 +157,6 @@ struct spwd *fgetspent(FILE *stream) return result; } -#endif -/**********************************************************************/ -#ifdef L_sgetspent_r - int sgetspent_r(const char *string, struct spwd *result_buf, char *buffer, size_t buflen, struct spwd **result) { @@ -211,65 +185,53 @@ int sgetspent_r(const char *string, struct spwd *result_buf, return rv; } -#endif /**********************************************************************/ #ifdef GETXXKEY_R_FUNC #error GETXXKEY_R_FUNC is already defined! #endif -#ifdef L_getpwnam_r -#define GETXXKEY_R_FUNC getpwnam_r +#define GETXXKEY_R_FUNC getpwnam_R #define GETXXKEY_R_PARSER __parsepwent #define GETXXKEY_R_ENTTYPE struct passwd #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->pw_name, key)) #define DO_GETXXKEY_R_KEYTYPE const char *__restrict #define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD #include "pwd_grp_internal.c" -#endif -#ifdef L_getgrnam_r -#define GETXXKEY_R_FUNC getgrnam_r +#define GETXXKEY_R_FUNC getgrnam_R #define GETXXKEY_R_PARSER __parsegrent #define GETXXKEY_R_ENTTYPE struct group #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->gr_name, key)) #define DO_GETXXKEY_R_KEYTYPE const char *__restrict #define DO_GETXXKEY_R_PATHNAME _PATH_GROUP #include "pwd_grp_internal.c" -#endif -#ifdef L_getspnam_r -#define GETXXKEY_R_FUNC getspnam_r +#define GETXXKEY_R_FUNC getspnam_R #define GETXXKEY_R_PARSER __parsespent #define GETXXKEY_R_ENTTYPE struct spwd #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->sp_namp, key)) #define DO_GETXXKEY_R_KEYTYPE const char *__restrict #define DO_GETXXKEY_R_PATHNAME _PATH_SHADOW #include "pwd_grp_internal.c" -#endif -#ifdef L_getpwuid_r -#define GETXXKEY_R_FUNC getpwuid_r +#define GETXXKEY_R_FUNC getpwuid_R #define GETXXKEY_R_PARSER __parsepwent #define GETXXKEY_R_ENTTYPE struct passwd #define GETXXKEY_R_TEST(ENT) ((ENT)->pw_uid == key) #define DO_GETXXKEY_R_KEYTYPE uid_t #define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD #include "pwd_grp_internal.c" -#endif -#ifdef L_getgrgid_r -#define GETXXKEY_R_FUNC getgrgid_r +#define GETXXKEY_R_FUNC getgrgid_R #define GETXXKEY_R_PARSER __parsegrent #define GETXXKEY_R_ENTTYPE struct group #define GETXXKEY_R_TEST(ENT) ((ENT)->gr_gid == key) #define DO_GETXXKEY_R_KEYTYPE gid_t #define DO_GETXXKEY_R_PATHNAME _PATH_GROUP #include "pwd_grp_internal.c" -#endif /**********************************************************************/ -#ifdef L_getpwuid struct passwd *getpwuid(uid_t uid) { @@ -281,10 +243,6 @@ struct passwd *getpwuid(uid_t uid) return result; } -#endif -/**********************************************************************/ -#ifdef L_getgrgid - struct group *getgrgid(gid_t gid) { static char buffer[GRP_BUFFER_SIZE]; @@ -295,10 +253,6 @@ struct group *getgrgid(gid_t gid) return result; } -#endif -/**********************************************************************/ -#ifdef L_getspuid_r - /* This function is non-standard and is currently not built. It seems * to have been created as a reentrant version of the non-standard * functions getspuid. Why getspuid was added, I do not know. */ @@ -320,10 +274,6 @@ int getspuid_r(uid_t uid, struct spwd *__restrict resultbuf, return rv; } -#endif -/**********************************************************************/ -#ifdef L_getspuid - /* This function is non-standard and is currently not built. * Why it was added, I do not know. */ @@ -337,10 +287,6 @@ struct spwd *getspuid(uid_t uid) return result; } -#endif -/**********************************************************************/ -#ifdef L_getpwnam - struct passwd *getpwnam(const char *name) { static char buffer[PWD_BUFFER_SIZE]; @@ -351,10 +297,6 @@ struct passwd *getpwnam(const char *name) return result; } -#endif -/**********************************************************************/ -#ifdef L_getgrnam - struct group *getgrnam(const char *name) { static char buffer[GRP_BUFFER_SIZE]; @@ -365,10 +307,6 @@ struct group *getgrnam(const char *name) return result; } -#endif -/**********************************************************************/ -#ifdef L_getspnam - struct spwd *getspnam(const char *name) { static char buffer[PWD_BUFFER_SIZE]; @@ -379,10 +317,6 @@ struct spwd *getspnam(const char *name) return result; } -#endif -/**********************************************************************/ -#ifdef L_getpw - int getpw(uid_t uid, char *buf) { struct passwd resultbuf; @@ -406,10 +340,8 @@ int getpw(uid_t uid, char *buf) return -1; } -#endif /**********************************************************************/ -#if defined(L_getpwent_r) || defined(L_getgrent_r) || defined(L_getspent_r) #if defined CONFIG_USE_BB_THREADSAFE_SHADOW && defined PTHREAD_MUTEX_INITIALIZER static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; # define LOCK pthread_mutex_lock(&mylock) @@ -418,9 +350,7 @@ static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; # define LOCK ((void) 0) # define UNLOCK ((void) 0) #endif -#endif -#ifdef L_getpwent_r static FILE *pwf /*= NULL*/; void setpwent(void) { @@ -468,10 +398,6 @@ int getpwent_r(struct passwd *__restrict resultbuf, return rv; } -#endif -/**********************************************************************/ -#ifdef L_getgrent_r - static FILE *grf /*= NULL*/; void setgrent(void) { @@ -518,10 +444,6 @@ int getgrent_r(struct group *__restrict resultbuf, return rv; } -#endif -/**********************************************************************/ -#ifdef L_getspent_r - static FILE *spf /*= NULL*/; void setspent(void) { @@ -567,10 +489,6 @@ int getspent_r(struct spwd *resultbuf, char *buffer, return rv; } -#endif -/**********************************************************************/ -#ifdef L_getpwent - struct passwd *getpwent(void) { static char line_buff[PWD_BUFFER_SIZE]; @@ -581,10 +499,6 @@ struct passwd *getpwent(void) return result; } -#endif -/**********************************************************************/ -#ifdef L_getgrent - struct group *getgrent(void) { static char line_buff[GRP_BUFFER_SIZE]; @@ -595,10 +509,6 @@ struct group *getgrent(void) return result; } -#endif -/**********************************************************************/ -#ifdef L_getspent - struct spwd *getspent(void) { static char line_buff[PWD_BUFFER_SIZE]; @@ -609,10 +519,6 @@ struct spwd *getspent(void) return result; } -#endif -/**********************************************************************/ -#ifdef L_sgetspent - struct spwd *sgetspent(const char *string) { static char line_buff[PWD_BUFFER_SIZE]; @@ -623,10 +529,6 @@ struct spwd *sgetspent(const char *string) return result; } -#endif -/**********************************************************************/ -#ifdef L_initgroups - int initgroups(const char *user, gid_t gid) { FILE *grfile; @@ -679,10 +581,6 @@ int initgroups(const char *user, gid_t gid) return rv; } -#endif -/**********************************************************************/ -#ifdef L_putpwent - int putpwent(const struct passwd *__restrict p, FILE *__restrict f) { int rv = -1; @@ -704,10 +602,6 @@ int putpwent(const struct passwd *__restrict p, FILE *__restrict f) return rv; } -#endif -/**********************************************************************/ -#ifdef L_putgrent - int putgrent(const struct group *__restrict p, FILE *__restrict f) { static const char format[] = ",%s"; @@ -749,10 +643,6 @@ int putgrent(const struct group *__restrict p, FILE *__restrict f) return rv; } -#endif -/**********************************************************************/ -#ifdef L_putspent - static const unsigned char _sp_off[] = { offsetof(struct spwd, sp_lstchg), /* 2 - not a char ptr */ offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ @@ -799,11 +689,9 @@ DO_UNLOCK: return rv; } -#endif /**********************************************************************/ /* Internal uClibc functions. */ /**********************************************************************/ -#ifdef L___parsepwent static const unsigned char pw_off[] = { offsetof(struct passwd, pw_name), /* 0 */ @@ -860,9 +748,7 @@ int __parsepwent(void *data, char *line) return -1; } -#endif /**********************************************************************/ -#ifdef L___parsegrent static const unsigned char gr_off[] = { offsetof(struct group, gr_name), /* 0 */ @@ -958,9 +844,7 @@ int __parsegrent(void *data, char *line) return -1; } -#endif /**********************************************************************/ -#ifdef L___parsespent static const unsigned char sp_off[] = { offsetof(struct spwd, sp_namp), /* 0 */ @@ -1017,9 +901,7 @@ int __parsespent(void *data, char * line) return EINVAL; } -#endif /**********************************************************************/ -#ifdef L___pgsreader /* Reads until if EOF, or until if finds a line which fits in the buffer * and for which the parser function succeeds. @@ -1084,5 +966,4 @@ int __pgsreader(int (*__parserfunc)(void *d, char *line), void *data, return rv; } -#endif /**********************************************************************/ diff --git a/libpwdgrp/pwd_grp_internal.c b/libpwdgrp/pwd_grp_internal.c index 39c11f677..866ed3699 100644 --- a/libpwdgrp/pwd_grp_internal.c +++ b/libpwdgrp/pwd_grp_internal.c @@ -18,96 +18,45 @@ * */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pwd_.h" -#include "grp_.h" -#include "shadow_.h" -#include "libbb.h" - -#ifndef _PATH_SHADOW -#define _PATH_SHADOW "/etc/shadow" -#endif -#ifndef _PATH_PASSWD -#define _PATH_PASSWD "/etc/passwd" -#endif -#ifndef _PATH_GROUP -#define _PATH_GROUP "/etc/group" -#endif - -/**********************************************************************/ -/* Sizes for statically allocated buffers. */ - -/* If you change these values, also change _SC_GETPW_R_SIZE_MAX and - * _SC_GETGR_R_SIZE_MAX in libc/unistd/sysconf.c to match */ -#define PWD_BUFFER_SIZE 256 -#define GRP_BUFFER_SIZE 256 - -/**********************************************************************/ -/* Prototypes for internal functions. */ - -extern int __parsepwent(void *pw, char *line); -extern int __parsegrent(void *gr, char *line); -extern int __parsespent(void *sp, char *line); - -extern int __pgsreader(int (*__parserfunc)(void *d, char *line), void *data, - char *__restrict line_buff, size_t buflen, FILE *f); - - #ifndef GETXXKEY_R_FUNC #error GETXXKEY_R_FUNC is not defined! #endif -/**********************************************************************/ -#ifdef GETXXKEY_R_FUNC int GETXXKEY_R_FUNC(DO_GETXXKEY_R_KEYTYPE key, - GETXXKEY_R_ENTTYPE *__restrict resultbuf, - char *__restrict buffer, size_t buflen, - GETXXKEY_R_ENTTYPE **__restrict result) + GETXXKEY_R_ENTTYPE *__restrict resultbuf, + char *__restrict buffer, size_t buflen, + GETXXKEY_R_ENTTYPE **__restrict result) { FILE *stream; int rv; *result = NULL; - if (!(stream = fopen(DO_GETXXKEY_R_PATHNAME, "r"))) { - rv = errno; - } else { - do { - if (!(rv = __pgsreader(GETXXKEY_R_PARSER, resultbuf, - buffer, buflen, stream)) - ) { - if (GETXXKEY_R_TEST(resultbuf)) { /* Found key? */ - *result = resultbuf; - break; - } - } else { - if (rv == ENOENT) { /* end-of-file encountered. */ - rv = 0; - } + stream = fopen(DO_GETXXKEY_R_PATHNAME, "r"); + if (!stream) + return errno; + while (1) { + rv = __pgsreader(GETXXKEY_R_PARSER, resultbuf, buffer, buflen, stream); + if (!rv) { + if (GETXXKEY_R_TEST(resultbuf)) { /* Found key? */ + *result = resultbuf; break; } - } while (1); - fclose(stream); + } else { + if (rv == ENOENT) { /* end-of-file encountered. */ + rv = 0; + } + break; + } } + fclose(stream); return rv; } -#endif -/**********************************************************************/ #undef GETXXKEY_R_FUNC #undef GETXXKEY_R_PARSER #undef GETXXKEY_R_ENTTYPE #undef GETXXKEY_R_TEST #undef DO_GETXXKEY_R_KEYTYPE #undef DO_GETXXKEY_R_PATHNAME - diff --git a/loginutils/Config.in b/loginutils/Config.in index 6e45b706a..f434585ef 100644 --- a/loginutils/Config.in +++ b/loginutils/Config.in @@ -5,7 +5,7 @@ menu "Login/Password Management Utilities" -config CONFIG_FEATURE_SHADOWPASSWDS +config FEATURE_SHADOWPASSWDS bool "Support for shadow passwords" default n help @@ -13,10 +13,10 @@ config CONFIG_FEATURE_SHADOWPASSWDS readable by root and thus the encrypted passwords are no longer publicly readable. -config CONFIG_USE_BB_SHADOW +config USE_BB_SHADOW bool " Use busybox shadow password functions" default y - depends on CONFIG_USE_BB_PWD_GRP && CONFIG_FEATURE_SHADOWPASSWDS + depends on USE_BB_PWD_GRP && FEATURE_SHADOWPASSWDS help If you leave this disabled, busybox will use the system's shadow password handling functions. And if you are using the GNU C library @@ -32,7 +32,7 @@ config CONFIG_USE_BB_SHADOW able to use PAM to access shadow passwords from remote LDAP password servers and whatnot. -config CONFIG_USE_BB_PWD_GRP +config USE_BB_PWD_GRP bool "Use internal password and group functions rather than system functions" default n help @@ -53,86 +53,86 @@ config CONFIG_USE_BB_PWD_GRP If you enable this option, it will add about 1.5k to busybox. -config CONFIG_ADDGROUP +config ADDGROUP bool "addgroup" default n help Utility for creating a new group account. -config CONFIG_DELGROUP +config DELGROUP bool "delgroup" default n help Utility for deleting a group account. -config CONFIG_ADDUSER +config ADDUSER bool "adduser" default n help Utility for creating a new user account. -config CONFIG_DELUSER +config DELUSER bool "deluser" default n help Utility for deleting a user account. -config CONFIG_GETTY +config GETTY bool "getty" default n - select CONFIG_FEATURE_SYSLOG + select FEATURE_SYSLOG help getty lets you log in on a tty, it is normally invoked by init. -config CONFIG_FEATURE_UTMP +config FEATURE_UTMP bool "Support utmp file" - depends on CONFIG_GETTY || CONFIG_LOGIN || CONFIG_SU || CONFIG_WHO + depends on GETTY || LOGIN || SU || WHO default n help The file /var/run/utmp is used to track who is currently logged in. -config CONFIG_FEATURE_WTMP +config FEATURE_WTMP bool "Support wtmp file" - depends on CONFIG_GETTY || CONFIG_LOGIN || CONFIG_SU || CONFIG_LAST + depends on GETTY || LOGIN || SU || LAST default n - select CONFIG_FEATURE_UTMP + select FEATURE_UTMP help The file /var/run/wtmp is used to track when user's have logged into and logged out of the system. -config CONFIG_LOGIN +config LOGIN bool "login" default n - select CONFIG_FEATURE_SUID - select CONFIG_FEATURE_SYSLOG + select FEATURE_SUID + select FEATURE_SYSLOG help login is used when signing onto a system. Note that Busybox binary must be setuid root for this applet to work properly. -config CONFIG_LOGIN_SCRIPTS +config LOGIN_SCRIPTS bool "Support for login scripts" - depends on CONFIG_LOGIN + depends on LOGIN default n help Enable this if you want login to execute $LOGIN_PRE_SUID_SCRIPT just prior to swithching from root to logged-in user. -config CONFIG_FEATURE_SECURETTY +config FEATURE_SECURETTY bool "Support for /etc/securetty" default y - depends on CONFIG_LOGIN + depends on LOGIN help The file /etc/securetty is used by (some versions of) login(1). The file contains the device names of tty lines (one per line, without leading /dev/) on which root is allowed to login. -config CONFIG_PASSWD +config PASSWD bool "passwd" default n - select CONFIG_FEATURE_SUID - select CONFIG_FEATURE_SYSLOG + select FEATURE_SUID + select FEATURE_SYSLOG help passwd changes passwords for user and group accounts. A normal user may only change the password for his/her own account, the super user @@ -142,11 +142,11 @@ config CONFIG_PASSWD Note that Busybox binary must be setuid root for this applet to work properly. -config CONFIG_SU +config SU bool "su" default n - select CONFIG_FEATURE_SUID - select CONFIG_FEATURE_SYSLOG + select FEATURE_SUID + select FEATURE_SYSLOG help su is used to become another user during a login session. Invoked without a username, su defaults to becoming the super user. @@ -154,25 +154,25 @@ config CONFIG_SU Note that Busybox binary must be setuid root for this applet to work properly. -config CONFIG_SU_SYSLOG +config SU_SYSLOG bool "Support for syslog in su" default y - depends on CONFIG_SU + depends on SU help Enables support for syslog in su. -config CONFIG_SULOGIN +config SULOGIN bool "sulogin" default n - select CONFIG_FEATURE_SYSLOG + select FEATURE_SYSLOG help sulogin is invoked when the system goes into single user mode (this is done through an entry in inittab). -config CONFIG_VLOCK +config VLOCK bool "vlock" default n - select CONFIG_FEATURE_SUID + select FEATURE_SUID help Build the "vlock" applet which allows you to lock (virtual) terminals. diff --git a/loginutils/Kbuild b/loginutils/Kbuild new file mode 100644 index 000000000..6c9d193e1 --- /dev/null +++ b/loginutils/Kbuild @@ -0,0 +1,17 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_ADDGROUP) += addgroup.o +lib-$(CONFIG_ADDUSER) += adduser.o +lib-$(CONFIG_GETTY) += getty.o +lib-$(CONFIG_LOGIN) += login.o +lib-$(CONFIG_PASSWD) += passwd.o +lib-$(CONFIG_SU) += su.o +lib-$(CONFIG_SULOGIN) += sulogin.o +lib-$(CONFIG_VLOCK) += vlock.o +lib-$(CONFIG_DELUSER) += deluser.o +lib-$(CONFIG_DELGROUP) += deluser.o diff --git a/loginutils/Makefile b/loginutils/Makefile deleted file mode 100644 index b81f42964..000000000 --- a/loginutils/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/loginutils -LOGINUTILS_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/loginutils/Makefile.in b/loginutils/Makefile.in deleted file mode 100644 index 0063762ab..000000000 --- a/loginutils/Makefile.in +++ /dev/null @@ -1,52 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -LOGINUTILS_AR:=loginutils.a -ifndef LOGINUTILS_DIR -LOGINUTILS_DIR:=$(top_builddir)/loginutils/ -endif -srcdir=$(top_srcdir)/loginutils - -LOGINUTILS-y:= -LOGINUTILS-$(CONFIG_ADDGROUP) += addgroup.o -LOGINUTILS-$(CONFIG_ADDUSER) += adduser.o -LOGINUTILS-$(CONFIG_GETTY) += getty.o -LOGINUTILS-$(CONFIG_LOGIN) += login.o -LOGINUTILS-$(CONFIG_PASSWD) += passwd.o -LOGINUTILS-$(CONFIG_SU) += su.o -LOGINUTILS-$(CONFIG_SULOGIN) += sulogin.o -LOGINUTILS-$(CONFIG_VLOCK) += vlock.o -LOGINUTILS-$(CONFIG_DELUSER) += deluser.o -LOGINUTILS-$(CONFIG_DELGROUP) += deluser.o - -LOGINUTILS-y:=$(sort $(LOGINUTILS-y)) - -ifneq ($(strip $(LOGINUTILS-y)),) -libraries-y+=$(LOGINUTILS_DIR)$(LOGINUTILS_AR) -endif - -LOGINUTILS_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(LOGINUTILS-y)) -LOGINUTILS_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(LOGINUTILS_SRC-y) -APPLET_SRC-a+=$(LOGINUTILS_SRC-a) - -needcrypt-y:= -needcrypt-$(CONFIG_LOGIN) := y -needcrypt-$(CONFIG_PASSWD) := y -needcrypt-$(CONFIG_SU) := y -needcrypt-$(CONFIG_SULOGIN) := y -needcrypt-$(CONFIG_VLOCK) := y - - -ifeq ($(needcrypt-y),y) - LIBRARIES := -lcrypt $(filter-out -lcrypt,$(LIBRARIES)) -endif - -$(LOGINUTILS_DIR)$(LOGINUTILS_AR): $(patsubst %,$(LOGINUTILS_DIR)%, $(LOGINUTILS-y)) - $(do_ar) - -$(LOGINUTILS_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/miscutils/Config.in b/miscutils/Config.in index 50ed4df99..311c7135c 100644 --- a/miscutils/Config.in +++ b/miscutils/Config.in @@ -5,25 +5,25 @@ menu "Miscellaneous Utilities" -config CONFIG_ADJTIMEX +config ADJTIMEX bool "adjtimex" default n help Adjtimex reads and optionally sets adjustment parameters for the Linux clock adjustment algorithm. -config CONFIG_BBCONFIG +config BBCONFIG bool "bbconfig" default n help The bbconfig applet will print the config file with which busybox was built. -config CONFIG_CROND +config CROND bool "crond" default n - select CONFIG_FEATURE_SUID - select CONFIG_FEATURE_SYSLOG + select FEATURE_SUID + select FEATURE_SYSLOG help Crond is a background daemon that parses individual crontab files and executes commands on behalf of the users in question. @@ -35,39 +35,39 @@ config CONFIG_CROND Note that Busybox binary must be setuid root for this applet to work properly. -config CONFIG_DEBUG_CROND_OPTION +config DEBUG_CROND_OPTION bool "Support debug option -d" - depends on CONFIG_CROND + depends on CROND default n help Support option -d to enter debug mode. -config CONFIG_FEATURE_CROND_CALL_SENDMAIL +config FEATURE_CROND_CALL_SENDMAIL bool "Using /usr/sbin/sendmail?" default n - depends on CONFIG_CROND + depends on CROND help Support calling /usr/sbin/sendmail for send cmd outputs. -config CONFIG_CRONTAB +config CRONTAB bool "crontab" default n - select CONFIG_FEATURE_SUID + select FEATURE_SUID help Crontab manipulates the crontab for a particular user. Only the superuser may specify a different user and/or crontab directory. -config CONFIG_DC +config DC bool "dc" default n help Dc is a reverse-polish desk calculator which supports unlimited precision arithmetic. -config CONFIG_DEVFSD +config DEVFSD bool "devfsd (obsolete)" default n - select CONFIG_FEATURE_SYSLOG + select FEATURE_SYSLOG help This is deprecated, and will be removed at the end of 2008. @@ -80,30 +80,30 @@ config CONFIG_DEVFSD But only if they are written UPPERCASE!!!!!!!! -config CONFIG_DEVFSD_MODLOAD +config DEVFSD_MODLOAD bool "Adds support for MODLOAD keyword in devsfd.conf" default n - depends on CONFIG_DEVFSD + depends on DEVFSD help This actually doesn't work with busybox modutils but needs the external modutils. -config CONFIG_DEVFSD_FG_NP +config DEVFSD_FG_NP bool "Enables the -fg and -np options" default n - depends on CONFIG_DEVFSD + depends on DEVFSD help -fg Run the daemon in the foreground. -np Exit after parsing the configuration file. Do not poll for events. -config CONFIG_DEVFSD_VERBOSE +config DEVFSD_VERBOSE bool "Increases logging (and size)" default n - depends on CONFIG_DEVFSD + depends on DEVFSD help Increases logging to stderr or syslog. -config CONFIG_FEATURE_DEVFS +config FEATURE_DEVFS bool " Use devfs names for all devices (obsolete)" default n help @@ -113,126 +113,126 @@ config CONFIG_FEATURE_DEVFS /dev/loop0. If your /dev directory has normal names instead of devfs names, you don't want this. -config CONFIG_EJECT +config EJECT bool "eject" default n help Used to eject cdroms. (defaults to /dev/cdrom) -config CONFIG_LAST +config LAST bool "last" default n - select CONFIG_FEATURE_WTMP + select FEATURE_WTMP help 'last' displays a list of the last users that logged into the system. -config CONFIG_LESS +config LESS bool "less" default n help 'less' is a pager, meaning that it displays text files. It possesses a wide array of features, and is an improvement over 'more'. -config CONFIG_FEATURE_LESS_BRACKETS +config FEATURE_LESS_BRACKETS bool "Enable bracket searching" default y - depends on CONFIG_LESS + depends on LESS help This option adds the capability to search for matching left and right brackets, facilitating programming. -config CONFIG_FEATURE_LESS_FLAGS +config FEATURE_LESS_FLAGS bool "Enable extra flags" default y - depends on CONFIG_LESS + depends on LESS help The extra flags provided do the following: The -M flag enables a more sophisticated status line. The -m flag enables a simpler status line with a percentage. -config CONFIG_FEATURE_LESS_FLAGCS +config FEATURE_LESS_FLAGCS bool "Enable flag changes" default n - depends on CONFIG_LESS + depends on LESS help This enables the ability to change command-line flags within less itself. -config CONFIG_FEATURE_LESS_MARKS +config FEATURE_LESS_MARKS bool "Enable marks" default n - depends on CONFIG_LESS + depends on LESS help Marks enable positions in a file to be stored for easy reference. -config CONFIG_FEATURE_LESS_REGEXP +config FEATURE_LESS_REGEXP bool "Enable regular expressions" default n - depends on CONFIG_LESS + depends on LESS help Enable regular expressions, allowing complex file searches. -config CONFIG_HDPARM +config HDPARM bool "hdparm" default n help Get/Set hard drive parameters. Primarily intended for ATA drives. Adds about 13k (or around 30k if you enable the - CONFIG_FEATURE_HDPARM_GET_IDENTITY option).... + FEATURE_HDPARM_GET_IDENTITY option).... -config CONFIG_FEATURE_HDPARM_GET_IDENTITY +config FEATURE_HDPARM_GET_IDENTITY bool "Support obtaining detailed information directly from drives" default y - depends on CONFIG_HDPARM + depends on HDPARM help Enables the -I and -i options to obtain detailed information directly from drives about their capabilities and supported ATA feature set. If no device name is specified, hdparm will read identify data from stdin. Enabling this option will add about 16k... -config CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF +config FEATURE_HDPARM_HDIO_SCAN_HWIF bool "Register an IDE interface (DANGEROUS)" default n - depends on CONFIG_HDPARM + depends on HDPARM help Enables the 'hdparm -R' option to register an IDE interface. This is dangerous stuff, so you should probably say N. -config CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF +config FEATURE_HDPARM_HDIO_UNREGISTER_HWIF bool "Un-register an IDE interface (DANGEROUS)" default n - depends on CONFIG_HDPARM + depends on HDPARM help Enables the 'hdparm -U' option to un-register an IDE interface. This is dangerous stuff, so you should probably say N. -config CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET +config FEATURE_HDPARM_HDIO_DRIVE_RESET bool "perform device reset (DANGEROUS)" default n - depends on CONFIG_HDPARM + depends on HDPARM help Enables the 'hdparm -w' option to perform a device reset. This is dangerous stuff, so you should probably say N. -config CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF +config FEATURE_HDPARM_HDIO_TRISTATE_HWIF bool "tristate device for hotswap (DANGEROUS)" default n - depends on CONFIG_HDPARM + depends on HDPARM help Enables the 'hdparm -x' option to tristate device for hotswap, and the '-b' option to get/set bus state. This is dangerous stuff, so you should probably say N. -config CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA +config FEATURE_HDPARM_HDIO_GETSET_DMA bool "get/set using_dma flag (DANGEROUS)" default n - depends on CONFIG_HDPARM + depends on HDPARM help Enables the 'hdparm -d' option to get/set using_dma flag. This is dangerous stuff, so you should probably say N. -config CONFIG_MAKEDEVS +config MAKEDEVS bool "makedevs" default n help @@ -253,24 +253,24 @@ config CONFIG_MAKEDEVS choice prompt "Choose makedevs behaviour" - depends CONFIG_MAKEDEVS - default CONFIG_FEATURE_MAKEDEVS_TABLE + depends MAKEDEVS + default FEATURE_MAKEDEVS_TABLE -config CONFIG_FEATURE_MAKEDEVS_LEAF +config FEATURE_MAKEDEVS_LEAF bool "leaf" -config CONFIG_FEATURE_MAKEDEVS_TABLE +config FEATURE_MAKEDEVS_TABLE bool "table" endchoice -config CONFIG_MOUNTPOINT +config MOUNTPOINT bool "mountpoint" default n help mountpoint checks if the directory is a mountpoint. -config CONFIG_MT +config MT bool "mt" default n help @@ -278,7 +278,7 @@ config CONFIG_MT to advance or rewind a tape past a specified number of archive files on the tape. -config CONFIG_READAHEAD +config READAHEAD bool "readahead" default n help @@ -294,7 +294,7 @@ config CONFIG_READAHEAD As readahead(2) blocks until each file has been read, it is best to run this applet as a background job. -config CONFIG_RUNLEVEL +config RUNLEVEL bool "runlevel" default n help @@ -303,32 +303,32 @@ config CONFIG_RUNLEVEL This applet uses utmp but does not rely on busybox supporing utmp on purpose. It is used by e.g. emdebian via /etc/init.d/rc. -config CONFIG_RX +config RX bool "rx" default n help Receive files using the Xmodem protocol. -config CONFIG_STRINGS +config STRINGS bool "strings" default n help strings prints the printable character sequences for each file specified. -config CONFIG_SETSID +config SETSID bool "setsid" default n help setsid runs a program in a new session -config CONFIG_TASKSET +config TASKSET bool "taskset" default n help Retrieve or set a processes's CPU affinity. -config CONFIG_TIME +config TIME bool "time" default n help @@ -336,7 +336,7 @@ config CONFIG_TIME When the command finishes, time writes a message to standard output giving timing statistics about this program run. -config CONFIG_WATCHDOG +config WATCHDOG bool "watchdog" default n help diff --git a/miscutils/Kbuild b/miscutils/Kbuild new file mode 100644 index 000000000..1c9e9fded --- /dev/null +++ b/miscutils/Kbuild @@ -0,0 +1,27 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_ADJTIMEX) += adjtimex.o +lib-$(CONFIG_CROND) += crond.o +lib-$(CONFIG_CRONTAB) += crontab.o +lib-$(CONFIG_BBCONFIG) += bbconfig.o +lib-$(CONFIG_DC) += dc.o +lib-$(CONFIG_DEVFSD) += devfsd.o +lib-$(CONFIG_EJECT) += eject.o +lib-$(CONFIG_HDPARM) += hdparm.o +lib-$(CONFIG_LAST) += last.o +lib-$(CONFIG_LESS) += less.o +lib-$(CONFIG_MAKEDEVS) += makedevs.o +lib-$(CONFIG_MOUNTPOINT) += mountpoint.o +lib-$(CONFIG_MT) += mt.o +lib-$(CONFIG_READAHEAD) += readahead.o +lib-$(CONFIG_RUNLEVEL) += runlevel.o +lib-$(CONFIG_RX) += rx.o +lib-$(CONFIG_SETSID) += setsid.o +lib-$(CONFIG_STRINGS) += strings.o +lib-$(CONFIG_TIME) += time.o +lib-$(CONFIG_WATCHDOG) += watchdog.o diff --git a/miscutils/Makefile b/miscutils/Makefile deleted file mode 100644 index 91b31ec9e..000000000 --- a/miscutils/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/miscutils -MISCUTILS_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/miscutils/Makefile.in b/miscutils/Makefile.in deleted file mode 100644 index d32d7714e..000000000 --- a/miscutils/Makefile.in +++ /dev/null @@ -1,55 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -MISCUTILS_AR:=miscutils.a -ifndef $(MISCUTILS_DIR) -MISCUTILS_DIR:=$(top_builddir)/miscutils/ -endif -srcdir=$(top_srcdir)/miscutils - -MISCUTILS-y:= -MISCUTILS-$(CONFIG_ADJTIMEX) += adjtimex.o -MISCUTILS-$(CONFIG_CROND) += crond.o -MISCUTILS-$(CONFIG_CRONTAB) += crontab.o -MISCUTILS-$(CONFIG_BBCONFIG) += bbconfig.o -MISCUTILS-$(CONFIG_DC) += dc.o -MISCUTILS-$(CONFIG_DEVFSD) += devfsd.o -MISCUTILS-$(CONFIG_EJECT) += eject.o -MISCUTILS-$(CONFIG_HDPARM) += hdparm.o -MISCUTILS-$(CONFIG_LAST) += last.o -MISCUTILS-$(CONFIG_LESS) += less.o -MISCUTILS-$(CONFIG_MAKEDEVS) += makedevs.o -MISCUTILS-$(CONFIG_MOUNTPOINT) += mountpoint.o -MISCUTILS-$(CONFIG_MT) += mt.o -MISCUTILS-$(CONFIG_READAHEAD) += readahead.o -MISCUTILS-$(CONFIG_RUNLEVEL) += runlevel.o -MISCUTILS-$(CONFIG_RX) += rx.o -MISCUTILS-$(CONFIG_SETSID) += setsid.o -MISCUTILS-$(CONFIG_STRINGS) += strings.o -MISCUTILS-$(CONFIG_TIME) += time.o -MISCUTILS-$(CONFIG_WATCHDOG) += watchdog.o - -ifneq ($(strip $(MISCUTILS-y)),) -libraries-y+=$(MISCUTILS_DIR)$(MISCUTILS_AR) -endif - -MISCUTILS_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(MISCUTILS-y)) -MISCUTILS_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(MISCUTILS_SRC-y) -APPLET_SRC-a+=$(MISCUTILS_SRC-a) - -needlibm-y:= -needlibm-$(CONFIG_DC) := y - -ifeq ($(needlibm-y),y) - LIBRARIES := -lm $(filter-out -lm,$(LIBRARIES)) -endif - -$(MISCUTILS_DIR)$(MISCUTILS_AR): $(patsubst %,$(MISCUTILS_DIR)%, $(MISCUTILS-y)) - $(do_ar) - -$(MISCUTILS_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/miscutils/rx.c b/miscutils/rx.c index 52a76bfd9..00951b711 100644 --- a/miscutils/rx.c +++ b/miscutils/rx.c @@ -266,7 +266,7 @@ int rx_main(int argc, char **argv) filefd = xopen3(fn, O_RDWR|O_CREAT|O_TRUNC, 0666); if (tcgetattr(ttyfd, &tty) < 0) - bb_perror_msg_and_die("%s: tcgetattr failed", argv[0]); + bb_perror_msg_and_die("tcgetattr"); orig_tty = tty; @@ -284,8 +284,7 @@ int rx_main(int argc, char **argv) tcsetattr(ttyfd, TCSAFLUSH, &orig_tty); if (n < 0) - bb_error_msg_and_die("\n%s: receive failed:\n %s", - argv[0], error_buf); + bb_error_msg_and_die("\nreceive failed:\n %s", error_buf); bb_fflush_stdout_and_exit(EXIT_SUCCESS); } diff --git a/modutils/Config.in b/modutils/Config.in index 8974fb795..b28c66d24 100644 --- a/modutils/Config.in +++ b/modutils/Config.in @@ -5,24 +5,24 @@ menu "Linux Module Utilities" -config CONFIG_INSMOD +config INSMOD bool "insmod" default n help insmod is used to load specified modules in the running kernel. -config CONFIG_FEATURE_INSMOD_VERSION_CHECKING +config FEATURE_INSMOD_VERSION_CHECKING bool "Module version checking" default n - depends on CONFIG_INSMOD && CONFIG_FEATURE_2_4_MODULES + depends on INSMOD && FEATURE_2_4_MODULES help Support checking of versions for modules. This is used to ensure that the kernel and module are made for each other. -config CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS +config FEATURE_INSMOD_KSYMOOPS_SYMBOLS bool "Add module symbols to kernel symbol table" default n - depends on CONFIG_INSMOD && CONFIG_FEATURE_2_4_MODULES + depends on INSMOD && FEATURE_2_4_MODULES help By adding module symbols to the kernel symbol table, Oops messages occuring within kernel modules can be properly debugged. By enabling @@ -30,20 +30,20 @@ config CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS table for properly debugging support. If you are not interested in Oops messages from kernel modules, say N. -config CONFIG_FEATURE_INSMOD_LOADINKMEM +config FEATURE_INSMOD_LOADINKMEM bool "In kernel memory optimization (uClinux only)" default n - depends on CONFIG_INSMOD && CONFIG_FEATURE_2_4_MODULES + depends on INSMOD && FEATURE_2_4_MODULES help This is a special uClinux only memory optimization that lets insmod load the specified kernel module directly into kernel space, reducing memory usage by preventing the need for two copies of the module being loaded into memory. -config CONFIG_FEATURE_INSMOD_LOAD_MAP +config FEATURE_INSMOD_LOAD_MAP bool "Enable load map (-m) option" default n - depends on CONFIG_INSMOD && CONFIG_FEATURE_2_4_MODULES + depends on INSMOD && FEATURE_2_4_MODULES help Enabling this, one would be able to get a load map output on stdout. This makes kernel module debugging @@ -51,36 +51,36 @@ config CONFIG_FEATURE_INSMOD_LOAD_MAP If you don't plan to debug kernel modules, you don't need this option. -config CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL +config FEATURE_INSMOD_LOAD_MAP_FULL bool "Symbols in load map" default y - depends on CONFIG_FEATURE_INSMOD_LOAD_MAP + depends on FEATURE_INSMOD_LOAD_MAP help Without this option, -m will only output section load map. With this option, -m will also output symbols load map. -config CONFIG_RMMOD +config RMMOD bool "rmmod" default n help rmmod is used to unload specified modules from the kernel. -config CONFIG_LSMOD +config LSMOD bool "lsmod" default n help lsmod is used to display a list of loaded modules. -config CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT +config FEATURE_LSMOD_PRETTY_2_6_OUTPUT bool "lsmod pretty output for 2.6.x Linux kernels " default n - depends on CONFIG_LSMOD + depends on LSMOD help This option makes output format of lsmod adjusted to the format of module-init-tools for Linux kernel 2.6. -config CONFIG_MODPROBE +config MODPROBE bool "modprobe" default n help @@ -90,11 +90,11 @@ config CONFIG_MODPROBE Note that in the state, modprobe does not understand multiple module options from the configuration file. See option below. -config CONFIG_FEATURE_MODPROBE_MULTIPLE_OPTIONS +config FEATURE_MODPROBE_MULTIPLE_OPTIONS bool - prompt "Multiple options parsing" if CONFIG_NITPICK + prompt "Multiple options parsing" if NITPICK default y - depends on CONFIG_MODPROBE + depends on MODPROBE help Allow modprobe to understand more than one option to pass to modules. @@ -107,51 +107,51 @@ config CONFIG_FEATURE_MODPROBE_MULTIPLE_OPTIONS Saying Y here is not a bad idea if you're not that short on storage capacity. -config CONFIG_FEATURE_MODPROBE_FANCY_ALIAS +config FEATURE_MODPROBE_FANCY_ALIAS bool - prompt "Fancy alias parsing" if CONFIG_NITPICK + prompt "Fancy alias parsing" if NITPICK default y - depends on CONFIG_MODPROBE && CONFIG_FEATURE_2_6_MODULES + depends on MODPROBE && FEATURE_2_6_MODULES help Say 'y' here to enable parsing of aliases with underscore/dash mismatch between module name and file name, along with bus-specific aliases (such as pci:... or usb:... aliases). comment "Options common to multiple modutils" - depends on CONFIG_INSMOD || CONFIG_RMMOD || CONFIG_MODPROBE || CONFIG_LSMOD + depends on INSMOD || RMMOD || MODPROBE || LSMOD -config CONFIG_FEATURE_CHECK_TAINTED_MODULE +config FEATURE_CHECK_TAINTED_MODULE # Simulate indentation bool "Support tainted module checking with new kernels" default y - depends on CONFIG_INSMOD || CONFIG_LSMOD + depends on INSMOD || LSMOD help Support checking for tainted modules. These are usually binary only modules that will make the linux-kernel list ignore your support request. This option is required to support GPLONLY modules. -config CONFIG_FEATURE_2_4_MODULES +config FEATURE_2_4_MODULES # Simulate indentation bool "Support version 2.2.x to 2.4.x Linux kernels" default y - depends on CONFIG_INSMOD || CONFIG_RMMOD + depends on INSMOD || RMMOD help Support module loading for 2.2.x and 2.4.x Linux kernels. -config CONFIG_FEATURE_2_6_MODULES +config FEATURE_2_6_MODULES # Simulate indentation bool "Support version 2.6.x Linux kernels" default y - depends on CONFIG_INSMOD || CONFIG_RMMOD || CONFIG_MODPROBE + depends on INSMOD || RMMOD || MODPROBE help Support module loading for newer 2.6.x Linux kernels. -config CONFIG_FEATURE_QUERY_MODULE_INTERFACE +config FEATURE_QUERY_MODULE_INTERFACE bool default y - depends on CONFIG_FEATURE_2_4_MODULES && !CONFIG_FEATURE_2_6_MODULES + depends on FEATURE_2_4_MODULES && !FEATURE_2_6_MODULES endmenu diff --git a/modutils/Kbuild b/modutils/Kbuild new file mode 100644 index 000000000..cff02b4f2 --- /dev/null +++ b/modutils/Kbuild @@ -0,0 +1,11 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_INSMOD) += insmod.o +lib-$(CONFIG_LSMOD) += lsmod.o +lib-$(CONFIG_MODPROBE) += modprobe.o +lib-$(CONFIG_RMMOD) += rmmod.o diff --git a/modutils/Makefile b/modutils/Makefile deleted file mode 100644 index 65090c5a2..000000000 --- a/modutils/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/modutils -MODUTILS_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/modutils/Makefile.in b/modutils/Makefile.in deleted file mode 100644 index 5c7c9238e..000000000 --- a/modutils/Makefile.in +++ /dev/null @@ -1,32 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -MODUTILS_AR:=modutils.a -ifndef $(MODUTILS_DIR) -MODUTILS_DIR:=$(top_builddir)/modutils/ -endif -srcdir=$(top_srcdir)/modutils - -MODUTILS-y:= -MODUTILS-$(CONFIG_INSMOD) += insmod.o -MODUTILS-$(CONFIG_LSMOD) += lsmod.o -MODUTILS-$(CONFIG_MODPROBE) += modprobe.o -MODUTILS-$(CONFIG_RMMOD) += rmmod.o - -ifneq ($(strip $(MODUTILS-y)),) -libraries-y+=$(MODUTILS_DIR)$(MODUTILS_AR) -endif - -MODUTILS_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(MODUTILS-y)) -MODUTILS_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(MODUTILS_SRC-y) -APPLET_SRC-a+=$(MODUTILS_SRC-a) - -$(MODUTILS_DIR)$(MODUTILS_AR): $(patsubst %,$(MODUTILS_DIR)%, $(MODUTILS-y)) - $(do_ar) - -$(MODUTILS_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/networking/Config.in b/networking/Config.in index b78ae37e7..f9ea56488 100644 --- a/networking/Config.in +++ b/networking/Config.in @@ -5,132 +5,132 @@ menu "Networking Utilities" -config CONFIG_FEATURE_IPV6 +config FEATURE_IPV6 bool "Enable IPv6 support" default n help Enable IPv6 support in busybox. This adds IPv6 support in the networking applets. -config CONFIG_ARPING +config ARPING bool "arping" default n help Ping hosts by ARP packets -config CONFIG_DNSD +config DNSD bool "dnsd" default n help Small and static DNS server daemon. -config CONFIG_ETHER_WAKE +config ETHER_WAKE bool "ether-wake" default n help Send a magic packet to wake up sleeping machines. -config CONFIG_FAKEIDENTD +config FAKEIDENTD bool "fakeidentd" default n - select CONFIG_FEATURE_SYSLOG + select FEATURE_SYSLOG help fakeidentd listens on the ident port and returns a predefined fake value on any query. -config CONFIG_FTPGET +config FTPGET bool "ftpget" default n help Retrieve a remote file via FTP. -config CONFIG_FTPPUT +config FTPPUT bool "ftpput" default n help Store a remote file via FTP. -config CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS +config FEATURE_FTPGETPUT_LONG_OPTIONS bool "Enable long options in ftpget/ftpput" default n - depends on CONFIG_GETOPT_LONG && (CONFIG_FTPGET || CONFIG_FTPPUT) + depends on GETOPT_LONG && (CONFIG_FTPGET || FTPPUT) help Support long options for the ftpget/ftpput applet. -config CONFIG_HOSTNAME +config HOSTNAME bool "hostname" default n help Show or set the system's host name -config CONFIG_HTTPD +config HTTPD bool "httpd" default n help Serve web pages via an HTTP server. -config CONFIG_FEATURE_HTTPD_WITHOUT_INETD +config FEATURE_HTTPD_WITHOUT_INETD bool "Support using httpd as a daemon (not from inetd)" default n - depends on CONFIG_HTTPD + depends on HTTPD help This option enables uid and port options for the httpd applet, and eliminates the need to be called from the inetd server daemon. -config CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP +config FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP bool "Support reloading the global config file using hup signal" default n - depends on CONFIG_HTTPD && CONFIG_FEATURE_HTTPD_WITHOUT_INETD + depends on HTTPD && FEATURE_HTTPD_WITHOUT_INETD help This option enables processing of SIGHUP to reload cached configuration settings. -config CONFIG_FEATURE_HTTPD_SETUID +config FEATURE_HTTPD_SETUID bool "Enable support -u option" default n - depends on CONFIG_HTTPD && CONFIG_FEATURE_HTTPD_WITHOUT_INETD + depends on HTTPD && FEATURE_HTTPD_WITHOUT_INETD help This option allows the server to run as a specific user rather than defaulting to the user that starts the server. Use of this option requires special privileges to change to a different user. -config CONFIG_FEATURE_HTTPD_BASIC_AUTH +config FEATURE_HTTPD_BASIC_AUTH bool "Enable Basic http Authentication" default y - depends on CONFIG_HTTPD + depends on HTTPD help Utilizes password settings from /etc/httpd.conf for basic authentication on a per url basis. -config CONFIG_FEATURE_HTTPD_AUTH_MD5 +config FEATURE_HTTPD_AUTH_MD5 bool "Support MD5 crypted passwords for http Authentication" default n - depends on CONFIG_FEATURE_HTTPD_BASIC_AUTH + depends on FEATURE_HTTPD_BASIC_AUTH help Enables basic per URL authentication from /etc/httpd.conf using md5 passwords. -config CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES +config FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES bool "Support loading additional MIME types at run-time" default n - depends on CONFIG_HTTPD + depends on HTTPD help This option enables support for additional MIME types at run-time to be specified in the configuration file. -config CONFIG_FEATURE_HTTPD_CGI +config FEATURE_HTTPD_CGI bool "Support Common Gateway Interface (CGI)" default y - depends on CONFIG_HTTPD + depends on HTTPD help This option allows scripts and executables to be invoked when specific URLs are requested. -config CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR +config FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR bool "Enable support for running scripts through an interpreter" default n - depends on CONFIG_FEATURE_HTTPD_CGI + depends on FEATURE_HTTPD_CGI help This option enables support for running scripts through an interpreter. Turn this on if you want PHP scripts to work @@ -138,81 +138,81 @@ config CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR config file: *.php:/path/to/your/php -config CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV +config FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV bool "Support the REMOTE_PORT environment variable for CGI" default n - depends on CONFIG_FEATURE_HTTPD_CGI + depends on FEATURE_HTTPD_CGI help Use of this option can assist scripts in generating references that contain a unique port number. -config CONFIG_FEATURE_HTTPD_ENCODE_URL_STR +config FEATURE_HTTPD_ENCODE_URL_STR bool "Enable the -e option for shell script CGI simplification." default y - depends on CONFIG_HTTPD + depends on HTTPD help This option allows html encoding arbitrary strings for display of the browser. Output goes to stdout. For example, httpd -e "" as "<Hello World>". -config CONFIG_IFCONFIG +config IFCONFIG bool "ifconfig" default n help Ifconfig is used to configure the kernel-resident network interfaces. -config CONFIG_FEATURE_IFCONFIG_STATUS +config FEATURE_IFCONFIG_STATUS bool "Enable status reporting output (+7k)" default y - depends on CONFIG_IFCONFIG + depends on IFCONFIG help If ifconfig is called with no arguments it will display the status of the currently active interfaces. -config CONFIG_FEATURE_IFCONFIG_SLIP +config FEATURE_IFCONFIG_SLIP bool "Enable slip-specific options \"keepalive\" and \"outfill\"" default n - depends on CONFIG_IFCONFIG + depends on IFCONFIG help Allow "keepalive" and "outfill" support for SLIP. If you're not planning on using serial lines, leave this unchecked. -config CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ +config FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ bool "Enable options \"mem_start\", \"io_addr\", and \"irq\"" default n - depends on CONFIG_IFCONFIG + depends on IFCONFIG help Allow the start address for shared memory, start address for I/O, and/or the interrupt line used by the specified device. -config CONFIG_FEATURE_IFCONFIG_HW +config FEATURE_IFCONFIG_HW bool "Enable option \"hw\" (ether only)" default y - depends on CONFIG_IFCONFIG + depends on IFCONFIG help Set the hardware address of this interface, if the device driver supports this operation. Currently, we only support the 'ether' class. -config CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS +config FEATURE_IFCONFIG_BROADCAST_PLUS bool "Set the broadcast automatically" default n - depends on CONFIG_IFCONFIG + depends on IFCONFIG help Setting this will make ifconfig attempt to find the broadcast automatically if the value '+' is used. -config CONFIG_IFUPDOWN +config IFUPDOWN bool "ifupdown" default n - select CONFIG_RUN_PARTS + select RUN_PARTS help Activate or deactivate the specified interfaces. This applet makes use of either "ifconfig" and "route" or the "ip" command to actually configure network interfaces. Therefore, you will probably also want - to enable either CONFIG_IFCONFIG and CONFIG_ROUTE, or enable - CONFIG_FEATURE_IFUPDOWN_IP and the various CONFIG_IP options. Of + to enable either IFCONFIG and ROUTE, or enable + FEATURE_IFUPDOWN_IP and the various IP options. Of course you could use non-busybox versions of these programs, so against my better judgement (since this will surely result in plenty of support questions on the mailing list), I do not force you to @@ -220,34 +220,34 @@ config CONFIG_IFUPDOWN "ifconfig" and "route" or the "ip" command, either via busybox or via standalone utilities. -config CONFIG_FEATURE_IFUPDOWN_IP +config FEATURE_IFUPDOWN_IP bool "Use ip applet" default n - depends on CONFIG_IFUPDOWN + depends on IFUPDOWN help Use the iproute "ip" command to implement "ifup" and "ifdown", rather than the default of using the older 'ifconfig' and 'route' utilities. -config CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN +config FEATURE_IFUPDOWN_IP_BUILTIN bool "Use busybox ip applet" default y - depends on CONFIG_FEATURE_IFUPDOWN_IP - select CONFIG_IP - select CONFIG_FEATURE_IP_ADDRESS - select CONFIG_FEATURE_IP_LINK - select CONFIG_FEATURE_IP_ROUTE + depends on FEATURE_IFUPDOWN_IP + select IP + select FEATURE_IP_ADDRESS + select FEATURE_IP_LINK + select FEATURE_IP_ROUTE help Use the busybox iproute "ip" applet to implement "ifupdown". If leave this disabled, you must install the full-blown iproute2 utility or the "ifup" and "ifdown" applets will not work. -config CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN +config FEATURE_IFUPDOWN_IP_BUILTIN bool "Use busybox ifconfig and route applets" default y - depends on CONFIG_IFUPDOWN && !CONFIG_FEATURE_IFUPDOWN_IP - select CONFIG_IFCONFIG - select CONFIG_ROUTE + depends on IFUPDOWN && !CONFIG_FEATURE_IFUPDOWN_IP + select IFCONFIG + select ROUTE help Use the busybox iproute "ifconfig" and "route" applets to implement the "ifup" and "ifdown" utilities. @@ -256,87 +256,87 @@ config CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN and route utilities, or the "ifup" and "ifdown" applets will not work. -config CONFIG_FEATURE_IFUPDOWN_IPV4 +config FEATURE_IFUPDOWN_IPV4 bool "Enable support for IPv4" default y - depends on CONFIG_IFUPDOWN + depends on IFUPDOWN help If you want busybox to talk IPv4, leave this on. -config CONFIG_FEATURE_IFUPDOWN_IPV6 +config FEATURE_IFUPDOWN_IPV6 bool "Enable support for IPv6" default n - depends on CONFIG_IFUPDOWN && CONFIG_FEATURE_IPV6 + depends on IFUPDOWN && FEATURE_IPV6 help If you need support for IPv6, turn this option on. -config CONFIG_FEATURE_IFUPDOWN_IPX +config FEATURE_IFUPDOWN_IPX bool "Enable support for IPX" default n - depends on CONFIG_IFUPDOWN + depends on IFUPDOWN help If this option is selected you can use busybox to work with IPX networks. -config CONFIG_FEATURE_IFUPDOWN_MAPPING +config FEATURE_IFUPDOWN_MAPPING bool "Enable mapping support" default n - depends on CONFIG_IFUPDOWN + depends on IFUPDOWN help This enables support for the "mapping" stanza, unless you have a weird network setup you don't need it. -config CONFIG_INETD +config INETD bool "inetd" default n - select CONFIG_FEATURE_SYSLOG + select FEATURE_SYSLOG help Internet superserver daemon -config CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO +config FEATURE_INETD_SUPPORT_BUILTIN_ECHO bool "Support echo service" default y - depends on CONFIG_INETD + depends on INETD help Echo received data internal inetd service -config CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD +config FEATURE_INETD_SUPPORT_BUILTIN_DISCARD bool "Support discard service" default y - depends on CONFIG_INETD + depends on INETD help Internet /dev/null internal inetd service -config CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME +config FEATURE_INETD_SUPPORT_BUILTIN_TIME bool "Support time service" default y - depends on CONFIG_INETD + depends on INETD help Return 32 bit time since 1900 internal inetd service -config CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME +config FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME bool "Support daytime service" default y - depends on CONFIG_INETD + depends on INETD help Return human-readable time internal inetd service -config CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN +config FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN bool "Support chargen service" default y - depends on CONFIG_INETD + depends on INETD help Familiar character generator internal inetd service -config CONFIG_FEATURE_INETD_RPC +config FEATURE_INETD_RPC bool "Support RPC services" default n - depends on CONFIG_INETD + depends on INETD help Suuport Sun-RPC based services -config CONFIG_IP +config IP bool "ip" default n help @@ -344,38 +344,38 @@ config CONFIG_IP utility. You generally don't need "ip" to use busybox with TCP/IP. -config CONFIG_FEATURE_IP_ADDRESS +config FEATURE_IP_ADDRESS bool "ip address" default y - depends on CONFIG_IP + depends on IP help Address manipulation support for the "ip" applet. -config CONFIG_FEATURE_IP_LINK +config FEATURE_IP_LINK bool "ip link" default y - depends on CONFIG_IP + depends on IP help Configure network devices with "ip". -config CONFIG_FEATURE_IP_ROUTE +config FEATURE_IP_ROUTE bool "ip route" default y - depends on CONFIG_IP + depends on IP help Add support for routing table management to "ip". -config CONFIG_FEATURE_IP_TUNNEL +config FEATURE_IP_TUNNEL bool "ip tunnel" default n - depends on CONFIG_IP + depends on IP help Add support for tunneling commands to "ip". -config CONFIG_FEATURE_IP_SHORT_FORMS +config FEATURE_IP_SHORT_FORMS bool "Support short forms of ip commands." default n - depends on CONFIG_IP + depends on IP help Also support short-form of ip commands: ip addr -> ipaddr @@ -386,51 +386,51 @@ config CONFIG_FEATURE_IP_SHORT_FORMS Say N unless you desparately need the short form of the ip object commands. -config CONFIG_IPADDR +config IPADDR bool default y - depends on CONFIG_FEATURE_IP_SHORT_FORMS && CONFIG_FEATURE_IP_ADDRESS + depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_ADDRESS -config CONFIG_IPLINK +config IPLINK bool default y - depends on CONFIG_FEATURE_IP_SHORT_FORMS && CONFIG_FEATURE_IP_LINK + depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_LINK -config CONFIG_IPROUTE +config IPROUTE bool default y - depends on CONFIG_FEATURE_IP_SHORT_FORMS && CONFIG_FEATURE_IP_ROUTE + depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_ROUTE -config CONFIG_IPTUNNEL +config IPTUNNEL bool default y - depends on CONFIG_FEATURE_IP_SHORT_FORMS && CONFIG_FEATURE_IP_TUNNEL + depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_TUNNEL -config CONFIG_IPCALC +config IPCALC bool "ipcalc" default n help ipcalc takes an IP address and netmask and calculates the resulting broadcast, network, and host range. -config CONFIG_FEATURE_IPCALC_FANCY +config FEATURE_IPCALC_FANCY bool "Fancy IPCALC, more options, adds 1 kbyte" default y - depends on CONFIG_IPCALC + depends on IPCALC help Adds the options hostname, prefix and silent to the output of "ipcalc". -config CONFIG_FEATURE_IPCALC_LONG_OPTIONS +config FEATURE_IPCALC_LONG_OPTIONS bool "Enable long options" default n - depends on CONFIG_IPCALC && CONFIG_GETOPT_LONG + depends on IPCALC && GETOPT_LONG help Support long options for the ipcalc applet. -config CONFIG_NAMEIF +config NAMEIF bool "nameif" default n - select CONFIG_FEATURE_SYSLOG + select FEATURE_SYSLOG help nameif is used to rename network interface by its MAC address. Renamed interfaces MUST be in the down state. @@ -442,107 +442,107 @@ config CONFIG_NAMEIF # Comment new_interface_name XX:XX:XX:XX:XX:XX -config CONFIG_NC +config NC bool "nc" default n help A simple Unix utility which reads and writes data across network connections. -config CONFIG_NC_SERVER +config NC_SERVER bool "Netcat server options (-lp)" default n - depends on CONFIG_NC + depends on NC help Allow netcat to act as a server. -config CONFIG_NC_EXTRA +config NC_EXTRA bool "Netcat extensions (-eiw and filename)" default n - depends on CONFIG_NC + depends on NC help Add -e (support for executing the rest of the command line after making or receiving a successful connection), -i (delay interval for lines sent), -w (timeout for initial connection). -config CONFIG_NETSTAT +config NETSTAT bool "netstat" default n help netstat prints information about the Linux networking subsystem. -config CONFIG_NSLOOKUP +config NSLOOKUP bool "nslookup" default n help nslookup is a tool to query Internet name servers. -config CONFIG_PING +config PING bool "ping" default n help ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to elicit an ICMP ECHO_RESPONSE from a host or gateway. -config CONFIG_FEATURE_FANCY_PING +config FEATURE_FANCY_PING bool "Enable fancy ping output" default y - depends on CONFIG_PING + depends on PING help Make the output from the ping applet include statistics, and at the same time provide full support for ICMP packets. -config CONFIG_PING6 +config PING6 bool "ping6" default n - depends on CONFIG_FEATURE_IPV6 + depends on FEATURE_IPV6 help This will give you a ping that can talk IPv6. -config CONFIG_FEATURE_FANCY_PING6 +config FEATURE_FANCY_PING6 bool "Enable fancy ping6 output" default y - depends on CONFIG_PING6 + depends on PING6 help Make the output from the ping6 applet include statistics, and at the same time provide full support for ICMP packets. -config CONFIG_ROUTE +config ROUTE bool "route" default n help Route displays or manipulates the kernel's IP routing tables. -config CONFIG_TELNET +config TELNET bool "telnet" default n help Telnet is an interface to the TELNET protocol, but is also commonly used to test other simple protocols. -config CONFIG_FEATURE_TELNET_TTYPE +config FEATURE_TELNET_TTYPE bool "Pass TERM type to remote host" default y - depends on CONFIG_TELNET + depends on TELNET help Setting this option will forward the TERM environment variable to the remote host you are connecting to. This is useful to make sure that things like ANSI colors and other control sequences behave. -config CONFIG_FEATURE_TELNET_AUTOLOGIN +config FEATURE_TELNET_AUTOLOGIN bool "Pass USER type to remote host" default y - depends on CONFIG_TELNET + depends on TELNET help Setting this option will forward the USER environment variable to the remote host you are connecting to. This is useful when you need to log into a machine without telling the username (autologin). This option enables `-a' and `-l USER' arguments. -config CONFIG_TELNETD +config TELNETD bool "telnetd" default n - select CONFIG_FEATURE_SYSLOG + select FEATURE_SYSLOG help A daemon for the TELNET protocol, allowing you to log onto the host running the daemon. Please keep in mind that the TELNET protocol @@ -554,8 +554,8 @@ config CONFIG_TELNETD Note that for busybox telnetd to work you need several things: First of all, your kernel needs: - CONFIG_UNIX98_PTYS=y - CONFIG_DEVPTS_FS=y + UNIX98_PTYS=y + DEVPTS_FS=y Next, you need a /dev/pts directory on your root filesystem: @@ -572,8 +572,8 @@ config CONFIG_TELNETD mount -t devpts devpts /dev/pts - You need to be sure that Busybox has CONFIG_LOGIN and - CONFIG_FEATURE_SUID enabled. And finally, you should make + You need to be sure that Busybox has LOGIN and + FEATURE_SUID enabled. And finally, you should make certain that Busybox has been installed setuid root: chown root.root /bin/busybox @@ -582,15 +582,15 @@ config CONFIG_TELNETD with all that done, telnetd _should_ work.... -config CONFIG_FEATURE_TELNETD_INETD +config FEATURE_TELNETD_INETD bool "Support call from inetd only" default n - depends on CONFIG_TELNETD + depends on TELNETD help Selecting this will make telnetd only callable from inetd, removing the standalone support. -config CONFIG_TFTP +config TFTP bool "tftp" default n help @@ -598,114 +598,114 @@ config CONFIG_TFTP is usually used for simple, small transfers such as a root image for a network-enabled bootloader. -config CONFIG_FEATURE_TFTP_GET +config FEATURE_TFTP_GET bool "Enable \"get\" command" default y - depends on CONFIG_TFTP + depends on TFTP help Add support for the GET command within the TFTP client. This allows a client to retrieve a file from a TFTP server. -config CONFIG_FEATURE_TFTP_PUT +config FEATURE_TFTP_PUT bool "Enable \"put\" command" default y - depends on CONFIG_TFTP + depends on TFTP help Add support for the PUT command within the TFTP client. This allows a client to transfer a file to a TFTP server. -config CONFIG_FEATURE_TFTP_BLOCKSIZE +config FEATURE_TFTP_BLOCKSIZE bool "Enable \"blocksize\" command" default n - depends on CONFIG_TFTP + depends on TFTP help Allow the client to specify the desired block size for transfers. -config CONFIG_DEBUG_TFTP +config DEBUG_TFTP bool "Enable debug" default n - depends on CONFIG_TFTP + depends on TFTP help Enable debug settings for tftp. This is useful if you're running into problems with tftp as the protocol doesn't help you much when you run into problems. -config CONFIG_TRACEROUTE +config TRACEROUTE bool "traceroute" default n help Utility to trace the route of IP packets -config CONFIG_FEATURE_TRACEROUTE_VERBOSE +config FEATURE_TRACEROUTE_VERBOSE bool "Enable verbose output" default n - depends on CONFIG_TRACEROUTE + depends on TRACEROUTE help Add some verbosity to traceroute. This includes amongst other things hostnames and ICMP response types. -config CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE +config FEATURE_TRACEROUTE_SOURCE_ROUTE bool "Enable loose source route" default n - depends on CONFIG_TRACEROUTE + depends on TRACEROUTE help Add option to specify a loose source route gateway (8 maximum). -config CONFIG_FEATURE_TRACEROUTE_USE_ICMP +config FEATURE_TRACEROUTE_USE_ICMP bool "Use ICMP instead of UDP" default n - depends on CONFIG_TRACEROUTE + depends on TRACEROUTE help Add feature to allow for ICMP ECHO instead of UDP datagrams. source networking/udhcp/Config.in -config CONFIG_VCONFIG +config VCONFIG bool "vconfig" default n help Creates, removes, and configures VLAN interfaces -config CONFIG_WGET +config WGET bool "wget" default n help wget is a utility for non-interactive download of files from HTTP, HTTPS, and FTP servers. -config CONFIG_FEATURE_WGET_STATUSBAR +config FEATURE_WGET_STATUSBAR bool "Enable a nifty process meter (+2k)" default y - depends on CONFIG_WGET + depends on WGET help Enable the transfer progress bar for wget transfers. -config CONFIG_FEATURE_WGET_AUTHENTICATION +config FEATURE_WGET_AUTHENTICATION bool "Enable HTTP authentication" default y - depends on CONFIG_WGET + depends on WGET help Support authenticated HTTP transfers. -config CONFIG_FEATURE_WGET_IP6_LITERAL +config FEATURE_WGET_IP6_LITERAL bool "Enable IPv6 literal addresses" default y - depends on CONFIG_WGET && CONFIG_FEATURE_IPV6 + depends on WGET && FEATURE_IPV6 help Support IPv6 address literal notation in URLs. -config CONFIG_FEATURE_WGET_LONG_OPTIONS +config FEATURE_WGET_LONG_OPTIONS bool "Enable long options" default n - depends on CONFIG_WGET && CONFIG_GETOPT_LONG + depends on WGET && GETOPT_LONG help Support long options for the wget applet. -config CONFIG_ZCIP +config ZCIP bool "zcip" default n - select CONFIG_FEATURE_SYSLOG + select FEATURE_SYSLOG help ZCIP provides ZeroConf IPv4 address selection, according to RFC 3927. It's a daemon that allocates and defends a dynamically assigned diff --git a/networking/Kbuild b/networking/Kbuild new file mode 100644 index 000000000..066475925 --- /dev/null +++ b/networking/Kbuild @@ -0,0 +1,38 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_ARPING) += arping.o +lib-$(CONFIG_DNSD) += dnsd.o +lib-$(CONFIG_ETHER_WAKE) += ether-wake.o +lib-$(CONFIG_FAKEIDENTD) += fakeidentd.o +lib-$(CONFIG_FTPGET) += ftpgetput.o +lib-$(CONFIG_FTPPUT) += ftpgetput.o +lib-$(CONFIG_HOSTNAME) += hostname.o +lib-$(CONFIG_HTTPD) += httpd.o +lib-$(CONFIG_IFCONFIG) += ifconfig.o interface.o +lib-$(CONFIG_IFUPDOWN) += ifupdown.o +lib-$(CONFIG_INETD) += inetd.o +lib-$(CONFIG_IP) += ip.o +lib-$(CONFIG_IPCALC) += ipcalc.o +lib-$(CONFIG_IPADDR) += ipaddr.o +lib-$(CONFIG_IPLINK) += iplink.o +lib-$(CONFIG_IPROUTE) += iproute.o +lib-$(CONFIG_IPTUNNEL) += iptunnel.o +lib-$(CONFIG_NAMEIF) += nameif.o +lib-$(CONFIG_NC) += nc.o +lib-$(CONFIG_NETSTAT) += netstat.o +lib-$(CONFIG_NSLOOKUP) += nslookup.o +lib-$(CONFIG_PING) += ping.o +lib-$(CONFIG_PING6) += ping6.o +lib-$(CONFIG_ROUTE) += route.o +lib-$(CONFIG_TELNET) += telnet.o +lib-$(CONFIG_TELNETD) += telnetd.o +lib-$(CONFIG_TFTP) += tftp.o +lib-$(CONFIG_TRACEROUTE) += traceroute.o +lib-$(CONFIG_VCONFIG) += vconfig.o +lib-$(CONFIG_WGET) += wget.o +lib-$(CONFIG_ZCIP) += zcip.o diff --git a/networking/Makefile b/networking/Makefile deleted file mode 100644 index c3f2d79c9..000000000 --- a/networking/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/networking -NETWORKING_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/networking/Makefile.in b/networking/Makefile.in deleted file mode 100644 index 650fc1a4a..000000000 --- a/networking/Makefile.in +++ /dev/null @@ -1,70 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -NETWORKING_AR:=networking.a -ifndef $(NETWORKING_DIR) -NETWORKING_DIR:=$(top_builddir)/networking/ -endif -srcdir=$(top_srcdir)/networking - -NETWORKING-y:= -NETWORKING-$(CONFIG_ARPING) += arping.o -NETWORKING-$(CONFIG_DNSD) += dnsd.o -NETWORKING-$(CONFIG_ETHER_WAKE) += ether-wake.o -NETWORKING-$(CONFIG_FAKEIDENTD) += fakeidentd.o -NETWORKING-$(CONFIG_FTPGET) += ftpgetput.o -NETWORKING-$(CONFIG_FTPPUT) += ftpgetput.o -NETWORKING-$(CONFIG_HOSTNAME) += hostname.o -NETWORKING-$(CONFIG_HTTPD) += httpd.o -NETWORKING-$(CONFIG_IFCONFIG) += ifconfig.o interface.o -NETWORKING-$(CONFIG_IFUPDOWN) += ifupdown.o -NETWORKING-$(CONFIG_INETD) += inetd.o -NETWORKING-$(CONFIG_IP) += ip.o -NETWORKING-$(CONFIG_IPCALC) += ipcalc.o -NETWORKING-$(CONFIG_IPADDR) += ipaddr.o -NETWORKING-$(CONFIG_IPLINK) += iplink.o -NETWORKING-$(CONFIG_IPROUTE) += iproute.o -NETWORKING-$(CONFIG_IPTUNNEL) += iptunnel.o -NETWORKING-$(CONFIG_NAMEIF) += nameif.o -NETWORKING-$(CONFIG_NC) += nc.o -NETWORKING-$(CONFIG_NETSTAT) += netstat.o -NETWORKING-$(CONFIG_NSLOOKUP) += nslookup.o -NETWORKING-$(CONFIG_PING) += ping.o -NETWORKING-$(CONFIG_PING6) += ping6.o -NETWORKING-$(CONFIG_ROUTE) += route.o -NETWORKING-$(CONFIG_TELNET) += telnet.o -NETWORKING-$(CONFIG_TELNETD) += telnetd.o -NETWORKING-$(CONFIG_TFTP) += tftp.o -NETWORKING-$(CONFIG_TRACEROUTE) += traceroute.o -NETWORKING-$(CONFIG_VCONFIG) += vconfig.o -NETWORKING-$(CONFIG_WGET) += wget.o -NETWORKING-$(CONFIG_ZCIP) += zcip.o - -NETWORKING-y:=$(sort $(NETWORKING-y)) -ifneq ($(strip $(NETWORKING-y)),) -libraries-y+=$(NETWORKING_DIR)$(NETWORKING_AR) -endif - -NETWORKING_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(NETWORKING-y)) -NETWORKING_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(NETWORKING_SRC-y) -APPLET_SRC-a+=$(NETWORKING_SRC-a) - -LIBRARY_DEFINE-y+= -I$(top_srcdir)/networking -LIBRARY_DEFINE-a+= -I$(top_srcdir)/networking - -needcrypt-y:= -needcrypt-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) := y - -ifeq ($(needcrypt-y),y) - LIBRARIES := -lcrypt $(filter-out -lcrypt,$(LIBRARIES)) -endif - -$(NETWORKING_DIR)$(NETWORKING_AR): $(patsubst %,$(NETWORKING_DIR)%, $(NETWORKING-y)) - $(do_ar) - -$(NETWORKING_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/networking/libiproute/Kbuild b/networking/libiproute/Kbuild new file mode 100644 index 000000000..476374e19 --- /dev/null +++ b/networking/libiproute/Kbuild @@ -0,0 +1,58 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2004 by Erik Andersen +# +# Licensed under the GPL v2 or later, see the file LICENSE in this tarball. +# + +lib-y:= +lib-$(CONFIG_IP) += \ + ip_parse_common_args.o \ + ipaddress.o \ + iplink.o \ + iproute.o \ + iptunnel.o \ + libnetlink.o \ + ll_addr.o \ + ll_map.o \ + ll_proto.o \ + ll_types.o \ + rt_names.o \ + rtm_map.o \ + utils.o + +lib-$(CONFIG_IPADDR) += \ + ip_parse_common_args.o \ + ipaddress.o \ + libnetlink.o \ + ll_addr.o \ + ll_map.o \ + ll_types.o \ + rt_names.o \ + utils.o + +lib-$(CONFIG_IPLINK) += \ + ip_parse_common_args.o \ + ipaddress.o \ + iplink.o \ + libnetlink.o \ + ll_addr.o \ + ll_map.o \ + ll_types.o \ + rt_names.o \ + utils.o + +lib-$(CONFIG_IPROUTE) += \ + ip_parse_common_args.o \ + iproute.o \ + libnetlink.o \ + ll_map.o \ + rt_names.o \ + rtm_map.o \ + utils.o + +lib-$(CONFIG_IPTUNNEL) += \ + ip_parse_common_args.o \ + iptunnel.o \ + rt_names.o \ + utils.o diff --git a/networking/libiproute/Makefile b/networking/libiproute/Makefile deleted file mode 100644 index 2fafae738..000000000 --- a/networking/libiproute/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2004 by Erik Andersen -# -# 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 -# - -ifndef top_srcdir -top_srcdir=../.. -endif -ifndef top_builddir -top_builddir=../.. -endif -srcdir=$(top_srcdir)/networking/libiproute -LIBIPROUTE_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/networking/libiproute/Makefile.in b/networking/libiproute/Makefile.in deleted file mode 100644 index f713502b3..000000000 --- a/networking/libiproute/Makefile.in +++ /dev/null @@ -1,83 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2004 by Erik Andersen -# -# Licensed under the GPL v2 or later, see the file LICENSE in this tarball. -# - -LIBIPROUTE_AR:=libiproute.a -ifndef $(LIBIPROUTE_DIR) -LIBIPROUTE_DIR:=$(top_builddir)/networking/libiproute -endif -srcdir=$(top_srcdir)/networking/libiproute - -LIBIPROUTE-y:= -LIBIPROUTE-$(CONFIG_IP) += \ - ip_parse_common_args.o \ - ipaddress.o \ - iplink.o \ - iproute.o \ - iptunnel.o \ - libnetlink.o \ - ll_addr.o \ - ll_map.o \ - ll_proto.o \ - ll_types.o \ - rt_names.o \ - rtm_map.o \ - utils.o - -LIBIPROUTE-$(CONFIG_IPADDR) += \ - ip_parse_common_args.o \ - ipaddress.o \ - libnetlink.o \ - ll_addr.o \ - ll_map.o \ - ll_types.o \ - rt_names.o \ - utils.o - -LIBIPROUTE-$(CONFIG_IPLINK) += \ - ip_parse_common_args.o \ - ipaddress.o \ - iplink.o \ - libnetlink.o \ - ll_addr.o \ - ll_map.o \ - ll_types.o \ - rt_names.o \ - utils.o - -LIBIPROUTE-$(CONFIG_IPROUTE) += \ - ip_parse_common_args.o \ - iproute.o \ - libnetlink.o \ - ll_map.o \ - rt_names.o \ - rtm_map.o \ - utils.o - -LIBIPROUTE-$(CONFIG_IPTUNNEL) += \ - ip_parse_common_args.o \ - iptunnel.o \ - rt_names.o \ - utils.o - -LIBIPROUTE-y:=$(sort $(LIBIPROUTE-y)) - -LIBIPROUTE_SRC-y:=$(patsubst %,$(srcdir)/%,$(subst .o,.c,$(LIBIPROUTE-y))) -LIBIPROUTE_SRC-a:=$(wildcard $(srcdir)/*.c) -LIBRARY_SRC-y+=$(LIBIPROUTE_SRC-y) -LIBRARY_SRC-a+=$(LIBIPROUTE_SRC-a) - -LIBIPROUTE-obj:=$(LIBIPROUTE_DIR)/$(LIBIPROUTE_AR) - -ifneq ($(strip $(LIBIPROUTE-y)),) -libraries-y+=$(LIBIPROUTE_DIR)/$(LIBIPROUTE_AR) -endif - -$(LIBIPROUTE_DIR)/$(LIBIPROUTE_AR): $(patsubst %,$(LIBIPROUTE_DIR)/%,$(LIBIPROUTE-y)) - $(do_ar) - -$(LIBIPROUTE_DIR)/%.o: $(srcdir)/%.c - $(compile.c) diff --git a/networking/udhcp/Config.in b/networking/udhcp/Config.in index f01340192..13dbcee9c 100644 --- a/networking/udhcp/Config.in +++ b/networking/udhcp/Config.in @@ -3,7 +3,7 @@ # see scripts/kbuild/config-language.txt. # -config CONFIG_APP_UDHCPD +config APP_UDHCPD bool "udhcp Server (udhcpd)" default n help @@ -12,10 +12,10 @@ config CONFIG_APP_UDHCPD See http://udhcp.busybox.net for further details. -config CONFIG_APP_DUMPLEASES +config APP_DUMPLEASES bool "Lease display utility (dumpleases)" default n - depends on CONFIG_APP_UDHCPD + depends on APP_UDHCPD help dumpleases displays the leases written out by the udhcpd server. Lease times are stored in the file by time remaining in lease, or @@ -23,7 +23,7 @@ config CONFIG_APP_DUMPLEASES See http://udhcp.busybox.net for further details. -config CONFIG_APP_UDHCPC +config APP_UDHCPC bool "udhcp Client (udhcpc)" default n help @@ -35,21 +35,21 @@ config CONFIG_APP_UDHCPC See http://udhcp.busybox.net for further details. -config CONFIG_FEATURE_UDHCP_SYSLOG +config FEATURE_UDHCP_SYSLOG bool "Log udhcp messages to syslog" default n - depends on CONFIG_APP_UDHCPD || CONFIG_APP_UDHCPC - select CONFIG_FEATURE_SYSLOG + depends on APP_UDHCPD || APP_UDHCPC + select FEATURE_SYSLOG help If not daemonized, udhcpd prints its messages to stdout/stderr. If this option is selected, it will also log them to syslog. See http://udhcp.busybox.net for further details. -config CONFIG_FEATURE_UDHCP_DEBUG +config FEATURE_UDHCP_DEBUG bool "Compile udhcp with noisy debugging messages" default n - depends on CONFIG_APP_UDHCPD || CONFIG_APP_UDHCPC + depends on APP_UDHCPD || APP_UDHCPC help If selected, udhcpd will output extra debugging output. If using this option, compile uDHCP with "-g", and do not fork the daemon to diff --git a/networking/udhcp/Kbuild b/networking/udhcp/Kbuild new file mode 100644 index 000000000..90047c174 --- /dev/null +++ b/networking/udhcp/Kbuild @@ -0,0 +1,17 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2004 by Erik Andersen +# +# Licensed under the GPL v2 or later, see the file LICENSE in this tarball. +# + +lib-y:= +lib-$(CONFIG_APP_UDHCPC) += common.o options.o packet.o pidfile.o \ + signalpipe.o socket.o +lib-$(CONFIG_APP_UDHCPD) += common.o options.o packet.o pidfile.o \ + signalpipe.o socket.o +lib-$(CONFIG_APP_UDHCPC) += dhcpc.o clientpacket.o clientsocket.o \ + script.o +lib-$(CONFIG_APP_UDHCPD) += dhcpd.o arpping.o files.o leases.o \ + serverpacket.o static_leases.o +lib-$(CONFIG_APP_DUMPLEASES) += dumpleases.o diff --git a/networking/udhcp/Makefile b/networking/udhcp/Makefile deleted file mode 100644 index 23131f8f0..000000000 --- a/networking/udhcp/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2004 by Erik Andersen -# -# Licensed under GPLv2 or later, see file LICENSE in this tarball for details. - -#ifndef top_srcdir -#top_srcdir=../.. -#endif -#ifndef top_builddir -#top_builddir=../.. -#endif -srcdir=$(top_srcdir)/networking/udhcp -UDHCP_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/networking/udhcp/Makefile.in b/networking/udhcp/Makefile.in deleted file mode 100644 index cbc6f2b39..000000000 --- a/networking/udhcp/Makefile.in +++ /dev/null @@ -1,53 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2004 by Erik Andersen -# -# Licensed under the GPL v2 or later, see the file LICENSE in this tarball. -# - -UDHCP_AR:=udhcp.a -ifndef $(UDHCP_DIR) -UDHCP_DIR:=$(top_builddir)/networking/udhcp/ -endif -srcdir=$(top_srcdir)/networking/udhcp - -#ok, so I forgot how to do an or, but this is a quick and dirty hack -ifeq ($(strip $(CONFIG_APP_UDHCPC)),y) -CONFIG_UDHCP_SHARED=y -else -ifeq ($(strip $(CONFIG_APP_UDHCPD)),y) -CONFIG_UDHCP_SHARED=y -else -CONFIG_UDHCP_SHARED=n -endif -endif - -UDHCP-y:= -UDHCP-$(CONFIG_UDHCP_SHARED) += common.c options.c packet.c pidfile.c \ - signalpipe.c socket.c -UDHCP-$(CONFIG_APP_UDHCPC) += dhcpc.c clientpacket.c clientsocket.c \ - script.c -UDHCP-$(CONFIG_APP_UDHCPD) += dhcpd.c arpping.c files.c leases.c \ - serverpacket.c static_leases.c -UDHCP-$(CONFIG_APP_DUMPLEASES) += dumpleases.c -UDHCP_OBJS:=$(patsubst %.c,$(UDHCP_DIR)%.o, $(UDHCP-y)) - -ifneq ($(strip $(UDHCP-y)),) -libraries-y+=$(UDHCP_DIR)$(UDHCP_AR) -endif - -UDHCP-y:=$(patsubst %,$(srcdir)/%,$(UDHCP-y)) -UDHCP-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(UDHCP-y) -APPLET_SRC-a+=$(UDHCP-a) - -UDHCP_INCLUDES:=$(srcdir) - -APPLETS_DEFINE-y+= -I$(UDHCP_INCLUDES) -APPLETS_DEFINE-a+= -I$(UDHCP_INCLUDES) - -$(UDHCP_DIR)$(UDHCP_AR): $(UDHCP_OBJS) - $(do_ar) - -$(UDHCP_OBJS): $(UDHCP_DIR)%.o : $(srcdir)/%.c - $(compile.c) diff --git a/procps/Config.in b/procps/Config.in index 2d4ad3bd4..20d5f9bf2 100644 --- a/procps/Config.in +++ b/procps/Config.in @@ -5,7 +5,7 @@ menu "Process Utilities" -config CONFIG_FREE +config FREE bool "free" default n help @@ -13,7 +13,7 @@ config CONFIG_FREE memory in the system, as well as the buffers used by the kernel. The shared memory column should be ignored; it is obsolete. -config CONFIG_FUSER +config FUSER bool "fuser" default n help @@ -21,7 +21,7 @@ config CONFIG_FUSER file open. fuser can also list all PIDs that have a given network (TCP or UDP) port open. -config CONFIG_KILL +config KILL bool "kill" default n help @@ -29,86 +29,86 @@ config CONFIG_KILL process or process group. If no signal is specified, the TERM signal is sent. -config CONFIG_KILLALL +config KILLALL bool "killall" default n - depends on CONFIG_KILL + depends on KILL help killall sends a signal to all processes running any of the specified commands. If no signal name is specified, SIGTERM is sent. -config CONFIG_KILLALL5 +config KILLALL5 bool "killall5" default n - depends on CONFIG_KILL + depends on KILL -config CONFIG_PIDOF +config PIDOF bool "pidof" default n help Pidof finds the process id's (pids) of the named programs. It prints those id's on the standard output. -config CONFIG_FEATURE_PIDOF_SINGLE +config FEATURE_PIDOF_SINGLE bool "Enable argument for single shot (-s)" default n - depends on CONFIG_PIDOF + depends on PIDOF help Support argument '-s' for returning only the first pid found. -config CONFIG_FEATURE_PIDOF_OMIT +config FEATURE_PIDOF_OMIT bool "Enable argument for omitting pids (-o)" default n - depends on CONFIG_PIDOF + depends on PIDOF help Support argument '-o' for omitting the given pids in output. The special pid %PPID can be used to name the parent process of the pidof, in other words the calling shell or shell script. -config CONFIG_PS +config PS bool "ps" default n help ps gives a snapshot of the current processes. -config CONFIG_FEATURE_PS_WIDE +config FEATURE_PS_WIDE bool "Enable argument for wide output (-w)" default n - depends on CONFIG_PS + depends on PS help Support argument 'w' for wide output. If given once, 132 chars are printed and given more than one, the length is unlimited. -config CONFIG_RENICE +config RENICE bool "renice" default n help Renice alters the scheduling priority of one or more running processes. -config CONFIG_BB_SYSCTL +config BB_SYSCTL bool "sysctl" default n help Configure kernel parameters at runtime. -config CONFIG_TOP +config TOP bool "top" default n help The top program provides a dynamic real-time view of a running system. -config CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE +config FEATURE_TOP_CPU_USAGE_PERCENTAGE bool "Support showing CPU usage percentage (add 2k bytes)" default y - depends on CONFIG_TOP + depends on TOP help Make top display CPU usage. -config CONFIG_UPTIME +config UPTIME bool "uptime" default n help diff --git a/procps/Kbuild b/procps/Kbuild new file mode 100644 index 000000000..6a9a86637 --- /dev/null +++ b/procps/Kbuild @@ -0,0 +1,16 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_FREE) += free.o +lib-$(CONFIG_KILL) += kill.o +lib-$(CONFIG_PIDOF) += pidof.o +lib-$(CONFIG_PS) += ps.o +lib-$(CONFIG_RENICE) += renice.o +lib-$(CONFIG_BB_SYSCTL) += sysctl.o +lib-$(CONFIG_TOP) += top.o +lib-$(CONFIG_UPTIME) += uptime.o +lib-$(CONFIG_FUSER) += fuser.o diff --git a/procps/Makefile b/procps/Makefile deleted file mode 100644 index 1db6ffa58..000000000 --- a/procps/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/procps -PROCPS_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/procps/Makefile.in b/procps/Makefile.in deleted file mode 100644 index 261c49b02..000000000 --- a/procps/Makefile.in +++ /dev/null @@ -1,37 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -PROCPS_AR:=procps.a -ifndef $(PROCPS_DIR) -PROCPS_DIR:=$(top_builddir)/procps/ -endif -srcdir=$(top_srcdir)/procps - -PROCPS-y:= -PROCPS-$(CONFIG_FREE) += free.o -PROCPS-$(CONFIG_KILL) += kill.o -PROCPS-$(CONFIG_PIDOF) += pidof.o -PROCPS-$(CONFIG_PS) += ps.o -PROCPS-$(CONFIG_RENICE) += renice.o -PROCPS-$(CONFIG_BB_SYSCTL) += sysctl.o -PROCPS-$(CONFIG_TOP) += top.o -PROCPS-$(CONFIG_UPTIME) += uptime.o -PROCPS-$(CONFIG_FUSER) += fuser.o - -ifneq ($(strip $(PROCPS-y)),) -libraries-y+=$(PROCPS_DIR)$(PROCPS_AR) -endif - -PROCPS_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(PROCPS-y)) -PROCPS_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(PROCPS_SRC-y) -APPLET_SRC-a+=$(PROCPS_SRC-a) - -$(PROCPS_DIR)$(PROCPS_AR): $(patsubst %,$(PROCPS_DIR)%, $(PROCPS-y)) - $(do_ar) - -$(PROCPS_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/runit/Config.in b/runit/Config.in index 073ca1425..b90b0232e 100644 --- a/runit/Config.in +++ b/runit/Config.in @@ -5,30 +5,30 @@ menu "Runit Utilities" -config CONFIG_CHPST +config CHPST bool "chpst" default n help chpst changes the process state according to the given options, and execs specified program. -config CONFIG_SETUIDGID +config SETUIDGID bool "setuidgid" help Sets soft resource limits as specified by options -config CONFIG_ENVUIDGID +config ENVUIDGID bool "envuidgid" help Sets $UID to account's uid and $GID to account's gid -config CONFIG_ENVDIR +config ENVDIR bool "envdir" help Sets various environment variables as specified by files in the given directory -config CONFIG_SOFTLIMIT +config SOFTLIMIT bool "softlimit" help Sets soft resource limits as specified by options diff --git a/runit/Kbuild b/runit/Kbuild new file mode 100644 index 000000000..9fee84224 --- /dev/null +++ b/runit/Kbuild @@ -0,0 +1,8 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_CHPST) += chpst.o uidgid.o diff --git a/runit/Makefile b/runit/Makefile deleted file mode 100644 index be65856fe..000000000 --- a/runit/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/runit -RUNIT_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/runit/Makefile.in b/runit/Makefile.in deleted file mode 100644 index d8cea10c2..000000000 --- a/runit/Makefile.in +++ /dev/null @@ -1,42 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -RUNIT_AR:=runit.a -ifndef RUNIT_DIR -RUNIT_DIR:=$(top_builddir)/runit/ -endif -srcdir=$(top_srcdir)/runit - -#unix_a:=buffer.o \ -#buffer_get.o buffer_put.o buffer_read.o buffer_write.o coe.o \ -#fd_copy.o fd_move.o fifo.o lock_ex.o lock_exnb.o \ -#ndelay_off.o ndelay_on.o open_append.o open_read.o \ -#open_trunc.o open_write.o openreadclose.o pathexec_env.o \ -#pathexec_run.o prot.o readclose.o seek_set.o sig.o \ -#sig_block.o sig_catch.o sig_pause.o stralloc_cat.o stralloc_catb.o \ -#stralloc_cats.o stralloc_eady.o stralloc_opyb.o stralloc_opys.o \ -#stralloc_pend.o wait_nohang.o \ -#wait_pid.o - -RUNIT-y:= -RUNIT-$(CONFIG_CHPST) += chpst.o uidgid.o - -RUNIT-y:=$(sort $(RUNIT-y)) - -ifneq ($(strip $(RUNIT-y)),) -libraries-y+=$(RUNIT_DIR)$(RUNIT_AR) -endif - -RUNIT_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(RUNIT-y)) -RUNIT_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(RUNIT_SRC-y) -APPLET_SRC-a+=$(RUNIT_SRC-a) - -$(RUNIT_DIR)$(RUNIT_AR): $(patsubst %,$(RUNIT_DIR)%, $(RUNIT-y)) - $(do_ar) - -$(RUNIT_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/scripts/Kbuild b/scripts/Kbuild new file mode 100644 index 000000000..80c60733e --- /dev/null +++ b/scripts/Kbuild @@ -0,0 +1,11 @@ +### +# scripts contains sources for various helper programs used throughout +# the kernel for the build process. +# --------------------------------------------------------------------------- + +hostprogs-y += usage + +always := $(hostprogs-y) + +# Let clean descend into subdirs +subdir- += basic kconfig diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include new file mode 100644 index 000000000..b0d067be7 --- /dev/null +++ b/scripts/Kbuild.include @@ -0,0 +1,148 @@ +#### +# kbuild: Generic definitions + +# Convinient variables +comma := , +squote := ' +empty := +space := $(empty) $(empty) + +### +# The temporary file to save gcc -MD generated dependencies must not +# contain a comma +depfile = $(subst $(comma),_,$(@D)/.$(@F).d) + +### +# Escape single quote for use in echo statements +escsq = $(subst $(squote),'\$(squote)',$1) + +### +# filechk is used to check if the content of a generated file is updated. +# Sample usage: +# define filechk_sample +# echo $KERNELRELEASE +# endef +# version.h : Makefile +# $(call filechk,sample) +# The rule defined shall write to stdout the content of the new file. +# The existing file will be compared with the new one. +# - If no file exist it is created +# - If the content differ the new file is used +# - If they are equal no change, and no timestamp update +# - stdin is piped in from the first prerequisite ($<) so one has +# to specify a valid file as first prerequisite (often the kbuild file) +define filechk + $(Q)set -e; \ + echo ' CHK $@'; \ + mkdir -p $(dir $@); \ + $(filechk_$(1)) < $< > $@.tmp; \ + if [ -r $@ ] && cmp -s $@ $@.tmp; then \ + rm -f $@.tmp; \ + else \ + echo ' UPD $@'; \ + mv -f $@.tmp $@; \ + fi +endef + +###### +# gcc support functions +# See documentation in Documentation/kbuild/makefiles.txt + +# as-option +# Usage: cflags-y += $(call as-option, -Wa$(comma)-isa=foo,) + +as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \ + -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \ + else echo "$(2)"; fi ;) + +# cc-option +# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586) + +cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ + > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) + +# cc-option-yn +# Usage: flag := $(call cc-option-yn, -march=winchip-c6) +cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ + > /dev/null 2>&1; then echo "y"; else echo "n"; fi;) + +# cc-option-align +# Prefix align with either -falign or -malign +cc-option-align = $(subst -functions=0,,\ + $(call cc-option,-falign-functions=0,-malign-functions=0)) + +# cc-version +# Usage gcc-ver := $(call cc-version, $(CC)) +cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh \ + $(if $(1), $(1), $(CC))) + +# cc-ifversion +# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) +cc-ifversion = $(shell if [ $(call cc-version, $(CC)) $(1) $(2) ]; then \ + echo $(3); fi;) + +### +# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= +# Usage: +# $(Q)$(MAKE) $(build)=dir +build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj + +# Prefix -I with $(srctree) if it is not an absolute path +addtree = $(if $(filter-out -I/%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1))) $(1) +# Find all -I options and call addtree +flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) + +# If quiet is set, only print short version of command +cmd = @$(echo-cmd) $(cmd_$(1)) + +# Add $(obj)/ for paths that is not absolute +objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o))) + +### +# if_changed - execute command if any prerequisite is newer than +# target, or command line has changed +# if_changed_dep - as if_changed, but uses fixdep to reveal dependencies +# including used config symbols +# if_changed_rule - as if_changed but execute rule instead +# See Documentation/kbuild/makefiles.txt for more info + +ifneq ($(KBUILD_NOCMDDEP),1) +# Check if both arguments has same arguments. Result in empty string if equal +# User may override this check using make KBUILD_NOCMDDEP=1 +arg-check = $(strip $(filter-out $(1), $(2)) $(filter-out $(2), $(1)) ) +endif + +# echo command. Short version is $(quiet) equals quiet, otherwise full command +echo-cmd = $(if $($(quiet)cmd_$(1)), \ + echo ' $(call escsq,$($(quiet)cmd_$(1)))';) + +make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))) + +# function to only execute the passed command if necessary +# >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file +# note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars +# +if_changed = $(if $(strip $(filter-out $(PHONY),$?) \ + $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ + @set -e; \ + $(echo-cmd) $(cmd_$(1)); \ + echo 'cmd_$@ := $(make-cmd)' > $(@D)/.$(@F).cmd) + +# execute the command and also postprocess generated .d dependencies +# file +if_changed_dep = $(if $(strip $(filter-out $(PHONY),$?) \ + $(filter-out FORCE $(wildcard $^),$^) \ + $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \ + @set -e; \ + $(echo-cmd) $(cmd_$(1)); \ + scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(@D)/.$(@F).tmp; \ + rm -f $(depfile); \ + mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd) + +# Usage: $(call if_changed_rule,foo) +# will check if $(cmd_foo) changed, or any of the prequisites changed, +# and if so will execute $(rule_foo) +if_changed_rule = $(if $(strip $(filter-out $(PHONY),$?) \ + $(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\ + @set -e; \ + $(rule_$(1))) diff --git a/scripts/Makefile.build b/scripts/Makefile.build new file mode 100644 index 000000000..e48e60da3 --- /dev/null +++ b/scripts/Makefile.build @@ -0,0 +1,338 @@ +# ========================================================================== +# Building +# ========================================================================== + +src := $(obj) + +PHONY := __build +__build: + +# Read .config if it exist, otherwise ignore +-include .config + +include scripts/Kbuild.include + +# The filename Kbuild has precedence over Makefile +kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) +include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) + +include scripts/Makefile.lib + +ifdef host-progs +ifneq ($(hostprogs-y),$(host-progs)) +$(warning kbuild: $(obj)/Makefile - Usage of host-progs is deprecated. Please replace with hostprogs-y!) +hostprogs-y += $(host-progs) +endif +endif + +# Do not include host rules unles needed +ifneq ($(hostprogs-y)$(hostprogs-m),) +include scripts/Makefile.host +endif + +ifneq ($(KBUILD_SRC),) +# Create output directory if not already present +_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj)) + +# Create directories for object files if directory does not exist +# Needed when obj-y := dir/file.o syntax is used +_dummy := $(foreach d,$(obj-dirs), $(shell [ -d $(d) ] || mkdir -p $(d))) +endif + + +ifdef EXTRA_TARGETS +$(warning kbuild: $(obj)/Makefile - Usage of EXTRA_TARGETS is obsolete in 2.6. Please fix!) +endif + +ifdef build-targets +$(warning kbuild: $(obj)/Makefile - Usage of build-targets is obsolete in 2.6. Please fix!) +endif + +ifdef export-objs +$(warning kbuild: $(obj)/Makefile - Usage of export-objs is obsolete in 2.6. Please fix!) +endif + +ifdef O_TARGET +$(warning kbuild: $(obj)/Makefile - Usage of O_TARGET := $(O_TARGET) is obsolete in 2.6. Please fix!) +endif + +ifdef L_TARGET +$(error kbuild: $(obj)/Makefile - Use of L_TARGET is replaced by lib-y in 2.6. Please fix!) +endif + +ifdef list-multi +$(warning kbuild: $(obj)/Makefile - list-multi := $(list-multi) is obsolete in 2.6. Please fix!) +endif + +ifndef obj +$(warning kbuild: Makefile.build is included improperly) +endif + +# =========================================================================== + +ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),) +lib-target := $(obj)/lib.a +endif + +ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(lib-target)),) +builtin-target := $(obj)/built-in.o +endif + +# We keep a list of all modules in $(MODVERDIR) + +__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \ + $(if $(KBUILD_MODULES),$(obj-m)) \ + $(subdir-ym) $(always) + @: + +# Linus' kernel sanity checking tool +ifneq ($(KBUILD_CHECKSRC),0) + ifeq ($(KBUILD_CHECKSRC),2) + quiet_cmd_force_checksrc = CHECK $< + cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ; + else + quiet_cmd_checksrc = CHECK $< + cmd_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ; + endif +endif + + +# Compile C sources (.c) +# --------------------------------------------------------------------------- + +# Default is built-in, unless we know otherwise +modkern_cflags := $(CFLAGS_KERNEL) +quiet_modtag := $(empty) $(empty) + +$(real-objs-m) : modkern_cflags := $(CFLAGS_MODULE) +$(real-objs-m:.o=.i) : modkern_cflags := $(CFLAGS_MODULE) +$(real-objs-m:.o=.s) : modkern_cflags := $(CFLAGS_MODULE) +$(real-objs-m:.o=.lst): modkern_cflags := $(CFLAGS_MODULE) + +$(real-objs-m) : quiet_modtag := [M] +$(real-objs-m:.o=.i) : quiet_modtag := [M] +$(real-objs-m:.o=.s) : quiet_modtag := [M] +$(real-objs-m:.o=.lst): quiet_modtag := [M] + +$(obj-m) : quiet_modtag := [M] + +# Default for not multi-part modules +modname = $(*F) + +$(multi-objs-m) : modname = $(modname-multi) +$(multi-objs-m:.o=.i) : modname = $(modname-multi) +$(multi-objs-m:.o=.s) : modname = $(modname-multi) +$(multi-objs-m:.o=.lst) : modname = $(modname-multi) +$(multi-objs-y) : modname = $(modname-multi) +$(multi-objs-y:.o=.i) : modname = $(modname-multi) +$(multi-objs-y:.o=.s) : modname = $(modname-multi) +$(multi-objs-y:.o=.lst) : modname = $(modname-multi) + +quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ +cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm -S -o $@ $< + +%.s: %.c FORCE + $(call if_changed_dep,cc_s_c) + +quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@ +cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $< + +%.i: %.c FORCE + $(call if_changed_dep,cc_i_c) + +# C (.c) files +# The C file is compiled and updated dependency information is generated. +# (See cmd_cc_o_c + relevant part of rule_cc_o_c) + +quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ + +ifndef CONFIG_MODVERSIONS +cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< + +else +# When module versioning is enabled the following steps are executed: +# o compile a .tmp_.o from .c +# o if .tmp_.o doesn't contain a __ksymtab version, i.e. does +# not export symbols, we just rename .tmp_.o to .o and +# are done. +# o otherwise, we calculate symbol versions using the good old +# genksyms on the preprocessed source and postprocess them in a way +# that they are usable as a linker script +# o generate .o from .tmp_.o using the linker to +# replace the unresolved symbols __crc_exported_symbol with +# the actual value of the checksum generated by genksyms + +cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< +cmd_modversions = \ + if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ + $(CPP) -D__GENKSYMS__ $(c_flags) $< \ + | $(GENKSYMS) -a $(ARCH) \ + > $(@D)/.tmp_$(@F:.o=.ver); \ + \ + $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ + -T $(@D)/.tmp_$(@F:.o=.ver); \ + rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ + else \ + mv -f $(@D)/.tmp_$(@F) $@; \ + fi; +endif + +define rule_cc_o_c + $(call echo-cmd,checksrc) $(cmd_checksrc) \ + $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \ + $(cmd_modversions) \ + scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > $(@D)/.$(@F).tmp; \ + rm -f $(depfile); \ + mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd +endef + +# Built-in and composite module parts + +%.o: %.c FORCE + $(call cmd,force_checksrc) + $(call if_changed_rule,cc_o_c) + +# Single-part modules are special since we need to mark them in $(MODVERDIR) + +$(single-used-m): %.o: %.c FORCE + $(call cmd,force_checksrc) + $(call if_changed_rule,cc_o_c) + @{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod) + +quiet_cmd_cc_lst_c = MKLST $@ + cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ + $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \ + System.map $(OBJDUMP) > $@ + +%.lst: %.c FORCE + $(call if_changed_dep,cc_lst_c) + +# Compile assembler sources (.S) +# --------------------------------------------------------------------------- + +modkern_aflags := $(AFLAGS_KERNEL) + +$(real-objs-m) : modkern_aflags := $(AFLAGS_MODULE) +$(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE) + +quiet_cmd_as_s_S = CPP $(quiet_modtag) $@ +cmd_as_s_S = $(CPP) $(a_flags) -o $@ $< + +%.s: %.S FORCE + $(call if_changed_dep,as_s_S) + +quiet_cmd_as_o_S = AS $(quiet_modtag) $@ +cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< + +%.o: %.S FORCE + $(call if_changed_dep,as_o_S) + +targets += $(real-objs-y) $(real-objs-m) $(lib-y) +targets += $(extra-y) $(MAKECMDGOALS) $(always) + +# Linker scripts preprocessor (.lds.S -> .lds) +# --------------------------------------------------------------------------- +quiet_cmd_cpp_lds_S = LDS $@ + cmd_cpp_lds_S = $(CPP) $(cpp_flags) -D__ASSEMBLY__ -o $@ $< + +%.lds: %.lds.S FORCE + $(call if_changed_dep,cpp_lds_S) + +# Build the compiled-in targets +# --------------------------------------------------------------------------- + +# To build objects in subdirs, we need to descend into the directories +$(sort $(subdir-obj-y)): $(subdir-ym) ; + +# +# Rule to compile a set of .o files into one .o file +# +ifdef builtin-target +quiet_cmd_link_o_target = LD $@ +# If the list of objects to link is empty, just create an empty built-in.o +cmd_link_o_target = $(if $(strip $(obj-y)),\ + $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^),\ + rm -f $@; $(AR) rcs $@) + +$(builtin-target): $(obj-y) FORCE + $(call if_changed,link_o_target) + +targets += $(builtin-target) +endif # builtin-target + +# +# Rule to compile a set of .o files into one .a file +# +ifdef lib-target +quiet_cmd_link_l_target = AR $@ +cmd_link_l_target = rm -f $@; $(AR) $(EXTRA_ARFLAGS) rcs $@ $(lib-y) + +$(lib-target): $(lib-y) FORCE + $(call if_changed,link_l_target) + +targets += $(lib-target) +endif + +# +# Rule to link composite objects +# +# Composite objects are specified in kbuild makefile as follows: +# -objs := +# or +# -y := +link_multi_deps = \ +$(filter $(addprefix $(obj)/, \ +$($(subst $(obj)/,,$(@:.o=-objs))) \ +$($(subst $(obj)/,,$(@:.o=-y)))), $^) + +quiet_cmd_link_multi-y = LD $@ +cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) + +quiet_cmd_link_multi-m = LD [M] $@ +cmd_link_multi-m = $(LD) $(ld_flags) $(LDFLAGS_MODULE) -o $@ $(link_multi_deps) + +# We would rather have a list of rules like +# foo.o: $(foo-objs) +# but that's not so easy, so we rather make all composite objects depend +# on the set of all their parts +$(multi-used-y) : %.o: $(multi-objs-y) FORCE + $(call if_changed,link_multi-y) + +$(multi-used-m) : %.o: $(multi-objs-m) FORCE + $(call if_changed,link_multi-m) + @{ echo $(@:.o=.ko); echo $(link_multi_deps); } > $(MODVERDIR)/$(@F:.o=.mod) + +targets += $(multi-used-y) $(multi-used-m) + + +# Descending +# --------------------------------------------------------------------------- + +PHONY += $(subdir-ym) +$(subdir-ym): + $(Q)$(MAKE) $(build)=$@ + +# Add FORCE to the prequisites of a target to force it to be always rebuilt. +# --------------------------------------------------------------------------- + +PHONY += FORCE + +FORCE: + +# Read all saved command lines and dependencies for the $(targets) we +# may be building above, using $(if_changed{,_dep}). As an +# optimization, we don't need to read them if the target does not +# exist, we will rebuild anyway in that case. + +targets := $(wildcard $(sort $(targets))) +cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) + +ifneq ($(cmd_files),) + include $(cmd_files) +endif + + +# Declare the contents of the .PHONY variable as phony. We keep that +# information in a variable se we can use it in if_changed and friends. + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.host b/scripts/Makefile.host new file mode 100644 index 000000000..2d519704b --- /dev/null +++ b/scripts/Makefile.host @@ -0,0 +1,156 @@ +# ========================================================================== +# Building binaries on the host system +# Binaries are used during the compilation of the kernel, for example +# to preprocess a data file. +# +# Both C and C++ is supported, but preferred language is C for such utilities. +# +# Samle syntax (see Documentation/kbuild/makefile.txt for reference) +# hostprogs-y := bin2hex +# Will compile bin2hex.c and create an executable named bin2hex +# +# hostprogs-y := lxdialog +# lxdialog-objs := checklist.o lxdialog.o +# Will compile lxdialog.c and checklist.c, and then link the executable +# lxdialog, based on checklist.o and lxdialog.o +# +# hostprogs-y := qconf +# qconf-cxxobjs := qconf.o +# qconf-objs := menu.o +# Will compile qconf as a C++ program, and menu as a C program. +# They are linked as C++ code to the executable qconf + +# hostprogs-y := conf +# conf-objs := conf.o libkconfig.so +# libkconfig-objs := expr.o type.o +# Will create a shared library named libkconfig.so that consist of +# expr.o and type.o (they are both compiled as C code and the object file +# are made as position independent code). +# conf.c is compiled as a c program, and conf.o is linked together with +# libkconfig.so as the executable conf. +# Note: Shared libraries consisting of C++ files are not supported + +__hostprogs := $(sort $(hostprogs-y)$(hostprogs-m)) + +# hostprogs-y := tools/build may have been specified. Retreive directory +obj-dirs += $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f)))) +obj-dirs := $(strip $(sort $(filter-out ./,$(obj-dirs)))) + + +# C code +# Executables compiled from a single .c file +host-csingle := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m))) + +# C executables linked based on several .o files +host-cmulti := $(foreach m,$(__hostprogs),\ + $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m)))) + +# Object (.o) files compiled from .c files +host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs))) + +# C++ code +# C++ executables compiled from at least on .cc file +# and zero or more .c files +host-cxxmulti := $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m))) + +# C++ Object (.o) files compiled from .cc files +host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs))) + +# Shared libaries (only .c supported) +# Shared libraries (.so) - all .so files referenced in "xxx-objs" +host-cshlib := $(sort $(filter %.so, $(host-cobjs))) +# Remove .so files from "xxx-objs" +host-cobjs := $(filter-out %.so,$(host-cobjs)) + +#Object (.o) files used by the shared libaries +host-cshobjs := $(sort $(foreach m,$(host-cshlib),$($(m:.so=-objs)))) + +__hostprogs := $(addprefix $(obj)/,$(__hostprogs)) +host-csingle := $(addprefix $(obj)/,$(host-csingle)) +host-cmulti := $(addprefix $(obj)/,$(host-cmulti)) +host-cobjs := $(addprefix $(obj)/,$(host-cobjs)) +host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti)) +host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs)) +host-cshlib := $(addprefix $(obj)/,$(host-cshlib)) +host-cshobjs := $(addprefix $(obj)/,$(host-cshobjs)) +obj-dirs := $(addprefix $(obj)/,$(obj-dirs)) + +##### +# Handle options to gcc. Support building with separate output directory + +_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS_$(*F).o) +_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) $(HOSTCXXFLAGS_$(*F).o) + +ifeq ($(KBUILD_SRC),) +__hostc_flags = $(_hostc_flags) +__hostcxx_flags = $(_hostcxx_flags) +else +__hostc_flags = -I$(obj) $(call flags,_hostc_flags) +__hostcxx_flags = -I$(obj) $(call flags,_hostcxx_flags) +endif + +hostc_flags = -Wp,-MD,$(depfile) $(__hostc_flags) +hostcxx_flags = -Wp,-MD,$(depfile) $(__hostcxx_flags) + +##### +# Compile programs on the host + +# Create executable from a single .c file +# host-csingle -> Executable +quiet_cmd_host-csingle = HOSTCC $@ + cmd_host-csingle = $(HOSTCC) $(hostc_flags) -o $@ $< \ + $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) +$(host-csingle): %: %.c FORCE + $(call if_changed_dep,host-csingle) + +# Link an executable based on list of .o files, all plain c +# host-cmulti -> executable +quiet_cmd_host-cmulti = HOSTLD $@ + cmd_host-cmulti = $(HOSTCC) $(HOSTLDFLAGS) -o $@ \ + $(addprefix $(obj)/,$($(@F)-objs)) \ + $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) +$(host-cmulti): %: $(host-cobjs) $(host-cshlib) FORCE + $(call if_changed,host-cmulti) + +# Create .o file from a single .c file +# host-cobjs -> .o +quiet_cmd_host-cobjs = HOSTCC $@ + cmd_host-cobjs = $(HOSTCC) $(hostc_flags) -c -o $@ $< +$(host-cobjs): %.o: %.c FORCE + $(call if_changed_dep,host-cobjs) + +# Link an executable based on list of .o files, a mixture of .c and .cc +# host-cxxmulti -> executable +quiet_cmd_host-cxxmulti = HOSTLD $@ + cmd_host-cxxmulti = $(HOSTCXX) $(HOSTLDFLAGS) -o $@ \ + $(foreach o,objs cxxobjs,\ + $(addprefix $(obj)/,$($(@F)-$(o)))) \ + $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) +$(host-cxxmulti): %: $(host-cobjs) $(host-cxxobjs) $(host-cshlib) FORCE + $(call if_changed,host-cxxmulti) + +# Create .o file from a single .cc (C++) file +quiet_cmd_host-cxxobjs = HOSTCXX $@ + cmd_host-cxxobjs = $(HOSTCXX) $(hostcxx_flags) -c -o $@ $< +$(host-cxxobjs): %.o: %.cc FORCE + $(call if_changed_dep,host-cxxobjs) + +# Compile .c file, create position independent .o file +# host-cshobjs -> .o +quiet_cmd_host-cshobjs = HOSTCC -fPIC $@ + cmd_host-cshobjs = $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $< +$(host-cshobjs): %.o: %.c FORCE + $(call if_changed_dep,host-cshobjs) + +# Link a shared library, based on position independent .o files +# *.o -> .so shared library (host-cshlib) +quiet_cmd_host-cshlib = HOSTLLD -shared $@ + cmd_host-cshlib = $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \ + $(addprefix $(obj)/,$($(@F:.so=-objs))) \ + $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) +$(host-cshlib): %: $(host-cshobjs) FORCE + $(call if_changed,host-cshlib) + +targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\ + $(host-cxxmulti) $(host-cxxobjs) $(host-cshlib) $(host-cshobjs) + diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib new file mode 100644 index 000000000..2cb4935e8 --- /dev/null +++ b/scripts/Makefile.lib @@ -0,0 +1,165 @@ +# Backward compatibility - to be removed... +extra-y += $(EXTRA_TARGETS) +# Figure out what we need to build from the various variables +# =========================================================================== + +# When an object is listed to be built compiled-in and modular, +# only build the compiled-in version + +obj-m := $(filter-out $(obj-y),$(obj-m)) + +# Libraries are always collected in one lib file. +# Filter out objects already built-in + +lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m))) + + +# Handle objects in subdirs +# --------------------------------------------------------------------------- +# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.o +# and add the directory to the list of dirs to descend into: $(subdir-y) +# o if we encounter foo/ in $(obj-m), remove it from $(obj-m) +# and add the directory to the list of dirs to descend into: $(subdir-m) + +__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) +subdir-y += $(__subdir-y) +__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m))) +subdir-m += $(__subdir-m) +obj-y := $(patsubst %/, %/built-in.o, $(obj-y)) +obj-m := $(filter-out %/, $(obj-m)) + +# Subdirectories we need to descend into + +subdir-ym := $(sort $(subdir-y) $(subdir-m)) + +# if $(foo-objs) exists, foo.o is a composite object +multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) +multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) +multi-used := $(multi-used-y) $(multi-used-m) +single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m))) + +# Build list of the parts of our composite objects, our composite +# objects depend on those (obviously) +multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)) $($(m:.o=-y))) +multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y))) +multi-objs := $(multi-objs-y) $(multi-objs-m) + +# $(subdir-obj-y) is the list of objects in $(obj-y) which do not live +# in the local directory +subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o))) + +# $(obj-dirs) is a list of directories that contain object files +obj-dirs := $(dir $(multi-objs) $(subdir-obj-y)) + +# Replace multi-part objects by their individual parts, look at local dir only +real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(extra-y) +real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) + +# Add subdir path + +extra-y := $(addprefix $(obj)/,$(extra-y)) +always := $(addprefix $(obj)/,$(always)) +targets := $(addprefix $(obj)/,$(targets)) +obj-y := $(addprefix $(obj)/,$(obj-y)) +obj-m := $(addprefix $(obj)/,$(obj-m)) +lib-y := $(addprefix $(obj)/,$(lib-y)) +subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y)) +real-objs-y := $(addprefix $(obj)/,$(real-objs-y)) +real-objs-m := $(addprefix $(obj)/,$(real-objs-m)) +single-used-m := $(addprefix $(obj)/,$(single-used-m)) +multi-used-y := $(addprefix $(obj)/,$(multi-used-y)) +multi-used-m := $(addprefix $(obj)/,$(multi-used-m)) +multi-objs-y := $(addprefix $(obj)/,$(multi-objs-y)) +multi-objs-m := $(addprefix $(obj)/,$(multi-objs-m)) +subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) +obj-dirs := $(addprefix $(obj)/,$(obj-dirs)) + +# These flags are needed for modversions and compiling, so we define them here +# already +# $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will +# end up in (or would, if it gets compiled in) +# Note: It's possible that one object gets potentially linked into more +# than one module. In that case KBUILD_MODNAME will be set to foo_bar, +# where foo and bar are the name of the modules. +name-fix = $(subst $(comma),_,$(subst -,_,$1)) +basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(*F)))" +modname_flags = $(if $(filter 1,$(words $(modname))),\ + -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + +_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) +_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o) +_cpp_flags = $(CPPFLAGS) $(EXTRA_CPPFLAGS) $(CPPFLAGS_$(@F)) + +# If building the kernel in a separate objtree expand all occurrences +# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/'). + +ifeq ($(KBUILD_SRC),) +__c_flags = $(_c_flags) +__a_flags = $(_a_flags) +__cpp_flags = $(_cpp_flags) +else + +# -I$(obj) locates generated .h files +# $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files +# and locates generated .h files +# FIXME: Replace both with specific CFLAGS* statements in the makefiles +__c_flags = $(call addtree,-I$(obj)) $(call flags,_c_flags) +__a_flags = $(call flags,_a_flags) +__cpp_flags = $(call flags,_cpp_flags) +endif + +c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \ + $(__c_flags) $(modkern_cflags) \ + -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + +a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \ + $(__a_flags) $(modkern_aflags) + +cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(__cpp_flags) + +ld_flags = $(LDFLAGS) $(EXTRA_LDFLAGS) + +# Finds the multi-part object the current object will be linked into +modname-multi = $(sort $(foreach m,$(multi-used),\ + $(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=)))) + +# Shipped files +# =========================================================================== + +quiet_cmd_shipped = SHIPPED $@ +cmd_shipped = cat $< > $@ + +$(obj)/%:: $(src)/%_shipped + $(call cmd,shipped) + +# Commands useful for building a boot image +# =========================================================================== +# +# Use as following: +# +# target: source(s) FORCE +# $(if_changed,ld/objcopy/gzip) +# +# and add target to EXTRA_TARGETS so that we know we have to +# read in the saved command line + +# Linking +# --------------------------------------------------------------------------- + +quiet_cmd_ld = LD $@ +cmd_ld = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_$(@F)) \ + $(filter-out FORCE,$^) -o $@ + +# Objcopy +# --------------------------------------------------------------------------- + +quiet_cmd_objcopy = OBJCOPY $@ +cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ + +# Gzip +# --------------------------------------------------------------------------- + +quiet_cmd_gzip = GZIP $@ +cmd_gzip = gzip -f -9 < $< > $@ + + diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile new file mode 100644 index 000000000..f22e94c3a --- /dev/null +++ b/scripts/basic/Makefile @@ -0,0 +1,18 @@ +### +# Makefile.basic list the most basic programs used during the build process. +# The programs listed herein is what is needed to do the basic stuff, +# such as splitting .config and fix dependency file. +# This initial step is needed to avoid files to be recompiled +# when kernel configuration changes (which is what happens when +# .config is included by main Makefile. +# --------------------------------------------------------------------------- +# fixdep: Used to generate dependency information during build process +# split-include: Divide all config symbols up in a number of files in +# include/config/... +# docproc: Used in Documentation/docbook + +hostprogs-y := fixdep split-include docproc +always := $(hostprogs-y) + +# fixdep is needed to compile other host programs +$(addprefix $(obj)/,$(filter-out fixdep,$(always))): $(obj)/fixdep diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c new file mode 100644 index 000000000..cb02baa63 --- /dev/null +++ b/scripts/basic/docproc.c @@ -0,0 +1,398 @@ +/* + * docproc is a simple preprocessor for the template files + * used as placeholders for the kernel internal documentation. + * docproc is used for documentation-frontend and + * dependency-generator. + * The two usages have in common that they require + * some knowledge of the .tmpl syntax, therefore they + * are kept together. + * + * documentation-frontend + * Scans the template file and call kernel-doc for + * all occurrences of ![EIF]file + * Beforehand each referenced file are scanned for + * any exported sympols "EXPORT_SYMBOL()" statements. + * This is used to create proper -function and + * -nofunction arguments in calls to kernel-doc. + * Usage: docproc doc file.tmpl + * + * dependency-generator: + * Scans the template file and list all files + * referenced in a format recognized by make. + * Usage: docproc depend file.tmpl + * Writes dependency information to stdout + * in the following format: + * file.tmpl src.c src2.c + * The filenames are obtained from the following constructs: + * !Efilename + * !Ifilename + * !Dfilename + * !Ffilename + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* exitstatus is used to keep track of any failing calls to kernel-doc, + * but execution continues. */ +int exitstatus = 0; + +typedef void DFL(char *); +DFL *defaultline; + +typedef void FILEONLY(char * file); +FILEONLY *internalfunctions; +FILEONLY *externalfunctions; +FILEONLY *symbolsonly; + +typedef void FILELINE(char * file, char * line); +FILELINE * singlefunctions; +FILELINE * entity_system; + +#define MAXLINESZ 2048 +#define MAXFILES 250 +#define KERNELDOCPATH "scripts/" +#define KERNELDOC "kernel-doc" +#define DOCBOOK "-docbook" +#define FUNCTION "-function" +#define NOFUNCTION "-nofunction" + +void usage (void) +{ + fprintf(stderr, "Usage: docproc {doc|depend} file\n"); + fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n"); + fprintf(stderr, "doc: frontend when generating kernel documentation\n"); + fprintf(stderr, "depend: generate list of files referenced within file\n"); +} + +/* + * Execute kernel-doc with parameters givin in svec + */ +void exec_kernel_doc(char **svec) +{ + pid_t pid; + int ret; + char real_filename[PATH_MAX + 1]; + /* Make sure output generated so far are flushed */ + fflush(stdout); + switch(pid=fork()) { + case -1: + perror("fork"); + exit(1); + case 0: + memset(real_filename, 0, sizeof(real_filename)); + strncat(real_filename, getenv("SRCTREE"), PATH_MAX); + strncat(real_filename, KERNELDOCPATH KERNELDOC, + PATH_MAX - strlen(real_filename)); + execvp(real_filename, svec); + fprintf(stderr, "exec "); + perror(real_filename); + exit(1); + default: + waitpid(pid, &ret ,0); + } + if (WIFEXITED(ret)) + exitstatus |= WEXITSTATUS(ret); + else + exitstatus = 0xff; +} + +/* Types used to create list of all exported symbols in a number of files */ +struct symbols +{ + char *name; +}; + +struct symfile +{ + char *filename; + struct symbols *symbollist; + int symbolcnt; +}; + +struct symfile symfilelist[MAXFILES]; +int symfilecnt = 0; + +void add_new_symbol(struct symfile *sym, char * symname) +{ + sym->symbollist = + realloc(sym->symbollist, (sym->symbolcnt + 1) * sizeof(char *)); + sym->symbollist[sym->symbolcnt++].name = strdup(symname); +} + +/* Add a filename to the list */ +struct symfile * add_new_file(char * filename) +{ + symfilelist[symfilecnt++].filename = strdup(filename); + return &symfilelist[symfilecnt - 1]; +} +/* Check if file already are present in the list */ +struct symfile * filename_exist(char * filename) +{ + int i; + for (i=0; i < symfilecnt; i++) + if (strcmp(symfilelist[i].filename, filename) == 0) + return &symfilelist[i]; + return NULL; +} + +/* + * List all files referenced within the template file. + * Files are separated by tabs. + */ +void adddep(char * file) { printf("\t%s", file); } +void adddep2(char * file, char * line) { line = line; adddep(file); } +void noaction(char * line) { line = line; } +void noaction2(char * file, char * line) { file = file; line = line; } + +/* Echo the line without further action */ +void printline(char * line) { printf("%s", line); } + +/* + * Find all symbols exported with EXPORT_SYMBOL and EXPORT_SYMBOL_GPL + * in filename. + * All symbols located are stored in symfilelist. + */ +void find_export_symbols(char * filename) +{ + FILE * fp; + struct symfile *sym; + char line[MAXLINESZ]; + if (filename_exist(filename) == NULL) { + char real_filename[PATH_MAX + 1]; + memset(real_filename, 0, sizeof(real_filename)); + strncat(real_filename, getenv("SRCTREE"), PATH_MAX); + strncat(real_filename, filename, + PATH_MAX - strlen(real_filename)); + sym = add_new_file(filename); + fp = fopen(real_filename, "r"); + if (fp == NULL) + { + fprintf(stderr, "docproc: "); + perror(real_filename); + } + while(fgets(line, MAXLINESZ, fp)) { + char *p; + char *e; + if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != 0) || + ((p = strstr(line, "EXPORT_SYMBOL")) != 0)) { + /* Skip EXPORT_SYMBOL{_GPL} */ + while (isalnum(*p) || *p == '_') + p++; + /* Remove paranteses and additional ws */ + while (isspace(*p)) + p++; + if (*p != '(') + continue; /* Syntax error? */ + else + p++; + while (isspace(*p)) + p++; + e = p; + while (isalnum(*e) || *e == '_') + e++; + *e = '\0'; + add_new_symbol(sym, p); + } + } + fclose(fp); + } +} + +/* + * Document all external or internal functions in a file. + * Call kernel-doc with following parameters: + * kernel-doc -docbook -nofunction function_name1 filename + * function names are obtained from all the the src files + * by find_export_symbols. + * intfunc uses -nofunction + * extfunc uses -function + */ +void docfunctions(char * filename, char * type) +{ + int i,j; + int symcnt = 0; + int idx = 0; + char **vec; + + for (i=0; i <= symfilecnt; i++) + symcnt += symfilelist[i].symbolcnt; + vec = malloc((2 + 2 * symcnt + 2) * sizeof(char*)); + if (vec == NULL) { + perror("docproc: "); + exit(1); + } + vec[idx++] = KERNELDOC; + vec[idx++] = DOCBOOK; + for (i=0; i < symfilecnt; i++) { + struct symfile * sym = &symfilelist[i]; + for (j=0; j < sym->symbolcnt; j++) { + vec[idx++] = type; + vec[idx++] = sym->symbollist[j].name; + } + } + vec[idx++] = filename; + vec[idx] = NULL; + printf("\n", filename); + exec_kernel_doc(vec); + fflush(stdout); + free(vec); +} +void intfunc(char * filename) { docfunctions(filename, NOFUNCTION); } +void extfunc(char * filename) { docfunctions(filename, FUNCTION); } + +/* + * Document spÃ¥ecific function(s) in a file. + * Call kernel-doc with the following parameters: + * kernel-doc -docbook -function function1 [-function function2] + */ +void singfunc(char * filename, char * line) +{ + char *vec[200]; /* Enough for specific functions */ + int i, idx = 0; + int startofsym = 1; + vec[idx++] = KERNELDOC; + vec[idx++] = DOCBOOK; + + /* Split line up in individual parameters preceeded by FUNCTION */ + for (i=0; line[i]; i++) { + if (isspace(line[i])) { + line[i] = '\0'; + startofsym = 1; + continue; + } + if (startofsym) { + startofsym = 0; + vec[idx++] = FUNCTION; + vec[idx++] = &line[i]; + } + } + vec[idx++] = filename; + vec[idx] = NULL; + exec_kernel_doc(vec); +} + +/* + * Parse file, calling action specific functions for: + * 1) Lines containing !E + * 2) Lines containing !I + * 3) Lines containing !D + * 4) Lines containing !F + * 5) Default lines - lines not matching the above + */ +void parse_file(FILE *infile) +{ + char line[MAXLINESZ]; + char * s; + while(fgets(line, MAXLINESZ, infile)) { + if (line[0] == '!') { + s = line + 2; + switch (line[1]) { + case 'E': + while (*s && !isspace(*s)) s++; + *s = '\0'; + externalfunctions(line+2); + break; + case 'I': + while (*s && !isspace(*s)) s++; + *s = '\0'; + internalfunctions(line+2); + break; + case 'D': + while (*s && !isspace(*s)) s++; + *s = '\0'; + symbolsonly(line+2); + break; + case 'F': + /* filename */ + while (*s && !isspace(*s)) s++; + *s++ = '\0'; + /* function names */ + while (isspace(*s)) + s++; + singlefunctions(line +2, s); + break; + default: + defaultline(line); + } + } + else { + defaultline(line); + } + } + fflush(stdout); +} + + +int main(int argc, char *argv[]) +{ + FILE * infile; + if (argc != 3) { + usage(); + exit(1); + } + /* Open file, exit on error */ + infile = fopen(argv[2], "r"); + if (infile == NULL) { + fprintf(stderr, "docproc: "); + perror(argv[2]); + exit(2); + } + + if (strcmp("doc", argv[1]) == 0) + { + /* Need to do this in two passes. + * First pass is used to collect all symbols exported + * in the various files. + * Second pass generate the documentation. + * This is required because function are declared + * and exported in different files :-(( + */ + /* Collect symbols */ + defaultline = noaction; + internalfunctions = find_export_symbols; + externalfunctions = find_export_symbols; + symbolsonly = find_export_symbols; + singlefunctions = noaction2; + parse_file(infile); + + /* Rewind to start from beginning of file again */ + fseek(infile, 0, SEEK_SET); + defaultline = printline; + internalfunctions = intfunc; + externalfunctions = extfunc; + symbolsonly = printline; + singlefunctions = singfunc; + + parse_file(infile); + } + else if (strcmp("depend", argv[1]) == 0) + { + /* Create first part of dependency chain + * file.tmpl */ + printf("%s\t", argv[2]); + defaultline = noaction; + internalfunctions = adddep; + externalfunctions = adddep; + symbolsonly = adddep; + singlefunctions = adddep2; + parse_file(infile); + printf("\n"); + } + else + { + fprintf(stderr, "Unknown option: %s\n", argv[1]); + exit(1); + } + fclose(infile); + fflush(stdout); + return exitstatus; +} + diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c new file mode 100644 index 000000000..cc2c6541b --- /dev/null +++ b/scripts/basic/fixdep.c @@ -0,0 +1,393 @@ +/* + * "Optimize" a list of dependencies as spit out by gcc -MD + * for the kernel build + * =========================================================================== + * + * Author Kai Germaschewski + * Copyright 2002 by Kai Germaschewski + * + * 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 which then again + * includes + * + * 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. + * + * To be exact, split-include populates a tree in include/config/, + * e.g. include/config/his/driver.h, which contains the #define/#undef + * for the CONFIG_HIS_DRIVER option. + * + * 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, . + * This is a C version of syncdep.pl by Werner Almesberger. + * + * + * It is invoked as + * + * fixdep + * + * and will read the dependency file + * + * The transformed dependency snipped is written to stdout. + * + * It first generates a line + * + * cmd_ = + * + * and then basically copies the ..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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 \n"); + exit(1); +} + +/* + * Print out the commandline prefixed with cmd_ := + */ +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: + 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/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/scripts/basic/split-include.c b/scripts/basic/split-include.c new file mode 100644 index 000000000..459c45276 --- /dev/null +++ b/scripts/basic/split-include.c @@ -0,0 +1,226 @@ +/* + * split-include.c + * + * Copyright abandoned, Michael Chastain, . + * This is a C version of syncdep.pl by Werner Almesberger. + * + * This program takes autoconf.h as input and outputs a directory full + * of one-line include files, merging onto the old values. + * + * Think of the configuration options as key-value pairs. Then there + * are five cases: + * + * key old value new value action + * + * KEY-1 VALUE-1 VALUE-1 leave file alone + * KEY-2 VALUE-2A VALUE-2B write VALUE-2B into file + * KEY-3 - VALUE-3 write VALUE-3 into file + * KEY-4 VALUE-4 - write an empty file + * KEY-5 (empty) - leave old empty file alone + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define ERROR_EXIT(strExit) \ + { \ + const int errnoSave = errno; \ + fprintf(stderr, "%s: ", str_my_name); \ + errno = errnoSave; \ + perror((strExit)); \ + exit(1); \ + } + + + +int main(int argc, const char * argv []) +{ + const char * str_my_name; + const char * str_file_autoconf; + const char * str_dir_config; + + FILE * fp_config; + FILE * fp_target; + FILE * fp_find; + + int buffer_size; + + char * line; + char * old_line; + char * list_target; + char * ptarget; + + struct stat stat_buf; + + /* Check arg count. */ + if (argc != 3) + { + fprintf(stderr, "%s: wrong number of arguments.\n", argv[0]); + exit(1); + } + + str_my_name = argv[0]; + str_file_autoconf = argv[1]; + str_dir_config = argv[2]; + + /* Find a buffer size. */ + if (stat(str_file_autoconf, &stat_buf) != 0) + ERROR_EXIT(str_file_autoconf); + buffer_size = 2 * stat_buf.st_size + 4096; + + /* Allocate buffers. */ + if ( (line = malloc(buffer_size)) == NULL + || (old_line = malloc(buffer_size)) == NULL + || (list_target = malloc(buffer_size)) == NULL ) + ERROR_EXIT(str_file_autoconf); + + /* Open autoconfig file. */ + if ((fp_config = fopen(str_file_autoconf, "r")) == NULL) + ERROR_EXIT(str_file_autoconf); + + /* Make output directory if needed. */ + if (stat(str_dir_config, &stat_buf) != 0) + { + if (mkdir(str_dir_config, 0755) != 0) + ERROR_EXIT(str_dir_config); + } + + /* Change to output directory. */ + if (chdir(str_dir_config) != 0) + ERROR_EXIT(str_dir_config); + + /* Put initial separator into target list. */ + ptarget = list_target; + *ptarget++ = '\n'; + + /* Read config lines. */ + while (fgets(line, buffer_size, fp_config)) + { + const char * str_config; + int is_same; + int itarget; + + if (line[0] != '#') + continue; + if ((str_config = strstr(line, "CONFIG_")) == NULL) + continue; + + /* Make the output file name. */ + str_config += sizeof("CONFIG_") - 1; + for (itarget = 0; !isspace(str_config[itarget]); itarget++) + { + int c = (unsigned char) str_config[itarget]; + if (isupper(c)) c = tolower(c); + if (c == '_') c = '/'; + ptarget[itarget] = c; + } + ptarget[itarget++] = '.'; + ptarget[itarget++] = 'h'; + ptarget[itarget++] = '\0'; + + /* Check for existing file. */ + is_same = 0; + if ((fp_target = fopen(ptarget, "r")) != NULL) + { + fgets(old_line, buffer_size, fp_target); + if (fclose(fp_target) != 0) + ERROR_EXIT(ptarget); + if (!strcmp(line, old_line)) + is_same = 1; + } + + if (!is_same) + { + /* Auto-create directories. */ + int islash; + for (islash = 0; islash < itarget; islash++) + { + if (ptarget[islash] == '/') + { + ptarget[islash] = '\0'; + if (stat(ptarget, &stat_buf) != 0 + && mkdir(ptarget, 0755) != 0) + ERROR_EXIT( ptarget ); + ptarget[islash] = '/'; + } + } + + /* Write the file. */ + if ((fp_target = fopen(ptarget, "w" )) == NULL) + ERROR_EXIT(ptarget); + fputs(line, fp_target); + if (ferror(fp_target) || fclose(fp_target) != 0) + ERROR_EXIT(ptarget); + } + + /* Update target list */ + ptarget += itarget; + *(ptarget-1) = '\n'; + } + + /* + * Close autoconfig file. + * Terminate the target list. + */ + if (fclose(fp_config) != 0) + ERROR_EXIT(str_file_autoconf); + *ptarget = '\0'; + + /* + * Fix up existing files which have no new value. + * This is Case 4 and Case 5. + * + * I re-read the tree and filter it against list_target. + * This is crude. But it avoids data copies. Also, list_target + * is compact and contiguous, so it easily fits into cache. + * + * Notice that list_target contains strings separated by \n, + * with a \n before the first string and after the last. + * fgets gives the incoming names a terminating \n. + * So by having an initial \n, strstr will find exact matches. + */ + + fp_find = popen("find * -type f -name \"*.h\" -print", "r"); + if (fp_find == 0) + ERROR_EXIT( "find" ); + + line[0] = '\n'; + while (fgets(line+1, buffer_size, fp_find)) + { + if (strstr(list_target, line) == NULL) + { + /* + * This is an old file with no CONFIG_* flag in autoconf.h. + */ + + /* First strip the \n. */ + line[strlen(line)-1] = '\0'; + + /* Grab size. */ + if (stat(line+1, &stat_buf) != 0) + ERROR_EXIT(line); + + /* If file is not empty, make it empty and give it a fresh date. */ + if (stat_buf.st_size != 0) + { + if ((fp_target = fopen(line+1, "w")) == NULL) + ERROR_EXIT(line); + if (fclose(fp_target) != 0) + ERROR_EXIT(line); + } + } + } + + if (pclose(fp_find) != 0) + ERROR_EXIT("find"); + + return 0; +} diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile new file mode 100644 index 000000000..a28414de8 --- /dev/null +++ b/scripts/kconfig/Makefile @@ -0,0 +1,254 @@ +# =========================================================================== +# Kernel configuration targets +# These targets are used from top-level makefile + +PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config + +xconfig: $(obj)/qconf + $< Config.in + +gconfig: $(obj)/gconf + $< Config.in + +menuconfig: $(obj)/mconf + $(Q)$(MAKE) $(build)=scripts/kconfig/lxdialog + $< Config.in + +config: $(obj)/conf + $< Config.in + +oldconfig: $(obj)/conf + $< -o Config.in + +silentoldconfig: $(obj)/conf + $< -s Config.in + +update-po-config: $(obj)/kxgettext + xgettext --default-domain=linux \ + --add-comments --keyword=_ --keyword=N_ \ + --files-from=scripts/kconfig/POTFILES.in \ + --output scripts/kconfig/config.pot + $(Q)ln -fs Kconfig_i386 arch/um/Kconfig_arch + $(Q)for i in `ls arch/`; \ + do \ + scripts/kconfig/kxgettext arch/$$i/Kconfig \ + | msguniq -o scripts/kconfig/linux_$${i}.pot; \ + done + $(Q)msgcat scripts/kconfig/config.pot \ + `find scripts/kconfig/ -type f -name linux_*.pot` \ + --output scripts/kconfig/linux_raw.pot + $(Q)msguniq --sort-by-file scripts/kconfig/linux_raw.pot \ + --output scripts/kconfig/linux.pot + $(Q)rm -f arch/um/Kconfig_arch + $(Q)rm -f scripts/kconfig/linux_*.pot scripts/kconfig/config.pot + +PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig + +randconfig: $(obj)/conf + $< -r Config.in + +allyesconfig: $(obj)/conf + $< -y Config.in + +allnoconfig: $(obj)/conf + $< -n Config.in + +allmodconfig: $(obj)/conf + $< -m Config.in + +defconfig: $(obj)/conf +ifeq ($(KBUILD_DEFCONFIG),) + $< -d Config.in +else + @echo *** Default configuration is based on '$(KBUILD_DEFCONFIG)' + $(Q)$< -D $(KBUILD_DEFCONFIG) Config.in +endif + +%_defconfig: $(obj)/conf + $(Q)$< -D $@ Config.in + +# Help text used by make help +help: + @echo ' config - Update current config utilising a line-oriented program' + @echo ' menuconfig - Update current config utilising a menu based program' + @echo ' xconfig - Update current config utilising a QT based front-end' + @echo ' gconfig - Update current config utilising a GTK based front-end' + @echo ' oldconfig - Update current config utilising a provided .config as base' + @echo ' randconfig - New config with random answer to all options' + @echo ' defconfig - New config with default answer to all options' + @echo ' allmodconfig - New config selecting modules when possible' + @echo ' allyesconfig - New config where all options are accepted with yes' + @echo ' allnoconfig - New config where all options are answered with no' + +# =========================================================================== +# Shared Makefile for the various kconfig executables: +# conf: Used for defconfig, oldconfig and related targets +# mconf: Used for the mconfig target. +# Utilizes the lxdialog package +# qconf: Used for the xconfig target +# Based on QT which needs to be installed to compile it +# gconf: Used for the gconfig target +# Based on GTK which needs to be installed to compile it +# object files used by all kconfig flavours + +hostprogs-y := conf mconf qconf gconf kxgettext +conf-objs := conf.o zconf.tab.o +mconf-objs := mconf.o zconf.tab.o +kxgettext-objs := kxgettext.o zconf.tab.o + +ifeq ($(MAKECMDGOALS),xconfig) + qconf-target := 1 +endif +ifeq ($(MAKECMDGOALS),gconfig) + gconf-target := 1 +endif + + +ifeq ($(qconf-target),1) +qconf-cxxobjs := qconf.o +qconf-objs := kconfig_load.o zconf.tab.o +endif + +ifeq ($(gconf-target),1) +gconf-objs := gconf.o kconfig_load.o zconf.tab.o +endif + +clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \ + .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c +subdir- += lxdialog + +# Needed for systems without gettext +KBUILD_HAVE_NLS := $(shell \ + if echo "\#include " | $(HOSTCC) $(HOSTCFLAGS) -E - > /dev/null 2>&1 ; \ + then echo yes ; \ + else echo no ; fi) +ifeq ($(KBUILD_HAVE_NLS),no) +HOSTCFLAGS += -DKBUILD_NO_NLS +endif + +# generated files seem to need this to find local include files +HOSTCFLAGS_lex.zconf.o := -I$(src) +HOSTCFLAGS_zconf.tab.o := -I$(src) + +HOSTLOADLIBES_qconf = $(KC_QT_LIBS) -ldl +HOSTCXXFLAGS_qconf.o = $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK + +HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0` +HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \ + -D LKC_DIRECT_LINK + +$(obj)/qconf.o: $(obj)/.tmp_qtcheck + +ifeq ($(qconf-target),1) +$(obj)/.tmp_qtcheck: $(src)/Makefile +-include $(obj)/.tmp_qtcheck + +# QT needs some extra effort... +$(obj)/.tmp_qtcheck: + @set -e; echo " CHECK qt"; dir=""; pkg=""; \ + pkg-config --exists qt 2> /dev/null && pkg=qt; \ + pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ + if [ -n "$$pkg" ]; then \ + cflags="\$$(shell pkg-config $$pkg --cflags)"; \ + libs="\$$(shell pkg-config $$pkg --libs)"; \ + moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ + dir="$$(pkg-config $$pkg --variable=prefix)"; \ + else \ + for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \ + if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \ + done; \ + if [ -z "$$dir" ]; then \ + echo "*"; \ + echo "* Unable to find the QT installation. Please make sure that"; \ + echo "* the QT development package is correctly installed and"; \ + echo "* either install pkg-config or set the QTDIR environment"; \ + echo "* variable to the correct location."; \ + echo "*"; \ + false; \ + fi; \ + libpath=$$dir/lib; lib=qt; osdir=""; \ + $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \ + osdir=x$$($(HOSTCXX) -print-multi-os-directory); \ + test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \ + test -f $$libpath/libqt-mt.so && lib=qt-mt; \ + cflags="-I$$dir/include"; \ + libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \ + moc="$$dir/bin/moc"; \ + fi; \ + if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \ + echo "*"; \ + echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \ + echo "*"; \ + moc="/usr/bin/moc"; \ + fi; \ + echo "KC_QT_CFLAGS=$$cflags" > $@; \ + echo "KC_QT_LIBS=$$libs" >> $@; \ + echo "KC_QT_MOC=$$moc" >> $@ +endif + +$(obj)/gconf.o: $(obj)/.tmp_gtkcheck + +ifeq ($(gconf-target),1) +-include $(obj)/.tmp_gtkcheck + +# GTK needs some extra effort, too... +$(obj)/.tmp_gtkcheck: + @if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then \ + if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then \ + touch $@; \ + else \ + echo "*"; \ + echo "* GTK+ is present but version >= 2.0.0 is required."; \ + echo "*"; \ + false; \ + fi \ + else \ + echo "*"; \ + echo "* Unable to find the GTK+ installation. Please make sure that"; \ + echo "* the GTK+ 2.0 development package is correctly installed..."; \ + echo "* You need gtk+-2.0, glib-2.0 and libglade-2.0."; \ + echo "*"; \ + false; \ + fi +endif + +$(obj)/zconf.tab.o: $(obj)/lex.zconf.c $(obj)/zconf.hash.c + +$(obj)/kconfig_load.o: $(obj)/lkc_defs.h + +$(obj)/qconf.o: $(obj)/qconf.moc $(obj)/lkc_defs.h + +$(obj)/gconf.o: $(obj)/lkc_defs.h + +$(obj)/%.moc: $(src)/%.h + $(KC_QT_MOC) -i $< -o $@ + +$(obj)/lkc_defs.h: $(src)/lkc_proto.h + sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/' + + +### +# The following requires flex/bison/gperf +# By default we use the _shipped versions, uncomment the following line if +# you are modifying the flex/bison src. +# LKC_GENPARSER := 1 + +ifdef LKC_GENPARSER + +$(obj)/zconf.tab.c: $(src)/zconf.y +$(obj)/lex.zconf.c: $(src)/zconf.l +$(obj)/zconf.hash.c: $(src)/zconf.gperf + +%.tab.c: %.y + bison -l -b $* -p $(notdir $*) $< + cp $@ $@_shipped + +lex.%.c: %.l + flex -L -P$(notdir $*) -o$@ $< + cp $@ $@_shipped + +%.hash.c: %.gperf + gperf < $< > $@ + cp $@ $@_shipped + +endif diff --git a/scripts/kconfig/POTFILES.in b/scripts/kconfig/POTFILES.in new file mode 100644 index 000000000..cc94e46a7 --- /dev/null +++ b/scripts/kconfig/POTFILES.in @@ -0,0 +1,5 @@ +scripts/kconfig/mconf.c +scripts/kconfig/conf.c +scripts/kconfig/confdata.c +scripts/kconfig/gconf.c +scripts/kconfig/qconf.cc diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c new file mode 100644 index 000000000..8012d1076 --- /dev/null +++ b/scripts/kconfig/conf.c @@ -0,0 +1,612 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +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 +} input_mode = ask_all; +char *defconfig_file; + +static int indent = 1; +static int valid_stdin = 1; +static int conf_cnt; +static char line[128]; +static struct menu *rootEntry; + +static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"); + +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. ")); + printf(_("Run 'make oldconfig' to update configuration.\n\n")); + exit(1); + } +} + +static void conf_askvalue(struct symbol *sym, const char *def) +{ + enum symbol_type type = sym_get_type(sym); + tristate val; + + if (!sym_has_value(sym)) + printf("(NEW) "); + + line[0] = '\n'; + line[1] = 0; + + if (!sym_is_changable(sym)) { + printf("%s\n", def); + line[0] = '\n'; + line[1] = 0; + return; + } + + switch (input_mode) { + case set_no: + case set_mod: + case set_yes: + case set_random: + if (sym_has_value(sym)) { + printf("%s\n", def); + return; + } + break; + case ask_new: + case ask_silent: + if (sym_has_value(sym)) { + printf("%s\n", def); + return; + } + check_stdin(); + case ask_all: + fflush(stdout); + fgets(line, 128, stdin); + return; + case set_default: + printf("%s\n", def); + return; + default: + break; + } + + switch (type) { + case S_INT: + case S_HEX: + case S_STRING: + printf("%s\n", def); + return; + 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; + } + line[1] = '\n'; + line[2] = 0; + break; + default: + break; + } + printf("%s", line); +} + +int conf_string(struct menu *menu) +{ + struct symbol *sym = menu->sym; + const char *def, *help; + + while (1) { + printf("%*s%s ", indent - 1, "", menu->prompt->text); + printf("(%s) ", sym->name); + def = sym_get_string_value(sym); + if (sym_get_string_value(sym)) + printf("[%s] ", def); + conf_askvalue(sym, def); + switch (line[0]) { + case '\n': + break; + case '?': + /* print help */ + if (line[1] == '\n') { + help = nohelp_text; + if (menu->sym->help) + help = menu->sym->help; + printf("\n%s\n", menu->sym->help); + 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; + int type; + tristate oldval, newval; + const char *help; + + while (1) { + printf("%*s%s ", indent - 1, "", menu->prompt->text); + if (sym->name) + printf("(%s) ", sym->name); + type = sym_get_type(sym); + putchar('['); + oldval = sym_get_tristate_value(sym); + switch (oldval) { + case no: + putchar('N'); + break; + case mod: + putchar('M'); + break; + case yes: + putchar('Y'); + break; + } + if (oldval != no && sym_tristate_within_range(sym, no)) + printf("/n"); + if (oldval != mod && sym_tristate_within_range(sym, mod)) + printf("/m"); + if (oldval != yes && sym_tristate_within_range(sym, yes)) + printf("/y"); + if (sym->help) + printf("/?"); + printf("] "); + conf_askvalue(sym, sym_get_string_value(sym)); + 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: + help = nohelp_text; + if (sym->help) + help = sym->help; + printf("\n%s\n", help); + } +} + +static int conf_choice(struct menu *menu) +{ + struct symbol *sym, *def_sym; + struct menu *child; + int type; + bool is_new; + + sym = menu->sym; + type = sym_get_type(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: + printf("%*s%s\n", indent - 1, "", menu_get_prompt(menu)); + return 0; + case yes: + break; + } + } + + while (1) { + int cnt, def; + + printf("%*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) { + printf("%*c %s\n", indent, '*', menu_get_prompt(child)); + continue; + } + cnt++; + if (child->sym == def_sym) { + def = cnt; + printf("%*c", indent, '>'); + } else + printf("%*c", indent, ' '); + printf(" %d. %s", cnt, menu_get_prompt(child)); + if (child->sym->name) + printf(" (%s)", child->sym->name); + if (!sym_has_value(child->sym)) + printf(" (NEW)"); + printf("\n"); + } + printf("%*schoice", indent - 1, ""); + if (cnt == 1) { + printf("[1]: 1\n"); + goto conf_childs; + } + printf("[1-%d", cnt); + if (sym->help) + printf("?"); + printf("]: "); + switch (input_mode) { + case ask_new: + case ask_silent: + if (!is_new) { + cnt = def; + printf("%d\n", cnt); + break; + } + check_stdin(); + case ask_all: + fflush(stdout); + fgets(line, 128, stdin); + strip(line); + if (line[0] == '?') { + printf("\n%s\n", menu->sym->help ? + menu->sym->help : nohelp_text); + 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: + cnt = def; + printf("%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] == '?') { + printf("\n%s\n", child->sym->help ? + child->sym->help : nohelp_text); + 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) + printf("%*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++) + printf(_("*\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; + + 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 '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: Kconfig file missing\n"), av[0]); + } + 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: + if (stat(".config", &tmpstat)) { + printf(_("***\n" + "*** You have not yet configured your kernel!\n" + "***\n" + "*** Please run some configurator (e.g. \"make oldconfig\" or\n" + "*** \"make menuconfig\" or \"make xconfig\").\n" + "***\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: + name = getenv("KCONFIG_ALLCONFIG"); + if (name && !stat(name, &tmpstat)) { + conf_read_simple(name); + 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; + default: break; + } + if (!stat(name, &tmpstat)) + conf_read_simple(name); + else if (!stat("all.config", &tmpstat)) + conf_read_simple("all.config"); + break; + default: + break; + } + + if (input_mode != ask_silent) { + rootEntry = &rootmenu; + conf(&rootmenu); + if (input_mode == ask_all) { + input_mode = ask_silent; + valid_stdin = 1; + } + } + do { + conf_cnt = 0; + check_conf(&rootmenu); + } while (conf_cnt); + if (conf_write(NULL)) { + fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); + return 1; + } + return 0; +} diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c new file mode 100644 index 000000000..301774f0c --- /dev/null +++ b/scripts/kconfig/confdata.c @@ -0,0 +1,560 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +static void conf_warning(const char *fmt, ...) + __attribute__ ((format (printf, 1, 2))); + +static const char *conf_filename; +static int conf_lineno, conf_warnings, conf_unsaved; + +const char conf_def_filename[] = ".config"; + +const char conf_defname[] = "arch/$ARCH/defconfig"; + +const char *conf_confnames[] = { + ".config", + "/lib/modules/$UNAME_RELEASE/.config", + "/etc/kernel-config", + "/boot/config-$UNAME_RELEASE", + conf_defname, + NULL, +}; + +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++; +} + +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) +{ + struct stat buf; + static char fullname[PATH_MAX+1]; + char *env, *name; + + name = conf_expand_value(conf_defname); + env = getenv(SRCTREE); + if (env) { + sprintf(fullname, "%s/%s", env, name); + if (!stat(fullname, &buf)) + return fullname; + } + return name; +} + +int conf_read_simple(const char *name) +{ + FILE *in = NULL; + char line[1024]; + char *p, *p2; + struct symbol *sym; + int i; + + if (name) { + in = zconf_fopen(name); + } else { + const char **names = conf_confnames; + while ((name = *names++)) { + name = conf_expand_value(name); + in = zconf_fopen(name); + if (in) { + printf(_("#\n" + "# using defaults found in %s\n" + "#\n"), name); + break; + } + } + } + if (!in) + return 1; + + conf_filename = name; + conf_lineno = 0; + conf_warnings = 0; + conf_unsaved = 0; + + for_all_symbols(i, sym) { + sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; + if (sym_is_choice(sym)) + sym->flags &= ~SYMBOL_NEW; + sym->flags &= ~SYMBOL_VALID; + switch (sym->type) { + case S_INT: + case S_HEX: + case S_STRING: + if (sym->user.val) + free(sym->user.val); + default: + sym->user.val = NULL; + sym->user.tri = no; + } + } + + while (fgets(line, sizeof(line), in)) { + conf_lineno++; + sym = NULL; + switch (line[0]) { + case '#': + if (memcmp(line + 2, "CONFIG_", 7)) + continue; + p = strchr(line + 9, ' '); + if (!p) + continue; + *p++ = 0; + if (strncmp(p, "is not set", 10)) + continue; + sym = sym_find(line + 9); + if (!sym) { + conf_warning("trying to assign nonexistent symbol %s", line + 9); + break; + } else if (!(sym->flags & SYMBOL_NEW)) { + conf_warning("trying to reassign symbol %s", sym->name); + break; + } + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: + sym->user.tri = no; + sym->flags &= ~SYMBOL_NEW; + break; + default: + ; + } + break; + case 'C': + if (memcmp(line, "CONFIG_", 7)) { + conf_warning("unexpected data"); + continue; + } + p = strchr(line + 7, '='); + if (!p) + continue; + *p++ = 0; + p2 = strchr(p, '\n'); + if (p2) + *p2 = 0; + sym = sym_find(line + 7); + if (!sym) { + conf_warning("trying to assign nonexistent symbol %s", line + 7); + break; + } else if (!(sym->flags & SYMBOL_NEW)) { + conf_warning("trying to reassign symbol %s", sym->name); + break; + } + switch (sym->type) { + case S_TRISTATE: + if (p[0] == 'm') { + sym->user.tri = mod; + sym->flags &= ~SYMBOL_NEW; + break; + } + case S_BOOLEAN: + if (p[0] == 'y') { + sym->user.tri = yes; + sym->flags &= ~SYMBOL_NEW; + break; + } + if (p[0] == 'n') { + sym->user.tri = no; + sym->flags &= ~SYMBOL_NEW; + break; + } + conf_warning("symbol value '%s' invalid for %s", p, sym->name); + break; + 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: + if (sym_string_valid(sym, p)) { + sym->user.val = strdup(p); + sym->flags &= ~SYMBOL_NEW; + } else { + conf_warning("symbol value '%s' invalid for %s", p, sym->name); + continue; + } + break; + default: + ; + } + break; + 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->user.tri) { + case no: + break; + case mod: + if (cs->user.tri == yes) { + conf_warning("%s creates inconsistent choice state", sym->name); + cs->flags |= SYMBOL_NEW; + } + break; + case yes: + if (cs->user.tri != no) { + conf_warning("%s creates inconsistent choice state", sym->name); + cs->flags |= SYMBOL_NEW; + } else + cs->user.val = sym; + break; + } + cs->user.tri = E_OR(cs->user.tri, sym->user.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; + + if (conf_read_simple(name)) + 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->user.tri != sym_get_tristate_value(sym)) + break; + if (!sym_is_choice(sym)) + goto sym_ok; + default: + if (!strcmp(sym->curr.val, sym->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_has_value(sym) && !sym_is_choice_value(sym)) { + if (sym->visible == no) + sym->flags |= SYMBOL_NEW; + switch (sym->type) { + case S_STRING: + case S_INT: + case S_HEX: + if (!sym_string_within_range(sym, sym->user.val)) { + sym->flags |= SYMBOL_NEW; + sym->flags &= ~SYMBOL_VALID; + } + default: + break; + } + } + if (!sym_is_choice(sym)) + continue; + prop = sym_get_choice_prop(sym); + for (e = prop->expr; e; e = e->left.expr) + if (e->right.sym->visible != no) + sym->flags |= e->right.sym->flags & SYMBOL_NEW; + } + + sym_change_count = conf_warnings || conf_unsaved; + + return 0; +} + +int conf_write(const char *name) +{ + FILE *out, *out_h; + struct symbol *sym; + struct menu *menu; + const char *basename; + char dirname[128], tmpname[128], newname[128]; + 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_def_filename; + } 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_def_filename; + } else + basename = name; + } else + basename = conf_def_filename; + + sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid()); + out = fopen(newname, "w"); + if (!out) + return 1; + out_h = NULL; + if (!name) { + out_h = fopen(".tmpconfig.h", "w"); + if (!out_h) + return 1; + file_write_dep(NULL); + } + sym = sym_lookup("KERNELVERSION", 0); + sym_calc_value(sym); + time(&now); + env = getenv("KCONFIG_NOTIMESTAMP"); + if (env && *env) + use_timestamp = 0; + + fprintf(out, _("#\n" + "# Automatically generated make config: don't edit\n" + "# Linux kernel version: %s\n" + "%s%s" + "#\n"), + sym_get_string_value(sym), + use_timestamp ? "# " : "", + use_timestamp ? ctime(&now) : ""); + if (out_h) { + char buf[sizeof("#define AUTOCONF_TIMESTAMP " + "\"YYYY-MM-DD HH:MM:SS some_timezone\"\n")]; + buf[0] = '\0'; + if (use_timestamp) + strftime(buf, sizeof(buf), "#define AUTOCONF_TIMESTAMP " + "\"%Y-%m-%d %H:%M:%S %Z\"\n", localtime(&now)); + fprintf(out_h, "/*\n" + " * Automatically generated C config: don't edit\n" + " * Linux kernel version: %s\n" + " */\n" + "%s" + "#define AUTOCONF_INCLUDED\n", + sym_get_string_value(sym), + buf); + } + if (!sym_change_count) + 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); + if (out_h) + fprintf(out_h, "\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); + if (out_h) { + fprintf(out_h, "#undef CONFIG_%s\n", sym->name); + /* bbox */ + fprintf(out_h, "#define ENABLE_%s 0\n", sym->name); + fprintf(out_h, "#define USE_%s(...)\n", sym->name); + fprintf(out_h, "#define SKIP_%s(...) __VA_ARGS__\n", sym->name); + } + break; + case mod: + fprintf(out, "CONFIG_%s=m\n", sym->name); + if (out_h) + fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name); + break; + case yes: + fprintf(out, "CONFIG_%s=y\n", sym->name); + if (out_h) { + fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); + /* bbox */ + fprintf(out_h, "#define ENABLE_%s 1\n", sym->name); + fprintf(out_h, "#define USE_%s(...) __VA_ARGS__\n", sym->name); + fprintf(out_h, "#define SKIP_%s(...)\n", sym->name); + } + break; + } + break; + case S_STRING: + // fix me + str = sym_get_string_value(sym); + fprintf(out, "CONFIG_%s=\"", sym->name); + if (out_h) + fprintf(out_h, "#define CONFIG_%s \"", sym->name); + do { + l = strcspn(str, "\"\\"); + if (l) { + fwrite(str, l, 1, out); + if (out_h) + fwrite(str, l, 1, out_h); + } + str += l; + while (*str == '\\' || *str == '"') { + fprintf(out, "\\%c", *str); + if (out_h) + fprintf(out_h, "\\%c", *str); + str++; + } + } while (*str); + fputs("\"\n", out); + if (out_h) { + fputs("\"\n", out_h); + /* bbox */ + fprintf(out_h, "#define ENABLE_%s 1\n", sym->name); + fprintf(out_h, "#define USE_%s(...) __VA_ARGS__\n", sym->name); + fprintf(out_h, "#define SKIP_%s(...)\n", sym->name); + } + 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); + if (out_h) { + fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); + /* bbox */ + fprintf(out_h, "#define ENABLE_%s 1\n", sym->name); + fprintf(out_h, "#define USE_%s(...) __VA_ARGS__\n", sym->name); + fprintf(out_h, "#define SKIP_%s(...)\n", sym->name); + } + break; + } + case S_INT: + str = sym_get_string_value(sym); + fprintf(out, "CONFIG_%s=%s\n", sym->name, str); + if (out_h) { + fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); + /* bbox */ + fprintf(out_h, "#define ENABLE_%s 1\n", sym->name); + fprintf(out_h, "#define USE_%s(...) __VA_ARGS__\n", sym->name); + fprintf(out_h, "#define SKIP_%s(...)\n", sym->name); + } + 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 (out_h) { + fclose(out_h); + rename(".tmpconfig.h", "include/autoconf.h"); + } + if (!name || basename != conf_def_filename) { + if (!name) + name = conf_def_filename; + sprintf(tmpname, "%s.old", name); + rename(name, tmpname); + } + sprintf(tmpname, "%s%s", dirname, basename); + if (rename(newname, tmpname)) + return 1; + + sym_change_count = 0; + + return 0; +} diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c new file mode 100644 index 000000000..30e4f9d69 --- /dev/null +++ b/scripts/kconfig/expr.c @@ -0,0 +1,1099 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include + +#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->flags & (SYMBOL_YES|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 *, const char *), void *data, int prevtoken) +{ + if (!e) { + fn(data, "y"); + return; + } + + if (expr_compare_type(prevtoken, e->type) > 0) + fn(data, "("); + switch (e->type) { + case E_SYMBOL: + if (e->left.sym->name) + fn(data, e->left.sym->name); + else + fn(data, ""); + break; + case E_NOT: + fn(data, "!"); + expr_print(e->left.expr, fn, data, E_NOT); + break; + case E_EQUAL: + fn(data, e->left.sym->name); + fn(data, "="); + fn(data, e->right.sym->name); + break; + case E_UNEQUAL: + fn(data, e->left.sym->name); + fn(data, "!="); + fn(data, e->right.sym->name); + break; + case E_OR: + expr_print(e->left.expr, fn, data, E_OR); + fn(data, " || "); + expr_print(e->right.expr, fn, data, E_OR); + break; + case E_AND: + expr_print(e->left.expr, fn, data, E_AND); + fn(data, " && "); + expr_print(e->right.expr, fn, data, E_AND); + break; + case E_CHOICE: + fn(data, e->right.sym->name); + if (e->left.expr) { + fn(data, " ^ "); + expr_print(e->left.expr, fn, data, E_CHOICE); + } + break; + case E_RANGE: + fn(data, "["); + fn(data, e->left.sym->name); + fn(data, " "); + fn(data, e->right.sym->name); + fn(data, "]"); + break; + default: + { + char buf[32]; + sprintf(buf, "", e->type); + fn(data, buf); + break; + } + } + if (expr_compare_type(prevtoken, e->type) > 0) + fn(data, ")"); +} + +static void expr_print_file_helper(void *data, 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, 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/scripts/kconfig/expr.h b/scripts/kconfig/expr.h new file mode 100644 index 000000000..1b36ef18c --- /dev/null +++ b/scripts/kconfig/expr.h @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#ifndef EXPR_H +#define EXPR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifndef __cplusplus +#include +#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 +}; + +struct symbol { + struct symbol *next; + char *name; + char *help; + enum symbol_type type; + struct symbol_value curr, user; + tristate visible; + int flags; + struct property *prop; + struct expr *dep, *dep2; + 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_YES 0x0001 +#define SYMBOL_MOD 0x0002 +#define SYMBOL_NO 0x0004 +#define SYMBOL_CONST 0x0007 +#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_NEW 0x0800 +#define SYMBOL_AUTO 0x1000 +#define SYMBOL_CHECKED 0x2000 +#define SYMBOL_WARNED 0x8000 + +#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 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/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c new file mode 100644 index 000000000..665bd5300 --- /dev/null +++ b/scripts/kconfig/gconf.c @@ -0,0 +1,1645 @@ +/* Hey EMACS -*- linux-c -*- */ +/* + * + * Copyright (C) 2002-2003 Romain Lievin + * Released under the terms of the GNU GPL v2.0. + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "lkc.h" +#include "images.c" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//#define DEBUG + +enum { + SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW +}; + +static gint view_mode = FULL_VIEW; +static gboolean show_name = TRUE; +static gboolean show_range = TRUE; +static gboolean show_value = TRUE; +static gboolean show_all = FALSE; +static gboolean show_debug = FALSE; +static gboolean resizeable = FALSE; + +static gboolean config_changed = FALSE; + +static char nohelp_text[] = + N_("Sorry, no help available for this option yet.\n"); + +GtkWidget *main_wnd = NULL; +GtkWidget *tree1_w = NULL; // left frame +GtkWidget *tree2_w = NULL; // right frame +GtkWidget *text_w = NULL; +GtkWidget *hpaned = NULL; +GtkWidget *vpaned = NULL; +GtkWidget *back_btn = NULL; + +GtkTextTag *tag1, *tag2; +GdkColor color; + +GtkTreeStore *tree1, *tree2, *tree; +GtkTreeModel *model1, *model2; +static GtkTreeIter *parents[256]; +static gint indent; + +static struct menu *current; // current node for SINGLE view +static struct menu *browsed; // browsed node for SPLIT view + +enum { + COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE, + COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF, + COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD, + COL_NUMBER +}; + +static void display_list(void); +static void display_tree(struct menu *menu); +static void display_tree_part(void); +static void update_tree(struct menu *src, GtkTreeIter * dst); +static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row); +static gchar **fill_row(struct menu *menu); + + +/* Helping/Debugging Functions */ + + +const char *dbg_print_stype(int val) +{ + static char buf[256]; + + bzero(buf, 256); + + if (val == S_UNKNOWN) + strcpy(buf, "unknown"); + if (val == S_BOOLEAN) + strcpy(buf, "boolean"); + if (val == S_TRISTATE) + strcpy(buf, "tristate"); + if (val == S_INT) + strcpy(buf, "int"); + if (val == S_HEX) + strcpy(buf, "hex"); + if (val == S_STRING) + strcpy(buf, "string"); + if (val == S_OTHER) + strcpy(buf, "other"); + +#ifdef DEBUG + printf("%s", buf); +#endif + + return buf; +} + +const char *dbg_print_flags(int val) +{ + static char buf[256]; + + bzero(buf, 256); + + if (val & SYMBOL_YES) + strcat(buf, "yes/"); + if (val & SYMBOL_MOD) + strcat(buf, "mod/"); + if (val & SYMBOL_NO) + strcat(buf, "no/"); + if (val & SYMBOL_CONST) + strcat(buf, "const/"); + if (val & SYMBOL_CHECK) + strcat(buf, "check/"); + if (val & SYMBOL_CHOICE) + strcat(buf, "choice/"); + if (val & SYMBOL_CHOICEVAL) + strcat(buf, "choiceval/"); + if (val & SYMBOL_PRINTED) + strcat(buf, "printed/"); + if (val & SYMBOL_VALID) + strcat(buf, "valid/"); + if (val & SYMBOL_OPTIONAL) + strcat(buf, "optional/"); + if (val & SYMBOL_WRITE) + strcat(buf, "write/"); + if (val & SYMBOL_CHANGED) + strcat(buf, "changed/"); + if (val & SYMBOL_NEW) + strcat(buf, "new/"); + if (val & SYMBOL_AUTO) + strcat(buf, "auto/"); + + buf[strlen(buf) - 1] = '\0'; +#ifdef DEBUG + printf("%s", buf); +#endif + + return buf; +} + +const char *dbg_print_ptype(int val) +{ + static char buf[256]; + + bzero(buf, 256); + + if (val == P_UNKNOWN) + strcpy(buf, "unknown"); + if (val == P_PROMPT) + strcpy(buf, "prompt"); + if (val == P_COMMENT) + strcpy(buf, "comment"); + if (val == P_MENU) + strcpy(buf, "menu"); + if (val == P_DEFAULT) + strcpy(buf, "default"); + if (val == P_CHOICE) + strcpy(buf, "choice"); + +#ifdef DEBUG + printf("%s", buf); +#endif + + return buf; +} + + +void replace_button_icon(GladeXML * xml, GdkDrawable * window, + GtkStyle * style, gchar * btn_name, gchar ** xpm) +{ + GdkPixmap *pixmap; + GdkBitmap *mask; + GtkToolButton *button; + GtkWidget *image; + + pixmap = gdk_pixmap_create_from_xpm_d(window, &mask, + &style->bg[GTK_STATE_NORMAL], + xpm); + + button = GTK_TOOL_BUTTON(glade_xml_get_widget(xml, btn_name)); + image = gtk_image_new_from_pixmap(pixmap, mask); + gtk_widget_show(image); + gtk_tool_button_set_icon_widget(button, image); +} + +/* Main Window Initialization */ +void init_main_window(const gchar * glade_file) +{ + GladeXML *xml; + GtkWidget *widget; + GtkTextBuffer *txtbuf; + char title[256]; + GtkStyle *style; + + xml = glade_xml_new(glade_file, "window1", NULL); + if (!xml) + g_error(_("GUI loading failed !\n")); + glade_xml_signal_autoconnect(xml); + + main_wnd = glade_xml_get_widget(xml, "window1"); + hpaned = glade_xml_get_widget(xml, "hpaned1"); + vpaned = glade_xml_get_widget(xml, "vpaned1"); + tree1_w = glade_xml_get_widget(xml, "treeview1"); + tree2_w = glade_xml_get_widget(xml, "treeview2"); + text_w = glade_xml_get_widget(xml, "textview3"); + + back_btn = glade_xml_get_widget(xml, "button1"); + gtk_widget_set_sensitive(back_btn, FALSE); + + widget = glade_xml_get_widget(xml, "show_name1"); + gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, + show_name); + + widget = glade_xml_get_widget(xml, "show_range1"); + gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, + show_range); + + widget = glade_xml_get_widget(xml, "show_data1"); + gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, + show_value); + + style = gtk_widget_get_style(main_wnd); + widget = glade_xml_get_widget(xml, "toolbar1"); + +#if 0 /* Use stock Gtk icons instead */ + replace_button_icon(xml, main_wnd->window, style, + "button1", (gchar **) xpm_back); + replace_button_icon(xml, main_wnd->window, style, + "button2", (gchar **) xpm_load); + replace_button_icon(xml, main_wnd->window, style, + "button3", (gchar **) xpm_save); +#endif + replace_button_icon(xml, main_wnd->window, style, + "button4", (gchar **) xpm_single_view); + replace_button_icon(xml, main_wnd->window, style, + "button5", (gchar **) xpm_split_view); + replace_button_icon(xml, main_wnd->window, style, + "button6", (gchar **) xpm_tree_view); + +#if 0 + switch (view_mode) { + case SINGLE_VIEW: + widget = glade_xml_get_widget(xml, "button4"); + g_signal_emit_by_name(widget, "clicked"); + break; + case SPLIT_VIEW: + widget = glade_xml_get_widget(xml, "button5"); + g_signal_emit_by_name(widget, "clicked"); + break; + case FULL_VIEW: + widget = glade_xml_get_widget(xml, "button6"); + g_signal_emit_by_name(widget, "clicked"); + break; + } +#endif + txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1", + "foreground", "red", + "weight", PANGO_WEIGHT_BOLD, + NULL); + tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2", + /*"style", PANGO_STYLE_OBLIQUE, */ + NULL); + + sprintf(title, _("Linux Kernel v%s Configuration"), + getenv("KERNELVERSION")); + gtk_window_set_title(GTK_WINDOW(main_wnd), title); + + gtk_widget_show(main_wnd); +} + +void init_tree_model(void) +{ + gint i; + + tree = tree2 = gtk_tree_store_new(COL_NUMBER, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_POINTER, GDK_TYPE_COLOR, + G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN); + model2 = GTK_TREE_MODEL(tree2); + + for (parents[0] = NULL, i = 1; i < 256; i++) + parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter)); + + tree1 = gtk_tree_store_new(COL_NUMBER, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_POINTER, GDK_TYPE_COLOR, + G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, + G_TYPE_BOOLEAN); + model1 = GTK_TREE_MODEL(tree1); +} + +void init_left_tree(void) +{ + GtkTreeView *view = GTK_TREE_VIEW(tree1_w); + GtkCellRenderer *renderer; + GtkTreeSelection *sel; + GtkTreeViewColumn *column; + + gtk_tree_view_set_model(view, model1); + gtk_tree_view_set_headers_visible(view, TRUE); + gtk_tree_view_set_rules_hint(view, FALSE); + + column = gtk_tree_view_column_new(); + gtk_tree_view_append_column(view, column); + gtk_tree_view_column_set_title(column, _("Options")); + + renderer = gtk_cell_renderer_toggle_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "active", COL_BTNACT, + "inconsistent", COL_BTNINC, + "visible", COL_BTNVIS, + "radio", COL_BTNRAD, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "text", COL_OPTION, + "foreground-gdk", + COL_COLOR, NULL); + + sel = gtk_tree_view_get_selection(view); + gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); + gtk_widget_realize(tree1_w); +} + +static void renderer_edited(GtkCellRendererText * cell, + const gchar * path_string, + const gchar * new_text, gpointer user_data); +static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle, + gchar * arg1, gpointer user_data); + +void init_right_tree(void) +{ + GtkTreeView *view = GTK_TREE_VIEW(tree2_w); + GtkCellRenderer *renderer; + GtkTreeSelection *sel; + GtkTreeViewColumn *column; + gint i; + + gtk_tree_view_set_model(view, model2); + gtk_tree_view_set_headers_visible(view, TRUE); + gtk_tree_view_set_rules_hint(view, FALSE); + + column = gtk_tree_view_column_new(); + gtk_tree_view_append_column(view, column); + gtk_tree_view_column_set_title(column, _("Options")); + + renderer = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "pixbuf", COL_PIXBUF, + "visible", COL_PIXVIS, NULL); + renderer = gtk_cell_renderer_toggle_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "active", COL_BTNACT, + "inconsistent", COL_BTNINC, + "visible", COL_BTNVIS, + "radio", COL_BTNRAD, NULL); + /*g_signal_connect(G_OBJECT(renderer), "toggled", + G_CALLBACK(renderer_toggled), NULL); */ + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "text", COL_OPTION, + "foreground-gdk", + COL_COLOR, NULL); + + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + _("Name"), renderer, + "text", COL_NAME, + "foreground-gdk", + COL_COLOR, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "N", renderer, + "text", COL_NO, + "foreground-gdk", + COL_COLOR, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "M", renderer, + "text", COL_MOD, + "foreground-gdk", + COL_COLOR, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "Y", renderer, + "text", COL_YES, + "foreground-gdk", + COL_COLOR, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + _("Value"), renderer, + "text", COL_VALUE, + "editable", + COL_EDIT, + "foreground-gdk", + COL_COLOR, NULL); + g_signal_connect(G_OBJECT(renderer), "edited", + G_CALLBACK(renderer_edited), NULL); + + column = gtk_tree_view_get_column(view, COL_NAME); + gtk_tree_view_column_set_visible(column, show_name); + column = gtk_tree_view_get_column(view, COL_NO); + gtk_tree_view_column_set_visible(column, show_range); + column = gtk_tree_view_get_column(view, COL_MOD); + gtk_tree_view_column_set_visible(column, show_range); + column = gtk_tree_view_get_column(view, COL_YES); + gtk_tree_view_column_set_visible(column, show_range); + column = gtk_tree_view_get_column(view, COL_VALUE); + gtk_tree_view_column_set_visible(column, show_value); + + if (resizeable) { + for (i = 0; i < COL_VALUE; i++) { + column = gtk_tree_view_get_column(view, i); + gtk_tree_view_column_set_resizable(column, TRUE); + } + } + + sel = gtk_tree_view_get_selection(view); + gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); +} + + +/* Utility Functions */ + + +static void text_insert_help(struct menu *menu) +{ + GtkTextBuffer *buffer; + GtkTextIter start, end; + const char *prompt = menu_get_prompt(menu); + gchar *name; + const char *help = _(nohelp_text); + + if (!menu->sym) + help = ""; + else if (menu->sym->help) + help = _(menu->sym->help); + + if (menu->sym && menu->sym->name) + name = g_strdup_printf(_(menu->sym->name)); + else + name = g_strdup(""); + + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + gtk_text_buffer_get_bounds(buffer, &start, &end); + gtk_text_buffer_delete(buffer, &start, &end); + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15); + + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1, + NULL); + gtk_text_buffer_insert_at_cursor(buffer, " ", 1); + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, name, -1, tag1, + NULL); + gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, help, -1, tag2, + NULL); +} + + +static void text_insert_msg(const char *title, const char *message) +{ + GtkTextBuffer *buffer; + GtkTextIter start, end; + const char *msg = message; + + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + gtk_text_buffer_get_bounds(buffer, &start, &end); + gtk_text_buffer_delete(buffer, &start, &end); + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15); + + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1, + NULL); + gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2); + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2, + NULL); +} + + +/* Main Windows Callbacks */ + +void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data); +gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event, + gpointer user_data) +{ + GtkWidget *dialog, *label; + gint result; + + if (config_changed == FALSE) + return FALSE; + + dialog = gtk_dialog_new_with_buttons(_("Warning !"), + GTK_WINDOW(main_wnd), + (GtkDialogFlags) + (GTK_DIALOG_MODAL | + GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_STOCK_OK, + GTK_RESPONSE_YES, + GTK_STOCK_NO, + GTK_RESPONSE_NO, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, NULL); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), + GTK_RESPONSE_CANCEL); + + label = gtk_label_new(_("\nSave configuration ?\n")); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label); + gtk_widget_show(label); + + result = gtk_dialog_run(GTK_DIALOG(dialog)); + switch (result) { + case GTK_RESPONSE_YES: + on_save1_activate(NULL, NULL); + return FALSE; + case GTK_RESPONSE_NO: + return FALSE; + case GTK_RESPONSE_CANCEL: + case GTK_RESPONSE_DELETE_EVENT: + default: + gtk_widget_destroy(dialog); + return TRUE; + } + + return FALSE; +} + + +void on_window1_destroy(GtkObject * object, gpointer user_data) +{ + gtk_main_quit(); +} + + +void +on_window1_size_request(GtkWidget * widget, + GtkRequisition * requisition, gpointer user_data) +{ + static gint old_h; + gint w, h; + + if (widget->window == NULL) + gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h); + else + gdk_window_get_size(widget->window, &w, &h); + + if (h == old_h) + return; + old_h = h; + + gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3); +} + + +/* Menu & Toolbar Callbacks */ + + +static void +load_filename(GtkFileSelection * file_selector, gpointer user_data) +{ + const gchar *fn; + + fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION + (user_data)); + + if (conf_read(fn)) + text_insert_msg(_("Error"), _("Unable to load configuration !")); + else + display_tree(&rootmenu); +} + +void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *fs; + + fs = gtk_file_selection_new(_("Load file...")); + g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), + "clicked", + G_CALLBACK(load_filename), (gpointer) fs); + g_signal_connect_swapped(GTK_OBJECT + (GTK_FILE_SELECTION(fs)->ok_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + (gpointer) fs); + g_signal_connect_swapped(GTK_OBJECT + (GTK_FILE_SELECTION(fs)->cancel_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + (gpointer) fs); + gtk_widget_show(fs); +} + + +void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + if (conf_write(NULL)) + text_insert_msg(_("Error"), _("Unable to save configuration !")); + + config_changed = FALSE; +} + + +static void +store_filename(GtkFileSelection * file_selector, gpointer user_data) +{ + const gchar *fn; + + fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION + (user_data)); + + if (conf_write(fn)) + text_insert_msg(_("Error"), _("Unable to save configuration !")); + + gtk_widget_destroy(GTK_WIDGET(user_data)); +} + +void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *fs; + + fs = gtk_file_selection_new(_("Save file as...")); + g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), + "clicked", + G_CALLBACK(store_filename), (gpointer) fs); + g_signal_connect_swapped(GTK_OBJECT + (GTK_FILE_SELECTION(fs)->ok_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + (gpointer) fs); + g_signal_connect_swapped(GTK_OBJECT + (GTK_FILE_SELECTION(fs)->cancel_button), + "clicked", G_CALLBACK(gtk_widget_destroy), + (gpointer) fs); + gtk_widget_show(fs); +} + + +void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + if (!on_window1_delete_event(NULL, NULL, NULL)) + gtk_widget_destroy(GTK_WIDGET(main_wnd)); +} + + +void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkTreeViewColumn *col; + + show_name = GTK_CHECK_MENU_ITEM(menuitem)->active; + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME); + if (col) + gtk_tree_view_column_set_visible(col, show_name); +} + + +void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkTreeViewColumn *col; + + show_range = GTK_CHECK_MENU_ITEM(menuitem)->active; + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO); + if (col) + gtk_tree_view_column_set_visible(col, show_range); + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD); + if (col) + gtk_tree_view_column_set_visible(col, show_range); + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES); + if (col) + gtk_tree_view_column_set_visible(col, show_range); + +} + + +void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkTreeViewColumn *col; + + show_value = GTK_CHECK_MENU_ITEM(menuitem)->active; + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE); + if (col) + gtk_tree_view_column_set_visible(col, show_value); +} + + +void +on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + show_all = GTK_CHECK_MENU_ITEM(menuitem)->active; + + gtk_tree_store_clear(tree2); + display_tree(&rootmenu); // instead of update_tree to speed-up +} + + +void +on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active; + update_tree(&rootmenu, NULL); +} + + +void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *dialog; + const gchar *intro_text = _( + "Welcome to gkc, the GTK+ graphical kernel configuration tool\n" + "for Linux.\n" + "For each option, a blank box indicates the feature is disabled, a\n" + "check indicates it is enabled, and a dot indicates that it is to\n" + "be compiled as a module. Clicking on the box will cycle through the three states.\n" + "\n" + "If you do not see an option (e.g., a device driver) that you\n" + "believe should be present, try turning on Show All Options\n" + "under the Options menu.\n" + "Although there is no cross reference yet to help you figure out\n" + "what other options must be enabled to support the option you\n" + "are interested in, you can still view the help of a grayed-out\n" + "option.\n" + "\n" + "Toggling Show Debug Info under the Options menu will show \n" + "the dependencies, which you can then match by examining other options."); + + dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, intro_text); + g_signal_connect_swapped(GTK_OBJECT(dialog), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(dialog)); + gtk_widget_show_all(dialog); +} + + +void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *dialog; + const gchar *about_text = + _("gkc is copyright (c) 2002 Romain Lievin .\n" + "Based on the source code from Roman Zippel.\n"); + + dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, about_text); + g_signal_connect_swapped(GTK_OBJECT(dialog), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(dialog)); + gtk_widget_show_all(dialog); +} + + +void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) +{ + GtkWidget *dialog; + const gchar *license_text = + _("gkc is released under the terms of the GNU GPL v2.\n" + "For more information, please see the source code or\n" + "visit http://www.fsf.org/licenses/licenses.html\n"); + + dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, license_text); + g_signal_connect_swapped(GTK_OBJECT(dialog), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(dialog)); + gtk_widget_show_all(dialog); +} + + +void on_back_clicked(GtkButton * button, gpointer user_data) +{ + enum prop_type ptype; + + current = current->parent; + ptype = current->prompt ? current->prompt->type : P_UNKNOWN; + if (ptype != P_MENU) + current = current->parent; + display_tree_part(); + + if (current == &rootmenu) + gtk_widget_set_sensitive(back_btn, FALSE); +} + + +void on_load_clicked(GtkButton * button, gpointer user_data) +{ + on_load1_activate(NULL, user_data); +} + + +void on_save_clicked(GtkButton * button, gpointer user_data) +{ + on_save1_activate(NULL, user_data); +} + + +void on_single_clicked(GtkButton * button, gpointer user_data) +{ + view_mode = SINGLE_VIEW; + gtk_paned_set_position(GTK_PANED(hpaned), 0); + gtk_widget_hide(tree1_w); + current = &rootmenu; + display_tree_part(); +} + + +void on_split_clicked(GtkButton * button, gpointer user_data) +{ + gint w, h; + view_mode = SPLIT_VIEW; + gtk_widget_show(tree1_w); + gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h); + gtk_paned_set_position(GTK_PANED(hpaned), w / 2); + if (tree2) + gtk_tree_store_clear(tree2); + display_list(); + + /* Disable back btn, like in full mode. */ + gtk_widget_set_sensitive(back_btn, FALSE); +} + + +void on_full_clicked(GtkButton * button, gpointer user_data) +{ + view_mode = FULL_VIEW; + gtk_paned_set_position(GTK_PANED(hpaned), 0); + gtk_widget_hide(tree1_w); + if (tree2) + gtk_tree_store_clear(tree2); + display_tree(&rootmenu); + gtk_widget_set_sensitive(back_btn, FALSE); +} + + +void on_collapse_clicked(GtkButton * button, gpointer user_data) +{ + gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w)); +} + + +void on_expand_clicked(GtkButton * button, gpointer user_data) +{ + gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); +} + + +/* CTree Callbacks */ + +/* Change hex/int/string value in the cell */ +static void renderer_edited(GtkCellRendererText * cell, + const gchar * path_string, + const gchar * new_text, gpointer user_data) +{ + GtkTreePath *path = gtk_tree_path_new_from_string(path_string); + GtkTreeIter iter; + const char *old_def, *new_def; + struct menu *menu; + struct symbol *sym; + + if (!gtk_tree_model_get_iter(model2, &iter, path)) + return; + + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + sym = menu->sym; + + gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1); + new_def = new_text; + + sym_set_string_value(sym, new_def); + + config_changed = TRUE; + update_tree(&rootmenu, NULL); + + gtk_tree_path_free(path); +} + +/* Change the value of a symbol and update the tree */ +static void change_sym_value(struct menu *menu, gint col) +{ + struct symbol *sym = menu->sym; + tristate oldval, newval; + + if (!sym) + return; + + if (col == COL_NO) + newval = no; + else if (col == COL_MOD) + newval = mod; + else if (col == COL_YES) + newval = yes; + else + return; + + switch (sym_get_type(sym)) { + case S_BOOLEAN: + case S_TRISTATE: + oldval = sym_get_tristate_value(sym); + if (!sym_tristate_within_range(sym, newval)) + newval = yes; + sym_set_tristate_value(sym, newval); + config_changed = TRUE; + if (view_mode == FULL_VIEW) + update_tree(&rootmenu, NULL); + else if (view_mode == SPLIT_VIEW) { + update_tree(browsed, NULL); + display_list(); + } + else if (view_mode == SINGLE_VIEW) + display_tree_part(); //fixme: keep exp/coll + break; + case S_INT: + case S_HEX: + case S_STRING: + default: + break; + } +} + +static void toggle_sym_value(struct menu *menu) +{ + if (!menu->sym) + return; + + sym_toggle_tristate_value(menu->sym); + if (view_mode == FULL_VIEW) + update_tree(&rootmenu, NULL); + else if (view_mode == SPLIT_VIEW) { + update_tree(browsed, NULL); + display_list(); + } + else if (view_mode == SINGLE_VIEW) + display_tree_part(); //fixme: keep exp/coll +} + +static void renderer_toggled(GtkCellRendererToggle * cell, + gchar * path_string, gpointer user_data) +{ + GtkTreePath *path, *sel_path = NULL; + GtkTreeIter iter, sel_iter; + GtkTreeSelection *sel; + struct menu *menu; + + path = gtk_tree_path_new_from_string(path_string); + if (!gtk_tree_model_get_iter(model2, &iter, path)) + return; + + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree2_w)); + if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter)) + sel_path = gtk_tree_model_get_path(model2, &sel_iter); + if (!sel_path) + goto out1; + if (gtk_tree_path_compare(path, sel_path)) + goto out2; + + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + toggle_sym_value(menu); + + out2: + gtk_tree_path_free(sel_path); + out1: + gtk_tree_path_free(path); +} + +static gint column2index(GtkTreeViewColumn * column) +{ + gint i; + + for (i = 0; i < COL_NUMBER; i++) { + GtkTreeViewColumn *col; + + col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i); + if (col == column) + return i; + } + + return -1; +} + + +/* User click: update choice (full) or goes down (single) */ +gboolean +on_treeview2_button_press_event(GtkWidget * widget, + GdkEventButton * event, gpointer user_data) +{ + GtkTreeView *view = GTK_TREE_VIEW(widget); + GtkTreePath *path; + GtkTreeViewColumn *column; + GtkTreeIter iter; + struct menu *menu; + gint col; + +#if GTK_CHECK_VERSION(2,1,4) // bug in ctree with earlier version of GTK + gint tx = (gint) event->x; + gint ty = (gint) event->y; + gint cx, cy; + + gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx, + &cy); +#else + gtk_tree_view_get_cursor(view, &path, &column); +#endif + if (path == NULL) + return FALSE; + + if (!gtk_tree_model_get_iter(model2, &iter, path)) + return FALSE; + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + + col = column2index(column); + if (event->type == GDK_2BUTTON_PRESS) { + enum prop_type ptype; + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + + if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) { + // goes down into menu + current = menu; + display_tree_part(); + gtk_widget_set_sensitive(back_btn, TRUE); + } else if ((col == COL_OPTION)) { + toggle_sym_value(menu); + gtk_tree_view_expand_row(view, path, TRUE); + } + } else { + if (col == COL_VALUE) { + toggle_sym_value(menu); + gtk_tree_view_expand_row(view, path, TRUE); + } else if (col == COL_NO || col == COL_MOD + || col == COL_YES) { + change_sym_value(menu, col); + gtk_tree_view_expand_row(view, path, TRUE); + } + } + + return FALSE; +} + +/* Key pressed: update choice */ +gboolean +on_treeview2_key_press_event(GtkWidget * widget, + GdkEventKey * event, gpointer user_data) +{ + GtkTreeView *view = GTK_TREE_VIEW(widget); + GtkTreePath *path; + GtkTreeViewColumn *column; + GtkTreeIter iter; + struct menu *menu; + gint col; + + gtk_tree_view_get_cursor(view, &path, &column); + if (path == NULL) + return FALSE; + + if (event->keyval == GDK_space) { + if (gtk_tree_view_row_expanded(view, path)) + gtk_tree_view_collapse_row(view, path); + else + gtk_tree_view_expand_row(view, path, FALSE); + return TRUE; + } + if (event->keyval == GDK_KP_Enter) { + } + if (widget == tree1_w) + return FALSE; + + gtk_tree_model_get_iter(model2, &iter, path); + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + + if (!strcasecmp(event->string, "n")) + col = COL_NO; + else if (!strcasecmp(event->string, "m")) + col = COL_MOD; + else if (!strcasecmp(event->string, "y")) + col = COL_YES; + else + col = -1; + change_sym_value(menu, col); + + return FALSE; +} + + +/* Row selection changed: update help */ +void +on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data) +{ + GtkTreeSelection *selection; + GtkTreeIter iter; + struct menu *menu; + + selection = gtk_tree_view_get_selection(treeview); + if (gtk_tree_selection_get_selected(selection, &model2, &iter)) { + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + text_insert_help(menu); + } +} + + +/* User click: display sub-tree in the right frame. */ +gboolean +on_treeview1_button_press_event(GtkWidget * widget, + GdkEventButton * event, gpointer user_data) +{ + GtkTreeView *view = GTK_TREE_VIEW(widget); + GtkTreePath *path; + GtkTreeViewColumn *column; + GtkTreeIter iter; + struct menu *menu; + + gint tx = (gint) event->x; + gint ty = (gint) event->y; + gint cx, cy; + + gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx, + &cy); + if (path == NULL) + return FALSE; + + gtk_tree_model_get_iter(model1, &iter, path); + gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1); + + if (event->type == GDK_2BUTTON_PRESS) { + toggle_sym_value(menu); + current = menu; + display_tree_part(); + } else { + browsed = menu; + display_tree_part(); + } + + gtk_widget_realize(tree2_w); + gtk_tree_view_set_cursor(view, path, NULL, FALSE); + gtk_widget_grab_focus(tree2_w); + + return FALSE; +} + + +/* Fill a row of strings */ +static gchar **fill_row(struct menu *menu) +{ + static gchar *row[COL_NUMBER]; + struct symbol *sym = menu->sym; + const char *def; + int stype; + tristate val; + enum prop_type ptype; + int i; + + for (i = COL_OPTION; i <= COL_COLOR; i++) + g_free(row[i]); + bzero(row, sizeof(row)); + + row[COL_OPTION] = + g_strdup_printf("%s %s", menu_get_prompt(menu), + sym ? (sym-> + flags & SYMBOL_NEW ? "(NEW)" : "") : + ""); + + if (show_all && !menu_is_visible(menu)) + row[COL_COLOR] = g_strdup("DarkGray"); + else + row[COL_COLOR] = g_strdup("Black"); + + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + switch (ptype) { + case P_MENU: + row[COL_PIXBUF] = (gchar *) xpm_menu; + if (view_mode == SINGLE_VIEW) + row[COL_PIXVIS] = GINT_TO_POINTER(TRUE); + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + break; + case P_COMMENT: + row[COL_PIXBUF] = (gchar *) xpm_void; + row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + break; + default: + row[COL_PIXBUF] = (gchar *) xpm_void; + row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); + row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); + break; + } + + if (!sym) + return row; + row[COL_NAME] = g_strdup(sym->name); + + sym_calc_value(sym); + sym->flags &= ~SYMBOL_CHANGED; + + if (sym_is_choice(sym)) { // parse childs for getting final value + struct menu *child; + struct symbol *def_sym = sym_get_choice_value(sym); + struct menu *def_menu = NULL; + + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child) + && child->sym == def_sym) + def_menu = child; + } + + if (def_menu) + row[COL_VALUE] = + g_strdup(menu_get_prompt(def_menu)); + } + if (sym->flags & SYMBOL_CHOICEVAL) + row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); + + stype = sym_get_type(sym); + switch (stype) { + case S_BOOLEAN: + if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE) + row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); + if (sym_is_choice(sym)) + break; + case S_TRISTATE: + val = sym_get_tristate_value(sym); + switch (val) { + case no: + row[COL_NO] = g_strdup("N"); + row[COL_VALUE] = g_strdup("N"); + row[COL_BTNACT] = GINT_TO_POINTER(FALSE); + row[COL_BTNINC] = GINT_TO_POINTER(FALSE); + break; + case mod: + row[COL_MOD] = g_strdup("M"); + row[COL_VALUE] = g_strdup("M"); + row[COL_BTNINC] = GINT_TO_POINTER(TRUE); + break; + case yes: + row[COL_YES] = g_strdup("Y"); + row[COL_VALUE] = g_strdup("Y"); + row[COL_BTNACT] = GINT_TO_POINTER(TRUE); + row[COL_BTNINC] = GINT_TO_POINTER(FALSE); + break; + } + + if (val != no && sym_tristate_within_range(sym, no)) + row[COL_NO] = g_strdup("_"); + if (val != mod && sym_tristate_within_range(sym, mod)) + row[COL_MOD] = g_strdup("_"); + if (val != yes && sym_tristate_within_range(sym, yes)) + row[COL_YES] = g_strdup("_"); + break; + case S_INT: + case S_HEX: + case S_STRING: + def = sym_get_string_value(sym); + row[COL_VALUE] = g_strdup(def); + row[COL_EDIT] = GINT_TO_POINTER(TRUE); + row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); + break; + } + + return row; +} + + +/* Set the node content with a row of strings */ +static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row) +{ + GdkColor color; + gboolean success; + GdkPixbuf *pix; + + pix = gdk_pixbuf_new_from_xpm_data((const char **) + row[COL_PIXBUF]); + + gdk_color_parse(row[COL_COLOR], &color); + gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1, + FALSE, FALSE, &success); + + gtk_tree_store_set(tree, node, + COL_OPTION, row[COL_OPTION], + COL_NAME, row[COL_NAME], + COL_NO, row[COL_NO], + COL_MOD, row[COL_MOD], + COL_YES, row[COL_YES], + COL_VALUE, row[COL_VALUE], + COL_MENU, (gpointer) menu, + COL_COLOR, &color, + COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]), + COL_PIXBUF, pix, + COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]), + COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]), + COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]), + COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]), + COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]), + -1); + + g_object_unref(pix); +} + + +/* Add a node to the tree */ +static void place_node(struct menu *menu, char **row) +{ + GtkTreeIter *parent = parents[indent - 1]; + GtkTreeIter *node = parents[indent]; + + gtk_tree_store_append(tree, node, parent); + set_node(node, menu, row); +} + + +/* Find a node in the GTK+ tree */ +static GtkTreeIter found; + +/* + * Find a menu in the GtkTree starting at parent. + */ +GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent, + struct menu *tofind) +{ + GtkTreeIter iter; + GtkTreeIter *child = &iter; + gboolean valid; + GtkTreeIter *ret; + + valid = gtk_tree_model_iter_children(model2, child, parent); + while (valid) { + struct menu *menu; + + gtk_tree_model_get(model2, child, 6, &menu, -1); + + if (menu == tofind) { + memcpy(&found, child, sizeof(GtkTreeIter)); + return &found; + } + + ret = gtktree_iter_find_node(child, tofind); + if (ret) + return ret; + + valid = gtk_tree_model_iter_next(model2, child); + } + + return NULL; +} + + +/* + * Update the tree by adding/removing entries + * Does not change other nodes + */ +static void update_tree(struct menu *src, GtkTreeIter * dst) +{ + struct menu *child1; + GtkTreeIter iter, tmp; + GtkTreeIter *child2 = &iter; + gboolean valid; + GtkTreeIter *sibling; + struct symbol *sym; + struct property *prop; + struct menu *menu1, *menu2; + + if (src == &rootmenu) + indent = 1; + + valid = gtk_tree_model_iter_children(model2, child2, dst); + for (child1 = src->list; child1; child1 = child1->next) { + + prop = child1->prompt; + sym = child1->sym; + + reparse: + menu1 = child1; + if (valid) + gtk_tree_model_get(model2, child2, COL_MENU, + &menu2, -1); + else + menu2 = NULL; // force adding of a first child + +#ifdef DEBUG + printf("%*c%s | %s\n", indent, ' ', + menu1 ? menu_get_prompt(menu1) : "nil", + menu2 ? menu_get_prompt(menu2) : "nil"); +#endif + + if (!menu_is_visible(child1) && !show_all) { // remove node + if (gtktree_iter_find_node(dst, menu1) != NULL) { + memcpy(&tmp, child2, sizeof(GtkTreeIter)); + valid = gtk_tree_model_iter_next(model2, + child2); + gtk_tree_store_remove(tree2, &tmp); + if (!valid) + return; // next parent + else + goto reparse; // next child + } else + continue; + } + + if (menu1 != menu2) { + if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node + if (!valid && !menu2) + sibling = NULL; + else + sibling = child2; + gtk_tree_store_insert_before(tree2, + child2, + dst, sibling); + set_node(child2, menu1, fill_row(menu1)); + if (menu2 == NULL) + valid = TRUE; + } else { // remove node + memcpy(&tmp, child2, sizeof(GtkTreeIter)); + valid = gtk_tree_model_iter_next(model2, + child2); + gtk_tree_store_remove(tree2, &tmp); + if (!valid) + return; // next parent + else + goto reparse; // next child + } + } else if (sym && (sym->flags & SYMBOL_CHANGED)) { + set_node(child2, menu1, fill_row(menu1)); + } + + indent++; + update_tree(child1, child2); + indent--; + + valid = gtk_tree_model_iter_next(model2, child2); + } +} + + +/* Display the whole tree (single/split/full view) */ +static void display_tree(struct menu *menu) +{ + struct symbol *sym; + struct property *prop; + struct menu *child; + enum prop_type ptype; + + if (menu == &rootmenu) { + indent = 1; + current = &rootmenu; + } + + for (child = menu->list; child; child = child->next) { + prop = child->prompt; + sym = child->sym; + ptype = prop ? prop->type : P_UNKNOWN; + + if (sym) + sym->flags &= ~SYMBOL_CHANGED; + + if ((view_mode == SPLIT_VIEW) + && !(child->flags & MENU_ROOT) && (tree == tree1)) + continue; + + if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) + && (tree == tree2)) + continue; + + if (menu_is_visible(child) || show_all) + place_node(child, fill_row(child)); +#ifdef DEBUG + printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); + printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); + dbg_print_ptype(ptype); + printf(" | "); + if (sym) { + dbg_print_stype(sym->type); + printf(" | "); + dbg_print_flags(sym->flags); + printf("\n"); + } else + printf("\n"); +#endif + if ((view_mode != FULL_VIEW) && (ptype == P_MENU) + && (tree == tree2)) + continue; +/* + if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) + || (view_mode == FULL_VIEW) + || (view_mode == SPLIT_VIEW))*/ + if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT)) + || (view_mode == FULL_VIEW) + || (view_mode == SPLIT_VIEW)) { + indent++; + display_tree(child); + indent--; + } + } +} + +/* Display a part of the tree starting at current node (single/split view) */ +static void display_tree_part(void) +{ + if (tree2) + gtk_tree_store_clear(tree2); + if (view_mode == SINGLE_VIEW) + display_tree(current); + else if (view_mode == SPLIT_VIEW) + display_tree(browsed); + gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); +} + +/* Display the list in the left frame (split view) */ +static void display_list(void) +{ + if (tree1) + gtk_tree_store_clear(tree1); + + tree = tree1; + display_tree(&rootmenu); + gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w)); + tree = tree2; +} + +void fixup_rootmenu(struct menu *menu) +{ + struct menu *child; + static int menu_cnt = 0; + + menu->flags |= MENU_ROOT; + for (child = menu->list; child; child = child->next) { + if (child->prompt && child->prompt->type == P_MENU) { + menu_cnt++; + fixup_rootmenu(child); + menu_cnt--; + } else if (!menu_cnt) + fixup_rootmenu(child); + } +} + + +/* Main */ +int main(int ac, char *av[]) +{ + const char *name; + char *env; + gchar *glade_file; + +#ifndef LKC_DIRECT_LINK + kconfig_load(); +#endif + + bindtextdomain(PACKAGE, LOCALEDIR); + bind_textdomain_codeset(PACKAGE, "UTF-8"); + textdomain(PACKAGE); + + /* GTK stuffs */ + gtk_set_locale(); + gtk_init(&ac, &av); + glade_init(); + + //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps"); + //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps"); + + /* Determine GUI path */ + env = getenv(SRCTREE); + if (env) + glade_file = g_strconcat(env, "/scripts/kconfig/gconf.glade", NULL); + else if (av[0][0] == '/') + glade_file = g_strconcat(av[0], ".glade", NULL); + else + glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL); + + /* Load the interface and connect signals */ + init_main_window(glade_file); + init_tree_model(); + init_left_tree(); + init_right_tree(); + + /* Conf stuffs */ + if (ac > 1 && av[1][0] == '-') { + switch (av[1][1]) { + case 'a': + //showAll = 1; + break; + case 'h': + case '?': + printf("%s \n", av[0]); + exit(0); + } + name = av[2]; + } else + name = av[1]; + + conf_parse(name); + fixup_rootmenu(&rootmenu); + conf_read(NULL); + + switch (view_mode) { + case SINGLE_VIEW: + display_tree_part(); + break; + case SPLIT_VIEW: + display_list(); + break; + case FULL_VIEW: + display_tree(&rootmenu); + break; + } + + gtk_main(); + + return 0; +} diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade new file mode 100644 index 000000000..f8744ed64 --- /dev/null +++ b/scripts/kconfig/gconf.glade @@ -0,0 +1,648 @@ + + + + + + + True + Gtk Kernel Configurator + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + 640 + 480 + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + + + + + + + True + False + 0 + + + + True + + + + True + _File + True + + + + + + + True + Load a config file + _Load + True + + + + + + True + gtk-open + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + Save the config in .config + _Save + True + + + + + + True + gtk-save + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + Save the config in a file + Save _as + True + + + + + True + gtk-save-as + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + + + + + + True + _Quit + True + + + + + + True + gtk-quit + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + + + + + True + _Options + True + + + + + + + True + Show name + Show _name + True + False + + + + + + + True + Show range (Y/M/N) + Show _range + True + False + + + + + + + True + Show value of the option + Show _data + True + False + + + + + + + True + + + + + + True + Show all options + Show all _options + True + False + + + + + + + True + Show masked options + Show _debug info + True + False + + + + + + + + + + + True + _Help + True + + + + + + + True + _Introduction + True + + + + + + True + gtk-dialog-question + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + _About + True + + + + + + True + gtk-properties + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + True + _License + True + + + + + True + gtk-justify-fill + 1 + 0.5 + 0.5 + 0 + 0 + + + + + + + + + + + 0 + False + False + + + + + + True + GTK_SHADOW_OUT + GTK_POS_LEFT + GTK_POS_TOP + + + + True + GTK_ORIENTATION_HORIZONTAL + GTK_TOOLBAR_BOTH + True + True + + + + True + Goes up of one level (single view) + Back + True + gtk-undo + True + True + False + + + + False + True + + + + + + True + True + True + False + + + + True + + + + + False + False + + + + + + True + Load a config file + Load + True + gtk-open + True + True + False + + + + False + True + + + + + + True + Save a config file + Save + True + gtk-save + True + True + False + + + + False + True + + + + + + True + True + True + False + + + + True + + + + + False + False + + + + + + True + Single view + Single + True + gtk-missing-image + True + True + False + + + + False + True + + + + + + True + Split view + Split + True + gtk-missing-image + True + True + False + + + + False + True + + + + + + True + Full view + Full + True + gtk-missing-image + True + True + False + + + + False + True + + + + + + True + True + True + False + + + + True + + + + + False + False + + + + + + True + Collapse the whole tree in the right frame + Collapse + True + gtk-remove + True + True + False + + + + False + True + + + + + + True + Expand the whole tree in the right frame + Expand + True + gtk-add + True + True + False + + + + False + True + + + + + + + 0 + False + False + + + + + + 1 + True + True + 0 + + + + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + True + False + False + True + + + + + + + + True + False + + + + + + True + True + 0 + + + + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + True + True + False + False + True + + + + + + + + True + False + + + + + + True + GTK_POLICY_NEVER + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + False + False + True + GTK_JUSTIFY_LEFT + GTK_WRAP_WORD + True + 0 + 0 + 0 + 0 + 0 + 0 + Sorry, no help available for this option yet. + + + + + True + True + + + + + True + True + + + + + 0 + True + True + + + + + + + diff --git a/scripts/kconfig/images.c b/scripts/kconfig/images.c new file mode 100644 index 000000000..d4f84bd4a --- /dev/null +++ b/scripts/kconfig/images.c @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +static const char *xpm_load[] = { +"22 22 5 1", +". c None", +"# c #000000", +"c c #838100", +"a c #ffff00", +"b c #ffffff", +"......................", +"......................", +"......................", +"............####....#.", +"...........#....##.##.", +"..................###.", +".................####.", +".####...........#####.", +"#abab##########.......", +"#babababababab#.......", +"#ababababababa#.......", +"#babababababab#.......", +"#ababab###############", +"#babab##cccccccccccc##", +"#abab##cccccccccccc##.", +"#bab##cccccccccccc##..", +"#ab##cccccccccccc##...", +"#b##cccccccccccc##....", +"###cccccccccccc##.....", +"##cccccccccccc##......", +"###############.......", +"......................"}; + +static const char *xpm_save[] = { +"22 22 5 1", +". c None", +"# c #000000", +"a c #838100", +"b c #c5c2c5", +"c c #cdb6d5", +"......................", +".####################.", +".#aa#bbbbbbbbbbbb#bb#.", +".#aa#bbbbbbbbbbbb#bb#.", +".#aa#bbbbbbbbbcbb####.", +".#aa#bbbccbbbbbbb#aa#.", +".#aa#bbbccbbbbbbb#aa#.", +".#aa#bbbbbbbbbbbb#aa#.", +".#aa#bbbbbbbbbbbb#aa#.", +".#aa#bbbbbbbbbbbb#aa#.", +".#aa#bbbbbbbbbbbb#aa#.", +".#aaa############aaa#.", +".#aaaaaaaaaaaaaaaaaa#.", +".#aaaaaaaaaaaaaaaaaa#.", +".#aaa#############aa#.", +".#aaa#########bbb#aa#.", +".#aaa#########bbb#aa#.", +".#aaa#########bbb#aa#.", +".#aaa#########bbb#aa#.", +".#aaa#########bbb#aa#.", +"..##################..", +"......................"}; + +static const char *xpm_back[] = { +"22 22 3 1", +". c None", +"# c #000083", +"a c #838183", +"......................", +"......................", +"......................", +"......................", +"......................", +"...........######a....", +"..#......##########...", +"..##...####......##a..", +"..###.###.........##..", +"..######..........##..", +"..#####...........##..", +"..######..........##..", +"..#######.........##..", +"..########.......##a..", +"...............a###...", +"...............###....", +"......................", +"......................", +"......................", +"......................", +"......................", +"......................"}; + +static const char *xpm_tree_view[] = { +"22 22 2 1", +". c None", +"# c #000000", +"......................", +"......................", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......########........", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......########........", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......#...............", +"......########........", +"......................", +"......................"}; + +static const char *xpm_single_view[] = { +"22 22 2 1", +". c None", +"# c #000000", +"......................", +"......................", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"..........#...........", +"......................", +"......................"}; + +static const char *xpm_split_view[] = { +"22 22 2 1", +". c None", +"# c #000000", +"......................", +"......................", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......#......#........", +"......................", +"......................"}; + +static const char *xpm_symbol_no[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" .......... ", +" "}; + +static const char *xpm_symbol_mod[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . . ", +" . .. . ", +" . .... . ", +" . .... . ", +" . .. . ", +" . . ", +" . . ", +" .......... ", +" "}; + +static const char *xpm_symbol_yes[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . . ", +" . . . ", +" . .. . ", +" . . .. . ", +" . .... . ", +" . .. . ", +" . . ", +" .......... ", +" "}; + +static const char *xpm_choice_no[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .... ", +" .. .. ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" .. .. ", +" .... ", +" "}; + +static const char *xpm_choice_yes[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .... ", +" .. .. ", +" . . ", +" . .. . ", +" . .... . ", +" . .... . ", +" . .. . ", +" . . ", +" .. .. ", +" .... ", +" "}; + +static const char *xpm_menu[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . .. . ", +" . .... . ", +" . ...... . ", +" . ...... . ", +" . .... . ", +" . .. . ", +" . . ", +" .......... ", +" "}; + +static const char *xpm_menu_inv[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" .......... ", +" .. ...... ", +" .. .... ", +" .. .. ", +" .. .. ", +" .. .... ", +" .. ...... ", +" .......... ", +" .......... ", +" "}; + +static const char *xpm_menuback[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" .......... ", +" . . ", +" . .. . ", +" . .... . ", +" . ...... . ", +" . ...... . ", +" . .... . ", +" . .. . ", +" . . ", +" .......... ", +" "}; + +static const char *xpm_void[] = { +"12 12 2 1", +" c white", +". c black", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/scripts/kconfig/kconfig_load.c b/scripts/kconfig/kconfig_load.c new file mode 100644 index 000000000..dbdcaad82 --- /dev/null +++ b/scripts/kconfig/kconfig_load.c @@ -0,0 +1,35 @@ +#include +#include +#include + +#include "lkc.h" + +#define P(name,type,arg) type (*name ## _p) arg +#include "lkc_proto.h" +#undef P + +void kconfig_load(void) +{ + void *handle; + char *error; + + handle = dlopen("./libkconfig.so", RTLD_LAZY); + if (!handle) { + handle = dlopen("./scripts/kconfig/libkconfig.so", RTLD_LAZY); + if (!handle) { + fprintf(stderr, "%s\n", dlerror()); + exit(1); + } + } + +#define P(name,type,arg) \ +{ \ + name ## _p = dlsym(handle, #name); \ + if ((error = dlerror())) { \ + fprintf(stderr, "%s\n", error); \ + exit(1); \ + } \ +} +#include "lkc_proto.h" +#undef P +} diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c new file mode 100644 index 000000000..abee55ca6 --- /dev/null +++ b/scripts/kconfig/kxgettext.c @@ -0,0 +1,227 @@ +/* + * Arnaldo Carvalho de Melo , 2005 + * + * Released under the terms of the GNU GPL v2.0 + */ + +#include +#include + +#define LKC_DIRECT_LINK +#include "lkc.h" + +static char *escape(const char* text, char *bf, int len) +{ + char *bfp = bf; + int multiline = strchr(text, '\n') != NULL; + int eol = 0; + int textlen = strlen(text); + + if ((textlen > 0) && (text[textlen-1] == '\n')) + eol = 1; + + *bfp++ = '"'; + --len; + + if (multiline) { + *bfp++ = '"'; + *bfp++ = '\n'; + *bfp++ = '"'; + len -= 3; + } + + while (*text != '\0' && len > 1) { + if (*text == '"') + *bfp++ = '\\'; + else if (*text == '\n') { + *bfp++ = '\\'; + *bfp++ = 'n'; + *bfp++ = '"'; + *bfp++ = '\n'; + *bfp++ = '"'; + len -= 5; + ++text; + goto next; + } + *bfp++ = *text++; +next: + --len; + } + + if (multiline && eol) + bfp -= 3; + + *bfp++ = '"'; + *bfp = '\0'; + + return bf; +} + +struct file_line { + struct file_line *next; + char* file; + int lineno; +}; + +static struct file_line *file_line__new(char *file, int lineno) +{ + struct file_line *self = malloc(sizeof(*self)); + + if (self == NULL) + goto out; + + self->file = file; + self->lineno = lineno; + self->next = NULL; +out: + return self; +} + +struct message { + const char *msg; + const char *option; + struct message *next; + struct file_line *files; +}; + +static struct message *message__list; + +static struct message *message__new(const char *msg, char *option, char *file, int lineno) +{ + struct message *self = malloc(sizeof(*self)); + + if (self == NULL) + goto out; + + self->files = file_line__new(file, lineno); + if (self->files == NULL) + goto out_fail; + + self->msg = strdup(msg); + if (self->msg == NULL) + goto out_fail_msg; + + self->option = option; + self->next = NULL; +out: + return self; +out_fail_msg: + free(self->files); +out_fail: + free(self); + self = NULL; + goto out; +} + +static struct message *mesage__find(const char *msg) +{ + struct message *m = message__list; + + while (m != NULL) { + if (strcmp(m->msg, msg) == 0) + break; + m = m->next; + } + + return m; +} + +static int message__add_file_line(struct message *self, char *file, int lineno) +{ + int rc = -1; + struct file_line *fl = file_line__new(file, lineno); + + if (fl == NULL) + goto out; + + fl->next = self->files; + self->files = fl; + rc = 0; +out: + return rc; +} + +static int message__add(const char *msg, char *option, char *file, int lineno) +{ + int rc = 0; + char bf[16384]; + char *escaped = escape(msg, bf, sizeof(bf)); + struct message *m = mesage__find(escaped); + + if (m != NULL) + rc = message__add_file_line(m, file, lineno); + else { + m = message__new(escaped, option, file, lineno); + + if (m != NULL) { + m->next = message__list; + message__list = m; + } else + rc = -1; + } + return rc; +} + +void menu_build_message_list(struct menu *menu) +{ + struct menu *child; + + message__add(menu_get_prompt(menu), NULL, + menu->file == NULL ? "Root Menu" : menu->file->name, + menu->lineno); + + if (menu->sym != NULL && menu->sym->help != NULL) + message__add(menu->sym->help, menu->sym->name, + menu->file == NULL ? "Root Menu" : menu->file->name, + menu->lineno); + + for (child = menu->list; child != NULL; child = child->next) + if (child->prompt != NULL) + menu_build_message_list(child); +} + +static void message__print_file_lineno(struct message *self) +{ + struct file_line *fl = self->files; + + putchar('\n'); + if (self->option != NULL) + printf("# %s:00000\n", self->option); + + printf("#: %s:%d", fl->file, fl->lineno); + fl = fl->next; + + while (fl != NULL) { + printf(", %s:%d", fl->file, fl->lineno); + fl = fl->next; + } + + putchar('\n'); +} + +static void message__print_gettext_msgid_msgstr(struct message *self) +{ + message__print_file_lineno(self); + + printf("msgid %s\n" + "msgstr \"\"\n", self->msg); +} + +void menu__xgettext(void) +{ + struct message *m = message__list; + + while (m != NULL) { + message__print_gettext_msgid_msgstr(m); + m = m->next; + } +} + +int main(int ac, char **av) +{ + conf_parse(av[1]); + + menu_build_message_list(menu_get_root_menu(NULL)); + menu__xgettext(); + return 0; +} diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped new file mode 100644 index 000000000..24e3c8cbb --- /dev/null +++ b/scripts/kconfig/lex.zconf.c_shipped @@ -0,0 +1,2317 @@ + +#line 3 "scripts/kconfig/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 31 +#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 +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +#include +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 + +#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 = 1; /* 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 + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include +#include + +#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 +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* 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 + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#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) = 0; + +#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 + { + size_t 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; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + zconfrestart(zconfin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( zconfwrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve zconftext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** 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 yy_str 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 * yy_str ) +{ + + return zconf_scan_bytes(yy_str,strlen(yy_str) ); +} + +/** 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 * bytes, int 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 = len + 2; + buf = (char *) zconfalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[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 ; +} + +/* 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; + + 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" + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef yytext_ptr +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +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[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 : ""; +} + diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h new file mode 100644 index 000000000..527f60c99 --- /dev/null +++ b/scripts/kconfig/lkc.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2002 Roman Zippel + * Released under the terms of the GNU GPL v2.0. + */ + +#ifndef LKC_H +#define LKC_H + +#include "expr.h" + +#ifndef KBUILD_NO_NLS +# include +#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 + +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 */ +extern const char conf_def_filename[]; + +char *conf_get_default_confname(void); + +/* 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_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_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_NEW ? false : true; +} + +#ifdef __cplusplus +} +#endif + +#endif /* LKC_H */ diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h new file mode 100644 index 000000000..b6a389c5f --- /dev/null +++ b/scripts/kconfig/lkc_proto.h @@ -0,0 +1,41 @@ + +/* confdata.c */ +P(conf_parse,void,(const char *name)); +P(conf_read,int,(const char *name)); +P(conf_read_simple,int,(const char *name)); +P(conf_write,int,(const char *name)); + +/* 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)); + +/* symbol.c */ +P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]); +P(sym_change_count,int,); + +P(sym_lookup,struct symbol *,(const char *name, int isconst)); +P(sym_find,struct symbol *,(const char *name)); +P(sym_re_search,struct symbol **,(const char *pattern)); +P(sym_type_name,const char *,(enum symbol_type type)); +P(sym_calc_value,void,(struct symbol *sym)); +P(sym_get_type,enum symbol_type,(struct symbol *sym)); +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 *, const char *), void *data, int prevtoken)); diff --git a/scripts/kconfig/lxdialog/BIG.FAT.WARNING b/scripts/kconfig/lxdialog/BIG.FAT.WARNING new file mode 100644 index 000000000..a8999d82b --- /dev/null +++ b/scripts/kconfig/lxdialog/BIG.FAT.WARNING @@ -0,0 +1,4 @@ +This is NOT the official version of dialog. This version has been +significantly modified from the original. It is for use by the Linux +kernel configuration script. Please do not bother Savio Lam with +questions about this program. diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile new file mode 100644 index 000000000..a8b026326 --- /dev/null +++ b/scripts/kconfig/lxdialog/Makefile @@ -0,0 +1,21 @@ +# Makefile to build lxdialog package +# + +check-lxdialog := $(srctree)/$(src)/check-lxdialog.sh + +# Use reursively expanded variables so we do not call gcc unless +# we really need to do so. (Do not call gcc as part of make mrproper) +HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) +HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) + +HOST_EXTRACFLAGS += -DLOCALE + +PHONY += dochecklxdialog +$(obj)/dochecklxdialog: + $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_LOADLIBES) + +hostprogs-y := lxdialog +always := $(hostprogs-y) dochecklxdialog + +lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \ + util.o lxdialog.o msgbox.o diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh new file mode 100644 index 000000000..120d624e6 --- /dev/null +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# Check ncurses compatibility + +# What library to link +ldflags() +{ + $cc -print-file-name=libncursesw.so | grep -q / + if [ $? -eq 0 ]; then + echo '-lncursesw' + exit + fi + $cc -print-file-name=libncurses.so | grep -q / + if [ $? -eq 0 ]; then + echo '-lncurses' + exit + fi + $cc -print-file-name=libcurses.so | grep -q / + if [ $? -eq 0 ]; then + echo '-lcurses' + exit + fi + exit 1 +} + +# Where is ncurses.h? +ccflags() +{ + if [ -f /usr/include/ncurses/ncurses.h ]; then + echo '-I/usr/include/ncurses -DCURSES_LOC=""' + elif [ -f /usr/include/ncurses/curses.h ]; then + echo '-I/usr/include/ncurses -DCURSES_LOC=""' + elif [ -f /usr/include/ncurses.h ]; then + echo '-DCURSES_LOC=""' + else + echo '-DCURSES_LOC=""' + fi +} + +# Temp file, try to clean up after us +tmp=.lxdialog.tmp +trap "rm -f $tmp" 0 1 2 3 15 + +# Check if we can link to ncurses +check() { + echo "main() {}" | $cc -xc - -o $tmp 2> /dev/null + if [ $? != 0 ]; then + echo " *** Unable to find the ncurses libraries." 1>&2 + echo " *** make menuconfig require the ncurses libraries" 1>&2 + echo " *** " 1>&2 + echo " *** Install ncurses (ncurses-devel) and try again" 1>&2 + echo " *** " 1>&2 + exit 1 + fi +} + +usage() { + printf "Usage: $0 [-check compiler options|-header|-library]\n" +} + +if [ $# == 0 ]; then + usage + exit 1 +fi + +cc="" +case "$1" in + "-check") + shift + cc="$@" + check + ;; + "-ccflags") + ccflags + ;; + "-ldflags") + shift + cc="$@" + ldflags + ;; + "*") + usage + exit 1 + ;; +esac diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c new file mode 100644 index 000000000..be0200e9c --- /dev/null +++ b/scripts/kconfig/lxdialog/checklist.c @@ -0,0 +1,333 @@ +/* + * checklist.c -- implements the checklist box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension + * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +static int list_width, check_x, item_x; + +/* + * Print list item + */ +static void print_item(WINDOW * win, const char *item, int status, int choice, + int selected) +{ + int i; + + /* Clear 'residue' of last item */ + wattrset(win, menubox_attr); + wmove(win, choice, 0); + for (i = 0; i < list_width; i++) + waddch(win, ' '); + + wmove(win, choice, check_x); + wattrset(win, selected ? check_selected_attr : check_attr); + wprintw(win, "(%c)", status ? 'X' : ' '); + + wattrset(win, selected ? tag_selected_attr : tag_attr); + mvwaddch(win, choice, item_x, item[0]); + wattrset(win, selected ? item_selected_attr : item_attr); + waddstr(win, (char *)item + 1); + if (selected) { + wmove(win, choice, check_x + 1); + wrefresh(win); + } +} + +/* + * Print the scroll indicators. + */ +static void print_arrows(WINDOW * win, int choice, int item_no, int scroll, + int y, int x, int height) +{ + wmove(win, y, x); + + if (scroll > 0) { + wattrset(win, uarrow_attr); + waddch(win, ACS_UARROW); + waddstr(win, "(-)"); + } else { + wattrset(win, menubox_attr); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + } + + y = y + height + 1; + wmove(win, y, x); + + if ((height < item_no) && (scroll + choice < item_no - 1)) { + wattrset(win, darrow_attr); + waddch(win, ACS_DARROW); + waddstr(win, "(+)"); + } else { + wattrset(win, menubox_border_attr); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + } +} + +/* + * Display the termination buttons + */ +static void print_buttons(WINDOW * dialog, int height, int width, int selected) +{ + int x = width / 2 - 11; + int y = height - 2; + + print_button(dialog, "Select", y, x, selected == 0); + print_button(dialog, " Help ", y, x + 14, selected == 1); + + wmove(dialog, y, x + 1 + 14 * selected); + wrefresh(dialog); +} + +/* + * Display a dialog box with a list of options that can be turned on or off + * in the style of radiolist (only one option turned on at a time). + */ +int dialog_checklist(const char *title, const char *prompt, int height, + int width, int list_height, int item_no, + const char *const *items) +{ + int i, x, y, box_x, box_y; + int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; + WINDOW *dialog, *list; + + /* Allocate space for storing item on/off status */ + if ((status = malloc(sizeof(int) * item_no)) == NULL) { + endwin(); + fprintf(stderr, + "\nCan't allocate memory in dialog_checklist().\n"); + exit(-1); + } + + /* Initializes status */ + for (i = 0; i < item_no; i++) { + status[i] = !strcasecmp(items[i * 3 + 2], "on"); + if ((!choice && status[i]) + || !strcasecmp(items[i * 3 + 2], "selected")) + choice = i + 1; + } + if (choice) + choice--; + + max_choice = MIN(list_height, item_no); + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + + dialog = newwin(height, width, y, x); + keypad(dialog, TRUE); + + draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset(dialog, border_attr); + mvwaddch(dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch(dialog, ACS_HLINE); + wattrset(dialog, dialog_attr); + waddch(dialog, ACS_RTEE); + + print_title(dialog, title, width); + + wattrset(dialog, dialog_attr); + print_autowrap(dialog, prompt, width - 2, 1, 3); + + list_width = width - 6; + box_y = height - list_height - 5; + box_x = (width - list_width) / 2 - 1; + + /* create new window for the list */ + list = subwin(dialog, list_height, list_width, y + box_y + 1, + x + box_x + 1); + + keypad(list, TRUE); + + /* draw a box around the list items */ + draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, + menubox_border_attr, menubox_attr); + + /* Find length of longest item in order to center checklist */ + check_x = 0; + for (i = 0; i < item_no; i++) + check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4); + + check_x = (list_width - check_x) / 2; + item_x = check_x + 4; + + if (choice >= list_height) { + scroll = choice - list_height + 1; + choice -= scroll; + } + + /* Print the list */ + for (i = 0; i < max_choice; i++) { + print_item(list, items[(scroll + i) * 3 + 1], + status[i + scroll], i, i == choice); + } + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + print_buttons(dialog, height, width, 0); + + wnoutrefresh(dialog); + wnoutrefresh(list); + doupdate(); + + while (key != ESC) { + key = wgetch(dialog); + + for (i = 0; i < max_choice; i++) + if (toupper(key) == + toupper(items[(scroll + i) * 3 + 1][0])) + break; + + if (i < max_choice || key == KEY_UP || key == KEY_DOWN || + key == '+' || key == '-') { + if (key == KEY_UP || key == '-') { + if (!choice) { + if (!scroll) + continue; + /* Scroll list down */ + if (list_height > 1) { + /* De-highlight current first item */ + print_item(list, items[scroll * 3 + 1], + status[scroll], 0, FALSE); + scrollok(list, TRUE); + wscrl(list, -1); + scrollok(list, FALSE); + } + scroll--; + print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE); + print_arrows(dialog, choice, item_no, + scroll, box_y, box_x + check_x + 5, list_height); + + wnoutrefresh(dialog); + wrefresh(list); + + continue; /* wait for another key press */ + } else + i = choice - 1; + } else if (key == KEY_DOWN || key == '+') { + if (choice == max_choice - 1) { + if (scroll + choice >= item_no - 1) + continue; + /* Scroll list up */ + if (list_height > 1) { + /* De-highlight current last item before scrolling up */ + print_item(list, items[(scroll + max_choice - 1) * 3 + 1], + status[scroll + max_choice - 1], + max_choice - 1, FALSE); + scrollok(list, TRUE); + wscrl(list, 1); + scrollok(list, FALSE); + } + scroll++; + print_item(list, items[(scroll + max_choice - 1) * 3 + 1], + status[scroll + max_choice - 1], max_choice - 1, TRUE); + + print_arrows(dialog, choice, item_no, + scroll, box_y, box_x + check_x + 5, list_height); + + wnoutrefresh(dialog); + wrefresh(list); + + continue; /* wait for another key press */ + } else + i = choice + 1; + } + if (i != choice) { + /* De-highlight current item */ + print_item(list, items[(scroll + choice) * 3 + 1], + status[scroll + choice], choice, FALSE); + /* Highlight new item */ + choice = i; + print_item(list, items[(scroll + choice) * 3 + 1], + status[scroll + choice], choice, TRUE); + wnoutrefresh(dialog); + wrefresh(list); + } + continue; /* wait for another key press */ + } + switch (key) { + case 'H': + case 'h': + case '?': + fprintf(stderr, "%s", items[(scroll + choice) * 3]); + delwin(dialog); + free(status); + return 1; + case TAB: + case KEY_LEFT: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 1 : (button > 1 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh(dialog); + break; + case 'S': + case 's': + case ' ': + case '\n': + if (!button) { + if (!status[scroll + choice]) { + for (i = 0; i < item_no; i++) + status[i] = 0; + status[scroll + choice] = 1; + for (i = 0; i < max_choice; i++) + print_item(list, items[(scroll + i) * 3 + 1], + status[scroll + i], i, i == choice); + } + wnoutrefresh(dialog); + wrefresh(list); + + for (i = 0; i < item_no; i++) + if (status[i]) + fprintf(stderr, "%s", items[i * 3]); + } else + fprintf(stderr, "%s", items[(scroll + choice) * 3]); + delwin(dialog); + free(status); + return button; + case 'X': + case 'x': + key = ESC; + case ESC: + break; + } + + /* Now, update everything... */ + doupdate(); + } + + delwin(dialog); + free(status); + return -1; /* ESC pressed */ +} diff --git a/scripts/kconfig/lxdialog/colors.h b/scripts/kconfig/lxdialog/colors.h new file mode 100644 index 000000000..db071df12 --- /dev/null +++ b/scripts/kconfig/lxdialog/colors.h @@ -0,0 +1,154 @@ +/* + * colors.h -- color attribute definitions + * + * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Default color definitions + * + * *_FG = foreground + * *_BG = background + * *_HL = highlight? + */ +#define SCREEN_FG COLOR_CYAN +#define SCREEN_BG COLOR_BLUE +#define SCREEN_HL TRUE + +#define SHADOW_FG COLOR_BLACK +#define SHADOW_BG COLOR_BLACK +#define SHADOW_HL TRUE + +#define DIALOG_FG COLOR_BLACK +#define DIALOG_BG COLOR_WHITE +#define DIALOG_HL FALSE + +#define TITLE_FG COLOR_YELLOW +#define TITLE_BG COLOR_WHITE +#define TITLE_HL TRUE + +#define BORDER_FG COLOR_WHITE +#define BORDER_BG COLOR_WHITE +#define BORDER_HL TRUE + +#define BUTTON_ACTIVE_FG COLOR_WHITE +#define BUTTON_ACTIVE_BG COLOR_BLUE +#define BUTTON_ACTIVE_HL TRUE + +#define BUTTON_INACTIVE_FG COLOR_BLACK +#define BUTTON_INACTIVE_BG COLOR_WHITE +#define BUTTON_INACTIVE_HL FALSE + +#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE +#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE +#define BUTTON_KEY_ACTIVE_HL TRUE + +#define BUTTON_KEY_INACTIVE_FG COLOR_RED +#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE +#define BUTTON_KEY_INACTIVE_HL FALSE + +#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW +#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE +#define BUTTON_LABEL_ACTIVE_HL TRUE + +#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK +#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE +#define BUTTON_LABEL_INACTIVE_HL TRUE + +#define INPUTBOX_FG COLOR_BLACK +#define INPUTBOX_BG COLOR_WHITE +#define INPUTBOX_HL FALSE + +#define INPUTBOX_BORDER_FG COLOR_BLACK +#define INPUTBOX_BORDER_BG COLOR_WHITE +#define INPUTBOX_BORDER_HL FALSE + +#define SEARCHBOX_FG COLOR_BLACK +#define SEARCHBOX_BG COLOR_WHITE +#define SEARCHBOX_HL FALSE + +#define SEARCHBOX_TITLE_FG COLOR_YELLOW +#define SEARCHBOX_TITLE_BG COLOR_WHITE +#define SEARCHBOX_TITLE_HL TRUE + +#define SEARCHBOX_BORDER_FG COLOR_WHITE +#define SEARCHBOX_BORDER_BG COLOR_WHITE +#define SEARCHBOX_BORDER_HL TRUE + +#define POSITION_INDICATOR_FG COLOR_YELLOW +#define POSITION_INDICATOR_BG COLOR_WHITE +#define POSITION_INDICATOR_HL TRUE + +#define MENUBOX_FG COLOR_BLACK +#define MENUBOX_BG COLOR_WHITE +#define MENUBOX_HL FALSE + +#define MENUBOX_BORDER_FG COLOR_WHITE +#define MENUBOX_BORDER_BG COLOR_WHITE +#define MENUBOX_BORDER_HL TRUE + +#define ITEM_FG COLOR_BLACK +#define ITEM_BG COLOR_WHITE +#define ITEM_HL FALSE + +#define ITEM_SELECTED_FG COLOR_WHITE +#define ITEM_SELECTED_BG COLOR_BLUE +#define ITEM_SELECTED_HL TRUE + +#define TAG_FG COLOR_YELLOW +#define TAG_BG COLOR_WHITE +#define TAG_HL TRUE + +#define TAG_SELECTED_FG COLOR_YELLOW +#define TAG_SELECTED_BG COLOR_BLUE +#define TAG_SELECTED_HL TRUE + +#define TAG_KEY_FG COLOR_YELLOW +#define TAG_KEY_BG COLOR_WHITE +#define TAG_KEY_HL TRUE + +#define TAG_KEY_SELECTED_FG COLOR_YELLOW +#define TAG_KEY_SELECTED_BG COLOR_BLUE +#define TAG_KEY_SELECTED_HL TRUE + +#define CHECK_FG COLOR_BLACK +#define CHECK_BG COLOR_WHITE +#define CHECK_HL FALSE + +#define CHECK_SELECTED_FG COLOR_WHITE +#define CHECK_SELECTED_BG COLOR_BLUE +#define CHECK_SELECTED_HL TRUE + +#define UARROW_FG COLOR_GREEN +#define UARROW_BG COLOR_WHITE +#define UARROW_HL TRUE + +#define DARROW_FG COLOR_GREEN +#define DARROW_BG COLOR_WHITE +#define DARROW_HL TRUE + +/* End of default color definitions */ + +#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y))) +#define COLOR_NAME_LEN 10 +#define COLOR_COUNT 8 + +/* + * Global variables + */ + +extern int color_table[][3]; diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h new file mode 100644 index 000000000..af3cf716e --- /dev/null +++ b/scripts/kconfig/lxdialog/dialog.h @@ -0,0 +1,177 @@ +/* + * dialog.h -- common declarations for all dialog modules + * + * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#ifdef __sun__ +#define CURS_MACROS +#endif +#include CURSES_LOC + +/* + * Colors in ncurses 1.9.9e do not work properly since foreground and + * background colors are OR'd rather than separately masked. This version + * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible + * with standard curses. The simplest fix (to make this work with standard + * curses) uses the wbkgdset() function, not used in the original hack. + * Turn it off if we're building with 1.9.9e, since it just confuses things. + */ +#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE) +#define OLD_NCURSES 1 +#undef wbkgdset +#define wbkgdset(w,p) /*nothing */ +#else +#define OLD_NCURSES 0 +#endif + +#define TR(params) _tracef params + +#define ESC 27 +#define TAB 9 +#define MAX_LEN 2048 +#define BUF_SIZE (10*1024) +#define MIN(x,y) (x < y ? x : y) +#define MAX(x,y) (x > y ? x : y) + +#ifndef ACS_ULCORNER +#define ACS_ULCORNER '+' +#endif +#ifndef ACS_LLCORNER +#define ACS_LLCORNER '+' +#endif +#ifndef ACS_URCORNER +#define ACS_URCORNER '+' +#endif +#ifndef ACS_LRCORNER +#define ACS_LRCORNER '+' +#endif +#ifndef ACS_HLINE +#define ACS_HLINE '-' +#endif +#ifndef ACS_VLINE +#define ACS_VLINE '|' +#endif +#ifndef ACS_LTEE +#define ACS_LTEE '+' +#endif +#ifndef ACS_RTEE +#define ACS_RTEE '+' +#endif +#ifndef ACS_UARROW +#define ACS_UARROW '^' +#endif +#ifndef ACS_DARROW +#define ACS_DARROW 'v' +#endif + +/* + * Attribute names + */ +#define screen_attr attributes[0] +#define shadow_attr attributes[1] +#define dialog_attr attributes[2] +#define title_attr attributes[3] +#define border_attr attributes[4] +#define button_active_attr attributes[5] +#define button_inactive_attr attributes[6] +#define button_key_active_attr attributes[7] +#define button_key_inactive_attr attributes[8] +#define button_label_active_attr attributes[9] +#define button_label_inactive_attr attributes[10] +#define inputbox_attr attributes[11] +#define inputbox_border_attr attributes[12] +#define searchbox_attr attributes[13] +#define searchbox_title_attr attributes[14] +#define searchbox_border_attr attributes[15] +#define position_indicator_attr attributes[16] +#define menubox_attr attributes[17] +#define menubox_border_attr attributes[18] +#define item_attr attributes[19] +#define item_selected_attr attributes[20] +#define tag_attr attributes[21] +#define tag_selected_attr attributes[22] +#define tag_key_attr attributes[23] +#define tag_key_selected_attr attributes[24] +#define check_attr attributes[25] +#define check_selected_attr attributes[26] +#define uarrow_attr attributes[27] +#define darrow_attr attributes[28] + +/* number of attributes */ +#define ATTRIBUTE_COUNT 29 + +/* + * Global variables + */ +extern bool use_colors; +extern bool use_shadow; + +extern chtype attributes[]; + +extern const char *backtitle; + +/* + * Function prototypes + */ +extern void create_rc(const char *filename); +extern int parse_rc(void); + +void init_dialog(void); +void end_dialog(void); +void attr_clear(WINDOW * win, int height, int width, chtype attr); +void dialog_clear(void); +void color_setup(void); +void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x); +void print_button(WINDOW * win, const char *label, int y, int x, int selected); +void print_title(WINDOW *dialog, const char *title, int width); +void draw_box(WINDOW * win, int y, int x, int height, int width, chtype box, + chtype border); +void draw_shadow(WINDOW * win, int y, int x, int height, int width); + +int first_alpha(const char *string, const char *exempt); +int dialog_yesno(const char *title, const char *prompt, int height, int width); +int dialog_msgbox(const char *title, const char *prompt, int height, + int width, int pause); +int dialog_textbox(const char *title, const char *file, int height, int width); +int dialog_menu(const char *title, const char *prompt, int height, int width, + int menu_height, const char *choice, int item_no, + const char *const *items); +int dialog_checklist(const char *title, const char *prompt, int height, + int width, int list_height, int item_no, + const char *const *items); +extern char dialog_input_result[]; +int dialog_inputbox(const char *title, const char *prompt, int height, + int width, const char *init); + +/* + * This is the base for fictitious keys, which activate + * the buttons. + * + * Mouse-generated keys are the following: + * -- the first 32 are used as numbers, in addition to '0'-'9' + * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o') + * -- uppercase chars are used to invoke the button (M_EVENT + 'O') + */ +#define M_EVENT (KEY_MAX+1) diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c new file mode 100644 index 000000000..779503726 --- /dev/null +++ b/scripts/kconfig/lxdialog/inputbox.c @@ -0,0 +1,224 @@ +/* + * inputbox.c -- implements the input box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +char dialog_input_result[MAX_LEN + 1]; + +/* + * Print the termination buttons + */ +static void print_buttons(WINDOW * dialog, int height, int width, int selected) +{ + int x = width / 2 - 11; + int y = height - 2; + + print_button(dialog, " Ok ", y, x, selected == 0); + print_button(dialog, " Help ", y, x + 14, selected == 1); + + wmove(dialog, y, x + 1 + 14 * selected); + wrefresh(dialog); +} + +/* + * Display a dialog box for inputing a string + */ +int dialog_inputbox(const char *title, const char *prompt, int height, int width, + const char *init) +{ + int i, x, y, box_y, box_x, box_width; + int input_x = 0, scroll = 0, key = 0, button = -1; + char *instr = dialog_input_result; + WINDOW *dialog; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + + dialog = newwin(height, width, y, x); + keypad(dialog, TRUE); + + draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset(dialog, border_attr); + mvwaddch(dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch(dialog, ACS_HLINE); + wattrset(dialog, dialog_attr); + waddch(dialog, ACS_RTEE); + + print_title(dialog, title, width); + + wattrset(dialog, dialog_attr); + print_autowrap(dialog, prompt, width - 2, 1, 3); + + /* Draw the input field box */ + box_width = width - 6; + getyx(dialog, y, x); + box_y = y + 2; + box_x = (width - box_width) / 2; + draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, border_attr, dialog_attr); + + print_buttons(dialog, height, width, 0); + + /* Set up the initial value */ + wmove(dialog, box_y, box_x); + wattrset(dialog, inputbox_attr); + + if (!init) + instr[0] = '\0'; + else + strcpy(instr, init); + + input_x = strlen(instr); + + if (input_x >= box_width) { + scroll = input_x - box_width + 1; + input_x = box_width - 1; + for (i = 0; i < box_width - 1; i++) + waddch(dialog, instr[scroll + i]); + } else { + waddstr(dialog, instr); + } + + wmove(dialog, box_y, box_x + input_x); + + wrefresh(dialog); + + while (key != ESC) { + key = wgetch(dialog); + + if (button == -1) { /* Input box selected */ + switch (key) { + case TAB: + case KEY_UP: + case KEY_DOWN: + break; + case KEY_LEFT: + continue; + case KEY_RIGHT: + continue; + case KEY_BACKSPACE: + case 127: + if (input_x || scroll) { + wattrset(dialog, inputbox_attr); + if (!input_x) { + scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1); + wmove(dialog, box_y, box_x); + for (i = 0; i < box_width; i++) + waddch(dialog, + instr[scroll + input_x + i] ? + instr[scroll + input_x + i] : ' '); + input_x = strlen(instr) - scroll; + } else + input_x--; + instr[scroll + input_x] = '\0'; + mvwaddch(dialog, box_y, input_x + box_x, ' '); + wmove(dialog, box_y, input_x + box_x); + wrefresh(dialog); + } + continue; + default: + if (key < 0x100 && isprint(key)) { + if (scroll + input_x < MAX_LEN) { + wattrset(dialog, inputbox_attr); + instr[scroll + input_x] = key; + instr[scroll + input_x + 1] = '\0'; + if (input_x == box_width - 1) { + scroll++; + wmove(dialog, box_y, box_x); + for (i = 0; i < box_width - 1; i++) + waddch(dialog, instr [scroll + i]); + } else { + wmove(dialog, box_y, input_x++ + box_x); + waddch(dialog, key); + } + wrefresh(dialog); + } else + flash(); /* Alarm user about overflow */ + continue; + } + } + } + switch (key) { + case 'O': + case 'o': + delwin(dialog); + return 0; + case 'H': + case 'h': + delwin(dialog); + return 1; + case KEY_UP: + case KEY_LEFT: + switch (button) { + case -1: + button = 1; /* Indicates "Cancel" button is selected */ + print_buttons(dialog, height, width, 1); + break; + case 0: + button = -1; /* Indicates input box is selected */ + print_buttons(dialog, height, width, 0); + wmove(dialog, box_y, box_x + input_x); + wrefresh(dialog); + break; + case 1: + button = 0; /* Indicates "OK" button is selected */ + print_buttons(dialog, height, width, 0); + break; + } + break; + case TAB: + case KEY_DOWN: + case KEY_RIGHT: + switch (button) { + case -1: + button = 0; /* Indicates "OK" button is selected */ + print_buttons(dialog, height, width, 0); + break; + case 0: + button = 1; /* Indicates "Cancel" button is selected */ + print_buttons(dialog, height, width, 1); + break; + case 1: + button = -1; /* Indicates input box is selected */ + print_buttons(dialog, height, width, 0); + wmove(dialog, box_y, box_x + input_x); + wrefresh(dialog); + break; + } + break; + case ' ': + case '\n': + delwin(dialog); + return (button == -1 ? 0 : button); + case 'X': + case 'x': + key = ESC; + case ESC: + break; + } + } + + delwin(dialog); + return -1; /* ESC pressed */ +} diff --git a/scripts/kconfig/lxdialog/lxdialog.c b/scripts/kconfig/lxdialog/lxdialog.c new file mode 100644 index 000000000..79f6c5fb5 --- /dev/null +++ b/scripts/kconfig/lxdialog/lxdialog.c @@ -0,0 +1,204 @@ +/* + * dialog - Display simple dialog boxes from shell scripts + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +static void Usage(const char *name); + +typedef int (jumperFn) (const char *title, int argc, const char *const *argv); + +struct Mode { + char *name; + int argmin, argmax, argmod; + jumperFn *jumper; +}; + +jumperFn j_menu, j_radiolist, j_yesno, j_textbox, j_inputbox; +jumperFn j_msgbox, j_infobox; + +static struct Mode modes[] = { + {"--menu", 9, 0, 3, j_menu}, + {"--radiolist", 9, 0, 3, j_radiolist}, + {"--yesno", 5, 5, 1, j_yesno}, + {"--textbox", 5, 5, 1, j_textbox}, + {"--inputbox", 5, 6, 1, j_inputbox}, + {"--msgbox", 5, 5, 1, j_msgbox}, + {"--infobox", 5, 5, 1, j_infobox}, + {NULL, 0, 0, 0, NULL} +}; + +static struct Mode *modePtr; + +#ifdef LOCALE +#include +#endif + +int main(int argc, const char *const *argv) +{ + int offset = 0, opt_clear = 0, end_common_opts = 0, retval; + const char *title = NULL; + +#ifdef LOCALE + (void)setlocale(LC_ALL, ""); +#endif + +#ifdef TRACE + trace(TRACE_CALLS | TRACE_UPDATE); +#endif + if (argc < 2) { + Usage(argv[0]); + exit(-1); + } + + while (offset < argc - 1 && !end_common_opts) { /* Common options */ + if (!strcmp(argv[offset + 1], "--title")) { + if (argc - offset < 3 || title != NULL) { + Usage(argv[0]); + exit(-1); + } else { + title = argv[offset + 2]; + offset += 2; + } + } else if (!strcmp(argv[offset + 1], "--backtitle")) { + if (backtitle != NULL) { + Usage(argv[0]); + exit(-1); + } else { + backtitle = argv[offset + 2]; + offset += 2; + } + } else if (!strcmp(argv[offset + 1], "--clear")) { + if (opt_clear) { /* Hey, "--clear" can't appear twice! */ + Usage(argv[0]); + exit(-1); + } else if (argc == 2) { /* we only want to clear the screen */ + init_dialog(); + refresh(); /* init_dialog() will clear the screen for us */ + end_dialog(); + return 0; + } else { + opt_clear = 1; + offset++; + } + } else /* no more common options */ + end_common_opts = 1; + } + + if (argc - 1 == offset) { /* no more options */ + Usage(argv[0]); + exit(-1); + } + /* use a table to look for the requested mode, to avoid code duplication */ + + for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */ + if (!strcmp(argv[offset + 1], modePtr->name)) + break; + + if (!modePtr->name) + Usage(argv[0]); + if (argc - offset < modePtr->argmin) + Usage(argv[0]); + if (modePtr->argmax && argc - offset > modePtr->argmax) + Usage(argv[0]); + + init_dialog(); + retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset); + + if (opt_clear) { /* clear screen before exit */ + attr_clear(stdscr, LINES, COLS, screen_attr); + refresh(); + } + end_dialog(); + + exit(retval); +} + +/* + * Print program usage + */ +static void Usage(const char *name) +{ + fprintf(stderr, "\ +\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\ +\n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\ +\n modified/gutted for use as a Linux kernel config tool by \ +\n William Roadcap (roadcapw@cfw.com)\ +\n\ +\n* Display dialog boxes from shell scripts *\ +\n\ +\nUsage: %s --clear\ +\n %s [--title ] [--backtitle <backtitle>] --clear <Box options>\ +\n\ +\nBox options:\ +\n\ +\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\ +\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\ +\n --textbox <file> <height> <width>\ +\n --inputbox <text> <height> <width> [<init>]\ +\n --yesno <text> <height> <width>\ +\n", name, name); + exit(-1); +} + +/* + * These are the program jumpers + */ + +int j_menu(const char *t, int ac, const char *const *av) +{ + return dialog_menu(t, av[2], atoi(av[3]), atoi(av[4]), + atoi(av[5]), av[6], (ac - 6) / 2, av + 7); +} + +int j_radiolist(const char *t, int ac, const char *const *av) +{ + return dialog_checklist(t, av[2], atoi(av[3]), atoi(av[4]), + atoi(av[5]), (ac - 6) / 3, av + 6); +} + +int j_textbox(const char *t, int ac, const char *const *av) +{ + return dialog_textbox(t, av[2], atoi(av[3]), atoi(av[4])); +} + +int j_yesno(const char *t, int ac, const char *const *av) +{ + return dialog_yesno(t, av[2], atoi(av[3]), atoi(av[4])); +} + +int j_inputbox(const char *t, int ac, const char *const *av) +{ + int ret = dialog_inputbox(t, av[2], atoi(av[3]), atoi(av[4]), + ac == 6 ? av[5] : (char *)NULL); + if (ret == 0) + fprintf(stderr, dialog_input_result); + return ret; +} + +int j_msgbox(const char *t, int ac, const char *const *av) +{ + return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 1); +} + +int j_infobox(const char *t, int ac, const char *const *av) +{ + return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 0); +} diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c new file mode 100644 index 000000000..bf8052f4f --- /dev/null +++ b/scripts/kconfig/lxdialog/menubox.c @@ -0,0 +1,426 @@ +/* + * menubox.c -- implements the menu box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Changes by Clifford Wolf (god@clifford.at) + * + * [ 1998-06-13 ] + * + * *) A bugfix for the Page-Down problem + * + * *) Formerly when I used Page Down and Page Up, the cursor would be set + * to the first position in the menu box. Now lxdialog is a bit + * smarter and works more like other menu systems (just have a look at + * it). + * + * *) Formerly if I selected something my scrolling would be broken because + * lxdialog is re-invoked by the Menuconfig shell script, can't + * remember the last scrolling position, and just sets it so that the + * cursor is at the bottom of the box. Now it writes the temporary file + * lxdialog.scrltmp which contains this information. The file is + * deleted by lxdialog if the user leaves a submenu or enters a new + * one, but it would be nice if Menuconfig could make another "rm -f" + * just to be sure. Just try it out - you will recognise a difference! + * + * [ 1998-06-14 ] + * + * *) Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files + * and menus change their size on the fly. + * + * *) If for some reason the last scrolling position is not saved by + * lxdialog, it sets the scrolling so that the selected item is in the + * middle of the menu box, not at the bottom. + * + * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net) + * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus. + * This fixes a bug in Menuconfig where using ' ' to descend into menus + * would leave mis-synchronized lxdialog.scrltmp files lying around, + * fscanf would read in 'scroll', and eventually that value would get used. + */ + +#include "dialog.h" + +static int menu_width, item_x; + +/* + * Print menu item + */ +static void do_print_item(WINDOW * win, const char *item, int choice, + int selected, int hotkey) +{ + int j; + char *menu_item = malloc(menu_width + 1); + + strncpy(menu_item, item, menu_width - item_x); + menu_item[menu_width] = 0; + j = first_alpha(menu_item, "YyNnMmHh"); + + /* Clear 'residue' of last item */ + wattrset(win, menubox_attr); + wmove(win, choice, 0); +#if OLD_NCURSES + { + int i; + for (i = 0; i < menu_width; i++) + waddch(win, ' '); + } +#else + wclrtoeol(win); +#endif + wattrset(win, selected ? item_selected_attr : item_attr); + mvwaddstr(win, choice, item_x, menu_item); + if (hotkey) { + wattrset(win, selected ? tag_key_selected_attr : tag_key_attr); + mvwaddch(win, choice, item_x + j, menu_item[j]); + } + if (selected) { + wmove(win, choice, item_x + 1); + } + free(menu_item); + wrefresh(win); +} + +#define print_item(index, choice, selected) \ +do {\ + int hotkey = (items[(index) * 2][0] != ':'); \ + do_print_item(menu, items[(index) * 2 + 1], choice, selected, hotkey); \ +} while (0) + +/* + * Print the scroll indicators. + */ +static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x, + int height) +{ + int cur_y, cur_x; + + getyx(win, cur_y, cur_x); + + wmove(win, y, x); + + if (scroll > 0) { + wattrset(win, uarrow_attr); + waddch(win, ACS_UARROW); + waddstr(win, "(-)"); + } else { + wattrset(win, menubox_attr); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + } + + y = y + height + 1; + wmove(win, y, x); + wrefresh(win); + + if ((height < item_no) && (scroll + height < item_no)) { + wattrset(win, darrow_attr); + waddch(win, ACS_DARROW); + waddstr(win, "(+)"); + } else { + wattrset(win, menubox_border_attr); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + waddch(win, ACS_HLINE); + } + + wmove(win, cur_y, cur_x); + wrefresh(win); +} + +/* + * Display the termination buttons. + */ +static void print_buttons(WINDOW * win, int height, int width, int selected) +{ + int x = width / 2 - 16; + int y = height - 2; + + print_button(win, "Select", y, x, selected == 0); + print_button(win, " Exit ", y, x + 12, selected == 1); + print_button(win, " Help ", y, x + 24, selected == 2); + + wmove(win, y, x + 1 + 12 * selected); + wrefresh(win); +} + +/* scroll up n lines (n may be negative) */ +static void do_scroll(WINDOW *win, int *scroll, int n) +{ + /* Scroll menu up */ + scrollok(win, TRUE); + wscrl(win, n); + scrollok(win, FALSE); + *scroll = *scroll + n; + wrefresh(win); +} + +/* + * Display a menu for choosing among a number of options + */ +int dialog_menu(const char *title, const char *prompt, int height, int width, + int menu_height, const char *current, int item_no, + const char *const *items) +{ + int i, j, x, y, box_x, box_y; + int key = 0, button = 0, scroll = 0, choice = 0; + int first_item = 0, max_choice; + WINDOW *dialog, *menu; + FILE *f; + + max_choice = MIN(menu_height, item_no); + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + + dialog = newwin(height, width, y, x); + keypad(dialog, TRUE); + + draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset(dialog, border_attr); + mvwaddch(dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch(dialog, ACS_HLINE); + wattrset(dialog, dialog_attr); + wbkgdset(dialog, dialog_attr & A_COLOR); + waddch(dialog, ACS_RTEE); + + print_title(dialog, title, width); + + wattrset(dialog, dialog_attr); + print_autowrap(dialog, prompt, width - 2, 1, 3); + + menu_width = width - 6; + box_y = height - menu_height - 5; + box_x = (width - menu_width) / 2 - 1; + + /* create new window for the menu */ + menu = subwin(dialog, menu_height, menu_width, + y + box_y + 1, x + box_x + 1); + keypad(menu, TRUE); + + /* draw a box around the menu items */ + draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2, + menubox_border_attr, menubox_attr); + + item_x = (menu_width - 70) / 2; + + /* Set choice to default item */ + for (i = 0; i < item_no; i++) + if (strcmp(current, items[i * 2]) == 0) + choice = i; + + /* get the scroll info from the temp file */ + if ((f = fopen("lxdialog.scrltmp", "r")) != NULL) { + if ((fscanf(f, "%d\n", &scroll) == 1) && (scroll <= choice) && + (scroll + max_choice > choice) && (scroll >= 0) && + (scroll + max_choice <= item_no)) { + first_item = scroll; + choice = choice - scroll; + fclose(f); + } else { + scroll = 0; + remove("lxdialog.scrltmp"); + fclose(f); + f = NULL; + } + } + if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) { + if (choice >= item_no - max_choice / 2) + scroll = first_item = item_no - max_choice; + else + scroll = first_item = choice - max_choice / 2; + choice = choice - scroll; + } + + /* Print the menu */ + for (i = 0; i < max_choice; i++) { + print_item(first_item + i, i, i == choice); + } + + wnoutrefresh(menu); + + print_arrows(dialog, item_no, scroll, + box_y, box_x + item_x + 1, menu_height); + + print_buttons(dialog, height, width, 0); + wmove(menu, choice, item_x + 1); + wrefresh(menu); + + while (key != ESC) { + key = wgetch(menu); + + if (key < 256 && isalpha(key)) + key = tolower(key); + + if (strchr("ynmh", key)) + i = max_choice; + else { + for (i = choice + 1; i < max_choice; i++) { + j = first_alpha(items[(scroll + i) * 2 + 1], "YyNnMmHh"); + if (key == tolower(items[(scroll + i) * 2 + 1][j])) + break; + } + if (i == max_choice) + for (i = 0; i < max_choice; i++) { + j = first_alpha(items [(scroll + i) * 2 + 1], "YyNnMmHh"); + if (key == tolower(items[(scroll + i) * 2 + 1][j])) + break; + } + } + + if (i < max_choice || + key == KEY_UP || key == KEY_DOWN || + key == '-' || key == '+' || + key == KEY_PPAGE || key == KEY_NPAGE) { + /* Remove highligt of current item */ + print_item(scroll + choice, choice, FALSE); + + if (key == KEY_UP || key == '-') { + if (choice < 2 && scroll) { + /* Scroll menu down */ + do_scroll(menu, &scroll, -1); + + print_item(scroll, 0, FALSE); + } else + choice = MAX(choice - 1, 0); + + } else if (key == KEY_DOWN || key == '+') { + print_item(scroll+choice, choice, FALSE); + + if ((choice > max_choice - 3) && + (scroll + max_choice < item_no)) { + /* Scroll menu up */ + do_scroll(menu, &scroll, 1); + + print_item(scroll+max_choice - 1, + max_choice - 1, FALSE); + } else + choice = MIN(choice + 1, max_choice - 1); + + } else if (key == KEY_PPAGE) { + scrollok(menu, TRUE); + for (i = 0; (i < max_choice); i++) { + if (scroll > 0) { + do_scroll(menu, &scroll, -1); + print_item(scroll, 0, FALSE); + } else { + if (choice > 0) + choice--; + } + } + + } else if (key == KEY_NPAGE) { + for (i = 0; (i < max_choice); i++) { + if (scroll + max_choice < item_no) { + do_scroll(menu, &scroll, 1); + print_item(scroll+max_choice-1, + max_choice - 1, FALSE); + } else { + if (choice + 1 < max_choice) + choice++; + } + } + } else + choice = i; + + print_item(scroll + choice, choice, TRUE); + + print_arrows(dialog, item_no, scroll, + box_y, box_x + item_x + 1, menu_height); + + wnoutrefresh(dialog); + wrefresh(menu); + + continue; /* wait for another key press */ + } + + switch (key) { + case KEY_LEFT: + case TAB: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 2 : (button > 2 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh(menu); + break; + case ' ': + case 's': + case 'y': + case 'n': + case 'm': + case '/': + /* save scroll info */ + if ((f = fopen("lxdialog.scrltmp", "w")) != NULL) { + fprintf(f, "%d\n", scroll); + fclose(f); + } + delwin(dialog); + fprintf(stderr, "%s\n", items[(scroll + choice) * 2]); + switch (key) { + case 's': + return 3; + case 'y': + return 3; + case 'n': + return 4; + case 'm': + return 5; + case ' ': + return 6; + case '/': + return 7; + } + return 0; + case 'h': + case '?': + button = 2; + case '\n': + delwin(dialog); + if (button == 2) + fprintf(stderr, "%s \"%s\"\n", + items[(scroll + choice) * 2], + items[(scroll + choice) * 2 + 1] + + first_alpha(items [(scroll + choice) * 2 + 1], "")); + else + fprintf(stderr, "%s\n", + items[(scroll + choice) * 2]); + + remove("lxdialog.scrltmp"); + return button; + case 'e': + case 'x': + key = ESC; + case ESC: + break; + } + } + + delwin(dialog); + remove("lxdialog.scrltmp"); + return -1; /* ESC pressed */ +} diff --git a/scripts/kconfig/lxdialog/msgbox.c b/scripts/kconfig/lxdialog/msgbox.c new file mode 100644 index 000000000..7323f5471 --- /dev/null +++ b/scripts/kconfig/lxdialog/msgbox.c @@ -0,0 +1,71 @@ +/* + * msgbox.c -- implements the message box and info box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +/* + * Display a message box. Program will pause and display an "OK" button + * if the parameter 'pause' is non-zero. + */ +int dialog_msgbox(const char *title, const char *prompt, int height, int width, + int pause) +{ + int i, x, y, key = 0; + WINDOW *dialog; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + + dialog = newwin(height, width, y, x); + keypad(dialog, TRUE); + + draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); + + print_title(dialog, title, width); + + wattrset(dialog, dialog_attr); + print_autowrap(dialog, prompt, width - 2, 1, 2); + + if (pause) { + wattrset(dialog, border_attr); + mvwaddch(dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch(dialog, ACS_HLINE); + wattrset(dialog, dialog_attr); + waddch(dialog, ACS_RTEE); + + print_button(dialog, " Ok ", height - 2, width / 2 - 4, TRUE); + + wrefresh(dialog); + while (key != ESC && key != '\n' && key != ' ' && + key != 'O' && key != 'o' && key != 'X' && key != 'x') + key = wgetch(dialog); + } else { + key = '\n'; + wrefresh(dialog); + } + + delwin(dialog); + return key == ESC ? -1 : 0; +} diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c new file mode 100644 index 000000000..77848bb8e --- /dev/null +++ b/scripts/kconfig/lxdialog/textbox.c @@ -0,0 +1,533 @@ +/* + * textbox.c -- implements the text box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +static void back_lines(int n); +static void print_page(WINDOW * win, int height, int width); +static void print_line(WINDOW * win, int row, int width); +static char *get_line(void); +static void print_position(WINDOW * win, int height, int width); + +static int hscroll, fd, file_size, bytes_read; +static int begin_reached = 1, end_reached, page_length; +static char *buf, *page; + +/* + * Display text from a file in a dialog box. + */ +int dialog_textbox(const char *title, const char *file, int height, int width) +{ + int i, x, y, cur_x, cur_y, fpos, key = 0; + int passed_end; + char search_term[MAX_LEN + 1]; + WINDOW *dialog, *text; + + search_term[0] = '\0'; /* no search term entered yet */ + + /* Open input file for reading */ + if ((fd = open(file, O_RDONLY)) == -1) { + endwin(); + fprintf(stderr, "\nCan't open input file in dialog_textbox().\n"); + exit(-1); + } + /* Get file size. Actually, 'file_size' is the real file size - 1, + since it's only the last byte offset from the beginning */ + if ((file_size = lseek(fd, 0, SEEK_END)) == -1) { + endwin(); + fprintf(stderr, "\nError getting file size in dialog_textbox().\n"); + exit(-1); + } + /* Restore file pointer to beginning of file after getting file size */ + if (lseek(fd, 0, SEEK_SET) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); + exit(-1); + } + /* Allocate space for read buffer */ + if ((buf = malloc(BUF_SIZE + 1)) == NULL) { + endwin(); + fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n"); + exit(-1); + } + if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) { + endwin(); + fprintf(stderr, "\nError reading file in dialog_textbox().\n"); + exit(-1); + } + buf[bytes_read] = '\0'; /* mark end of valid data */ + page = buf; /* page is pointer to start of page to be displayed */ + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + + dialog = newwin(height, width, y, x); + keypad(dialog, TRUE); + + /* Create window for text region, used for scrolling text */ + text = subwin(dialog, height - 4, width - 2, y + 1, x + 1); + wattrset(text, dialog_attr); + wbkgdset(text, dialog_attr & A_COLOR); + + keypad(text, TRUE); + + /* register the new window, along with its borders */ + draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); + + wattrset(dialog, border_attr); + mvwaddch(dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch(dialog, ACS_HLINE); + wattrset(dialog, dialog_attr); + wbkgdset(dialog, dialog_attr & A_COLOR); + waddch(dialog, ACS_RTEE); + + print_title(dialog, title, width); + + print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE); + wnoutrefresh(dialog); + getyx(dialog, cur_y, cur_x); /* Save cursor position */ + + /* Print first page of text */ + attr_clear(text, height - 4, width - 2, dialog_attr); + print_page(text, height - 4, width - 2); + print_position(dialog, height, width); + wmove(dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh(dialog); + + while ((key != ESC) && (key != '\n')) { + key = wgetch(dialog); + switch (key) { + case 'E': /* Exit */ + case 'e': + case 'X': + case 'x': + delwin(dialog); + free(buf); + close(fd); + return 0; + case 'g': /* First page */ + case KEY_HOME: + if (!begin_reached) { + begin_reached = 1; + /* First page not in buffer? */ + if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); + exit(-1); + } + if (fpos > bytes_read) { /* Yes, we have to read it in */ + if (lseek(fd, 0, SEEK_SET) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer in " + "dialog_textbox().\n"); + exit(-1); + } + if ((bytes_read = + read(fd, buf, BUF_SIZE)) == -1) { + endwin(); + fprintf(stderr, "\nError reading file in dialog_textbox().\n"); + exit(-1); + } + buf[bytes_read] = '\0'; + } + page = buf; + print_page(text, height - 4, width - 2); + print_position(dialog, height, width); + wmove(dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh(dialog); + } + break; + case 'G': /* Last page */ + case KEY_END: + + end_reached = 1; + /* Last page not in buffer? */ + if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); + exit(-1); + } + if (fpos < file_size) { /* Yes, we have to read it in */ + if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n"); + exit(-1); + } + if ((bytes_read = + read(fd, buf, BUF_SIZE)) == -1) { + endwin(); + fprintf(stderr, "\nError reading file in dialog_textbox().\n"); + exit(-1); + } + buf[bytes_read] = '\0'; + } + page = buf + bytes_read; + back_lines(height - 4); + print_page(text, height - 4, width - 2); + print_position(dialog, height, width); + wmove(dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh(dialog); + break; + case 'K': /* Previous line */ + case 'k': + case KEY_UP: + if (!begin_reached) { + back_lines(page_length + 1); + + /* We don't call print_page() here but use scrolling to ensure + faster screen update. However, 'end_reached' and + 'page_length' should still be updated, and 'page' should + point to start of next page. This is done by calling + get_line() in the following 'for' loop. */ + scrollok(text, TRUE); + wscrl(text, -1); /* Scroll text region down one line */ + scrollok(text, FALSE); + page_length = 0; + passed_end = 0; + for (i = 0; i < height - 4; i++) { + if (!i) { + /* print first line of page */ + print_line(text, 0, width - 2); + wnoutrefresh(text); + } else + /* Called to update 'end_reached' and 'page' */ + get_line(); + if (!passed_end) + page_length++; + if (end_reached && !passed_end) + passed_end = 1; + } + + print_position(dialog, height, width); + wmove(dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh(dialog); + } + break; + case 'B': /* Previous page */ + case 'b': + case KEY_PPAGE: + if (begin_reached) + break; + back_lines(page_length + height - 4); + print_page(text, height - 4, width - 2); + print_position(dialog, height, width); + wmove(dialog, cur_y, cur_x); + wrefresh(dialog); + break; + case 'J': /* Next line */ + case 'j': + case KEY_DOWN: + if (!end_reached) { + begin_reached = 0; + scrollok(text, TRUE); + scroll(text); /* Scroll text region up one line */ + scrollok(text, FALSE); + print_line(text, height - 5, width - 2); + wnoutrefresh(text); + print_position(dialog, height, width); + wmove(dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh(dialog); + } + break; + case KEY_NPAGE: /* Next page */ + case ' ': + if (end_reached) + break; + + begin_reached = 0; + print_page(text, height - 4, width - 2); + print_position(dialog, height, width); + wmove(dialog, cur_y, cur_x); + wrefresh(dialog); + break; + case '0': /* Beginning of line */ + case 'H': /* Scroll left */ + case 'h': + case KEY_LEFT: + if (hscroll <= 0) + break; + + if (key == '0') + hscroll = 0; + else + hscroll--; + /* Reprint current page to scroll horizontally */ + back_lines(page_length); + print_page(text, height - 4, width - 2); + wmove(dialog, cur_y, cur_x); + wrefresh(dialog); + break; + case 'L': /* Scroll right */ + case 'l': + case KEY_RIGHT: + if (hscroll >= MAX_LEN) + break; + hscroll++; + /* Reprint current page to scroll horizontally */ + back_lines(page_length); + print_page(text, height - 4, width - 2); + wmove(dialog, cur_y, cur_x); + wrefresh(dialog); + break; + case ESC: + break; + } + } + + delwin(dialog); + free(buf); + close(fd); + return -1; /* ESC pressed */ +} + +/* + * Go back 'n' lines in text file. Called by dialog_textbox(). + * 'page' will be updated to point to the desired line in 'buf'. + */ +static void back_lines(int n) +{ + int i, fpos; + + begin_reached = 0; + /* We have to distinguish between end_reached and !end_reached + since at end of file, the line is not ended by a '\n'. + The code inside 'if' basically does a '--page' to move one + character backward so as to skip '\n' of the previous line */ + if (!end_reached) { + /* Either beginning of buffer or beginning of file reached? */ + if (page == buf) { + if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer in " + "back_lines().\n"); + exit(-1); + } + if (fpos > bytes_read) { /* Not beginning of file yet */ + /* We've reached beginning of buffer, but not beginning of + file yet, so read previous part of file into buffer. + Note that we only move backward for BUF_SIZE/2 bytes, + but not BUF_SIZE bytes to avoid re-reading again in + print_page() later */ + /* Really possible to move backward BUF_SIZE/2 bytes? */ + if (fpos < BUF_SIZE / 2 + bytes_read) { + /* No, move less then */ + if (lseek(fd, 0, SEEK_SET) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer in " + "back_lines().\n"); + exit(-1); + } + page = buf + fpos - bytes_read; + } else { /* Move backward BUF_SIZE/2 bytes */ + if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer " + "in back_lines().\n"); + exit(-1); + } + page = buf + BUF_SIZE / 2; + } + if ((bytes_read = + read(fd, buf, BUF_SIZE)) == -1) { + endwin(); + fprintf(stderr, "\nError reading file in back_lines().\n"); + exit(-1); + } + buf[bytes_read] = '\0'; + } else { /* Beginning of file reached */ + begin_reached = 1; + return; + } + } + if (*(--page) != '\n') { /* '--page' here */ + /* Something's wrong... */ + endwin(); + fprintf(stderr, "\nInternal error in back_lines().\n"); + exit(-1); + } + } + /* Go back 'n' lines */ + for (i = 0; i < n; i++) + do { + if (page == buf) { + if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer in back_lines().\n"); + exit(-1); + } + if (fpos > bytes_read) { + /* Really possible to move backward BUF_SIZE/2 bytes? */ + if (fpos < BUF_SIZE / 2 + bytes_read) { + /* No, move less then */ + if (lseek(fd, 0, SEEK_SET) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer " + "in back_lines().\n"); + exit(-1); + } + page = buf + fpos - bytes_read; + } else { /* Move backward BUF_SIZE/2 bytes */ + if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer" + " in back_lines().\n"); + exit(-1); + } + page = buf + BUF_SIZE / 2; + } + if ((bytes_read = + read(fd, buf, BUF_SIZE)) == -1) { + endwin(); + fprintf(stderr, "\nError reading file in " + "back_lines().\n"); + exit(-1); + } + buf[bytes_read] = '\0'; + } else { /* Beginning of file reached */ + begin_reached = 1; + return; + } + } + } while (*(--page) != '\n'); + page++; +} + +/* + * Print a new page of text. Called by dialog_textbox(). + */ +static void print_page(WINDOW * win, int height, int width) +{ + int i, passed_end = 0; + + page_length = 0; + for (i = 0; i < height; i++) { + print_line(win, i, width); + if (!passed_end) + page_length++; + if (end_reached && !passed_end) + passed_end = 1; + } + wnoutrefresh(win); +} + +/* + * Print a new line of text. Called by dialog_textbox() and print_page(). + */ +static void print_line(WINDOW * win, int row, int width) +{ + int y, x; + char *line; + + line = get_line(); + line += MIN(strlen(line), hscroll); /* Scroll horizontally */ + wmove(win, row, 0); /* move cursor to correct line */ + waddch(win, ' '); + waddnstr(win, line, MIN(strlen(line), width - 2)); + + getyx(win, y, x); + /* Clear 'residue' of previous line */ +#if OLD_NCURSES + { + int i; + for (i = 0; i < width - x; i++) + waddch(win, ' '); + } +#else + wclrtoeol(win); +#endif +} + +/* + * Return current line of text. Called by dialog_textbox() and print_line(). + * 'page' should point to start of current line before calling, and will be + * updated to point to start of next line. + */ +static char *get_line(void) +{ + int i = 0, fpos; + static char line[MAX_LEN + 1]; + + end_reached = 0; + while (*page != '\n') { + if (*page == '\0') { + /* Either end of file or end of buffer reached */ + if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer in " + "get_line().\n"); + exit(-1); + } + if (fpos < file_size) { /* Not end of file yet */ + /* We've reached end of buffer, but not end of file yet, + so read next part of file into buffer */ + if ((bytes_read = + read(fd, buf, BUF_SIZE)) == -1) { + endwin(); + fprintf(stderr, "\nError reading file in get_line().\n"); + exit(-1); + } + buf[bytes_read] = '\0'; + page = buf; + } else { + if (!end_reached) + end_reached = 1; + break; + } + } else if (i < MAX_LEN) + line[i++] = *(page++); + else { + /* Truncate lines longer than MAX_LEN characters */ + if (i == MAX_LEN) + line[i++] = '\0'; + page++; + } + } + if (i <= MAX_LEN) + line[i] = '\0'; + if (!end_reached) + page++; /* move pass '\n' */ + + return line; +} + +/* + * Print current position + */ +static void print_position(WINDOW * win, int height, int width) +{ + int fpos, percent; + + if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) { + endwin(); + fprintf(stderr, "\nError moving file pointer in print_position().\n"); + exit(-1); + } + wattrset(win, position_indicator_attr); + wbkgdset(win, position_indicator_attr & A_COLOR); + percent = !file_size ? + 100 : ((fpos - bytes_read + page - buf) * 100) / file_size; + wmove(win, height - 3, width - 9); + wprintw(win, "(%3d%%)", percent); +} diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c new file mode 100644 index 000000000..f82cebb9f --- /dev/null +++ b/scripts/kconfig/lxdialog/util.c @@ -0,0 +1,362 @@ +/* + * util.c + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +/* use colors by default? */ +bool use_colors = 1; + +const char *backtitle = NULL; + +/* + * Attribute values, default is for mono display + */ +chtype attributes[] = { + A_NORMAL, /* screen_attr */ + A_NORMAL, /* shadow_attr */ + A_NORMAL, /* dialog_attr */ + A_BOLD, /* title_attr */ + A_NORMAL, /* border_attr */ + A_REVERSE, /* button_active_attr */ + A_DIM, /* button_inactive_attr */ + A_REVERSE, /* button_key_active_attr */ + A_BOLD, /* button_key_inactive_attr */ + A_REVERSE, /* button_label_active_attr */ + A_NORMAL, /* button_label_inactive_attr */ + A_NORMAL, /* inputbox_attr */ + A_NORMAL, /* inputbox_border_attr */ + A_NORMAL, /* searchbox_attr */ + A_BOLD, /* searchbox_title_attr */ + A_NORMAL, /* searchbox_border_attr */ + A_BOLD, /* position_indicator_attr */ + A_NORMAL, /* menubox_attr */ + A_NORMAL, /* menubox_border_attr */ + A_NORMAL, /* item_attr */ + A_REVERSE, /* item_selected_attr */ + A_BOLD, /* tag_attr */ + A_REVERSE, /* tag_selected_attr */ + A_BOLD, /* tag_key_attr */ + A_REVERSE, /* tag_key_selected_attr */ + A_BOLD, /* check_attr */ + A_REVERSE, /* check_selected_attr */ + A_BOLD, /* uarrow_attr */ + A_BOLD /* darrow_attr */ +}; + +#include "colors.h" + +/* + * Table of color values + */ +int color_table[][3] = { + {SCREEN_FG, SCREEN_BG, SCREEN_HL}, + {SHADOW_FG, SHADOW_BG, SHADOW_HL}, + {DIALOG_FG, DIALOG_BG, DIALOG_HL}, + {TITLE_FG, TITLE_BG, TITLE_HL}, + {BORDER_FG, BORDER_BG, BORDER_HL}, + {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL}, + {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL}, + {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL}, + {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, + BUTTON_KEY_INACTIVE_HL}, + {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, + BUTTON_LABEL_ACTIVE_HL}, + {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG, + BUTTON_LABEL_INACTIVE_HL}, + {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL}, + {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL}, + {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL}, + {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL}, + {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL}, + {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL}, + {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL}, + {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL}, + {ITEM_FG, ITEM_BG, ITEM_HL}, + {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL}, + {TAG_FG, TAG_BG, TAG_HL}, + {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL}, + {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL}, + {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL}, + {CHECK_FG, CHECK_BG, CHECK_HL}, + {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL}, + {UARROW_FG, UARROW_BG, UARROW_HL}, + {DARROW_FG, DARROW_BG, DARROW_HL}, +}; /* color_table */ + +/* + * Set window to attribute 'attr' + */ +void attr_clear(WINDOW * win, int height, int width, chtype attr) +{ + int i, j; + + wattrset(win, attr); + for (i = 0; i < height; i++) { + wmove(win, i, 0); + for (j = 0; j < width; j++) + waddch(win, ' '); + } + touchwin(win); +} + +void dialog_clear(void) +{ + attr_clear(stdscr, LINES, COLS, screen_attr); + /* Display background title if it exists ... - SLH */ + if (backtitle != NULL) { + int i; + + wattrset(stdscr, screen_attr); + mvwaddstr(stdscr, 0, 1, (char *)backtitle); + wmove(stdscr, 1, 1); + for (i = 1; i < COLS - 1; i++) + waddch(stdscr, ACS_HLINE); + } + wnoutrefresh(stdscr); +} + +/* + * Do some initialization for dialog + */ +void init_dialog(void) +{ + initscr(); /* Init curses */ + keypad(stdscr, TRUE); + cbreak(); + noecho(); + + if (use_colors) /* Set up colors */ + color_setup(); + + dialog_clear(); +} + +/* + * Setup for color display + */ +void color_setup(void) +{ + int i; + + if (has_colors()) { /* Terminal supports color? */ + start_color(); + + /* Initialize color pairs */ + for (i = 0; i < ATTRIBUTE_COUNT; i++) + init_pair(i + 1, color_table[i][0], color_table[i][1]); + + /* Setup color attributes */ + for (i = 0; i < ATTRIBUTE_COUNT; i++) + attributes[i] = C_ATTR(color_table[i][2], i + 1); + } +} + +/* + * End using dialog functions. + */ +void end_dialog(void) +{ + endwin(); +} + +/* Print the title of the dialog. Center the title and truncate + * tile if wider than dialog (- 2 chars). + **/ +void print_title(WINDOW *dialog, const char *title, int width) +{ + if (title) { + int tlen = MIN(width - 2, strlen(title)); + wattrset(dialog, title_attr); + mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' '); + mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen); + waddch(dialog, ' '); + } +} + +/* + * Print a string of text in a window, automatically wrap around to the + * next line if the string is too long to fit on one line. Newline + * characters '\n' are replaced by spaces. We start on a new line + * if there is no room for at least 4 nonblanks following a double-space. + */ +void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) +{ + int newl, cur_x, cur_y; + int i, prompt_len, room, wlen; + char tempstr[MAX_LEN + 1], *word, *sp, *sp2; + + strcpy(tempstr, prompt); + + prompt_len = strlen(tempstr); + + /* + * Remove newlines + */ + for (i = 0; i < prompt_len; i++) { + if (tempstr[i] == '\n') + tempstr[i] = ' '; + } + + if (prompt_len <= width - x * 2) { /* If prompt is short */ + wmove(win, y, (width - prompt_len) / 2); + waddstr(win, tempstr); + } else { + cur_x = x; + cur_y = y; + newl = 1; + word = tempstr; + while (word && *word) { + sp = index(word, ' '); + if (sp) + *sp++ = 0; + + /* Wrap to next line if either the word does not fit, + or it is the first word of a new sentence, and it is + short, and the next word does not fit. */ + room = width - cur_x; + wlen = strlen(word); + if (wlen > room || + (newl && wlen < 4 && sp + && wlen + 1 + strlen(sp) > room + && (!(sp2 = index(sp, ' ')) + || wlen + 1 + (sp2 - sp) > room))) { + cur_y++; + cur_x = x; + } + wmove(win, cur_y, cur_x); + waddstr(win, word); + getyx(win, cur_y, cur_x); + cur_x++; + if (sp && *sp == ' ') { + cur_x++; /* double space */ + while (*++sp == ' ') ; + newl = 1; + } else + newl = 0; + word = sp; + } + } +} + +/* + * Print a button + */ +void print_button(WINDOW * win, const char *label, int y, int x, int selected) +{ + int i, temp; + + wmove(win, y, x); + wattrset(win, selected ? button_active_attr : button_inactive_attr); + waddstr(win, "<"); + temp = strspn(label, " "); + label += temp; + wattrset(win, selected ? button_label_active_attr + : button_label_inactive_attr); + for (i = 0; i < temp; i++) + waddch(win, ' '); + wattrset(win, selected ? button_key_active_attr + : button_key_inactive_attr); + waddch(win, label[0]); + wattrset(win, selected ? button_label_active_attr + : button_label_inactive_attr); + waddstr(win, (char *)label + 1); + wattrset(win, selected ? button_active_attr : button_inactive_attr); + waddstr(win, ">"); + wmove(win, y, x + temp + 1); +} + +/* + * Draw a rectangular box with line drawing characters + */ +void +draw_box(WINDOW * win, int y, int x, int height, int width, + chtype box, chtype border) +{ + int i, j; + + wattrset(win, 0); + for (i = 0; i < height; i++) { + wmove(win, y + i, x); + for (j = 0; j < width; j++) + if (!i && !j) + waddch(win, border | ACS_ULCORNER); + else if (i == height - 1 && !j) + waddch(win, border | ACS_LLCORNER); + else if (!i && j == width - 1) + waddch(win, box | ACS_URCORNER); + else if (i == height - 1 && j == width - 1) + waddch(win, box | ACS_LRCORNER); + else if (!i) + waddch(win, border | ACS_HLINE); + else if (i == height - 1) + waddch(win, box | ACS_HLINE); + else if (!j) + waddch(win, border | ACS_VLINE); + else if (j == width - 1) + waddch(win, box | ACS_VLINE); + else + waddch(win, box | ' '); + } +} + +/* + * Draw shadows along the right and bottom edge to give a more 3D look + * to the boxes + */ +void draw_shadow(WINDOW * win, int y, int x, int height, int width) +{ + int i; + + if (has_colors()) { /* Whether terminal supports color? */ + wattrset(win, shadow_attr); + wmove(win, y + height, x + 2); + for (i = 0; i < width; i++) + waddch(win, winch(win) & A_CHARTEXT); + for (i = y + 1; i < y + height + 1; i++) { + wmove(win, i, x + width); + waddch(win, winch(win) & A_CHARTEXT); + waddch(win, winch(win) & A_CHARTEXT); + } + wnoutrefresh(win); + } +} + +/* + * Return the position of the first alphabetic character in a string. + */ +int first_alpha(const char *string, const char *exempt) +{ + int i, in_paren = 0, c; + + for (i = 0; i < strlen(string); i++) { + c = tolower(string[i]); + + if (strchr("<[(", c)) + ++in_paren; + if (strchr(">])", c) && in_paren > 0) + --in_paren; + + if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0) + return i; + } + + return 0; +} diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c new file mode 100644 index 000000000..cb2568aae --- /dev/null +++ b/scripts/kconfig/lxdialog/yesno.c @@ -0,0 +1,102 @@ +/* + * yesno.c -- implements the yes/no box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "dialog.h" + +/* + * Display termination buttons + */ +static void print_buttons(WINDOW * dialog, int height, int width, int selected) +{ + int x = width / 2 - 10; + int y = height - 2; + + print_button(dialog, " Yes ", y, x, selected == 0); + print_button(dialog, " No ", y, x + 13, selected == 1); + + wmove(dialog, y, x + 1 + 13 * selected); + wrefresh(dialog); +} + +/* + * Display a dialog box with two buttons - Yes and No + */ +int dialog_yesno(const char *title, const char *prompt, int height, int width) +{ + int i, x, y, key = 0, button = 0; + WINDOW *dialog; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow(stdscr, y, x, height, width); + + dialog = newwin(height, width, y, x); + keypad(dialog, TRUE); + + draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset(dialog, border_attr); + mvwaddch(dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch(dialog, ACS_HLINE); + wattrset(dialog, dialog_attr); + waddch(dialog, ACS_RTEE); + + print_title(dialog, title, width); + + wattrset(dialog, dialog_attr); + print_autowrap(dialog, prompt, width - 2, 1, 3); + + print_buttons(dialog, height, width, 0); + + while (key != ESC) { + key = wgetch(dialog); + switch (key) { + case 'Y': + case 'y': + delwin(dialog); + return 0; + case 'N': + case 'n': + delwin(dialog); + return 1; + + case TAB: + case KEY_LEFT: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh(dialog); + break; + case ' ': + case '\n': + delwin(dialog); + return button; + case ESC: + break; + } + } + + delwin(dialog); + return -1; /* ESC pressed */ +} diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c new file mode 100644 index 000000000..7f973195e --- /dev/null +++ b/scripts/kconfig/mconf.c @@ -0,0 +1,1098 @@ +/* + * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> + * Released under the terms of the GNU GPL v2.0. + * + * Introduced single menu mode (show all sub-menus in one large tree). + * 2002-11-06 Petr Baudis <pasky@ucw.cz> + * + * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br> + */ + +#include <sys/ioctl.h> +#include <sys/wait.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <signal.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> +#include <locale.h> + +#define LKC_DIRECT_LINK +#include "lkc.h" + +static char menu_backtitle[128]; +static const char mconf_readme[] = N_( +"Overview\n" +"--------\n" +"Some kernel features may be built directly into the kernel.\n" +"Some may be made into loadable runtime modules. Some features\n" +"may be completely removed altogether. There are also certain\n" +"kernel parameters which are not really features, but must be\n" +"entered in as decimal or hexadecimal numbers or possibly text.\n" +"\n" +"Menu items beginning with [*], <M> or [ ] represent features\n" +"configured to be built in, modularized or removed respectively.\n" +"Pointed brackets <> represent module capable features.\n" +"\n" +"To change any of these features, highlight it with the cursor\n" +"keys and press <Y> to build it in, <M> to make it a module or\n" +"<N> to removed it. You may also press the <Space Bar> to cycle\n" +"through the available options (ie. Y->N->M->Y).\n" +"\n" +"Some additional keyboard hints:\n" +"\n" +"Menus\n" +"----------\n" +"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n" +" you wish to change or submenu wish to select and press <Enter>.\n" +" Submenus are designated by \"--->\".\n" +"\n" +" Shortcut: Press the option's highlighted letter (hotkey).\n" +" Pressing a hotkey more than once will sequence\n" +" through all visible items which use that hotkey.\n" +"\n" +" You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" +" unseen options into view.\n" +"\n" +"o To exit a menu use the cursor keys to highlight the <Exit> button\n" +" and press <ENTER>.\n" +"\n" +" Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n" +" using those letters. You may press a single <ESC>, but\n" +" there is a delayed response which you may find annoying.\n" +"\n" +" Also, the <TAB> and cursor keys will cycle between <Select>,\n" +" <Exit> and <Help>\n" +"\n" +"o To get help with an item, use the cursor keys to highlight <Help>\n" +" and Press <ENTER>.\n" +"\n" +" Shortcut: Press <H> or <?>.\n" +"\n" +"\n" +"Radiolists (Choice lists)\n" +"-----------\n" +"o Use the cursor keys to select the option you wish to set and press\n" +" <S> or the <SPACE BAR>.\n" +"\n" +" Shortcut: Press the first letter of the option you wish to set then\n" +" press <S> or <SPACE BAR>.\n" +"\n" +"o To see available help for the item, use the cursor keys to highlight\n" +" <Help> and Press <ENTER>.\n" +"\n" +" Shortcut: Press <H> or <?>.\n" +"\n" +" Also, the <TAB> and cursor keys will cycle between <Select> and\n" +" <Help>\n" +"\n" +"\n" +"Data Entry\n" +"-----------\n" +"o Enter the requested information and press <ENTER>\n" +" If you are entering hexadecimal values, it is not necessary to\n" +" add the '0x' prefix to the entry.\n" +"\n" +"o For help, use the <TAB> or cursor keys to highlight the help option\n" +" and press <ENTER>. You can try <TAB><H> as well.\n" +"\n" +"\n" +"Text Box (Help Window)\n" +"--------\n" +"o Use the cursor keys to scroll up/down/left/right. The VI editor\n" +" keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n" +" who are familiar with less and lynx.\n" +"\n" +"o Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n" +"\n" +"\n" +"Alternate Configuration Files\n" +"-----------------------------\n" +"Menuconfig supports the use of alternate configuration files for\n" +"those who, for various reasons, find it necessary to switch\n" +"between different kernel configurations.\n" +"\n" +"At the end of the main menu you will find two options. One is\n" +"for saving the current configuration to a file of your choosing.\n" +"The other option is for loading a previously saved alternate\n" +"configuration.\n" +"\n" +"Even if you don't use alternate configuration files, but you\n" +"find during a Menuconfig session that you have completely messed\n" +"up your settings, you may use the \"Load Alternate...\" option to\n" +"restore your previously saved settings from \".config\" without\n" +"restarting Menuconfig.\n" +"\n" +"Other information\n" +"-----------------\n" +"If you use Menuconfig in an XTERM window make sure you have your\n" +"$TERM variable set to point to a xterm definition which supports color.\n" +"Otherwise, Menuconfig will look rather bad. Menuconfig will not\n" +"display correctly in a RXVT window because rxvt displays only one\n" +"intensity of color, bright.\n" +"\n" +"Menuconfig will display larger menus on screens or xterms which are\n" +"set to display more than the standard 25 row by 80 column geometry.\n" +"In order for this to work, the \"stty size\" command must be able to\n" +"display the screen's current row and column geometry. I STRONGLY\n" +"RECOMMEND that you make sure you do NOT have the shell variables\n" +"LINES and COLUMNS exported into your environment. Some distributions\n" +"export those variables via /etc/profile. Some ncurses programs can\n" +"become confused when those variables (LINES & COLUMNS) don't reflect\n" +"the true screen size.\n" +"\n" +"Optional personality available\n" +"------------------------------\n" +"If you prefer to have all of the kernel options listed in a single\n" +"menu, rather than the default multimenu hierarchy, run the menuconfig\n" +"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n" +"\n" +"make MENUCONFIG_MODE=single_menu menuconfig\n" +"\n" +"<Enter> will then unroll the appropriate category, or enfold it if it\n" +"is already unrolled.\n" +"\n" +"Note that this mode can eventually be a little more CPU expensive\n" +"(especially with a larger number of unrolled categories) than the\n" +"default mode.\n"), +menu_instructions[] = N_( + "Arrow keys navigate the menu. " + "<Enter> selects submenus --->. " + "Highlighted letters are hotkeys. " + "Pressing <Y> includes, <N> excludes, <M> modularizes features. " + "Press <Esc><Esc> to exit, <?> for Help, </> for Search. " + "Legend: [*] built-in [ ] excluded <M> module < > module capable"), +radiolist_instructions[] = N_( + "Use the arrow keys to navigate this window or " + "press the hotkey of the item you wish to select " + "followed by the <SPACE BAR>. " + "Press <?> for additional information about this option."), +inputbox_instructions_int[] = N_( + "Please enter a decimal value. " + "Fractions will not be accepted. " + "Use the <TAB> key to move from the input field to the buttons below it."), +inputbox_instructions_hex[] = N_( + "Please enter a hexadecimal value. " + "Use the <TAB> key to move from the input field to the buttons below it."), +inputbox_instructions_string[] = N_( + "Please enter a string value. " + "Use the <TAB> key to move from the input field to the buttons below it."), +setmod_text[] = N_( + "This feature depends on another which has been configured as a module.\n" + "As a result, this feature will be built as a module."), +nohelp_text[] = N_( + "There is no help available for this kernel option.\n"), +load_config_text[] = N_( + "Enter the name of the configuration file you wish to load. " + "Accept the name shown to restore the configuration you " + "last retrieved. Leave blank to abort."), +load_config_help[] = N_( + "\n" + "For various reasons, one may wish to keep several different kernel\n" + "configurations available on a single machine.\n" + "\n" + "If you have saved a previous configuration in a file other than the\n" + "kernel's default, entering the name of the file here will allow you\n" + "to modify that configuration.\n" + "\n" + "If you are uncertain, then you have probably never used alternate\n" + "configuration files. You should therefor leave this blank to abort.\n"), +save_config_text[] = N_( + "Enter a filename to which this configuration should be saved " + "as an alternate. Leave blank to abort."), +save_config_help[] = N_( + "\n" + "For various reasons, one may wish to keep different kernel\n" + "configurations available on a single machine.\n" + "\n" + "Entering a file name here will allow you to later retrieve, modify\n" + "and use the current configuration as an alternate to whatever\n" + "configuration options you have selected at that time.\n" + "\n" + "If you are uncertain what all this means then you should probably\n" + "leave this blank.\n"), +search_help[] = N_( + "\n" + "Search for CONFIG_ symbols and display their relations.\n" + "Regular expressions are allowed.\n" + "Example: search for \"^FOO\"\n" + "Result:\n" + "-----------------------------------------------------------------\n" + "Symbol: FOO [=m]\n" + "Prompt: Foo bus is used to drive the bar HW\n" + "Defined at drivers/pci/Kconfig:47\n" + "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" + "Location:\n" + " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" + " -> PCI support (PCI [=y])\n" + " -> PCI access mode (<choice> [=y])\n" + "Selects: LIBCRC32\n" + "Selected by: BAR\n" + "-----------------------------------------------------------------\n" + "o The line 'Prompt:' shows the text used in the menu structure for\n" + " this CONFIG_ symbol\n" + "o The 'Defined at' line tell at what file / line number the symbol\n" + " is defined\n" + "o The 'Depends on:' line tell what symbols needs to be defined for\n" + " this symbol to be visible in the menu (selectable)\n" + "o The 'Location:' lines tell where in the menu structure this symbol\n" + " is located\n" + " A location followed by a [=y] indicate that this is a selectable\n" + " menu item - and current value is displayed inside brackets.\n" + "o The 'Selects:' line tell what symbol will be automatically\n" + " selected if this symbol is selected (y or m)\n" + "o The 'Selected by' line tell what symbol has selected this symbol\n" + "\n" + "Only relevant lines are shown.\n" + "\n\n" + "Search examples:\n" + "Examples: USB => find all CONFIG_ symbols containing USB\n" + " ^USB => find all CONFIG_ symbols starting with USB\n" + " USB$ => find all CONFIG_ symbols ending with USB\n" + "\n"); + +static char buf[4096], *bufptr = buf; +static char input_buf[4096]; +static char filename[PATH_MAX+1] = ".config"; +static char *args[1024], **argptr = args; +static int indent; +static struct termios ios_org; +static int rows = 0, cols = 0; +static struct menu *current_menu; +static int child_count; +static int do_resize; +static int single_menu_mode; + +static void conf(struct menu *menu); +static void conf_choice(struct menu *menu); +static void conf_string(struct menu *menu); +static void conf_load(void); +static void conf_save(void); +static void show_textbox(const char *title, const char *text, int r, int c); +static void show_helptext(const char *title, const char *text); +static void show_help(struct menu *menu); +static void show_file(const char *filename, const char *title, int r, int c); + +static void cprint_init(void); +static int cprint1(const char *fmt, ...); +static void cprint_done(void); +static int cprint(const char *fmt, ...); + +static void init_wsize(void) +{ + struct winsize ws; + char *env; + + if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) { + rows = ws.ws_row; + cols = ws.ws_col; + } + + if (!rows) { + env = getenv("LINES"); + if (env) + rows = atoi(env); + if (!rows) + rows = 24; + } + if (!cols) { + env = getenv("COLUMNS"); + if (env) + cols = atoi(env); + if (!cols) + cols = 80; + } + + if (rows < 19 || cols < 80) { + fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); + fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n")); + exit(1); + } + + rows -= 4; + cols -= 5; +} + +static void cprint_init(void) +{ + bufptr = buf; + argptr = args; + memset(args, 0, sizeof(args)); + indent = 0; + child_count = 0; + cprint("./scripts/kconfig/lxdialog/lxdialog"); + cprint("--backtitle"); + cprint(menu_backtitle); +} + +static int cprint1(const char *fmt, ...) +{ + va_list ap; + int res; + + if (!*argptr) + *argptr = bufptr; + va_start(ap, fmt); + res = vsprintf(bufptr, fmt, ap); + va_end(ap); + bufptr += res; + + return res; +} + +static void cprint_done(void) +{ + *bufptr++ = 0; + argptr++; +} + +static int cprint(const char *fmt, ...) +{ + va_list ap; + int res; + + *argptr++ = bufptr; + va_start(ap, fmt); + res = vsprintf(bufptr, fmt, ap); + va_end(ap); + bufptr += res; + *bufptr++ = 0; + + return res; +} + +static void get_prompt_str(struct gstr *r, struct property *prop) +{ + int i, j; + struct menu *submenu[8], *menu; + + str_printf(r, "Prompt: %s\n", prop->text); + str_printf(r, " Defined at %s:%d\n", prop->menu->file->name, + prop->menu->lineno); + if (!expr_is_yes(prop->visible.expr)) { + str_append(r, " Depends on: "); + expr_gstr_print(prop->visible.expr, r); + str_append(r, "\n"); + } + menu = prop->menu->parent; + for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) + submenu[i++] = menu; + if (i > 0) { + str_printf(r, " Location:\n"); + for (j = 4; --i >= 0; j += 2) { + menu = submenu[i]; + str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu)); + if (menu->sym) { + str_printf(r, " (%s [=%s])", menu->sym->name ? + menu->sym->name : "<choice>", + sym_get_string_value(menu->sym)); + } + str_append(r, "\n"); + } + } +} + +static void get_symbol_str(struct gstr *r, struct symbol *sym) +{ + bool hit; + struct property *prop; + + str_printf(r, "Symbol: %s [=%s]\n", sym->name, + sym_get_string_value(sym)); + for_all_prompts(sym, prop) + get_prompt_str(r, prop); + hit = false; + for_all_properties(sym, prop, P_SELECT) { + if (!hit) { + str_append(r, " Selects: "); + hit = true; + } else + str_printf(r, " && "); + expr_gstr_print(prop->expr, r); + } + if (hit) + str_append(r, "\n"); + if (sym->rev_dep.expr) { + str_append(r, " Selected by: "); + expr_gstr_print(sym->rev_dep.expr, r); + str_append(r, "\n"); + } + str_append(r, "\n\n"); +} + +static struct gstr get_relations_str(struct symbol **sym_arr) +{ + struct symbol *sym; + struct gstr res = str_new(); + int i; + + for (i = 0; sym_arr && (sym = sym_arr[i]); i++) + get_symbol_str(&res, sym); + if (!i) + str_append(&res, "No matches found.\n"); + return res; +} + +pid_t pid; + +static void winch_handler(int sig) +{ + if (!do_resize) { + kill(pid, SIGINT); + do_resize = 1; + } +} + +static int exec_conf(void) +{ + int pipefd[2], stat, size; + struct sigaction sa; + sigset_t sset, osset; + + sigemptyset(&sset); + sigaddset(&sset, SIGINT); + sigprocmask(SIG_BLOCK, &sset, &osset); + + signal(SIGINT, SIG_DFL); + + sa.sa_handler = winch_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sigaction(SIGWINCH, &sa, NULL); + + *argptr++ = NULL; + + pipe(pipefd); + pid = fork(); + if (pid == 0) { + sigprocmask(SIG_SETMASK, &osset, NULL); + dup2(pipefd[1], 2); + close(pipefd[0]); + close(pipefd[1]); + execv(args[0], args); + _exit(EXIT_FAILURE); + } + + close(pipefd[1]); + bufptr = input_buf; + while (1) { + size = input_buf + sizeof(input_buf) - bufptr; + size = read(pipefd[0], bufptr, size); + if (size <= 0) { + if (size < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + perror("read"); + } + break; + } + bufptr += size; + } + *bufptr++ = 0; + close(pipefd[0]); + waitpid(pid, &stat, 0); + + if (do_resize) { + init_wsize(); + do_resize = 0; + sigprocmask(SIG_SETMASK, &osset, NULL); + return -1; + } + if (WIFSIGNALED(stat)) { + printf("\finterrupted(%d)\n", WTERMSIG(stat)); + exit(1); + } +#if 0 + printf("\fexit state: %d\nexit data: '%s'\n", WEXITSTATUS(stat), input_buf); + sleep(1); +#endif + sigpending(&sset); + if (sigismember(&sset, SIGINT)) { + printf("\finterrupted\n"); + exit(1); + } + sigprocmask(SIG_SETMASK, &osset, NULL); + + return WEXITSTATUS(stat); +} + +static void search_conf(void) +{ + struct symbol **sym_arr; + int stat; + struct gstr res; + +again: + cprint_init(); + cprint("--title"); + cprint(_("Search Configuration Parameter")); + cprint("--inputbox"); + cprint(_("Enter CONFIG_ (sub)string to search for (omit CONFIG_)")); + cprint("10"); + cprint("75"); + cprint(""); + stat = exec_conf(); + if (stat < 0) + goto again; + switch (stat) { + case 0: + break; + case 1: + show_helptext(_("Search Configuration"), search_help); + goto again; + default: + return; + } + + sym_arr = sym_re_search(input_buf); + res = get_relations_str(sym_arr); + free(sym_arr); + show_textbox(_("Search Results"), str_get(&res), 0, 0); + str_free(&res); +} + +static void build_conf(struct menu *menu) +{ + struct symbol *sym; + struct property *prop; + struct menu *child; + int type, tmp, doint = 2; + tristate val; + char ch; + + if (!menu_is_visible(menu)) + return; + + sym = menu->sym; + prop = menu->prompt; + if (!sym) { + if (prop && menu != current_menu) { + const char *prompt = menu_get_prompt(menu); + switch (prop->type) { + case P_MENU: + child_count++; + cprint("m%p", menu); + + if (single_menu_mode) { + cprint1("%s%*c%s", + menu->data ? "-->" : "++>", + indent + 1, ' ', prompt); + } else + cprint1(" %*c%s --->", indent + 1, ' ', prompt); + + cprint_done(); + if (single_menu_mode && menu->data) + goto conf_childs; + return; + default: + if (prompt) { + child_count++; + cprint(":%p", menu); + cprint("---%*c%s", indent + 1, ' ', prompt); + } + } + } else + doint = 0; + goto conf_childs; + } + + type = sym_get_type(sym); + if (sym_is_choice(sym)) { + struct symbol *def_sym = sym_get_choice_value(sym); + struct menu *def_menu = NULL; + + child_count++; + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child) && child->sym == def_sym) + def_menu = child; + } + + val = sym_get_tristate_value(sym); + if (sym_is_changable(sym)) { + cprint("t%p", menu); + switch (type) { + case S_BOOLEAN: + cprint1("[%c]", val == no ? ' ' : '*'); + break; + case S_TRISTATE: + switch (val) { + case yes: ch = '*'; break; + case mod: ch = 'M'; break; + default: ch = ' '; break; + } + cprint1("<%c>", ch); + break; + } + } else { + cprint("%c%p", def_menu ? 't' : ':', menu); + cprint1(" "); + } + + cprint1("%*c%s", indent + 1, ' ', menu_get_prompt(menu)); + if (val == yes) { + if (def_menu) { + cprint1(" (%s)", menu_get_prompt(def_menu)); + cprint1(" --->"); + cprint_done(); + if (def_menu->list) { + indent += 2; + build_conf(def_menu); + indent -= 2; + } + } else + cprint_done(); + return; + } + cprint_done(); + } else { + if (menu == current_menu) { + cprint(":%p", menu); + cprint("---%*c%s", indent + 1, ' ', menu_get_prompt(menu)); + goto conf_childs; + } + child_count++; + val = sym_get_tristate_value(sym); + if (sym_is_choice_value(sym) && val == yes) { + cprint(":%p", menu); + cprint1(" "); + } else { + switch (type) { + case S_BOOLEAN: + cprint("t%p", menu); + if (sym_is_changable(sym)) + cprint1("[%c]", val == no ? ' ' : '*'); + else + cprint1("---"); + break; + case S_TRISTATE: + cprint("t%p", menu); + switch (val) { + case yes: ch = '*'; break; + case mod: ch = 'M'; break; + default: ch = ' '; break; + } + if (sym_is_changable(sym)) + cprint1("<%c>", ch); + else + cprint1("---"); + break; + default: + cprint("s%p", menu); + tmp = cprint1("(%s)", sym_get_string_value(sym)); + tmp = indent - tmp + 4; + if (tmp < 0) + tmp = 0; + cprint1("%*c%s%s", tmp, ' ', menu_get_prompt(menu), + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : " (NEW)"); + cprint_done(); + goto conf_childs; + } + } + cprint1("%*c%s%s", indent + 1, ' ', menu_get_prompt(menu), + (sym_has_value(sym) || !sym_is_changable(sym)) ? + "" : " (NEW)"); + if (menu->prompt->type == P_MENU) { + cprint1(" --->"); + cprint_done(); + return; + } + cprint_done(); + } + +conf_childs: + indent += doint; + for (child = menu->list; child; child = child->next) + build_conf(child); + indent -= doint; +} + +static void conf(struct menu *menu) +{ + struct menu *submenu; + const char *prompt = menu_get_prompt(menu); + struct symbol *sym; + char active_entry[40]; + int stat, type, i; + + unlink("lxdialog.scrltmp"); + active_entry[0] = 0; + while (1) { + cprint_init(); + cprint("--title"); + cprint("%s", prompt ? prompt : _("Main Menu")); + cprint("--menu"); + cprint(_(menu_instructions)); + cprint("%d", rows); + cprint("%d", cols); + cprint("%d", rows - 10); + cprint("%s", active_entry); + current_menu = menu; + build_conf(menu); + if (!child_count) + break; + if (menu == &rootmenu) { + cprint(":"); + cprint("--- "); + cprint("L"); + cprint(_(" Load an Alternate Configuration File")); + cprint("S"); + cprint(_(" Save Configuration to an Alternate File")); + } + stat = exec_conf(); + if (stat < 0) + continue; + + if (stat == 1 || stat == 255) + break; + + type = input_buf[0]; + if (!type) + continue; + + for (i = 0; input_buf[i] && !isspace(input_buf[i]); i++) + ; + if (i >= sizeof(active_entry)) + i = sizeof(active_entry) - 1; + input_buf[i] = 0; + strcpy(active_entry, input_buf); + + sym = NULL; + submenu = NULL; + if (sscanf(input_buf + 1, "%p", &submenu) == 1) + sym = submenu->sym; + + switch (stat) { + case 0: + switch (type) { + case 'm': + if (single_menu_mode) + submenu->data = (void *) (long) !submenu->data; + else + conf(submenu); + break; + case 't': + if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes) + conf_choice(submenu); + else if (submenu->prompt->type == P_MENU) + conf(submenu); + break; + case 's': + conf_string(submenu); + break; + case 'L': + conf_load(); + break; + case 'S': + conf_save(); + break; + } + break; + case 2: + if (sym) + show_help(submenu); + else + show_helptext("README", _(mconf_readme)); + break; + case 3: + if (type == 't') { + if (sym_set_tristate_value(sym, yes)) + break; + if (sym_set_tristate_value(sym, mod)) + show_textbox(NULL, setmod_text, 6, 74); + } + break; + case 4: + if (type == 't') + sym_set_tristate_value(sym, no); + break; + case 5: + if (type == 't') + sym_set_tristate_value(sym, mod); + break; + case 6: + if (type == 't') + sym_toggle_tristate_value(sym); + else if (type == 'm') + conf(submenu); + break; + case 7: + search_conf(); + break; + } + } +} + +static void show_textbox(const char *title, const char *text, int r, int c) +{ + int fd; + + fd = creat(".help.tmp", 0777); + write(fd, text, strlen(text)); + close(fd); + show_file(".help.tmp", title, r, c); + unlink(".help.tmp"); +} + +static void show_helptext(const char *title, const char *text) +{ + show_textbox(title, text, 0, 0); +} + +static void show_help(struct menu *menu) +{ + struct gstr help = str_new(); + struct symbol *sym = menu->sym; + + if (sym->help) + { + if (sym->name) { + str_printf(&help, "CONFIG_%s:\n\n", sym->name); + str_append(&help, _(sym->help)); + str_append(&help, "\n"); + } + } else { + str_append(&help, nohelp_text); + } + get_symbol_str(&help, sym); + show_helptext(menu_get_prompt(menu), str_get(&help)); + str_free(&help); +} + +static void show_file(const char *filename, const char *title, int r, int c) +{ + do { + cprint_init(); + if (title) { + cprint("--title"); + cprint("%s", title); + } + cprint("--textbox"); + cprint("%s", filename); + cprint("%d", r ? r : rows); + cprint("%d", c ? c : cols); + } while (exec_conf() < 0); +} + +static void conf_choice(struct menu *menu) +{ + const char *prompt = menu_get_prompt(menu); + struct menu *child; + struct symbol *active; + int stat; + + active = sym_get_choice_value(menu->sym); + while (1) { + cprint_init(); + cprint("--title"); + cprint("%s", prompt ? prompt : _("Main Menu")); + cprint("--radiolist"); + cprint(_(radiolist_instructions)); + cprint("15"); + cprint("70"); + cprint("6"); + + current_menu = menu; + for (child = menu->list; child; child = child->next) { + if (!menu_is_visible(child)) + continue; + cprint("%p", child); + cprint("%s", menu_get_prompt(child)); + if (child->sym == sym_get_choice_value(menu->sym)) + cprint("ON"); + else if (child->sym == active) + cprint("SELECTED"); + else + cprint("OFF"); + } + + stat = exec_conf(); + switch (stat) { + case 0: + if (sscanf(input_buf, "%p", &child) != 1) + break; + sym_set_tristate_value(child->sym, yes); + return; + case 1: + if (sscanf(input_buf, "%p", &child) == 1) { + show_help(child); + active = child->sym; + } else + show_help(menu); + break; + case 255: + return; + } + } +} + +static void conf_string(struct menu *menu) +{ + const char *prompt = menu_get_prompt(menu); + int stat; + + while (1) { + cprint_init(); + cprint("--title"); + cprint("%s", prompt ? prompt : _("Main Menu")); + cprint("--inputbox"); + switch (sym_get_type(menu->sym)) { + case S_INT: + cprint(_(inputbox_instructions_int)); + break; + case S_HEX: + cprint(_(inputbox_instructions_hex)); + break; + case S_STRING: + cprint(_(inputbox_instructions_string)); + break; + default: + /* panic? */; + } + cprint("10"); + cprint("75"); + cprint("%s", sym_get_string_value(menu->sym)); + stat = exec_conf(); + switch (stat) { + case 0: + if (sym_set_string_value(menu->sym, input_buf)) + return; + show_textbox(NULL, _("You have made an invalid entry."), 5, 43); + break; + case 1: + show_help(menu); + break; + case 255: + return; + } + } +} + +static void conf_load(void) +{ + int stat; + + while (1) { + cprint_init(); + cprint("--inputbox"); + cprint(load_config_text); + cprint("11"); + cprint("55"); + cprint("%s", filename); + stat = exec_conf(); + switch(stat) { + case 0: + if (!input_buf[0]) + return; + if (!conf_read(input_buf)) + return; + show_textbox(NULL, _("File does not exist!"), 5, 38); + break; + case 1: + show_helptext(_("Load Alternate Configuration"), load_config_help); + break; + case 255: + return; + } + } +} + +static void conf_save(void) +{ + int stat; + + while (1) { + cprint_init(); + cprint("--inputbox"); + cprint(save_config_text); + cprint("11"); + cprint("55"); + cprint("%s", filename); + stat = exec_conf(); + switch(stat) { + case 0: + if (!input_buf[0]) + return; + if (!conf_write(input_buf)) + return; + show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60); + break; + case 1: + show_helptext(_("Save Alternate Configuration"), save_config_help); + break; + case 255: + return; + } + } +} + +static void conf_cleanup(void) +{ + tcsetattr(1, TCSAFLUSH, &ios_org); + unlink(".help.tmp"); + unlink("lxdialog.scrltmp"); +} + +int main(int ac, char **av) +{ + struct symbol *sym; + char *mode; + int stat; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + conf_parse(av[1]); + conf_read(NULL); + + sym = sym_lookup("KERNELVERSION", 0); + sym_calc_value(sym); + sprintf(menu_backtitle, _("Linux Kernel v%s Configuration"), + sym_get_string_value(sym)); + + mode = getenv("MENUCONFIG_MODE"); + if (mode) { + if (!strcasecmp(mode, "single_menu")) + single_menu_mode = 1; + } + + tcgetattr(1, &ios_org); + atexit(conf_cleanup); + init_wsize(); + conf(&rootmenu); + + do { + cprint_init(); + cprint("--yesno"); + cprint(_("Do you wish to save your new kernel configuration?")); + cprint("5"); + cprint("60"); + stat = exec_conf(); + } while (stat < 0); + + if (stat == 0) { + if (conf_write(NULL)) { + fprintf(stderr, _("\n\n" + "Error during writing of the kernel configuration.\n" + "Your kernel configuration changes were NOT saved." + "\n\n")); + return 1; + } + printf(_("\n\n" + "*** End of Linux kernel configuration.\n" + "*** Execute 'make' to build the kernel or try 'make help'." + "\n\n")); + } else { + fprintf(stderr, _("\n\n" + "Your kernel configuration changes were NOT saved." + "\n\n")); + } + + return 0; +} diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c new file mode 100644 index 000000000..0fce20cb7 --- /dev/null +++ b/scripts/kconfig/menu.c @@ -0,0 +1,397 @@ +/* + * 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 = ¤t_entry->list; + return current_menu = current_entry; +} + +void menu_end_menu(void) +{ + last_entry_ptr = ¤t_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'\n", + 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->text = prompt; + prop->expr = expr; + prop->visible.expr = menu_check_dep(dep); + + if (prompt) { + if (current_entry->prompt) + menu_warn(current_entry, "prompt redefined\n"); + current_entry->prompt = prop; + } + + 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); +} + +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' " + "refer 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\n"); + + if (sym_is_choice(sym) && !parent->prompt) + menu_warn(parent, "choice must have a prompt\n"); + + /* 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; +} + diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc new file mode 100644 index 000000000..4590cd316 --- /dev/null +++ b/scripts/kconfig/qconf.cc @@ -0,0 +1,1426 @@ +/* + * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> + * Released under the terms of the GNU GPL v2.0. + */ + +#include <qapplication.h> +#include <qmainwindow.h> +#include <qtoolbar.h> +#include <qvbox.h> +#include <qsplitter.h> +#include <qlistview.h> +#include <qtextview.h> +#include <qlineedit.h> +#include <qmenubar.h> +#include <qmessagebox.h> +#include <qaction.h> +#include <qheader.h> +#include <qfiledialog.h> +#include <qregexp.h> + +#include <stdlib.h> + +#include "lkc.h" +#include "qconf.h" + +#include "qconf.moc" +#include "images.c" + +#ifdef _ +# undef _ +# define _ qgettext +#endif + +static QApplication *configApp; + +static inline QString qgettext(const char* str) +{ + return QString::fromLocal8Bit(gettext(str)); +} + +static inline QString qgettext(const QString& str) +{ + return QString::fromLocal8Bit(gettext(str.latin1())); +} + +ConfigSettings::ConfigSettings() + : showAll(false), showName(false), showRange(false), showData(false) +{ +} + +#if QT_VERSION >= 300 +/** + * Reads the list column settings from the application settings. + */ +void ConfigSettings::readListSettings() +{ + showAll = readBoolEntry("/kconfig/qconf/showAll", false); + showName = readBoolEntry("/kconfig/qconf/showName", false); + showRange = readBoolEntry("/kconfig/qconf/showRange", false); + showData = readBoolEntry("/kconfig/qconf/showData", false); +} + +/** + * Reads a list of integer values from the application settings. + */ +QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok) +{ + QValueList<int> result; + QStringList entryList = readListEntry(key, ok); + if (ok) { + QStringList::Iterator it; + for (it = entryList.begin(); it != entryList.end(); ++it) + result.push_back((*it).toInt()); + } + + return result; +} + +/** + * Writes a list of integer values to the application settings. + */ +bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value) +{ + QStringList stringList; + QValueList<int>::ConstIterator it; + + for (it = value.begin(); it != value.end(); ++it) + stringList.push_back(QString::number(*it)); + return writeEntry(key, stringList); +} +#endif + + +/* + * update all the children of a menu entry + * removes/adds the entries from the parent widget as necessary + * + * parent: either the menu list widget or a menu entry widget + * menu: entry to be updated + */ +template <class P> +void ConfigList::updateMenuList(P* parent, struct menu* menu) +{ + struct menu* child; + ConfigItem* item; + ConfigItem* last; + bool visible; + enum prop_type type; + + if (!menu) { + while ((item = parent->firstChild())) + delete item; + return; + } + + last = parent->firstChild(); + if (last && !last->goParent) + last = 0; + for (child = menu->list; child; child = child->next) { + item = last ? last->nextSibling() : parent->firstChild(); + type = child->prompt ? child->prompt->type : P_UNKNOWN; + + switch (mode) { + case menuMode: + if (!(child->flags & MENU_ROOT)) + goto hide; + break; + case symbolMode: + if (child->flags & MENU_ROOT) + goto hide; + break; + default: + break; + } + + visible = menu_is_visible(child); + if (showAll || visible) { + if (!item || item->menu != child) + item = new ConfigItem(parent, last, child, visible); + else + item->testUpdateMenu(visible); + + if (mode == fullMode || mode == menuMode || type != P_MENU) + updateMenuList(item, child); + else + updateMenuList(item, 0); + last = item; + continue; + } + hide: + if (item && item->menu == child) { + last = parent->firstChild(); + if (last == item) + last = 0; + else while (last->nextSibling() != item) + last = last->nextSibling(); + delete item; + } + } +} + +#if QT_VERSION >= 300 +/* + * set the new data + * TODO check the value + */ +void ConfigItem::okRename(int col) +{ + Parent::okRename(col); + sym_set_string_value(menu->sym, text(dataColIdx).latin1()); +} +#endif + +/* + * update the displayed of a menu entry + */ +void ConfigItem::updateMenu(void) +{ + ConfigList* list; + struct symbol* sym; + struct property *prop; + QString prompt; + int type; + tristate expr; + + list = listView(); + if (goParent) { + setPixmap(promptColIdx, list->menuBackPix); + prompt = ".."; + goto set_prompt; + } + + sym = menu->sym; + prop = menu->prompt; + prompt = QString::fromLocal8Bit(menu_get_prompt(menu)); + + if (prop) switch (prop->type) { + case P_MENU: + if (list->mode == singleMode || list->mode == symbolMode) { + /* a menuconfig entry is displayed differently + * depending whether it's at the view root or a child. + */ + if (sym && list->rootEntry == menu) + break; + setPixmap(promptColIdx, list->menuPix); + } else { + if (sym) + break; + setPixmap(promptColIdx, 0); + } + goto set_prompt; + case P_COMMENT: + setPixmap(promptColIdx, 0); + goto set_prompt; + default: + ; + } + if (!sym) + goto set_prompt; + + setText(nameColIdx, QString::fromLocal8Bit(sym->name)); + + type = sym_get_type(sym); + switch (type) { + case S_BOOLEAN: + case S_TRISTATE: + char ch; + + if (!sym_is_changable(sym) && !list->showAll) { + setPixmap(promptColIdx, 0); + setText(noColIdx, QString::null); + setText(modColIdx, QString::null); + setText(yesColIdx, QString::null); + break; + } + expr = sym_get_tristate_value(sym); + switch (expr) { + case yes: + if (sym_is_choice_value(sym) && type == S_BOOLEAN) + setPixmap(promptColIdx, list->choiceYesPix); + else + setPixmap(promptColIdx, list->symbolYesPix); + setText(yesColIdx, "Y"); + ch = 'Y'; + break; + case mod: + setPixmap(promptColIdx, list->symbolModPix); + setText(modColIdx, "M"); + ch = 'M'; + break; + default: + if (sym_is_choice_value(sym) && type == S_BOOLEAN) + setPixmap(promptColIdx, list->choiceNoPix); + else + setPixmap(promptColIdx, list->symbolNoPix); + setText(noColIdx, "N"); + ch = 'N'; + break; + } + if (expr != no) + setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0); + if (expr != mod) + setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0); + if (expr != yes) + setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0); + + setText(dataColIdx, QChar(ch)); + break; + case S_INT: + case S_HEX: + case S_STRING: + const char* data; + + data = sym_get_string_value(sym); + +#if QT_VERSION >= 300 + int i = list->mapIdx(dataColIdx); + if (i >= 0) + setRenameEnabled(i, TRUE); +#endif + setText(dataColIdx, data); + if (type == S_STRING) + prompt = QString("%1: %2").arg(prompt).arg(data); + else + prompt = QString("(%2) %1").arg(prompt).arg(data); + break; + } + if (!sym_has_value(sym) && visible) + prompt += " (NEW)"; +set_prompt: + setText(promptColIdx, prompt); +} + +void ConfigItem::testUpdateMenu(bool v) +{ + ConfigItem* i; + + visible = v; + if (!menu) + return; + + sym_calc_value(menu->sym); + if (menu->flags & MENU_CHANGED) { + /* the menu entry changed, so update all list items */ + menu->flags &= ~MENU_CHANGED; + for (i = (ConfigItem*)menu->data; i; i = i->nextItem) + i->updateMenu(); + } else if (listView()->updateAll) + updateMenu(); +} + +void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align) +{ + ConfigList* list = listView(); + + if (visible) { + if (isSelected() && !list->hasFocus() && list->mode == menuMode) + Parent::paintCell(p, list->inactivedColorGroup, column, width, align); + else + Parent::paintCell(p, cg, column, width, align); + } else + Parent::paintCell(p, list->disabledColorGroup, column, width, align); +} + +/* + * construct a menu entry + */ +void ConfigItem::init(void) +{ + if (menu) { + ConfigList* list = listView(); + nextItem = (ConfigItem*)menu->data; + menu->data = this; + + if (list->mode != fullMode) + setOpen(TRUE); + sym_calc_value(menu->sym); + } + updateMenu(); +} + +/* + * destruct a menu entry + */ +ConfigItem::~ConfigItem(void) +{ + if (menu) { + ConfigItem** ip = (ConfigItem**)&menu->data; + for (; *ip; ip = &(*ip)->nextItem) { + if (*ip == this) { + *ip = nextItem; + break; + } + } + } +} + +void ConfigLineEdit::show(ConfigItem* i) +{ + item = i; + if (sym_get_string_value(item->menu->sym)) + setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym))); + else + setText(QString::null); + Parent::show(); + setFocus(); +} + +void ConfigLineEdit::keyPressEvent(QKeyEvent* e) +{ + switch (e->key()) { + case Key_Escape: + break; + case Key_Return: + case Key_Enter: + sym_set_string_value(item->menu->sym, text().latin1()); + parent()->updateList(item); + break; + default: + Parent::keyPressEvent(e); + return; + } + e->accept(); + parent()->list->setFocus(); + hide(); +} + +ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv, ConfigSettings* configSettings) + : Parent(p), cview(cv), + updateAll(false), + symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), + choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), + menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void), + showAll(false), showName(false), showRange(false), showData(false), + rootEntry(0) +{ + int i; + + setSorting(-1); + setRootIsDecorated(TRUE); + disabledColorGroup = palette().active(); + disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text()); + inactivedColorGroup = palette().active(); + inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight()); + + connect(this, SIGNAL(selectionChanged(void)), + SLOT(updateSelection(void))); + + if (configSettings) { + showAll = configSettings->showAll; + showName = configSettings->showName; + showRange = configSettings->showRange; + showData = configSettings->showData; + } + + for (i = 0; i < colNr; i++) + colMap[i] = colRevMap[i] = -1; + addColumn(promptColIdx, "Option"); + + reinit(); +} + +void ConfigList::reinit(void) +{ + removeColumn(dataColIdx); + removeColumn(yesColIdx); + removeColumn(modColIdx); + removeColumn(noColIdx); + removeColumn(nameColIdx); + + if (showName) + addColumn(nameColIdx, "Name"); + if (showRange) { + addColumn(noColIdx, "N"); + addColumn(modColIdx, "M"); + addColumn(yesColIdx, "Y"); + } + if (showData) + addColumn(dataColIdx, "Value"); + + updateListAll(); +} + +void ConfigList::updateSelection(void) +{ + struct menu *menu; + enum prop_type type; + + ConfigItem* item = (ConfigItem*)selectedItem(); + if (!item) + return; + + cview->setHelp(item); + + menu = item->menu; + if (!menu) + return; + type = menu->prompt ? menu->prompt->type : P_UNKNOWN; + if (mode == menuMode && type == P_MENU) + emit menuSelected(menu); +} + +void ConfigList::updateList(ConfigItem* item) +{ + ConfigItem* last = 0; + + if (!rootEntry) + goto update; + + if (rootEntry != &rootmenu && (mode == singleMode || + (mode == symbolMode && rootEntry->parent != &rootmenu))) { + item = firstChild(); + if (!item) + item = new ConfigItem(this, 0, true); + last = item; + } + if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) && + rootEntry->sym && rootEntry->prompt) { + item = last ? last->nextSibling() : firstChild(); + if (!item) + item = new ConfigItem(this, last, rootEntry, true); + else + item->testUpdateMenu(true); + + updateMenuList(item, rootEntry); + triggerUpdate(); + return; + } +update: + updateMenuList(this, rootEntry); + triggerUpdate(); +} + +void ConfigList::setAllOpen(bool open) +{ + QListViewItemIterator it(this); + + for (; it.current(); it++) + it.current()->setOpen(open); +} + +void ConfigList::setValue(ConfigItem* item, tristate val) +{ + struct symbol* sym; + int type; + tristate oldval; + + sym = item->menu ? item->menu->sym : 0; + if (!sym) + return; + + type = sym_get_type(sym); + switch (type) { + case S_BOOLEAN: + case S_TRISTATE: + oldval = sym_get_tristate_value(sym); + + if (!sym_set_tristate_value(sym, val)) + return; + if (oldval == no && item->menu->list) + item->setOpen(TRUE); + parent()->updateList(item); + break; + } +} + +void ConfigList::changeValue(ConfigItem* item) +{ + struct symbol* sym; + struct menu* menu; + int type, oldexpr, newexpr; + + menu = item->menu; + if (!menu) + return; + sym = menu->sym; + if (!sym) { + if (item->menu->list) + item->setOpen(!item->isOpen()); + return; + } + + type = sym_get_type(sym); + switch (type) { + case S_BOOLEAN: + case S_TRISTATE: + oldexpr = sym_get_tristate_value(sym); + newexpr = sym_toggle_tristate_value(sym); + if (item->menu->list) { + if (oldexpr == newexpr) + item->setOpen(!item->isOpen()); + else if (oldexpr == no) + item->setOpen(TRUE); + } + if (oldexpr != newexpr) + parent()->updateList(item); + break; + case S_INT: + case S_HEX: + case S_STRING: +#if QT_VERSION >= 300 + if (colMap[dataColIdx] >= 0) + item->startRename(colMap[dataColIdx]); + else +#endif + parent()->lineEdit->show(item); + break; + } +} + +void ConfigList::setRootMenu(struct menu *menu) +{ + enum prop_type type; + + if (rootEntry == menu) + return; + type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN; + if (type != P_MENU) + return; + updateMenuList(this, 0); + rootEntry = menu; + updateListAll(); + setSelected(currentItem(), hasFocus()); +} + +void ConfigList::setParentMenu(void) +{ + ConfigItem* item; + struct menu *oldroot; + + oldroot = rootEntry; + if (rootEntry == &rootmenu) + return; + setRootMenu(menu_get_parent_menu(rootEntry->parent)); + + QListViewItemIterator it(this); + for (; (item = (ConfigItem*)it.current()); it++) { + if (item->menu == oldroot) { + setCurrentItem(item); + ensureItemVisible(item); + break; + } + } +} + +void ConfigList::keyPressEvent(QKeyEvent* ev) +{ + QListViewItem* i = currentItem(); + ConfigItem* item; + struct menu *menu; + enum prop_type type; + + if (ev->key() == Key_Escape && mode != fullMode) { + emit parentSelected(); + ev->accept(); + return; + } + + if (!i) { + Parent::keyPressEvent(ev); + return; + } + item = (ConfigItem*)i; + + switch (ev->key()) { + case Key_Return: + case Key_Enter: + if (item->goParent) { + emit parentSelected(); + break; + } + menu = item->menu; + if (!menu) + break; + type = menu->prompt ? menu->prompt->type : P_UNKNOWN; + if (type == P_MENU && rootEntry != menu && + mode != fullMode && mode != menuMode) { + emit menuSelected(menu); + break; + } + case Key_Space: + changeValue(item); + break; + case Key_N: + setValue(item, no); + break; + case Key_M: + setValue(item, mod); + break; + case Key_Y: + setValue(item, yes); + break; + default: + Parent::keyPressEvent(ev); + return; + } + ev->accept(); +} + +void ConfigList::contentsMousePressEvent(QMouseEvent* e) +{ + //QPoint p(contentsToViewport(e->pos())); + //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y()); + Parent::contentsMousePressEvent(e); +} + +void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e) +{ + QPoint p(contentsToViewport(e->pos())); + ConfigItem* item = (ConfigItem*)itemAt(p); + struct menu *menu; + enum prop_type ptype; + const QPixmap* pm; + int idx, x; + + if (!item) + goto skip; + + menu = item->menu; + x = header()->offset() + p.x(); + idx = colRevMap[header()->sectionAt(x)]; + switch (idx) { + case promptColIdx: + pm = item->pixmap(promptColIdx); + if (pm) { + int off = header()->sectionPos(0) + itemMargin() + + treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0)); + if (x >= off && x < off + pm->width()) { + if (item->goParent) { + emit parentSelected(); + break; + } else if (!menu) + break; + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + if (ptype == P_MENU && rootEntry != menu && + mode != fullMode && mode != menuMode) + emit menuSelected(menu); + else + changeValue(item); + } + } + break; + case noColIdx: + setValue(item, no); + break; + case modColIdx: + setValue(item, mod); + break; + case yesColIdx: + setValue(item, yes); + break; + case dataColIdx: + changeValue(item); + break; + } + +skip: + //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y()); + Parent::contentsMouseReleaseEvent(e); +} + +void ConfigList::contentsMouseMoveEvent(QMouseEvent* e) +{ + //QPoint p(contentsToViewport(e->pos())); + //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y()); + Parent::contentsMouseMoveEvent(e); +} + +void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e) +{ + QPoint p(contentsToViewport(e->pos())); + ConfigItem* item = (ConfigItem*)itemAt(p); + struct menu *menu; + enum prop_type ptype; + + if (!item) + goto skip; + if (item->goParent) { + emit parentSelected(); + goto skip; + } + menu = item->menu; + if (!menu) + goto skip; + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + if (ptype == P_MENU && (mode == singleMode || mode == symbolMode)) + emit menuSelected(menu); + else if (menu->sym) + changeValue(item); + +skip: + //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y()); + Parent::contentsMouseDoubleClickEvent(e); +} + +void ConfigList::focusInEvent(QFocusEvent *e) +{ + Parent::focusInEvent(e); + + QListViewItem* item = currentItem(); + if (!item) + return; + + setSelected(item, TRUE); + emit gotFocus(); +} + +ConfigView* ConfigView::viewList; + +ConfigView::ConfigView(QWidget* parent, ConfigMainWindow* cview, + ConfigSettings *configSettings) + : Parent(parent) +{ + list = new ConfigList(this, cview, configSettings); + lineEdit = new ConfigLineEdit(this); + lineEdit->hide(); + + this->nextView = viewList; + viewList = this; +} + +ConfigView::~ConfigView(void) +{ + ConfigView** vp; + + for (vp = &viewList; *vp; vp = &(*vp)->nextView) { + if (*vp == this) { + *vp = nextView; + break; + } + } +} + +void ConfigView::updateList(ConfigItem* item) +{ + ConfigView* v; + + for (v = viewList; v; v = v->nextView) + v->list->updateList(item); +} + +void ConfigView::updateListAll(void) +{ + ConfigView* v; + + for (v = viewList; v; v = v->nextView) + v->list->updateListAll(); +} + +/* + * Construct the complete config widget + */ +ConfigMainWindow::ConfigMainWindow(void) +{ + QMenuBar* menu; + bool ok; + int x, y, width, height; + + QWidget *d = configApp->desktop(); + + ConfigSettings* configSettings = new ConfigSettings(); +#if QT_VERSION >= 300 + width = configSettings->readNumEntry("/kconfig/qconf/window width", d->width() - 64); + height = configSettings->readNumEntry("/kconfig/qconf/window height", d->height() - 64); + resize(width, height); + x = configSettings->readNumEntry("/kconfig/qconf/window x", 0, &ok); + if (ok) + y = configSettings->readNumEntry("/kconfig/qconf/window y", 0, &ok); + if (ok) + move(x, y); + showDebug = configSettings->readBoolEntry("/kconfig/qconf/showDebug", false); + + // read list settings into configSettings, will be used later for ConfigList setup + configSettings->readListSettings(); +#else + width = d->width() - 64; + height = d->height() - 64; + resize(width, height); + showDebug = false; +#endif + + split1 = new QSplitter(this); + split1->setOrientation(QSplitter::Horizontal); + setCentralWidget(split1); + + menuView = new ConfigView(split1, this, configSettings); + menuList = menuView->list; + + split2 = new QSplitter(split1); + split2->setOrientation(QSplitter::Vertical); + + // create config tree + configView = new ConfigView(split2, this, configSettings); + configList = configView->list; + + helpText = new QTextView(split2); + helpText->setTextFormat(Qt::RichText); + + setTabOrder(configList, helpText); + configList->setFocus(); + + menu = menuBar(); + toolBar = new QToolBar("Tools", this); + + backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this); + connect(backAction, SIGNAL(activated()), SLOT(goBack())); + backAction->setEnabled(FALSE); + QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this); + connect(quitAction, SIGNAL(activated()), SLOT(close())); + QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this); + connect(loadAction, SIGNAL(activated()), SLOT(loadConfig())); + QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this); + connect(saveAction, SIGNAL(activated()), SLOT(saveConfig())); + QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this); + connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs())); + QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this); + connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView())); + QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this); + connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView())); + QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this); + connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView())); + + QAction *showNameAction = new QAction(NULL, "Show Name", 0, this); + showNameAction->setToggleAction(TRUE); + showNameAction->setOn(configList->showName); + connect(showNameAction, SIGNAL(toggled(bool)), SLOT(setShowName(bool))); + QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this); + showRangeAction->setToggleAction(TRUE); + showRangeAction->setOn(configList->showRange); + connect(showRangeAction, SIGNAL(toggled(bool)), SLOT(setShowRange(bool))); + QAction *showDataAction = new QAction(NULL, "Show Data", 0, this); + showDataAction->setToggleAction(TRUE); + showDataAction->setOn(configList->showData); + connect(showDataAction, SIGNAL(toggled(bool)), SLOT(setShowData(bool))); + QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this); + showAllAction->setToggleAction(TRUE); + showAllAction->setOn(configList->showAll); + connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool))); + QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this); + showDebugAction->setToggleAction(TRUE); + showDebugAction->setOn(showDebug); + connect(showDebugAction, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); + + QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this); + connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro())); + QAction *showAboutAction = new QAction(NULL, "About", 0, this); + connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout())); + + // init tool bar + backAction->addTo(toolBar); + toolBar->addSeparator(); + loadAction->addTo(toolBar); + saveAction->addTo(toolBar); + toolBar->addSeparator(); + singleViewAction->addTo(toolBar); + splitViewAction->addTo(toolBar); + fullViewAction->addTo(toolBar); + + // create config menu + QPopupMenu* config = new QPopupMenu(this); + menu->insertItem("&File", config); + loadAction->addTo(config); + saveAction->addTo(config); + saveAsAction->addTo(config); + config->insertSeparator(); + quitAction->addTo(config); + + // create options menu + QPopupMenu* optionMenu = new QPopupMenu(this); + menu->insertItem("&Option", optionMenu); + showNameAction->addTo(optionMenu); + showRangeAction->addTo(optionMenu); + showDataAction->addTo(optionMenu); + optionMenu->insertSeparator(); + showAllAction->addTo(optionMenu); + showDebugAction->addTo(optionMenu); + + // create help menu + QPopupMenu* helpMenu = new QPopupMenu(this); + menu->insertSeparator(); + menu->insertItem("&Help", helpMenu); + showIntroAction->addTo(helpMenu); + showAboutAction->addTo(helpMenu); + + connect(configList, SIGNAL(menuSelected(struct menu *)), + SLOT(changeMenu(struct menu *))); + connect(configList, SIGNAL(parentSelected()), + SLOT(goBack())); + connect(menuList, SIGNAL(menuSelected(struct menu *)), + SLOT(changeMenu(struct menu *))); + + connect(configList, SIGNAL(gotFocus(void)), + SLOT(listFocusChanged(void))); + connect(menuList, SIGNAL(gotFocus(void)), + SLOT(listFocusChanged(void))); + +#if QT_VERSION >= 300 + QString listMode = configSettings->readEntry("/kconfig/qconf/listMode", "symbol"); + if (listMode == "single") + showSingleView(); + else if (listMode == "full") + showFullView(); + else /*if (listMode == "split")*/ + showSplitView(); + + // UI setup done, restore splitter positions + QValueList<int> sizes = configSettings->readSizes("/kconfig/qconf/split1", &ok); + if (ok) + split1->setSizes(sizes); + + sizes = configSettings->readSizes("/kconfig/qconf/split2", &ok); + if (ok) + split2->setSizes(sizes); +#else + showSplitView(); +#endif + delete configSettings; +} + +static QString print_filter(const QString &str) +{ + QRegExp re("[<>&\"\\n]"); + QString res = str; + for (int i = 0; (i = res.find(re, i)) >= 0;) { + switch (res[i].latin1()) { + case '<': + res.replace(i, 1, "<"); + i += 4; + break; + case '>': + res.replace(i, 1, ">"); + i += 4; + break; + case '&': + res.replace(i, 1, "&"); + i += 5; + break; + case '"': + res.replace(i, 1, """); + i += 6; + break; + case '\n': + res.replace(i, 1, "<br>"); + i += 4; + break; + } + } + return res; +} + +static void expr_print_help(void *data, const char *str) +{ + reinterpret_cast<QString*>(data)->append(print_filter(str)); +} + +/* + * display a new help entry as soon as a new menu entry is selected + */ +void ConfigMainWindow::setHelp(QListViewItem* item) +{ + struct symbol* sym; + struct menu* menu = 0; + + configList->parent()->lineEdit->hide(); + if (item) + menu = ((ConfigItem*)item)->menu; + if (!menu) { + helpText->setText(QString::null); + return; + } + + QString head, debug, help; + menu = ((ConfigItem*)item)->menu; + sym = menu->sym; + if (sym) { + if (menu->prompt) { + head += "<big><b>"; + head += print_filter(_(menu->prompt->text)); + head += "</b></big>"; + if (sym->name) { + head += " ("; + head += print_filter(_(sym->name)); + head += ")"; + } + } else if (sym->name) { + head += "<big><b>"; + head += print_filter(_(sym->name)); + head += "</b></big>"; + } + head += "<br><br>"; + + if (showDebug) { + debug += "type: "; + debug += print_filter(sym_type_name(sym->type)); + if (sym_is_choice(sym)) + debug += " (choice)"; + debug += "<br>"; + if (sym->rev_dep.expr) { + debug += "reverse dep: "; + expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE); + debug += "<br>"; + } + for (struct property *prop = sym->prop; prop; prop = prop->next) { + switch (prop->type) { + case P_PROMPT: + case P_MENU: + debug += "prompt: "; + debug += print_filter(_(prop->text)); + debug += "<br>"; + break; + case P_DEFAULT: + debug += "default: "; + expr_print(prop->expr, expr_print_help, &debug, E_NONE); + debug += "<br>"; + break; + case P_CHOICE: + if (sym_is_choice(sym)) { + debug += "choice: "; + expr_print(prop->expr, expr_print_help, &debug, E_NONE); + debug += "<br>"; + } + break; + case P_SELECT: + debug += "select: "; + expr_print(prop->expr, expr_print_help, &debug, E_NONE); + debug += "<br>"; + break; + case P_RANGE: + debug += "range: "; + expr_print(prop->expr, expr_print_help, &debug, E_NONE); + debug += "<br>"; + break; + default: + debug += "unknown property: "; + debug += prop_get_type_name(prop->type); + debug += "<br>"; + } + if (prop->visible.expr) { + debug += "    dep: "; + expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); + debug += "<br>"; + } + } + debug += "<br>"; + } + + help = print_filter(_(sym->help)); + } else if (menu->prompt) { + head += "<big><b>"; + head += print_filter(_(menu->prompt->text)); + head += "</b></big><br><br>"; + if (showDebug) { + if (menu->prompt->visible.expr) { + debug += "  dep: "; + expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE); + debug += "<br><br>"; + } + } + } + if (showDebug) + debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno); + helpText->setText(head + debug + help); +} + +void ConfigMainWindow::loadConfig(void) +{ + QString s = QFileDialog::getOpenFileName(".config", NULL, this); + if (s.isNull()) + return; + if (conf_read(QFile::encodeName(s))) + QMessageBox::information(this, "qconf", "Unable to load configuration!"); + ConfigView::updateListAll(); +} + +void ConfigMainWindow::saveConfig(void) +{ + if (conf_write(NULL)) + QMessageBox::information(this, "qconf", "Unable to save configuration!"); +} + +void ConfigMainWindow::saveConfigAs(void) +{ + QString s = QFileDialog::getSaveFileName(".config", NULL, this); + if (s.isNull()) + return; + if (conf_write(QFile::encodeName(s))) + QMessageBox::information(this, "qconf", "Unable to save configuration!"); +} + +void ConfigMainWindow::changeMenu(struct menu *menu) +{ + configList->setRootMenu(menu); + backAction->setEnabled(TRUE); +} + +void ConfigMainWindow::listFocusChanged(void) +{ + if (menuList->hasFocus()) { + if (menuList->mode == menuMode) + configList->clearSelection(); + setHelp(menuList->selectedItem()); + } else if (configList->hasFocus()) { + setHelp(configList->selectedItem()); + } +} + +void ConfigMainWindow::goBack(void) +{ + ConfigItem* item; + + configList->setParentMenu(); + if (configList->rootEntry == &rootmenu) + backAction->setEnabled(FALSE); + item = (ConfigItem*)menuList->selectedItem(); + while (item) { + if (item->menu == configList->rootEntry) { + menuList->setSelected(item, TRUE); + break; + } + item = (ConfigItem*)item->parent(); + } +} + +void ConfigMainWindow::showSingleView(void) +{ + menuView->hide(); + menuList->setRootMenu(0); + configList->mode = singleMode; + if (configList->rootEntry == &rootmenu) + configList->updateListAll(); + else + configList->setRootMenu(&rootmenu); + configList->setAllOpen(TRUE); + configList->setFocus(); +} + +void ConfigMainWindow::showSplitView(void) +{ + configList->mode = symbolMode; + if (configList->rootEntry == &rootmenu) + configList->updateListAll(); + else + configList->setRootMenu(&rootmenu); + configList->setAllOpen(TRUE); + configApp->processEvents(); + menuList->mode = menuMode; + menuList->setRootMenu(&rootmenu); + menuList->setAllOpen(TRUE); + menuView->show(); + menuList->setFocus(); +} + +void ConfigMainWindow::showFullView(void) +{ + menuView->hide(); + menuList->setRootMenu(0); + configList->mode = fullMode; + if (configList->rootEntry == &rootmenu) + configList->updateListAll(); + else + configList->setRootMenu(&rootmenu); + configList->setAllOpen(FALSE); + configList->setFocus(); +} + +void ConfigMainWindow::setShowAll(bool b) +{ + if (configList->showAll == b) + return; + configList->showAll = b; + configList->updateListAll(); + menuList->showAll = b; + menuList->updateListAll(); +} + +void ConfigMainWindow::setShowDebug(bool b) +{ + if (showDebug == b) + return; + showDebug = b; +} + +void ConfigMainWindow::setShowName(bool b) +{ + if (configList->showName == b) + return; + configList->showName = b; + configList->reinit(); + menuList->showName = b; + menuList->reinit(); +} + +void ConfigMainWindow::setShowRange(bool b) +{ + if (configList->showRange == b) + return; + configList->showRange = b; + configList->reinit(); + menuList->showRange = b; + menuList->reinit(); +} + +void ConfigMainWindow::setShowData(bool b) +{ + if (configList->showData == b) + return; + configList->showData = b; + configList->reinit(); + menuList->showData = b; + menuList->reinit(); +} + +/* + * ask for saving configuration before quitting + * TODO ask only when something changed + */ +void ConfigMainWindow::closeEvent(QCloseEvent* e) +{ + if (!sym_change_count) { + e->accept(); + return; + } + QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning, + QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); + mb.setButtonText(QMessageBox::Yes, "&Save Changes"); + mb.setButtonText(QMessageBox::No, "&Discard Changes"); + mb.setButtonText(QMessageBox::Cancel, "Cancel Exit"); + switch (mb.exec()) { + case QMessageBox::Yes: + conf_write(NULL); + case QMessageBox::No: + e->accept(); + break; + case QMessageBox::Cancel: + e->ignore(); + break; + } +} + +void ConfigMainWindow::showIntro(void) +{ + static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n" + "For each option, a blank box indicates the feature is disabled, a check\n" + "indicates it is enabled, and a dot indicates that it is to be compiled\n" + "as a module. Clicking on the box will cycle through the three states.\n\n" + "If you do not see an option (e.g., a device driver) that you believe\n" + "should be present, try turning on Show All Options under the Options menu.\n" + "Although there is no cross reference yet to help you figure out what other\n" + "options must be enabled to support the option you are interested in, you can\n" + "still view the help of a grayed-out option.\n\n" + "Toggling Show Debug Info under the Options menu will show the dependencies,\n" + "which you can then match by examining other options.\n\n"; + + QMessageBox::information(this, "qconf", str); +} + +void ConfigMainWindow::showAbout(void) +{ + static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n" + "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"; + + QMessageBox::information(this, "qconf", str); +} + +void ConfigMainWindow::saveSettings(void) +{ +#if QT_VERSION >= 300 + ConfigSettings *configSettings = new ConfigSettings; + configSettings->writeEntry("/kconfig/qconf/window x", pos().x()); + configSettings->writeEntry("/kconfig/qconf/window y", pos().y()); + configSettings->writeEntry("/kconfig/qconf/window width", size().width()); + configSettings->writeEntry("/kconfig/qconf/window height", size().height()); + configSettings->writeEntry("/kconfig/qconf/showName", configList->showName); + configSettings->writeEntry("/kconfig/qconf/showRange", configList->showRange); + configSettings->writeEntry("/kconfig/qconf/showData", configList->showData); + configSettings->writeEntry("/kconfig/qconf/showAll", configList->showAll); + configSettings->writeEntry("/kconfig/qconf/showDebug", showDebug); + + QString entry; + switch(configList->mode) { + case singleMode : + entry = "single"; + break; + + case symbolMode : + entry = "split"; + break; + + case fullMode : + entry = "full"; + break; + } + configSettings->writeEntry("/kconfig/qconf/listMode", entry); + + configSettings->writeSizes("/kconfig/qconf/split1", split1->sizes()); + configSettings->writeSizes("/kconfig/qconf/split2", split2->sizes()); + + delete configSettings; +#endif +} + +void fixup_rootmenu(struct menu *menu) +{ + struct menu *child; + static int menu_cnt = 0; + + menu->flags |= MENU_ROOT; + for (child = menu->list; child; child = child->next) { + if (child->prompt && child->prompt->type == P_MENU) { + menu_cnt++; + fixup_rootmenu(child); + menu_cnt--; + } else if (!menu_cnt) + fixup_rootmenu(child); + } +} + +static const char *progname; + +static void usage(void) +{ + printf("%s <config>\n", progname); + exit(0); +} + +int main(int ac, char** av) +{ + ConfigMainWindow* v; + const char *name; + + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + +#ifndef LKC_DIRECT_LINK + kconfig_load(); +#endif + + progname = av[0]; + configApp = new QApplication(ac, av); + if (ac > 1 && av[1][0] == '-') { + switch (av[1][1]) { + case 'h': + case '?': + usage(); + } + name = av[2]; + } else + name = av[1]; + if (!name) + usage(); + + conf_parse(name); + fixup_rootmenu(&rootmenu); + conf_read(NULL); + //zconfdump(stdout); + + v = new ConfigMainWindow(); + + //zconfdump(stdout); + v->show(); + configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); + configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings())); + configApp->exec(); + + return 0; +} diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h new file mode 100644 index 000000000..e52f3e90b --- /dev/null +++ b/scripts/kconfig/qconf.h @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> + * Released under the terms of the GNU GPL v2.0. + */ + +#include <qlistview.h> +#if QT_VERSION >= 300 +#include <qsettings.h> +#else +class QSettings { }; +#endif + +class ConfigList; +class ConfigItem; +class ConfigLineEdit; +class ConfigMainWindow; + + +class ConfigSettings : public QSettings { +public: + ConfigSettings(); + +#if QT_VERSION >= 300 + void readListSettings(); + QValueList<int> readSizes(const QString& key, bool *ok); + bool writeSizes(const QString& key, const QValueList<int>& value); +#endif + + bool showAll; + bool showName; + bool showRange; + bool showData; +}; + +class ConfigView : public QVBox { + Q_OBJECT + typedef class QVBox Parent; +public: + ConfigView(QWidget* parent, ConfigMainWindow* cview, ConfigSettings* configSettings); + ~ConfigView(void); + static void updateList(ConfigItem* item); + static void updateListAll(void); + +public: + ConfigList* list; + ConfigLineEdit* lineEdit; + + static ConfigView* viewList; + ConfigView* nextView; +}; + +enum colIdx { + promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr +}; +enum listMode { + singleMode, menuMode, symbolMode, fullMode +}; + +class ConfigList : public QListView { + Q_OBJECT + typedef class QListView Parent; +public: + ConfigList(ConfigView* p, ConfigMainWindow* cview, ConfigSettings *configSettings); + void reinit(void); + ConfigView* parent(void) const + { + return (ConfigView*)Parent::parent(); + } + +protected: + ConfigMainWindow* cview; + + void keyPressEvent(QKeyEvent *e); + void contentsMousePressEvent(QMouseEvent *e); + void contentsMouseReleaseEvent(QMouseEvent *e); + void contentsMouseMoveEvent(QMouseEvent *e); + void contentsMouseDoubleClickEvent(QMouseEvent *e); + void focusInEvent(QFocusEvent *e); +public slots: + void setRootMenu(struct menu *menu); + + void updateList(ConfigItem *item); + void setValue(ConfigItem* item, tristate val); + void changeValue(ConfigItem* item); + void updateSelection(void); +signals: + void menuSelected(struct menu *menu); + void parentSelected(void); + void gotFocus(void); + +public: + void updateListAll(void) + { + updateAll = true; + updateList(NULL); + updateAll = false; + } + ConfigList* listView() + { + return this; + } + ConfigItem* firstChild() const + { + return (ConfigItem *)Parent::firstChild(); + } + int mapIdx(colIdx idx) + { + return colMap[idx]; + } + void addColumn(colIdx idx, const QString& label) + { + colMap[idx] = Parent::addColumn(label); + colRevMap[colMap[idx]] = idx; + } + void removeColumn(colIdx idx) + { + int col = colMap[idx]; + if (col >= 0) { + Parent::removeColumn(col); + colRevMap[col] = colMap[idx] = -1; + } + } + void setAllOpen(bool open); + void setParentMenu(void); + + template <class P> + void updateMenuList(P*, struct menu*); + + bool updateAll; + + QPixmap symbolYesPix, symbolModPix, symbolNoPix; + QPixmap choiceYesPix, choiceNoPix; + QPixmap menuPix, menuInvPix, menuBackPix, voidPix; + + bool showAll, showName, showRange, showData; + enum listMode mode; + struct menu *rootEntry; + QColorGroup disabledColorGroup; + QColorGroup inactivedColorGroup; + +private: + int colMap[colNr]; + int colRevMap[colNr]; +}; + +class ConfigItem : public QListViewItem { + typedef class QListViewItem Parent; +public: + ConfigItem(QListView *parent, ConfigItem *after, struct menu *m, bool v) + : Parent(parent, after), menu(m), visible(v), goParent(false) + { + init(); + } + ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v) + : Parent(parent, after), menu(m), visible(v), goParent(false) + { + init(); + } + ConfigItem(QListView *parent, ConfigItem *after, bool v) + : Parent(parent, after), menu(0), visible(v), goParent(true) + { + init(); + } + ~ConfigItem(void); + void init(void); +#if QT_VERSION >= 300 + void okRename(int col); +#endif + void updateMenu(void); + void testUpdateMenu(bool v); + ConfigList* listView() const + { + return (ConfigList*)Parent::listView(); + } + ConfigItem* firstChild() const + { + return (ConfigItem *)Parent::firstChild(); + } + ConfigItem* nextSibling() const + { + return (ConfigItem *)Parent::nextSibling(); + } + void setText(colIdx idx, const QString& text) + { + Parent::setText(listView()->mapIdx(idx), text); + } + QString text(colIdx idx) const + { + return Parent::text(listView()->mapIdx(idx)); + } + void setPixmap(colIdx idx, const QPixmap& pm) + { + Parent::setPixmap(listView()->mapIdx(idx), pm); + } + const QPixmap* pixmap(colIdx idx) const + { + return Parent::pixmap(listView()->mapIdx(idx)); + } + void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align); + + ConfigItem* nextItem; + struct menu *menu; + bool visible; + bool goParent; +}; + +class ConfigLineEdit : public QLineEdit { + Q_OBJECT + typedef class QLineEdit Parent; +public: + ConfigLineEdit(ConfigView* parent) + : Parent(parent) + { } + ConfigView* parent(void) const + { + return (ConfigView*)Parent::parent(); + } + void show(ConfigItem *i); + void keyPressEvent(QKeyEvent *e); + +public: + ConfigItem *item; +}; + +class ConfigMainWindow : public QMainWindow { + Q_OBJECT +public: + ConfigMainWindow(void); +public slots: + void setHelp(QListViewItem* item); + void changeMenu(struct menu *); + void listFocusChanged(void); + void goBack(void); + void loadConfig(void); + void saveConfig(void); + void saveConfigAs(void); + void showSingleView(void); + void showSplitView(void); + void showFullView(void); + void setShowAll(bool); + void setShowDebug(bool); + void setShowRange(bool); + void setShowName(bool); + void setShowData(bool); + void showIntro(void); + void showAbout(void); + void saveSettings(void); + +protected: + void closeEvent(QCloseEvent *e); + + ConfigView *menuView; + ConfigList *menuList; + ConfigView *configView; + ConfigList *configList; + QTextView *helpText; + QToolBar *toolBar; + QAction *backAction; + QSplitter* split1; + QSplitter* split2; + + bool showDebug; +}; diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c new file mode 100644 index 000000000..3d7877afc --- /dev/null +++ b/scripts/kconfig/symbol.c @@ -0,0 +1,882 @@ +/* + * 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> +#include <regex.h> +#include <sys/utsname.h> + +#define LKC_DIRECT_LINK +#include "lkc.h" + +struct symbol symbol_yes = { + .name = "y", + .curr = { "y", yes }, + .flags = SYMBOL_YES|SYMBOL_VALID, +}, symbol_mod = { + .name = "m", + .curr = { "m", mod }, + .flags = SYMBOL_MOD|SYMBOL_VALID, +}, symbol_no = { + .name = "n", + .curr = { "n", no }, + .flags = SYMBOL_NO|SYMBOL_VALID, +}, symbol_empty = { + .name = "", + .curr = { "", no }, + .flags = SYMBOL_VALID, +}; + +int sym_change_count; +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; + struct utsname uts; + char *p; + static bool inited = false; + + if (inited) + return; + inited = true; + + uname(&uts); + + 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); + + sym = sym_lookup("UNAME_RELEASE", 0); + sym->type = S_STRING; + sym->flags |= SYMBOL_AUTO; + sym_add_default(sym, uts.release); +} + +enum symbol_type sym_get_type(struct symbol *sym) +{ + enum symbol_type 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->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->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->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) + 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_change_count++; + 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_NEW) { + sym->flags &= ~SYMBOL_NEW; + 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->user.val = sym; + cs->flags &= ~SYMBOL_NEW; + 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_NEW; + } + } + + sym->user.tri = val; + if (oldval != val) { + sym_clear_all_valid(); + if (sym == modules_sym) + sym_set_all_changed(); + } + + 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_NEW) { + sym->flags &= ~SYMBOL_NEW; + sym_set_changed(sym); + } + + oldval = sym->user.val; + size = strlen(newval) + 1; + if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { + size += 2; + sym->user.val = val = malloc(size); + *val++ = '0'; + *val++ = 'x'; + } else if (!oldval || strcmp(oldval, newval)) + sym->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; + symbol->flags = SYMBOL_NEW; + 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; +} + +struct symbol **sym_re_search(const char *pattern) +{ + struct symbol *sym, **sym_arr = NULL; + int i, cnt, size; + regex_t re; + + cnt = size = 0; + /* Skip if empty */ + if (strlen(pattern) == 0) + return NULL; + if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE)) + return NULL; + + for_all_symbols(i, sym) { + if (sym->flags & SYMBOL_CONST || !sym->name) + continue; + if (regexec(&re, sym->name, 0, NULL, 0)) + continue; + if (cnt + 1 >= size) { + void *tmp = sym_arr; + size += 16; + sym_arr = realloc(sym_arr, size * sizeof(struct symbol *)); + if (!sym_arr) { + free(tmp); + return NULL; + } + } + sym_arr[cnt++] = sym; + } + if (sym_arr) + sym_arr[cnt] = NULL; + regfree(&re); + + return sym_arr; +} + + +struct symbol *sym_check_deps(struct symbol *sym); + +static struct symbol *sym_check_expr_deps(struct expr *e) +{ + 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; +} + +struct symbol *sym_check_deps(struct symbol *sym) +{ + struct symbol *sym2; + struct property *prop; + + if (sym->flags & SYMBOL_CHECK) { + printf("Warning! Found recursive dependency: %s", 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) { + printf(" %s", sym->name); + if (sym2 == sym) { + printf("\n"); + sym2 = NULL; + } + } + 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/scripts/kconfig/util.c b/scripts/kconfig/util.c new file mode 100644 index 000000000..aea8d56ce --- /dev/null +++ b/scripts/kconfig/util.c @@ -0,0 +1,109 @@ +/* + * 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, "\n.config include/autoconf.h: $(deps_config)\n\n$(deps_config):\n"); + fclose(out); + 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/scripts/kconfig/zconf.gperf b/scripts/kconfig/zconf.gperf new file mode 100644 index 000000000..b03220600 --- /dev/null +++ b/scripts/kconfig/zconf.gperf @@ -0,0 +1,43 @@ +%language=ANSI-C +%define hash-function-name kconf_id_hash +%define lookup-function-name kconf_id_lookup +%define string-pool-name kconf_id_strings +%compare-strncmp +%enum +%pic +%struct-type + +struct kconf_id; + +%% +mainmenu, T_MAINMENU, TF_COMMAND +menu, T_MENU, TF_COMMAND +endmenu, T_ENDMENU, TF_COMMAND +source, T_SOURCE, TF_COMMAND +choice, T_CHOICE, TF_COMMAND +endchoice, T_ENDCHOICE, TF_COMMAND +comment, T_COMMENT, TF_COMMAND +config, T_CONFIG, TF_COMMAND +menuconfig, T_MENUCONFIG, TF_COMMAND +help, T_HELP, TF_COMMAND +if, T_IF, TF_COMMAND|TF_PARAM +endif, T_ENDIF, TF_COMMAND +depends, T_DEPENDS, TF_COMMAND +requires, T_REQUIRES, TF_COMMAND +optional, T_OPTIONAL, TF_COMMAND +default, T_DEFAULT, TF_COMMAND, S_UNKNOWN +prompt, T_PROMPT, TF_COMMAND +tristate, T_TYPE, TF_COMMAND, S_TRISTATE +def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE +bool, T_TYPE, TF_COMMAND, S_BOOLEAN +boolean, T_TYPE, TF_COMMAND, S_BOOLEAN +def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN +def_boolean, T_DEFAULT, TF_COMMAND, S_BOOLEAN +int, T_TYPE, TF_COMMAND, S_INT +hex, T_TYPE, TF_COMMAND, S_HEX +string, T_TYPE, TF_COMMAND, S_STRING +select, T_SELECT, TF_COMMAND +enable, T_SELECT, TF_COMMAND +range, T_RANGE, TF_COMMAND +on, T_ON, TF_PARAM +%% diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped new file mode 100644 index 000000000..345f0fc07 --- /dev/null +++ b/scripts/kconfig/zconf.hash.c_shipped @@ -0,0 +1,231 @@ +/* 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, 10, 15, + 0, 0, 5, 47, 0, 0, 47, 47, 0, 10, + 0, 20, 20, 20, 5, 0, 0, 20, 47, 47, + 20, 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("if")]; + char kconf_id_strings_str3[sizeof("int")]; + char kconf_id_strings_str4[sizeof("help")]; + char kconf_id_strings_str5[sizeof("endif")]; + char kconf_id_strings_str6[sizeof("select")]; + char kconf_id_strings_str7[sizeof("endmenu")]; + char kconf_id_strings_str8[sizeof("tristate")]; + char kconf_id_strings_str9[sizeof("endchoice")]; + char kconf_id_strings_str10[sizeof("range")]; + char kconf_id_strings_str11[sizeof("string")]; + char kconf_id_strings_str12[sizeof("default")]; + char kconf_id_strings_str13[sizeof("def_bool")]; + char kconf_id_strings_str14[sizeof("menu")]; + char kconf_id_strings_str16[sizeof("def_boolean")]; + char kconf_id_strings_str17[sizeof("def_tristate")]; + char kconf_id_strings_str18[sizeof("mainmenu")]; + char kconf_id_strings_str20[sizeof("menuconfig")]; + char kconf_id_strings_str21[sizeof("config")]; + char kconf_id_strings_str22[sizeof("on")]; + char kconf_id_strings_str23[sizeof("hex")]; + char kconf_id_strings_str26[sizeof("source")]; + char kconf_id_strings_str27[sizeof("depends")]; + char kconf_id_strings_str28[sizeof("optional")]; + char kconf_id_strings_str31[sizeof("enable")]; + char kconf_id_strings_str32[sizeof("comment")]; + char kconf_id_strings_str33[sizeof("requires")]; + char kconf_id_strings_str34[sizeof("bool")]; + char kconf_id_strings_str37[sizeof("boolean")]; + char kconf_id_strings_str41[sizeof("choice")]; + char kconf_id_strings_str46[sizeof("prompt")]; + }; +static struct kconf_id_strings_t kconf_id_strings_contents = + { + "if", + "int", + "help", + "endif", + "select", + "endmenu", + "tristate", + "endchoice", + "range", + "string", + "default", + "def_bool", + "menu", + "def_boolean", + "def_tristate", + "mainmenu", + "menuconfig", + "config", + "on", + "hex", + "source", + "depends", + "optional", + "enable", + "comment", + "requires", + "bool", + "boolean", + "choice", + "prompt" + }; +#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 = 30, + MIN_WORD_LENGTH = 2, + MAX_WORD_LENGTH = 12, + 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_IF, TF_COMMAND|TF_PARAM}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str4, T_HELP, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_SELECT, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND}, + {(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_TYPE, TF_COMMAND, S_STRING}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_MENU, TF_COMMAND}, + {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_DEFAULT, TF_COMMAND, S_BOOLEAN}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_MAINMENU, TF_COMMAND}, + {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20, T_MENUCONFIG, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_CONFIG, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ON, TF_PARAM}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_HEX}, + {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SOURCE, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_DEPENDS, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPTIONAL, TF_COMMAND}, + {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_REQUIRES, TF_COMMAND}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34, T_TYPE, TF_COMMAND, S_BOOLEAN}, + {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_TYPE, TF_COMMAND, S_BOOLEAN}, + {-1}, {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_CHOICE, TF_COMMAND}, + {-1}, {-1}, {-1}, {-1}, + {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_PROMPT, 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/scripts/kconfig/zconf.l b/scripts/kconfig/zconf.l new file mode 100644 index 000000000..cfa46077c --- /dev/null +++ b/scripts/kconfig/zconf.l @@ -0,0 +1,350 @@ +%option backup nostdinit noyywrap never-interactive full ecs +%option 8bit backup nodefault perf-report perf-report +%x COMMAND HELP STRING PARAM +%{ +/* + * 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; +} +%} + +ws [ \n\t] +n [A-Za-z0-9_] + +%% + int str = 0; + int ts, i; + +[ \t]*#.*\n | +[ \t]*\n { + current_file->lineno++; + return T_EOL; +} +[ \t]*#.* + + +[ \t]+ { + BEGIN(COMMAND); +} + +. { + unput(yytext[0]); + BEGIN(COMMAND); +} + + +<COMMAND>{ + {n}+ { + struct kconf_id *id = kconf_id_lookup(yytext, yyleng); + 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(yytext, yyleng); + zconflval.string = text; + return T_WORD; + } + . + \n { + BEGIN(INITIAL); + current_file->lineno++; + return T_EOL; + } +} + +<PARAM>{ + "&&" return T_AND; + "||" return T_OR; + "(" return T_OPEN_PAREN; + ")" return T_CLOSE_PAREN; + "!" return T_NOT; + "=" return T_EQUAL; + "!=" return T_UNEQUAL; + \"|\' { + str = yytext[0]; + new_string(); + BEGIN(STRING); + } + \n BEGIN(INITIAL); current_file->lineno++; return T_EOL; + --- /* ignore */ + ({n}|[-/.])+ { + struct kconf_id *id = kconf_id_lookup(yytext, yyleng); + if (id && id->flags & TF_PARAM) { + zconflval.id = id; + return id->token; + } + alloc_string(yytext, yyleng); + zconflval.string = text; + return T_WORD; + } + #.* /* comment */ + \\\n current_file->lineno++; + . + <<EOF>> { + BEGIN(INITIAL); + } +} + +<STRING>{ + [^'"\\\n]+/\n { + append_string(yytext, yyleng); + zconflval.string = text; + return T_WORD_QUOTE; + } + [^'"\\\n]+ { + append_string(yytext, yyleng); + } + \\.?/\n { + append_string(yytext + 1, yyleng - 1); + zconflval.string = text; + return T_WORD_QUOTE; + } + \\.? { + append_string(yytext + 1, yyleng - 1); + } + \'|\" { + if (str == yytext[0]) { + BEGIN(PARAM); + zconflval.string = text; + return T_WORD_QUOTE; + } else + append_string(yytext, 1); + } + \n { + printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno()); + current_file->lineno++; + BEGIN(INITIAL); + return T_EOL; + } + <<EOF>> { + BEGIN(INITIAL); + } +} + +<HELP>{ + [ \t]+ { + ts = 0; + for (i = 0; i < yyleng; i++) { + if (yytext[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); + } + } + [ \t]*\n/[^ \t\n] { + current_file->lineno++; + zconf_endhelp(); + return T_HELPTEXT; + } + [ \t]*\n { + current_file->lineno++; + append_string("\n", 1); + } + [^ \t\n].* { + append_string(yytext, yyleng); + if (!first_ts) + first_ts = last_ts; + } + <<EOF>> { + zconf_endhelp(); + return T_HELPTEXT; + } +} + +<<EOF>> { + if (current_file) { + zconf_endfile(); + return T_EOL; + } + fclose(yyin); + yyterminate(); +} + +%% +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[0] != '/') { + env = getenv(SRCTREE); + if (env) { + sprintf(fullname, "%s/%s", env, name); + f = fopen(fullname, "r"); + } + } + return f; +} + +void zconf_initscan(const char *name) +{ + yyin = zconf_fopen(name); + if (!yyin) { + 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; + yyin = zconf_fopen(name); + if (!yyin) { + printf("%s:%d: can't open file \"%s\"\n", zconf_curname(), zconf_lineno(), name); + exit(1); + } + yy_switch_to_buffer(yy_create_buffer(yyin, 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(yyin); + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_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/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped new file mode 100644 index 000000000..ea7755da8 --- /dev/null +++ b/scripts/kconfig/zconf.tab.c_shipped @@ -0,0 +1,2173 @@ +/* A Bison parser, made by GNU Bison 2.0. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, 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 + +/* 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_ON = 279, + T_WORD = 280, + T_WORD_QUOTE = 281, + T_UNEQUAL = 282, + T_CLOSE_PAREN = 283, + T_OPEN_PAREN = 284, + T_EOL = 285, + T_OR = 286, + T_AND = 287, + T_EQUAL = 288, + T_NOT = 289 + }; +#endif +#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_ON 279 +#define T_WORD 280 +#define T_WORD_QUOTE 281 +#define T_UNEQUAL 282 +#define T_CLOSE_PAREN 283 +#define T_OPEN_PAREN 284 +#define T_EOL 285 +#define T_OR 286 +#define T_AND 287 +#define T_EQUAL 288 +#define T_NOT 289 + + + + +/* 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 <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 + +#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 190 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 213 of yacc.c. */ + + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +# ifndef YYFREE +# define YYFREE free +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# endif + +/* 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 +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# 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 \ + { \ + register 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 264 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 35 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 42 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 104 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 175 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 289 + +#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 +}; + +#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, 104, 109, + 114, 119, 125, 128, 131, 133, 137, 138, 141, 144, + 147, 150, 153, 158, 162, 165, 170, 171, 174, 178, + 180, 184, 185, 188, 191, 194, 198, 201, 203, 207, + 208, 211, 214, 217, 221, 225, 228, 231, 234, 235, + 238, 241, 244, 249, 253, 257, 258, 261, 263, 265, + 268, 271, 274, 276, 279, 280, 283, 285, 289, 293, + 297, 300, 304, 308, 310 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 36, 0, -1, 37, -1, -1, 37, 39, -1, 37, + 50, -1, 37, 61, -1, 37, 3, 71, 73, -1, + 37, 72, -1, 37, 25, 1, 30, -1, 37, 38, + 1, 30, -1, 37, 1, 30, -1, 16, -1, 19, + -1, 20, -1, 22, -1, 18, -1, 23, -1, 21, + -1, 30, -1, 56, -1, 65, -1, 42, -1, 44, + -1, 63, -1, 25, 1, 30, -1, 1, 30, -1, + 10, 25, 30, -1, 41, 45, -1, 11, 25, 30, + -1, 43, 45, -1, -1, 45, 46, -1, 45, 69, + -1, 45, 67, -1, 45, 40, -1, 45, 30, -1, + 20, 70, 30, -1, 19, 71, 74, 30, -1, 21, + 75, 74, 30, -1, 22, 25, 74, 30, -1, 23, + 76, 76, 74, 30, -1, 7, 30, -1, 47, 51, + -1, 72, -1, 48, 53, 49, -1, -1, 51, 52, + -1, 51, 69, -1, 51, 67, -1, 51, 30, -1, + 51, 40, -1, 19, 71, 74, 30, -1, 20, 70, + 30, -1, 18, 30, -1, 21, 25, 74, 30, -1, + -1, 53, 39, -1, 14, 75, 73, -1, 72, -1, + 54, 57, 55, -1, -1, 57, 39, -1, 57, 61, + -1, 57, 50, -1, 4, 71, 30, -1, 58, 68, + -1, 72, -1, 59, 62, 60, -1, -1, 62, 39, + -1, 62, 61, -1, 62, 50, -1, 6, 71, 30, + -1, 9, 71, 30, -1, 64, 68, -1, 12, 30, + -1, 66, 13, -1, -1, 68, 69, -1, 68, 30, + -1, 68, 40, -1, 16, 24, 75, 30, -1, 16, + 75, 30, -1, 17, 75, 30, -1, -1, 71, 74, + -1, 25, -1, 26, -1, 5, 30, -1, 8, 30, + -1, 15, 30, -1, 30, -1, 73, 30, -1, -1, + 14, 75, -1, 76, -1, 76, 33, 76, -1, 76, + 27, 76, -1, 29, 75, 28, -1, 34, 75, -1, + 75, 31, 75, -1, 75, 32, 75, -1, 25, -1, + 26, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short int yyrline[] = +{ + 0, 103, 103, 105, 107, 108, 109, 110, 111, 112, + 113, 117, 121, 121, 121, 121, 121, 121, 121, 125, + 126, 127, 128, 129, 130, 134, 135, 141, 149, 155, + 163, 173, 175, 176, 177, 178, 179, 182, 190, 196, + 206, 212, 220, 229, 234, 242, 245, 247, 248, 249, + 250, 251, 254, 260, 271, 277, 287, 289, 294, 302, + 310, 313, 315, 316, 317, 322, 329, 334, 342, 345, + 347, 348, 349, 352, 360, 367, 374, 380, 387, 389, + 390, 391, 394, 399, 404, 412, 414, 419, 420, 423, + 424, 425, 429, 430, 433, 434, 437, 438, 439, 440, + 441, 442, 443, 446, 447 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[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_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", "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 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 35, 36, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 38, 38, 38, 38, 38, 38, 38, 39, + 39, 39, 39, 39, 39, 40, 40, 41, 42, 43, + 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, + 46, 46, 47, 48, 49, 50, 51, 51, 51, 51, + 51, 51, 52, 52, 52, 52, 53, 53, 54, 55, + 56, 57, 57, 57, 57, 58, 59, 60, 61, 62, + 62, 62, 62, 63, 64, 65, 66, 67, 68, 68, + 68, 68, 69, 69, 69, 70, 70, 71, 71, 72, + 72, 72, 73, 73, 74, 74, 75, 75, 75, 75, + 75, 75, 75, 76, 76 +}; + +/* 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, 3, 4, 4, + 4, 5, 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, 46, 56, 5, 61, 20, 78, 69, 6, 24, + 78, 21, 8, 11, 87, 88, 0, 0, 89, 0, + 42, 90, 0, 0, 0, 103, 104, 0, 0, 0, + 96, 91, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 92, 7, 65, 73, 74, 27, 29, 0, + 100, 0, 0, 58, 0, 0, 9, 10, 0, 0, + 0, 0, 0, 85, 0, 0, 0, 0, 36, 35, + 32, 0, 34, 33, 0, 0, 85, 0, 50, 51, + 47, 49, 48, 57, 45, 44, 62, 64, 60, 63, + 59, 80, 81, 79, 70, 72, 68, 71, 67, 93, + 99, 101, 102, 98, 97, 26, 76, 0, 0, 0, + 94, 0, 94, 94, 94, 0, 0, 77, 54, 94, + 0, 94, 0, 83, 84, 0, 0, 37, 86, 0, + 0, 94, 25, 0, 53, 0, 82, 95, 38, 39, + 40, 0, 52, 55, 41 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const short int yydefgoto[] = +{ + -1, 1, 2, 25, 26, 99, 27, 28, 29, 30, + 64, 100, 31, 32, 114, 33, 66, 110, 67, 34, + 118, 35, 68, 36, 37, 126, 38, 70, 39, 40, + 41, 101, 102, 69, 103, 141, 142, 42, 73, 156, + 59, 60 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -78 +static const short int yypact[] = +{ + -78, 2, 159, -78, -21, 0, 0, -12, 0, 1, + 4, 0, 27, 38, 60, 58, -78, -78, -78, -78, + -78, -78, -78, 100, -78, 104, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, 86, 113, -78, 114, + -78, -78, 125, 127, 128, -78, -78, 60, 60, 210, + 65, -78, 141, 142, 39, 103, 182, 200, 6, 66, + 6, 131, -78, 146, -78, -78, -78, -78, -78, 196, + -78, 60, 60, 146, 40, 40, -78, -78, 155, 156, + -2, 60, 0, 0, 60, 105, 40, 194, -78, -78, + -78, 206, -78, -78, 183, 0, 0, 195, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, -78, -78, -78, -78, + -78, 197, -78, -78, -78, -78, -78, 60, 213, 216, + 212, 203, 212, 190, 212, 40, 208, -78, -78, 212, + 222, 212, 219, -78, -78, 60, 223, -78, -78, 224, + 225, 212, -78, 226, -78, 227, -78, 47, -78, -78, + -78, 228, -78, -78, -78 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const short int yypgoto[] = +{ + -78, -78, -78, -78, 164, -36, -78, -78, -78, -78, + 230, -78, -78, -78, -78, 29, -78, -78, -78, -78, + -78, -78, -78, -78, -78, -78, 59, -78, -78, -78, + -78, -78, 198, 220, 24, 157, -5, 169, 202, 74, + -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 -76 +static const short int yytable[] = +{ + 46, 47, 3, 49, 79, 80, 52, 133, 134, 43, + 6, 7, 8, 9, 10, 11, 12, 13, 48, 145, + 14, 15, 137, 55, 56, 44, 45, 57, 131, 132, + 109, 50, 58, 122, 51, 122, 24, 138, 139, -28, + 88, 143, -28, -28, -28, -28, -28, -28, -28, -28, + -28, 89, 53, -28, -28, 90, 91, -28, 92, 93, + 94, 95, 96, 54, 97, 55, 56, 88, 161, 98, + -66, -66, -66, -66, -66, -66, -66, -66, 81, 82, + -66, -66, 90, 91, 152, 55, 56, 140, 61, 57, + 112, 97, 84, 123, 58, 123, 121, 117, 85, 125, + 149, 62, 167, -30, 88, 63, -30, -30, -30, -30, + -30, -30, -30, -30, -30, 89, 72, -30, -30, 90, + 91, -30, 92, 93, 94, 95, 96, 119, 97, 127, + 144, -75, 88, 98, -75, -75, -75, -75, -75, -75, + -75, -75, -75, 74, 75, -75, -75, 90, 91, -75, + -75, -75, -75, -75, -75, 76, 97, 77, 78, -2, + 4, 121, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 86, 87, 14, 15, 16, 129, 17, 18, 19, + 20, 21, 22, 88, 23, 135, 136, -43, -43, 24, + -43, -43, -43, -43, 89, 146, -43, -43, 90, 91, + 104, 105, 106, 107, 155, 7, 8, 97, 10, 11, + 12, 13, 108, 148, 14, 15, 158, 159, 160, 147, + 151, 81, 82, 163, 130, 165, 155, 81, 82, 82, + 24, 113, 116, 157, 124, 171, 115, 120, 162, 128, + 72, 81, 82, 153, 81, 82, 154, 81, 82, 166, + 81, 82, 164, 168, 169, 170, 172, 173, 174, 65, + 71, 83, 0, 150, 111 +}; + +static const short int yycheck[] = +{ + 5, 6, 0, 8, 57, 58, 11, 84, 85, 30, + 4, 5, 6, 7, 8, 9, 10, 11, 30, 96, + 14, 15, 24, 25, 26, 25, 26, 29, 81, 82, + 66, 30, 34, 69, 30, 71, 30, 90, 91, 0, + 1, 94, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 25, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 25, 25, 25, 26, 1, 145, 30, + 4, 5, 6, 7, 8, 9, 10, 11, 31, 32, + 14, 15, 16, 17, 137, 25, 26, 92, 30, 29, + 66, 25, 27, 69, 34, 71, 30, 68, 33, 70, + 105, 1, 155, 0, 1, 1, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 30, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 68, 25, 70, + 25, 0, 1, 30, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 30, 30, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 30, 25, 30, 30, 0, + 1, 30, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 30, 30, 14, 15, 16, 30, 18, 19, 20, + 21, 22, 23, 1, 25, 30, 30, 5, 6, 30, + 8, 9, 10, 11, 12, 1, 14, 15, 16, 17, + 18, 19, 20, 21, 14, 5, 6, 25, 8, 9, + 10, 11, 30, 30, 14, 15, 142, 143, 144, 13, + 25, 31, 32, 149, 28, 151, 14, 31, 32, 32, + 30, 67, 68, 30, 70, 161, 67, 68, 30, 70, + 30, 31, 32, 30, 31, 32, 30, 31, 32, 30, + 31, 32, 30, 30, 30, 30, 30, 30, 30, 29, + 40, 59, -1, 106, 66 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 36, 37, 0, 1, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 14, 15, 16, 18, 19, 20, + 21, 22, 23, 25, 30, 38, 39, 41, 42, 43, + 44, 47, 48, 50, 54, 56, 58, 59, 61, 63, + 64, 65, 72, 30, 25, 26, 71, 71, 30, 71, + 30, 30, 71, 25, 25, 25, 26, 29, 34, 75, + 76, 30, 1, 1, 45, 45, 51, 53, 57, 68, + 62, 68, 30, 73, 30, 30, 30, 30, 30, 75, + 75, 31, 32, 73, 27, 33, 30, 30, 1, 12, + 16, 17, 19, 20, 21, 22, 23, 25, 30, 40, + 46, 66, 67, 69, 18, 19, 20, 21, 30, 40, + 52, 67, 69, 39, 49, 72, 39, 50, 55, 61, + 72, 30, 40, 69, 39, 50, 60, 61, 72, 30, + 28, 75, 75, 76, 76, 30, 30, 24, 75, 75, + 71, 70, 71, 75, 25, 76, 1, 13, 30, 71, + 70, 25, 75, 30, 30, 14, 74, 30, 74, 74, + 74, 76, 30, 74, 30, 74, 30, 75, 30, 30, + 30, 74, 30, 30, 30 +}; + +#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) +# if defined (__STDC__) || defined (__cplusplus) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#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 ("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 int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + 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 + SIZE_MAX < 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 +{ + register 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 +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# 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 48: /* 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 54: /* 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 59: /* 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 +{ + + register int yystate; + register 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; + register short int *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register 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; + + + yyvsp[0] = yylval; + + 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 ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short int *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + 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 37: + + { + 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 38: + + { + menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr)); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 39: + + { + 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 40: + + { + 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 41: + + { + 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 42: + + { + 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 43: + + { + (yyval.menu) = menu_add_menu(); +;} + break; + + case 44: + + { + 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 52: + + { + menu_add_prompt(P_PROMPT, (yyvsp[-2].string), (yyvsp[-1].expr)); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 53: + + { + 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 54: + + { + current_entry->sym->flags |= SYMBOL_OPTIONAL; + printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 55: + + { + 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 58: + + { + 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 59: + + { + 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 65: + + { + 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 66: + + { + (yyval.menu) = menu_add_menu(); +;} + break; + + case 67: + + { + 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 73: + + { + printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), (yyvsp[-1].string)); + zconf_nextfile((yyvsp[-1].string)); +;} + break; + + case 74: + + { + 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 75: + + { + menu_end_entry(); +;} + break; + + case 76: + + { + printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); + zconf_starthelp(); +;} + break; + + case 77: + + { + current_entry->sym->help = (yyvsp[0].string); +;} + break; + + case 82: + + { + menu_add_dep((yyvsp[-1].expr)); + printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 83: + + { + menu_add_dep((yyvsp[-1].expr)); + printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 84: + + { + menu_add_dep((yyvsp[-1].expr)); + printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno()); +;} + break; + + case 86: + + { + menu_add_prompt(P_PROMPT, (yyvsp[-1].string), (yyvsp[0].expr)); +;} + break; + + case 89: + + { (yyval.id) = (yyvsp[-1].id); ;} + break; + + case 90: + + { (yyval.id) = (yyvsp[-1].id); ;} + break; + + case 91: + + { (yyval.id) = (yyvsp[-1].id); ;} + break; + + case 94: + + { (yyval.expr) = NULL; ;} + break; + + case 95: + + { (yyval.expr) = (yyvsp[0].expr); ;} + break; + + case 96: + + { (yyval.expr) = expr_alloc_symbol((yyvsp[0].symbol)); ;} + break; + + case 97: + + { (yyval.expr) = expr_alloc_comp(E_EQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;} + break; + + case 98: + + { (yyval.expr) = expr_alloc_comp(E_UNEQUAL, (yyvsp[-2].symbol), (yyvsp[0].symbol)); ;} + break; + + case 99: + + { (yyval.expr) = (yyvsp[-1].expr); ;} + break; + + case 100: + + { (yyval.expr) = expr_alloc_one(E_NOT, (yyvsp[0].expr)); ;} + break; + + case 101: + + { (yyval.expr) = expr_alloc_two(E_OR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} + break; + + case 102: + + { (yyval.expr) = expr_alloc_two(E_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;} + break; + + case 103: + + { (yyval.symbol) = sym_lookup((yyvsp[0].string), 0); free((yyvsp[0].string)); ;} + break; + + case 104: + + { (yyval.symbol) = sym_lookup((yyvsp[0].string), 1); free((yyvsp[0].string)); ;} + break; + + + } + +/* Line 1037 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) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + const char* yyprefix; + char *yymsg; + int yyx; + + /* 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 = 0; + + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); + yycount += 1; + if (yycount == 5) + { + yysize = 0; + break; + } + } + yysize += (sizeof ("syntax error, unexpected ") + + yystrlen (yytname[yytype])); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yyp = yystpcpy (yyp, yyprefix); + yyp = yystpcpy (yyp, yytname[yyx]); + yyprefix = " or "; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* If at end of input, pop the error token, + then the rest of the stack, then return failure. */ + if (yychar == YYEOF) + for (;;) + { + + YYPOPSTACK; + if (yyssp == yyss) + YYABORT; + yydestruct ("Error: popping", + yystos[*yyssp], yyvsp); + } + } + 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: + +#ifdef __GNUC__ + /* Pacify GCC when the user code never invokes YYERROR and the label + yyerrorlab therefore never appears in user code. */ + if (0) + goto yyerrorlab; +#endif + +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: + yydestruct ("Error: discarding lookahead", + yytoken, &yylval); + yychar = YYEMPTY; + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#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("MODULES", 0); + rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); + +#if YYDEBUG + if (getenv("ZCONF_DEBUG")) + zconfdebug = 1; +#endif + zconfparse(); + if (zconfnerrs) + exit(1); + menu_finalize(&rootmenu); + for_all_symbols(i, sym) { + sym_check_deps(sym); + } + + sym_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 (sym->help) { + int len = strlen(sym->help); + while (sym->help[--len] == '\n') + sym->help[len] = 0; + fprintf(out, " help\n%s\n", sym->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" + + diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y new file mode 100644 index 000000000..1f61fba6a --- /dev/null +++ b/scripts/kconfig/zconf.y @@ -0,0 +1,681 @@ +%{ +/* + * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> + * Released under the terms of the GNU GPL v2.0. + */ + +#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 +%} +%expect 26 + +%union +{ + char *string; + struct file *file; + struct symbol *symbol; + struct expr *expr; + struct menu *menu; + struct kconf_id *id; +} + +%token <id>T_MAINMENU +%token <id>T_MENU +%token <id>T_ENDMENU +%token <id>T_SOURCE +%token <id>T_CHOICE +%token <id>T_ENDCHOICE +%token <id>T_COMMENT +%token <id>T_CONFIG +%token <id>T_MENUCONFIG +%token <id>T_HELP +%token <string> T_HELPTEXT +%token <id>T_IF +%token <id>T_ENDIF +%token <id>T_DEPENDS +%token <id>T_REQUIRES +%token <id>T_OPTIONAL +%token <id>T_PROMPT +%token <id>T_TYPE +%token <id>T_DEFAULT +%token <id>T_SELECT +%token <id>T_RANGE +%token <id>T_ON +%token <string> T_WORD +%token <string> T_WORD_QUOTE +%token T_UNEQUAL +%token T_CLOSE_PAREN +%token T_OPEN_PAREN +%token T_EOL + +%left T_OR +%left T_AND +%left T_EQUAL T_UNEQUAL +%nonassoc T_NOT + +%type <string> prompt +%type <symbol> symbol +%type <expr> expr +%type <expr> if_expr +%type <id> end +%type <id> option_name +%type <menu> if_entry menu_entry choice_entry + +%destructor { + fprintf(stderr, "%s:%d: missing end statement for this entry\n", + $$->file->name, $$->lineno); + if (current_menu == $$) + menu_end_menu(); +} if_entry menu_entry choice_entry + +%% +input: stmt_list; + +stmt_list: + /* empty */ + | stmt_list common_stmt + | stmt_list choice_stmt + | stmt_list menu_stmt + | stmt_list T_MAINMENU prompt nl + | stmt_list end { zconf_error("unexpected end statement"); } + | stmt_list T_WORD error T_EOL { zconf_error("unknown statement \"%s\"", $2); } + | stmt_list option_name error T_EOL +{ + zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name); +} + | stmt_list error T_EOL { zconf_error("invalid statement"); } +; + +option_name: + T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT +; + +common_stmt: + T_EOL + | if_stmt + | comment_stmt + | config_stmt + | menuconfig_stmt + | source_stmt +; + +option_error: + T_WORD error T_EOL { zconf_error("unknown option \"%s\"", $1); } + | error T_EOL { zconf_error("invalid option"); } +; + + +/* config/menuconfig entry */ + +config_entry_start: T_CONFIG T_WORD T_EOL +{ + struct symbol *sym = sym_lookup($2, 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2); +}; + +config_stmt: config_entry_start config_option_list +{ + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +}; + +menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL +{ + struct symbol *sym = sym_lookup($2, 0); + sym->flags |= SYMBOL_OPTIONAL; + menu_add_entry(sym); + printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2); +}; + +menuconfig_stmt: menuconfig_entry_start config_option_list +{ + if (current_entry->prompt) + current_entry->prompt->type = P_MENU; + else + zconfprint("warning: menuconfig statement without prompt"); + menu_end_entry(); + printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); +}; + +config_option_list: + /* empty */ + | config_option_list config_option + | config_option_list depends + | config_option_list help + | config_option_list option_error + | config_option_list T_EOL +; + +config_option: T_TYPE prompt_stmt_opt T_EOL +{ + menu_set_type($1->stype); + printd(DEBUG_PARSE, "%s:%d:type(%u)\n", + zconf_curname(), zconf_lineno(), + $1->stype); +}; + +config_option: T_PROMPT prompt if_expr T_EOL +{ + menu_add_prompt(P_PROMPT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_DEFAULT expr if_expr T_EOL +{ + menu_add_expr(P_DEFAULT, $2, $3); + if ($1->stype != S_UNKNOWN) + menu_set_type($1->stype); + printd(DEBUG_PARSE, "%s:%d:default(%u)\n", + zconf_curname(), zconf_lineno(), + $1->stype); +}; + +config_option: T_SELECT T_WORD if_expr T_EOL +{ + menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3); + printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); +}; + +config_option: T_RANGE symbol symbol if_expr T_EOL +{ + menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); + printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); +}; + +/* choice entry */ + +choice: T_CHOICE T_EOL +{ + 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()); +}; + +choice_entry: choice choice_option_list +{ + $$ = menu_add_menu(); +}; + +choice_end: end +{ + if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); + } +}; + +choice_stmt: choice_entry choice_block choice_end +; + +choice_option_list: + /* empty */ + | choice_option_list choice_option + | choice_option_list depends + | choice_option_list help + | choice_option_list T_EOL + | choice_option_list option_error +; + +choice_option: T_PROMPT prompt if_expr T_EOL +{ + menu_add_prompt(P_PROMPT, $2, $3); + printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_TYPE prompt_stmt_opt T_EOL +{ + if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) { + menu_set_type($1->stype); + printd(DEBUG_PARSE, "%s:%d:type(%u)\n", + zconf_curname(), zconf_lineno(), + $1->stype); + } else + YYERROR; +}; + +choice_option: T_OPTIONAL T_EOL +{ + current_entry->sym->flags |= SYMBOL_OPTIONAL; + printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); +}; + +choice_option: T_DEFAULT T_WORD if_expr T_EOL +{ + if ($1->stype == S_UNKNOWN) { + menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3); + printd(DEBUG_PARSE, "%s:%d:default\n", + zconf_curname(), zconf_lineno()); + } else + YYERROR; +}; + +choice_block: + /* empty */ + | choice_block common_stmt +; + +/* if entry */ + +if_entry: T_IF expr nl +{ + printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); + menu_add_entry(NULL); + menu_add_dep($2); + $$ = menu_add_menu(); +}; + +if_end: end +{ + if (zconf_endtoken($1, T_IF, T_ENDIF)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); + } +}; + +if_stmt: if_entry if_block if_end +; + +if_block: + /* empty */ + | if_block common_stmt + | if_block menu_stmt + | if_block choice_stmt +; + +/* menu entry */ + +menu: T_MENU prompt T_EOL +{ + menu_add_entry(NULL); + menu_add_prompt(P_MENU, $2, NULL); + printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); +}; + +menu_entry: menu depends_list +{ + $$ = menu_add_menu(); +}; + +menu_end: end +{ + if (zconf_endtoken($1, T_MENU, T_ENDMENU)) { + menu_end_menu(); + printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); + } +}; + +menu_stmt: menu_entry menu_block menu_end +; + +menu_block: + /* empty */ + | menu_block common_stmt + | menu_block menu_stmt + | menu_block choice_stmt +; + +source_stmt: T_SOURCE prompt T_EOL +{ + printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); + zconf_nextfile($2); +}; + +/* comment entry */ + +comment: T_COMMENT prompt T_EOL +{ + menu_add_entry(NULL); + menu_add_prompt(P_COMMENT, $2, NULL); + printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); +}; + +comment_stmt: comment depends_list +{ + menu_end_entry(); +}; + +/* help option */ + +help_start: T_HELP T_EOL +{ + printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); + zconf_starthelp(); +}; + +help: help_start T_HELPTEXT +{ + current_entry->sym->help = $2; +}; + +/* depends option */ + +depends_list: + /* empty */ + | depends_list depends + | depends_list T_EOL + | depends_list option_error +; + +depends: T_DEPENDS T_ON expr T_EOL +{ + menu_add_dep($3); + printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); +} + | T_DEPENDS expr T_EOL +{ + menu_add_dep($2); + printd(DEBUG_PARSE, "%s:%d:depends\n", zconf_curname(), zconf_lineno()); +} + | T_REQUIRES expr T_EOL +{ + menu_add_dep($2); + printd(DEBUG_PARSE, "%s:%d:requires\n", zconf_curname(), zconf_lineno()); +}; + +/* prompt statement */ + +prompt_stmt_opt: + /* empty */ + | prompt if_expr +{ + menu_add_prompt(P_PROMPT, $1, $2); +}; + +prompt: T_WORD + | T_WORD_QUOTE +; + +end: T_ENDMENU T_EOL { $$ = $1; } + | T_ENDCHOICE T_EOL { $$ = $1; } + | T_ENDIF T_EOL { $$ = $1; } +; + +nl: + T_EOL + | nl T_EOL +; + +if_expr: /* empty */ { $$ = NULL; } + | T_IF expr { $$ = $2; } +; + +expr: symbol { $$ = expr_alloc_symbol($1); } + | symbol T_EQUAL symbol { $$ = expr_alloc_comp(E_EQUAL, $1, $3); } + | symbol T_UNEQUAL symbol { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); } + | T_OPEN_PAREN expr T_CLOSE_PAREN { $$ = $2; } + | T_NOT expr { $$ = expr_alloc_one(E_NOT, $2); } + | expr T_OR expr { $$ = expr_alloc_two(E_OR, $1, $3); } + | expr T_AND expr { $$ = expr_alloc_two(E_AND, $1, $3); } +; + +symbol: T_WORD { $$ = sym_lookup($1, 0); free($1); } + | T_WORD_QUOTE { $$ = sym_lookup($1, 1); free($1); } +; + +%% + +void conf_parse(const char *name) +{ + struct symbol *sym; + int i; + + zconf_initscan(name); + + sym_init(); + menu_init(); + modules_sym = sym_lookup("MODULES", 0); + rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); + +#if YYDEBUG + if (getenv("ZCONF_DEBUG")) + zconfdebug = 1; +#endif + zconfparse(); + if (zconfnerrs) + exit(1); + menu_finalize(&rootmenu); + for_all_symbols(i, sym) { + sym_check_deps(sym); + } + + sym_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 (sym->help) { + int len = strlen(sym->help); + while (sym->help[--len] == '\n') + sym->help[len] = 0; + fprintf(out, " help\n%s\n", sym->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" diff --git a/scripts/mkconfigs b/scripts/mkconfigs new file mode 100755 index 000000000..fda9de72f --- /dev/null +++ b/scripts/mkconfigs @@ -0,0 +1,51 @@ +#!/bin/sh +# +# Copyright (C) 2002 Khalid Aziz <khalid_aziz at hp.com> +# Copyright (C) 2002 Randy Dunlap <rddunlap at osdl.org> +# Copyright (C) 2002 Al Stone <ahs3 at fc.hp.com> +# Copyright (C) 2002 Hewlett-Packard Company +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# Busybox version by Matteo Croce <3297627799 at wind.it> +# +# Rules to generate bbconfig.h from .config: +# - Retain lines that begin with "CONFIG_" +# - Retain lines that begin with "# CONFIG_" +# - lines that use double-quotes must \\-escape-quote them + +if [ $# -lt 1 ] +then + config=.config +else config=$1 +fi + +echo "#ifndef _BBCONFIGOPTS_H" +echo "#define _BBCONFIGOPTS_H" +echo \ +"/* + * busybox configuration settings. + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + * + * This file is generated automatically by scripts/config/mkconfigs. + * Do not edit. + * + */" + +echo "static const char * const bbconfig_config =" +echo "`sed 's/\"/\\\\\"/g' $config | grep "^#\? \?CONFIG_" | awk '{print "\\"" $0 "\\\\n\\"";}'`" +echo ";" +echo "#endif /* _BBCONFIGOPTS_H */" diff --git a/scripts/trylink b/scripts/trylink new file mode 100755 index 000000000..dfe282db5 --- /dev/null +++ b/scripts/trylink @@ -0,0 +1,18 @@ +#!/bin/sh + +debug=false + +function try { + added="$1" + shift + $debug && echo "Trying: $* $added" + "$@" $added >/dev/null 2>&1 \ + && exit 0 +} + +try "" "$@" +try "-lm" "$@" +try "-lcrypt" "$@" +try "-Wl,--start-group -lcrypt -lm -Wl,--end-group" "$@" +# It failed. Rerun & let people see the error messages +"$@" $added diff --git a/scripts/usage.c b/scripts/usage.c index 373642cd6..adb290e4d 100644 --- a/scripts/usage.c +++ b/scripts/usage.c @@ -1,11 +1,13 @@ /* vi: set sw=4 ts=4: */ #include <unistd.h> -#include "busybox.h" + +#include "../include/autoconf.h" +#include "../include/busybox.h" static const char usage_messages[] = #define MAKE_USAGE -#include "usage.h" -#include "applets.h" +#include "../include/usage.h" +#include "../include/applets.h" ; int main(void) diff --git a/scripts/usage_compressed b/scripts/usage_compressed old mode 100644 new mode 100755 index 8e2228af2..ab164aa12 --- a/scripts/usage_compressed +++ b/scripts/usage_compressed @@ -1,13 +1,19 @@ #!/bin/sh -loc="$1" +target="$1" +loc="$2" +test "$target" || exit 1 test "$loc" || loc=. test -x "$loc/usage" || exit 1 +test "$SED" || SED=sed + +sz=`"$loc/usage" | wc -c` || exit 1 + +exec >"$target" echo 'static const char packed_usage[] = ' -"$loc"/usage | bzip2 -1 | od -v -t x1 \ -| $SED -e 's/^[^ ]*//' -e 's/ \(..\)/\\x\1/g' -e 's/^\(.*\)$/"\1"/' || exit 1 +"$loc/usage" | bzip2 -1 | od -v -t x1 \ +| $SED -e 's/^[^ ]*//' -e 's/ \(..\)/\\x\1/g' -e 's/^\(.*\)$/"\1"/' echo ';' -sz=`"$loc"/usage | wc -c` || exit 1 echo '#define SIZEOF_usage_messages' `expr 0 + $sz` diff --git a/shell/Config.in b/shell/Config.in index cfe081f2c..0e25bedcb 100644 --- a/shell/Config.in +++ b/shell/Config.in @@ -7,36 +7,36 @@ menu "Shells" choice prompt "Choose your default shell" - default CONFIG_FEATURE_SH_IS_NONE + default FEATURE_SH_IS_NONE help Choose a shell. The ash shell is the most bash compatible and full featured one. -config CONFIG_FEATURE_SH_IS_ASH - select CONFIG_ASH +config FEATURE_SH_IS_ASH + select ASH bool "ash" -config CONFIG_FEATURE_SH_IS_HUSH - select CONFIG_HUSH +config FEATURE_SH_IS_HUSH + select HUSH bool "hush" -config CONFIG_FEATURE_SH_IS_LASH - select CONFIG_LASH +config FEATURE_SH_IS_LASH + select LASH bool "lash" -config CONFIG_FEATURE_SH_IS_MSH - select CONFIG_MSH +config FEATURE_SH_IS_MSH + select MSH bool "msh" -config CONFIG_FEATURE_SH_IS_NONE +config FEATURE_SH_IS_NONE bool "none" endchoice -config CONFIG_ASH +config ASH bool "ash" default n - select CONFIG_TEST + select TEST help Tha 'ash' shell adds about 60k in the default configuration and is the most complete and most pedantically correct shell included with @@ -45,105 +45,105 @@ config CONFIG_ASH (written by Kenneth Almquist) from NetBSD. comment "Ash Shell Options" - depends on CONFIG_ASH + depends on ASH -config CONFIG_ASH_JOB_CONTROL +config ASH_JOB_CONTROL bool "Job control" default y - depends on CONFIG_ASH + depends on ASH help Enable job control in the ash shell. -config CONFIG_ASH_READ_NCHARS +config ASH_READ_NCHARS bool "'read -n N' and 'read -s' support" default n - depends on CONFIG_ASH + depends on ASH help 'read -n N' will return a value after N characters have been read. 'read -s' will read without echoing the user's input. -config CONFIG_ASH_READ_TIMEOUT +config ASH_READ_TIMEOUT bool "'read -t S' support." default n - depends on CONFIG_ASH + depends on ASH help 'read -t S' will return a value after S seconds have passed. This implementation will allow fractional seconds, expressed as a decimal fraction, e.g. 'read -t 2.5 foo'. -config CONFIG_ASH_ALIAS +config ASH_ALIAS bool "alias support" default y - depends on CONFIG_ASH + depends on ASH help Enable alias support in the ash shell. -config CONFIG_ASH_MATH_SUPPORT +config ASH_MATH_SUPPORT bool "Posix math support" default y - depends on CONFIG_ASH + depends on ASH help Enable math support in the ash shell. -config CONFIG_ASH_MATH_SUPPORT_64 +config ASH_MATH_SUPPORT_64 bool "Extend Posix math support to 64 bit" default n - depends on CONFIG_ASH_MATH_SUPPORT + depends on ASH_MATH_SUPPORT help Enable 64-bit math support in the ash shell. This will make the shell slightly larger, but will allow computation with very large numbers. -config CONFIG_ASH_GETOPTS +config ASH_GETOPTS bool "Builtin getopt to parse positional parameters" default n - depends on CONFIG_ASH + depends on ASH help Enable getopts builtin in the ash shell. -config CONFIG_ASH_BUILTIN_ECHO +config ASH_BUILTIN_ECHO bool "Builtin version of 'echo'" default y - select CONFIG_ECHO - depends on CONFIG_ASH + select ECHO + depends on ASH help Enable support for echo, built in to ash. -config CONFIG_ASH_BUILTIN_TEST +config ASH_BUILTIN_TEST bool "Builtin version of 'test'" default y - select CONFIG_TEST - depends on CONFIG_ASH + select TEST + depends on ASH help Enable support for test, built in to ash. -config CONFIG_ASH_CMDCMD +config ASH_CMDCMD bool "'command' command to override shell builtins" default n - depends on CONFIG_ASH + depends on ASH help Enable support for the ash 'command' builtin, which allows you to run the specified command with the specified arguments, even when there is an ash builtin command with the same name. -config CONFIG_ASH_MAIL +config ASH_MAIL bool "Check for new mail on interactive shells" default y - depends on CONFIG_ASH + depends on ASH help Enable "check for new mail" in the ash shell. -config CONFIG_ASH_OPTIMIZE_FOR_SIZE +config ASH_OPTIMIZE_FOR_SIZE bool "Optimize for size instead of speed" default y - depends on CONFIG_ASH + depends on ASH help Compile ash for reduced size at the price of speed. -config CONFIG_ASH_RANDOM_SUPPORT +config ASH_RANDOM_SUPPORT bool "Pseudorandom generator and variable $RANDOM" default n - depends on CONFIG_ASH + depends on ASH help Enable pseudorandom generator and dynamic variable "$RANDOM". Each read of "$RANDOM" will generate a new pseudorandom value. @@ -151,21 +151,21 @@ config CONFIG_ASH_RANDOM_SUPPORT After "unset RANDOM" then generator will switch off and this variable will no longer have special treatment. -config CONFIG_ASH_EXPAND_PRMT +config ASH_EXPAND_PRMT bool "Expand prompt string" default n - depends on CONFIG_ASH + depends on ASH help "PS#" may be contain volatile content, such as backquote commands. This option recreates the prompt string from the environment variable each time it is displayed. -config CONFIG_HUSH +config HUSH bool "hush" default n - select CONFIG_TRUE - select CONFIG_FALSE - select CONFIG_TEST + select TRUE + select FALSE + select TEST help hush is a very small shell (just 18k) and it has fairly complete Bourne shell grammar. It even handles all the normal flow control @@ -177,12 +177,12 @@ config CONFIG_HUSH expansion, &> and >& redirection of stdout+stderr, etc. -config CONFIG_LASH +config LASH bool "lash" default n - select CONFIG_TRUE - select CONFIG_FALSE - select CONFIG_TEST + select TRUE + select FALSE + select TEST help lash is the very smallest shell (adds just 10k) and it is quite usable as a command prompt, but it is not suitable for any but the @@ -192,12 +192,12 @@ config CONFIG_LASH command editing makes it a very nice lightweight command prompt. -config CONFIG_MSH +config MSH bool "msh" default n - select CONFIG_TRUE - select CONFIG_FALSE - select CONFIG_TEST + select TRUE + select FALSE + select TEST help The minix shell (adds just 30k) is quite complete and handles things like for/do/done, case/esac and all the things you expect a Bourne @@ -207,19 +207,19 @@ config CONFIG_MSH It also uses only vfork, so it can be used on uClinux systems. comment "Bourne Shell Options" - depends on CONFIG_MSH || CONFIG_LASH || CONFIG_HUSH || CONFIG_ASH + depends on MSH || LASH || HUSH || ASH -config CONFIG_FEATURE_SH_EXTRA_QUIET +config FEATURE_SH_EXTRA_QUIET bool "Hide message on interactive shell startup" default n - depends on CONFIG_MSH || CONFIG_LASH || CONFIG_HUSH || CONFIG_ASH + depends on MSH || LASH || HUSH || ASH help Remove the busybox introduction when starting a shell. -config CONFIG_FEATURE_SH_STANDALONE_SHELL +config FEATURE_SH_STANDALONE_SHELL bool "Standalone shell" default n - depends on CONFIG_MSH || CONFIG_LASH || CONFIG_HUSH || CONFIG_ASH + depends on MSH || LASH || HUSH || ASH help This option causes the selected busybox shell to use busybox applets in preference to executables in the PATH whenever possible. For @@ -240,53 +240,53 @@ config CONFIG_FEATURE_SH_STANDALONE_SHELL that exact location with that exact name, this option will not work at all. -config CONFIG_FEATURE_COMMAND_EDITING +config FEATURE_COMMAND_EDITING bool "Command line editing" default n - depends on CONFIG_MSH || CONFIG_LASH || CONFIG_HUSH || CONFIG_ASH + depends on MSH || LASH || HUSH || ASH help Enable command editing in shell. -config CONFIG_FEATURE_COMMAND_EDITING_VI +config FEATURE_COMMAND_EDITING_VI bool "vi-style line editing commands" default n - depends on CONFIG_FEATURE_COMMAND_EDITING + depends on FEATURE_COMMAND_EDITING help Enable vi-style line editing in the shell. This mode can be turned on and off with "set -o vi" and "set +o vi". -config CONFIG_FEATURE_COMMAND_HISTORY +config FEATURE_COMMAND_HISTORY int "History size" default 15 - depends on CONFIG_FEATURE_COMMAND_EDITING + depends on FEATURE_COMMAND_EDITING help Specify command history size in shell. -config CONFIG_FEATURE_COMMAND_SAVEHISTORY +config FEATURE_COMMAND_SAVEHISTORY bool "History saving" default n - depends on CONFIG_ASH && CONFIG_FEATURE_COMMAND_EDITING + depends on ASH && FEATURE_COMMAND_EDITING help Enable history saving in ash shell. -config CONFIG_FEATURE_COMMAND_TAB_COMPLETION +config FEATURE_COMMAND_TAB_COMPLETION bool "Tab completion" default n - depends on CONFIG_FEATURE_COMMAND_EDITING + depends on FEATURE_COMMAND_EDITING help Enable tab completion in shell. -config CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION +config FEATURE_COMMAND_USERNAME_COMPLETION bool "Username completion" default n - depends on CONFIG_FEATURE_COMMAND_TAB_COMPLETION + depends on FEATURE_COMMAND_TAB_COMPLETION help Enable username completion in shell. -config CONFIG_FEATURE_SH_FANCY_PROMPT +config FEATURE_SH_FANCY_PROMPT bool "Fancy shell prompts" default n - depends on CONFIG_FEATURE_COMMAND_EDITING + depends on FEATURE_COMMAND_EDITING help Setting this option allows for prompts to use things like \w and \$ and also using escape codes. diff --git a/shell/Kbuild b/shell/Kbuild new file mode 100644 index 000000000..eb0199ee2 --- /dev/null +++ b/shell/Kbuild @@ -0,0 +1,12 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_ASH) += ash.o +lib-$(CONFIG_HUSH) += hush.o +lib-$(CONFIG_LASH) += lash.o +lib-$(CONFIG_MSH) += msh.o +lib-$(CONFIG_FEATURE_COMMAND_EDITING) += cmdedit.o diff --git a/shell/Makefile b/shell/Makefile deleted file mode 100644 index 9590f524e..000000000 --- a/shell/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/shell -SHELL_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) - diff --git a/shell/Makefile.in b/shell/Makefile.in deleted file mode 100644 index fcd93f345..000000000 --- a/shell/Makefile.in +++ /dev/null @@ -1,33 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -SHELL_AR:=shell.a -ifndef $(SHELL_DIR) -SHELL_DIR:=$(top_builddir)/shell/ -endif -srcdir=$(top_srcdir)/shell - -SHELLT-y:= -SHELLT-$(CONFIG_ASH) += ash.o -SHELLT-$(CONFIG_HUSH) += hush.o -SHELLT-$(CONFIG_LASH) += lash.o -SHELLT-$(CONFIG_MSH) += msh.o -SHELLT-$(CONFIG_FEATURE_COMMAND_EDITING) += cmdedit.o - -ifneq ($(strip $(SHELLT-y)),) -libraries-y+=$(SHELL_DIR)$(SHELL_AR) -endif - -SHELLT_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(SHELLT-y)) -SHELLT_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(SHELLT_SRC-y) -APPLET_SRC-a+=$(SHELLT_SRC-a) - -$(SHELL_DIR)$(SHELL_AR): $(patsubst %,$(SHELL_DIR)%, $(SHELLT-y)) - $(do_ar) - -$(SHELL_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/shell/ash.c b/shell/ash.c index 0d9fa7fe2..3564044b2 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -81,8 +81,6 @@ #include <time.h> #include <fnmatch.h> -#include "pwd_.h" - #ifdef CONFIG_ASH_JOB_CONTROL #define JOBS 1 #else diff --git a/shell/cmdedit.c b/shell/cmdedit.c index a9fc84798..7b4d46511 100644 --- a/shell/cmdedit.c +++ b/shell/cmdedit.c @@ -79,11 +79,6 @@ #define CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR #endif -#ifdef CONFIG_FEATURE_GETUSERNAME_AND_HOMEDIR -#include "pwd_.h" -#endif /* advanced FEATURES */ - - /* Maximum length of the linked list for the command line history */ #ifndef CONFIG_FEATURE_COMMAND_HISTORY #define MAX_HISTORY 15 diff --git a/sysklogd/Config.in b/sysklogd/Config.in index 399315208..9875b3c12 100644 --- a/sysklogd/Config.in +++ b/sysklogd/Config.in @@ -5,7 +5,7 @@ menu "System Logging Utilities" -config CONFIG_SYSLOGD +config SYSLOGD bool "syslogd" default n help @@ -20,18 +20,18 @@ config CONFIG_SYSLOGD wrong. And something almost always will go wrong if you wait long enough.... -config CONFIG_FEATURE_ROTATE_LOGFILE +config FEATURE_ROTATE_LOGFILE bool "Rotate message files" default n - depends on CONFIG_SYSLOGD + depends on SYSLOGD help This enables syslogd to rotate the message files on his own. No need to use an external rotatescript. -config CONFIG_FEATURE_REMOTE_LOG +config FEATURE_REMOTE_LOG bool "Remote Log support" default n - depends on CONFIG_SYSLOGD + depends on SYSLOGD help When you enable this feature, the syslogd utility can be used to send system log messages to another system @@ -42,10 +42,10 @@ config CONFIG_FEATURE_REMOTE_LOG measure to prevent system logs from being tampered with by an intruder. -config CONFIG_FEATURE_IPC_SYSLOG +config FEATURE_IPC_SYSLOG bool "Circular Buffer support" default n - depends on CONFIG_SYSLOGD + depends on SYSLOGD help When you enable this feature, the syslogd utility will use a circular buffer to record system log messages. @@ -56,28 +56,28 @@ config CONFIG_FEATURE_IPC_SYSLOG entire filesystem, which may cause your system to break badly. -config CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE +config FEATURE_IPC_SYSLOG_BUFFER_SIZE int " Circular buffer size in Kbytes (minimum 4KB)" default 16 - depends on CONFIG_FEATURE_IPC_SYSLOG + depends on FEATURE_IPC_SYSLOG help This option sets the size of the circular buffer used to record system log messages. -config CONFIG_LOGREAD +config LOGREAD bool "logread" default y - depends on CONFIG_FEATURE_IPC_SYSLOG + depends on FEATURE_IPC_SYSLOG help If you enabled Circular Buffer support, you almost certainly want to enable this feature as well. This utility will allow you to read the messages that are stored in the syslogd circular buffer. -config CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING +config FEATURE_LOGREAD_REDUCED_LOCKING bool "logread double buffering" default n - depends on CONFIG_LOGREAD + depends on LOGREAD help 'logread' ouput to slow serial terminals can have side effects on syslog because of the semaphore. @@ -85,11 +85,11 @@ config CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING from circular buffer, minimizing semaphore contention at some minor memory expense. -config CONFIG_KLOGD +config KLOGD bool "klogd" default n - depends on CONFIG_SYSLOGD - select CONFIG_FEATURE_SYSLOG + depends on SYSLOGD + select FEATURE_SYSLOG help klogd is a utility which intercepts and logs all messages from the Linux kernel and sends the messages @@ -97,10 +97,10 @@ config CONFIG_KLOGD you wish to record the messages produced by the kernel, you should enable this option. -config CONFIG_LOGGER +config LOGGER bool "logger" default n - select CONFIG_FEATURE_SYSLOG + select FEATURE_SYSLOG help The logger utility allows you to send arbitrary text messages to the system log (i.e. the 'syslogd' utility) so diff --git a/sysklogd/Kbuild b/sysklogd/Kbuild new file mode 100644 index 000000000..0d5b2b929 --- /dev/null +++ b/sysklogd/Kbuild @@ -0,0 +1,11 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_KLOGD) += klogd.o +lib-$(CONFIG_LOGGER) += logger.o +lib-$(CONFIG_LOGREAD) += logread.o +lib-$(CONFIG_SYSLOGD) += syslogd.o diff --git a/sysklogd/Makefile b/sysklogd/Makefile deleted file mode 100644 index 0ae4f1d35..000000000 --- a/sysklogd/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/sysklogd -SYSKLOGD_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) diff --git a/sysklogd/Makefile.in b/sysklogd/Makefile.in deleted file mode 100644 index 83f77be90..000000000 --- a/sysklogd/Makefile.in +++ /dev/null @@ -1,32 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -SYSKLOGD_AR:=sysklogd.a -ifndef $(SYSKLOGD_DIR) -SYSKLOGD_DIR:=$(top_builddir)/sysklogd/ -endif -srcdir=$(top_srcdir)/sysklogd - -SYSKLOGD-y:= -SYSKLOGD-$(CONFIG_KLOGD) += klogd.o -SYSKLOGD-$(CONFIG_LOGGER) += logger.o -SYSKLOGD-$(CONFIG_LOGREAD) += logread.o -SYSKLOGD-$(CONFIG_SYSLOGD) += syslogd.o - -ifneq ($(strip $(SYSKLOGD-y)),) -libraries-y+=$(SYSKLOGD_DIR)$(SYSKLOGD_AR) -endif - -SYSKLOGD_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(SYSKLOGD-y)) -SYSKLOGD_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(SYSKLOGD_SRC-y) -APPLET_SRC-a+=$(SYSKLOGD_SRC-a) - -$(SYSKLOGD_DIR)$(SYSKLOGD_AR): $(patsubst %,$(SYSKLOGD_DIR)%, $(SYSKLOGD-y)) - $(do_ar) - -$(SYSKLOGD_DIR)%.o: $(srcdir)/%.c - $(compile.c) diff --git a/util-linux/Config.in b/util-linux/Config.in index a215e250f..a6640e19d 100644 --- a/util-linux/Config.in +++ b/util-linux/Config.in @@ -5,7 +5,7 @@ menu "Linux System Utilities" -config CONFIG_DMESG +config DMESG bool "dmesg" default n help @@ -17,10 +17,10 @@ config CONFIG_DMESG are also logged to the system console. Enable this option if you wish to enable the 'dmesg' utility. -config CONFIG_FEATURE_DMESG_PRETTY +config FEATURE_DMESG_PRETTY bool "pretty dmesg output" default y - depends on CONFIG_DMESG + depends on DMESG help If you wish to scrub the syslog level from the output, say 'Y' here. The syslog level is a string prefixed to every line with the form "<#>". @@ -37,7 +37,7 @@ config CONFIG_FEATURE_DMESG_PRETTY <6>BIOS-provided physical RAM map: <6> BIOS-e820: 0000000000000000 - 000000000009f000 (usable) -config CONFIG_FBSET +config FBSET bool "fbset" default n help @@ -46,26 +46,26 @@ config CONFIG_FBSET interface to access a graphics display. Enable this option if you wish to enable the 'fbset' utility. -config CONFIG_FEATURE_FBSET_FANCY +config FEATURE_FBSET_FANCY bool "Turn on extra fbset options" default n - depends on CONFIG_FBSET + depends on FBSET help This option enables extended fbset options, allowing one to set the framebuffer size, color depth, etc. interface to access a graphics display. Enable this option if you wish to enable extended fbset options. -config CONFIG_FEATURE_FBSET_READMODE +config FEATURE_FBSET_READMODE bool "Turn on fbset readmode support" default n - depends on CONFIG_FBSET + depends on FBSET help This option allows fbset to read the video mode database stored by default as /etc/fb.modes, which can be used to set frame buffer device to pre-defined video modes. -config CONFIG_FDFLUSH +config FDFLUSH bool "fdflush" default n help @@ -77,13 +77,13 @@ config CONFIG_FDFLUSH you change a disk. Most people have working hardware and can safely leave this disabled. -config CONFIG_FDFORMAT +config FDFORMAT bool "fdformat" default n help fdformat is used to low-level format a floppy disk. -config CONFIG_FDISK +config FDISK bool "fdisk" default n help @@ -95,62 +95,62 @@ config CONFIG_FDISK config FDISK_SUPPORT_LARGE_DISKS bool "support over 4GB disks" default y - depends on CONFIG_FDISK + depends on FDISK help Enable this option to support large disks > 4GB. -config CONFIG_FEATURE_FDISK_WRITABLE +config FEATURE_FDISK_WRITABLE bool "Write support" default y - depends on CONFIG_FDISK + depends on FDISK help Enabling this option allows you to create or change a partition table and write those changes out to disk. If you leave this option disabled, you will only be able to view the partition table. -config CONFIG_FEATURE_AIX_LABEL +config FEATURE_AIX_LABEL bool "Support AIX disklabels" default n - depends on CONFIG_FDISK && CONFIG_FEATURE_FDISK_WRITABLE + depends on FDISK && FEATURE_FDISK_WRITABLE help Enabling this option allows you to create or change AIX disklabels. Most people can safely leave this option disabled. -config CONFIG_FEATURE_SGI_LABEL +config FEATURE_SGI_LABEL bool "Support SGI disklabels" default n - depends on CONFIG_FDISK && CONFIG_FEATURE_FDISK_WRITABLE + depends on FDISK && FEATURE_FDISK_WRITABLE help Enabling this option allows you to create or change SGI disklabels. Most people can safely leave this option disabled. -config CONFIG_FEATURE_SUN_LABEL +config FEATURE_SUN_LABEL bool "Support SUN disklabels" default n - depends on CONFIG_FDISK && CONFIG_FEATURE_FDISK_WRITABLE + depends on FDISK && FEATURE_FDISK_WRITABLE help Enabling this option allows you to create or change SUN disklabels. Most people can safely leave this option disabled. -config CONFIG_FEATURE_OSF_LABEL +config FEATURE_OSF_LABEL bool "Support BSD disklabels" default n - depends on CONFIG_FDISK && CONFIG_FEATURE_FDISK_WRITABLE + depends on FDISK && FEATURE_FDISK_WRITABLE help Enabling this option allows you to create or change BSD disklabels and define and edit BSD disk slices. -config CONFIG_FEATURE_FDISK_ADVANCED +config FEATURE_FDISK_ADVANCED bool "Support expert mode" default n - depends on CONFIG_FDISK && CONFIG_FEATURE_FDISK_WRITABLE + depends on FDISK && FEATURE_FDISK_WRITABLE help Enabling this option allows you to do terribly unsafe things like define arbitrary drive geometry, move the beginning of data in a partition, and similarly evil things. Unless you have a very good reason you would be wise to leave this disabled. -config CONFIG_FREERAMDISK +config FREERAMDISK bool "freeramdisk" default n help @@ -161,7 +161,7 @@ config CONFIG_FREERAMDISK ramdisk. If you have no use for freeing memory from a ramdisk, leave this disabled. -config CONFIG_FSCK_MINIX +config FSCK_MINIX bool "fsck_minix" default n help @@ -172,7 +172,7 @@ config CONFIG_FSCK_MINIX check for and attempt to repair any corruption that occurs to a minix filesystem. -config CONFIG_MKFS_MINIX +config MKFS_MINIX bool "mkfs_minix" default n help @@ -181,18 +181,18 @@ config CONFIG_MKFS_MINIX this utility will do the job for you. comment "Minix filesystem support" - depends on CONFIG_FSCK_MINIX || CONFIG_MKFS_MINIX + depends on FSCK_MINIX || MKFS_MINIX -config CONFIG_FEATURE_MINIX2 +config FEATURE_MINIX2 bool "Support Minix fs v2 (fsck_minix/mkfs_minix)" default y - depends on CONFIG_FSCK_MINIX || CONFIG_MKFS_MINIX + depends on FSCK_MINIX || MKFS_MINIX help If you wish to be able to create version 2 minix filesystems, enable this. If you enabled 'mkfs_minix' then you almost certainly want to be using the version 2 filesystem support. -config CONFIG_GETOPT +config GETOPT bool "getopt" default n help @@ -203,14 +203,14 @@ config CONFIG_GETOPT written by others, this utility may be for you. Most people will wisely leave this disabled. -config CONFIG_HEXDUMP +config HEXDUMP bool "hexdump" default n help The hexdump utility is used to display binary data in a readable way that is comparable to the output from most hex editors. -config CONFIG_HWCLOCK +config HWCLOCK bool "hwclock" default n help @@ -219,19 +219,19 @@ config CONFIG_HWCLOCK shutdown in the hardware clock, so the hardware will keep the correct time when Linux is _not_ running. -config CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS +config FEATURE_HWCLOCK_LONG_OPTIONS bool "Support long options (--hctosys,...)" default n - depends on CONFIG_HWCLOCK && CONFIG_GETOPT_LONG + depends on HWCLOCK && GETOPT_LONG help By default, the hwclock utility only uses short options. If you are overly fond of its long options, such as --hctosys, --utc, etc) then enable this option. -config CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS +config FEATURE_HWCLOCK_ADJTIME_FHS bool "Use FHS /var/lib/hwclock/adjtime" default y - depends on CONFIG_HWCLOCK + depends on HWCLOCK help Starting with FHS 2.3, the adjtime state file is supposed to exist at /var/lib/hwclock/adjtime instead of /etc/adjtime. If you wish @@ -240,24 +240,24 @@ config CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS http://www.pathname.com/fhs/pub/fhs-2.3.html#VARLIBHWCLOCKSTATEDIRECTORYFORHWCLO -config CONFIG_IPCRM +config IPCRM bool "ipcrm" default n - select CONFIG_FEATURE_SUID + select FEATURE_SUID help The ipcrm utility allows the removal of System V interprocess communication (IPC) objects and the associated data structures from the system. -config CONFIG_IPCS +config IPCS bool "ipcs" default n - select CONFIG_FEATURE_SUID + select FEATURE_SUID help The ipcs utility is used to provide information on the currently allocated System V interprocess (IPC) objects in the system. -config CONFIG_LOSETUP +config LOSETUP bool "losetup" default n help @@ -265,7 +265,7 @@ config CONFIG_LOSETUP file or block device, and to query the status of a loop device. This version does not currently support enabling data encryption. -config CONFIG_MDEV +config MDEV bool "mdev" default n help @@ -274,10 +274,10 @@ config CONFIG_MDEV have it handle hotplug events afterwards. Device names are taken from sysfs. -config CONFIG_FEATURE_MDEV_CONF +config FEATURE_MDEV_CONF bool "Support /etc/mdev.conf" default n - depends on CONFIG_MDEV + depends on MDEV help The mdev config file contains lines that look like: @@ -289,10 +289,10 @@ config CONFIG_FEATURE_MDEV_CONF entry is matched, devices are created with default 0:0 660. (Make the last line match .* to override this.) -config CONFIG_FEATURE_MDEV_EXEC +config FEATURE_MDEV_EXEC bool "Support command execution at device addition/removal" default n - depends on CONFIG_FEATURE_MDEV_CONF + depends on FEATURE_MDEV_CONF help This adds support for an optional field to /etc/mdev.conf, consisting of a special character and a command line to run after creating the @@ -310,7 +310,7 @@ config CONFIG_FEATURE_MDEV_EXEC Commands are executed via system() so you need /bin/sh, meaning you probably want to select a default shell in the Shells menu. -config CONFIG_MKSWAP +config MKSWAP bool "mkswap" default n help @@ -323,17 +323,17 @@ config CONFIG_MKSWAP Once you have created swap space using 'mkswap' you need to enable the swap space using the 'swapon' utility. -config CONFIG_FEATURE_MKSWAP_V0 +config FEATURE_MKSWAP_V0 bool "version 0 support" default n - depends on CONFIG_MKSWAP -# depends on CONFIG_MKSWAP && CONFIG_DEPRECATED + depends on MKSWAP +# depends on MKSWAP && DEPRECATED help Enable support for the old v0 style. If your kernel is older than 2.1.117, then v0 support is the only option. -config CONFIG_MORE +config MORE bool "more" default n help @@ -343,10 +343,10 @@ config CONFIG_MORE you will probably find this utility very helpful. If you don't have any need to reading text files, you can leave this disabled. -config CONFIG_FEATURE_USE_TERMIOS +config FEATURE_USE_TERMIOS bool "Use termios to manipulate the screen" default y - depends on CONFIG_MORE + depends on MORE help This option allows utilities such as 'more' and 'top' to determine the size of the screen. If you leave this disabled, your utilities @@ -354,7 +354,7 @@ config CONFIG_FEATURE_USE_TERMIOS will be unable to determine the current screen size, and will be unable to move the cursor. -config CONFIG_MOUNT +config MOUNT bool "mount" default n help @@ -365,23 +365,23 @@ config CONFIG_MOUNT NFS filesystems. Most people using BusyBox will also want to enable the 'mount' utility. -config CONFIG_FEATURE_MOUNT_NFS +config FEATURE_MOUNT_NFS bool "Support mounting NFS file systems" default n - depends on CONFIG_MOUNT - select CONFIG_FEATURE_SYSLOG + depends on MOUNT + select FEATURE_SYSLOG help Enable mounting of NFS file systems. -config CONFIG_FEATURE_MOUNT_CIFS +config FEATURE_MOUNT_CIFS bool "Support mounting CIFS/SMB file systems" default n - depends on CONFIG_MOUNT + depends on MOUNT help Enable support for samba mounts. -config CONFIG_FEATURE_MOUNT_FLAGS - depends on CONFIG_MOUNT +config FEATURE_MOUNT_FLAGS + depends on MOUNT bool "Support lots of -o flags in mount" default y help @@ -390,14 +390,14 @@ config CONFIG_FEATURE_MOUNT_FLAGS noatime, diratime, nodiratime, loud, bind, move, shared, slave, private, unbindable, rshared, rslave, rprivate, and runbindable. -config CONFIG_FEATURE_MOUNT_FSTAB - depends on CONFIG_MOUNT +config FEATURE_MOUNT_FSTAB + depends on MOUNT bool "Support /etc/fstab and -a" default y help Support mount all and looking for files in /etc/fstab. -config CONFIG_PIVOT_ROOT +config PIVOT_ROOT bool "pivot_root" default n help @@ -409,7 +409,7 @@ config CONFIG_PIVOT_ROOT Note: This is for initrd in linux 2.4. Under initramfs (introduced in linux 2.6) use switch_root instead. -config CONFIG_RDATE +config RDATE bool "rdate" default n help @@ -418,13 +418,13 @@ config CONFIG_RDATE the RFC868 protocol, which is built into the inetd daemon on most systems. -config CONFIG_READPROFILE +config READPROFILE bool "readprofile" default n help This allows you to parse /proc/profile for basic profiling. -config CONFIG_SETARCH +config SETARCH bool "setarch" default n help @@ -433,7 +433,7 @@ config CONFIG_SETARCH this util on a system that supports both 64bit and 32bit userland (like amd64/x86, ppc64/ppc, sparc64/sparc, etc...). -config CONFIG_SWAPONOFF +config SWAPONOFF bool "swaponoff" default n help @@ -444,7 +444,7 @@ config CONFIG_SWAPONOFF space. If you are not using any swap space, you can leave this option disabled. -config CONFIG_SWITCH_ROOT +config SWITCH_ROOT bool "switch_root" default n help @@ -463,7 +463,7 @@ config CONFIG_SWITCH_ROOT and ending point for searching through the kernel's doubly linked list of active mount points. That's why. -config CONFIG_UMOUNT +config UMOUNT bool "umount" default n help @@ -472,20 +472,20 @@ config CONFIG_UMOUNT the tool to use. If you enabled the 'mount' utility, you almost certainly also want to enable 'umount'. -config CONFIG_FEATURE_UMOUNT_ALL +config FEATURE_UMOUNT_ALL bool "umount -a option" default n - depends on CONFIG_UMOUNT + depends on UMOUNT help Support -a option to unmount all currently mounted filesystems. comment "Common options for mount/umount" - depends on CONFIG_MOUNT || CONFIG_UMOUNT + depends on MOUNT || UMOUNT -config CONFIG_FEATURE_MOUNT_LOOP +config FEATURE_MOUNT_LOOP bool "Support loopback mounts" default n - depends on CONFIG_MOUNT || CONFIG_UMOUNT + depends on MOUNT || UMOUNT help Enabling this feature allows automatic mounting of files (containing filesystem images) via the linux kernel's loopback devices. The mount @@ -498,10 +498,10 @@ config CONFIG_FEATURE_MOUNT_LOOP specify an offset or cryptographic options to the loopback device. (If you don't want umount to free the loop device, use "umount -D".) -config CONFIG_FEATURE_MTAB_SUPPORT +config FEATURE_MTAB_SUPPORT bool "Support for the old /etc/mtab file" default n - depends on CONFIG_MOUNT || CONFIG_UMOUNT + depends on MOUNT || UMOUNT help Historically, Unix systems kept track of the currently mounted partitions in the file "/etc/mtab". These days, the kernel exports diff --git a/util-linux/Kbuild b/util-linux/Kbuild new file mode 100644 index 000000000..cc1d0e05d --- /dev/null +++ b/util-linux/Kbuild @@ -0,0 +1,32 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> +# +# Licensed under the GPL v2, see the file LICENSE in this tarball. + +lib-y:= +lib-$(CONFIG_DMESG) +=dmesg.o +lib-$(CONFIG_FBSET) +=fbset.o +lib-$(CONFIG_FDFLUSH) +=freeramdisk.o +lib-$(CONFIG_FDFORMAT) +=fdformat.o +lib-$(CONFIG_FDISK) +=fdisk.o +lib-$(CONFIG_FREERAMDISK) +=freeramdisk.o +lib-$(CONFIG_FSCK_MINIX) +=fsck_minix.o +lib-$(CONFIG_GETOPT) +=getopt.o +lib-$(CONFIG_HEXDUMP) +=hexdump.o +lib-$(CONFIG_HWCLOCK) +=hwclock.o +lib-$(CONFIG_IPCRM) +=ipcrm.o +lib-$(CONFIG_IPCS) +=ipcs.o +lib-$(CONFIG_LOSETUP) +=losetup.o +lib-$(CONFIG_MDEV) +=mdev.o +lib-$(CONFIG_MKFS_MINIX) +=mkfs_minix.o +lib-$(CONFIG_MKSWAP) +=mkswap.o +lib-$(CONFIG_MORE) +=more.o +lib-$(CONFIG_MOUNT) +=mount.o +lib-$(CONFIG_PIVOT_ROOT) +=pivot_root.o +lib-$(CONFIG_RDATE) +=rdate.o +lib-$(CONFIG_READPROFILE) +=readprofile.o +lib-$(CONFIG_SETARCH) +=setarch.o +lib-$(CONFIG_SWAPONOFF) +=swaponoff.o +lib-$(CONFIG_SWITCH_ROOT) +=switch_root.o +lib-$(CONFIG_UMOUNT) +=umount.o diff --git a/util-linux/Makefile b/util-linux/Makefile deleted file mode 100644 index 9a53470a4..000000000 --- a/util-linux/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -ifndef top_srcdir -top_srcdir=.. -endif -ifndef top_builddir -top_builddir=.. -endif -srcdir=$(top_srcdir)/util-linux -UTILLINUX_DIR:=./ -include $(top_srcdir)/Rules.mak -include $(top_builddir)/.config -include Makefile.in -all: $(libraries-y) --include $(top_builddir)/.depend - -clean: - rm -f *.o *.a $(AR_TARGET) diff --git a/util-linux/Makefile.in b/util-linux/Makefile.in deleted file mode 100644 index 3d6c96a35..000000000 --- a/util-linux/Makefile.in +++ /dev/null @@ -1,62 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> -# -# Licensed under the GPL v2, see the file LICENSE in this tarball. - -UTILLINUX_AR:=util-linux.a -ifndef $(UTILLINUX_DIR) -UTILLINUX_DIR:=$(top_builddir)/util-linux/ -endif -srcdir=$(top_srcdir)/util-linux - -UTILLINUX-y:= -UTILLINUX-$(CONFIG_DMESG) +=dmesg.o -UTILLINUX-$(CONFIG_FBSET) +=fbset.o -UTILLINUX-$(CONFIG_FDFLUSH) +=freeramdisk.o -UTILLINUX-$(CONFIG_FDFORMAT) +=fdformat.o -UTILLINUX-$(CONFIG_FDISK) +=fdisk.o -UTILLINUX-$(CONFIG_FREERAMDISK) +=freeramdisk.o -UTILLINUX-$(CONFIG_FSCK_MINIX) +=fsck_minix.o -UTILLINUX-$(CONFIG_GETOPT) +=getopt.o -UTILLINUX-$(CONFIG_HEXDUMP) +=hexdump.o -UTILLINUX-$(CONFIG_HWCLOCK) +=hwclock.o -UTILLINUX-$(CONFIG_IPCRM) +=ipcrm.o -UTILLINUX-$(CONFIG_IPCS) +=ipcs.o -UTILLINUX-$(CONFIG_LOSETUP) +=losetup.o -UTILLINUX-$(CONFIG_MDEV) +=mdev.o -UTILLINUX-$(CONFIG_MKFS_MINIX) +=mkfs_minix.o -UTILLINUX-$(CONFIG_MKSWAP) +=mkswap.o -UTILLINUX-$(CONFIG_MORE) +=more.o -UTILLINUX-$(CONFIG_MOUNT) +=mount.o -UTILLINUX-$(CONFIG_PIVOT_ROOT) +=pivot_root.o -UTILLINUX-$(CONFIG_RDATE) +=rdate.o -UTILLINUX-$(CONFIG_READPROFILE) +=readprofile.o -UTILLINUX-$(CONFIG_SETARCH) +=setarch.o -UTILLINUX-$(CONFIG_SWAPONOFF) +=swaponoff.o -UTILLINUX-$(CONFIG_SWITCH_ROOT) +=switch_root.o -UTILLINUX-$(CONFIG_UMOUNT) +=umount.o - -UTILLINUX-y:=$(sort $(UTILLINUX-y)) - -ifneq ($(strip $(UTILLINUX-y)),) -libraries-y+=$(UTILLINUX_DIR)$(UTILLINUX_AR) -endif - -UTILLINUX_SRC-y:=$(patsubst %.o,$(srcdir)/%.c,$(UTILLINUX-y)) -UTILLINUX_SRC-a:=$(wildcard $(srcdir)/*.c) -APPLET_SRC-y+=$(UTILLINUX_SRC-y) -APPLET_SRC-a+=$(UTILLINUX_SRC-a) - -$(UTILLINUX_DIR)$(UTILLINUX_AR): $(patsubst %,$(UTILLINUX_DIR)%, $(UTILLINUX-y)) - $(do_ar) - -$(UTILLINUX_DIR)%.o: $(srcdir)/%.c - $(compile.c) - -ifneq ($(strip $(CONFIG_LFS)),y) -ifeq ($(strip $(FDISK_SUPPORT_LARGE_DISKS)),y) -$(UTILLINUX_DIR)fdisk.o: $(srcdir)/fdisk.c - $(compile.c) -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -endif -endif