Update to ct-ng 1.22.

Minor bump of support packages.
This commit is contained in:
Solomon Peachy 2016-07-12 20:23:21 -04:00
parent e2cea27d58
commit 6068e5eb44
916 changed files with 110429 additions and 173895 deletions

3
BUILD
View File

@ -7,7 +7,8 @@ Pre-requisites for building:
yum -y install git zip gcc gcc-c++ make bison flex gperf texinfo wget \
patch libtool ncurses-devel xz zlib-devel \
glibc-static libstdc++-static expat-devel python-devel
glibc-static libstdc++-static expat-devel python-devel \
help2man
Debian/Ubuntu

View File

@ -22,3 +22,5 @@ build.log
.build/
# .. and the legacy location
targets/
# .. and log for 'build-all'
.build-all

45
crosstool-ng/.travis.sh Normal file
View File

@ -0,0 +1,45 @@
# Add current directory to PATH
export PATH="$(pwd):$PATH"
# Manage the travis build
ct-ng_travis_build()
{
# Override the log behaviour
sed -i -e 's/^.*\(CT_LOG_ERROR\).*$/# \1 is not set/' \
-e 's/^.*\(CT_LOG_WARN\).*$/# \1 is not set/' \
-e 's/^.*\(CT_LOG_INFO\).*$/# \1 is not set/' \
-e 's/^.*\(CT_LOG_EXTRA\).*$/\1=y/' \
-e 's/^.*\(CT_LOG_ALL\).*$/# \1 is not set/' \
-e 's/^.*\(CT_LOG_DEBUG\).*$/# \1 is not set/' \
-e 's/^.*\(CT_LOG_LEVEL_MAX\).*$/\1="EXTRA"/' \
-e 's/^.*\(CT_LOG_PROGRESS_BAR\).*$/# \1 is not set/' \
-e 's/^.*\(CT_LOCAL_TARBALLS_DIR\).*$/\1="${HOME}\/src"/' \
-e 's/^.*\(CT_SAVE_TARBALLS\).*$/\1=y/' \
.config
# Build the sample
ct-ng build.2 &
local build_pid=$!
# Start a runner task to print a "still running" line every 5 minutes
# to avoid travis to think that the build is stuck
{
while true
do
sleep 300
printf "Crosstool-NG is still running ...\r"
done
} &
local runner_pid=$!
# Wait for the build to finish and get the result
wait $build_pid 2>/dev/null
local result=$?
# Stop the runner task
kill $runner_pid
wait $runner_pid 2>/dev/null
# Return the result
return $result
}

56
crosstool-ng/.travis.yml Normal file
View File

@ -0,0 +1,56 @@
# Using container-based infrastructure
sudo: false
# 'bash' will define a generic environment without interfering environment
# settings like "CC=gcc"
language: bash
# Only build the master branch
branches:
only:
- master
# Caching the downloaded src packages between several builds to save travis-ci
# download time and bandwidth
cache:
directories:
- $HOME/src
# Installing needed dependencies
addons:
apt:
packages:
- bison
- flex
- gperf
- libncurses5-dev
- texinfo
- help2man
# Building crosstool-NG core
install:
- ./bootstrap
- ./configure --enable-local
- make
# Here is the list of all the standard samples tracked
# by the continuous integration system
env:
- CT_SAMPLE=arm-unknown-eabi
- CT_SAMPLE=arm-unknown-linux-gnueabi
- CT_SAMPLE=armeb-unknown-linux-gnueabi
- CT_SAMPLE=arm-unknown-linux-musleabi
- CT_SAMPLE=mips64el-n64-linux-uclibc
- CT_SAMPLE=powerpc-e500v2-linux-gnuspe
- CT_SAMPLE=x86_64-unknown-linux-uclibc
- CT_SAMPLE=xtensa-unknown-linux-uclibc
# Building the standard samples
script:
- . ./.travis.sh # Load the travis environment
- ct-ng $CT_SAMPLE # Configure the build
- ct-ng_travis_build # Build the sample
# On failure displaying the last lines of the log file
after_failure:
- tail -n 1000 build.log

View File

@ -75,6 +75,7 @@ export CPPFLAGS := @CPPFLAGS@
export CFLAGS := @CFLAGS@
export LDFLAGS := @LDFLAGS@
export LIBS := @LIBS@
export INTL_LIBS := @INTL_LIBS@
export curses_hdr := @ac_ct_curses_hdr@
export gettext := @gettext@
@ -381,7 +382,7 @@ install-post:
#--------------------------------------
# Uninstall rules
real-uninstall: $(patsubst %,uninstall-%,$(TARGETS))
real-uninstall: $(patsubst %,uninstall-%,$(filter-out lib-kconfig,$(TARGETS)))
uninstall-bin:
@echo " RM '$(DESTDIR)$(bindir)/$(PROG_NAME)'"

View File

@ -1,29 +0,0 @@
This is the README for crosstool-NG
Crosstool-NG follows the autoconf dance. So, to get you
kick-started, just run:
./configure --help
If you are using a development snapshot, you'll have to
create the configure script, first. Just run:
./bootstrap
You will find the documentation in the directory 'docs'.
Here is a quick overview of what you'll find there:
0 - Table of content
1 - Introduction
2 - Installing crosstool-NG
3 - Configuring a toolchain
4 - Building the toolchain
5 - Using the toolchain
6 - Toolchain types
7 - Contributing
8 - Internals
A - Credits
B - Known issues
C - Misc. tutorials
You can also point your browser at:
http://crosstool-ng.org/
Aloha!

38
crosstool-ng/README.md Normal file
View File

@ -0,0 +1,38 @@
# Crosstool-NG [![Build Status][travis-status]][travis]
Crosstool-NG follows the `autoconf` dance. So, to get you
kick-started, just run:
./configure --help
If you are using a development snapshot, you'll have to
create the configure script, first. Just run:
./bootstrap
You will find the documentation in the directory `docs`.
Here is a quick overview of what you'll find there:
<ol start="0">
<li>Table of content</li>
<li>Introduction</li>
<li>Installing crosstool-NG</li>
<li>Configuring a toolchain</li>
<li>Building the toolchain</li>
<li>Using the toolchain</li>
<li>Toolchain types</li>
<li>Contributing</li>
<li>Internals</li>
</ol>
<ol type="A">
<li>Credits</li>
<li>Known issues</li>
<li>Misc. tutorials</li>
</ol>
You can also point your browser at: http://crosstool-ng.org
Aloha!
[travis-status]: https://travis-ci.org/crosstool-ng/crosstool-ng.svg
[travis]: https://travis-ci.org/crosstool-ng/crosstool-ng

View File

@ -10,7 +10,6 @@ Recurring tasks:
Non-recurring tasks:
- update newlib (for enhanced bare metal)
- confirm existing implementation on targets other than AVR32
- try to make it generic, will help for uClibc++
- multilib

View File

@ -9,6 +9,7 @@
## select ARCH_DEFAULT_LE
## select ARCH_SUPPORTS_WITH_ARCH
## select ARCH_SUPPORTS_WITH_CPU
## select ARCH_EXCLUSIVE_WITH_CPU
## select ARCH_SUPPORTS_WITH_TUNE
## select ARCH_SUPPORTS_WITH_FLOAT if ARCH_32
## select ARCH_SUPPORTS_WITH_FPU if ARCH_32

View File

@ -1,13 +0,0 @@
# AVR32 specific configuration file
## select ARCH_SUPPORTS_32
## select ARCH_DEFAULT_32
## select ARCH_USE_MMU
## select ARCH_DEFAULT_BE
## select ARCH_SUPPORTS_WITH_ARCH
## select ARCH_SUPPORTS_WITH_CPU
## select ARCH_SUPPORTS_WITH_TUNE
## select ARCH_SUPPORTS_WITH_FPU
##
## help The AVR32 architecture, as defined by:
## help http://www.atmel.com/products/avr32

View File

@ -1,11 +0,0 @@
# Blackfin specific configuration file
## select ARCH_SUPPORTS_32
## select ARCH_DEFAULT_32
## select ARCH_DEFAULT_LE
## select ARCH_SUPPORTS_WITH_ARCH
## select ARCH_SUPPORTS_WITH_CPU
## select ARCH_SUPPORTS_WITH_TUNE
## select ARCH_SUPPORTS_WITH_FPU
##
## help The Blackfin architecture

View File

@ -1,7 +1,7 @@
# MIPS specific config options
## select ARCH_SUPPORTS_32
## select ARCH_SUPPORTS_64 if EXPERIMENTAL
## select ARCH_SUPPORTS_64
## select ARCH_DEFAULT_32
## select ARCH_USE_MMU
## select ARCH_SUPPORTS_BOTH_ENDIAN

View File

@ -0,0 +1,20 @@
# xtensa specific configuration file
## select ARCH_SUPPORTS_32
## select ARCH_SUPPORTS_BOTH_MMU
## select ARCH_DEFAULT_HAS_MMU
##
## help The xtensa architecture
## help
## help Xtensa is a configurable and extensible processor architecture.
## help Supporting a specific configuration typically requires minor
## help modifications to a small set of configuration files in various
## help development tools. This process is automated and only requires
## help a configuration specific 'overlay' file.
## help
## help For a custom configuration, select the XTENSA_CUSTOM option and
## help provide the name of the processor configuration through the
## help CT_ARCH_XTENSA_CUSTOM_NAME option.
## help
## help The default option (ARCH_xtensa_fsf) uses a built-in configuration,
## help which may or may not work for a particular Xtensa processor.

View File

@ -0,0 +1,32 @@
choice
prompt "Target Architecture Variant"
default ARCH_xtensa_fsf
config XTENSA_CUSTOM
bool "Custom Xtensa processor configuration"
config ARCH_xtensa_fsf
bool "fsf - Default configuration"
endchoice
config ARCH_XTENSA_CUSTOM_NAME
string "Custom Xtensa processor configuration name"
depends on XTENSA_CUSTOM
default ""
help
Enter the name of the custom processor configuration.
Overlay file for that configuration must be called
'xtensa_<CUSTOM_NAME>.tar'.
Leave blank to use the default 'xtensa-overlay.tar'.
For more information about this option, please also consult
section 'Using crosstool-NG to build Xtensa toolchains' in the
docs/C - Misc. tutorials.txt
config ARCH_XTENSA_CUSTOM_OVERLAY_LOCATION
string "Full path to custom Xtensa processor configurations"
depends on XTENSA_CUSTOM
default ""
help
Enter the path to the directory for the custom processor
configuration file or leave blank to use the default location:
CT_CUSTOM_LOCATION_ROOT_DIR

View File

@ -8,6 +8,8 @@ config BACKEND
bool
default y if IS_A_BACKEND = "y" || IS_A_BACKEND = "Y"
if BACKEND
config BACKEND_ARCH
string
option env="CT_BACKEND_ARCH"
@ -19,3 +21,5 @@ config BACKEND_KERNEL
config BACKEND_LIBC
string
option env="CT_BACKEND_LIBC"
endif #if BACKEND

View File

@ -25,6 +25,11 @@ choice
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config BINUTILS_V_2_25_1
bool
prompt "2.25.1"
select BINUTILS_2_25_1_or_later
config BINUTILS_LINARO_V_2_25
bool
prompt "linaro-2.25.0-2015.01-2"
@ -87,13 +92,12 @@ config BINUTILS_V_2_18a
prompt "2.18a"
select BINUTILS_2_18_or_later
endchoice
config BINUTILS_CUSTOM
bool
prompt "Custom binutils"
depends on EXPERIMENTAL
select BINUTILS_2_22_or_later
endchoice
if BINUTILS_CUSTOM
@ -111,6 +115,7 @@ config BINUTILS_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "2.25.1" if BINUTILS_V_2_25_1
default "linaro-2.25.0-2015.01-2" if BINUTILS_LINARO_V_2_25
default "2.25" if BINUTILS_V_2_25
default "linaro-2.24.0-2014.11-2" if BINUTILS_LINARO_V_2_24
@ -123,7 +128,10 @@ config BINUTILS_VERSION
default "2.20.1a" if BINUTILS_V_2_20_1a
default "2.19.1a" if BINUTILS_V_2_19_1a
default "2.18a" if BINUTILS_V_2_18a
default "custom" if BINUTILS_CUSTOM
config BINUTILS_2_25_1_or_later
bool
select BINUTILS_2_25_or_later
config BINUTILS_2_25_or_later
bool
@ -172,6 +180,13 @@ config BINUTILS_GOLD_SUPPORTS_ARCH
default y if ARCH_arm
default y if ARCH_x86
config BINUTILS_GOLD_SUPPORT
bool
default y
depends on BINUTILS_HAS_GOLD
depends on BINUTILS_GOLD_SUPPORTS_ARCH
depends on ! STATIC_TOOLCHAIN
config BINUTILS_HAS_PLUGINS
bool
@ -197,8 +212,7 @@ config BINUTILS_LINKER_LD
config BINUTILS_LINKER_GOLD
bool
prompt "gold"
depends on BINUTILS_HAS_GOLD
depends on BINUTILS_GOLD_SUPPORTS_ARCH
depends on BINUTILS_GOLD_SUPPORT
depends on ! BINUTILS_FORCE_LD_BFD
select BINUTILS_GOLD_INSTALLED
help
@ -210,8 +224,7 @@ config BINUTILS_LINKER_GOLD
config BINUTILS_LINKER_LD_GOLD
bool
prompt "ld, gold"
depends on BINUTILS_HAS_GOLD
depends on BINUTILS_GOLD_SUPPORTS_ARCH
depends on BINUTILS_GOLD_SUPPORT
select BINUTILS_GOLD_INSTALLED
select BINUTILS_LINKER_BOTH
help
@ -223,8 +236,7 @@ config BINUTILS_LINKER_LD_GOLD
config BINUTILS_LINKER_GOLD_LD
bool
prompt "gold, ld"
depends on BINUTILS_HAS_GOLD
depends on BINUTILS_GOLD_SUPPORTS_ARCH
depends on BINUTILS_GOLD_SUPPORT
select BINUTILS_GOLD_INSTALLED
select BINUTILS_LINKER_BOTH
select BINUTILS_LD_WRAPPER if BINUTILS_FORCE_LD_BFD

View File

@ -40,12 +40,7 @@ choice
config CC_GCC_V_5_2_0
bool
prompt "5.2.0"
select CC_GCC_5_2
config CC_GCC_V_5_1_0
bool
prompt "5.1.0"
select CC_GCC_5_1
select CC_GCC_5
config CC_GCC_V_linaro_4_9
bool
@ -58,21 +53,6 @@ config CC_GCC_V_4_9_3
prompt "4.9.3"
select CC_GCC_4_9
config CC_GCC_V_4_9_2
bool
prompt "4.9.2"
select CC_GCC_4_9
config CC_GCC_V_4_9_1
bool
prompt "4.9.1"
select CC_GCC_4_9
config CC_GCC_V_4_9_0
bool
prompt "4.9.0"
select CC_GCC_4_9
config CC_GCC_V_linaro_4_8
bool
prompt "linaro-4.8-2015.06"
@ -84,31 +64,6 @@ config CC_GCC_V_4_8_5
prompt "4.8.5"
select CC_GCC_4_8
config CC_GCC_V_4_8_4
bool
prompt "4.8.4"
select CC_GCC_4_8
config CC_GCC_V_4_8_3
bool
prompt "4.8.3"
select CC_GCC_4_8
config CC_GCC_V_4_8_2
bool
prompt "4.8.2"
select CC_GCC_4_8
config CC_GCC_V_4_8_1
bool
prompt "4.8.1"
select CC_GCC_4_8
config CC_GCC_V_4_8_0
bool
prompt "4.8.0"
select CC_GCC_4_8
config CC_GCC_V_linaro_4_7
bool
prompt "linaro-4.7-2014.06"
@ -120,26 +75,6 @@ config CC_GCC_V_4_7_4
prompt "4.7.4"
select CC_GCC_4_7
config CC_GCC_V_4_7_3
bool
prompt "4.7.3"
select CC_GCC_4_7
config CC_GCC_V_4_7_2
bool
prompt "4.7.2"
select CC_GCC_4_7
config CC_GCC_V_4_7_1
bool
prompt "4.7.1"
select CC_GCC_4_7
config CC_GCC_V_4_7_0
bool
prompt "4.7.0"
select CC_GCC_4_7
config CC_GCC_V_linaro_4_6
bool
prompt "linaro-4.6-2013.05"
@ -151,50 +86,15 @@ config CC_GCC_V_4_6_4
prompt "4.6.4"
select CC_GCC_4_6
config CC_GCC_V_4_6_3
bool
prompt "4.6.3"
select CC_GCC_4_6
config CC_GCC_V_4_6_2
bool
prompt "4.6.2"
select CC_GCC_4_6
config CC_GCC_V_4_6_1
bool
prompt "4.6.1"
select CC_GCC_4_6
config CC_GCC_V_4_6_0
bool
prompt "4.6.0"
select CC_GCC_4_6
config CC_GCC_V_linaro_4_5
bool
prompt "linaro-4.5-2012.03"
depends on CC_GCC_SHOW_LINARO
select CC_GCC_4_5
config CC_GCC_V_4_5_3
config CC_GCC_V_4_5_4
bool
prompt "4.5.3"
select CC_GCC_4_5
config CC_GCC_V_4_5_2
bool
prompt "4.5.2"
select CC_GCC_4_5
config CC_GCC_V_4_5_1
bool
prompt "4.5.1"
select CC_GCC_4_5
config CC_GCC_V_4_5_0
bool
prompt "4.5.0"
prompt "4.5.4"
select CC_GCC_4_5
config CC_GCC_V_linaro_4_4
@ -208,105 +108,25 @@ config CC_GCC_V_4_4_7
prompt "4.4.7"
select CC_GCC_4_4
config CC_GCC_V_4_4_6
bool
prompt "4.4.6"
select CC_GCC_4_4
config CC_GCC_V_4_4_5
bool
prompt "4.4.5"
select CC_GCC_4_4
config CC_GCC_V_4_4_4
bool
prompt "4.4.4"
select CC_GCC_4_4
config CC_GCC_V_4_4_3
bool
prompt "4.4.3"
select CC_GCC_4_4
config CC_GCC_V_4_4_2
bool
prompt "4.4.2"
select CC_GCC_4_4
config CC_GCC_V_4_4_1
bool
prompt "4.4.1"
select CC_GCC_4_4
config CC_GCC_V_4_4_0
bool
prompt "4.4.0"
select CC_GCC_4_4
config CC_GCC_V_4_3_6
bool
prompt "4.3.6"
select CC_GCC_4_3
config CC_GCC_V_4_3_5
bool
prompt "4.3.5"
select CC_GCC_4_3
config CC_GCC_V_4_3_4
bool
prompt "4.3.4"
select CC_GCC_4_3
config CC_GCC_V_4_3_3
bool
prompt "4.3.3"
select CC_GCC_4_3
config CC_GCC_V_4_3_2
bool
prompt "4.3.2"
select CC_GCC_4_3
config CC_GCC_V_4_3_1
bool
prompt "4.3.1"
select CC_GCC_4_3
config CC_GCC_V_4_2_4
bool
prompt "4.2.4"
select CC_GCC_4_2
# We need that one, it's the only version with avr32 support
# because we have a patch for it
config CC_GCC_V_4_2_2
bool
prompt "4.2.2"
select CC_GCC_4_2
config CC_GCC_V_4_1_2
bool
prompt "4.1.2 (OBSOLETE)"
depends on OBSOLETE
config CC_GCC_V_4_0_4
bool
prompt "4.0.4 (OBSOLETE)"
depends on OBSOLETE
config CC_GCC_V_3_4_6
bool
prompt "3.4.6 (OBSOLETE)"
depends on OBSOLETE
endchoice
config CC_GCC_CUSTOM
bool
prompt "Custom gcc"
depends on EXPERIMENTAL
select CC_GCC_latest
endchoice
help
The choosen compiler version shall be not downloaded. Instead use
a custom location to get the source.
if CC_GCC_CUSTOM
@ -429,9 +249,9 @@ config CC_GCC_4_9_or_later
bool
select CC_GCC_4_8_or_later
config CC_GCC_5_2
config CC_GCC_5
bool
select CC_GCC_5_2_or_later
select CC_GCC_5_or_later
select CC_GCC_USE_GMP_MPFR
select CC_GCC_USE_MPC
select CC_GCC_HAS_GRAPHITE
@ -443,31 +263,14 @@ config CC_GCC_5_2
select CC_GCC_HAS_LIBSANITIZER
select CC_SUPPORT_GOLANG
config CC_GCC_5_2_or_later
bool
select CC_GCC_5_1_or_later
config CC_GCC_5_1
bool
select CC_GCC_5_1_or_later
select CC_GCC_USE_GMP_MPFR
select CC_GCC_USE_MPC
select CC_GCC_HAS_GRAPHITE
select CC_GCC_HAS_LTO
select CC_GCC_HAS_PKGVERSION_BUGURL
select CC_GCC_HAS_BUILD_ID
select CC_GCC_HAS_LNK_HASH_STYLE
select CC_GCC_HAS_LIBQUADMATH
select CC_GCC_HAS_LIBSANITIZER
select CC_SUPPORT_GOLANG
config CC_GCC_5_1_or_later
config CC_GCC_5_or_later
bool
select CC_GCC_4_9_or_later
config CC_GCC_latest
bool
select CC_GCC_5_1_or_later
select CC_GCC_5_or_later
select CC_GCC_USE_GMP_MPFR
select CC_GCC_USE_MPC
select CC_GCC_HAS_GRAPHITE
@ -487,7 +290,7 @@ config CC_GCC_USE_GRAPHITE
bool
default y
depends on CC_GCC_HAS_GRAPHITE
select CLOOG_NEEDED if !CC_GCC_5_1_or_later
select CLOOG_NEEDED if !CC_GCC_5_or_later
select PPL_NEEDED if !CC_GCC_4_8_or_later
select ISL_NEEDED if CC_GCC_4_8_or_later
help
@ -565,58 +368,20 @@ config CC_GCC_VERSION
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "5.2.0" if CC_GCC_V_5_2_0
default "5.1.0" if CC_GCC_V_5_1_0
default "linaro-4.9-2015.06" if CC_GCC_V_linaro_4_9
default "4.9.3" if CC_GCC_V_4_9_3
default "4.9.2" if CC_GCC_V_4_9_2
default "4.9.1" if CC_GCC_V_4_9_1
default "4.9.0" if CC_GCC_V_4_9_0
default "linaro-4.8-2015.06" if CC_GCC_V_linaro_4_8
default "4.8.5" if CC_GCC_V_4_8_5
default "4.8.4" if CC_GCC_V_4_8_4
default "4.8.3" if CC_GCC_V_4_8_3
default "4.8.2" if CC_GCC_V_4_8_2
default "4.8.1" if CC_GCC_V_4_8_1
default "4.8.0" if CC_GCC_V_4_8_0
default "linaro-4.7-2014.06" if CC_GCC_V_linaro_4_7
default "4.7.4" if CC_GCC_V_4_7_4
default "4.7.3" if CC_GCC_V_4_7_3
default "4.7.2" if CC_GCC_V_4_7_2
default "4.7.1" if CC_GCC_V_4_7_1
default "4.7.0" if CC_GCC_V_4_7_0
default "linaro-4.6-2013.05" if CC_GCC_V_linaro_4_6
default "4.6.4" if CC_GCC_V_4_6_4
default "4.6.3" if CC_GCC_V_4_6_3
default "4.6.2" if CC_GCC_V_4_6_2
default "4.6.1" if CC_GCC_V_4_6_1
default "4.6.0" if CC_GCC_V_4_6_0
default "linaro-4.5-2012.03" if CC_GCC_V_linaro_4_5
default "4.5.3" if CC_GCC_V_4_5_3
default "4.5.2" if CC_GCC_V_4_5_2
default "4.5.1" if CC_GCC_V_4_5_1
default "4.5.0" if CC_GCC_V_4_5_0
default "4.5.4" if CC_GCC_V_4_5_4
default "linaro-4.4-2011.02-0" if CC_GCC_V_linaro_4_4
default "4.4.7" if CC_GCC_V_4_4_7
default "4.4.6" if CC_GCC_V_4_4_6
default "4.4.5" if CC_GCC_V_4_4_5
default "4.4.4" if CC_GCC_V_4_4_4
default "4.4.3" if CC_GCC_V_4_4_3
default "4.4.2" if CC_GCC_V_4_4_2
default "4.4.1" if CC_GCC_V_4_4_1
default "4.4.0" if CC_GCC_V_4_4_0
default "4.3.6" if CC_GCC_V_4_3_6
default "4.3.5" if CC_GCC_V_4_3_5
default "4.3.4" if CC_GCC_V_4_3_4
default "4.3.3" if CC_GCC_V_4_3_3
default "4.3.2" if CC_GCC_V_4_3_2
default "4.3.1" if CC_GCC_V_4_3_1
default "4.3.0" if CC_GCC_V_4_3_0
default "4.2.4" if CC_GCC_V_4_2_4
default "4.2.2" if CC_GCC_V_4_2_2
default "4.1.2" if CC_GCC_V_4_1_2
default "4.0.4" if CC_GCC_V_4_0_4
default "3.4.6" if CC_GCC_V_3_4_6
default "custom" if CC_GCC_CUSTOM
config CC_LANG_JAVA_USE_ECJ
bool

View File

@ -37,6 +37,27 @@ config CC_GCC_EXTRA_CONFIG_ARRAY
if they are properly quoted (or escaped, but prefer quotes). Eg.:
--with-foo="1st arg with 4 spaces" --with-bar=2nd-arg-without-space
config CC_GCC_EXTRA_ENV_ARRAY
string
prompt "Extra env variables to set for make"
default ""
help
Used to add specific env variables on the make command line for the
gcc build (eg. INHIBIT_LIBC_CFLAGS='-DUSE_TM_CLONE_REGISTRY=0')
Leave blank if you don't know better.
config CC_GCC_TARGET_FINAL
bool
prompt "Use the default targets all and install for the final compiler"
default n
depends on BARE_METAL
help
The final GCC for a bare metal system is built by the core gcc script.
This script does a lot of tricks to build the core gcc, which are not
required for the final gcc build. If you set this flag to true, all the
tricks are not done and the compiler is build with all/install.
config STATIC_TOOLCHAIN
select CC_GCC_STATIC_LIBSTDCXX if CC_GCC_4_4_or_later
@ -165,7 +186,7 @@ config CC_CXA_ATEXIT
bool
prompt "Use __cxa_atexit"
default y
depends on ! BARE_METAL
depends on ! BARE_METAL || LIBC_PROVIDES_CXA_ATEXIT
help
If you get the missing symbol "__cxa_atexit" when building C++ programs,
you might want to try disabling this option.

View File

@ -7,6 +7,17 @@ menu "Companion libraries"
config COMPLIBS_NEEDED
bool
config LIBICONV_NEEDED
bool
select LIBICONV
select COMPLIBS_NEEDED
config GETTEXT_NEEDED
bool
select GETTEXT
select LIBICONV_NEEDED
select COMPLIBS_NEEDED
config GMP_NEEDED
bool
select GMP
@ -42,9 +53,27 @@ config LIBELF_NEEDED
select LIBELF
select COMPLIBS_NEEDED
config EXPAT_NEEDED
bool
select EXPAT
select COMPLIBS_NEEDED
config NCURSES_NEEDED
bool
select NCURSES
select COMPLIBS_NEEDED
config COMPLIBS
bool
config LIBICONV
bool
select COMPLIBS
config GETTEXT
bool
select COMPLIBS
config GMP
bool
select COMPLIBS
@ -82,6 +111,26 @@ config LIBELF
config LIBELF_TARGET
bool
config EXPAT
bool
select COMPLIBS
config EXPAT_TARGET
bool
config NCURSES
bool
select COMPLIBS
config NCURSES_TARGET
bool
if LIBICONV
source "config/companion_libs/libiconv.in"
endif
if GETTEXT
source "config/companion_libs/gettext.in"
endif
if GMP
source "config/companion_libs/gmp.in"
endif
@ -105,9 +154,16 @@ comment "libelf version needed to build for target"
depends on !LIBELF
source "config/companion_libs/libelf.in"
endif
config FOO
bool
if EXPAT || EXPAT_TARGET
comment "expat version needed to build for target"
depends on !EXPAT
source "config/companion_libs/expat.in"
endif
if NCURSES || NCURSES_TARGET
comment "ncurses version needed to build for target"
depends on !NCURSES
source "config/companion_libs/ncurses.in"
endif
if COMPLIBS

View File

@ -9,6 +9,11 @@ if ISL
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config CLOOG_V_0_18_4
bool
prompt "0.18.4"
select CLOOG_0_18_4_or_later
config CLOOG_V_0_18_1
bool
prompt "0.18.1"
@ -36,10 +41,15 @@ config CLOOG_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "0.18.4" if CLOOG_V_0_18_4
default "0.18.1" if CLOOG_V_0_18_1
default "0.18.0" if CLOOG_V_0_18_0
default "0.15.11" if CLOOG_V_0_15_11
config CLOOG_0_18_4_or_later
bool
select CLOOG_0_18_or_later
config CLOOG_0_18_or_later
bool

View File

@ -0,0 +1,19 @@
# expat config file
choice
bool
prompt "expat version"
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config EXPAT_V_2_1_0
bool
prompt "2.1.0"
endchoice
config EXPAT_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "2.1.0" if EXPAT_V_2_1_0

View File

@ -0,0 +1,19 @@
# gettext options
choice
bool
prompt "gettext version"
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config GETTEXT_V_0_19_6
bool
prompt "0.19.6"
endchoice
config GETTEXT_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "0.19.6" if GETTEXT_V_0_19_6

View File

@ -9,18 +9,30 @@ choice
config ISL_V_0_14
bool
prompt "0.14"
depends on CLOOG_0_18_4_or_later || CC_GCC_5_or_later
select ISL_V_0_14_or_later
config ISL_V_0_12_2
bool
prompt "0.12.2"
depends on ! CLOOG_0_18_4_or_later || CC_GCC_5_or_later
select ISL_V_0_12_or_later
config ISL_V_0_11_1
bool
prompt "0.11.1"
depends on ! CC_GCC_5_1_or_later
depends on ! CLOOG_0_18_4_or_later
depends on ! CC_GCC_5_or_later
endchoice
config ISL_V_0_14_or_later
bool
select ISL_V_0_12_or_later
config ISL_V_0_12_or_later
bool
config ISL_VERSION
string
# Don't remove next line

View File

@ -0,0 +1,19 @@
# libiconv options
choice
bool
prompt "libiconv version"
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config LIBICONV_V_1_14
bool
prompt "1.14"
endchoice
config LIBICONV_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "1.14" if LIBICONV_V_1_14

View File

@ -6,6 +6,10 @@ choice
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config MPC_V_1_0_3
bool
prompt "1.0.3"
config MPC_V_1_0_2
bool
prompt "1.0.2"
@ -40,6 +44,7 @@ config MPC_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "1.0.3" if MPC_V_1_0_3
default "1.0.2" if MPC_V_1_0_2
default "1.0.1" if MPC_V_1_0_1
default "1.0" if MPC_V_1_0

View File

@ -6,6 +6,10 @@ choice
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config MPFR_V_3_1_3
bool
prompt "3.1.3"
config MPFR_V_3_1_2
bool
prompt "3.1.2"
@ -40,6 +44,7 @@ config MPFR_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "3.1.3" if MPFR_V_3_1_3
default "3.1.2" if MPFR_V_3_1_2
default "3.1.0" if MPFR_V_3_1_0
default "3.0.1" if MPFR_V_3_0_1

View File

@ -0,0 +1,32 @@
# expat config file
choice
bool
prompt "ncurses version"
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config NCURSES_V_6_0
bool
prompt "6.0"
endchoice
config NCURSES_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "6.0" if NCURSES_V_6_0
if NCURSES
config NCURSES_NEW_ABI
bool
prompt "ncurses 6.0 ABI support"
depends on EXPERIMENTAL
depends on NCURSES
help
This option allows you to use the new ncurses-6 ABI.
It's wise to leave this disabled and stick with the ncurses-5 ABI!
endif # NCURSES

View File

@ -50,12 +50,12 @@ config_files: $(STATIC_CONFIG_FILES) $(GEN_CONFIG_FILES)
# Where to access to the source config files from
config:
@$(ECHO) " LN config"
@$(CT_ECHO) " LN config"
$(SILENT)ln -s $(CT_LIB_DIR)/config config
# Where to store the generated config files into
config.gen:
@$(ECHO) " MKDIR config.gen"
@$(CT_ECHO) " MKDIR config.gen"
$(SILENT)mkdir -p config.gen
#-----------------------------------------------------------
@ -74,34 +74,34 @@ DEBUGS = $(patsubst config/debug/%.in,%,$(DEBUG_CONFIG_FILES))
# WARNING! If a .in file disapears between two runs, that will NOT be detected!
config.gen/arch.in: $(ARCH_CONFIG_FILES) $(ARCH_CONFIG_FILES_2)
@$(ECHO) ' IN $(@)'
@$(CT_ECHO) ' IN $(@)'
$(SILENT)$(CT_LIB_DIR)/scripts/gen_in_frags.sh choice "$@" "Target Architecture" "ARCH" "config/arch" "Y" $(ARCHS)
config.gen/kernel.in: $(KERNEL_CONFIG_FILES) $(KERNEL_CONFIG_FILES_2)
@$(ECHO) ' IN $(@)'
@$(CT_ECHO) ' IN $(@)'
$(SILENT)$(CT_LIB_DIR)/scripts/gen_in_frags.sh choice "$@" "Target OS" "KERNEL" "config/kernel" "Y" $(KERNELS)
config.gen/cc.in: $(CC_CONFIG_FILES) $(CC_CONFIG_FILES_2)
@$(ECHO) ' IN $(@)'
@$(CT_ECHO) ' IN $(@)'
$(SILENT)$(CT_LIB_DIR)/scripts/gen_in_frags.sh choice "$@" "C compiler" "CC" "config/cc" "N" $(CCS)
config.gen/binutils.in: $(CC_BINUTILS_FILES) $(CC_BINUTILS_FILES_2)
@$(ECHO) ' IN $(@)'
@$(CT_ECHO) ' IN $(@)'
$(SILENT)$(CT_LIB_DIR)/scripts/gen_in_frags.sh choice "$@" "Binutils" "BINUTILS" "config/binutils" "N" $(BINUTILSS)
config.gen/libc.in: $(LIBC_CONFIG_FILES) $(LIBC_CONFIG_FILES_2)
@$(ECHO) ' IN $(@)'
@$(CT_ECHO) ' IN $(@)'
$(SILENT)$(CT_LIB_DIR)/scripts/gen_in_frags.sh choice "$@" "C library" "LIBC" "config/libc" "Y" $(LIBCS)
config.gen/debug.in: $(DEBUG_CONFIG_FILES)
@$(ECHO) ' IN $(@)'
@$(CT_ECHO) ' IN $(@)'
$(SILENT)$(CT_LIB_DIR)/scripts/gen_in_frags.sh menu "$@" "Debug facilities" "DEBUG" "config/debug" $(DEBUGS)
#-----------------------------------------------------------
# Cleaning up the mess...
clean::
@$(ECHO) " CLEAN config"
@$(CT_ECHO) " CLEAN config"
$(SILENT)rm -f config 2>/dev/null || true
@$(ECHO) " CLEAN config.gen"
@$(CT_ECHO) " CLEAN config.gen"
$(SILENT)rm -rf config.gen

View File

@ -33,6 +33,11 @@ choice
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config GDB_V_7_10
bool
prompt "7.10"
select GDB_7_2_or_later
config GDB_V_7_9_1
bool
prompt "7.9.1"
@ -159,13 +164,15 @@ config GDB_V_6_8a
bool
prompt "6.8a"
endchoice
config GDB_CUSTOM
bool
prompt "Custom gdb"
depends on EXPERIMENTAL
select GDB_7_2_or_later
endchoice
help
The choosen gdb version shall be not downloaded. Instead use
a custom location to get the source.
config GDB_7_2_or_later
bool
@ -190,6 +197,7 @@ config GDB_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "7.10" if GDB_V_7_10
default "7.9.1" if GDB_V_7_9_1
default "7.9" if GDB_V_7_9
default "7.8.2" if GDB_V_7_8_2
@ -214,7 +222,6 @@ config GDB_VERSION
default "7.0.1a" if GDB_V_7_0_1a
default "7.0a" if GDB_V_7_0a
default "6.8a" if GDB_V_6_8a
default "custom" if GDB_CUSTOM
if GDB_CUSTOM

View File

@ -8,6 +8,8 @@ config GDB_CROSS
prompt "Cross-gdb"
default y
select GDB_GDBSERVER if ! BARE_METAL
select EXPAT_NEEDED
select NCURSES_NEEDED
help
Build and install a cross-gdb for the target, to run on host.

View File

@ -5,6 +5,8 @@ config GDB_NATIVE
prompt "Native gdb"
depends on ! BARE_METAL
depends on ! BACKEND
select EXPAT_TARGET
select NCURSES_TARGET
help
Build and install a native gdb for the target, to run on the target.

View File

@ -3,6 +3,7 @@
# Allow unconditional usage of tristates
config MODULES
bool
option modules
default y
menu "Paths and misc options"

View File

@ -117,12 +117,22 @@ config INSTALL_DIR_RO
Useful for toolchains destined for production.
config STRIP_ALL_TOOLCHAIN_EXECUTABLES
config STRIP_HOST_TOOLCHAIN_EXECUTABLES
bool
prompt "Strip all toolchain executables"
prompt "Strip host toolchain executables"
default y
help
All build host executables contain a lot of unnecessary info.
By stripping all executables it slightly speeds up the compilation
By stripping host executables it slightly speeds up the compilation
of large projects.
NOTE: It does NOT strip the target libraries, only HOST executables
config STRIP_TARGET_TOOLCHAIN_EXECUTABLES
bool
prompt "Strip target toolchain executables"
depends on CC_GCC_4_6_or_later
help
It means using install-strip target for GCC 4.6 or later.
An install-strip make target is provided that installs stripped
executables, and may install libraries with unneeded or debugging
sections stripped.

View File

@ -27,41 +27,45 @@ choice
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config KERNEL_V_4_3
bool
prompt "4.3 (mainline)"
config KERNEL_V_4_2
bool
prompt "4.2.6 (stable)"
config KERNEL_V_4_1
bool
prompt "4.1.2 (stable)"
config KERNEL_V_4_0
bool
prompt "4.0.8 (stable)"
prompt "4.1.13"
config KERNEL_V_3_18
bool
prompt "3.18.18"
prompt "3.18.24"
config KERNEL_V_3_14
bool
prompt "3.14.48"
prompt "3.14.57"
config KERNEL_V_3_12
bool
prompt "3.12.44"
prompt "3.12.50"
config KERNEL_V_3_10
bool
prompt "3.10.84"
prompt "3.10.93"
config KERNEL_V_3_4
bool
prompt "3.4.108"
prompt "3.4.110"
config KERNEL_V_3_2
bool
prompt "3.2.69"
prompt "3.2.72"
config KERNEL_V_2_6_32
bool
prompt "2.6.32.67"
prompt "2.6.32.68"
help
config KERNEL_LINUX_CUSTOM
@ -84,15 +88,16 @@ config KERNEL_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "4.1.2" if KERNEL_V_4_1
default "4.0.8" if KERNEL_V_4_0
default "3.18.18" if KERNEL_V_3_18
default "3.14.48" if KERNEL_V_3_14
default "3.12.44" if KERNEL_V_3_12
default "3.10.84" if KERNEL_V_3_10
default "3.4.108" if KERNEL_V_3_4
default "3.2.69" if KERNEL_V_3_2
default "2.6.32.67" if KERNEL_V_2_6_32
default "4.3" if KERNEL_V_4_3
default "4.2.6" if KERNEL_V_4_2
default "4.1.13" if KERNEL_V_4_1
default "3.18.24" if KERNEL_V_3_18
default "3.14.57" if KERNEL_V_3_14
default "3.12.50" if KERNEL_V_3_12
default "3.10.93" if KERNEL_V_3_10
default "3.4.110" if KERNEL_V_3_4
default "3.2.72" if KERNEL_V_3_2
default "2.6.32.68" if KERNEL_V_2_6_32
default "custom" if KERNEL_LINUX_CUSTOM
endif # ! KERNEL_LINUX_USE_CUSTOM_HEADERS

View File

@ -1,6 +1,7 @@
# windows config options
## depends on ARCH_x86
## depends on EXPERIMENTAL
##
## select WINDOWS
##

View File

@ -35,6 +35,9 @@ config LIBC_SUPPORT_THREADS_LT
config LIBC_SUPPORT_THREADS_NONE
bool
config LIBC_PROVIDES_CXA_ATEXIT
bool
# C libraries should provide other values
config THREADS
string

View File

@ -4,6 +4,7 @@
##
## select LIBC_SUPPORT_THREADS_NATIVE
## select CC_CORE_PASSES_NEEDED
## select GETTEXT_NEEDED
##
## help The de-facto standard for Linux distributions.
## help Feature-rich, but large... Most useful for desktop-like systems.
@ -34,10 +35,15 @@ choice
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config LIBC_GLIBC_V_2_22
bool
prompt "2.22"
select LIBC_GLIBC_2_21_or_later
config LIBC_GLIBC_V_2_21
bool
prompt "2.21"
select LIBC_GLIBC_2_20_or_later
select LIBC_GLIBC_2_21_or_later
config LIBC_GLIBC_LINARO_V_2_20
bool
@ -53,14 +59,17 @@ config LIBC_GLIBC_V_2_20
config LIBC_GLIBC_V_2_19
bool
prompt "2.19"
select LIBC_GLIBC_2_17_or_later
config LIBC_GLIBC_V_2_18
bool
prompt "2.18"
select LIBC_GLIBC_2_17_or_later
config LIBC_GLIBC_V_2_17
bool
prompt "2.17"
select LIBC_GLIBC_2_17_or_later
config LIBC_GLIBC_V_2_16_0
bool
@ -132,8 +141,19 @@ config LIBC_GLIBC_CUSTOM
endchoice
# glibc 2.21 depends on gcc >= 4.6
config LIBC_GLIBC_2_21_or_later
bool
depends on CC_GCC_4_6_or_later
select LIBC_GLIBC_2_20_or_later
config LIBC_GLIBC_2_20_or_later
bool
select LIBC_GLIBC_2_17_or_later
# DeMark no more ports
config LIBC_GLIBC_2_17_or_later
bool
config LIBC_CUSTOM
bool
@ -154,6 +174,7 @@ config LIBC_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "2.22" if LIBC_GLIBC_V_2_22
default "2.21" if LIBC_GLIBC_V_2_21
default "linaro-2.20-2014.11" if LIBC_GLIBC_LINARO_V_2_20
default "2.20" if LIBC_GLIBC_V_2_20

View File

@ -14,14 +14,18 @@ choice
bool
prompt "Windows API version"
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config WINAPI_V_DEVEL
bool
prompt "devel"
depends on EXPERIMENTAL
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config WINAPI_V_4_0_4
bool
prompt "4.0.4"
config WINAPI_V_4_0_2
bool
prompt "4.0.2"
@ -59,9 +63,10 @@ endchoice
config WINAPI_VERSION
string
prompt "Windows API version" if WINAPI_V_select
default "devel" if WINAPI_V_DEVEL
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "devel" if WINAPI_V_DEVEL
default "4.0.4" if WINAPI_V_4_0_4
default "4.0.2" if WINAPI_V_4_0_2
default "4.0.1" if WINAPI_V_4_0_1
default "4.0.0" if WINAPI_V_4_0_0

View File

@ -20,7 +20,7 @@ choice
config LIBC_MUSL_V_1_1
bool
prompt "1.1.9 (Mainline)"
prompt "1.1.12 (Mainline)"
depends on EXPERIMENTAL
config LIBC_MUSL_V_1_0
@ -38,6 +38,6 @@ config LIBC_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "1.1.9" if LIBC_MUSL_V_1_1
default "1.1.12" if LIBC_MUSL_V_1_1
default "1.0.5" if LIBC_MUSL_V_1_0
default "custom" if LIBC_MUSL_V_CUSTOM

View File

@ -40,23 +40,28 @@ config LIBC_NEWLIB_LINARO_V_2_2_0
bool
prompt "Linaro 2.2.0-2015.01"
depends on CC_NEWLIB_SHOW_LINARO
select LIBC_NEWLIB_2_2
config LIBC_NEWLIB_V_2_2_0
bool
prompt "2.2.0"
select LIBC_NEWLIB_2_2
config LIBC_NEWLIB_LINARO_V_2_1_0
bool
prompt "Linaro 2.1.0-2014.09"
depends on CC_NEWLIB_SHOW_LINARO
select LIBC_NEWLIB_2_1
config LIBC_NEWLIB_V_2_1_0
bool
prompt "2.1.0"
select LIBC_NEWLIB_2_1
config LIBC_NEWLIB_V_2_0_0
bool
prompt "2.0.0"
select LIBC_NEWLIB_2_0
config LIBC_NEWLIB_V_1_20_0
bool
@ -74,12 +79,41 @@ config LIBC_NEWLIB_V_1_17_0
bool
prompt "1.17.0"
endchoice
config LIBC_NEWLIB_CUSTOM
bool
prompt "Custom newlib"
depends on EXPERIMENTAL
help
The choosen library version shall be not downloaded. Instead use
a custom location to get the source.
endchoice
config LIBC_NEWLIB_2_2
bool
select LIBC_NEWLIB_2_2_or_later
config LIBC_NEWLIB_2_1
bool
select LIBC_NEWLIB_2_1_or_later
config LIBC_NEWLIB_2_0
bool
select LIBC_NEWLIB_2_0_or_later
config LIBC_NEWLIB_2_2_or_later
bool
select LIBC_NEWLIB_2_1_or_later
config LIBC_NEWLIB_2_1_or_later
bool
select LIBC_NEWLIB_2_0_or_later
# maybe older versions of newlib will support it too, but this
# needs to be checked
config LIBC_NEWLIB_2_0_or_later
bool
select LIBC_PROVIDES_CXA_ATEXIT
if LIBC_NEWLIB_CUSTOM
@ -106,20 +140,20 @@ config LIBC_VERSION
default "1.19.0" if LIBC_NEWLIB_V_1_19_0
default "1.18.0" if LIBC_NEWLIB_V_1_18_0
default "1.17.0" if LIBC_NEWLIB_V_1_17_0
default "custom" if LIBC_NEWLIB_CUSTOM
help
Enter the tag you want to use.
Leave empty to use the 'head' of the repository.
comment "Architecture specific options"
config ATMEL_AVR32_HEADERS
bool
prompt "Install Atmel AVR32 headers"
depends on ARCH_avr32
default y
config LIBC_NEWLIB_TARGET_CFLAGS
string
prompt "Target CFLAGS for newlib"
default ""
help
Install Atmel AVR32 headers for native AVR32 development. Most
AVR32 MCU devices are supported.
If you do native AVR32 development you want to say 'Y' here.
Used to add specific options when compiling the target libraries
(eg. -ffunction-sections -fdata-sections), which can't be defined
in global TARGET_CFLAGS, because they shall be not used for the
gcc target libraries.
Note: Both TARGET_CFLAGS and LIBC_NEWLIB_TARGET_CFLAGS are used
to compile the libraries.
Leave blank if you don't know better.

View File

@ -26,62 +26,21 @@ choice
# Don't remove next line
# CT_INSERT_VERSION_BELOW
config LIBC_UCLIBC_NG_V_1_0_9
bool
prompt "1.0.9"
select LIBC_UCLIBC_NG_1_0_9_or_later
config LIBC_UCLIBC_V_0_9_33_2
bool
prompt "0.9.33.2"
select LIBC_UCLIBC_0_9_32_or_later
config LIBC_UCLIBC_V_0_9_33_1
bool
prompt "0.9.33.1"
select LIBC_UCLIBC_0_9_32_or_later
config LIBC_UCLIBC_V_0_9_33
bool
prompt "0.9.33"
select LIBC_UCLIBC_0_9_32_or_later
config LIBC_UCLIBC_V_0_9_32_1
bool
prompt "0.9.32.1"
select LIBC_UCLIBC_0_9_32_or_later
config LIBC_UCLIBC_V_0_9_32
bool
prompt "0.9.32"
select LIBC_UCLIBC_0_9_32_or_later
config LIBC_UCLIBC_V_0_9_31
bool
prompt "0.9.31"
select LIBC_UCLIBC_0_9_30_or_later
config LIBC_UCLIBC_V_0_9_30_3
bool
prompt "0.9.30.3"
select LIBC_UCLIBC_0_9_30_or_later
config LIBC_UCLIBC_V_0_9_30_2
bool
prompt "0.9.30.2"
select LIBC_UCLIBC_0_9_30_or_later
config LIBC_UCLIBC_V_0_9_30_1
bool
prompt "0.9.30.1"
select LIBC_UCLIBC_0_9_30_or_later
config LIBC_UCLIBC_V_0_9_30
bool
prompt "0.9.30"
select LIBC_UCLIBC_0_9_30_or_later
select LIBC_UCLIBC_0_9_33_2_or_later
config LIBC_UCLIBC_CUSTOM
bool
prompt "Custom uClibc"
depends on EXPERIMENTAL
select LIBC_SUPPORT_THREADS_NATIVE
select LIBC_UCLIBC_0_9_30_or_later
select LIBC_UCLIBC_0_9_33_2_or_later
endchoice
@ -101,30 +60,29 @@ config LIBC_VERSION
string
# Don't remove next line
# CT_INSERT_VERSION_STRING_BELOW
default "1.0.9" if LIBC_UCLIBC_NG_V_1_0_9
default "0.9.33.2" if LIBC_UCLIBC_V_0_9_33_2
default "0.9.33.1" if LIBC_UCLIBC_V_0_9_33_1
default "0.9.33" if LIBC_UCLIBC_V_0_9_33
default "0.9.32.1" if LIBC_UCLIBC_V_0_9_32_1
default "0.9.32" if LIBC_UCLIBC_V_0_9_32
default "0.9.31" if LIBC_UCLIBC_V_0_9_31
default "0.9.30.3" if LIBC_UCLIBC_V_0_9_30_3
default "0.9.30.2" if LIBC_UCLIBC_V_0_9_30_2
default "0.9.30.1" if LIBC_UCLIBC_V_0_9_30_1
default "0.9.30" if LIBC_UCLIBC_V_0_9_30
default "custom" if LIBC_UCLIBC_CUSTOM
config LIBC_UCLIBC_0_9_32_or_later
config LIBC_UCLIBC_NG_1_0_9_or_later
bool
select LIBC_UCLIBC_NG_1_0_0_or_later
config LIBC_UCLIBC_NG_1_0_0_or_later
bool
select LIBC_UCLIBC_NG
select LIBC_UCLIBC_0_9_33_2_or_later
config LIBC_UCLIBC_0_9_33_2_or_later
bool
select LIBC_SUPPORT_THREADS_NATIVE
select LIBC_UCLIBC_0_9_30_or_later
config LIBC_UCLIBC_0_9_30_or_later
bool
select LIBC_UCLIBC_PARALLEL
config LIBC_UCLIBC_PARALLEL
bool
config LIBC_UCLIBC_NG
bool
choice
bool
prompt "uClibc verbosity:"
@ -191,5 +149,5 @@ config LIBC_UCLIBC_CONFIG_FILE
default ""
help
Path to the configuration file.
You _must_ provide one (for now).
If the file is not provided, we fall back to a default config file.

View File

@ -22,7 +22,7 @@ config LIBC_UCLIBC_LNXTHRD_NEW
help
From the uClibc config option help:
The new version has not been tested much, and lacks ports for arches
which glibc does not support (like bfin/frv/etc...), but is based on
which glibc does not support (like frv, etc...), but is based on
the latest code from glibc, so it may be the only choice for the
newer ports (like alpha/amd64/64bit arches and hppa).
@ -50,6 +50,7 @@ config LIBC_UCLIBC_LOCALES_PREGEN_DATA
bool
prompt "Use pregen locales"
depends on LIBC_UCLIBC_LOCALES
depends on ! LIBC_UCLIBC_NG
default y
help
If you see issues with using pre-generated locales data,

View File

@ -210,11 +210,14 @@ config ARCH_SUPPORTS_WITH_FPU
config ARCH_SUPPORTS_SOFTFP
bool
config ARCH_EXCLUSIVE_WITH_CPU
bool
config ARCH_ARCH
string
prompt "Architecture level"
depends on ARCH_SUPPORTS_WITH_ARCH
depends on ARCH_CPU = ""
depends on !ARCH_EXCLUSIVE_WITH_CPU || ARCH_CPU = ""
default ""
help
GCC uses this name to determine what kind of instructions it can emit
@ -271,7 +274,7 @@ config ARCH_TUNE
string
prompt "Tune for CPU"
depends on ARCH_SUPPORTS_WITH_TUNE
depends on ARCH_CPU = ""
depends on !ARCH_EXCLUSIVE_WITH_CPU || ARCH_CPU = ""
default ""
help
This option is very similar to the ARCH_CPU option (above), except

307
crosstool-ng/configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for crosstool-NG 1.20.0.
# Generated by GNU Autoconf 2.69 for crosstool-NG crosstool-ng-1.22.0.
#
# Report bugs to <crossgcc@sourceware.org>.
#
@ -580,8 +580,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='crosstool-NG'
PACKAGE_TARNAME='crosstool-ng'
PACKAGE_VERSION='1.20.0'
PACKAGE_STRING='crosstool-NG 1.20.0'
PACKAGE_VERSION='crosstool-ng-1.22.0'
PACKAGE_STRING='crosstool-NG crosstool-ng-1.22.0'
PACKAGE_BUGREPORT='crossgcc@sourceware.org'
PACKAGE_URL=''
@ -626,6 +626,7 @@ subdocdir
sublibdir
DATE
ac_ct_curses_hdr
INTL_LIBS
gettext
ALLOCA
LIBOBJS
@ -641,7 +642,9 @@ SET_MAKE
MAKE
_AWK
_BASH
ac_ct_PATCH
PATCH
help2man
bzip2
gzip
tar
@ -704,6 +707,7 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@ -791,6 +795,7 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@ -1043,6 +1048,15 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@ -1180,7 +1194,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir
libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@ -1293,7 +1307,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures crosstool-NG 1.20.0 to adapt to many kinds of systems.
\`configure' configures crosstool-NG crosstool-ng-1.22.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1333,6 +1347,7 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@ -1363,7 +1378,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of crosstool-NG 1.20.0:";;
short | recursive ) echo "Configuration of crosstool-NG crosstool-ng-1.22.0:";;
esac
cat <<\_ACEOF
@ -1469,7 +1484,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
crosstool-NG configure 1.20.0
crosstool-NG configure crosstool-ng-1.22.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -1938,7 +1953,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by crosstool-NG $as_me 1.20.0, which was
It was created by crosstool-NG $as_me crosstool-ng-1.22.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -4778,32 +4793,26 @@ done
as_fn_error $? "missing required tool: bzip2" "$LINENO" 5
fi
#--------------------------------------------------------------------
# Still boring, but remember the path, now...
#--------------------------------------------------------------------
for ac_prog in patch
for ac_prog in help2man
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_PATCH+:} false; then :
if ${ac_cv_prog_help2man+:} false; then :
$as_echo_n "(cached) " >&6
else
case $PATCH in
[\\/]* | ?:[\\/]*)
ac_cv_path_PATCH="$PATCH" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
if test -n "$help2man"; then
ac_cv_prog_help2man="$help2man" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PATCH="$as_dir/$ac_word$ac_exec_ext"
ac_cv_prog_help2man="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
@ -4811,10 +4820,60 @@ done
done
IFS=$as_save_IFS
;;
esac
fi
PATCH=$ac_cv_path_PATCH
fi
help2man=$ac_cv_prog_help2man
if test -n "$help2man"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $help2man" >&5
$as_echo "$help2man" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$help2man" && break
done
if test -z "$help2man"; then :
as_fn_error $? "missing required tool: help2man" "$LINENO" 5
fi
#--------------------------------------------------------------------
# Still boring, but remember the path, now...
#--------------------------------------------------------------------
if test -n "$ac_tool_prefix"; then
for ac_prog in gpatch patch
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_PATCH+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$PATCH"; then
ac_cv_prog_PATCH="$PATCH" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PATCH="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
PATCH=$ac_cv_prog_PATCH
if test -n "$PATCH"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATCH" >&5
$as_echo "$PATCH" >&6; }
@ -4824,14 +4883,83 @@ $as_echo "no" >&6; }
fi
test -n "$PATCH" && break
test -n "$PATCH" && break
done
fi
if test -z "$PATCH"; then
ac_ct_PATCH=$PATCH
for ac_prog in gpatch patch
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_PATCH+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_PATCH"; then
ac_cv_prog_ac_ct_PATCH="$ac_ct_PATCH" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_PATCH="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
if test -z "$PATCH"; then :
as_fn_error $? "missing required tool: patch" "$LINENO" 5
fi
fi
ac_ct_PATCH=$ac_cv_prog_ac_ct_PATCH
if test -n "$ac_ct_PATCH"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PATCH" >&5
$as_echo "$ac_ct_PATCH" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$ac_ct_PATCH" && break
done
if test "x$ac_ct_PATCH" = x; then
PATCH=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
PATCH=$ac_ct_PATCH
fi
fi
if test -z "$PATCH"; then :
as_fn_error $? "missing required tool: gpatch patch" "$LINENO" 5
fi
case $PATCH in #(
/*) :
;; #(
?*) :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for absolute path to $PATCH" >&5
$as_echo_n "checking for absolute path to $PATCH... " >&6; }
PATCH=$(which $PATCH)
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATCH" >&5
$as_echo "$PATCH" >&6; } ;; #(
*) :
;;
esac
#--------------------------------------------------------------------
# And a bunch of less boring tests...
#--------------------------------------------------------------------
@ -5919,7 +6047,7 @@ fi
#----------------------------------------
# Check for gettext, for the kconfig frontends
# Check for gettext and libintl for the kconfig frontends
for ac_header in libintl.h
do :
@ -5942,6 +6070,65 @@ if test "x$ac_cv_have_decl_gettext" = xyes; then :
fi
fi
SAVE_LIBS=$LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing bindtextdomain" >&5
$as_echo_n "checking for library containing bindtextdomain... " >&6; }
if ${ac_cv_search_bindtextdomain+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char bindtextdomain ();
int
main ()
{
return bindtextdomain ();
;
return 0;
}
_ACEOF
for ac_lib in '' intl; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_bindtextdomain=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_bindtextdomain+:} false; then :
break
fi
done
if ${ac_cv_search_bindtextdomain+:} false; then :
else
ac_cv_search_bindtextdomain=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_bindtextdomain" >&5
$as_echo "$ac_cv_search_bindtextdomain" >&6; }
ac_res=$ac_cv_search_bindtextdomain
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
test "$ac_res" = "none required" || INTL_LIBS="${ac_res}"
fi
LIBS=$SAVE_LIBS
#----------------------------------------
# Check for ncurses, for the kconfig frontends
@ -6021,6 +6208,62 @@ fi
if test -z "$ac_ct_curses_lib_found"; then :
as_fn_error $? "could not find curses library, required for the kconfig frontends" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tgetent" >&5
$as_echo_n "checking for library containing tgetent... " >&6; }
if ${ac_cv_search_tgetent+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char tgetent ();
int
main ()
{
return tgetent ();
;
return 0;
}
_ACEOF
for ac_lib in '' termcap tinfo ncursesw ncurses curses; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_tgetent=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_tgetent+:} false; then :
break
fi
done
if ${ac_cv_search_tgetent+:} false; then :
else
ac_cv_search_tgetent=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_tgetent" >&5
$as_echo "$ac_cv_search_tgetent" >&6; }
ac_res=$ac_cv_search_tgetent
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
fi
#--------------------------------------------------------------------
# Lastly, take care of crosstool-NG internal values
@ -6066,8 +6309,8 @@ $as_echo "$as_me: overiding all of --prefix and the likes, because --enable-loca
datarootdir="$prefix"
mandir="$docdir"
else
sublibdir="/ct-ng.\${VERSION}"
subdocdir="/ct-ng.\${VERSION}"
sublibdir="/\${VERSION}"
subdocdir="/\${VERSION}"
fi
#--------------------------------------------------------------------
@ -6617,7 +6860,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by crosstool-NG $as_me 1.20.0, which was
This file was extended by crosstool-NG $as_me crosstool-ng-1.22.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -6670,7 +6913,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
crosstool-NG config.status 1.20.0
crosstool-NG config.status crosstool-ng-1.22.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@ -171,11 +171,12 @@ ACX_CHECK_PROGS_REQ([wget], [wget])
ACX_CHECK_PROGS_REQ([tar], [tar])
ACX_CHECK_PROGS_REQ([gzip], [gzip])
ACX_CHECK_PROGS_REQ([bzip2], [bzip2])
ACX_CHECK_PROGS_REQ([help2man], [help2man])
#--------------------------------------------------------------------
# Still boring, but remember the path, now...
#--------------------------------------------------------------------
ACX_PATH_PROGS_REQ([PATCH], [patch])
ACX_PATH_TOOL_REQ([PATCH], [gpatch patch])
#--------------------------------------------------------------------
# And a bunch of less boring tests...
@ -320,7 +321,7 @@ AC_FUNC_REALLOC
AC_FUNC_ALLOCA
#----------------------------------------
# Check for gettext, for the kconfig frontends
# Check for gettext and libintl for the kconfig frontends
AC_SUBST([gettext])
AC_CHECK_HEADERS(
[libintl.h],
@ -332,6 +333,10 @@ AS_IF(
[gettext=y],,
[AC_INCLUDES_DEFAULT()
#include <$ac_ct_gettext_hdr>])])
SAVE_LIBS=$LIBS
AC_SEARCH_LIBS(bindtextdomain, intl, [test "$ac_res" = "none required" || INTL_LIBS="${ac_res}"])
LIBS=$SAVE_LIBS
AC_SUBST([INTL_LIBS])
#----------------------------------------
# Check for ncurses, for the kconfig frontends
@ -349,6 +354,9 @@ AC_SEARCH_LIBS(
AS_IF(
[test -z "$ac_ct_curses_lib_found"],
[AC_MSG_ERROR([could not find curses library, required for the kconfig frontends])])
AC_SEARCH_LIBS(
[tgetent],
[termcap tinfo ncursesw ncurses curses])
#--------------------------------------------------------------------
# Lastly, take care of crosstool-NG internal values

View File

@ -0,0 +1,41 @@
DO_C99_MATH=y
KERNEL_HEADERS="/usr/src/linux/include"
# LDSO_CACHE_SUPPORT is not set
# UCLIBC_STATIC_LDCONFIG is not set
LDSO_RUNPATH=y
LDSO_RUNPATH_OF_EXECUTABLE=y
MALLOC_GLIBC_COMPAT=y
UCLIBC_HAS_OBSTACK=y
UCLIBC_HAS_UTMPX=y
UCLIBC_HAS_UTMP=y
UCLIBC_SUSV2_LEGACY=y
UCLIBC_SUSV3_LEGACY=y
UCLIBC_HAS_CONTEXT_FUNCS=y
UCLIBC_SUSV4_LEGACY=y
UCLIBC_HAS_PROGRAM_INVOCATION_NAME=y
UCLIBC_HAS_GETPT=y
UCLIBC_HAS_LIBUTIL=y
UCLIBC_HAS_OBSOLETE_BSD_SIGNAL=y
UCLIBC_USE_NETLINK=y
UCLIBC_SUPPORT_AI_ADDRCONFIG=y
UCLIBC_HAS_RESOLVER_SUPPORT=y
UCLIBC_HAS_LIBRESOLV_STUB=y
UCLIBC_HAS_LIBNSL_STUB=y
UCLIBC_HAS_CTYPE_CHECKED=y
UCLIBC_HAS_HEXADECIMAL_FLOATS=y
UCLIBC_HAS_GLIBC_CUSTOM_PRINTF=y
UCLIBC_HAS_STDIO_GETC_MACRO=y
UCLIBC_HAS_STDIO_PUTC_MACRO=y
UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE=y
UCLIBC_HAS_GLIBC_CUSTOM_STREAMS=y
UCLIBC_HAS_PRINTF_M_SPEC=y
# UCLIBC_HAS_REGEX_OLD is not set
# UCLIBC_HAS_FNMATCH_OLD is not set
UCLIBC_HAS_NFTW=y
UCLIBC_HAS_FTW=y
UCLIBC_HAS_GNU_GLOB=y
RUNTIME_PREFIX="/"
DEVEL_PREFIX="/usr/"
UCLIBC_HAS_SSP=y
UCLIBC_BUILD_NOW=y
# DOSTRIP is not set

View File

@ -1,13 +1,12 @@
#
# Automatically generated make config: don't edit
# Version: 0.9.33.2
# Fri Sep 5 12:29:57 2014
# Version: 0.9.32-git
# Fri Jul 9 22:31:59 2010
#
# TARGET_alpha is not set
TARGET_arm=y
# TARGET_arm is not set
# TARGET_avr32 is not set
# TARGET_bfin is not set
# TARGET_c6x is not set
# TARGET_cris is not set
# TARGET_e1 is not set
# TARGET_frv is not set
@ -29,24 +28,43 @@ TARGET_arm=y
# TARGET_vax is not set
# TARGET_x86_64 is not set
# TARGET_xtensa is not set
# TARGET_c6x is not set
# CONFIG_GENERIC_ARM is not set
# CONFIG_ARM610 is not set
# CONFIG_ARM710 is not set
# CONFIG_ARM7TDMI is not set
# CONFIG_ARM720T is not set
# CONFIG_ARM920T is not set
# CONFIG_ARM922T is not set
# CONFIG_ARM926T is not set
# CONFIG_ARM10T is not set
# CONFIG_ARM1136JF_S is not set
# CONFIG_ARM1176JZ_S is not set
# CONFIG_ARM1176JZF_S is not set
# CONFIG_ARM_CORTEX_M3 is not set
# CONFIG_ARM_CORTEX_M1 is not set
# CONFIG_ARM_SA110 is not set
# CONFIG_ARM_SA1100 is not set
# CONFIG_ARM_XSCALE is not set
# CONFIG_ARM_IWMMXT is not set
# COMPILE_IN_THUMB_MODE is not set
USE_BX=y
TARGET_SUBARCH=""
#
# Target Architecture Features and Options
#
TARGET_ARCH="arm"
TARGET_ARCH="none"
FORCE_OPTIONS_FOR_ARCH=y
CONFIG_ARM_EABI=y
# COMPILE_IN_THUMB_MODE is not set
USE_BX=y
TARGET_SUBARCH=""
#
# Using ELF file format
#
ARCH_ANY_ENDIAN=y
ARCH_LITTLE_ENDIAN=y
# ARCH_LITTLE_ENDIAN is not set
# ARCH_BIG_ENDIAN is not set
# ARCH_WANTS_LITTLE_ENDIAN is not set
# ARCH_WANTS_BIG_ENDIAN is not set
ARCH_WANTS_LITTLE_ENDIAN=y
ARCH_HAS_MMU=y
ARCH_USE_MMU=y
UCLIBC_HAS_FLOATS=y
@ -54,14 +72,17 @@ UCLIBC_HAS_FPU=y
DO_C99_MATH=y
# DO_XSI_MATH is not set
# UCLIBC_HAS_FENV is not set
KERNEL_HEADERS="/usr/include"
UCLIBC_HAS_LONG_DOUBLE_MATH=y
KERNEL_HEADERS="/usr/src/linux/include"
HAVE_DOT_CONFIG=y
#
# General Library Settings
#
# HAVE_NO_PIC is not set
DOPIC=y
HAVE_SHARED=y
# ARCH_HAS_NO_SHARED is not set
# ARCH_HAS_NO_LDSO is not set
# FORCE_SHAREABLE_TEXT_SEGMENTS is not set
LDSO_LDD_SUPPORT=y
# LDSO_CACHE_SUPPORT is not set
@ -77,12 +98,11 @@ LDSO_LD_LIBRARY_PATH=y
UCLIBC_CTOR_DTOR=y
# LDSO_GNU_HASH_SUPPORT is not set
# HAS_NO_THREADS is not set
# LINUXTHREADS_OLD is not set
LINUXTHREADS_OLD=y
# LINUXTHREADS_NEW is not set
UCLIBC_HAS_THREADS_NATIVE=y
# UCLIBC_HAS_THREADS_NATIVE is not set
UCLIBC_HAS_THREADS=y
UCLIBC_HAS_TLS=y
PTHREADS_DEBUG_SUPPORT=y
# PTHREADS_DEBUG_SUPPORT is not set
UCLIBC_HAS_SYSLOG=y
UCLIBC_HAS_LFS=y
# MALLOC is not set
@ -144,6 +164,8 @@ UCLIBC_HAS_SOCKET=y
UCLIBC_HAS_IPV4=y
# UCLIBC_HAS_IPV6 is not set
# UCLIBC_HAS_RPC is not set
# UCLIBC_HAS_FULL_RPC is not set
# UCLIBC_HAS_REENTRANT_RPC is not set
UCLIBC_USE_NETLINK=y
UCLIBC_SUPPORT_AI_ADDRCONFIG=y
# UCLIBC_HAS_BSD_RES_CLOSE is not set
@ -156,7 +178,7 @@ UCLIBC_HAS_LIBNSL_STUB=y
#
# String and Stdio Support
#
# UCLIBC_HAS_STRING_GENERIC_OPT is not set
UCLIBC_HAS_STRING_GENERIC_OPT=y
UCLIBC_HAS_STRING_ARCH_OPT=y
UCLIBC_HAS_CTYPE_TABLES=y
UCLIBC_HAS_CTYPE_SIGNED=y
@ -166,6 +188,7 @@ UCLIBC_HAS_CTYPE_CHECKED=y
# UCLIBC_HAS_WCHAR is not set
# UCLIBC_HAS_LOCALE is not set
UCLIBC_HAS_HEXADECIMAL_FLOATS=y
# UCLIBC_HAS_GLIBC_DIGIT_GROUPING is not set
UCLIBC_HAS_GLIBC_CUSTOM_PRINTF=y
# USE_OLD_VFPRINTF is not set
UCLIBC_PRINTF_SCANF_POSITIONAL_ARGS=9
@ -181,8 +204,8 @@ UCLIBC_HAS_STDIO_BUILTIN_BUFFER_NONE=y
# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_4 is not set
# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_8 is not set
# UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT is not set
# UCLIBC_HAS_STDIO_GETC_MACRO is not set
# UCLIBC_HAS_STDIO_PUTC_MACRO is not set
UCLIBC_HAS_STDIO_GETC_MACRO=y
UCLIBC_HAS_STDIO_PUTC_MACRO=y
UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION=y
# UCLIBC_HAS_FOPEN_LARGEFILE_MODE is not set
UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE=y
@ -194,8 +217,7 @@ UCLIBC_HAS_ERRNO_MESSAGES=y
UCLIBC_HAS_SIGNUM_MESSAGES=y
# UCLIBC_HAS_SYS_SIGLIST is not set
UCLIBC_HAS_GNU_GETOPT=y
UCLIBC_HAS_STDIO_FUTEXES=y
# UCLIBC_HAS_GNU_GETSUBOPT is not set
UCLIBC_HAS_GNU_GETSUBOPT=y
#
# Big and Tall
@ -225,6 +247,7 @@ HARDWIRED_ABSPATH=y
#
# UCLIBC_BUILD_PIE is not set
# UCLIBC_HAS_ARC4RANDOM is not set
# HAVE_NO_SSP is not set
UCLIBC_HAS_SSP=y
# UCLIBC_HAS_SSP_COMPAT is not set
# SSP_QUICK_CANARY is not set
@ -236,11 +259,12 @@ UCLIBC_BUILD_NOW=y
UCLIBC_BUILD_NOEXECSTACK=y
#
# Development/debugging options
# uClibc development/debugging options
#
CROSS_COMPILER_PREFIX=""
UCLIBC_EXTRA_CFLAGS=""
# DODEBUG is not set
# DODEBUG_PT is not set
# DOSTRIP is not set
# DOASSERTS is not set
# SUPPORT_LD_DEBUG is not set

View File

@ -15,7 +15,7 @@ _ct_ng () {
start_steps=$(echo "${steps}" |sed -r -e 's/($| )/\1+/;')
stop_steps=$(echo "${steps}" |sed -r -e 's/(^| )/+\1/;')
actions='help menuconfig oldconfig saveconfig extractconfig
actions='help menuconfig nconfig oldconfig saveconfig extractconfig
defconfig savedefconfig
build build. build-all build-all.
wiki-samples list-samples list-samples-short check-samples

View File

@ -41,24 +41,24 @@ export CT_STOP:=$(STOP)
export CT_RESTART:=$(RESTART)
SILENT=@
ECHO=echo
CT_ECHO=echo
ifeq ($(strip $(origin V)),command line)
ifeq ($(strip $(V)),0)
SILENT=@
ECHO=:
CT_ECHO=:
else
ifeq ($(strip $(V)),1)
SILENT=
ECHO=:
CT_ECHO=:
else
ifeq ($(strip $(V)),2)
SILENT=
ECHO=echo
CT_ECHO=echo
endif # V == 2
endif # V== 1
endif # V == 0
endif # origin V
export V SILENT ECHO
export V SILENT CT_ECHO
all: help
@ -104,6 +104,7 @@ help-tail::
@echo 'See "man 1 $(notdir $(CT_NG))" for some help as well'
help-build::
@echo ' source - Download sources for currently configured toolchain'
@echo ' build[.#] - Build the currently configured toolchain'
help-clean::
@ -122,7 +123,8 @@ help-config::
help-distrib::
help-env::
@echo ' V=0|1|2 - 0 => show only human-readable messages (default)'
@echo ' V=0|1|2|<unset> - <unset> show only human-readable messages (default)'
@echo ' 0 => do not show commands or human-readable message'
@echo ' 1 => show only the commands being executed'
@echo ' 2 => show both'
@ -143,11 +145,14 @@ show-tuple: .config.2
$(SILENT)$(bash) $(CT_LIB_DIR)/scripts/showTuple.sh
# Actual build
source: .config.2
$(SILENT)CT_SOURCE=y $(CT_LIB_DIR)/scripts/crosstool-NG.sh
build: .config.2
$(SILENT)$(CT_LIB_DIR)/scripts/crosstool-NG.sh
build.%:
$(SILENT)$(MAKE) -rf $(CT_NG) $(shell echo "$(@)" |$(sed) -r -e 's|^([^.]+)\.([[:digit:]]+)$$|\1 CT_JOBS=\2|;')
$(SILENT)$(MAKE) -rf $(CT_NG) build CT_JOBS=$*
PHONY += version
version:
@ -161,14 +166,14 @@ version:
PHONY += clean
clean::
@$(ECHO) " CLEAN log"
@$(CT_ECHO) " CLEAN log"
$(SILENT)rm -f build.log
@$(ECHO) " CLEAN build dir"
@$(CT_ECHO) " CLEAN build dir"
$(SILENT)[ ! -d targets ] || chmod -R u+w targets
$(SILENT)[ ! -d .build ] || chmod -R u+w .build
$(SILENT)rm -rf targets .build
$(SILENT)rm -rf targets .build .build-all
PHONY += distclean
distclean:: clean
@$(ECHO) " CLEAN .config"
@$(CT_ECHO) " CLEAN .config"
$(SILENT)rm -f .config .config.* ..config*

BIN
crosstool-ng/dl/binutils-2.25.1.tar.bz2 (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
crosstool-ng/dl/expat-2.1.0.tar.gz (Stored with Git LFS) Normal file

Binary file not shown.

BIN
crosstool-ng/dl/gdb-7.10.tar.xz (Stored with Git LFS) Normal file

Binary file not shown.

BIN
crosstool-ng/dl/gdb-7.9.1.tar.xz (Stored with Git LFS)

Binary file not shown.

BIN
crosstool-ng/dl/mpc-1.0.2.tar.gz (Stored with Git LFS)

Binary file not shown.

BIN
crosstool-ng/dl/mpc-1.0.3.tar.gz (Stored with Git LFS) Normal file

Binary file not shown.

BIN
crosstool-ng/dl/mpfr-3.1.2.tar.xz (Stored with Git LFS)

Binary file not shown.

BIN
crosstool-ng/dl/mpfr-3.1.3.tar.xz (Stored with Git LFS) Normal file

Binary file not shown.

BIN
crosstool-ng/dl/ncurses-6.0.tar.gz (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -15,7 +15,7 @@ will support, the version of the components you want to use, etc... The
value for those options are then stored in a configuration file.
The configurator works the same way you configure your Linux kernel. It is
assumed you now how to handle this.
assumed you know how to handle this.
To enter the menu, type:
ct-ng menuconfig

View File

@ -313,3 +313,91 @@ Here is an example commit message (see revision 8bb5151c5b01):
I missed refreshing the patch before pushing. :-(
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Using crosstool-NG on Windows |
------------------------------+
Contributed by: Ray Donnelly
Prerequisites and instructions for using crosstool-NG for building a cross
toolchain on Windows (Cygwin) as build and, optionally Windows (hereafter)
MinGW-w64 as host.
0. Use Cygwin64 if you can. DLL base-address problems are lessened that
way and if you bought a 64-bit CPU, you may as well use it.
1. You must enable Case Sensitivity in the Windows Kernel (this is only really
necessary for Linux targets, but at present, crosstool-ng refuses to operate
on case insensitive filesystems). The registry key for this is:
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\kernel\obcaseinsensitive
Read more at:
https://cygwin.com/cygwin-ug-net/using-specialnames.html
2. Using setup{,-x86_64}.exe, install the default packages and also the
following ones: (tested versions in brackets, please test newer versions
and report successes via pull requests changing this list and failures to:
https://github.com/crosstool-ng/crosstool-ng/issues
autoconf (13-1), make (4.1-1), gcc-g++ (4.9.3-1), gperf (3.0.4-2),
bison (3.0.4-1), flex (2.5.39-1), texinfo (6.0-1), wget (1.16.3-1),
patch (2.7.4-1), libtool (2.4.6-2), automake (9-1), diffutils (3.3-3),
libncurses-devel (6.0-1.20151017), help2man (1.44.1-1)
mingw64-i686-gcc-g++* (4.9.2-2), mingw64-x86_64-gcc-g++* (4.9.2-2)
Leave "Select required packages (RECOMMENDED)" ticked.
Notes:
2.1 The packages marked with * are only needed if your host is MinGW-w64.
2.2 Unfortunately, wget pulls in an awful lot of dependencies, including
Python 2.7, Ruby, glib and Tcl.
3. Although nativestrict symlinks seem like the best idea, extracting glibc fails
when they are enabled, so just don't set anything here. If your host is MinGW-w64
then these 'Cygwin-special' symlinks won't work, but you can dereference them by
using tar options --dereference and --hard-dereference when making a final tarball.
I plan to investigate and fix or at least work around the extraction problem.
Read more at:
https://cygwin.com/cygwin-ug-net/using-cygwinenv.html
4. collect2.exe will attempt to run ld which is a shell script that runs either
ld.exe or gold.exe so you need to make sure that a working shell is in your path.
Eventually I will replace this with a native program for MinGW-w64 host.
Using crosstool-NG to build Xtensa toolchains |
----------------------------------------------+
Contributed by: Max Filippov
Xtensa cores are highly configurable: endianness, instruction set, register set
of a core is chosen at processor configuration time. New registers and
instructions may be added by designers, making each core configuration unique.
Toolchain components cannot know about features of each individual core and
need to be configured in order to be compatible with particular architecture
variant. This configuration includes:
- definitions of instruction formats, names and properties for assembler,
disassembler and debugger;
- definitions of register names and properties for assembler, disassembler and
debugger;
- selection of predefined features, such as endianness, presence of certain
processor options or instructions for compiler, debugger C library and OS
kernels;
- macros with instruction sequences for saving and restoring special, user or
coprocessor registers for OS kernels.
This configuration is provided in form of source files, that must replace
corresponding files in binutils, gcc, gdb or newlib source trees or be added
to OS kernel source tree. This set of files is usually distributed as archive
known as Xtensa configuration overlay.
Tensilica provides such an overlay as part of the processor download, however,
it needs to be reformatted to match the specific format required by the
crosstool-NG. For a script to convert the overlay file, and additional
information, please see
http://wiki.linux-xtensa.org/index.php/Toolchain_Overlay_File
The current version of crosstool-NG requires that the overlay file name has the
format xtensa_<CORE_NAME>.tar, where CORE_NAME can be any user selected name.
To make crosstool-NG use overlay file located at <PATH>/xtensa_<CORE_NAME>.tar
select XTENSA_CUSTOM, set config parameter CT_ARCH_XTENSA_CUSTOM_NAME to
CORE_NAME and CT_ARCH_XTENSA_CUSTOM_OVERLAY_LOCATION to PATH.
The fsf target architecture variant is the configuration provided by toolchain
components by default. It is present only for build-testing toolchain
components and is in no way special or universal.

View File

@ -2,7 +2,6 @@ conf
?conf
**.o
**.dep
lex.backup
lex.zconf.c
zconf.lex.c
zconf.hash.c
zconf.tab.c

View File

@ -7,11 +7,11 @@ all: conf mconf nconf
# Build flags
CFLAGS = -DCONFIG_=\"CT_\" -DPACKAGE="\"crosstool-NG $(VERSION)\""
LDFLAGS =
LDFLAGS = $(INTL_LIBS)
# Compiler flags to use gettext
ifeq ($(gettext),)
INTL_CFLAGS = -DKBUILD_NO_NLS
INTL_CFLAGS = -Wno-format-security -DKBUILD_NO_NLS
endif
# Compiler and linker flags to use ncurses
@ -48,14 +48,7 @@ nconf_SRC = nconf.c nconf.gui.c
nconf_OBJ = $(patsubst %.c,%.o,$(nconf_SRC))
nconf_DEP = $(patsubst %.c,%.dep,$(nconf_SRC))
$(nconf_OBJ) $(nconf_DEP): CFLAGS += $(INTL_CFLAGS) -I/usr/include/ncurses
nconf: LDFLAGS += -lmenu -lpanel -lncurses
# Under Cygwin, we need to auto-import some libs (which ones, exactly?)
# for mconf and nconf to lin properly.
ifeq ($(shell uname -o 2>/dev/null || echo unknown),Cygwin)
mconf: LDFLAGS += -Wl,--enable-auto-import
nconf: LDFLAGS += -Wl,--enable-auto-import
endif
nconf: LDFLAGS += -lmenu -lpanel $(LIBS)
# These are generated files:
ALL_OBJS = $(sort $(COMMON_OBJ) $(LX_OBJ) $(conf_OBJ) $(mconf_OBJ) $(nconf_OBJ))
@ -74,8 +67,8 @@ DEPS += $(nconf_DEP)
@$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -MM $< |$(sed) -r -e 's|([^:]+.o)( *:+)|$(<:.c=.o) $@\2|;' >$@
# Generate the grammar parser
zconf.tab.o: zconf.tab.c zconf.hash.c lex.zconf.c
zconf.tab.dep: zconf.tab.c zconf.hash.c lex.zconf.c
zconf.tab.o: zconf.tab.c zconf.hash.c zconf.lex.c
zconf.tab.dep: zconf.tab.c zconf.hash.c zconf.lex.c
.PRECIOUS: zconf.tab.c
zconf.tab.c: zconf.y
@ -84,9 +77,9 @@ zconf.tab.c: zconf.y
zconf.hash.c: zconf.gperf
@echo " GPERF '$@'"
@$(gperf) < $< > $@
@$(gperf) -C < $< > $@
lex.zconf.c: zconf.l
zconf.lex.c: zconf.l
@echo " LEX '$@'"
@flex -L -Pzconf -o$@ $<
@ -114,4 +107,4 @@ conf: $(COMMON_OBJ) $(conf_OBJ)
clean:
@echo " RM 'kconfig'"
@rm -f conf mconf nconf $(ALL_OBJS) $(ALL_DEPS)
@rm -f rm -f zconf.tab.c zconf.hash.c lex.zconf.c lex.backup
@rm -f rm -f zconf.tab.c zconf.hash.c zconf.lex.c lex.backup

View File

@ -1,6 +1,6 @@
#!/bin/sh
# Needed for systems without gettext
$* -xc -o /dev/null - > /dev/null 2>&1 << EOF
$* -x c -o /dev/null - > /dev/null 2>&1 << EOF
#include <libintl.h>
int main()
{
@ -11,4 +11,3 @@ EOF
if [ ! "$?" -eq "0" ]; then
echo -DKBUILD_NO_NLS;
fi

View File

@ -13,12 +13,13 @@
#include <getopt.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <errno.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
static void conf(struct menu *menu);
static void check_conf(struct menu *menu);
static void xfgets(char *str, int size, FILE *in);
enum input_mode {
oldaskconfig,
@ -32,12 +33,11 @@ enum input_mode {
defconfig,
savedefconfig,
listnewconfig,
oldnoconfig,
olddefconfig,
} input_mode = oldaskconfig;
char *defconfig_file;
static int indent = 1;
static int tty_stdio;
static int valid_stdin = 1;
static int sync_kconfig;
static int conf_cnt;
@ -106,9 +106,12 @@ static int conf_askvalue(struct symbol *sym, const char *def)
return 0;
}
check_stdin();
/* fall through */
case oldaskconfig:
fflush(stdout);
xfgets(line, 128, stdin);
if (!tty_stdio)
printf("\n");
return 1;
default:
break;
@ -150,6 +153,7 @@ static int conf_string(struct menu *menu)
def = NULL;
break;
}
/* fall through */
default:
line[strlen(line)-1] = 0;
def = line;
@ -304,6 +308,7 @@ static int conf_choice(struct menu *menu)
break;
}
check_stdin();
/* fall through */
case oldaskconfig:
fflush(stdout);
xfgets(line, 128, stdin);
@ -364,11 +369,12 @@ static void conf(struct menu *menu)
case P_MENU:
if ((input_mode == silentoldconfig ||
input_mode == listnewconfig ||
input_mode == oldnoconfig) &&
input_mode == olddefconfig) &&
rootEntry != menu) {
check_conf(menu);
return;
}
/* fall through */
case P_COMMENT:
prompt = menu_get_prompt(menu);
if (prompt)
@ -427,7 +433,7 @@ static void check_conf(struct menu *menu)
if (sym->name && !sym_is_choice_value(sym)) {
printf("%s%s\n", CONFIG_, sym->name);
}
} else if (input_mode != oldnoconfig) {
} else if (input_mode != olddefconfig) {
if (!conf_cnt++)
printf(_("*\n* Restart config...\n*\n"));
rootEntry = menu_get_parent_menu(menu);
@ -452,21 +458,34 @@ static struct option long_opts[] = {
{"alldefconfig", no_argument, NULL, alldefconfig},
{"randconfig", no_argument, NULL, randconfig},
{"listnewconfig", no_argument, NULL, listnewconfig},
{"oldnoconfig", no_argument, NULL, oldnoconfig},
{"olddefconfig", no_argument, NULL, olddefconfig},
/*
* oldnoconfig is an alias of olddefconfig, because people already
* are dependent on its behavior(sets new symbols to their default
* value but not 'n') with the counter-intuitive name.
*/
{"oldnoconfig", no_argument, NULL, olddefconfig},
{NULL, 0, NULL, 0}
};
int main(int ac, char **av)
{
const char *progname = av[0];
int opt;
const char *name;
const char *name, *defconfig_file = NULL /* gcc uninit */;
struct stat tmpstat;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) {
tty_stdio = isatty(0) && isatty(1) && isatty(2);
while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {
if (opt == 's') {
conf_set_message_callback(NULL);
continue;
}
input_mode = (enum input_mode)opt;
switch (opt) {
case silentoldconfig:
@ -480,17 +499,36 @@ int main(int ac, char **av)
{
struct timeval now;
unsigned int seed;
char *seed_env;
/*
* Use microseconds derived seed,
* compensate for systems where it may be zero
*/
gettimeofday(&now, NULL);
seed = (unsigned int)((now.tv_sec + 1) * (now.tv_usec + 1));
seed_env = getenv("KCONFIG_SEED");
if( seed_env && *seed_env ) {
char *endp;
int tmp = (int)strtol(seed_env, &endp, 0);
if (*endp == '\0') {
seed = tmp;
}
}
fprintf( stderr, "KCONFIG_SEED=0x%X\n", seed );
srand(seed);
break;
}
case oldaskconfig:
case oldconfig:
case allnoconfig:
case allyesconfig:
case allmodconfig:
case alldefconfig:
case listnewconfig:
case olddefconfig:
break;
case '?':
fprintf(stderr, _("See README for usage info\n"));
exit(1);
@ -533,7 +571,7 @@ int main(int ac, char **av)
case oldaskconfig:
case oldconfig:
case listnewconfig:
case oldnoconfig:
case olddefconfig:
conf_read(NULL);
break;
case allnoconfig:
@ -542,8 +580,15 @@ int main(int ac, char **av)
case alldefconfig:
case randconfig:
name = getenv("KCONFIG_ALLCONFIG");
if (name && !stat(name, &tmpstat)) {
conf_read_simple(name, S_DEF_USER);
if (!name)
break;
if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
if (conf_read_simple(name, S_DEF_USER)) {
fprintf(stderr,
_("*** Can't read seed configuration \"%s\"!\n"),
name);
exit(1);
}
break;
}
switch (input_mode) {
@ -554,10 +599,13 @@ int main(int ac, char **av)
case randconfig: name = "allrandom.config"; break;
default: break;
}
if (!stat(name, &tmpstat))
conf_read_simple(name, S_DEF_USER);
else if (!stat("all.config", &tmpstat))
conf_read_simple("all.config", S_DEF_USER);
if (conf_read_simple(name, S_DEF_USER) &&
conf_read_simple("all.config", S_DEF_USER)) {
fprintf(stderr,
_("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"),
name);
exit(1);
}
break;
default:
break;
@ -572,7 +620,7 @@ int main(int ac, char **av)
return 1;
}
}
valid_stdin = isatty(0) && isatty(1) && isatty(2);
valid_stdin = tty_stdio;
}
switch (input_mode) {
@ -589,7 +637,8 @@ int main(int ac, char **av)
conf_set_all_new_symbols(def_default);
break;
case randconfig:
conf_set_all_new_symbols(def_random);
/* Really nothing to do in this loop */
while (conf_set_all_new_symbols(def_random)) ;
break;
case defconfig:
conf_set_all_new_symbols(def_default);
@ -603,7 +652,7 @@ int main(int ac, char **av)
/* fall through */
case oldconfig:
case listnewconfig:
case oldnoconfig:
case olddefconfig:
case silentoldconfig:
/* Update until a loop caused no more changes */
do {
@ -611,7 +660,7 @@ int main(int ac, char **av)
check_conf(&rootmenu);
} while (conf_cnt &&
(input_mode != listnewconfig &&
input_mode != oldnoconfig));
input_mode != olddefconfig));
break;
}
@ -623,11 +672,15 @@ int main(int ac, char **av)
fprintf(stderr, _("\n*** Error during writing of the configuration.\n\n"));
exit(1);
}
/* In crosstool-NG, we do not use the autoconf stuff */
/* In crosstool-NG, we do not use the autoconf stuff
if (conf_write_autoconf()) {
fprintf(stderr, _("\n*** Error during update of the configuration.\n\n"));
return 1;
} */
} else if (input_mode == savedefconfig) {
if (conf_write_defconfig(defconfig_file)) {
fprintf(stderr, _("n*** Error while saving defconfig to: %s\n\n"),
defconfig_file);
defconfig_file);
return 1;
}
} else if (input_mode != listnewconfig) {
@ -638,13 +691,11 @@ int main(int ac, char **av)
}
return 0;
}
/*
* Helper function to facilitate fgets() by Jean Sacren.
*/
void xfgets(str, size, in)
char *str;
int size;
FILE *in;
void xfgets(char *str, int size, FILE *in)
{
if (fgets(str, size, in) == NULL)
fprintf(stderr, "\nError in reading or end of file.\n");

View File

@ -7,15 +7,20 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
struct conf_printer {
void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
void (*print_comment)(FILE *, const char *, void *);
};
static void conf_warning(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
@ -59,6 +64,7 @@ static void conf_message(const char *fmt, ...)
va_start(ap, fmt);
if (conf_message_callback)
conf_message_callback(fmt, ap);
va_end(ap);
}
const char *conf_get_configname(void)
@ -128,6 +134,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
sym->flags |= def_flags;
break;
}
/* fall through */
case S_BOOLEAN:
if (p[0] == 'y') {
sym->def[def].tri = yes;
@ -139,8 +146,10 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
sym->flags |= def_flags;
break;
}
conf_warning("symbol value '%s' invalid for %s", p, sym->name);
break;
if (def != S_DEF_AUTO)
conf_warning("symbol value '%s' invalid for %s",
p, sym->name);
return 1;
case S_OTHER:
if (*p != '"') {
for (p2 = p; *p2 && !isspace(*p2); p2++)
@ -148,6 +157,7 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
sym->type = S_STRING;
goto done;
}
/* fall through */
case S_STRING:
if (*p++ != '"')
break;
@ -159,9 +169,11 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
memmove(p2, p2 + 1, strlen(p2));
}
if (!p2) {
conf_warning("invalid string found");
if (def != S_DEF_AUTO)
conf_warning("invalid string found");
return 1;
}
/* fall through */
case S_INT:
case S_HEX:
done:
@ -169,7 +181,9 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
sym->def[def].val = strdup(p);
sym->flags |= def_flags;
} else {
conf_warning("symbol value '%s' invalid for %s", p, sym->name);
if (def != S_DEF_AUTO)
conf_warning("symbol value '%s' invalid for %s",
p, sym->name);
return 1;
}
break;
@ -179,10 +193,66 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
return 0;
}
#define LINE_GROWTH 16
static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
{
char *nline;
size_t new_size = slen + 1;
if (new_size > *n) {
new_size += LINE_GROWTH - 1;
new_size *= 2;
nline = realloc(*lineptr, new_size);
if (!nline)
return -1;
*lineptr = nline;
*n = new_size;
}
(*lineptr)[slen] = c;
return 0;
}
static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream)
{
char *line = *lineptr;
size_t slen = 0;
for (;;) {
int c = getc(stream);
switch (c) {
case '\n':
if (add_byte(c, &line, slen, n) < 0)
goto e_out;
slen++;
/* fall through */
case EOF:
if (add_byte('\0', &line, slen, n) < 0)
goto e_out;
*lineptr = line;
if (slen == 0)
return -1;
return slen;
default:
if (add_byte(c, &line, slen, n) < 0)
goto e_out;
slen++;
}
}
e_out:
line[slen-1] = '\0';
*lineptr = line;
return -1;
}
int conf_read_simple(const char *name, int def)
{
FILE *in = NULL;
char line[1024];
char *line = NULL;
size_t line_asize = 0;
char *p, *p2;
struct symbol *sym;
int i, def_flags;
@ -198,8 +268,7 @@ int conf_read_simple(const char *name, int def)
goto load;
sym_add_change_count(1);
if (!sym_defconfig_list) {
if (modules_sym)
sym_calc_value(modules_sym);
sym_calc_value(modules_sym);
return 1;
}
@ -237,13 +306,14 @@ load:
case S_STRING:
if (sym->def[def].val)
free(sym->def[def].val);
/* fall through */
default:
sym->def[def].val = NULL;
sym->def[def].tri = no;
}
}
while (fgets(line, sizeof(line), in)) {
while (compat_getline(&line, &line_asize, in) != -1) {
conf_lineno++;
sym = NULL;
if (line[0] == '#') {
@ -331,19 +401,16 @@ setsym:
cs->def[def].tri = EXPR_OR(cs->def[def].tri, sym->def[def].tri);
}
}
free(line);
fclose(in);
if (modules_sym)
sym_calc_value(modules_sym);
sym_calc_value(modules_sym);
return 0;
}
int conf_read(const char *name)
{
struct symbol *sym, *choice_sym;
struct property *prop;
struct expr *e;
int i, flags;
struct symbol *sym;
int i;
sym_set_change_count(0);
@ -353,7 +420,7 @@ int conf_read(const char *name)
for_all_symbols(i, sym) {
sym_calc_value(sym);
if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
goto sym_ok;
continue;
if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
/* check that calculated value agrees with saved value */
switch (sym->type) {
@ -362,29 +429,18 @@ int conf_read(const char *name)
if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
break;
if (!sym_is_choice(sym))
goto sym_ok;
continue;
/* fall through */
default:
if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
goto sym_ok;
continue;
break;
}
} else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
/* no previous value and not saved */
goto sym_ok;
continue;
conf_unsaved++;
/* maybe print value in verbose mode... */
sym_ok:
if (!sym_is_choice(sym))
continue;
/* The choice symbol only has a set value (and thus is not new)
* if all its visible childs have values.
*/
prop = sym_get_choice_prop(sym);
flags = sym->flags;
expr_list_for_each_sym(prop->expr, e, choice_sym)
if (choice_sym->visible != no)
flags &= choice_sym->flags;
sym->flags &= flags | ~SYMBOL_DEF_USER;
}
for_all_symbols(i, sym) {
@ -417,64 +473,191 @@ int conf_read(const char *name)
return 0;
}
/* Write a S_STRING */
static void conf_write_string(bool headerfile, const char *name,
const char *str, FILE *out)
/*
* Kconfig configuration printer
*
* This printer is used when generating the resulting configuration after
* kconfig invocation and `defconfig' files. Unset symbol might be omitted by
* passing a non-NULL argument to the printer.
*
*/
static void
kconfig_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
{
int l;
if (headerfile)
fprintf(out, "#define %s%s \"", CONFIG_, name);
else
fprintf(out, "%s%s=\"", CONFIG_, name);
while (1) {
l = strcspn(str, "\"\\");
if (l) {
xfwrite(str, l, 1, out);
str += l;
}
if (!*str)
break;
fprintf(out, "\\%c", *str++);
}
fputs("\"\n", out);
}
static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no)
{
const char *str;
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
switch (sym_get_tristate_value(sym)) {
case no:
if (write_no)
fprintf(out, "# %s%s is not set\n",
if (*value == 'n') {
bool skip_unset = (arg != NULL);
if (!skip_unset)
fprintf(fp, "# %s%s is not set\n",
CONFIG_, sym->name);
break;
case mod:
fprintf(out, "%s%s=m\n", CONFIG_, sym->name);
break;
case yes:
fprintf(out, "%s%s=y\n", CONFIG_, sym->name);
break;
return;
}
break;
default:
break;
}
fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, value);
}
static void
kconfig_print_comment(FILE *fp, const char *value, void *arg)
{
const char *p = value;
size_t l;
for (;;) {
l = strcspn(p, "\n");
fprintf(fp, "#");
if (l) {
fprintf(fp, " ");
xfwrite(p, l, 1, fp);
p += l;
}
fprintf(fp, "\n");
if (*p++ == '\0')
break;
}
}
static struct conf_printer kconfig_printer_cb =
{
.print_symbol = kconfig_print_symbol,
.print_comment = kconfig_print_comment,
};
/*
* Header printer
*
* This printer is used when generating the `include/generated/autoconf.h' file.
*/
static void
header_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
{
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE: {
const char *suffix = "";
switch (*value) {
case 'n':
break;
case 'm':
suffix = "_MODULE";
/* fall through */
default:
fprintf(fp, "#define %s%s%s 1\n",
CONFIG_, sym->name, suffix);
}
break;
}
case S_HEX: {
const char *prefix = "";
if (value[0] != '0' || (value[1] != 'x' && value[1] != 'X'))
prefix = "0x";
fprintf(fp, "#define %s%s %s%s\n",
CONFIG_, sym->name, prefix, value);
break;
}
case S_STRING:
conf_write_string(false, sym->name, sym_get_string_value(sym), out);
break;
case S_HEX:
case S_INT:
str = sym_get_string_value(sym);
fprintf(out, "%s%s=%s\n", CONFIG_, sym->name, str);
fprintf(fp, "#define %s%s %s\n",
CONFIG_, sym->name, value);
break;
default:
break;
}
}
static void
header_print_comment(FILE *fp, const char *value, void *arg)
{
const char *p = value;
size_t l;
fprintf(fp, "/*\n");
for (;;) {
l = strcspn(p, "\n");
fprintf(fp, " *");
if (l) {
fprintf(fp, " ");
xfwrite(p, l, 1, fp);
p += l;
}
fprintf(fp, "\n");
if (*p++ == '\0')
break;
}
fprintf(fp, " */\n");
}
static struct conf_printer header_printer_cb =
{
.print_symbol = header_print_symbol,
.print_comment = header_print_comment,
};
/*
* Tristate printer
*
* This printer is used when generating the `include/config/tristate.conf' file.
*/
static void
tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
{
if (sym->type == S_TRISTATE && *value != 'n')
fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value));
}
static struct conf_printer tristate_printer_cb =
{
.print_symbol = tristate_print_symbol,
.print_comment = kconfig_print_comment,
};
static void conf_write_symbol(FILE *fp, struct symbol *sym,
struct conf_printer *printer, void *printer_arg)
{
const char *str;
switch (sym->type) {
case S_OTHER:
case S_UNKNOWN:
break;
case S_STRING:
str = sym_get_string_value(sym);
str = sym_escape_string_value(str);
printer->print_symbol(fp, sym, str, printer_arg);
free((void *)str);
break;
default:
str = sym_get_string_value(sym);
printer->print_symbol(fp, sym, str, printer_arg);
}
}
static void
conf_write_heading(FILE *fp, struct conf_printer *printer, void *printer_arg)
{
char buf[256];
snprintf(buf, sizeof(buf),
"\n"
"Automatically generated file; DO NOT EDIT.\n"
"%s\n",
rootmenu.prompt->text);
printer->print_comment(fp, buf, printer_arg);
}
/*
* Write out a minimal config.
* All values that has default values are skipped as this is redundant.
@ -531,7 +714,7 @@ int conf_write_defconfig(const char *filename)
goto next_menu;
}
}
conf_write_symbol(sym, out, true);
conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
}
next_menu:
if (menu->list != NULL) {
@ -560,8 +743,6 @@ int conf_write(const char *name)
const char *basename;
const char *str;
char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
time_t now;
int use_timestamp = 1;
char *env;
dirname[0] = 0;
@ -598,19 +779,7 @@ int conf_write(const char *name)
if (!out)
return 1;
time(&now);
env = getenv("KCONFIG_NOTIMESTAMP");
if (env && *env)
use_timestamp = 0;
fprintf(out, _("#\n"
"# Automatically generated make config: don't edit\n"
"# %s\n"
"%s%s"
"#\n"),
rootmenu.prompt->text,
use_timestamp ? "# " : "",
use_timestamp ? ctime(&now) : "");
conf_write_heading(out, &kconfig_printer_cb, NULL);
if (!conf_get_changed())
sym_clear_all_valid();
@ -631,8 +800,8 @@ int conf_write(const char *name)
if (!(sym->flags & SYMBOL_WRITE))
goto next;
sym->flags &= ~SYMBOL_WRITE;
/* Write config symbol to file */
conf_write_symbol(sym, out, true);
conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
}
next:
@ -659,7 +828,7 @@ next:
return 1;
}
conf_message(_("configuration saved"));
conf_message(_("configuration written to %s"), newname);
sym_set_change_count(0);
@ -781,7 +950,6 @@ out:
int conf_write_autoconf(void)
{
struct symbol *sym;
const char *str;
const char *name;
FILE *out, *tristate, *out_h;
int i;
@ -810,68 +978,23 @@ int conf_write_autoconf(void)
return 1;
}
fprintf(out, "#\n"
"# Automatically generated make config: don't edit\n"
"# %s\n"
"#\n",
rootmenu.prompt->text);
fprintf(tristate, "#\n"
"# Automatically generated - do not edit\n"
"\n");
fprintf(out_h, "/*\n"
" * Automatically generated C config: don't edit\n"
" * %s\n"
" */\n",
rootmenu.prompt->text);
conf_write_heading(out, &kconfig_printer_cb, NULL);
conf_write_heading(tristate, &tristate_printer_cb, NULL);
conf_write_heading(out_h, &header_printer_cb, NULL);
for_all_symbols(i, sym) {
sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
continue;
/* write symbol to config file */
conf_write_symbol(sym, out, false);
/* write symbol to auto.conf, tristate and header files */
conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
/* update autoconf and tristate files */
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
switch (sym_get_tristate_value(sym)) {
case no:
break;
case mod:
fprintf(tristate, "%s%s=M\n",
CONFIG_, sym->name);
fprintf(out_h, "#define %s%s_MODULE 1\n",
CONFIG_, sym->name);
break;
case yes:
if (sym->type == S_TRISTATE)
fprintf(tristate,"%s%s=Y\n",
CONFIG_, sym->name);
fprintf(out_h, "#define %s%s 1\n",
CONFIG_, sym->name);
break;
}
break;
case S_STRING:
conf_write_string(true, sym->name, sym_get_string_value(sym), out_h);
break;
case S_HEX:
str = sym_get_string_value(sym);
if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
fprintf(out_h, "#define %s%s 0x%s\n",
CONFIG_, sym->name, str);
break;
}
case S_INT:
str = sym_get_string_value(sym);
fprintf(out_h, "#define %s%s %s\n",
CONFIG_, sym->name, str);
break;
default:
break;
}
conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1);
conf_write_symbol(out_h, sym, &header_printer_cb, NULL);
}
fclose(out);
fclose(tristate);
@ -925,7 +1048,7 @@ void conf_set_changed_callback(void (*fn)(void))
conf_changed_callback = fn;
}
static void randomize_choice_values(struct symbol *csym)
static bool randomize_choice_values(struct symbol *csym)
{
struct property *prop;
struct symbol *sym;
@ -938,7 +1061,7 @@ static void randomize_choice_values(struct symbol *csym)
* In both cases stop.
*/
if (csym->curr.tri != yes)
return;
return false;
prop = sym_get_choice_prop(csym);
@ -962,13 +1085,18 @@ static void randomize_choice_values(struct symbol *csym)
else {
sym->def[S_DEF_USER].tri = no;
}
sym->flags |= SYMBOL_DEF_USER;
/* clear VALID to get value calculated */
sym->flags &= ~SYMBOL_VALID;
}
csym->flags |= SYMBOL_DEF_USER;
/* clear VALID to get value calculated */
csym->flags &= ~(SYMBOL_VALID);
return true;
}
static void set_all_choice_values(struct symbol *csym)
void set_all_choice_values(struct symbol *csym)
{
struct property *prop;
struct symbol *sym;
@ -985,20 +1113,66 @@ static void set_all_choice_values(struct symbol *csym)
}
csym->flags |= SYMBOL_DEF_USER;
/* clear VALID to get value calculated */
csym->flags &= ~(SYMBOL_VALID);
csym->flags &= ~(SYMBOL_VALID | SYMBOL_NEED_SET_CHOICE_VALUES);
}
void conf_set_all_new_symbols(enum conf_def_mode mode)
bool conf_set_all_new_symbols(enum conf_def_mode mode)
{
struct symbol *sym, *csym;
int i, cnt;
int i, cnt, pby, pty, ptm; /* pby: probability of boolean = y
* pty: probability of tristate = y
* ptm: probability of tristate = m
*/
pby = 50; pty = ptm = 33; /* can't go as the default in switch-case
* below, otherwise gcc whines about
* -Wmaybe-uninitialized */
if (mode == def_random) {
int n, p[3];
char *env = getenv("KCONFIG_PROBABILITY");
n = 0;
while( env && *env ) {
char *endp;
int tmp = strtol( env, &endp, 10 );
if( tmp >= 0 && tmp <= 100 ) {
p[n++] = tmp;
} else {
errno = ERANGE;
perror( "KCONFIG_PROBABILITY" );
exit( 1 );
}
env = (*endp == ':') ? endp+1 : endp;
if( n >=3 ) {
break;
}
}
switch( n ) {
case 1:
pby = p[0]; ptm = pby/2; pty = pby-ptm;
break;
case 2:
pty = p[0]; ptm = p[1]; pby = pty + ptm;
break;
case 3:
pby = p[0]; pty = p[1]; ptm = p[2];
break;
}
if( pty+ptm > 100 ) {
errno = ERANGE;
perror( "KCONFIG_PROBABILITY" );
exit( 1 );
}
}
bool has_changed = false;
for_all_symbols(i, sym) {
if (sym_has_value(sym))
if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
continue;
switch (sym_get_type(sym)) {
case S_BOOLEAN:
case S_TRISTATE:
has_changed = true;
switch (mode) {
case def_yes:
sym->def[S_DEF_USER].tri = yes;
@ -1007,11 +1181,21 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
sym->def[S_DEF_USER].tri = mod;
break;
case def_no:
sym->def[S_DEF_USER].tri = no;
if (sym->flags & SYMBOL_ALLNOCONFIG_Y)
sym->def[S_DEF_USER].tri = yes;
else
sym->def[S_DEF_USER].tri = no;
break;
case def_random:
cnt = sym_get_type(sym) == S_TRISTATE ? 3 : 2;
sym->def[S_DEF_USER].tri = (tristate)(rand() % cnt);
sym->def[S_DEF_USER].tri = no;
cnt = rand() % 100;
if (sym->type == S_TRISTATE) {
if (cnt < pty)
sym->def[S_DEF_USER].tri = yes;
else if (cnt < (pty+ptm))
sym->def[S_DEF_USER].tri = mod;
} else if (cnt < pby)
sym->def[S_DEF_USER].tri = yes;
break;
default:
continue;
@ -1036,14 +1220,26 @@ void conf_set_all_new_symbols(enum conf_def_mode mode)
* selected in a choice block and we set it to yes,
* and the rest to no.
*/
if (mode != def_random) {
for_all_symbols(i, csym) {
if ((sym_is_choice(csym) && !sym_has_value(csym)) ||
sym_is_choice_value(csym))
csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES;
}
}
for_all_symbols(i, csym) {
if (sym_has_value(csym) || !sym_is_choice(csym))
continue;
sym_calc_value(csym);
if (mode == def_random)
randomize_choice_values(csym);
else
has_changed = randomize_choice_values(csym);
else {
set_all_choice_values(csym);
has_changed = true;
}
}
return has_changed;
}

View File

@ -7,15 +7,16 @@
#include <stdlib.h>
#include <string.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
#define DEBUG_EXPR 0
static int expr_eq(struct expr *e1, struct expr *e2);
static struct expr *expr_eliminate_yn(struct expr *e);
struct expr *expr_alloc_symbol(struct symbol *sym)
{
struct expr *e = malloc(sizeof(*e));
memset(e, 0, sizeof(*e));
struct expr *e = xcalloc(1, sizeof(*e));
e->type = E_SYMBOL;
e->left.sym = sym;
return e;
@ -23,8 +24,7 @@ struct expr *expr_alloc_symbol(struct symbol *sym)
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
{
struct expr *e = malloc(sizeof(*e));
memset(e, 0, sizeof(*e));
struct expr *e = xcalloc(1, sizeof(*e));
e->type = type;
e->left.expr = ce;
return e;
@ -32,8 +32,7 @@ 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 *e = malloc(sizeof(*e));
memset(e, 0, sizeof(*e));
struct expr *e = xcalloc(1, sizeof(*e));
e->type = type;
e->left.expr = e1;
e->right.expr = e2;
@ -42,8 +41,7 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *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));
struct expr *e = xcalloc(1, sizeof(*e));
e->type = type;
e->left.sym = s1;
e->right.sym = s2;
@ -71,7 +69,7 @@ struct expr *expr_copy(const struct expr *org)
if (!org)
return NULL;
e = malloc(sizeof(*org));
e = xmalloc(sizeof(*org));
memcpy(e, org, sizeof(*org));
switch (org->type) {
case E_SYMBOL:
@ -81,6 +79,10 @@ struct expr *expr_copy(const struct expr *org)
e->left.expr = expr_copy(org->left.expr);
break;
case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
e->left.sym = org->left.sym;
e->right.sym = org->right.sym;
@ -113,6 +115,10 @@ void expr_free(struct expr *e)
expr_free(e->left.expr);
return;
case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
break;
case E_OR:
@ -191,7 +197,7 @@ void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
#undef e1
#undef e2
int expr_eq(struct expr *e1, struct expr *e2)
static int expr_eq(struct expr *e1, struct expr *e2)
{
int res, old_count;
@ -199,6 +205,10 @@ int expr_eq(struct expr *e1, struct expr *e2)
return 0;
switch (e1->type) {
case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
case E_SYMBOL:
@ -233,7 +243,7 @@ int expr_eq(struct expr *e1, struct expr *e2)
return 0;
}
struct expr *expr_eliminate_yn(struct expr *e)
static struct expr *expr_eliminate_yn(struct expr *e)
{
struct expr *tmp;
@ -558,62 +568,6 @@ static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct
#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;
@ -626,7 +580,6 @@ struct expr *expr_eliminate_dups(struct expr *e)
switch (e->type) {
case E_OR: case E_AND:
expr_eliminate_dups1(e->type, &e, &e);
expr_eliminate_dups2(e->type, &e, &e);
default:
;
}
@ -646,6 +599,10 @@ struct expr *expr_transform(struct expr *e)
return NULL;
switch (e->type) {
case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
case E_SYMBOL:
case E_LIST:
@ -718,6 +675,22 @@ struct expr *expr_transform(struct expr *e)
e = tmp;
e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
break;
case E_LEQ:
case E_GEQ:
// !a<='x' -> a>'x'
tmp = e->left.expr;
free(e);
e = tmp;
e->type = e->type == E_LEQ ? E_GTH : E_LTH;
break;
case E_LTH:
case E_GTH:
// !a<'x' -> a>='x'
tmp = e->left.expr;
free(e);
e = tmp;
e->type = e->type == E_LTH ? E_GEQ : E_LEQ;
break;
case E_OR:
// !(a || b) -> !a && !b
tmp = e->left.expr;
@ -788,6 +761,10 @@ int expr_contains_symbol(struct expr *dep, struct symbol *sym)
case E_SYMBOL:
return dep->left.sym == sym;
case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
return dep->left.sym == sym ||
dep->right.sym == sym;
@ -828,57 +805,6 @@ bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
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;
@ -913,6 +839,10 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
case E_NOT:
return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
case E_UNEQUAL:
case E_LTH:
case E_LEQ:
case E_GTH:
case E_GEQ:
case E_EQUAL:
if (type == E_EQUAL) {
if (sym == &symbol_yes)
@ -940,10 +870,57 @@ struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symb
return NULL;
}
enum string_value_kind {
k_string,
k_signed,
k_unsigned,
k_invalid
};
union string_value {
unsigned long long u;
signed long long s;
};
static enum string_value_kind expr_parse_string(const char *str,
enum symbol_type type,
union string_value *val)
{
char *tail;
enum string_value_kind kind;
errno = 0;
switch (type) {
case S_BOOLEAN:
case S_TRISTATE:
return k_string;
case S_INT:
val->s = strtoll(str, &tail, 10);
kind = k_signed;
break;
case S_HEX:
val->u = strtoull(str, &tail, 16);
kind = k_unsigned;
break;
case S_STRING:
case S_UNKNOWN:
val->s = strtoll(str, &tail, 0);
kind = k_signed;
break;
default:
return k_invalid;
}
return !errno && !*tail && tail > str && isxdigit(tail[-1])
? kind : k_string;
}
tristate expr_calc_value(struct expr *e)
{
tristate val1, val2;
const char *str1, *str2;
enum string_value_kind k1 = k_string, k2 = k_string;
union string_value lval = {}, rval = {};
int res;
if (!e)
return yes;
@ -964,31 +941,70 @@ tristate expr_calc_value(struct expr *e)
val1 = expr_calc_value(e->left.expr);
return EXPR_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_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
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;
break;
default:
printf("expr_calc_value: %d?\n", e->type);
return no;
}
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);
if (e->left.sym->type != S_STRING || e->right.sym->type != S_STRING) {
k1 = expr_parse_string(str1, e->left.sym->type, &lval);
k2 = expr_parse_string(str2, e->right.sym->type, &rval);
}
if (k1 == k_string || k2 == k_string)
res = strcmp(str1, str2);
else if (k1 == k_invalid || k2 == k_invalid) {
if (e->type != E_EQUAL && e->type != E_UNEQUAL) {
printf("Cannot compare \"%s\" and \"%s\"\n", str1, str2);
return no;
}
res = strcmp(str1, str2);
} else if (k1 == k_unsigned || k2 == k_unsigned)
res = (lval.u > rval.u) - (lval.u < rval.u);
else /* if (k1 == k_signed && k2 == k_signed) */
res = (lval.s > rval.s) - (lval.s < rval.s);
switch(e->type) {
case E_EQUAL:
return res ? no : yes;
case E_GEQ:
return res >= 0 ? yes : no;
case E_GTH:
return res > 0 ? yes : no;
case E_LEQ:
return res <= 0 ? yes : no;
case E_LTH:
return res < 0 ? yes : no;
case E_UNEQUAL:
return res ? yes : no;
default:
printf("expr_calc_value: relation %d?\n", e->type);
return no;
}
}
int expr_compare_type(enum expr_type t1, enum expr_type t2)
static 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_LEQ:
case E_LTH:
case E_GEQ:
case E_GTH:
if (t2 == E_EQUAL || t2 == E_UNEQUAL)
return 1;
case E_EQUAL:
case E_UNEQUAL:
if (t2 == E_NOT)
@ -1010,7 +1026,6 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
}
printf("[%dgt%d?]", t1, t2);
return 0;
#endif
}
static inline struct expr *
@ -1083,6 +1098,24 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
fn(data, NULL, "=");
fn(data, e->right.sym, e->right.sym->name);
break;
case E_LEQ:
case E_LTH:
if (e->left.sym->name)
fn(data, e->left.sym, e->left.sym->name);
else
fn(data, NULL, "<choice>");
fn(data, NULL, e->type == E_LEQ ? "<=" : "<");
fn(data, e->right.sym, e->right.sym->name);
break;
case E_GEQ:
case E_GTH:
if (e->left.sym->name)
fn(data, e->left.sym, e->left.sym->name);
else
fn(data, NULL, "<choice>");
fn(data, NULL, e->type == E_GEQ ? ">=" : ">");
fn(data, e->right.sym, e->right.sym->name);
break;
case E_UNEQUAL:
if (e->left.sym->name)
fn(data, e->left.sym, e->left.sym->name);

View File

@ -10,7 +10,9 @@
extern "C" {
#endif
#include <assert.h>
#include <stdio.h>
#include "list.h"
#ifndef __cplusplus
#include <stdbool.h>
#endif
@ -27,7 +29,9 @@ typedef enum tristate {
} tristate;
enum expr_type {
E_NONE, E_OR, E_AND, E_NOT, E_EQUAL, E_UNEQUAL, E_LIST, E_SYMBOL, E_RANGE
E_NONE, E_OR, E_AND, E_NOT,
E_EQUAL, E_UNEQUAL, E_LTH, E_LEQ, E_GTH, E_GEQ,
E_LIST, E_SYMBOL, E_RANGE
};
union expr_data {
@ -91,7 +95,7 @@ struct symbol {
#define SYMBOL_CHOICEVAL 0x0020 /* used as a value in a choice block */
#define SYMBOL_VALID 0x0080 /* set when symbol.curr is calculated */
#define SYMBOL_OPTIONAL 0x0100 /* choice is optional - values can be 'n' */
#define SYMBOL_WRITE 0x0200 /* ? */
#define SYMBOL_WRITE 0x0200 /* write symbol to file (KCONFIG_CONFIG) */
#define SYMBOL_CHANGED 0x0400 /* ? */
#define SYMBOL_AUTO 0x1000 /* value from environment variable */
#define SYMBOL_CHECKED 0x2000 /* used during dependency checking */
@ -104,6 +108,12 @@ struct symbol {
#define SYMBOL_DEF3 0x40000 /* symbol.def[S_DEF_3] is valid */
#define SYMBOL_DEF4 0x80000 /* symbol.def[S_DEF_4] is valid */
/* choice values need to be set before calculating this symbol value */
#define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000
/* Set symbol to y if allnoconfig; used for symbols that hide others */
#define SYMBOL_ALLNOCONFIG_Y 0x200000
#define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 9973
@ -172,7 +182,14 @@ struct menu {
#define MENU_CHANGED 0x0001
#define MENU_ROOT 0x0002
#ifndef SWIG
struct jump_key {
struct list_head entries;
size_t offset;
struct menu *target;
int index;
};
#define JUMP_NB 9
extern struct file *file_list;
extern struct file *current_file;
@ -190,18 +207,13 @@ 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(const 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);
struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2);
@ -218,7 +230,6 @@ static inline int expr_is_no(struct expr *e)
{
return e && (e->type == E_SYMBOL && e->left.sym == &symbol_no);
}
#endif
#ifdef __cplusplus
}

View File

@ -10,29 +10,34 @@ PHONY += $(configurators)
$(configurators): config_files
export CT_IS_A_BACKEND:=$(CT_IS_A_BACKEND)
export CT_BACKEND_ARCH:=$(CT_BACKEND_ARCH)
export CT_BACKEND_KERNEL:=$(CT_BACKEND_KERNEL)
export CT_BACKEND_LIBC:=$(CT_BACKEND_LIBC)
# We need CONF for savedefconfig in scripts/saveSample.sh
export CONF := $(CT_LIB_DIR)/kconfig/conf
MCONF := $(CT_LIB_DIR)/kconfig/mconf
NCONF := $(CT_LIB_DIR)/kconfig/nconf
menuconfig:
@$(ECHO) " CONF $(KCONFIG_TOP)"
@$(CT_ECHO) " CONF $(KCONFIG_TOP)"
$(SILENT)$(MCONF) $(KCONFIG_TOP)
nconfig:
@$(ECHO) " CONF $(KCONFIG_TOP)"
@$(CT_ECHO) " CONF $(KCONFIG_TOP)"
$(SILENT)$(NCONF) $(KCONFIG_TOP)
oldconfig: .config
@$(ECHO) " CONF $(KCONFIG_TOP)"
@$(CT_ECHO) " CONF $(KCONFIG_TOP)"
$(SILENT)$(CONF) --silent$@ $(KCONFIG_TOP)
savedefconfig: .config
@$(ECHO) ' GEN $@'
@$(CT_ECHO) ' GEN $@'
$(SILENT)$(CONF) --savedefconfig=$${DEFCONFIG-defconfig} $(KCONFIG_TOP)
defconfig:
@$(ECHO) ' CONF $@'
@$(CT_ECHO) ' CONF $@'
$(SILENT)$(CONF) --defconfig=$${DEFCONFIG-defconfig} $(KCONFIG_TOP)
# Always be silent, the stdout an be >.config
@ -55,6 +60,7 @@ extractconfig:
help-config::
@echo ' menuconfig - Update current config using a menu based program'
@echo ' nconfig - Update current config using a menu based program'
@echo ' oldconfig - Update current config using a provided .config as base'
@echo ' extractconfig - Extract to stdout the configuration items from a'
@echo ' build.log file piped to stdin'

131
crosstool-ng/kconfig/list.h Normal file
View File

@ -0,0 +1,131 @@
#ifndef LIST_H
#define LIST_H
/*
* Copied from include/linux/...
*/
#undef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *_new,
struct list_head *prev,
struct list_head *next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
#define LIST_POISON1 ((void *) 0x00100100)
#define LIST_POISON2 ((void *) 0x00200200)
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = (struct list_head*)LIST_POISON1;
entry->prev = (struct list_head*)LIST_POISON2;
}
#endif

View File

@ -21,14 +21,7 @@ static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c;
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"
@ -44,6 +37,12 @@ extern "C" {
#ifndef CONFIG_
#define CONFIG_ "CONFIG_"
#endif
static inline const char *CONFIG_prefix(void)
{
return getenv( "CONFIG_" ) ?: CONFIG_;
}
#undef CONFIG_
#define CONFIG_ CONFIG_prefix()
#define TF_COMMAND 0x0001
#define TF_PARAM 0x0002
@ -60,6 +59,7 @@ enum conf_def_mode {
#define T_OPT_MODULES 1
#define T_OPT_DEFCONFIG_LIST 2
#define T_OPT_ENV 3
#define T_OPT_ALLNOCONFIG_Y 4
struct kconf_id {
int name;
@ -68,11 +68,6 @@ struct kconf_id {
enum symbol_type stype;
};
#ifdef YYDEBUG
extern int zconfdebug;
#endif
int zconfparse(void);
void zconfdump(FILE *out);
void zconf_starthelp(void);
FILE *zconf_fopen(const char *name);
@ -81,26 +76,23 @@ void zconf_nextfile(const char *name);
int zconf_lineno(void);
const char *zconf_curname(void);
/* conf.c */
void xfgets(char *str, int size, FILE *in);
/* confdata.c */
const char *conf_get_configname(void);
const char *conf_get_autoconfig_name(void);
char *conf_get_default_confname(void);
void sym_set_change_count(int count);
void sym_add_change_count(int count);
void conf_set_all_new_symbols(enum conf_def_mode mode);
bool conf_set_all_new_symbols(enum conf_def_mode mode);
void set_all_choice_values(struct symbol *csym);
/* confdata.c and expr.c */
static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
{
if (fwrite(str, len, count, out) < count)
fprintf(stderr, "\nError in writing or end of file.\n");
}
assert(len != 0);
/* kconfig_load.c */
void kconfig_load(void);
if (fwrite(str, len, count, out) != count)
fprintf(stderr, "Error in writing or end of file.\n");
}
/* menu.c */
void _menu_init(void);
@ -111,7 +103,6 @@ void menu_add_entry(struct symbol *sym);
void menu_end_entry(void);
void menu_add_dep(struct expr *dep);
void menu_add_visibility(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);
@ -122,6 +113,8 @@ void menu_set_type(int type);
/* util.c */
struct file *file_lookup(const char *name);
int file_write_dep(const char *name);
void *xmalloc(size_t size);
void *xcalloc(size_t nmemb, size_t size);
struct gstr {
size_t len;
@ -133,7 +126,6 @@ struct gstr {
int max_width;
};
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, ...);
@ -144,8 +136,6 @@ extern struct expr *sym_env_list;
void sym_init(void);
void sym_clear_all_valid(void);
void sym_set_all_changed(void);
void sym_set_changed(struct symbol *sym);
struct symbol *sym_choice_default(struct symbol *sym);
const char *sym_get_string_default(struct symbol *sym);
struct symbol *sym_check_deps(struct symbol *sym);

View File

@ -1,53 +1,52 @@
#include <stdarg.h>
/* confdata.c */
P(conf_parse,void,(const char *name));
P(conf_read,int,(const char *name));
P(conf_read_simple,int,(const char *name, int));
P(conf_write_defconfig,int,(const char *name));
P(conf_write,int,(const char *name));
P(conf_write_autoconf,int,(void));
P(conf_get_changed,bool,(void));
P(conf_set_changed_callback, void,(void (*fn)(void)));
P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap)));
void conf_parse(const char *name);
int conf_read(const char *name);
int conf_read_simple(const char *name, int);
int conf_write_defconfig(const char *name);
int conf_write(const char *name);
int conf_write_autoconf(void);
bool conf_get_changed(void);
void conf_set_changed_callback(void (*fn)(void));
void conf_set_message_callback(void (*fn)(const char *fmt, va_list ap));
/* menu.c */
P(rootmenu,struct menu,);
extern struct menu rootmenu;
P(menu_is_visible, bool, (struct menu *menu));
P(menu_has_prompt, bool, (struct menu *menu));
P(menu_get_prompt,const char *,(struct menu *menu));
P(menu_get_root_menu,struct menu *,(struct menu *menu));
P(menu_get_parent_menu,struct menu *,(struct menu *menu));
P(menu_has_help,bool,(struct menu *menu));
P(menu_get_help,const char *,(struct menu *menu));
P(get_symbol_str, void, (struct gstr *r, struct symbol *sym));
P(get_relations_str, struct gstr, (struct symbol **sym_arr));
P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
bool menu_is_empty(struct menu *menu);
bool menu_is_visible(struct menu *menu);
bool menu_has_prompt(struct menu *menu);
const char * menu_get_prompt(struct menu *menu);
struct menu * menu_get_root_menu(struct menu *menu);
struct menu * menu_get_parent_menu(struct menu *menu);
bool menu_has_help(struct menu *menu);
const char * menu_get_help(struct menu *menu);
struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
void menu_get_ext_help(struct menu *menu, struct gstr *help);
/* symbol.c */
P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
P(sym_lookup,struct symbol *,(const char *name, int flags));
P(sym_find,struct symbol *,(const char *name));
P(sym_expand_string_value,const char *,(const char *in));
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));
struct symbol * sym_lookup(const char *name, int flags);
struct symbol * sym_find(const char *name);
const char * sym_expand_string_value(const char *in);
const char * sym_escape_string_value(const char *in);
struct symbol ** sym_re_search(const char *pattern);
const char * sym_type_name(enum symbol_type type);
void sym_calc_value(struct symbol *sym);
enum symbol_type sym_get_type(struct symbol *sym);
bool sym_tristate_within_range(struct symbol *sym,tristate tri);
bool sym_set_tristate_value(struct symbol *sym,tristate tri);
tristate sym_toggle_tristate_value(struct symbol *sym);
bool sym_string_valid(struct symbol *sym, const char *newval);
bool sym_string_within_range(struct symbol *sym, const char *str);
bool sym_set_string_value(struct symbol *sym, const char *newval);
bool sym_is_changable(struct symbol *sym);
struct property * sym_get_choice_prop(struct symbol *sym);
const char * sym_get_string_value(struct symbol *sym);
P(prop_get_type_name,const char *,(enum prop_type type));
const char * prop_get_type_name(enum prop_type type);
/* expr.c */
P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2));
P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken));
void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);

View File

@ -4,7 +4,9 @@
# What library to link
ldflags()
{
for ext in so a dylib ; do
pkg-config --libs ncursesw 2>/dev/null && exit
pkg-config --libs ncurses 2>/dev/null && exit
for ext in so a dll.a dylib ; do
for lib in ncursesw ncurses curses ; do
$cc -print-file-name=lib${lib}.${ext} | grep -q /
if [ $? -eq 0 ]; then
@ -19,12 +21,17 @@ ldflags()
# Where is ncurses.h?
ccflags()
{
if [ -f /usr/include/ncurses/ncurses.h ]; then
if pkg-config --cflags ncursesw 2>/dev/null; then
echo '-DCURSES_LOC="<ncurses.h>" -DNCURSES_WIDECHAR=1'
elif pkg-config --cflags ncurses 2>/dev/null; then
echo '-DCURSES_LOC="<ncurses.h>"'
elif [ -f /usr/include/ncursesw/curses.h ]; then
echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"'
echo ' -DNCURSES_WIDECHAR=1'
elif [ -f /usr/include/ncurses/ncurses.h ]; then
echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"'
elif [ -f /usr/include/ncurses/curses.h ]; then
echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"'
elif [ -f /usr/include/ncursesw/curses.h ]; then
echo '-I/usr/include/ncursesw -DCURSES_LOC="<ncursesw/curses.h>"'
echo '-I/usr/include/ncurses -DCURSES_LOC="<curses.h>"'
elif [ -f /usr/include/ncurses.h ]; then
echo '-DCURSES_LOC="<ncurses.h>"'
else
@ -38,7 +45,7 @@ trap "rm -f $tmp" 0 1 2 3 15
# Check if we can link to ncurses
check() {
$cc -xc - -o $tmp 2>/dev/null <<'EOF'
$cc -x c - -o $tmp 2>/dev/null <<'EOF'
#include CURSES_LOC
main() {}
EOF

View File

@ -132,16 +132,16 @@ int dialog_checklist(const char *title, const char *prompt, int height,
}
do_resize:
if (getmaxy(stdscr) < (height + 6))
if (getmaxy(stdscr) < (height + CHECKLIST_HEIGTH_MIN))
return -ERRDISPLAYTOOSMALL;
if (getmaxx(stdscr) < (width + 6))
if (getmaxx(stdscr) < (width + CHECKLIST_WIDTH_MIN))
return -ERRDISPLAYTOOSMALL;
max_choice = MIN(list_height, item_count());
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
x = (getmaxx(stdscr) - width) / 2;
y = (getmaxy(stdscr) - height) / 2;
draw_shadow(stdscr, y, x, height, width);
@ -168,13 +168,13 @@ do_resize:
/* create new window for the list */
list = subwin(dialog, list_height, list_width, y + box_y + 1,
x + box_x + 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,
dlg.menubox_border.atr, dlg.menubox.atr);
dlg.menubox_border.atr, dlg.menubox.atr);
/* Find length of longest item in order to center checklist */
check_x = 0;

View File

@ -106,8 +106,14 @@ struct dialog_color {
int hl; /* highlight this item */
};
struct subtitle_list {
struct subtitle_list *next;
const char *text;
};
struct dialog_info {
const char *backtitle;
struct subtitle_list *subtitles;
struct dialog_color screen;
struct dialog_color shadow;
struct dialog_color dialog;
@ -144,6 +150,7 @@ struct dialog_info {
*/
extern struct dialog_info dlg;
extern char dialog_input_result[];
extern int saved_x, saved_y; /* Needed in signal handler in mconf.c */
/*
* Function prototypes
@ -163,7 +170,7 @@ char item_tag(void);
/* item list manipulation for lxdialog use */
#define MAXITEMSTR 200
struct dialog_item {
char str[MAXITEMSTR]; /* promtp displayed */
char str[MAXITEMSTR]; /* prompt displayed */
char tag;
void *data; /* pointer to menu item - used by menubox+checklist */
int selected; /* Set to 1 by dialog_*() function if selected. */
@ -193,8 +200,23 @@ int item_is_tag(char tag);
int on_key_esc(WINDOW *win);
int on_key_resize(void);
/* minimum (re)size values */
#define CHECKLIST_HEIGTH_MIN 6 /* For dialog_checklist() */
#define CHECKLIST_WIDTH_MIN 6
#define INPUTBOX_HEIGTH_MIN 2 /* For dialog_inputbox() */
#define INPUTBOX_WIDTH_MIN 2
#define MENUBOX_HEIGTH_MIN 15 /* For dialog_menu() */
#define MENUBOX_WIDTH_MIN 65
#define TEXTBOX_HEIGTH_MIN 8 /* For dialog_textbox() */
#define TEXTBOX_WIDTH_MIN 8
#define YESNO_HEIGTH_MIN 4 /* For dialog_yesno() */
#define YESNO_WIDTH_MIN 4
#define WINDOW_HEIGTH_MIN 19 /* For init_dialog() */
#define WINDOW_WIDTH_MIN 80
int init_dialog(const char *backtitle);
void set_dialog_backtitle(const char *backtitle);
void set_dialog_subtitles(struct subtitle_list *subtitles);
void end_dialog(int x, int y);
void attr_clear(WINDOW * win, int height, int width, chtype attr);
void dialog_clear(void);
@ -209,12 +231,17 @@ 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);
typedef void (*update_text_fn)(char *buf, size_t start, size_t end, void
*_data);
int dialog_textbox(const char *title, char *tbuf, int initial_height,
int initial_width, int *keys, int *_vscroll, int *_hscroll,
update_text_fn update_text, void *data);
int dialog_menu(const char *title, const char *prompt,
const void *selected, int *s_scroll);
int dialog_checklist(const char *title, const char *prompt, int height,
int width, int list_height);
extern char dialog_input_result[];
int dialog_inputbox(const char *title, const char *prompt, int height,
int width, const char *init);

View File

@ -42,10 +42,11 @@ static void print_buttons(WINDOW * dialog, int height, int width, int selected)
* Display a dialog box for inputing a string
*/
int dialog_inputbox(const char *title, const char *prompt, int height, int width,
const char *init)
const char *init)
{
int i, x, y, box_y, box_x, box_width;
int input_x = 0, scroll = 0, key = 0, button = -1;
int input_x = 0, key = 0, button = -1;
int show_x, len, pos;
char *instr = dialog_input_result;
WINDOW *dialog;
@ -55,14 +56,14 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width
strcpy(instr, init);
do_resize:
if (getmaxy(stdscr) <= (height - 2))
if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN))
return -ERRDISPLAYTOOSMALL;
if (getmaxx(stdscr) <= (width - 2))
if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN))
return -ERRDISPLAYTOOSMALL;
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
x = (getmaxx(stdscr) - width) / 2;
y = (getmaxy(stdscr) - height) / 2;
draw_shadow(stdscr, y, x, height, width);
@ -97,14 +98,17 @@ do_resize:
wmove(dialog, box_y, box_x);
wattrset(dialog, dlg.inputbox.atr);
input_x = strlen(instr);
len = strlen(instr);
pos = len;
if (input_x >= box_width) {
scroll = input_x - box_width + 1;
if (len >= box_width) {
show_x = len - box_width + 1;
input_x = box_width - 1;
for (i = 0; i < box_width - 1; i++)
waddch(dialog, instr[scroll + i]);
waddch(dialog, instr[show_x + i]);
} else {
show_x = 0;
input_x = len;
waddstr(dialog, instr);
}
@ -121,45 +125,104 @@ do_resize:
case KEY_UP:
case KEY_DOWN:
break;
case KEY_LEFT:
continue;
case KEY_RIGHT:
continue;
case KEY_BACKSPACE:
case 127:
if (input_x || scroll) {
if (pos) {
wattrset(dialog, dlg.inputbox.atr);
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;
if (input_x == 0) {
show_x--;
} else
input_x--;
instr[scroll + input_x] = '\0';
mvwaddch(dialog, box_y, input_x + box_x, ' ');
if (pos < len) {
for (i = pos - 1; i < len; i++) {
instr[i] = instr[i+1];
}
}
pos--;
len--;
instr[len] = '\0';
wmove(dialog, box_y, box_x);
for (i = 0; i < box_width; i++) {
if (!instr[show_x + i]) {
waddch(dialog, ' ');
break;
}
waddch(dialog, instr[show_x + i]);
}
wmove(dialog, box_y, input_x + box_x);
wrefresh(dialog);
}
continue;
case KEY_LEFT:
if (pos > 0) {
if (input_x > 0) {
wmove(dialog, box_y, --input_x + box_x);
} else if (input_x == 0) {
show_x--;
wmove(dialog, box_y, box_x);
for (i = 0; i < box_width; i++) {
if (!instr[show_x + i]) {
waddch(dialog, ' ');
break;
}
waddch(dialog, instr[show_x + i]);
}
wmove(dialog, box_y, box_x);
}
pos--;
}
continue;
case KEY_RIGHT:
if (pos < len) {
if (input_x < box_width - 1) {
wmove(dialog, box_y, ++input_x + box_x);
} else if (input_x == box_width - 1) {
show_x++;
wmove(dialog, box_y, box_x);
for (i = 0; i < box_width; i++) {
if (!instr[show_x + i]) {
waddch(dialog, ' ');
break;
}
waddch(dialog, instr[show_x + i]);
}
wmove(dialog, box_y, input_x + box_x);
}
pos++;
}
continue;
default:
if (key < 0x100 && isprint(key)) {
if (scroll + input_x < MAX_LEN) {
if (len < MAX_LEN) {
wattrset(dialog, dlg.inputbox.atr);
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]);
if (pos < len) {
for (i = len; i > pos; i--)
instr[i] = instr[i-1];
instr[pos] = key;
} else {
wmove(dialog, box_y, input_x++ + box_x);
waddch(dialog, key);
instr[len] = key;
}
pos++;
len++;
instr[len] = '\0';
if (input_x == box_width - 1) {
show_x++;
} else {
input_x++;
}
wmove(dialog, box_y, box_x);
for (i = 0; i < box_width; i++) {
if (!instr[show_x + i]) {
waddch(dialog, ' ');
break;
}
waddch(dialog, instr[show_x + i]);
}
wmove(dialog, box_y, input_x + box_x);
wrefresh(dialog);
} else
flash(); /* Alarm user about overflow */

View File

@ -26,7 +26,7 @@
*
* *) A bugfix for the Page-Down problem
*
* *) Formerly when I used Page Down and Page Up, the cursor would be set
* *) Formerly when I used Page Down and Page Up, the cursor would be set
* to the first position in the menu box. Now lxdialog is a bit
* smarter and works more like other menu systems (just have a look at
* it).
@ -64,7 +64,7 @@ static int menu_width, item_x;
* Print menu item
*/
static void do_print_item(WINDOW * win, const char *item, int line_y,
int selected, int hotkey)
int selected, int hotkey)
{
int j;
char *menu_item = malloc(menu_width + 1);
@ -154,12 +154,14 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
*/
static void print_buttons(WINDOW * win, int height, int width, int selected)
{
int x = width / 2 - 16;
int x = width / 2 - 28;
int y = height - 2;
print_button(win, gettext("Select"), y, x, selected == 0);
print_button(win, gettext(" Exit "), y, x + 12, selected == 1);
print_button(win, gettext(" Help "), y, x + 24, selected == 2);
print_button(win, gettext(" Save "), y, x + 36, selected == 3);
print_button(win, gettext(" Load "), y, x + 48, selected == 4);
wmove(win, y, x + 1 + 12 * selected);
wrefresh(win);
@ -180,7 +182,7 @@ static void do_scroll(WINDOW *win, int *scroll, int n)
* Display a menu for choosing among a number of options
*/
int dialog_menu(const char *title, const char *prompt,
const void *selected, int *s_scroll)
const void *selected, int *s_scroll)
{
int i, j, x, y, box_x, box_y;
int height, width, menu_height;
@ -191,7 +193,7 @@ int dialog_menu(const char *title, const char *prompt,
do_resize:
height = getmaxy(stdscr);
width = getmaxx(stdscr);
if (height < 15 || width < 65)
if (height < MENUBOX_HEIGTH_MIN || width < MENUBOX_WIDTH_MIN)
return -ERRDISPLAYTOOSMALL;
height -= 4;
@ -201,8 +203,8 @@ do_resize:
max_choice = MIN(menu_height, item_count());
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
x = (getmaxx(stdscr) - width) / 2;
y = (getmaxy(stdscr) - height) / 2;
draw_shadow(stdscr, y, x, height, width);
@ -301,10 +303,11 @@ do_resize:
}
}
if (i < max_choice ||
key == KEY_UP || key == KEY_DOWN ||
key == '-' || key == '+' ||
key == KEY_PPAGE || key == KEY_NPAGE) {
if (item_count() != 0 &&
(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);
@ -372,7 +375,7 @@ do_resize:
case TAB:
case KEY_RIGHT:
button = ((key == KEY_LEFT ? --button : ++button) < 0)
? 2 : (button > 2 ? 0 : button);
? 4 : (button > 4 ? 0 : button);
print_buttons(dialog, height, width, button);
wrefresh(menu);
@ -399,17 +402,17 @@ do_resize:
return 2;
case 's':
case 'y':
return 3;
case 'n':
return 4;
case 'm':
return 5;
case ' ':
case 'n':
return 6;
case '/':
case 'm':
return 7;
case 'z':
case ' ':
return 8;
case '/':
return 9;
case 'z':
return 10;
case '\n':
return button;
}

View File

@ -22,23 +22,25 @@
#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 void print_page(WINDOW *win, int height, int width, update_text_fn
update_text, void *data);
static void print_line(WINDOW *win, int row, int width);
static char *get_line(void);
static void print_position(WINDOW * win);
static int hscroll;
static int begin_reached, end_reached, page_length;
static const char *buf;
static const char *page;
static char *buf;
static char *page;
/*
* refresh window content
*/
static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
int cur_y, int cur_x)
int cur_y, int cur_x, update_text_fn update_text,
void *data)
{
print_page(box, boxh, boxw);
print_page(box, boxh, boxw, update_text, data);
print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
@ -47,14 +49,18 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
/*
* Display text from a file in a dialog box.
*
* keys is a null-terminated array
* update_text() may not add or remove any '\n' or '\0' in tbuf
*/
int dialog_textbox(const char *title, const char *tbuf,
int initial_height, int initial_width)
int dialog_textbox(const char *title, char *tbuf, int initial_height,
int initial_width, int *keys, int *_vscroll, int *_hscroll,
update_text_fn update_text, void *data)
{
int i, x, y, cur_x, cur_y, key = 0;
int height, width, boxh, boxw;
int passed_end;
WINDOW *dialog, *box;
bool done = false;
begin_reached = 1;
end_reached = 0;
@ -63,9 +69,18 @@ int dialog_textbox(const char *title, const char *tbuf,
buf = tbuf;
page = buf; /* page is pointer to start of page to be displayed */
if (_vscroll && *_vscroll) {
begin_reached = 0;
for (i = 0; i < *_vscroll; i++)
get_line();
}
if (_hscroll)
hscroll = *_hscroll;
do_resize:
getmaxyx(stdscr, height, width);
if (height < 8 || width < 8)
if (height < TEXTBOX_HEIGTH_MIN || width < TEXTBOX_WIDTH_MIN)
return -ERRDISPLAYTOOSMALL;
if (initial_height != 0)
height = initial_height;
@ -83,8 +98,8 @@ do_resize:
width = 0;
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
x = (getmaxx(stdscr) - width) / 2;
y = (getmaxy(stdscr) - height) / 2;
draw_shadow(stdscr, y, x, height, width);
@ -120,25 +135,28 @@ do_resize:
/* Print first page of text */
attr_clear(box, boxh, boxw, dlg.dialog.atr);
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text,
data);
while ((key != KEY_ESC) && (key != '\n')) {
while (!done) {
key = wgetch(dialog);
switch (key) {
case 'E': /* Exit */
case 'e':
case 'X':
case 'x':
delwin(box);
delwin(dialog);
return 0;
case 'q':
case '\n':
done = true;
break;
case 'g': /* First page */
case KEY_HOME:
if (!begin_reached) {
begin_reached = 1;
page = buf;
refresh_text_box(dialog, box, boxh, boxw,
cur_y, cur_x);
cur_y, cur_x, update_text,
data);
}
break;
case 'G': /* Last page */
@ -148,78 +166,48 @@ do_resize:
/* point to last char in buf */
page = buf + strlen(buf);
back_lines(boxh);
refresh_text_box(dialog, box, boxh, boxw,
cur_y, cur_x);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
break;
case 'K': /* Previous line */
case 'k':
case KEY_UP:
if (!begin_reached) {
back_lines(page_length + 1);
if (begin_reached)
break;
/* 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(box, TRUE);
wscrl(box, -1); /* Scroll box region down one line */
scrollok(box, FALSE);
page_length = 0;
passed_end = 0;
for (i = 0; i < boxh; i++) {
if (!i) {
/* print first line of page */
print_line(box, 0, boxw);
wnoutrefresh(box);
} 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);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
}
back_lines(page_length + 1);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
break;
case 'B': /* Previous page */
case 'b':
case 'u':
case KEY_PPAGE:
if (begin_reached)
break;
back_lines(page_length + boxh);
refresh_text_box(dialog, box, boxh, boxw,
cur_y, cur_x);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
break;
case 'J': /* Next line */
case 'j':
case KEY_DOWN:
if (!end_reached) {
begin_reached = 0;
scrollok(box, TRUE);
scroll(box); /* Scroll box region up one line */
scrollok(box, FALSE);
print_line(box, boxh - 1, boxw);
wnoutrefresh(box);
print_position(dialog);
wmove(dialog, cur_y, cur_x); /* Restore cursor position */
wrefresh(dialog);
}
if (end_reached)
break;
back_lines(page_length - 1);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
break;
case KEY_NPAGE: /* Next page */
case ' ':
case 'd':
if (end_reached)
break;
begin_reached = 0;
refresh_text_box(dialog, box, boxh, boxw,
cur_y, cur_x);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
break;
case '0': /* Beginning of line */
case 'H': /* Scroll left */
@ -234,8 +222,8 @@ do_resize:
hscroll--;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
refresh_text_box(dialog, box, boxh, boxw,
cur_y, cur_x);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
break;
case 'L': /* Scroll right */
case 'l':
@ -245,11 +233,12 @@ do_resize:
hscroll++;
/* Reprint current page to scroll horizontally */
back_lines(page_length);
refresh_text_box(dialog, box, boxh, boxw,
cur_y, cur_x);
refresh_text_box(dialog, box, boxh, boxw, cur_y,
cur_x, update_text, data);
break;
case KEY_ESC:
key = on_key_esc(dialog);
if (on_key_esc(dialog) == KEY_ESC)
done = true;
break;
case KEY_RESIZE:
back_lines(height);
@ -257,11 +246,31 @@ do_resize:
delwin(dialog);
on_key_resize();
goto do_resize;
default:
for (i = 0; keys[i]; i++) {
if (key == keys[i]) {
done = true;
break;
}
}
}
}
delwin(box);
delwin(dialog);
return key; /* ESC pressed */
if (_vscroll) {
const char *s;
s = buf;
*_vscroll = 0;
back_lines(page_length);
while (s < page && (s = strchr(s, '\n'))) {
(*_vscroll)++;
s++;
}
}
if (_hscroll)
*_hscroll = hscroll;
return key;
}
/*
@ -298,12 +307,23 @@ static void back_lines(int n)
}
/*
* Print a new page of text. Called by dialog_textbox().
* Print a new page of text.
*/
static void print_page(WINDOW * win, int height, int width)
static void print_page(WINDOW *win, int height, int width, update_text_fn
update_text, void *data)
{
int i, passed_end = 0;
if (update_text) {
char *end;
for (i = 0; i < height; i++)
get_line();
end = page;
back_lines(height);
update_text(buf, page - buf, end - buf, data);
}
page_length = 0;
for (i = 0; i < height; i++) {
print_line(win, i, width);
@ -316,11 +336,10 @@ static void print_page(WINDOW * win, int height, int width)
}
/*
* Print a new line of text. Called by dialog_textbox() and print_page().
* Print a new line of text.
*/
static void print_line(WINDOW * win, int row, int width)
{
int y, x;
char *line;
line = get_line();
@ -329,10 +348,10 @@ static void print_line(WINDOW * win, int row, int width)
waddch(win, ' ');
waddnstr(win, line, MIN(strlen(line), width - 2));
getyx(win, y, x);
/* Clear 'residue' of previous line */
#if OLD_NCURSES
{
int x = getcurx(win);
int i;
for (i = 0; i < width - x; i++)
waddch(win, ' ');
@ -355,10 +374,8 @@ static char *get_line(void)
end_reached = 0;
while (*page != '\n') {
if (*page == '\0') {
if (!end_reached) {
end_reached = 1;
break;
}
end_reached = 1;
break;
} else if (i < MAX_LEN)
line[i++] = *(page++);
else {
@ -371,7 +388,7 @@ static char *get_line(void)
if (i <= MAX_LEN)
line[i] = '\0';
if (!end_reached)
page++; /* move pass '\n' */
page++; /* move past '\n' */
return line;
}

View File

@ -23,6 +23,9 @@
#include "dialog.h"
/* Needed in signal handler in mconf.c */
int saved_x, saved_y;
struct dialog_info dlg;
static void set_mono_theme(void)
@ -251,15 +254,56 @@ void attr_clear(WINDOW * win, int height, int width, chtype attr)
void dialog_clear(void)
{
attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
int lines, columns;
lines = getmaxy(stdscr);
columns = getmaxx(stdscr);
attr_clear(stdscr, lines, columns, dlg.screen.atr);
/* Display background title if it exists ... - SLH */
if (dlg.backtitle != NULL) {
int i;
int i, len = 0, skip = 0;
struct subtitle_list *pos;
wattrset(stdscr, dlg.screen.atr);
mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);
for (pos = dlg.subtitles; pos != NULL; pos = pos->next) {
/* 3 is for the arrow and spaces */
len += strlen(pos->text) + 3;
}
wmove(stdscr, 1, 1);
for (i = 1; i < COLS - 1; i++)
if (len > columns - 2) {
const char *ellipsis = "[...] ";
waddstr(stdscr, ellipsis);
skip = len - (columns - 2 - strlen(ellipsis));
}
for (pos = dlg.subtitles; pos != NULL; pos = pos->next) {
if (skip == 0)
waddch(stdscr, ACS_RARROW);
else
skip--;
if (skip == 0)
waddch(stdscr, ' ');
else
skip--;
if (skip < strlen(pos->text)) {
waddstr(stdscr, pos->text + skip);
skip = 0;
} else
skip -= strlen(pos->text);
if (skip == 0)
waddch(stdscr, ' ');
else
skip--;
}
for (i = len + 1; i < columns - 1; i++)
waddch(stdscr, ACS_HLINE);
}
wnoutrefresh(stdscr);
@ -273,8 +317,12 @@ int init_dialog(const char *backtitle)
int height, width;
initscr(); /* Init curses */
/* Get current cursor position for signal handler in mconf.c */
getyx(stdscr, saved_y, saved_x);
getmaxyx(stdscr, height, width);
if (height < 19 || width < 80) {
if (height < WINDOW_HEIGTH_MIN || width < WINDOW_WIDTH_MIN) {
endwin();
return -ERRDISPLAYTOOSMALL;
}
@ -295,6 +343,11 @@ void set_dialog_backtitle(const char *backtitle)
dlg.backtitle = backtitle;
}
void set_dialog_subtitles(struct subtitle_list *subtitles)
{
dlg.subtitles = subtitles;
}
/*
* End using dialog functions.
*/
@ -323,27 +376,19 @@ void print_title(WINDOW *dialog, const char *title, int width)
/*
* 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
* characters '\n' are propperly processed. 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;
int prompt_len, room, wlen;
char tempstr[MAX_LEN + 1], *word, *sp, *sp2, *newline_separator = 0;
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);
@ -353,7 +398,10 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
newl = 1;
word = tempstr;
while (word && *word) {
sp = strchr(word, ' ');
sp = strpbrk(word, "\n ");
if (sp && *sp == '\n')
newline_separator = sp;
if (sp)
*sp++ = 0;
@ -365,7 +413,7 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
if (wlen > room ||
(newl && wlen < 4 && sp
&& wlen + 1 + strlen(sp) > room
&& (!(sp2 = strchr(sp, ' '))
&& (!(sp2 = strpbrk(sp, "\n "))
|| wlen + 1 + (sp2 - sp) > room))) {
cur_y++;
cur_x = x;
@ -373,7 +421,15 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
wmove(win, cur_y, cur_x);
waddstr(win, word);
getyx(win, cur_y, cur_x);
cur_x++;
/* Move to the next line if the word separator was a newline */
if (newline_separator) {
cur_y++;
cur_x = x;
newline_separator = 0;
} else
cur_x++;
if (sp && *sp == ' ') {
cur_x++; /* double space */
while (*++sp == ' ') ;
@ -567,7 +623,7 @@ void item_make(const char *fmt, ...)
void item_add_str(const char *fmt, ...)
{
va_list ap;
size_t avail;
size_t avail;
avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);

View File

@ -45,14 +45,14 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width)
WINDOW *dialog;
do_resize:
if (getmaxy(stdscr) < (height + 4))
if (getmaxy(stdscr) < (height + YESNO_HEIGTH_MIN))
return -ERRDISPLAYTOOSMALL;
if (getmaxx(stdscr) < (width + 4))
if (getmaxx(stdscr) < (width + YESNO_WIDTH_MIN))
return -ERRDISPLAYTOOSMALL;
/* center dialog box on screen */
x = (COLS - width) / 2;
y = (LINES - height) / 2;
x = (getmaxx(stdscr) - width) / 2;
y = (getmaxy(stdscr) - height) / 2;
draw_shadow(stdscr, y, x, height, width);

View File

@ -15,17 +15,17 @@
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <locale.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
#include "lxdialog/dialog.h"
static const char mconf_readme[] = N_(
"Overview\n"
"--------\n"
"This interface let you select features and parameters for the build.\n"
"This interface lets you select features and parameters for the build.\n"
"Features can either be built-in, modularized, or ignored. Parameters\n"
"must be entered in as decimal or hexadecimal numbers or text.\n"
"\n"
@ -39,16 +39,16 @@ static const char mconf_readme[] = 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> to remove it. You may also press the <Space Bar> to cycle\n"
"through the available options (i.e. 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"
"o Use the Up/Down arrow keys (cursor keys) to highlight the item you\n"
" wish to change or the submenu you wish to select and press <Enter>.\n"
" Submenus are designated by \"--->\", empty ones by \"----\".\n"
"\n"
" Shortcut: Press the option's highlighted letter (hotkey).\n"
" Pressing a hotkey more than once will sequence\n"
@ -65,7 +65,7 @@ static const char mconf_readme[] = 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"
" <Exit>, <Help>, <Save>, and <Load>.\n"
"\n"
"o To get help with an item, use the cursor keys to highlight <Help>\n"
" and press <ENTER>.\n"
@ -105,10 +105,10 @@ static const char mconf_readme[] = 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"
" keys h,j,k,l function here as do <u>, <d>, <SPACE BAR> and <B> for\n"
" those who are familiar with less and lynx.\n"
"\n"
"o Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n"
"o Press <E>, <X>, <q>, <Enter> or <Esc><Esc> to exit.\n"
"\n"
"\n"
"Alternate Configuration Files\n"
@ -117,23 +117,21 @@ static const char mconf_readme[] = N_(
"those who, for various reasons, find it necessary to switch\n"
"between different configurations.\n"
"\n"
"At the end of the main menu you will find two options. One is\n"
"for saving the current configuration to a file of your choosing.\n"
"The other option is for loading a previously saved alternate\n"
"configuration.\n"
"The <Save> button will let you save the current configuration to\n"
"a file of your choosing. Use the <Load> button to load a previously\n"
"saved alternate 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"
"Even if you don't use alternate configuration files, but you find\n"
"during a Menuconfig session that you have completely messed up your\n"
"settings, you may use the <Load> button to restore your previously\n"
"saved settings from \".config\" without 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"
"If you use Menuconfig in an XTERM window, make sure you have your\n"
"$TERM variable set to point to an xterm definition which supports\n"
"color. Otherwise, Menuconfig will look rather bad. Menuconfig will\n"
"not display correctly in an 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"
@ -148,8 +146,8 @@ static const char mconf_readme[] = N_(
"\n"
"Optional personality available\n"
"------------------------------\n"
"If you prefer to have all of the options listed in a single menu, rather\n"
"than the default multimenu hierarchy, run the menuconfig with\n"
"If you prefer to have all of the options listed in a single menu,\n"
"rather than the default multimenu hierarchy, run the menuconfig with\n"
"MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
"\n"
"make MENUCONFIG_MODE=single_menu menuconfig\n"
@ -172,11 +170,11 @@ static const char mconf_readme[] = N_(
" mono => selects colors suitable for monochrome displays\n"
" blackbg => selects a color scheme with black background\n"
" classic => theme with blue background. The classic look\n"
" bluetitle => a LCD friendly version of classic. (default)\n"
" bluetitle => an LCD friendly version of classic. (default)\n"
"\n"),
menu_instructions[] = N_(
"Arrow keys navigate the menu. "
"<Enter> selects submenus --->. "
"<Enter> selects submenus ---> (or empty submenus ----). "
"Highlighted letters are hotkeys. "
"Pressing <Y> includes, <N> excludes, <M> modularizes features. "
"Press <Esc><Esc> to exit, <?> for Help, </> for Search. "
@ -236,29 +234,36 @@ search_help[] = N_(
"Result:\n"
"-----------------------------------------------------------------\n"
"Symbol: FOO [=m]\n"
"Type : tristate\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"
" Location:\n"
" -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
" -> PCI support (PCI [=y])\n"
"(1) -> PCI access mode (<choice> [=y])\n"
" Defined at drivers/pci/Kconfig:47\n"
" Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
" Selects: LIBCRC32\n"
" Selected by: BAR [=n]\n"
"-----------------------------------------------------------------\n"
"o The line 'Type:' shows the type of the configuration option for\n"
" this symbol (boolean, tristate, string, ...)\n"
"o The line 'Prompt:' shows the text used in the menu structure for\n"
" this symbol\n"
"o The 'Defined at' line tell at what file / line number the symbol\n"
"o The 'Defined at' line tells 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"
"o The 'Depends on:' line tells what symbols need 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"
"o The 'Location:' lines tells 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"
" A location followed by a [=y] indicates that this is a\n"
" selectable menu item - and the current value is displayed inside\n"
" brackets.\n"
" Press the key in the (#) prefix to jump directly to that\n"
" location. You will be returned to the current search results\n"
" after exiting this new menu.\n"
"o The 'Selects:' line tells what symbols 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"
"o The 'Selected by' line tells what symbol has selected this symbol\n"
"\n"
"Only relevant lines are shown.\n"
"\n\n"
@ -273,12 +278,17 @@ static struct menu *current_menu;
static int child_count;
static int single_menu_mode;
static int show_all_options;
static int save_and_exit;
static int silent;
static void conf(struct menu *menu);
static void conf(struct menu *menu, struct menu *active_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 int show_textbox_ext(const char *title, char *text, int r, int c,
int *keys, int *vscroll, int *hscroll,
update_text_fn update_text, void *data);
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);
@ -290,7 +300,7 @@ static void set_config_filename(const char *config_filename)
int size;
size = snprintf(menu_backtitle, sizeof(menu_backtitle),
"%s - %s", config_filename, rootmenu.prompt->text);
"%s - %s", config_filename, rootmenu.prompt->text);
if (size >= sizeof(menu_backtitle))
menu_backtitle[sizeof(menu_backtitle)-1] = '\0';
set_dialog_backtitle(menu_backtitle);
@ -300,18 +310,103 @@ static void set_config_filename(const char *config_filename)
filename[sizeof(filename)-1] = '\0';
}
struct subtitle_part {
struct list_head entries;
const char *text;
};
static LIST_HEAD(trail);
static struct subtitle_list *subtitles;
static void set_subtitle(void)
{
struct subtitle_part *sp;
struct subtitle_list *pos, *tmp;
for (pos = subtitles; pos != NULL; pos = tmp) {
tmp = pos->next;
free(pos);
}
subtitles = NULL;
list_for_each_entry(sp, &trail, entries) {
if (sp->text) {
if (pos) {
pos->next = xcalloc(1, sizeof(*pos));
pos = pos->next;
} else {
subtitles = pos = xcalloc(1, sizeof(*pos));
}
pos->text = sp->text;
}
}
set_dialog_subtitles(subtitles);
}
static void reset_subtitle(void)
{
struct subtitle_list *pos, *tmp;
for (pos = subtitles; pos != NULL; pos = tmp) {
tmp = pos->next;
free(pos);
}
subtitles = NULL;
set_dialog_subtitles(subtitles);
}
struct search_data {
struct list_head *head;
struct menu **targets;
int *keys;
};
static void update_text(char *buf, size_t start, size_t end, void *_data)
{
struct search_data *data = _data;
struct jump_key *pos;
int k = 0;
list_for_each_entry(pos, data->head, entries) {
if (pos->offset >= start && pos->offset < end) {
char header[4];
if (k < JUMP_NB) {
int key = '0' + (pos->index % JUMP_NB) + 1;
sprintf(header, "(%c)", key);
data->keys[k] = key;
data->targets[k] = pos->target;
k++;
} else {
sprintf(header, " ");
}
memcpy(buf + pos->offset, header, sizeof(header) - 1);
}
}
data->keys[k] = 0;
}
static void search_conf(void)
{
struct symbol **sym_arr;
struct gstr res;
struct gstr title;
char *dialog_input;
int dres;
int dres, vscroll = 0, hscroll = 0;
bool again;
struct gstr sttext;
struct subtitle_part stpart;
title = str_new();
str_printf( &title, _("Enter (sub)string or regexp to search for "
"(with or without \"%s\")"), CONFIG_);
again:
dialog_clear();
dres = dialog_inputbox(_("Search Configuration Parameter"),
_("Enter " CONFIG_ " (sub)string to search for "
"(with or without \"" CONFIG_ "\")"),
str_get(&title),
10, 75, "");
switch (dres) {
case 0:
@ -320,6 +415,7 @@ again:
show_helptext(_("Search Configuration"), search_help);
goto again;
default:
str_free(&title);
return;
}
@ -328,11 +424,43 @@ again:
if (strncasecmp(dialog_input_result, CONFIG_, strlen(CONFIG_)) == 0)
dialog_input += strlen(CONFIG_);
sttext = str_new();
str_printf(&sttext, "Search (%s)", dialog_input_result);
stpart.text = str_get(&sttext);
list_add_tail(&stpart.entries, &trail);
sym_arr = sym_re_search(dialog_input);
res = get_relations_str(sym_arr);
do {
LIST_HEAD(head);
struct menu *targets[JUMP_NB];
int keys[JUMP_NB + 1], i;
struct search_data data = {
.head = &head,
.targets = targets,
.keys = keys,
};
struct jump_key *pos, *tmp;
res = get_relations_str(sym_arr, &head);
set_subtitle();
dres = show_textbox_ext(_("Search Results"), (char *)
str_get(&res), 0, 0, keys, &vscroll,
&hscroll, &update_text, (void *)
&data);
again = false;
for (i = 0; i < JUMP_NB && keys[i]; i++)
if (dres == keys[i]) {
conf(targets[i]->parent, targets[i]);
again = true;
}
str_free(&res);
list_for_each_entry_safe(pos, tmp, &head, entries)
free(pos);
} while (again);
free(sym_arr);
show_textbox(_("Search Results"), str_get(&res), 0, 0);
str_free(&res);
str_free(&title);
list_del(trail.prev);
str_free(&sttext);
}
static void build_conf(struct menu *menu)
@ -369,8 +497,9 @@ static void build_conf(struct menu *menu)
menu->data ? "-->" : "++>",
indent + 1, ' ', prompt);
} else
item_make(" %*c%s --->", indent + 1, ' ', prompt);
item_make(" %*c%s %s",
indent + 1, ' ', prompt,
menu_is_empty(menu) ? "----" : "--->");
item_set_tag('m');
item_set_data(menu);
if (single_menu_mode && menu->data)
@ -501,7 +630,7 @@ static void build_conf(struct menu *menu)
(sym_has_value(sym) || !sym_is_changable(sym)) ?
"" : _(" (NEW)"));
if (menu->prompt->type == P_MENU) {
item_add_str(" --->");
item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
return;
}
}
@ -513,40 +642,40 @@ conf_childs:
indent -= doint;
}
static void conf(struct menu *menu)
static void conf(struct menu *menu, struct menu *active_menu)
{
struct menu *submenu;
const char *prompt = menu_get_prompt(menu);
struct subtitle_part stpart;
struct symbol *sym;
struct menu *active_menu = NULL;
int res;
int s_scroll = 0;
if (menu != &rootmenu)
stpart.text = menu_get_prompt(menu);
else
stpart.text = NULL;
list_add_tail(&stpart.entries, &trail);
while (1) {
item_reset();
current_menu = menu;
build_conf(menu);
if (!child_count)
break;
if (menu == &rootmenu) {
item_make("--- ");
item_set_tag(':');
item_make(_(" Load an Alternate Configuration File"));
item_set_tag('L');
item_make(_(" Save an Alternate Configuration File"));
item_set_tag('S');
}
set_subtitle();
dialog_clear();
res = dialog_menu(prompt ? _(prompt) : _("Main Menu"),
_(menu_instructions),
active_menu, &s_scroll);
if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
break;
if (!item_activate_selected())
continue;
if (!item_tag())
continue;
if (item_count() != 0) {
if (!item_activate_selected())
continue;
if (!item_tag())
continue;
}
submenu = item_data();
active_menu = item_data();
if (submenu)
@ -561,32 +690,36 @@ static void conf(struct menu *menu)
if (single_menu_mode)
submenu->data = (void *) (long) !submenu->data;
else
conf(submenu);
conf(submenu, NULL);
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);
conf(submenu, NULL);
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
else {
reset_subtitle();
show_helptext(_("README"), _(mconf_readme));
}
break;
case 3:
reset_subtitle();
conf_save();
break;
case 4:
reset_subtitle();
conf_load();
break;
case 5:
if (item_is_tag('t')) {
if (sym_set_tristate_value(sym, yes))
break;
@ -594,34 +727,45 @@ static void conf(struct menu *menu)
show_textbox(NULL, setmod_text, 6, 74);
}
break;
case 4:
case 6:
if (item_is_tag('t'))
sym_set_tristate_value(sym, no);
break;
case 5:
case 7:
if (item_is_tag('t'))
sym_set_tristate_value(sym, mod);
break;
case 6:
case 8:
if (item_is_tag('t'))
sym_toggle_tristate_value(sym);
else if (item_is_tag('m'))
conf(submenu);
conf(submenu, NULL);
break;
case 7:
case 9:
search_conf();
break;
case 8:
case 10:
show_all_options = !show_all_options;
break;
}
}
list_del(trail.prev);
}
static int show_textbox_ext(const char *title, char *text, int r, int c, int
*keys, int *vscroll, int *hscroll, update_text_fn
update_text, void *data)
{
dialog_clear();
return dialog_textbox(title, text, r, c, keys, vscroll, hscroll,
update_text, data);
}
static void show_textbox(const char *title, const char *text, int r, int c)
{
dialog_clear();
dialog_textbox(title, text, r, c);
show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL,
NULL, NULL);
}
static void show_helptext(const char *title, const char *text)
@ -629,6 +773,19 @@ static void show_helptext(const char *title, const char *text)
show_textbox(title, text, 0, 0);
}
static void conf_message_callback(const char *fmt, va_list ap)
{
char buf[PATH_MAX+1];
vsnprintf(buf, sizeof(buf), fmt, ap);
if (save_and_exit) {
if (!silent)
printf("%s", buf);
} else {
show_textbox(NULL, buf, 6, 60);
}
}
static void show_help(struct menu *menu)
{
struct gstr help = str_new();
@ -671,7 +828,9 @@ static void conf_choice(struct menu *menu)
dialog_clear();
res = dialog_checklist(prompt ? _(prompt) : _("Main Menu"),
_(radiolist_instructions),
15, 70, 6);
MENUBOX_HEIGTH_MIN,
MENUBOX_WIDTH_MIN,
CHECKLIST_HEIGTH_MIN);
selected = item_activate_selected();
switch (res) {
case 0:
@ -793,9 +952,60 @@ static void conf_save(void)
}
}
static int handle_exit(void)
{
int res;
save_and_exit = 1;
reset_subtitle();
dialog_clear();
if (conf_get_changed())
res = dialog_yesno(NULL,
_("Do you wish to save your new configuration?\n"
"(Press <ESC><ESC> to continue Crosstool-NG configuration.)"),
6, 60);
else
res = -1;
end_dialog(saved_x, saved_y);
switch (res) {
case 0:
if (conf_write(filename)) {
fprintf(stderr, _("\n\n"
"Error while writing of the configuration.\n"
"Your configuration changes were NOT saved."
"\n\n"));
return 1;
}
/* fall through */
case -1:
if (!silent)
printf(_("\n\n"
"*** End of the configuration.\n"
"*** Execute 'ct-ng build' to start the build or try 'ct-ng help'."
"\n\n"));
res = 0;
break;
default:
if (!silent)
fprintf(stderr, _("\n\n"
"Your configuration changes were NOT saved."
"\n\n"));
if (res != KEY_ESC)
res = 0;
}
return res;
}
static void sig_handler(int signo)
{
exit(handle_exit());
}
int main(int ac, char **av)
{
int saved_x, saved_y;
char *mode;
int res;
@ -803,6 +1013,14 @@ int main(int ac, char **av)
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
signal(SIGINT, sig_handler);
if (ac > 1 && strcmp(av[1], "-s") == 0) {
silent = 1;
/* Silence conf_read() until the real callback is set up */
conf_set_message_callback(NULL);
av++;
}
conf_parse(av[1]);
conf_read(NULL);
@ -812,9 +1030,6 @@ int main(int ac, char **av)
single_menu_mode = 1;
}
initscr();
getyx(stdscr, saved_y, saved_x);
if (init_dialog(NULL)) {
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"));
@ -822,37 +1037,11 @@ int main(int ac, char **av)
}
set_config_filename(conf_get_configname());
conf_set_message_callback(conf_message_callback);
do {
conf(&rootmenu);
dialog_clear();
if (conf_get_changed())
res = dialog_yesno(NULL,
_("Do you wish to save your "
"new configuration?\n"
"<ESC><ESC> to continue."),
6, 60);
else
res = -1;
conf(&rootmenu, NULL);
res = handle_exit();
} while (res == KEY_ESC);
end_dialog(saved_x, saved_y);
switch (res) {
case 0:
if (conf_write(filename)) {
fprintf(stderr, _("\n\n"
"Error while writing of the configuration.\n"
"Your configuration changes were NOT saved."
"\n\n"));
return 1;
}
case -1:
break;
default:
fprintf(stderr, _("\n\n"
"Your configuration changes were NOT saved."
"\n\n"));
}
return 0;
return res;
}

View File

@ -3,14 +3,14 @@
* Released under the terms of the GNU GPL v2.0.
*/
#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
static const char nohelp_text[] = N_(
"There is no help available for this option.\n");
static const char nohelp_text[] = "There is no help available for this option.";
struct menu rootmenu;
static struct menu **last_entry_ptr;
@ -48,7 +48,7 @@ void menu_add_entry(struct symbol *sym)
{
struct menu *menu;
menu = malloc(sizeof(*menu));
menu = xmalloc(sizeof(*menu));
memset(menu, 0, sizeof(*menu));
menu->sym = sym;
menu->parent = current_menu;
@ -119,12 +119,13 @@ void menu_set_type(int type)
sym->type = type;
return;
}
menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'",
sym->name ? sym->name : "<choice>",
sym_type_name(sym->type), sym_type_name(type));
menu_warn(current_entry,
"ignoring type redefinition of '%s' from '%s' to '%s'",
sym->name ? sym->name : "<choice>",
sym_type_name(sym->type), sym_type_name(type));
}
struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
static 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);
@ -152,11 +153,24 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
struct menu *menu = current_entry;
while ((menu = menu->parent) != NULL) {
struct expr *dup_expr;
if (!menu->visibility)
continue;
/*
* Do not add a reference to the
* menu's visibility expression but
* use a copy of it. Otherwise the
* expression reduction functions
* will modify expressions that have
* multiple references which can
* cause unwanted side effects.
*/
dup_expr = expr_copy(menu->visibility);
prop->visible.expr
= expr_alloc_and(prop->visible.expr,
menu->visibility);
dup_expr);
}
}
@ -190,12 +204,15 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
void menu_add_option(int token, char *arg)
{
struct property *prop;
switch (token) {
case T_OPT_MODULES:
prop = prop_alloc(P_DEFAULT, modules_sym);
prop->expr = expr_alloc_symbol(current_entry->sym);
if (modules_sym)
zconf_error("symbol '%s' redefines option 'modules'"
" already defined by symbol '%s'",
current_entry->sym->name,
modules_sym->name
);
modules_sym = current_entry->sym;
break;
case T_OPT_DEFCONFIG_LIST:
if (!sym_defconfig_list)
@ -206,6 +223,9 @@ void menu_add_option(int token, char *arg)
case T_OPT_ENV:
prop_add_env(arg);
break;
case T_OPT_ALLNOCONFIG_Y:
current_entry->sym->flags |= SYMBOL_ALLNOCONFIG_Y;
break;
}
}
@ -244,8 +264,8 @@ static void sym_check_prop(struct symbol *sym)
"config symbol '%s' uses select, but is "
"not boolean or tristate", sym->name);
else if (sym2->type != S_UNKNOWN &&
sym2->type != S_BOOLEAN &&
sym2->type != S_TRISTATE)
sym2->type != S_BOOLEAN &&
sym2->type != S_TRISTATE)
prop_warn(prop,
"'%s' has wrong type. 'select' only "
"accept arguments of boolean and "
@ -254,7 +274,7 @@ static void sym_check_prop(struct symbol *sym)
case P_RANGE:
if (sym->type != S_INT && sym->type != S_HEX)
prop_warn(prop, "range is only allowed "
"for int or hex symbols");
"for int or hex symbols");
if (!menu_validate_number(sym, prop->expr->left.sym) ||
!menu_validate_number(sym, prop->expr->right.sym))
prop_warn(prop, "range is invalid");
@ -285,11 +305,6 @@ void menu_finalize(struct menu *parent)
}
}
}
if (parent->prompt &&
!expr_is_yes(parent->prompt->visible.expr)) {
parent->visibility = expr_alloc_and (parent->visibility,
parent->prompt->visible.expr);
}
/* set the type of the remaining choice values */
for (menu = parent->list; menu; menu = menu->next) {
current_entry = menu;
@ -441,6 +456,22 @@ bool menu_has_prompt(struct menu *menu)
return true;
}
/*
* Determine if a menu is empty.
* A menu is considered empty if it contains no or only
* invisible entries.
*/
bool menu_is_empty(struct menu *menu)
{
struct menu *child;
for (child = menu->list; child; child = child->next) {
if (menu_is_visible(child))
return(false);
}
return(true);
}
bool menu_is_visible(struct menu *menu)
{
struct menu *child;
@ -518,27 +549,53 @@ const char *menu_get_help(struct menu *menu)
return "";
}
static void get_prompt_str(struct gstr *r, struct property *prop)
static void get_prompt_str(struct gstr *r, struct property *prop,
struct list_head *head)
{
int i, j;
struct menu *submenu[8], *menu;
struct menu *submenu[8], *menu, *location = NULL;
struct jump_key *jump = NULL;
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)
for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
bool accessible = menu_is_visible(menu);
submenu[i++] = menu;
if (location == NULL && accessible)
location = menu;
}
if (head && location) {
jump = xmalloc(sizeof(struct jump_key));
if (menu_is_visible(prop->menu)) {
/*
* There is not enough room to put the hint at the
* beginning of the "Prompt" line. Put the hint on the
* last "Location" line even when it would belong on
* the former.
*/
jump->target = prop->menu;
} else
jump->target = location;
if (list_empty(head))
jump->index = 0;
else
jump->index = list_entry(head->prev, struct jump_key,
entries)->index + 1;
list_add_tail(&jump->entries, head);
}
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 (jump && menu == location)
jump->offset = strlen(r->s);
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>"),
@ -549,7 +606,23 @@ static void get_prompt_str(struct gstr *r, struct property *prop)
}
}
void get_symbol_str(struct gstr *r, struct symbol *sym)
/*
* get property of type P_SYMBOL
*/
static struct property *get_symbol_prop(struct symbol *sym)
{
struct property *prop = NULL;
for_all_properties(sym, prop, P_SYMBOL)
break;
return prop;
}
/*
* head is optional and may be NULL
*/
static void get_symbol_str(struct gstr *r, struct symbol *sym,
struct list_head *head)
{
bool hit;
struct property *prop;
@ -568,7 +641,19 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
}
}
for_all_prompts(sym, prop)
get_prompt_str(r, prop);
get_prompt_str(r, prop, head);
prop = get_symbol_prop(sym);
if (prop) {
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");
}
}
hit = false;
for_all_properties(sym, prop, P_SELECT) {
if (!hit) {
@ -588,14 +673,14 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
str_append(r, "\n\n");
}
struct gstr get_relations_str(struct symbol **sym_arr)
struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head)
{
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);
get_symbol_str(&res, sym, head);
if (!i)
str_append(&res, _("No matches found.\n"));
return res;
@ -605,16 +690,14 @@ struct gstr get_relations_str(struct symbol **sym_arr)
void menu_get_ext_help(struct menu *menu, struct gstr *help)
{
struct symbol *sym = menu->sym;
const char *help_text = nohelp_text;
if (menu_has_help(menu)) {
if (sym->name) {
if (sym->name)
str_printf(help, "%s%s:\n\n", CONFIG_, sym->name);
str_append(help, _(menu_get_help(menu)));
str_append(help, "\n");
}
} else {
str_append(help, nohelp_text);
help_text = menu_get_help(menu);
}
str_printf(help, "%s\n", _(help_text));
if (sym)
get_symbol_str(help, sym);
get_symbol_str(help, sym, NULL);
}

View File

@ -7,217 +7,211 @@
*/
#define _GNU_SOURCE
#include <string.h>
#define LKC_DIRECT_LINK
#include <stdlib.h>
#include "lkc.h"
#include "nconf.h"
#include <ctype.h>
static const char nconf_readme[] = N_(
"Overview\n"
"--------\n"
"This interface let you select features and parameters for the build.\n"
"Features can either be built-in, modularized, or ignored. Parameters\n"
"must be entered in as decimal or hexadecimal numbers or text.\n"
static const char nconf_global_help[] = N_(
"Help windows\n"
"------------\n"
"o Global help: Unless in a data entry window, pressing <F1> will give \n"
" you the global help window, which you are just reading.\n"
"\n"
"Menu items beginning with following braces represent features that\n"
" [ ] can be built in or removed\n"
" < > can be built in, modularized or removed\n"
" { } can be built in or modularized (selected by other feature)\n"
" - - are selected by other feature,\n"
" XXX cannot be selected. Use Symbol Info to find out why,\n"
"while *, M or whitespace inside braces means to build in, build as\n"
"a module or to exclude the feature respectively.\n"
"o A short version of the global help is available by pressing <F3>.\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"
"o Local help: To get help related to the current menu entry, use any\n"
" of <?> <h>, or if in a data entry window then press <F1>.\n"
"\n"
"Some additional keyboard hints:\n"
"\n"
"Menus\n"
"Menu entries\n"
"------------\n"
"This interface lets you select features and parameters for Crosstool-NG\n"
"build. Crosstool-NG features can either be built-in, modularized, or\n"
"removed.\n"
"Parameters must be entered as text or decimal or hexadecimal numbers.\n"
"\n"
"Menu entries beginning with following braces represent features that\n"
" [ ] can be built in or removed\n"
" < > can be built in, modularized or removed\n"
" { } can be built in or modularized, are selected by another feature\n"
" - - are selected by another feature\n"
" XXX cannot be selected. Symbol Info <F2> tells you why.\n"
"*, M or whitespace inside braces means to enable the option, let the build\n"
"automatically decide what to choose or to exclude the feature respectively.\n"
"The M (automatic decision) may have other meanings. It is suggested to\n"
"read the help for the feature.\n"
"\n"
"To change any of these features, highlight it with the movement keys\n"
"listed below and press <y> to enable it, <m> to let the component\n"
"automatically decide what to do or <n> to disable it. You may press\n"
"the <Space> key to cycle through the available options.\n"
"\n"
"A trailing \"--->\" designates a submenu, a trailing \"----\" an\n"
"empty submenu.\n"
"\n"
"Menu navigation keys\n"
"----------------------------------------------------------------------\n"
"Linewise up <Up>\n"
"Linewise down <Down>\n"
"Pagewise up <Page Up>\n"
"Pagewise down <Page Down>\n"
"First entry <Home>\n"
"Last entry <End>\n"
"Enter a submenu <Right> <Enter>\n"
"Go back to parent menu <Left> <Esc> <F5>\n"
"Close a help window <Enter> <Esc> <F5>\n"
"Close entry window, apply <Enter>\n"
"Close entry window, forget <Esc> <F5>\n"
"Start incremental, case-insensitive search for STRING in menu entries,\n"
" no regex support, STRING is displayed in upper left corner\n"
" </>STRING\n"
" Remove last character <Backspace>\n"
" Jump to next hit <Down>\n"
" Jump to previous hit <Up>\n"
"Exit menu search mode </> <Esc>\n"
"Search for configuration variables with or without leading CONFIG_\n"
" <F8>RegExpr<Enter>\n"
"Verbose search help <F8><F1>\n"
"----------------------------------------------------------------------\n"
"\n"
"Unless in a data entry window, key <1> may be used instead of <F1>,\n"
"<2> instead of <F2>, etc.\n"
"\n"
"\n"
"Radiolist (Choice list)\n"
"-----------------------\n"
"Use the movement keys listed above to select the option you wish to set\n"
"and press <Space>.\n"
"\n"
"\n"
"Data entry\n"
"----------\n"
"o Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
" you wish to change use <Enter> or <Space>. Goto submenu by \n"
" pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n"
" Submenus are designated by \"--->\".\n"
"\n"
" Searching: pressing '/' triggers interactive search mode.\n"
" nconfig performs a case insensitive search for the string\n"
" in the menu prompts (no regex support).\n"
" Pressing the up/down keys highlights the previous/next\n"
" matching item. Backspace removes one character from the\n"
" match string. Pressing either '/' again or ESC exits\n"
" search mode. All other keys behave normally.\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 just press <ESC> <F5> <F8> or <left-arrow>.\n"
"\n"
"o To get help with an item, press <F1>\n"
" Shortcut: Press <h> or <?>.\n"
"Enter the requested information and press <Enter>. Hexadecimal values\n"
"may be entered without the \"0x\" prefix.\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"
"Text Box (Help Window)\n"
"----------------------\n"
"Use movement keys as listed in table above.\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, press <F1>\n"
" Shortcut: Press <H> or <?>.\n"
"Press any of <Enter> <Esc> <q> <F5> <F9> to exit.\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, press <F1>.\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> for those\n"
" who are familiar with less and lynx.\n"
"\n"
"o Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n"
"\n"
"\n"
"Alternate Configuration Files\n"
"Alternate configuration files\n"
"-----------------------------\n"
"nconfig supports the use of alternate configuration files for\n"
"those who, for various reasons, find it necessary to switch\n"
"between different configurations.\n"
"nconfig supports switching between different configurations.\n"
"Press <F6> to save your current configuration. Press <F7> and enter\n"
"a file name to load a previously saved configuration.\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 nconfig 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 nconfig.\n"
"Terminal configuration\n"
"----------------------\n"
"If you use nconfig in a xterm window, make sure your TERM environment\n"
"variable specifies a terminal configuration which supports at least\n"
"16 colors. Otherwise nconfig will look rather bad.\n"
"\n"
"Other information\n"
"-----------------\n"
"If you use nconfig in an XTERM window make sure you have your\n"
"$TERM variable set to point to a xterm definition which supports color.\n"
"Otherwise, nconfig will look rather bad. nconfig will not\n"
"display correctly in a RXVT window because rxvt displays only one\n"
"intensity of color, bright.\n"
"If the \"stty size\" command reports the current terminalsize correctly,\n"
"nconfig will adapt to sizes larger than the traditional 80x25 \"standard\"\n"
"and display longer menus properly.\n"
"\n"
"nconfig will display larger menus on screens or xterms which are\n"
"set to display more than the standard 25 row by 80 column geometry.\n"
"In order for this to work, the \"stty size\" command must be able to\n"
"display the screen's current row and column geometry. I STRONGLY\n"
"RECOMMEND that you make sure you do NOT have the shell variables\n"
"LINES and COLUMNS exported into your environment. Some distributions\n"
"export those variables via /etc/profile. Some ncurses programs can\n"
"become confused when those variables (LINES & COLUMNS) don't reflect\n"
"the true screen size.\n"
"\n"
"Optional personality available\n"
"------------------------------\n"
"If you prefer to have all of the options listed in a single menu, rather\n"
"than the default multimenu hierarchy, run the nconfig with NCONFIG_MODE\n"
"environment variable set to single_menu. Example:\n"
"Single menu mode\n"
"----------------\n"
"If you prefer to have all of the menu entries listed in a single menu,\n"
"rather than the default multimenu hierarchy, run nconfig with\n"
"NCONFIG_MODE environment variable set to single_menu. Example:\n"
"\n"
"make NCONFIG_MODE=single_menu nconfig\n"
"ct-ng NCONFIG_MODE=single_menu nconfig\n"
"\n"
"<Enter> will then unroll the appropriate category, or enfold it if it\n"
"is already unrolled.\n"
"<Enter> will then unfold the appropriate category, or fold it if it\n"
"is already unfolded. Folded menu entries will be designated by a\n"
"leading \"++>\" and unfolded entries by a leading \"-->\".\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"
"Note that this mode can eventually be a little more CPU expensive than\n"
"the default mode, especially with a larger number of unfolded submenus.\n"
"\n"),
menu_no_f_instructions[] = N_(
" You do not have function keys support. Please follow the\n"
" following instructions:\n"
" Arrow keys navigate the menu.\n"
" <Enter> or <right-arrow> selects submenus --->.\n"
" Capital Letters are hotkeys.\n"
" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
" Pressing SpaceBar toggles between the above options.\n"
" Press <Esc> or <left-arrow> to go back one menu,\n"
" <?> or <h> for Help, </> for Search.\n"
" <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
" <Esc> always leaves the current window.\n"),
"Legend: [*] built-in [ ] excluded <M> automatic < > automatic capable.\n"
"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
"\n"
"Use the following keys to navigate the menus:\n"
"Move up or down with <Up> and <Down>.\n"
"Enter a submenu with <Enter> or <Right>.\n"
"Exit a submenu to its parent menu with <Esc> or <Left>.\n"
"Pressing <y> includes, <n> excludes, <m> modularizes features.\n"
"Pressing <Space> cycles through the available options.\n"
"To search for menu entries press </>.\n"
"<Esc> always leaves the current window.\n"
"\n"
"You do not have function keys support.\n"
"Press <1> instead of <F1>, <2> instead of <F2>, etc.\n"
"For verbose global help use key <1>.\n"
"For help related to the current menu entry press <?> or <h>.\n"),
menu_instructions[] = N_(
" Arrow keys navigate the menu.\n"
" <Enter> or <right-arrow> selects submenus --->.\n"
" Capital Letters are hotkeys.\n"
" Pressing <Y> includes, <N> excludes, <M> modularizes features.\n"
" Pressing SpaceBar toggles between the above options\n"
" Press <Esc>, <F5> or <left-arrow> to go back one menu,\n"
" <?>, <F1> or <h> for Help, </> for Search.\n"
" <1> is interchangeable with <F1>, <2> with <F2>, etc.\n"
" Legend: [*] built-in [ ] excluded <M> module < > module capable.\n"
" <Esc> always leaves the current window\n"),
"Legend: [*] built-in [ ] excluded <M> automatic < > automatic capable.\n"
"Submenus are designated by a trailing \"--->\", empty ones by \"----\".\n"
"\n"
"Use the following keys to navigate the menus:\n"
"Move up or down with <Up> or <Down>.\n"
"Enter a submenu with <Enter> or <Right>.\n"
"Exit a submenu to its parent menu with <Esc> or <Left>.\n"
"Pressing <y> includes, <n> excludes, <m> modularizes features.\n"
"Pressing <Space> cycles through the available options.\n"
"To search for menu entries press </>.\n"
"<Esc> always leaves the current window.\n"
"\n"
"Pressing <1> may be used instead of <F1>, <2> instead of <F2>, etc.\n"
"For verbose global help press <F1>.\n"
"For help related to the current menu entry press <?> or <h>.\n"),
radiolist_instructions[] = N_(
" Use the arrow keys to navigate this window or\n"
" press the hotkey of the item you wish to select\n"
" followed by the <SPACE BAR>.\n"
" Press <?>, <F1> or <h> for additional information about this option.\n"),
"Press <Up>, <Down>, <Home> or <End> to navigate a radiolist, select\n"
"with <Space>.\n"
"For help related to the current entry press <?> or <h>.\n"
"For global help press <F1>.\n"),
inputbox_instructions_int[] = N_(
"Please enter a decimal value.\n"
"Fractions will not be accepted.\n"
"Press <RETURN> to accept, <ESC> to cancel."),
"Press <Enter> to apply, <Esc> to cancel."),
inputbox_instructions_hex[] = N_(
"Please enter a hexadecimal value.\n"
"Press <RETURN> to accept, <ESC> to cancel."),
"Press <Enter> to apply, <Esc> to cancel."),
inputbox_instructions_string[] = N_(
"Please enter a string value.\n"
"Press <RETURN> to accept, <ESC> to cancel."),
"Press <Enter> to apply, <Esc> to cancel."),
setmod_text[] = N_(
"This feature depends on another which\n"
"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 option.\n"),
"This feature depends on another feature which has been configured as\n"
"automatic. As a result, the current feature will be built as automatic too."),
load_config_text[] = N_(
"Enter the name of the configuration file you wish to load.\n"
"Accept the name shown to restore the configuration you\n"
"last retrieved. Leave blank to abort."),
"Accept the name shown to restore the configuration you last\n"
"retrieved. Leave empty to abort."),
load_config_help[] = N_(
"\n"
"For various reasons, one may wish to keep several different\n"
"configurations available on a single machine.\n"
"\n"
"If you have saved a previous configuration in a file other than the\n"
"default one, entering its name here will allow you to modify that\n"
"configuration.\n"
"default one, entering its name here will allow you to load and modify\n"
"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"),
"Leave empty to abort.\n"),
save_config_text[] = N_(
"Enter a filename to which this configuration should be saved\n"
"as an alternate. Leave blank to abort."),
"as an alternate. Leave empty to abort."),
save_config_help[] = N_(
"\n"
"For various reasons, one may wish to keep different configurations\n"
"available on a single machine.\n"
"For various reasons, one may wish to keep several different\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"),
"Leave empty to abort.\n"),
search_help[] = N_(
"\n"
"Search for symbols and display their relations. Regular expressions\n"
"are allowed.\n"
"Example: search for \"^FOO\"\n"
"Search for symbols (configuration variable names CONFIG_*) and display\n"
"their relations. Regular expressions are supported.\n"
"Example: Search for \"^FOO\".\n"
"Result:\n"
"-----------------------------------------------------------------\n"
"Symbol: FOO [ = m]\n"
@ -225,32 +219,32 @@ search_help[] = 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"
" -> Bus options (PCI, PCMCIA, EISA, 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 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"
"o The line 'Prompt:' shows the text displayed for this symbol in\n"
" the menu hierarchy.\n"
"o The 'Defined at' line tells at what file / line number the symbol is\n"
" defined.\n"
"o The 'Depends on:' line lists symbols that need to be defined for\n"
" this symbol to be visible and selectable in the menu.\n"
"o The 'Location:' lines tell, where in the menu structure this symbol\n"
" is located. A location followed by a [ = y] indicates that this is\n"
" a selectable menu item, and the current value is displayed inside\n"
" brackets.\n"
"o The 'Selects:' line tells, what symbol will be automatically selected\n"
" if this symbol is selected (y or m).\n"
"o The 'Selected by' line tells what symbol has selected this symbol.\n"
"\n"
"Only relevant lines are shown.\n"
"\n\n"
"Search examples:\n"
"Examples: USB => find all symbols containing USB\n"
" ^USB => find all symbols starting with USB\n"
" USB$ => find all symbols ending with USB\n"
"USB => find all symbols containing USB\n"
"^USB => find all symbols starting with USB\n"
"USB$ => find all symbols ending with USB\n"
"\n");
struct mitem {
@ -280,6 +274,9 @@ static int global_exit;
/* the currently selected button */
const char *current_instructions = menu_instructions;
static char *dialog_input_result;
static int dialog_input_result_len;
static void conf(struct menu *menu);
static void conf_choice(struct menu *menu);
static void conf_string(struct menu *menu);
@ -318,19 +315,19 @@ struct function_keys function_keys[] = {
},
{
.key_str = "F2",
.func = "Sym Info",
.func = "SymInfo",
.key = F_SYMBOL,
.handler = handle_f2,
},
{
.key_str = "F3",
.func = "Insts",
.func = "Help 2",
.key = F_INSTS,
.handler = handle_f3,
},
{
.key_str = "F4",
.func = "Config",
.func = "ShowAll",
.key = F_CONF,
.handler = handle_f4,
},
@ -354,7 +351,7 @@ struct function_keys function_keys[] = {
},
{
.key_str = "F8",
.func = "Sym Search",
.func = "SymSearch",
.key = F_SEARCH,
.handler = handle_f8,
},
@ -371,15 +368,16 @@ static void print_function_line(void)
int i;
int offset = 1;
const int skip = 1;
int lines = getmaxy(stdscr);
for (i = 0; i < function_keys_num; i++) {
(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
mvwprintw(main_window, LINES-3, offset,
mvwprintw(main_window, lines-3, offset,
"%s",
function_keys[i].key_str);
(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
offset += strlen(function_keys[i].key_str);
mvwprintw(main_window, LINES-3,
mvwprintw(main_window, lines-3,
offset, "%s",
function_keys[i].func);
offset += strlen(function_keys[i].func) + skip;
@ -391,7 +389,7 @@ static void print_function_line(void)
static void handle_f1(int *key, struct menu *current_item)
{
show_scroll_win(main_window,
_("README"), _(nconf_readme));
_("Global help"), _(nconf_global_help));
return;
}
@ -406,7 +404,7 @@ static void handle_f2(int *key, struct menu *current_item)
static void handle_f3(int *key, struct menu *current_item)
{
show_scroll_win(main_window,
_("Instructions"),
_("Short help"),
_(current_instructions));
return;
}
@ -695,15 +693,19 @@ static void search_conf(void)
{
struct symbol **sym_arr;
struct gstr res;
char dialog_input_result[100];
struct gstr title;
char *dialog_input;
int dres;
title = str_new();
str_printf( &title, _("Enter (sub)string or regexp to search for "
"(with or without \"%s\")"), CONFIG_);
again:
dres = dialog_inputbox(main_window,
_("Search Configuration Parameter"),
_("Enter " CONFIG_ " (sub)string to search for "
"(with or without \"" CONFIG_ "\")"),
"", dialog_input_result, 99);
str_get(&title),
"", &dialog_input_result, &dialog_input_result_len);
switch (dres) {
case 0:
break;
@ -712,6 +714,7 @@ again:
_("Search Configuration"), search_help);
goto again;
default:
str_free(&title);
return;
}
@ -721,11 +724,12 @@ again:
dialog_input += strlen(CONFIG_);
sym_arr = sym_re_search(dialog_input);
res = get_relations_str(sym_arr);
res = get_relations_str(sym_arr, NULL);
free(sym_arr);
show_scroll_win(main_window,
_("Search Results"), str_get(&res));
str_free(&res);
str_free(&title);
}
@ -759,9 +763,9 @@ static void build_conf(struct menu *menu)
indent + 1, ' ', prompt);
} else
item_make(menu, 'm',
" %*c%s --->",
indent + 1,
' ', prompt);
" %*c%s %s",
indent + 1, ' ', prompt,
menu_is_empty(menu) ? "----" : "--->");
if (single_menu_mode && menu->data)
goto conf_childs;
@ -903,7 +907,7 @@ static void build_conf(struct menu *menu)
(sym_has_value(sym) || !sym_is_changable(sym)) ?
"" : _(" (NEW)"));
if (menu->prompt && menu->prompt->type == P_MENU) {
item_add_str(" --->");
item_add_str(" %s", menu_is_empty(menu) ? "----" : "--->");
return;
}
}
@ -954,7 +958,7 @@ static void show_menu(const char *prompt, const char *instructions,
clear();
(void) wattrset(main_window, attributes[NORMAL]);
print_in_middle(stdscr, 1, 0, COLS,
print_in_middle(stdscr, 1, 0, getmaxx(stdscr),
menu_backtitle,
attributes[MAIN_HEADING]);
@ -1067,7 +1071,6 @@ static void conf(struct menu *menu)
struct menu *submenu = 0;
const char *prompt = menu_get_prompt(menu);
struct symbol *sym;
struct menu *active_menu = NULL;
int res;
int current_index = 0;
int last_top_row = 0;
@ -1152,13 +1155,9 @@ static void conf(struct menu *menu)
continue;
submenu = (struct menu *) item_data();
active_menu = (struct menu *)item_data();
if (!submenu || !menu_is_visible(submenu))
continue;
if (submenu)
sym = submenu->sym;
else
sym = NULL;
sym = submenu->sym;
switch (res) {
case ' ':
@ -1222,20 +1221,13 @@ static void conf_message_callback(const char *fmt, va_list ap)
static void show_help(struct menu *menu)
{
struct gstr help = str_new();
struct gstr help;
if (menu && menu->sym && menu_has_help(menu)) {
if (menu->sym->name) {
str_printf(&help, "%s%s:\n\n", CONFIG_, menu->sym->name);
str_append(&help, _(menu_get_help(menu)));
str_append(&help, "\n");
get_symbol_str(&help, menu->sym);
} else {
str_append(&help, _(menu_get_help(menu)));
}
} else {
str_append(&help, nohelp_text);
}
if (!menu)
return;
help = str_new();
menu_get_ext_help(menu, &help);
show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help));
str_free(&help);
}
@ -1360,7 +1352,6 @@ static void conf_choice(struct menu *menu)
static void conf_string(struct menu *menu)
{
const char *prompt = menu_get_prompt(menu);
char dialog_input_result[256];
while (1) {
int res;
@ -1383,8 +1374,8 @@ static void conf_string(struct menu *menu)
prompt ? _(prompt) : _("Main Menu"),
heading,
sym_get_string_value(menu->sym),
dialog_input_result,
sizeof(dialog_input_result));
&dialog_input_result,
&dialog_input_result_len);
switch (res) {
case 0:
if (sym_set_string_value(menu->sym,
@ -1404,14 +1395,13 @@ static void conf_string(struct menu *menu)
static void conf_load(void)
{
char dialog_input_result[256];
while (1) {
int res;
res = dialog_inputbox(main_window,
NULL, load_config_text,
filename,
dialog_input_result,
sizeof(dialog_input_result));
&dialog_input_result,
&dialog_input_result_len);
switch (res) {
case 0:
if (!dialog_input_result[0])
@ -1436,14 +1426,13 @@ static void conf_load(void)
static void conf_save(void)
{
char dialog_input_result[256];
while (1) {
int res;
res = dialog_inputbox(main_window,
NULL, save_config_text,
filename,
dialog_input_result,
sizeof(dialog_input_result));
&dialog_input_result,
&dialog_input_result_len);
switch (res) {
case 0:
if (!dialog_input_result[0])
@ -1470,14 +1459,18 @@ static void conf_save(void)
void setup_windows(void)
{
int lines, columns;
getmaxyx(stdscr, lines, columns);
if (main_window != NULL)
delwin(main_window);
/* set up the menu and menu window */
main_window = newwin(LINES-2, COLS-2, 2, 1);
main_window = newwin(lines-2, columns-2, 2, 1);
keypad(main_window, TRUE);
mwin_max_lines = LINES-7;
mwin_max_cols = COLS-6;
mwin_max_lines = lines-7;
mwin_max_cols = columns-6;
/* panels order is from bottom to top */
new_panel(main_window);
@ -1485,12 +1478,18 @@ void setup_windows(void)
int main(int ac, char **av)
{
int lines, columns;
char *mode;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
if (ac > 1 && strcmp(av[1], "-s") == 0) {
/* Silence conf_read() until the real callback is set up */
conf_set_message_callback(NULL);
av++;
}
conf_parse(av[1]);
conf_read(NULL);
@ -1510,7 +1509,8 @@ int main(int ac, char **av)
keypad(stdscr, TRUE);
curs_set(0);
if (COLS < 75 || LINES < 20) {
getmaxyx(stdscr, lines, columns);
if (columns < 75 || lines < 20) {
endwin();
printf("Your terminal should have at "
"least 20 lines and 75 columns\n");
@ -1518,7 +1518,11 @@ int main(int ac, char **av)
}
notimeout(stdscr, FALSE);
#if NCURSES_REENTRANT
set_escdelay(1);
#else
ESCDELAY = 1;
#endif
/* set btns menu */
curses_menu = new_menu(curses_menu_items);
@ -1558,4 +1562,3 @@ int main(int ac, char **av)
endwin();
return 0;
}

View File

@ -48,7 +48,7 @@ static void set_normal_colors(void)
init_pair(INPUT_FIELD, -1, -1);
init_pair(FUNCTION_HIGHLIGHT, -1, -1);
init_pair(FUNCTION_TEXT, COLOR_BLUE, -1);
init_pair(FUNCTION_TEXT, COLOR_YELLOW, -1);
}
/* available attributes:
@ -276,8 +276,8 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
total_width = max(msg_width, btns_width);
/* place dialog in middle of screen */
y = (LINES-(msg_lines+4))/2;
x = (COLS-(total_width+4))/2;
y = (getmaxy(stdscr)-(msg_lines+4))/2;
x = (getmaxx(stdscr)-(total_width+4))/2;
/* create the windows */
@ -356,7 +356,7 @@ int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...)
int dialog_inputbox(WINDOW *main_window,
const char *title, const char *prompt,
const char *init, char *result, int result_len)
const char *init, char **resultp, int *result_len)
{
int prompt_lines = 0;
int prompt_width = 0;
@ -367,7 +367,13 @@ int dialog_inputbox(WINDOW *main_window,
int i, x, y;
int res = -1;
int cursor_position = strlen(init);
int cursor_form_win;
char *result = *resultp;
if (strlen(init)+1 > *result_len) {
*result_len = strlen(init)+1;
*resultp = result = realloc(result, *result_len);
}
/* find the widest line of msg: */
prompt_lines = get_line_no(prompt);
@ -381,10 +387,10 @@ int dialog_inputbox(WINDOW *main_window,
prompt_width = max(prompt_width, strlen(title));
/* place dialog in middle of screen */
y = (LINES-(prompt_lines+4))/2;
x = (COLS-(prompt_width+4))/2;
y = (getmaxy(stdscr)-(prompt_lines+4))/2;
x = (getmaxx(stdscr)-(prompt_width+4))/2;
strncpy(result, init, result_len);
strncpy(result, init, *result_len);
/* create the windows */
win = newwin(prompt_lines+6, prompt_width+7, y, x);
@ -405,7 +411,9 @@ int dialog_inputbox(WINDOW *main_window,
fill_window(prompt_win, prompt);
mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
mvwprintw(form_win, 0, 0, "%s", result);
cursor_form_win = min(cursor_position, prompt_width-1);
mvwprintw(form_win, 0, 0, "%s",
result + cursor_position-cursor_form_win);
/* create panels */
panel = new_panel(win);
@ -431,6 +439,8 @@ int dialog_inputbox(WINDOW *main_window,
&result[cursor_position],
len-cursor_position+1);
cursor_position--;
cursor_form_win--;
len--;
}
break;
case KEY_DC:
@ -438,38 +448,63 @@ int dialog_inputbox(WINDOW *main_window,
memmove(&result[cursor_position],
&result[cursor_position+1],
len-cursor_position+1);
len--;
}
break;
case KEY_UP:
case KEY_RIGHT:
if (cursor_position < len &&
cursor_position < min(result_len, prompt_width))
if (cursor_position < len) {
cursor_position++;
cursor_form_win++;
}
break;
case KEY_DOWN:
case KEY_LEFT:
if (cursor_position > 0)
if (cursor_position > 0) {
cursor_position--;
cursor_form_win--;
}
break;
case KEY_HOME:
cursor_position = 0;
cursor_form_win = 0;
break;
case KEY_END:
cursor_position = len;
cursor_form_win = min(cursor_position, prompt_width-1);
break;
default:
if ((isgraph(res) || isspace(res)) &&
len-2 < result_len) {
if ((isgraph(res) || isspace(res))) {
/* one for new char, one for '\0' */
if (len+2 > *result_len) {
*result_len = len+2;
*resultp = result = realloc(result,
*result_len);
}
/* insert the char at the proper position */
memmove(&result[cursor_position+1],
&result[cursor_position],
len+1);
len-cursor_position+1);
result[cursor_position] = res;
cursor_position++;
cursor_form_win++;
len++;
} else {
mvprintw(0, 0, "unknow key: %d\n", res);
mvprintw(0, 0, "unknown key: %d\n", res);
}
break;
}
if (cursor_form_win < 0)
cursor_form_win = 0;
else if (cursor_form_win > prompt_width-1)
cursor_form_win = prompt_width-1;
wmove(form_win, 0, 0);
wclrtoeol(form_win);
mvwprintw(form_win, 0, 0, "%*s", prompt_width, " ");
mvwprintw(form_win, 0, 0, "%s", result);
wmove(form_win, 0, cursor_position);
mvwprintw(form_win, 0, 0, "%s",
result + cursor_position-cursor_form_win);
wmove(form_win, 0, cursor_form_win);
touchwin(win);
refresh_all_windows(main_window);
@ -510,7 +545,7 @@ void show_scroll_win(WINDOW *main_window,
{
int res;
int total_lines = get_line_no(text);
int x, y;
int x, y, lines, columns;
int start_x = 0, start_y = 0;
int text_lines = 0, text_cols = 0;
int total_cols = 0;
@ -521,6 +556,8 @@ void show_scroll_win(WINDOW *main_window,
WINDOW *pad;
PANEL *panel;
getmaxyx(stdscr, lines, columns);
/* find the widest line of msg: */
total_lines = get_line_no(text);
for (i = 0; i < total_lines; i++) {
@ -534,14 +571,14 @@ void show_scroll_win(WINDOW *main_window,
(void) wattrset(pad, attributes[SCROLLWIN_TEXT]);
fill_window(pad, text);
win_lines = min(total_lines+4, LINES-2);
win_cols = min(total_cols+2, COLS-2);
win_lines = min(total_lines+4, lines-2);
win_cols = min(total_cols+2, columns-2);
text_lines = max(win_lines-4, 0);
text_cols = max(win_cols-2, 0);
/* place window in middle of screen */
y = (LINES-win_lines)/2;
x = (COLS-win_cols)/2;
y = (lines-win_lines)/2;
x = (columns-win_cols)/2;
win = newwin(win_lines, win_cols, y, x);
keypad(win, TRUE);
@ -569,9 +606,11 @@ void show_scroll_win(WINDOW *main_window,
switch (res) {
case KEY_NPAGE:
case ' ':
case 'd':
start_y += text_lines-2;
break;
case KEY_PPAGE:
case 'u':
start_y -= text_lines+2;
break;
case KEY_HOME:
@ -597,10 +636,10 @@ void show_scroll_win(WINDOW *main_window,
start_x++;
break;
}
if (res == 10 || res == 27 || res == 'q'
|| res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) {
if (res == 10 || res == 27 || res == 'q' ||
res == KEY_F(F_HELP) || res == KEY_F(F_BACK) ||
res == KEY_F(F_EXIT))
break;
}
if (start_y < 0)
start_y = 0;
if (start_y >= total_lines-text_lines)

View File

@ -89,7 +89,7 @@ void fill_window(WINDOW *win, const char *text);
int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...);
int dialog_inputbox(WINDOW *main_window,
const char *title, const char *prompt,
const char *init, char *result, int result_len);
const char *init, char **resultp, int *result_len);
void refresh_all_windows(WINDOW *main_window);
void show_scroll_win(WINDOW *main_window,
const char *title,

View File

@ -9,7 +9,6 @@
#include <regex.h>
#include <sys/utsname.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
struct symbol symbol_yes = {
@ -113,7 +112,7 @@ struct property *sym_get_env_prop(struct symbol *sym)
return NULL;
}
struct property *sym_get_default_prop(struct symbol *sym)
static struct property *sym_get_default_prop(struct symbol *sym)
{
struct property *prop;
@ -137,7 +136,7 @@ static struct property *sym_get_range_prop(struct symbol *sym)
return NULL;
}
static int sym_get_range_val(struct symbol *sym, int base)
static long long sym_get_range_val(struct symbol *sym, int base)
{
sym_calc_value(sym);
switch (sym->type) {
@ -150,13 +149,14 @@ static int sym_get_range_val(struct symbol *sym, int base)
default:
break;
}
return strtol(sym->curr.val, NULL, base);
return strtoll(sym->curr.val, NULL, base);
}
static void sym_validate_range(struct symbol *sym)
{
struct property *prop;
int base, val, val2;
int base;
long long val, val2;
char str[64];
switch (sym->type) {
@ -172,7 +172,7 @@ static void sym_validate_range(struct symbol *sym)
prop = sym_get_range_prop(sym);
if (!prop)
return;
val = strtol(sym->curr.val, NULL, base);
val = strtoll(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);
@ -180,12 +180,32 @@ static void sym_validate_range(struct symbol *sym)
return;
}
if (sym->type == S_INT)
sprintf(str, "%d", val2);
sprintf(str, "%lld", val2);
else
sprintf(str, "0x%x", val2);
sprintf(str, "0x%llx", val2);
sym->curr.val = strdup(str);
}
static 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;
}
}
static void sym_set_all_changed(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
sym_set_changed(sym);
}
static void sym_calc_visibility(struct symbol *sym)
{
struct property *prop;
@ -263,11 +283,18 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
struct symbol *def_sym;
struct property *prop;
struct expr *e;
int flags;
/* first calculate all choice values' visibilities */
flags = sym->flags;
prop = sym_get_choice_prop(sym);
expr_list_for_each_sym(prop->expr, e, def_sym)
expr_list_for_each_sym(prop->expr, e, def_sym) {
sym_calc_visibility(def_sym);
if (def_sym->visible != no)
flags &= def_sym->flags;
}
sym->flags &= flags | ~SYMBOL_DEF_USER;
/* is the user choice visible? */
def_sym = sym->def[S_DEF_USER].val;
@ -294,6 +321,14 @@ void sym_calc_value(struct symbol *sym)
if (sym->flags & SYMBOL_VALID)
return;
if (sym_is_choice_value(sym) &&
sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES) {
sym->flags &= ~SYMBOL_NEED_SET_CHOICE_VALUES;
prop = sym_get_choice_prop(sym);
sym_calc_value(prop_get_symbol(prop));
}
sym->flags |= SYMBOL_VALID;
oldval = sym->curr;
@ -419,6 +454,9 @@ void sym_calc_value(struct symbol *sym)
if (sym->flags & SYMBOL_AUTO)
sym->flags &= ~SYMBOL_WRITE;
if (sym->flags & SYMBOL_NEED_SET_CHOICE_VALUES)
set_all_choice_values(sym);
}
void sym_clear_all_valid(void)
@ -429,28 +467,7 @@ void sym_clear_all_valid(void)
for_all_symbols(i, sym)
sym->flags &= ~SYMBOL_VALID;
sym_add_change_count(1);
if (modules_sym)
sym_calc_value(modules_sym);
}
void sym_set_changed(struct symbol *sym)
{
struct property *prop;
sym->flags |= SYMBOL_CHANGED;
for (prop = sym->prop; prop; prop = prop->next) {
if (prop->menu)
prop->menu->flags |= MENU_CHANGED;
}
}
void sym_set_all_changed(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
sym_set_changed(sym);
sym_calc_value(modules_sym);
}
bool sym_tristate_within_range(struct symbol *sym, tristate val)
@ -577,7 +594,7 @@ bool sym_string_valid(struct symbol *sym, const char *str)
bool sym_string_within_range(struct symbol *sym, const char *str)
{
struct property *prop;
int val;
long long val;
switch (sym->type) {
case S_STRING:
@ -588,7 +605,7 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
prop = sym_get_range_prop(sym);
if (!prop)
return true;
val = strtol(str, NULL, 10);
val = strtoll(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:
@ -597,7 +614,7 @@ bool sym_string_within_range(struct symbol *sym, const char *str)
prop = sym_get_range_prop(sym);
if (!prop)
return true;
val = strtol(str, NULL, 16);
val = strtoll(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:
@ -650,11 +667,11 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
size = strlen(newval) + 1;
if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
size += 2;
sym->def[S_DEF_USER].val = val = malloc(size);
sym->def[S_DEF_USER].val = val = xmalloc(size);
*val++ = '0';
*val++ = 'x';
} else if (!oldval || strcmp(oldval, newval))
sym->def[S_DEF_USER].val = val = malloc(size);
sym->def[S_DEF_USER].val = val = xmalloc(size);
else
return true;
@ -751,7 +768,8 @@ const char *sym_get_string_value(struct symbol *sym)
case no:
return "n";
case mod:
return "m";
sym_calc_value(modules_sym);
return (modules_sym->curr.tri == no) ? "n" : "m";
case yes:
return "y";
}
@ -805,7 +823,7 @@ struct symbol *sym_lookup(const char *name, int flags)
hash = 0;
}
symbol = malloc(sizeof(*symbol));
symbol = xmalloc(sizeof(*symbol));
memset(symbol, 0, sizeof(*symbol));
symbol->name = new_name;
symbol->type = S_UNKNOWN;
@ -856,7 +874,7 @@ const char *sym_expand_string_value(const char *in)
size_t reslen;
reslen = strlen(in) + 1;
res = malloc(reslen);
res = xmalloc(reslen);
res[0] = '\0';
while ((src = strchr(in, '$'))) {
@ -893,38 +911,132 @@ const char *sym_expand_string_value(const char *in)
return res;
}
const char *sym_escape_string_value(const char *in)
{
const char *p;
size_t reslen;
char *res;
size_t l;
reslen = strlen(in) + strlen("\"\"") + 1;
p = in;
for (;;) {
l = strcspn(p, "\"\\");
p += l;
if (p[0] == '\0')
break;
reslen++;
p++;
}
res = xmalloc(reslen);
res[0] = '\0';
strcat(res, "\"");
p = in;
for (;;) {
l = strcspn(p, "\"\\");
strncat(res, p, l);
p += l;
if (p[0] == '\0')
break;
strcat(res, "\\");
strncat(res, p++, 1);
}
strcat(res, "\"");
return res;
}
struct sym_match {
struct symbol *sym;
off_t so, eo;
};
/* Compare matched symbols as thus:
* - first, symbols that match exactly
* - then, alphabetical sort
*/
static int sym_rel_comp(const void *sym1, const void *sym2)
{
const struct sym_match *s1 = sym1;
const struct sym_match *s2 = sym2;
int exact1, exact2;
/* Exact match:
* - if matched length on symbol s1 is the length of that symbol,
* then this symbol should come first;
* - if matched length on symbol s2 is the length of that symbol,
* then this symbol should come first.
* Note: since the search can be a regexp, both symbols may match
* exactly; if this is the case, we can't decide which comes first,
* and we fallback to sorting alphabetically.
*/
exact1 = (s1->eo - s1->so) == strlen(s1->sym->name);
exact2 = (s2->eo - s2->so) == strlen(s2->sym->name);
if (exact1 && !exact2)
return -1;
if (!exact1 && exact2)
return 1;
/* As a fallback, sort symbols alphabetically */
return strcmp(s1->sym->name, s2->sym->name);
}
struct symbol **sym_re_search(const char *pattern)
{
struct symbol *sym, **sym_arr = NULL;
struct sym_match *sym_match_arr = NULL;
int i, cnt, size;
regex_t re;
regmatch_t match[1];
cnt = size = 0;
/* Skip if empty */
if (strlen(pattern) == 0)
return NULL;
if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
if (regcomp(&re, pattern, REG_EXTENDED|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))
if (regexec(&re, sym->name, 1, match, 0))
continue;
if (cnt + 1 >= size) {
void *tmp = sym_arr;
if (cnt >= size) {
void *tmp;
size += 16;
sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
if (!sym_arr) {
free(tmp);
return NULL;
}
tmp = realloc(sym_match_arr, size * sizeof(struct sym_match));
if (!tmp)
goto sym_re_search_free;
sym_match_arr = tmp;
}
sym_calc_value(sym);
sym_arr[cnt++] = sym;
/* As regexec returned 0, we know we have a match, so
* we can use match[0].rm_[se]o without further checks
*/
sym_match_arr[cnt].so = match[0].rm_so;
sym_match_arr[cnt].eo = match[0].rm_eo;
sym_match_arr[cnt++].sym = sym;
}
if (sym_arr)
if (sym_match_arr) {
qsort(sym_match_arr, cnt, sizeof(struct sym_match), sym_rel_comp);
sym_arr = malloc((cnt+1) * sizeof(struct symbol));
if (!sym_arr)
goto sym_re_search_free;
for (i = 0; i < cnt; i++)
sym_arr[i] = sym_match_arr[i].sym;
sym_arr[cnt] = NULL;
}
sym_re_search_free:
/* sym_match_arr can be NULL if no match, but free(NULL) is OK */
free(sym_match_arr);
regfree(&re);
return sym_arr;
@ -934,7 +1046,7 @@ struct symbol **sym_re_search(const char *pattern)
* When we check for recursive dependencies we use a stack to save
* current state so we can print out relevant info to user.
* The entries are located on the call stack so no need to free memory.
* Note inser() remove() must always match to properly clear the stack.
* Note insert() remove() must always match to properly clear the stack.
*/
static struct dep_stack {
struct dep_stack *prev, *next;
@ -1004,6 +1116,8 @@ static void sym_check_print_recursive(struct symbol *last_sym)
if (stack->sym == last_sym)
fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
prop->file->name, prop->lineno);
fprintf(stderr, "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n");
fprintf(stderr, "subsection \"Kconfig recursive dependency limitations\"\n");
if (stack->expr) {
fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
prop->file->name, prop->lineno,
@ -1053,6 +1167,10 @@ static struct symbol *sym_check_expr_deps(struct expr *e)
case E_NOT:
return sym_check_expr_deps(e->left.expr);
case E_EQUAL:
case E_GEQ:
case E_GTH:
case E_LEQ:
case E_LTH:
case E_UNEQUAL:
sym = sym_check_deps(e->left.sym);
if (sym)
@ -1178,7 +1296,7 @@ struct property *prop_alloc(enum prop_type type, struct symbol *sym)
struct property *prop;
struct property **propp;
prop = malloc(sizeof(*prop));
prop = xmalloc(sizeof(*prop));
memset(prop, 0, sizeof(*prop));
prop->type = type;
prop->sym = sym;
@ -1255,4 +1373,6 @@ static void prop_add_env(const char *env)
p = getenv(env);
if (p)
sym_add_default(sym, p);
else
menu_warn(current_entry, "environment variable %s undefined", env);
}

View File

@ -5,6 +5,8 @@
* Released under the terms of the GNU GPL v2.0.
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "lkc.h"
@ -21,7 +23,7 @@ struct file *file_lookup(const char *name)
}
}
file = malloc(sizeof(*file));
file = xmalloc(sizeof(*file));
memset(file, 0, sizeof(*file));
file->name = file_name;
file->next = file_list;
@ -79,23 +81,13 @@ int file_write_dep(const char *name)
struct gstr str_new(void)
{
struct gstr gs;
gs.s = malloc(sizeof(char) * 64);
gs.s = xmalloc(sizeof(char) * 64);
gs.len = 64;
gs.max_width = 0;
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;
gs.max_width = 0;
return gs;
}
/* Free storage for growable string */
void str_free(struct gstr *gs)
{
@ -136,3 +128,20 @@ const char *str_get(struct gstr *gs)
return gs->s;
}
void *xmalloc(size_t size)
{
void *p = malloc(size);
if (p)
return p;
fprintf(stderr, "Out of memory.\n");
exit(1);
}
void *xcalloc(size_t nmemb, size_t size)
{
void *p = calloc(nmemb, size);
if (p)
return p;
fprintf(stderr, "Out of memory.\n");
exit(1);
}

View File

@ -7,18 +7,9 @@
%pic
%struct-type
%{
# ifndef offsetof
# include <stddef.h>
# ifndef offsetof
# define offsetof(st, m) ((size_t)(&((st *)0)->m))
# endif
# endif
%}
struct kconf_id;
static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
static const struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
%%
mainmenu, T_MAINMENU, TF_COMMAND
@ -31,6 +22,7 @@ comment, T_COMMENT, TF_COMMAND
config, T_CONFIG, TF_COMMAND
menuconfig, T_MENUCONFIG, TF_COMMAND
help, T_HELP, TF_COMMAND
---help---, T_HELP, TF_COMMAND
if, T_IF, TF_COMMAND|TF_PARAM
endif, T_ENDIF, TF_COMMAND
depends, T_DEPENDS, TF_COMMAND
@ -53,4 +45,5 @@ on, T_ON, TF_PARAM
modules, T_OPT_MODULES, TF_OPTION
defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION
env, T_OPT_ENV, TF_OPTION
allnoconfig_y, T_OPT_ALLNOCONFIG_Y,TF_OPTION
%%

View File

@ -1,5 +1,5 @@
%option backup nostdinit noyywrap never-interactive full ecs
%option 8bit backup nodefault perf-report perf-report
%option nostdinit noyywrap never-interactive full ecs
%option 8bit nodefault perf-report perf-report
%option noinput
%x COMMAND HELP STRING PARAM
%{
@ -14,7 +14,6 @@
#include <string.h>
#include <unistd.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
#define START_STRSIZE 16
@ -28,8 +27,8 @@ static char *text;
static int text_size, text_asize;
struct buffer {
struct buffer *parent;
YY_BUFFER_STATE state;
struct buffer *parent;
YY_BUFFER_STATE state;
};
struct buffer *current_buf;
@ -41,7 +40,7 @@ static void zconf_endfile(void);
static void new_string(void)
{
text = malloc(START_STRSIZE);
text = xmalloc(START_STRSIZE);
text_asize = START_STRSIZE;
text_size = 0;
*text = 0;
@ -63,14 +62,20 @@ static void append_string(const char *str, int size)
static void alloc_string(const char *str, int size)
{
text = malloc(size + 1);
text = xmalloc(size + 1);
memcpy(text, str, size);
text[size] = 0;
}
static void warn_ignored_character(char chr)
{
fprintf(stderr,
"%s:%d:warning: ignoring unsupported character '%c'\n",
zconf_curname(), zconf_lineno(), chr);
}
%}
ws [ \n\t]
n [A-Za-z0-9_]
n [A-Za-z0-9_-]
%%
int str = 0;
@ -96,7 +101,7 @@ n [A-Za-z0-9_]
<COMMAND>{
{n}+ {
struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
BEGIN(PARAM);
current_pos.file = current_file;
current_pos.lineno = current_file->lineno;
@ -108,7 +113,7 @@ n [A-Za-z0-9_]
zconflval.string = text;
return T_WORD;
}
.
. warn_ignored_character(*yytext);
\n {
BEGIN(INITIAL);
current_file->lineno++;
@ -124,15 +129,18 @@ n [A-Za-z0-9_]
"!" return T_NOT;
"=" return T_EQUAL;
"!=" return T_UNEQUAL;
"<=" return T_LESS_EQUAL;
">=" return T_GREATER_EQUAL;
"<" return T_LESS;
">" return T_GREATER;
\"|\' {
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);
({n}|[/.])+ {
const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
if (id && id->flags & TF_PARAM) {
zconflval.id = id;
return id->token;
@ -143,7 +151,8 @@ n [A-Za-z0-9_]
}
#.* /* comment */
\\\n current_file->lineno++;
.
[[:blank:]]+
. warn_ignored_character(*yytext);
<<EOF>> {
BEGIN(INITIAL);
}
@ -289,7 +298,7 @@ void zconf_initscan(const char *name)
exit(1);
}
current_buf = malloc(sizeof(*current_buf));
current_buf = xmalloc(sizeof(*current_buf));
memset(current_buf, 0, sizeof(*current_buf));
current_file = file_lookup(name);
@ -300,7 +309,7 @@ void zconf_nextfile(const char *name)
{
struct file *iter;
struct file *file = file_lookup(name);
struct buffer *buf = malloc(sizeof(*buf));
struct buffer *buf = xmalloc(sizeof(*buf));
memset(buf, 0, sizeof(*buf));
current_buf->state = YY_CURRENT_BUFFER;

View File

@ -11,7 +11,6 @@
#include <string.h>
#include <stdbool.h>
#define LKC_DIRECT_LINK
#include "lkc.h"
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
@ -25,16 +24,12 @@ 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);
static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken);
struct symbol *symbol_hash[SYMBOL_HASHSIZE];
static struct menu *current_menu, *current_entry;
#define YYDEBUG 0
#if YYDEBUG
#define YYERROR_VERBOSE
#endif
%}
%expect 30
@ -45,7 +40,7 @@ static struct menu *current_menu, *current_entry;
struct symbol *symbol;
struct expr *expr;
struct menu *menu;
struct kconf_id *id;
const struct kconf_id *id;
}
%token <id>T_MAINMENU
@ -74,6 +69,10 @@ static struct menu *current_menu, *current_entry;
%token <string> T_WORD
%token <string> T_WORD_QUOTE
%token T_UNEQUAL
%token T_LESS
%token T_LESS_EQUAL
%token T_GREATER
%token T_GREATER_EQUAL
%token T_CLOSE_PAREN
%token T_OPEN_PAREN
%token T_EOL
@ -81,6 +80,7 @@ static struct menu *current_menu, *current_entry;
%left T_OR
%left T_AND
%left T_EQUAL T_UNEQUAL
%left T_LESS T_LESS_EQUAL T_GREATER T_GREATER_EQUAL
%nonassoc T_NOT
%type <string> prompt
@ -229,7 +229,7 @@ symbol_option_list:
/* empty */
| symbol_option_list T_WORD symbol_option_arg
{
struct kconf_id *id = kconf_id_lookup($2, strlen($2));
const struct kconf_id *id = kconf_id_lookup($2, strlen($2));
if (id && id->flags & TF_OPTION)
menu_add_option(id->token, $3);
else
@ -472,6 +472,10 @@ if_expr: /* empty */ { $$ = NULL; }
;
expr: symbol { $$ = expr_alloc_symbol($1); }
| symbol T_LESS symbol { $$ = expr_alloc_comp(E_LTH, $1, $3); }
| symbol T_LESS_EQUAL symbol { $$ = expr_alloc_comp(E_LEQ, $1, $3); }
| symbol T_GREATER symbol { $$ = expr_alloc_comp(E_GTH, $1, $3); }
| symbol T_GREATER_EQUAL symbol { $$ = expr_alloc_comp(E_GEQ, $1, $3); }
| 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; }
@ -498,10 +502,7 @@ void conf_parse(const char *name)
sym_init();
_menu_init();
modules_sym = sym_lookup(NULL, 0);
modules_sym->type = S_BOOLEAN;
modules_sym->flags |= SYMBOL_AUTO;
rootmenu.prompt = menu_add_prompt(P_MENU, PACKAGE " Configuration", NULL);
rootmenu.prompt = menu_add_prompt(P_MENU, "Crosstool-NG Configuration", NULL);
#if YYDEBUG
if (getenv("ZCONF_DEBUG"))
@ -510,12 +511,8 @@ void conf_parse(const char *name)
zconfparse();
if (zconfnerrs)
exit(1);
if (!modules_sym->prop) {
struct property *prop;
prop = prop_alloc(P_DEFAULT, modules_sym);
prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
}
if (!modules_sym)
modules_sym = sym_find( "n" );
rootmenu.prompt->text = _(rootmenu.prompt->text);
rootmenu.prompt->text = sym_expand_string_value(rootmenu.prompt->text);
@ -524,7 +521,7 @@ void conf_parse(const char *name)
for_all_symbols(i, sym) {
if (sym_check_deps(sym))
zconfnerrs++;
}
}
if (zconfnerrs)
exit(1);
sym_set_change_count(1);
@ -545,7 +542,7 @@ static const char *zconf_tokenname(int token)
return "<token>";
}
static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
static bool zconf_endtoken(const struct kconf_id *id, int starttoken, int endtoken)
{
if (id->token != endtoken) {
zconf_error("unexpected '%s' within %s block",
@ -590,9 +587,7 @@ static void zconf_error(const char *err, ...)
static void zconferror(const char *err)
{
#if YYDEBUG
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
#endif
}
static void print_quoted_string(FILE *out, const char *str)
@ -741,7 +736,7 @@ void zconfdump(FILE *out)
}
}
#include "lex.zconf.c"
#include "zconf.lex.c"
#include "util.c"
#include "confdata.c"
#include "expr.c"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
r10231 | lethal | 2005-05-02 09:58:00 -0400 (Mon, 02 May 2005) | 13 lines
Likewise, binutils has no idea about any of these new targets either, so we
fix that up too.. now we're able to actually build a real toolchain for
sh2a_nofpu- and other more ineptly named toolchains (and yes, there are more
inept targets than that one, really. Go look, I promise).
diff --git a/configure b/configure
index 87677bc..2d916f1 100755
--- a/configure
+++ b/configure
@@ -3812,7 +3812,7 @@ case "${target}" in
or1k*-*-*)
noconfigdirs="$noconfigdirs gdb"
;;
- sh-*-* | sh64-*-*)
+ sh*-*-* | sh64-*-*)
case "${target}" in
sh*-*-elf)
;;
diff --git a/configure.ac b/configure.ac
index 8fe0eca..b10a99f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1140,7 +1140,7 @@ case "${target}" in
or1k*-*-*)
noconfigdirs="$noconfigdirs gdb"
;;
- sh-*-* | sh64-*-*)
+ sh*-*-* | sh64-*-*)
case "${target}" in
sh*-*-elf)
;;

View File

@ -0,0 +1,26 @@
diff --git a/ld/Makefile.am b/ld/Makefile.am
index 9575f1f..84df0bf 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -54,7 +54,7 @@ endif
# We put the scripts in the directory $(scriptdir)/ldscripts.
# We can't put the scripts in $(datadir) because the SEARCH_DIR
# directives need to be different for native and cross linkers.
-scriptdir = $(tooldir)/lib
+scriptdir = $(libdir)
EMUL = @EMUL@
EMULATION_OFILES = @EMULATION_OFILES@
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 9f56ca1..272860f 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -388,7 +388,7 @@ AM_CFLAGS = $(WARN_CFLAGS)
# We put the scripts in the directory $(scriptdir)/ldscripts.
# We can't put the scripts in $(datadir) because the SEARCH_DIR
# directives need to be different for native and cross linkers.
-scriptdir = $(tooldir)/lib
+scriptdir = $(libdir)
BASEDIR = $(srcdir)/..
BFDDIR = $(BASEDIR)/bfd
INCDIR = $(BASEDIR)/include

View File

@ -0,0 +1,22 @@
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 137446f..bb8391a 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1195,6 +1195,8 @@ fragment <<EOF
&& command_line.rpath == NULL)
{
lib_path = (const char *) getenv ("LD_RUN_PATH");
+ if ((lib_path) && (strlen (lib_path) == 0))
+ lib_path = NULL;
if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
force))
break;
@@ -1458,6 +1460,8 @@ gld${EMULATION_NAME}_before_allocation (void)
rpath = command_line.rpath;
if (rpath == NULL)
rpath = (const char *) getenv ("LD_RUN_PATH");
+ if ((rpath) && (*rpath == '\0'))
+ rpath = NULL;
for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)

View File

@ -0,0 +1,14 @@
--- binutils-2.25.1/gold/gold-threads.cc.orig 2014-10-14 08:32:04.000000000 +0100
+++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:38:18.640819300 +0100
@@ -102,9 +102,9 @@
if (err != 0)
gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err));
#ifdef PTHREAD_MUTEX_ADAPTIVE_NP
- err = pthread_mutextattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
+ err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
if (err != 0)
- gold_fatal(_("pthread_mutextattr_settype failed: %s"), strerror(err));
+ gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err));
#endif
err = pthread_mutex_init(&this->mutex_, &attr);

View File

@ -0,0 +1,11 @@
--- binutils-2.25.1/gold/gold-threads.cc.orig 2015-10-20 22:39:36.371169400 +0100
+++ binutils-2.25.1/gold/gold-threads.cc 2015-10-20 22:39:38.182772700 +0100
@@ -101,7 +101,7 @@
int err = pthread_mutexattr_init(&attr);
if (err != 0)
gold_fatal(_("pthead_mutextattr_init failed: %s"), strerror(err));
-#ifdef PTHREAD_MUTEX_ADAPTIVE_NP
+#if defined(PTHREAD_MUTEX_ADAPTIVE_NP) && !defined(_WIN32)
err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
if (err != 0)
gold_fatal(_("pthread_mutexattr_settype failed: %s"), strerror(err));

View File

@ -0,0 +1,102 @@
diff -urN binutils-2.25.1.orig/binutils/configure binutils-2.25.1/binutils/configure
--- binutils-2.25.1.orig/binutils/configure 2015-10-25 13:18:46.249052806 +0000
+++ binutils-2.25.1/binutils/configure 2015-10-25 13:39:21.339034801 +0000
@@ -12067,6 +12067,7 @@
done
test -n "$YACC" || YACC="yacc"
+save_LIBS=$LIBS
for ac_prog in flex lex
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
@@ -12227,6 +12228,8 @@
if test "$LEX" = :; then
LEX=${am_missing_run}flex
fi
+LIBS=$save_LIBS
+LEXLIB=
ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr"
# If we haven't got the data from the intl directory,
diff -urN binutils-2.25.1.orig/binutils/configure.ac binutils-2.25.1/binutils/configure.ac
--- binutils-2.25.1.orig/binutils/configure.ac 2015-10-25 13:18:46.249052806 +0000
+++ binutils-2.25.1/binutils/configure.ac 2015-10-25 13:38:52.969035216 +0000
@@ -87,7 +87,10 @@
fi
AC_PROG_YACC
+save_LIBS=$LIBS
AM_PROG_LEX
+LIBS=$save_LIBS
+LEXLIB=
ALL_LINGUAS="bg da es fi fr id it ja ro ru rw sk sv tr uk vi zh_CN zh_TW hr"
ZW_GNU_GETTEXT_SISTER_DIR
diff -urN binutils-2.25.1.orig/gas/configure binutils-2.25.1/gas/configure
--- binutils-2.25.1.orig/gas/configure 2015-10-25 13:18:46.389052803 +0000
+++ binutils-2.25.1/gas/configure 2015-10-25 15:16:55.988949456 +0000
@@ -12795,6 +12795,7 @@
done
test -n "$YACC" || YACC="yacc"
+save_LIBS=$LIBS
for ac_prog in flex lex
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
@@ -12955,6 +12956,8 @@
if test "$LEX" = :; then
LEX=${am_missing_run}flex
fi
+LIBS=$save_LIBS
+LEXLIB=
ALL_LINGUAS="fr tr es rw id ru fi ja"
# If we haven't got the data from the intl directory,
diff -urN binutils-2.25.1.orig/gas/configure.ac binutils-2.25.1/gas/configure.ac
--- binutils-2.25.1.orig/gas/configure.ac 2015-10-25 15:15:06.000000000 +0000
+++ binutils-2.25.1/gas/configure.ac 2015-10-25 14:45:32.000000000 +0000
@@ -717,7 +717,10 @@
AC_DEFINE_UNQUOTED(TARGET_OS, "${target_os}", [Target OS.])
AC_PROG_YACC
+save_LIBS=$LIBS
AM_PROG_LEX
+LIBS=$save_LIBS
+LEXLIB=
ALL_LINGUAS="fr tr es rw id ru fi ja"
ZW_GNU_GETTEXT_SISTER_DIR
diff -urN binutils-2.25.1.orig/ld/configure binutils-2.25.1/ld/configure
--- binutils-2.25.1.orig/ld/configure 2015-10-25 13:18:47.399052788 +0000
+++ binutils-2.25.1/ld/configure 2015-10-25 15:17:06.472282637 +0000
@@ -16071,6 +16071,7 @@
done
test -n "$YACC" || YACC="yacc"
+save_LIBS=$LIBS
for ac_prog in flex lex
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
@@ -16231,6 +16232,8 @@
if test "$LEX" = :; then
LEX=${am_missing_run}flex
fi
+LIBS=$save_LIBS
+LEXLIB=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
diff -urN binutils-2.25.1.orig/ld/configure.ac binutils-2.25.1/ld/configure.ac
--- binutils-2.25.1.orig/ld/configure.ac 2015-10-25 13:18:47.415719456 +0000
+++ binutils-2.25.1/ld/configure.ac 2015-10-25 15:14:43.000000000 +0000
@@ -173,7 +173,10 @@
AC_EXEEXT
AC_PROG_YACC
+save_LIBS=$LIBS
AM_PROG_LEX
+LIBS=$save_LIBS
+LEXLIB=
AM_MAINTAINER_MODE
AM_CONDITIONAL(GENINSRC_NEVER, false)

View File

@ -0,0 +1,90 @@
From 415480d6471e67aef97c0241d451ef2423a1da9d Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Tue, 25 Nov 2014 21:33:21 +0300
Subject: [PATCH] Fix trampolines search code for conditional branches
For conditional branches that need more than one trampoline to reach its
target assembler couldn't always find suitable trampoline because
post-loop condition check was placed inside the loop, resulting in
premature loop termination. Move check outside the loop.
This fixes the following build errors seen when assembling huge files
produced by gcc:
Error: jump target out of range; no usable trampoline found
Error: operand 1 of 'j' has out of range value '307307'
2014-11-25 Max Filippov <jcmvbkbc@gmail.com>
gas/
* config/tc-xtensa.c (search_trampolines): Move post-loop
condition check outside the search loop.
gas/testsuite/
* gas/xtensa/trampoline.d: Add expected output for branches.
* gas/xtensa/trampoline.s: Add test case for branches.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Backported from: d92b6eece424f0ad35d96fdd85bf207295e8c4c3
Changes to ChangeLogs are dropped.
gas/config/tc-xtensa.c | 8 ++++----
gas/testsuite/gas/xtensa/trampoline.d | 9 +++++++++
gas/testsuite/gas/xtensa/trampoline.s | 7 +++++++
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
index d11b0c7..f23ccf8 100644
--- a/gas/config/tc-xtensa.c
+++ b/gas/config/tc-xtensa.c
@@ -9514,11 +9514,11 @@ search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only)
if (next_addr == 0 || addr - next_addr > J_RANGE)
break;
}
- if (abs (addr - this_addr) < J_RANGE)
- return tf;
-
- return NULL;
}
+ if (abs (addr - this_addr) < J_RANGE)
+ return tf;
+
+ return NULL;
}
for ( ; tf; tf = tf->next)
{
diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d
index b4f65dc..5ae32a6 100644
--- a/gas/testsuite/gas/xtensa/trampoline.d
+++ b/gas/testsuite/gas/xtensa/trampoline.d
@@ -24,3 +24,12 @@
.*33462:.*j.0x49407
#...
.*49407:.*j.0x49407
+.*4940a:.*beqz.n.a2,.0x4940f
+.*4940c:.*j.0x693d1
+#...
+.*693d1:.*j.0x7ddd4
+#...
+.*7ddd4:.*j.0x927f5
+#...
+.*927f5:.*j.0x927f5
+#...
diff --git a/gas/testsuite/gas/xtensa/trampoline.s b/gas/testsuite/gas/xtensa/trampoline.s
index 259a3bb..4465786 100644
--- a/gas/testsuite/gas/xtensa/trampoline.s
+++ b/gas/testsuite/gas/xtensa/trampoline.s
@@ -19,3 +19,10 @@
.endr
3:
j 3b
+ bnez a2, 4f
+ .rep 50000
+ and a2, a2, a3
+ _ret
+ .endr
+4:
+ j 4b
--
1.8.1.4

View File

@ -0,0 +1,502 @@
From 20c79baf82273a0b368587f761f152c4d3a593a4 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Fri, 27 Mar 2015 07:13:55 +0300
Subject: [PATCH 1/4] xtensa: optimize check_section_ebb_pcrels_fit
The original check_section_ebb_pcrels_fit algorithm checks that text
actions proposed for current EBB are OK for every relocation in a
section. There's no need to check every relocation, because text actions
for EBB can only change size of that EBB, thus only affecting
relocations that in any way cross that EBB. In addition EBBs are
iterated in ascending order of their VMA, making it easier to track
relevant relocations.
Introduce a structure that can track relocations that cross the range of
VMAs of EBB and use it to only check relocations relevant to current EBB
in check_section_ebb_pcrels_fit.
It takes O(N log N) operations to build it and O(N) operations to move
current EBB VMA window through its entire range, where N is the number
of relocations in a section. The resulting complexity of
compute_text_actions is thus reduced from O(N^2) to O(N log N + N * M),
where M is the average number of relocations crossing each EBB.
Original profile:
% time self children called name
-----------------------------------------
44.26 71.53 6429/6429 compute_text_actions
50.2 44.26 71.53 6429 check_section_ebb_pcrels_fit
1.16 20.12 347506666/347576152 pcrel_reloc_fits
2.95 16.52 347506666/348104944 get_relocation_opnd
2.01 9.74 347575100/361252208 r_reloc_init
0.55 7.53 347575100/363381467 r_reloc_get_section
5.76 0.02 695013332/695013332 xlate_offset_with_removed_text
0.68 3.89 347575100/363483827 bfd_octets_per_byte
0.32 0.00 347506666/349910253 is_alt_relocation
0.18 0.11 6391/6391 build_xlate_map
0.00 0.00 6429/19417168 get_xtensa_relax_info
0.00 0.00 6391/6391 free_xlate_map
-----------------------------------------
Same data, after optimization:
% time self children called name
-----------------------------------------
2.56 3.08 6429/6429 compute_text_actions
8.2 2.56 3.08 6429 check_section_ebb_pcrels_fit
0.08 0.91 17721075/17790561 pcrel_reloc_fits
0.17 0.47 17721075/31685977 r_reloc_init
0.43 0.00 35442150/35442150 xlate_offset_with_removed_text
0.02 0.37 17721075/33815236 r_reloc_get_section
0.22 0.11 6391/6391 build_xlate_map
0.05 0.22 17721075/33917596 bfd_octets_per_byte
0.03 0.00 17721075/20405299 is_alt_relocation
0.01 0.00 6429/6429 reloc_range_list_update_range
0.00 0.00 6429/19417168 get_xtensa_relax_info
0.00 0.00 6391/6391 free_xlate_map
-----------------------------------------
2015-04-01 Max Filippov <jcmvbkbc@gmail.com>
bfd/
* elf32-xtensa.c (reloc_range_list, reloc_range_list_entry,
reloc_range): new typedef.
(reloc_range_list_struct, reloc_range_list_entry_struct,
reloc_range_struct): new structures.
(reloc_range_compare, build_reloc_ranges,
reloc_range_list_append, reloc_range_list_remove,
reloc_range_list_update_range, free_reloc_range_list): new
functions.
(compute_text_actions): precompute relocation opcodes before the
loop. Add relevant_relocs variable, initialize it before the
loop, pass it to the check_section_ebb_pcrels_fit.
(check_section_ebb_pcrels_fit): add new parameter:
relevant_relocs. Update address range in the relevant_relocs if
it's non-NULL and iterate only over relevant relocations.
Backported from: b2b326d246f839ee218192ac88da2384d929a072
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
bfd/elf32-xtensa.c | 321 +++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 298 insertions(+), 23 deletions(-)
diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
index 0b6f584..872370b 100644
--- a/bfd/elf32-xtensa.c
+++ b/bfd/elf32-xtensa.c
@@ -6619,8 +6619,10 @@ static bfd_boolean compute_text_actions
(bfd *, asection *, struct bfd_link_info *);
static bfd_boolean compute_ebb_proposed_actions (ebb_constraint *);
static bfd_boolean compute_ebb_actions (ebb_constraint *);
+typedef struct reloc_range_list_struct reloc_range_list;
static bfd_boolean check_section_ebb_pcrels_fit
- (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, const ebb_constraint *,
+ (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *,
+ reloc_range_list *, const ebb_constraint *,
const xtensa_opcode *);
static bfd_boolean check_section_ebb_reduces (const ebb_constraint *);
static void text_action_add_proposed
@@ -7219,6 +7221,221 @@ build_reloc_opcodes (bfd *abfd,
return reloc_opcodes;
}
+struct reloc_range_struct
+{
+ bfd_vma addr;
+ bfd_boolean add; /* TRUE if start of a range, FALSE otherwise. */
+ /* Original irel index in the array of relocations for a section. */
+ unsigned irel_index;
+};
+typedef struct reloc_range_struct reloc_range;
+
+typedef struct reloc_range_list_entry_struct reloc_range_list_entry;
+struct reloc_range_list_entry_struct
+{
+ reloc_range_list_entry *next;
+ reloc_range_list_entry *prev;
+ Elf_Internal_Rela *irel;
+ xtensa_opcode opcode;
+ int opnum;
+};
+
+struct reloc_range_list_struct
+{
+ /* The rest of the structure is only meaningful when ok is TRUE. */
+ bfd_boolean ok;
+
+ unsigned n_range; /* Number of range markers. */
+ reloc_range *range; /* Sorted range markers. */
+
+ unsigned first; /* Index of a first range element in the list. */
+ unsigned last; /* One past index of a last range element in the list. */
+
+ unsigned n_list; /* Number of list elements. */
+ reloc_range_list_entry *reloc; /* */
+ reloc_range_list_entry list_root;
+};
+
+static int
+reloc_range_compare (const void *a, const void *b)
+{
+ const reloc_range *ra = a;
+ const reloc_range *rb = b;
+
+ if (ra->addr != rb->addr)
+ return ra->addr < rb->addr ? -1 : 1;
+ if (ra->add != rb->add)
+ return ra->add ? -1 : 1;
+ return 0;
+}
+
+static void
+build_reloc_ranges (bfd *abfd, asection *sec,
+ bfd_byte *contents,
+ Elf_Internal_Rela *internal_relocs,
+ xtensa_opcode *reloc_opcodes,
+ reloc_range_list *list)
+{
+ unsigned i;
+ size_t n = 0;
+ size_t max_n = 0;
+ reloc_range *ranges = NULL;
+ reloc_range_list_entry *reloc =
+ bfd_malloc (sec->reloc_count * sizeof (*reloc));
+
+ memset (list, 0, sizeof (*list));
+ list->ok = TRUE;
+
+ for (i = 0; i < sec->reloc_count; i++)
+ {
+ Elf_Internal_Rela *irel = &internal_relocs[i];
+ int r_type = ELF32_R_TYPE (irel->r_info);
+ reloc_howto_type *howto = &elf_howto_table[r_type];
+ r_reloc r_rel;
+
+ if (r_type == R_XTENSA_ASM_SIMPLIFY
+ || r_type == R_XTENSA_32_PCREL
+ || !howto->pc_relative)
+ continue;
+
+ r_reloc_init (&r_rel, abfd, irel, contents,
+ bfd_get_section_limit (abfd, sec));
+
+ if (r_reloc_get_section (&r_rel) != sec)
+ continue;
+
+ if (n + 2 > max_n)
+ {
+ max_n = (max_n + 2) * 2;
+ ranges = bfd_realloc (ranges, max_n * sizeof (*ranges));
+ }
+
+ ranges[n].addr = irel->r_offset;
+ ranges[n + 1].addr = r_rel.target_offset;
+
+ ranges[n].add = ranges[n].addr < ranges[n + 1].addr;
+ ranges[n + 1].add = !ranges[n].add;
+
+ ranges[n].irel_index = i;
+ ranges[n + 1].irel_index = i;
+
+ n += 2;
+
+ reloc[i].irel = irel;
+
+ /* Every relocation won't possibly be checked in the optimized version of
+ check_section_ebb_pcrels_fit, so this needs to be done here. */
+ if (is_alt_relocation (ELF32_R_TYPE (irel->r_info)))
+ {
+ /* None of the current alternate relocs are PC-relative,
+ and only PC-relative relocs matter here. */
+ }
+ else
+ {
+ xtensa_opcode opcode;
+ int opnum;
+
+ if (reloc_opcodes)
+ opcode = reloc_opcodes[i];
+ else
+ opcode = get_relocation_opcode (abfd, sec, contents, irel);
+
+ if (opcode == XTENSA_UNDEFINED)
+ {
+ list->ok = FALSE;
+ break;
+ }
+
+ opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info));
+ if (opnum == XTENSA_UNDEFINED)
+ {
+ list->ok = FALSE;
+ break;
+ }
+
+ /* Record relocation opcode and opnum as we've calculated them
+ anyway and they won't change. */
+ reloc[i].opcode = opcode;
+ reloc[i].opnum = opnum;
+ }
+ }
+
+ if (list->ok)
+ {
+ ranges = bfd_realloc (ranges, n * sizeof (*ranges));
+ qsort (ranges, n, sizeof (*ranges), reloc_range_compare);
+
+ list->n_range = n;
+ list->range = ranges;
+ list->reloc = reloc;
+ list->list_root.prev = &list->list_root;
+ list->list_root.next = &list->list_root;
+ }
+ else
+ {
+ free (ranges);
+ free (reloc);
+ }
+}
+
+static void reloc_range_list_append (reloc_range_list *list,
+ unsigned irel_index)
+{
+ reloc_range_list_entry *entry = list->reloc + irel_index;
+
+ entry->prev = list->list_root.prev;
+ entry->next = &list->list_root;
+ entry->prev->next = entry;
+ entry->next->prev = entry;
+ ++list->n_list;
+}
+
+static void reloc_range_list_remove (reloc_range_list *list,
+ unsigned irel_index)
+{
+ reloc_range_list_entry *entry = list->reloc + irel_index;
+
+ entry->next->prev = entry->prev;
+ entry->prev->next = entry->next;
+ --list->n_list;
+}
+
+/* Update relocation list object so that it lists all relocations that cross
+ [first; last] range. Range bounds should not decrease with successive
+ invocations. */
+static void reloc_range_list_update_range (reloc_range_list *list,
+ bfd_vma first, bfd_vma last)
+{
+ /* This should not happen: EBBs are iterated from lower addresses to higher.
+ But even if that happens there's no need to break: just flush current list
+ and start from scratch. */
+ if ((list->last > 0 && list->range[list->last - 1].addr > last) ||
+ (list->first > 0 && list->range[list->first - 1].addr >= first))
+ {
+ list->first = 0;
+ list->last = 0;
+ list->n_list = 0;
+ list->list_root.next = &list->list_root;
+ list->list_root.prev = &list->list_root;
+ fprintf (stderr, "%s: move backwards requested\n", __func__);
+ }
+
+ for (; list->last < list->n_range &&
+ list->range[list->last].addr <= last; ++list->last)
+ if (list->range[list->last].add)
+ reloc_range_list_append (list, list->range[list->last].irel_index);
+
+ for (; list->first < list->n_range &&
+ list->range[list->first].addr < first; ++list->first)
+ if (!list->range[list->first].add)
+ reloc_range_list_remove (list, list->range[list->first].irel_index);
+}
+
+static void free_reloc_range_list (reloc_range_list *list)
+{
+ free (list->range);
+ free (list->reloc);
+}
/* The compute_text_actions function will build a list of potential
transformation actions for code in the extended basic block of each
@@ -7245,6 +7462,7 @@ compute_text_actions (bfd *abfd,
property_table_entry *prop_table = 0;
int ptblsize = 0;
bfd_size_type sec_size;
+ reloc_range_list relevant_relocs;
relax_info = get_xtensa_relax_info (sec);
BFD_ASSERT (relax_info);
@@ -7277,6 +7495,12 @@ compute_text_actions (bfd *abfd,
goto error_return;
}
+ /* Precompute the opcode for each relocation. */
+ reloc_opcodes = build_reloc_opcodes (abfd, sec, contents, internal_relocs);
+
+ build_reloc_ranges (abfd, sec, contents, internal_relocs, reloc_opcodes,
+ &relevant_relocs);
+
for (i = 0; i < sec->reloc_count; i++)
{
Elf_Internal_Rela *irel = &internal_relocs[i];
@@ -7340,17 +7564,13 @@ compute_text_actions (bfd *abfd,
ebb->start_reloc_idx = i;
ebb->end_reloc_idx = i;
- /* Precompute the opcode for each relocation. */
- if (reloc_opcodes == NULL)
- reloc_opcodes = build_reloc_opcodes (abfd, sec, contents,
- internal_relocs);
-
if (!extend_ebb_bounds (ebb)
|| !compute_ebb_proposed_actions (&ebb_table)
|| !compute_ebb_actions (&ebb_table)
|| !check_section_ebb_pcrels_fit (abfd, sec, contents,
- internal_relocs, &ebb_table,
- reloc_opcodes)
+ internal_relocs,
+ &relevant_relocs,
+ &ebb_table, reloc_opcodes)
|| !check_section_ebb_reduces (&ebb_table))
{
/* If anything goes wrong or we get unlucky and something does
@@ -7372,6 +7592,8 @@ compute_text_actions (bfd *abfd,
free_ebb_constraint (&ebb_table);
}
+ free_reloc_range_list (&relevant_relocs);
+
#if DEBUG
if (relax_info->action_list.head)
print_action_list (stderr, &relax_info->action_list);
@@ -7974,14 +8196,17 @@ check_section_ebb_pcrels_fit (bfd *abfd,
asection *sec,
bfd_byte *contents,
Elf_Internal_Rela *internal_relocs,
+ reloc_range_list *relevant_relocs,
const ebb_constraint *constraint,
const xtensa_opcode *reloc_opcodes)
{
unsigned i, j;
+ unsigned n = sec->reloc_count;
Elf_Internal_Rela *irel;
xlate_map_t *xmap = NULL;
bfd_boolean ok = TRUE;
xtensa_relax_info *relax_info;
+ reloc_range_list_entry *entry = NULL;
relax_info = get_xtensa_relax_info (sec);
@@ -7992,7 +8217,40 @@ check_section_ebb_pcrels_fit (bfd *abfd,
can still be used. */
}
- for (i = 0; i < sec->reloc_count; i++)
+ if (relevant_relocs && constraint->action_count)
+ {
+ if (!relevant_relocs->ok)
+ {
+ ok = FALSE;
+ n = 0;
+ }
+ else
+ {
+ bfd_vma min_offset, max_offset;
+ min_offset = max_offset = constraint->actions[0].offset;
+
+ for (i = 1; i < constraint->action_count; ++i)
+ {
+ proposed_action *action = &constraint->actions[i];
+ bfd_vma offset = action->offset;
+
+ if (offset < min_offset)
+ min_offset = offset;
+ if (offset > max_offset)
+ max_offset = offset;
+ }
+ reloc_range_list_update_range (relevant_relocs, min_offset,
+ max_offset);
+ n = relevant_relocs->n_list;
+ entry = &relevant_relocs->list_root;
+ }
+ }
+ else
+ {
+ relevant_relocs = NULL;
+ }
+
+ for (i = 0; i < n; i++)
{
r_reloc r_rel;
bfd_vma orig_self_offset, orig_target_offset;
@@ -8001,7 +8259,15 @@ check_section_ebb_pcrels_fit (bfd *abfd,
reloc_howto_type *howto;
int self_removed_bytes, target_removed_bytes;
- irel = &internal_relocs[i];
+ if (relevant_relocs)
+ {
+ entry = entry->next;
+ irel = entry->irel;
+ }
+ else
+ {
+ irel = internal_relocs + i;
+ }
r_type = ELF32_R_TYPE (irel->r_info);
howto = &elf_howto_table[r_type];
@@ -8067,21 +8333,30 @@ check_section_ebb_pcrels_fit (bfd *abfd,
xtensa_opcode opcode;
int opnum;
- if (reloc_opcodes)
- opcode = reloc_opcodes[i];
- else
- opcode = get_relocation_opcode (abfd, sec, contents, irel);
- if (opcode == XTENSA_UNDEFINED)
+ if (relevant_relocs)
{
- ok = FALSE;
- break;
+ opcode = entry->opcode;
+ opnum = entry->opnum;
}
-
- opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info));
- if (opnum == XTENSA_UNDEFINED)
+ else
{
- ok = FALSE;
- break;
+ if (reloc_opcodes)
+ opcode = reloc_opcodes[relevant_relocs ?
+ (unsigned)(entry - relevant_relocs->reloc) : i];
+ else
+ opcode = get_relocation_opcode (abfd, sec, contents, irel);
+ if (opcode == XTENSA_UNDEFINED)
+ {
+ ok = FALSE;
+ break;
+ }
+
+ opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info));
+ if (opnum == XTENSA_UNDEFINED)
+ {
+ ok = FALSE;
+ break;
+ }
}
if (!pcrel_reloc_fits (opcode, opnum, self_offset, target_offset))
@@ -8778,7 +9053,7 @@ move_shared_literal (asection *sec,
/* Check all of the PC-relative relocations to make sure they still fit. */
relocs_fit = check_section_ebb_pcrels_fit (target_sec->owner, target_sec,
target_sec_cache->contents,
- target_sec_cache->relocs,
+ target_sec_cache->relocs, NULL,
&ebb_table, NULL);
if (!relocs_fit)
--
1.8.1.4

View File

@ -0,0 +1,356 @@
From 3e3f60207399ab29dd55af109e5ae9facc7d8e83 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvbkbc@gmail.com>
Date: Sat, 28 Mar 2015 08:46:28 +0300
Subject: [PATCH 2/4] xtensa: optimize removed_by_actions
The function removed_by_actions iterates through text actions to
calculate an offset applied by text actions to a given VMA. Although it
has a parameter p_start_action that allows for incremental offset
calculation, in many places it's used with p_start_action explicitly set
to the first action. After the first relaxation pass when the list of
text actions is finalized, an array of offsets sorted by VMA may be used
to speed up this function.
Original profile:
% time self children called name
-----------------------------------------
0.35 0.00 33872/4808961 relax_section_symbols
3.32 0.00 326022/4808961 relax_property_section
12.83 0.00 1259379/4808961 offset_with_removed_text
32.50 0.00 3189688/4808961 translate_reloc
71.5 49.00 0.00 4808961 removed_by_actions
-----------------------------------------
Same data, after optimization:
% time self children called name
-----------------------------------------
0.00 0.00 33872/4808537 relax_section_symbols
0.01 0.00 326022/4808537 relax_property_section
0.05 0.00 1258955/4808537 offset_with_removed_text_map
0.13 0.00 3189688/4808537 translate_reloc
1.0 0.20 0.00 4808537 removed_by_actions_map
0.00 0.00 120/120 map_removal_by_action
-----------------------------------------
2015-04-01 Max Filippov <jcmvbkbc@gmail.com>
bfd/
* elf32-xtensa.c (removal_by_action_entry_struct,
removal_by_action_map_struct): new structures.
(removal_by_action_entry, removal_by_action_map): new typedefs.
(text_action_list_struct): add new field: map.
(map_removal_by_action, removed_by_actions_map,
offset_with_removed_text_map): new functions.
(relax_section): replace offset_with_removed_text with
offset_with_removed_text_map.
(translate_reloc, relax_property_section, relax_section_symbols):
replace removed_by_actions with removed_by_actions_map.
Backported from: 071aa5c98a31c966f5fbfc573fcee61350fd1936
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
bfd/elf32-xtensa.c | 181 +++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 156 insertions(+), 25 deletions(-)
diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
index 872370b..21b2871 100644
--- a/bfd/elf32-xtensa.c
+++ b/bfd/elf32-xtensa.c
@@ -5420,11 +5420,28 @@ struct text_action_struct
text_action *next;
};
+struct removal_by_action_entry_struct
+{
+ bfd_vma offset;
+ int removed;
+ int eq_removed;
+ int eq_removed_before_fill;
+};
+typedef struct removal_by_action_entry_struct removal_by_action_entry;
+
+struct removal_by_action_map_struct
+{
+ unsigned n_entries;
+ removal_by_action_entry *entry;
+};
+typedef struct removal_by_action_map_struct removal_by_action_map;
+
/* List of all of the actions taken on a text section. */
struct text_action_list_struct
{
text_action *head;
+ removal_by_action_map map;
};
@@ -5636,6 +5653,101 @@ action_list_count (text_action_list *action_list)
return count;
}
+static void
+map_removal_by_action (text_action_list *action_list)
+{
+ text_action *r;
+ int removed = 0;
+ removal_by_action_map map;
+ bfd_boolean eq_complete;
+
+ map.n_entries = 0;
+ map.entry = bfd_malloc (action_list_count (action_list) *
+ sizeof (removal_by_action_entry));
+ eq_complete = FALSE;
+
+ for (r = action_list->head; r;)
+ {
+ removal_by_action_entry *ientry = map.entry + map.n_entries;
+
+ if (map.n_entries && (ientry - 1)->offset == r->offset)
+ {
+ --ientry;
+ }
+ else
+ {
+ ++map.n_entries;
+ eq_complete = FALSE;
+ ientry->offset = r->offset;
+ ientry->eq_removed_before_fill = removed;
+ }
+
+ if (!eq_complete)
+ {
+ if (r->action != ta_fill || r->removed_bytes >= 0)
+ {
+ ientry->eq_removed = removed;
+ eq_complete = TRUE;
+ }
+ else
+ ientry->eq_removed = removed + r->removed_bytes;
+ }
+
+ removed += r->removed_bytes;
+ ientry->removed = removed;
+ r = r->next;
+ }
+ action_list->map = map;
+}
+
+static int
+removed_by_actions_map (text_action_list *action_list, bfd_vma offset,
+ bfd_boolean before_fill)
+{
+ unsigned a, b;
+
+ if (!action_list->map.entry)
+ map_removal_by_action (action_list);
+
+ if (!action_list->map.n_entries)
+ return 0;
+
+ a = 0;
+ b = action_list->map.n_entries;
+
+ while (b - a > 1)
+ {
+ unsigned c = (a + b) / 2;
+
+ if (action_list->map.entry[c].offset <= offset)
+ a = c;
+ else
+ b = c;
+ }
+
+ if (action_list->map.entry[a].offset < offset)
+ {
+ return action_list->map.entry[a].removed;
+ }
+ else if (action_list->map.entry[a].offset == offset)
+ {
+ return before_fill ?
+ action_list->map.entry[a].eq_removed_before_fill :
+ action_list->map.entry[a].eq_removed;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static bfd_vma
+offset_with_removed_text_map (text_action_list *action_list, bfd_vma offset)
+{
+ int removed = removed_by_actions_map (action_list, offset, FALSE);
+ return offset - removed;
+}
+
/* The find_insn_action routine will only find non-fill actions. */
@@ -5909,6 +6021,9 @@ init_xtensa_relax_info (asection *sec)
relax_info->action_list.head = NULL;
+ relax_info->action_list.map.n_entries = 0;
+ relax_info->action_list.map.entry = NULL;
+
relax_info->fix_list = NULL;
relax_info->fix_array = NULL;
relax_info->fix_array_count = 0;
@@ -9218,7 +9333,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
if (elf_hash_table (link_info)->dynamic_sections_created)
shrink_dynamic_reloc_sections (link_info, abfd, sec, irel);
irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
- irel->r_offset = offset_with_removed_text
+ irel->r_offset = offset_with_removed_text_map
(&relax_info->action_list, irel->r_offset);
continue;
}
@@ -9255,7 +9370,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
}
}
- source_offset = offset_with_removed_text
+ source_offset = offset_with_removed_text_map
(&relax_info->action_list, irel->r_offset);
irel->r_offset = source_offset;
}
@@ -9352,7 +9467,7 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
break;
}
- new_end_offset = offset_with_removed_text
+ new_end_offset = offset_with_removed_text_map
(&target_relax_info->action_list,
r_rel.target_offset + diff_value);
diff_value = new_end_offset - new_reloc.target_offset;
@@ -9750,7 +9865,6 @@ translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel, asection *sec)
xtensa_relax_info *relax_info;
removed_literal *removed;
bfd_vma target_offset, base_offset;
- text_action *act;
*new_rel = *orig_rel;
@@ -9803,19 +9917,26 @@ translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel, asection *sec)
offset. */
base_offset = r_reloc_get_target_offset (new_rel) - new_rel->rela.r_addend;
- act = relax_info->action_list.head;
if (base_offset <= target_offset)
{
- int base_removed = removed_by_actions (&act, base_offset, FALSE);
- int addend_removed = removed_by_actions (&act, target_offset, FALSE);
+ int base_removed = removed_by_actions_map (&relax_info->action_list,
+ base_offset, FALSE);
+ int addend_removed = removed_by_actions_map (&relax_info->action_list,
+ target_offset, FALSE) -
+ base_removed;
+
new_rel->target_offset = target_offset - base_removed - addend_removed;
new_rel->rela.r_addend -= addend_removed;
}
else
{
/* Handle a negative addend. The base offset comes first. */
- int tgt_removed = removed_by_actions (&act, target_offset, FALSE);
- int addend_removed = removed_by_actions (&act, base_offset, FALSE);
+ int tgt_removed = removed_by_actions_map (&relax_info->action_list,
+ target_offset, FALSE);
+ int addend_removed = removed_by_actions_map (&relax_info->action_list,
+ base_offset, FALSE) -
+ tgt_removed;
+
new_rel->target_offset = target_offset - tgt_removed;
new_rel->rela.r_addend += addend_removed;
}
@@ -10138,9 +10259,10 @@ relax_property_section (bfd *abfd,
bfd_vma old_offset = val.r_rel.target_offset;
bfd_vma new_offset;
long old_size, new_size;
- text_action *act = target_relax_info->action_list.head;
- new_offset = old_offset -
- removed_by_actions (&act, old_offset, FALSE);
+ int removed_by_old_offset =
+ removed_by_actions_map (&target_relax_info->action_list,
+ old_offset, FALSE);
+ new_offset = old_offset - removed_by_old_offset;
/* Assert that we are not out of bounds. */
old_size = bfd_get_32 (abfd, size_p);
@@ -10164,9 +10286,10 @@ relax_property_section (bfd *abfd,
/* Recompute the new_offset, but this time don't
include any fill inserted by relaxation. */
- act = target_relax_info->action_list.head;
- new_offset = old_offset -
- removed_by_actions (&act, old_offset, TRUE);
+ removed_by_old_offset =
+ removed_by_actions_map (&target_relax_info->action_list,
+ old_offset, TRUE);
+ new_offset = old_offset - removed_by_old_offset;
/* If it is not unreachable and we have not yet
seen an unreachable at this address, place it
@@ -10182,8 +10305,12 @@ relax_property_section (bfd *abfd,
}
}
else
- new_size -=
- removed_by_actions (&act, old_offset + old_size, TRUE);
+ {
+ int removed_by_old_offset_size =
+ removed_by_actions_map (&target_relax_info->action_list,
+ old_offset + old_size, TRUE);
+ new_size -= removed_by_old_offset_size - removed_by_old_offset;
+ }
if (new_size != old_size)
{
@@ -10441,14 +10568,16 @@ relax_section_symbols (bfd *abfd, asection *sec)
if (isym->st_shndx == sec_shndx)
{
- text_action *act = relax_info->action_list.head;
bfd_vma orig_addr = isym->st_value;
+ int removed = removed_by_actions_map (&relax_info->action_list,
+ orig_addr, FALSE);
- isym->st_value -= removed_by_actions (&act, orig_addr, FALSE);
-
+ isym->st_value -= removed;
if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC)
isym->st_size -=
- removed_by_actions (&act, orig_addr + isym->st_size, FALSE);
+ removed_by_actions_map (&relax_info->action_list,
+ orig_addr + isym->st_size, FALSE) -
+ removed;
}
}
@@ -10466,15 +10595,17 @@ relax_section_symbols (bfd *abfd, asection *sec)
|| sym_hash->root.type == bfd_link_hash_defweak)
&& sym_hash->root.u.def.section == sec)
{
- text_action *act = relax_info->action_list.head;
bfd_vma orig_addr = sym_hash->root.u.def.value;
+ int removed = removed_by_actions_map (&relax_info->action_list,
+ orig_addr, FALSE);
- sym_hash->root.u.def.value -=
- removed_by_actions (&act, orig_addr, FALSE);
+ sym_hash->root.u.def.value -= removed;
if (sym_hash->type == STT_FUNC)
sym_hash->size -=
- removed_by_actions (&act, orig_addr + sym_hash->size, FALSE);
+ removed_by_actions_map (&relax_info->action_list,
+ orig_addr + sym_hash->size, FALSE) -
+ removed;
}
}
--
1.8.1.4

Some files were not shown because too many files have changed in this diff Show More