]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'kbuild/for-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Thu, 5 Nov 2015 00:40:36 +0000 (11:40 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Thu, 5 Nov 2015 00:40:36 +0000 (11:40 +1100)
29 files changed:
Documentation/kbuild/Kconfig.recursion-issue-01 [new file with mode: 0644]
Documentation/kbuild/Kconfig.recursion-issue-02 [new file with mode: 0644]
Documentation/kbuild/Kconfig.select-break [new file with mode: 0644]
Documentation/kbuild/kconfig-language.txt
Documentation/lto-build [new file with mode: 0644]
Makefile
arch/x86/Kconfig
init/Kconfig
kernel/gcov/Kconfig
lib/Kconfig.debug
scripts/Makefile.lto [new file with mode: 0644]
scripts/Makefile.modpost
scripts/coccicheck
scripts/coccinelle/free/ifnullfree.cocci
scripts/coccinelle/iterators/device_node_continue.cocci [new file with mode: 0644]
scripts/coccinelle/misc/compare_const_fl.cocci [new file with mode: 0644]
scripts/coccinelle/misc/of_table.cocci
scripts/coccinelle/misc/simple_return.cocci [deleted file]
scripts/coccinelle/null/deref_null.cocci
scripts/coccinelle/tests/odd_ptr_err.cocci
scripts/kconfig/Makefile
scripts/kconfig/expr.c
scripts/kconfig/merge_config.sh
scripts/kconfig/qconf.cc
scripts/kconfig/qconf.h
scripts/kconfig/symbol.c
scripts/link-vmlinux.sh
scripts/package/builddeb
scripts/tags.sh

diff --git a/Documentation/kbuild/Kconfig.recursion-issue-01 b/Documentation/kbuild/Kconfig.recursion-issue-01
new file mode 100644 (file)
index 0000000..e8877db
--- /dev/null
@@ -0,0 +1,57 @@
+# Simple Kconfig recursive issue
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# Test with:
+#
+# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig
+#
+# This Kconfig file has a simple recursive dependency issue. In order to
+# understand why this recursive dependency issue occurs lets consider what
+# Kconfig needs to address. We iterate over what Kconfig needs to address
+# by stepping through the questions it needs to address sequentially.
+#
+#  * What values are possible for CORE?
+#
+# CORE_BELL_A_ADVANCED selects CORE, which means that it influences the values
+# that are possible for CORE. So for example if CORE_BELL_A_ADVANCED is 'y',
+# CORE must be 'y' too.
+#
+#  * What influences CORE_BELL_A_ADVANCED ?
+#
+# As the name implies CORE_BELL_A_ADVANCED is an advanced feature of
+# CORE_BELL_A so naturally it depends on CORE_BELL_A. So if CORE_BELL_A is 'y'
+# we know CORE_BELL_A_ADVANCED can be 'y' too.
+#
+#   * What influences CORE_BELL_A ?
+#
+# CORE_BELL_A depends on CORE, so CORE influences CORE_BELL_A.
+#
+# But that is a problem, because this means that in order to determine
+# what values are possible for CORE we ended up needing to address questions
+# regarding possible values of CORE itself again. Answering the original
+# question of what are the possible values of CORE would make the kconfig
+# tools run in a loop. When this happens Kconfig exits and complains about
+# the "recursive dependency detected" error.
+#
+# Reading the Documentation/kbuild/Kconfig.recursion-issue-01 file it may be
+# obvious that an easy to solution to this problem should just be the removal
+# of the "select CORE" from CORE_BELL_A_ADVANCED as that is implicit already
+# since CORE_BELL_A depends on CORE. Recursive dependency issues are not always
+# so trivial to resolve, we provide another example below of practical
+# implications of this recursive issue where the solution is perhaps not so
+# easy to understand. Note that matching semantics on the dependency on
+# CORE also consist of a solution to this recursive problem.
+
+mainmenu "Simple example to demo kconfig recursive dependency issue"
+
+config CORE
+       tristate
+
+config CORE_BELL_A
+       tristate
+       depends on CORE
+
+config CORE_BELL_A_ADVANCED
+       tristate
+       depends on CORE_BELL_A
+       select CORE
diff --git a/Documentation/kbuild/Kconfig.recursion-issue-02 b/Documentation/kbuild/Kconfig.recursion-issue-02
new file mode 100644 (file)
index 0000000..b9fd56c
--- /dev/null
@@ -0,0 +1,63 @@
+# Cumulative Kconfig recursive issue
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# Test with:
+#
+# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig
+#
+# The recursive limitations with Kconfig has some non intuitive implications on
+# kconfig sematics which are documented here. One known practical implication
+# of the recursive limitation is that drivers cannot negate features from other
+# drivers if they share a common core requirement and use disjoint semantics to
+# annotate those requirements, ie, some drivers use "depends on" while others
+# use "select". For instance it means if a driver A and driver B share the same
+# core requirement, and one uses "select" while the other uses "depends on" to
+# annotate this, all features that driver A selects cannot now be negated by
+# driver B.
+#
+# A perhaps not so obvious implication of this is that, if semantics on these
+# core requirements are not carefully synced, as drivers evolve features
+# they select or depend on end up becoming shared requirements which cannot be
+# negated by other drivers.
+#
+# The example provided in Documentation/kbuild/Kconfig.recursion-issue-02
+# describes a simple driver core layout of example features a kernel might
+# have. Let's assume we have some CORE functionality, then the kernel has a
+# series of bells and whistles it desires to implement, its not so advanced so
+# it only supports bells at this time: CORE_BELL_A and CORE_BELL_B. If
+# CORE_BELL_A has some advanced feature CORE_BELL_A_ADVANCED which selects
+# CORE_BELL_A then CORE_BELL_A ends up becoming a common BELL feature which
+# other bells in the system cannot negate. The reason for this issue is
+# due to the disjoint use of semantics on expressing each bell's relationship
+# with CORE, one uses "depends on" while the other uses "select". Another
+# more important reason is that kconfig does not check for dependencies listed
+# under 'select' for a symbol, when such symbols are selected kconfig them
+# as mandatory required symbols. For more details on the heavy handed nature
+# of select refer to Documentation/kbuild/Kconfig.select-break
+#
+# To fix this the "depends on CORE" must be changed to "select CORE", or the
+# "select CORE" must be changed to "depends on CORE".
+#
+# For an example real world scenario issue refer to the attempt to remove
+# "select FW_LOADER" [0], in the end the simple alternative solution to this
+# problem consisted on matching semantics with newly introduced features.
+#
+# [0] http://lkml.kernel.org/r/1432241149-8762-1-git-send-email-mcgrof@do-not-panic.com
+
+mainmenu "Simple example to demo cumulative kconfig recursive dependency implication"
+
+config CORE
+       tristate
+
+config CORE_BELL_A
+       tristate
+       depends on CORE
+
+config CORE_BELL_A_ADVANCED
+       tristate
+       select CORE_BELL_A
+
+config CORE_BELL_B
+       tristate
+       depends on !CORE_BELL_A
+       select CORE
diff --git a/Documentation/kbuild/Kconfig.select-break b/Documentation/kbuild/Kconfig.select-break
new file mode 100644 (file)
index 0000000..365ceb3
--- /dev/null
@@ -0,0 +1,33 @@
+# Select broken dependency issue
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# Test with:
+#
+# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.select-break menuconfig
+#
+# kconfig will not complain and enable this layout for configuration. This is
+# currently a feature of kconfig, given select was designed to be heavy handed.
+# Kconfig currently does not check the list of symbols listed on a symbol's
+# "select" list, this is done on purpose to help load a set of known required
+# symbols. Because of this use of select should be used with caution. An
+# example of this issue is below.
+#
+# The option B and C are clearly contradicting with respect to A.
+# However, when A is set, C can be set as well because Kconfig does not
+# visit the dependencies of the select target (in this case B).  And since
+# Kconfig does not visit the dependencies, it breaks the dependencies of B
+# (!A).
+
+mainmenu "Simple example to demo kconfig select broken dependency issue"
+
+config A
+       bool "CONFIG A"
+
+config B
+       bool "CONFIG B"
+       depends on !A
+
+config C
+       bool "CONFIG C"
+       depends on A
+       select B
index 350f733bf2c7165fd13a960df68bbfebf4a34bf8..c52856da0cad555c7eeecd90c9738fccf941adb2 100644 (file)
@@ -393,3 +393,164 @@ config FOO
        depends on BAR && m
 
 limits FOO to module (=m) or disabled (=n).
+
+Kconfig recursive dependency limitations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you've hit the Kconfig error: "recursive dependency detected" you've run
+into a recursive dependency issue with Kconfig, a recursive dependency can be
+summarized as a circular dependency. The kconfig tools need to ensure that
+Kconfig files comply with specified configuration requirements. In order to do
+that kconfig must determine the values that are possible for all Kconfig
+symbols, this is currently not possible if there is a circular relation
+between two or more Kconfig symbols. For more details refer to the "Simple
+Kconfig recursive issue" subsection below. Kconfig does not do recursive
+dependency resolution; this has a few implications for Kconfig file writers.
+We'll first explain why this issues exists and then provide an example
+technical limitation which this brings upon Kconfig developers. Eager
+developers wishing to try to address this limitation should read the next
+subsections.
+
+Simple Kconfig recursive issue
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Read: Documentation/kbuild/Kconfig.recursion-issue-01
+
+Test with:
+
+make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig
+
+Cumulative Kconfig recursive issue
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Read: Documentation/kbuild/Kconfig.recursion-issue-02
+
+Test with:
+
+make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig
+
+Practical solutions to kconfig recursive issue
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Developers who run into the recursive Kconfig issue have three options
+at their disposal. We document them below and also provide a list of
+historical issues resolved through these different solutions.
+
+  a) Remove any superfluous "select FOO" or "depends on FOO"
+  b) Match dependency semantics:
+       b1) Swap all "select FOO" to "depends on FOO" or,
+       b2) Swap all "depends on FOO" to "select FOO"
+
+The resolution to a) can be tested with the sample Kconfig file
+Documentation/kbuild/Kconfig.recursion-issue-01 through the removal
+of the "select CORE" from CORE_BELL_A_ADVANCED as that is implicit already
+since CORE_BELL_A depends on CORE. At times it may not be possible to remove
+some dependency criteria, for such cases you can work with solution b).
+
+The two different resolutions for b) can be tested in the sample Kconfig file
+Documentation/kbuild/Kconfig.recursion-issue-02.
+
+Below is a list of examples of prior fixes for these types of recursive issues;
+all errors appear to involve one or more select's and one or more "depends on".
+
+commit          fix
+======          ===
+06b718c01208    select A -> depends on A
+c22eacfe82f9    depends on A -> depends on B
+6a91e854442c    select A -> depends on A
+118c565a8f2e    select A -> select B
+f004e5594705    select A -> depends on A
+c7861f37b4c6    depends on A -> (null)
+80c69915e5fb    select A -> (null)              (1)
+c2218e26c0d0    select A -> depends on A        (1)
+d6ae99d04e1c    select A -> depends on A
+95ca19cf8cbf    select A -> depends on A
+8f057d7bca54    depends on A -> (null)
+8f057d7bca54    depends on A -> select A
+a0701f04846e    select A -> depends on A
+0c8b92f7f259    depends on A -> (null)
+e4e9e0540928    select A -> depends on A        (2)
+7453ea886e87    depends on A > (null)           (1)
+7b1fff7e4fdf    select A -> depends on A
+86c747d2a4f0    select A -> depends on A
+d9f9ab51e55e    select A -> depends on A
+0c51a4d8abd6    depends on A -> select A        (3)
+e98062ed6dc4    select A -> depends on A        (3)
+91e5d284a7f1    select A -> (null)
+
+(1) Partial (or no) quote of error.
+(2) That seems to be the gist of that fix.
+(3) Same error.
+
+Future kconfig work
+~~~~~~~~~~~~~~~~~~~
+
+Work on kconfig is welcomed on both areas of clarifying semantics and on
+evaluating the use of a full SAT solver for it. A full SAT solver can be
+desirable to enable more complex dependency mappings and / or queries,
+for instance on possible use case for a SAT solver could be that of handling
+the current known recursive dependency issues. It is not known if this would
+address such issues but such evaluation is desirable. If support for a full SAT
+solver proves too complex or that it cannot address recursive dependency issues
+Kconfig should have at least clear and well defined semantics which also
+addresses and documents limitations or requirements such as the ones dealing
+with recursive dependencies.
+
+Further work on both of these areas is welcomed on Kconfig. We elaborate
+on both of these in the next two subsections.
+
+Semantics of Kconfig
+~~~~~~~~~~~~~~~~~~~~
+
+The use of Kconfig is broad, Linux is now only one of Kconfig's users:
+one study has completed a broad analysis of Kconfig use in 12 projects [0].
+Despite its widespread use, and although this document does a reasonable job
+in documenting basic Kconfig syntax a more precise definition of Kconfig
+semantics is welcomed. One project deduced Kconfig semantics through
+the use of the xconfig configurator [1]. Work should be done to confirm if
+the deduced semantics matches our intended Kconfig design goals.
+
+Having well defined semantics can be useful for tools for practical
+evaluation of depenencies, for instance one such use known case was work to
+express in boolean abstraction of the inferred semantics of Kconfig to
+translate Kconfig logic into boolean formulas and run a SAT solver on this to
+find dead code / features (always inactive), 114 dead features were found in
+Linux using this methodology [1] (Section 8: Threats to validity).
+
+Confirming this could prove useful as Kconfig stands as one of the the leading
+industrial variability modeling languages [1] [2]. Its study would help
+evaluate practical uses of such languages, their use was only theoretical
+and real world requirements were not well understood. As it stands though
+only reverse engineering techniques have been used to deduce semantics from
+variability modeling languages such as Kconfig [3].
+
+[0] http://www.eng.uwaterloo.ca/~shshe/kconfig_semantics.pdf
+[1] http://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf
+[2] http://gsd.uwaterloo.ca/sites/default/files/ase241-berger_0.pdf
+[3] http://gsd.uwaterloo.ca/sites/default/files/icse2011.pdf
+
+Full SAT solver for Kconfig
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Although SAT solvers [0] haven't yet been used by Kconfig directly, as noted in
+the previous subsection, work has been done however to express in boolean
+abstraction the inferred semantics of Kconfig to translate Kconfig logic into
+boolean formulas and run a SAT solver on it [1]. Another known related project
+is CADOS [2] (former VAMOS [3]) and the tools, mainly undertaker [4], which has
+been introduced first with [5].  The basic concept of undertaker is to exract
+variability models from Kconfig, and put them together with a propositional
+formula extracted from CPP #ifdefs and build-rules into a SAT solver in order
+to find dead code, dead files, and dead symbols. If using a SAT solver is
+desirable on Kconfig one approach would be to evaluate repurposing such efforts
+somehow on Kconfig. There is enough interest from mentors of existing projects
+to not only help advise how to integrate this work upstream but also help
+maintain it long term. Interested developers should visit:
+
+http://kernelnewbies.org/KernelProjects/kconfig-sat
+
+[0] http://www.cs.cornell.edu/~sabhar/chapters/SATSolvers-KR-Handbook.pdf
+[1] http://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf
+[2] https://cados.cs.fau.de
+[3] https://vamos.cs.fau.de
+[4] https://undertaker.cs.fau.de
+[5] https://www4.cs.fau.de/Publications/2011/tartler_11_eurosys.pdf
diff --git a/Documentation/lto-build b/Documentation/lto-build
new file mode 100644 (file)
index 0000000..5dcce1e
--- /dev/null
@@ -0,0 +1,173 @@
+Link time optimization (LTO) for the Linux kernel
+
+This is an experimental feature.
+
+Link Time Optimization allows the compiler to optimize the complete program
+instead of just each file.  LTO requires at least gcc 4.8 (but
+works more efficiently with 4.9+) LTO requires Linux binutils (the normal FSF
+releases used in many distributions do not work at the moment)
+
+The compiler can inline functions between files and do various other global
+optimizations, like specializing functions for common parameters,
+determing when global variables are clobbered, making functions pure/const,
+propagating constants globally, removing unneeded data and others.
+
+It will also drop unused functions which can make the kernel
+image smaller in some circumstances, in particular for small kernel
+configurations.
+
+For small monolithic kernels it can throw away unused code very effectively
+(especially when modules are disabled) and usually shrinks
+the code size.
+
+Build time and memory consumption at build time will increase, depending
+on the size of the largest binary. Modular kernels are less affected.
+With LTO incremental builds are less incremental, as always the whole
+binary needs to be re-optimized (but not re-parsed)
+
+Oops can be somewhat more difficult to read, due to the more aggressive
+inlining.
+
+Normal "reasonable" builds work with less than 4GB of RAM, but very large
+configurations like allyesconfig may need more memory. The actual
+memory needed depends on the available memory (gcc sizes its garbage
+collector pools based on that or on the ulimit -m limits) and
+the compiler version.
+
+gcc 4.9+ has much better build performance and less memory consumption
+
+- A few kernel features are currently incompatible with LTO, in particular
+function tracing, because they require special compiler flags for
+specific files, which is not supported in LTO right now.
+- Jobserver control for -j does not work correctly for the final
+LTO phase due to some problems with the kernel's pipe code.
+The makefiles hard codes -j<number of online cpus> for the final
+LTO phase to work around for this
+
+Configuration:
+- Enable CONFIG_LTO_MENU and then disable CONFIG_LTO_DISABLE.
+This is mainly to not have allyesconfig default to LTO.
+- FUNCTION_TRACER, STACK_TRACER, FUNCTION_GRAPH_TRACER, KALLSYMS_ALL, GCOV
+have to disabled because they are currently incompatible with LTO.
+- MODVERSIONS have to be disabled (may work with 4.9+)
+
+Requirements:
+- Enough memory: 4GB for a standard build, more for allyesconfig
+The peak memory usage happens single threaded (when lto-wpa merges types),
+so dialing back -j options will not help much.
+
+A 32bit compiler is unlikely to work due to the memory requirements.
+You can however build a kernel targeted at 32bit on a 64bit host.
+
+Example build procedure:
+
+Simplified procedure for distributions that have gcc 4.8, but not
+the Linux binutils (for example openSUSE 13.1 or FC20):
+
+The LTO builds requires gcc-nm/gcc-ar. Some distributions ship
+those in separate packages, which may need to be explicitely installed.
+
+- Get the latest Linux binutils from
+http://www.kernel.org/pub/linux/devel/binutils/
+and unpack it.
+
+We install it in a separate directory to not overwrite the system binutils.
+
+# replace VERSION with respective version numbers
+
+cd binutils*
+# don't forget the --enable-plugins!
+./configure --prefix=/opt/binutils-VERSION --enable-plugins
+make -j $(getconf _NPROCESSORS_ONLN) && sudo make install
+
+Fix up the kernel configuration to allow LTO:
+
+<start with a suitable kernel configuration>
+./source/scripts/config --disable function_tracer \
+                       --disable function_graph_tracer \
+                       --disable stack_tracer --enable lto_menu \
+                        --disable lto_disable \
+                       --disable gcov \
+                       --disable kallsyms_all \
+                       --disable modversions
+make oldconfig
+
+Then you can build with
+
+# The COMPILER_PATH is needed to let gcc use the new binutils
+# as the LTO plugin linker
+# if you installed gcc in a separate directory like below also
+# add it to the PATH line below before the regular $PATH
+# The COMPILER_PATH setting is only needed if the gcc was not built
+# with --with-plugin-ld pointing to the Linux binutils ld
+# The AR/NM setting works around a Makefile bug
+COMPILER_PATH=/opt/binutils-VERSION/bin PATH=$COMPILER_PATH:$PATH \
+make -j$(getconf _NPROCESSORS_ONLN) AR=gcc-ar NM=gcc-nm
+
+If you don't have gcc 4.8+ as system compiler you would also need
+to install that compiler. In this case I recommend getting
+a gcc 4.9+ snapshot from http://gcc.gnu.org (or release when available),
+as it builds much faster for LTO than 4.8.
+
+Here's an example build procedure:
+
+Assuming gcc is unpacked in gcc-VERSION
+
+cd gcc-VERSION
+./contrib/download_preqrequisites
+cd ..
+
+mkdir obj-gcc
+# please don't skip this cd. the build will not work correctly in the
+# source dir, you have to use the separate object dir
+cd obj-gcc
+../gcc-VERSION/configure --prefix=/opt/gcc-VERSION --enable-lto \
+--with-plugin-ld=/opt/binutils-VERSION/bin/ld
+--disable-nls --enable-languages=c,c++ \
+--disable-libstdcxx-pch
+make -j$(getconf _NPROCESSORS_ONLN)
+sudo make install-no-fixedincludes
+
+FAQs:
+
+Q: I get a section type attribute conflict
+A: Usually because of someone doing
+const __initdata (should be const __initconst) or const __read_mostly
+(should be just const). Check both symbols reported by gcc.
+
+Q: I see lots of undefined symbols for memcmp etc.
+A: Usually because NM=gcc-nm AR=gcc-ar are missing.
+The Makefile tries to set those automatically, but it doesn't always
+work. Better to set it manually on the make command line.
+
+Q: It's quite slow / uses too much memory.
+A: Consider a gcc 4.9 snapshot/release (not released yet)
+The main problem in 4.8 is the type merging in the single threaded WPA pass,
+which has been improved considerably in 4.9 by running it distributed.
+
+Q: It's still slow
+A: It'll always be somewhat slower than non LTO sorry.
+
+Q: What's up with .XXXXX numeric post fixes
+A: This is due LTO turning (near) all symbols to static
+Use gcc 4.9, it avoids them in most cases. They are also filtered out
+in kallsyms.
+
+References:
+
+Presentation on Kernel LTO
+(note, performance numbers/details outdated.  In particular gcc 4.9 fixed
+most of the build time problems):
+http://halobates.de/kernel-lto.pdf
+
+Generic gcc LTO:
+http://www.ucw.cz/~hubicka/slides/labs2013.pdf
+http://www.hipeac.net/system/files/barcelona.pdf
+
+Somewhat outdated too:
+http://gcc.gnu.org/projects/lto/lto.pdf
+http://gcc.gnu.org/projects/lto/whopr.pdf
+
+Happy Link-Time-Optimizing!
+
+Andi Kleen
index d5b37391195f80866ad2b831a417039b3ee230cf..5e5c2def19ddb3db004cc8f264df78fb5b71764e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -342,9 +342,14 @@ include scripts/Kbuild.include
 # Make variables (CC, etc...)
 AS             = $(CROSS_COMPILE)as
 LD             = $(CROSS_COMPILE)ld
+LDFINAL        = $(LD)
 CC             = $(CROSS_COMPILE)gcc
 CPP            = $(CC) -E
+ifdef CONFIG_LTO
+AR             = $(CROSS_COMPILE)gcc-ar
+else
 AR             = $(CROSS_COMPILE)ar
+endif
 NM             = $(CROSS_COMPILE)nm
 STRIP          = $(CROSS_COMPILE)strip
 OBJCOPY                = $(CROSS_COMPILE)objcopy
@@ -406,7 +411,7 @@ KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(S
 
 export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
 export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
-export CPP AR NM STRIP OBJCOPY OBJDUMP
+export CPP AR NM STRIP OBJCOPY OBJDUMP LDFINAL
 export MAKE AWK GENKSYMS INSTALLKERNEL PERL PYTHON UTS_MACHINE
 export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
 
@@ -417,6 +422,17 @@ export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
 export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
 export KBUILD_ARFLAGS
 
+ifdef CONFIG_LTO
+# LTO gcc creates a lot of files in TMPDIR, and with /tmp as tmpfs
+# it's easy to drive the machine OOM. Use the object directory
+# instead.
+ifndef TMPDIR
+TMPDIR ?= $(objtree)
+export TMPDIR
+$(info setting TMPDIR=$(objtree) for LTO build)
+endif
+endif
+
 # When compiling out-of-tree modules, put MODVERDIR in the module
 # tree rather than in the kernel tree. The kernel tree might
 # even be read-only.
@@ -777,6 +793,7 @@ endif
 
 include scripts/Makefile.kasan
 include scripts/Makefile.extrawarn
+include scripts/Makefile.lto
 
 # Add any arch overrides and user supplied CPPFLAGS, AFLAGS and CFLAGS as the
 # last assignments
@@ -1075,6 +1092,9 @@ PHONY += kselftest
 kselftest:
        $(Q)$(MAKE) -C tools/testing/selftests run_tests
 
+kselftest-clean:
+       $(Q)$(MAKE) -C tools/testing/selftests clean
+
 # ---------------------------------------------------------------------------
 # Modules
 
@@ -1282,6 +1302,7 @@ help:
        @echo  '  kselftest       - Build and run kernel selftest (run as root)'
        @echo  '                    Build, install, and boot kernel before'
        @echo  '                    running kselftest on it'
+       @echo  '  kselftest-clean - Remove all generated kselftest files'
        @echo  ''
        @echo  'Kernel packaging:'
        @$(MAKE) $(build)=$(package-dir) help
index db3622f22b618303a8bc9c3c2f34762f400dbafb..c22df590e7e7463c71ac80a3f7e795656f1d33c2 100644 (file)
@@ -636,7 +636,7 @@ config X86_32_IRIS
 
 config SCHED_OMIT_FRAME_POINTER
        def_bool y
-       prompt "Single-depth WCHAN output"
+       prompt "Single-depth WCHAN output" if !LTO && !FRAME_POINTER
        depends on X86
        ---help---
          Calculate simpler /proc/<PID>/wchan values. If this option
index c24b6f767bf0f2a4d8a873388a5fbd59ba01c562..f1af42de48f48794fa95768c0bbc53481df1153d 100644 (file)
@@ -1316,6 +1316,77 @@ config CC_OPTIMIZE_FOR_SIZE
 
          If unsure, say N.
 
+config LTO_MENU
+       bool "Enable gcc link time optimization (LTO)"
+       # Only tested on X86 for now. For other architectures you likely
+       # have to fix some things first, like adding asmlinkages etc.
+       depends on X86
+       # lto does not support excluding flags for specific files
+       # right now. Can be removed if that is fixed.
+       depends on !FUNCTION_TRACER
+       help
+         With this option gcc will do whole program optimizations for
+         the whole kernel and module. This increases compile time, but can
+         lead to better code. It allows gcc to inline functions between
+         different files and do other optimization.  It might also trigger
+         bugs due to more aggressive optimization. It allows gcc to drop unused
+         code. On smaller monolithic kernel configurations
+         it usually leads to smaller kernels, especially when modules
+         are disabled.
+
+         With this option gcc will also do some global checking over
+         different source files. It also disables a number of kernel
+         features.
+
+         This option is recommended for release builds. With LTO
+         the kernel always has to be re-optimized (but not re-parsed)
+         on each build.
+
+         This requires a gcc 4.8 or later compiler and
+         Linux binutils 2.21.51.0.3 or later.  gcc 4.9 builds significantly
+         faster than 4.8 It does not currently work with a FSF release of
+         binutils or with the gold linker.
+
+         On larger configurations this may need more than 4GB of RAM.
+         It will likely not work on those with a 32bit compiler.
+
+         When the toolchain support is not available this will (hopefully)
+         be automatically disabled.
+
+         For more information see Documentation/lto-build
+
+config LTO_DISABLE
+         bool "Disable LTO again"
+         depends on LTO_MENU
+         default n
+         help
+           This option is merely here so that allyesconfig or allmodconfig do
+           not enable LTO. If you want to actually use LTO do not enable.
+
+config LTO
+       bool
+       default y
+       depends on LTO_MENU && !LTO_DISABLE
+
+config LTO_DEBUG
+       bool "Enable LTO compile time debugging"
+       depends on LTO
+       help
+         Enable LTO debugging in the compiler. The compiler dumps
+         some log files that make it easier to figure out LTO
+         behavior. The log files also allow to reconstruct
+         the global inlining and a global callgraph.
+         They however add some (single threaded) cost to the
+         compilation.  When in doubt do not enable.
+
+config LTO_CP_CLONE
+       bool "Allow aggressive cloning for function specialization"
+       depends on LTO
+       help
+         Allow the compiler to clone and specialize functions for specific
+         arguments when it determines these arguments are very commonly
+         called.  Experimential. Will increase text size.
+
 config SYSCTL
        bool
 
@@ -1881,6 +1952,8 @@ config MODULE_FORCE_UNLOAD
 
 config MODVERSIONS
        bool "Module versioning support"
+       # LTO should work with gcc 4.9
+       depends on !LTO
        help
          Usually, you have to use modules compiled with your kernel.
          Saying Y here makes it sometimes possible to use modules
index c92e44855ddda18843a2b7c9102a323811d27917..6ca0b99e5f0a2283e0f3627ecc53010639330c07 100644 (file)
@@ -2,7 +2,7 @@ menu "GCOV-based kernel profiling"
 
 config GCOV_KERNEL
        bool "Enable gcov-based kernel profiling"
-       depends on DEBUG_FS
+       depends on DEBUG_FS && !LTO
        select CONSTRUCTORS if !UML
        default n
        ---help---
index 1d1521c26302a2510e873d49a8b6bb525f399d66..8abc04ef781105a1f970ece63420c346ab1eb59a 100644 (file)
@@ -216,7 +216,7 @@ config STRIP_ASM_SYMS
 
 config READABLE_ASM
         bool "Generate readable assembler code"
-        depends on DEBUG_KERNEL
+        depends on DEBUG_KERNEL && !LTO
         help
           Disable some compiler optimizations that tend to generate human unreadable
           assembler output. This may make the kernel slightly slower, but it helps
diff --git a/scripts/Makefile.lto b/scripts/Makefile.lto
new file mode 100644 (file)
index 0000000..b8e9e48
--- /dev/null
@@ -0,0 +1,84 @@
+#
+# Support for gcc link time optimization
+#
+
+DISABLE_LTO :=
+LTO_CFLAGS :=
+
+export DISABLE_LTO
+export LTO_CFLAGS
+
+ifdef CONFIG_LTO
+# 4.7 works mostly, but it sometimes loses symbols on large builds
+# This can be worked around by marking those symbols visible,
+# but that is fairly ugly and the problem is gone with 4.8
+# So only allow it with 4.8 for now.
+ifeq ($(call cc-ifversion, -ge, 0408,y),y)
+ifneq ($(call cc-option,${LTO_CFLAGS},n),n)
+# We need HJ Lu's Linux binutils because mainline binutils does not
+# support mixing assembler and LTO code in the same ld -r object.
+# XXX check if the gcc plugin ld is the expected one too
+# XXX some Fedora binutils should also support it. How to check for that?
+ifeq ($(call ld-ifversion,-ge,22710001,y),y)
+        LTO_CFLAGS := -flto -fno-toplevel-reorder
+       LTO_FINAL_CFLAGS := -fuse-linker-plugin
+
+# the -fno-toplevel-reorder is to preserve the order of initcalls
+# everything else should tolerate reordering
+        LTO_FINAL_CFLAGS +=-fno-toplevel-reorder
+
+# enable LTO and set the jobs used by the LTO phase
+# this should be -flto=jobserver to coordinate with the
+# parent make, but work around
+# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50639
+# use as many jobs as processors are online for now
+# this actually seems to be a kernel bug with the pipe code
+       LTO_FINAL_CFLAGS := -flto=$(shell getconf _NPROCESSORS_ONLN)
+       #LTO_FINAL_CFLAGS := -flto=jobserver
+
+       # requires plugin ar passed and very recent HJ binutils
+        LTO_CFLAGS += -fno-fat-lto-objects
+
+# Used to disable LTO for specific files (e.g. vdso)
+       DISABLE_LTO := -fno-lto
+
+       LTO_FINAL_CFLAGS += ${LTO_CFLAGS} -fwhole-program
+
+ifdef CONFIG_LTO_DEBUG
+       LTO_FINAL_CFLAGS += -dH -fdump-ipa-cgraph -fdump-ipa-inline-details
+       # -Wl,-plugin-save-temps -save-temps
+       LTO_CFLAGS +=
+endif
+ifdef CONFIG_LTO_CP_CLONE
+       LTO_FINAL_CFLAGS += -fipa-cp-clone
+       LTO_CFLAGS += -fipa-cp-clone
+endif
+
+       # In principle gcc should pass through options in the object files,
+       # but it doesn't always work. So do it here manually
+       # Note that special options for individual files does not
+       # work currently (except for some special cases that only
+       # affect the compiler frontend)
+       # The main offenders are FTRACE and GCOV -- we exclude
+       # those in the config.
+       LTO_FINAL_CFLAGS += $(filter -g%,${KBUILD_CFLAGS})
+       LTO_FINAL_CFLAGS += $(filter -O%,${KBUILD_CFLAGS})
+       LTO_FINAL_CFLAGS += $(filter -f%,${KBUILD_CFLAGS})
+       LTO_FINAL_CFLAGS += $(filter -m%,${KBUILD_CFLAGS})
+       LTO_FINAL_CFLAGS += $(filter -W%,${KBUILD_CFLAGS})
+
+       KBUILD_CFLAGS += ${LTO_CFLAGS}
+
+       LDFINAL := ${CONFIG_SHELL} ${srctree}/scripts/gcc-ld \
+                  ${LTO_FINAL_CFLAGS}
+
+else
+        $(warning "WARNING: Too old linker version $(call ld-version) for kernel LTO. You need Linux binutils. CONFIG_LTO disabled.")
+endif
+else
+        $(warning "WARNING: Compiler/Linker does not support LTO/WHOPR with linker plugin. CONFIG_LTO disabled.")
+endif
+else
+        $(warning "WARNING: GCC $(call cc-version) too old for LTO/WHOPR. CONFIG_LTO disabled")
+endif
+endif
index 69f0a1417e9a47669f5568af2097f031c247e607..9c40daea846cdbe932328d73b789f2a634c8f8c6 100644 (file)
@@ -77,7 +77,8 @@ modpost = scripts/mod/modpost                    \
  $(if $(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(KBUILD_EXTRA_SYMBOLS))) \
  $(if $(KBUILD_EXTMOD),-o $(modulesymfile))      \
  $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S)      \
- $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
+ $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
+ $(if $(CONFIG_LTO),-w)
 
 MODPOST_OPT=$(subst -i,-n,$(filter -i,$(MAKEFLAGS)))
 
@@ -115,8 +116,8 @@ $(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
 targets += $(modules:.ko=.mod.o)
 
 # Step 6), final link of the modules
-quiet_cmd_ld_ko_o = LD [M]  $@
-      cmd_ld_ko_o = $(LD) -r $(LDFLAGS)                                 \
+quiet_cmd_ld_ko_o = LDFINAL [M]  $@
+      cmd_ld_ko_o = $(LDFINAL) -r $(LDFLAGS)                            \
                              $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
                              -o $@ $(filter-out FORCE,$^)
 
index bbf901afb606bcbd8c01e09a2b5063f4ae522e76..b2d758188f2f404b22c8c691b87d0e43a0404f5d 100755 (executable)
@@ -30,7 +30,7 @@ FLAGS="$SPFLAGS --very-quiet"
 # spatch only allows include directories with the syntax "-I include"
 # while gcc also allows "-Iinclude" and "-include include"
 COCCIINCLUDE=${LINUXINCLUDE//-I/-I }
-COCCIINCLUDE=${COCCIINCLUDE//-include/-I}
+COCCIINCLUDE=${COCCIINCLUDE// -include/ --include}
 
 if [ "$C" = "1" -o "$C" = "2" ]; then
     ONLINE=1
index a42d70bf88b3b5f834eb5654d5e52519982568d4..52bd235286fa60bb345172d58805e9ae9d04fe0d 100644 (file)
@@ -16,19 +16,21 @@ virtual context
 @r2 depends on patch@
 expression E;
 @@
-- if (E)
+- if (E != NULL)
 (
--      kfree(E);
-+ kfree(E);
+  kfree(E);
 |
--      debugfs_remove(E);
-+ debugfs_remove(E);
+  debugfs_remove(E);
 |
--      debugfs_remove_recursive(E);
-+ debugfs_remove_recursive(E);
+  debugfs_remove_recursive(E);
 |
--      usb_free_urb(E);
-+ usb_free_urb(E);
+  usb_free_urb(E);
+|
+  kmem_cache_destroy(E);
+|
+  mempool_destroy(E);
+|
+  dma_pool_destroy(E);
 )
 
 @r depends on context || report || org @
@@ -36,8 +38,10 @@ expression E;
 position p;
 @@
 
-* if (E)
-*      \(kfree@p\|debugfs_remove@p\|debugfs_remove_recursive@p\|usb_free_urb\)(E);
+* if (E != NULL)
+*      \(kfree@p\|debugfs_remove@p\|debugfs_remove_recursive@p\|
+*         usb_free_urb@p\|kmem_cache_destroy@p\|mempool_destroy@p\|
+*         dma_pool_destroy@p\)(E);
 
 @script:python depends on org@
 p << r.p;
diff --git a/scripts/coccinelle/iterators/device_node_continue.cocci b/scripts/coccinelle/iterators/device_node_continue.cocci
new file mode 100644 (file)
index 0000000..38ab744
--- /dev/null
@@ -0,0 +1,100 @@
+/// Device node iterators put the previous value of the index variable, so an
+/// explicit put causes a double put.
+///
+// Confidence: High
+// Copyright: (C) 2015 Julia Lawall, Inria. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options: --no-includes --include-headers
+// Keywords: for_each_child_of_node, etc.
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+@r exists@
+expression e1,e2;
+local idexpression n;
+iterator name for_each_node_by_name, for_each_node_by_type,
+for_each_compatible_node, for_each_matching_node,
+for_each_matching_node_and_match, for_each_child_of_node,
+for_each_available_child_of_node, for_each_node_with_property;
+iterator i;
+position p1,p2;
+statement S;
+@@
+
+(
+(
+for_each_node_by_name(n,e1) S
+|
+for_each_node_by_type(n,e1) S
+|
+for_each_compatible_node(n,e1,e2) S
+|
+for_each_matching_node(n,e1) S
+|
+for_each_matching_node_and_match(n,e1,e2) S
+|
+for_each_child_of_node(e1,n) S
+|
+for_each_available_child_of_node(e1,n) S
+|
+for_each_node_with_property(n,e1) S
+)
+&
+i@p1(...) {
+   ... when != of_node_get(n)
+       when any
+   of_node_put@p2(n);
+   ... when any
+}
+)
+
+@s exists@
+local idexpression r.n;
+statement S;
+position r.p1,r.p2;
+iterator i;
+@@
+
+ of_node_put@p2(n);
+ ... when any
+ i@p1(..., n, ...)
+ S
+
+@t depends on s && patch && !context && !org && !report@
+local idexpression n;
+position r.p2;
+@@
+
+- of_node_put@p2(n);
+
+// ----------------------------------------------------------------------------
+
+@t_context depends on s && !patch && (context || org || report)@
+local idexpression n;
+position r.p2;
+position j0;
+@@
+
+*  of_node_put@j0@p2(n);
+
+// ----------------------------------------------------------------------------
+
+@script:python t_org depends on org@
+j0 << t_context.j0;
+@@
+
+msg = "ERROR: probable double put."
+coccilib.org.print_todo(j0[0], msg)
+
+// ----------------------------------------------------------------------------
+
+@script:python t_report depends on report@
+j0 << t_context.j0;
+@@
+
+msg = "ERROR: probable double put."
+coccilib.report.print_report(j0[0], msg)
+
diff --git a/scripts/coccinelle/misc/compare_const_fl.cocci b/scripts/coccinelle/misc/compare_const_fl.cocci
new file mode 100644 (file)
index 0000000..b5d4bab
--- /dev/null
@@ -0,0 +1,171 @@
+/// Move constants to the right of binary operators.
+//# Depends on personal taste in some cases.
+///
+// Confidence: Moderate
+// Copyright: (C) 2015 Copyright: (C) 2015 Julia Lawall, Inria. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options: --no-includes --include-headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+@r1 depends on patch && !context && !org && !report
+ disable bitor_comm, neg_if_exp@
+constant c,c1;
+local idexpression i;
+expression e,e1,e2;
+binary operator b = {==,!=,&,|};
+type t;
+@@
+
+(
+c b (c1)
+|
+sizeof(t) b e1
+|
+sizeof e b e1
+|
+i b e1
+|
+c | e1 | e2 | ...
+|
+c | (e ? e1 : e2)
+|
+- c
++ e
+b
+- e
++ c
+)
+
+@r2 depends on patch && !context && !org && !report
+ disable gtr_lss, gtr_lss_eq, not_int2@
+constant c,c1;
+expression e,e1,e2;
+binary operator b;
+binary operator b1 = {<,<=},b2 = {<,<=};
+binary operator b3 = {>,>=},b4 = {>,>=};
+local idexpression i;
+type t;
+@@
+
+(
+c b c1
+|
+sizeof(t) b e1
+|
+sizeof e b e1
+|
+ (e1 b1 e) && (e b2 e2)
+|
+ (e1 b3 e) && (e b4 e2)
+|
+i b e
+|
+- c < e
++ e > c
+|
+- c <= e
++ e >= c
+|
+- c > e
++ e < c
+|
+- c >= e
++ e <= c
+)
+
+// ----------------------------------------------------------------------------
+
+@r1_context depends on !patch && (context || org || report)
+ disable bitor_comm, neg_if_exp exists@
+type t;
+binary operator b = {==,!=,&,|};
+constant c, c1;
+expression e, e1, e2;
+local idexpression i;
+position j0;
+@@
+
+(
+c b (c1)
+|
+sizeof(t) b e1
+|
+sizeof e b e1
+|
+i b e1
+|
+c | e1 | e2 | ...
+|
+c | (e ? e1 : e2)
+|
+* c@j0 b e
+)
+
+@r2_context depends on !patch && (context || org || report)
+ disable gtr_lss, gtr_lss_eq, not_int2 exists@
+type t;
+binary operator b, b1 = {<,<=}, b2 = {<,<=}, b3 = {>,>=}, b4 = {>,>=};
+constant c, c1;
+expression e, e1, e2;
+local idexpression i;
+position j0;
+@@
+
+(
+c b c1
+|
+sizeof(t) b e1
+|
+sizeof e b e1
+|
+ (e1 b1 e) && (e b2 e2)
+|
+ (e1 b3 e) && (e b4 e2)
+|
+i b e
+|
+* c@j0 < e
+|
+* c@j0 <= e
+|
+* c@j0 > e
+|
+* c@j0 >= e
+)
+
+// ----------------------------------------------------------------------------
+
+@script:python r1_org depends on org@
+j0 << r1_context.j0;
+@@
+
+msg = "Move constant to right."
+coccilib.org.print_todo(j0[0], msg)
+
+@script:python r2_org depends on org@
+j0 << r2_context.j0;
+@@
+
+msg = "Move constant to right."
+coccilib.org.print_todo(j0[0], msg)
+
+// ----------------------------------------------------------------------------
+
+@script:python r1_report depends on report@
+j0 << r1_context.j0;
+@@
+
+msg = "Move constant to right."
+coccilib.report.print_report(j0[0], msg)
+
+@script:python r2_report depends on report@
+j0 << r2_context.j0;
+@@
+
+msg = "Move constant to right."
+coccilib.report.print_report(j0[0], msg)
+
index 3c934046a06042afb3982b9e001280f36bb2340e..2294915a19bc42c70b1cc2c3d510a7412526036b 100644 (file)
@@ -1,6 +1,6 @@
-/// Make sure of_device_id tables are NULL terminated
+/// Make sure (of/i2c/platform)_device_id tables are NULL terminated
 //
-// Keywords: of_table
+// Keywords: of_table i2c_table platform_table
 // Confidence: Medium
 // Options: --include-headers
 
@@ -13,18 +13,26 @@ virtual report
 identifier var, arr;
 expression E;
 @@
-struct of_device_id arr[] = {
+(
+struct \(of_device_id \| i2c_device_id \| platform_device_id\) arr[] = {
        ...,
        {
        .var = E,
 *      }
 };
+|
+struct \(of_device_id \| i2c_device_id \| platform_device_id\) arr[] = {
+       ...,
+*      { ..., E, ... },
+};
+)
 
 @depends on patch@
 identifier var, arr;
 expression E;
 @@
-struct of_device_id arr[] = {
+(
+struct \(of_device_id \| i2c_device_id \| platform_device_id\) arr[] = {
        ...,
        {
        .var = E,
@@ -32,19 +40,34 @@ struct of_device_id arr[] = {
 +      },
 +      { }
 };
+|
+struct \(of_device_id \| i2c_device_id \| platform_device_id\) arr[] = {
+       ...,
+       { ..., E, ... },
++      { },
+};
+)
 
 @r depends on org || report@
 position p1;
 identifier var, arr;
 expression E;
 @@
-struct of_device_id arr[] = {
+(
+struct \(of_device_id \| i2c_device_id \| platform_device_id\) arr[] = {
        ...,
        {
        .var = E,
        }
        @p1
 };
+|
+struct \(of_device_id \| i2c_device_id \| platform_device_id\) arr[] = {
+       ...,
+       { ..., E, ... }
+       @p1
+};
+)
 
 @script:python depends on org@
 p1 << r.p1;
diff --git a/scripts/coccinelle/misc/simple_return.cocci b/scripts/coccinelle/misc/simple_return.cocci
deleted file mode 100644 (file)
index e8b6313..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/// Simplify a trivial if-return sequence.  Possibly combine with a
-/// preceding function call.
-///
-// Confidence: High
-// Copyright: (C) 2014 Julia Lawall, INRIA/LIP6.  GPLv2.
-// Copyright: (C) 2014 Gilles Muller, INRIA/LiP6.  GPLv2.
-// URL: http://coccinelle.lip6.fr/
-// Comments:
-// Options: --no-includes --include-headers
-
-virtual patch
-virtual context
-virtual org
-virtual report
-
-@r depends on patch@
-local idexpression e;
-identifier i,f,fn;
-@@
-
-fn(...) { <...
-- e@i =
-+ return
-    f(...);
--if (i != 0) return i;
--return 0;
-...> }
-
-@depends on patch@
-identifier r.i;
-type t;
-@@
-
--t i;
- ... when != i
-
-@depends on patch@
-expression e;
-@@
-
--if (e != 0)
-   return e;
--return 0;
-
-// -----------------------------------------------------------------------
-
-@s1 depends on context || org || report@
-local idexpression e;
-identifier i,f,fn;
-position p,p1,p2;
-@@
-
-fn(...) { <...
-* e@i@p = f(...);
-  if (\(i@p1 != 0\|i@p2 < 0\))
-     return i;
-  return 0;
-...> }
-
-@s2 depends on context || org || report forall@
-identifier s1.i;
-type t;
-position q,s1.p;
-expression e,f;
-@@
-
-* t i@q;
-  ... when != i
-  e@p = f(...);
-
-@s3 depends on context || org || report@
-expression e;
-position p1!=s1.p1;
-position p2!=s1.p2;
-@@
-
-*if (\(e@p1 != 0\|e@p2 < 0\))
-   return e;
- return 0;
-
-// -----------------------------------------------------------------------
-
-@script:python depends on org@
-p << s1.p;
-p1 << s1.p1;
-q << s2.q;
-@@
-
-cocci.print_main("decl",q)
-cocci.print_secs("use",p)
-cocci.include_match(False)
-
-@script:python depends on org@
-p << s1.p;
-p2 << s1.p2;
-q << s2.q;
-@@
-
-cocci.print_main("decl",q)
-cocci.print_secs("use with questionable test",p)
-cocci.include_match(False)
-
-@script:python depends on org@
-p << s1.p;
-p1 << s1.p1;
-@@
-
-cocci.print_main("use",p)
-
-@script:python depends on org@
-p << s1.p;
-p2 << s1.p2;
-@@
-
-cocci.print_main("use with questionable test",p)
-
-@script:python depends on org@
-p << s3.p1;
-@@
-
-cocci.print_main("test",p)
-
-@script:python depends on org@
-p << s3.p2;
-@@
-
-cocci.print_main("questionable test",p)
-
-// -----------------------------------------------------------------------
-
-@script:python depends on report@
-p << s1.p;
-p1 << s1.p1;
-q << s2.q;
-@@
-
-msg = "WARNING: end returns can be simpified and declaration on line %s can be dropped" % (q[0].line)
-coccilib.report.print_report(p[0],msg)
-cocci.include_match(False)
-
-@script:python depends on report@
-p << s1.p;
-p1 << s1.p1;
-q << s2.q
-;
-@@
-
-msg = "WARNING: end returns may be simpified if negative or 0 value and declaration on line %s can be dropped" % (q[0].line)
-coccilib.report.print_report(p[0],msg)
-cocci.include_match(False)
-
-@script:python depends on report@
-p << s1.p;
-p1 << s1.p1;
-@@
-
-msg = "WARNING: end returns can be simpified"
-coccilib.report.print_report(p[0],msg)
-
-@script:python depends on report@
-p << s1.p;
-p2 << s1.p2;
-@@
-
-msg = "WARNING: end returns can be simpified if negative or 0 value"
-coccilib.report.print_report(p[0],msg)
-
-@script:python depends on report@
-p << s3.p1;
-@@
-
-msg = "WARNING: end returns can be simpified"
-coccilib.report.print_report(p[0],msg)
-
-@script:python depends on report@
-p << s3.p2;
-@@
-
-msg = "WARNING: end returns can be simpified if tested value is negative or 0"
-coccilib.report.print_report(p[0],msg)
index cdac6cfcce92cc8ab25304806fbff81991b51dad..f192d6035d023b0be83e88c4acb691546722a015 100644 (file)
@@ -1,6 +1,6 @@
 ///
-/// A variable is dereference under a NULL test.
-/// Even though it is know to be NULL.
+/// A variable is dereferenced under a NULL test.
+/// Even though it is known to be NULL.
 ///
 // Confidence: Moderate
 // Copyright: (C) 2010 Nicolas Palix, DIKU.  GPLv2.
index cfe0a35cf2dd219090d6186996fd3a5ca6b94fda..dfc6b40c29698417c32c9c50eb22ad1b5c81044d 100644 (file)
@@ -1,12 +1,11 @@
 /// PTR_ERR should access the value just tested by IS_ERR
-//# There can be false positives in the patch case, where it is the call
+//# There can be false positives in the patch case, where it is the call to
 //# IS_ERR that is wrong.
 ///
 // Confidence: High
-// Copyright: (C) 2012 Julia Lawall, INRIA.  GPLv2.
-// Copyright: (C) 2012 Gilles Muller, INRIA.  GPLv2.
+// Copyright: (C) 2012, 2015 Julia Lawall, INRIA.  GPLv2.
+// Copyright: (C) 2012, 2015 Gilles Muller, INRIA.  GPLv2.
 // URL: http://coccinelle.lip6.fr/
-// Comments:
 // Options: --no-includes --include-headers
 
 virtual patch
@@ -14,52 +13,105 @@ virtual context
 virtual org
 virtual report
 
-@depends on patch@
-expression e,e1;
+@ok1 exists@
+expression x,e;
+position p;
 @@
 
+if (IS_ERR(x=e) || ...) {
+  <...
+   PTR_ERR@p(x)
+  ...>
+}
+
+@ok2 exists@
+expression x,e1,e2;
+position p;
+@@
+
+if (IS_ERR(x) || ...) {
+  <...
 (
-if (IS_ERR(e)) { ... PTR_ERR(e) ... }
+   PTR_ERR@p(\(e1 ? e2 : x\|e1 ? x : e2\))
 |
-if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... }
+   PTR_ERR@p(x)
+)
+  ...>
+}
+
+@r1 depends on patch && !context && !org && !report exists@
+expression x,y;
+position p != {ok1.p,ok2.p};
+@@
+
+if (IS_ERR(x) || ...) {
+  ... when any
+      when != IS_ERR(...)
+(
+  PTR_ERR(x)
 |
-if (IS_ERR(e))
- { ...
-  PTR_ERR(
--   e1
-+   e
+  PTR_ERR@p(
+-     y
++     x
   )
-   ... }
 )
+  ... when any
+}
+
+// ----------------------------------------------------------------------------
 
-@r depends on !patch@
-expression e,e1;
-position p1,p2;
+@r1_context depends on !patch && (context || org || report) exists@
+position p != {ok1.p,ok2.p};
+expression x, y;
+position j0, j1;
 @@
 
+if (IS_ERR@j0(x) || ...) {
+  ... when any
+      when != IS_ERR(...)
 (
-if (IS_ERR(e)) { ... PTR_ERR(e) ... }
+  PTR_ERR(x)
 |
-if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... }
-|
-*if (IS_ERR@p1(e))
- { ...
-*  PTR_ERR@p2(e1)
-   ... }
+  PTR_ERR@j1@p(
+     y
+  )
 )
+  ... when any
+}
 
-@script:python depends on org@
-p1 << r.p1;
-p2 << r.p2;
+@r1_disj depends on !patch && (context || org || report) exists@
+position p != {ok1.p,ok2.p};
+expression x, y;
+position r1_context.j0, r1_context.j1;
 @@
 
-cocci.print_main("inconsistent IS_ERR and PTR_ERR",p1)
-cocci.print_secs("PTR_ERR",p2)
+* if (IS_ERR@j0(x) || ...) {
+  ... when any
+      when != IS_ERR(...)
+*   PTR_ERR@j1@p(
+     y
+  )
+  ... when any
+}
 
-@script:python depends on report@
-p1 << r.p1;
-p2 << r.p2;
+// ----------------------------------------------------------------------------
+
+@script:python r1_org depends on org@
+j0 << r1_context.j0;
+j1 << r1_context.j1;
 @@
 
-msg = "inconsistent IS_ERR and PTR_ERR, PTR_ERR on line %s" % (p2[0].line)
-coccilib.report.print_report(p1[0],msg)
+msg = "inconsistent IS_ERR and PTR_ERR"
+coccilib.org.print_todo(j0[0], msg)
+coccilib.org.print_link(j1[0], "")
+
+// ----------------------------------------------------------------------------
+
+@script:python r1_report depends on report@
+j0 << r1_context.j0;
+j1 << r1_context.j1;
+@@
+
+msg = "inconsistent IS_ERR and PTR_ERR on line %s." % (j1[0].line)
+coccilib.report.print_report(j0[0], msg)
+
index 3043d6b0b51d4e84802087f0526d30eb65422702..d79cba4ce3ebfb24a660da011076deb81a6ff4ad 100644 (file)
@@ -229,49 +229,21 @@ $(obj)/.tmp_qtcheck: $(src)/Makefile
 
 # Qt needs some extra effort...
 $(obj)/.tmp_qtcheck:
-       @set -e; $(kecho) "  CHECK   qt"; dir=""; pkg=""; \
-       if ! pkg-config --exists QtCore 2> /dev/null; then \
-           echo "* Unable to find the Qt4 tool qmake. Trying to use Qt3"; \
-           pkg-config --exists qt 2> /dev/null && pkg=qt; \
-           pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \
-           if [ -n "$$pkg" ]; then \
-             cflags="\$$(shell pkg-config $$pkg --cflags)"; \
-             libs="\$$(shell pkg-config $$pkg --libs)"; \
-             moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \
-             dir="$$(pkg-config $$pkg --variable=prefix)"; \
-           else \
-             for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \
-               if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \
-             done; \
-             if [ -z "$$dir" ]; then \
-               echo >&2 "*"; \
-               echo >&2 "* Unable to find any Qt installation. Please make sure that"; \
-               echo >&2 "* the Qt4 or Qt3 development package is correctly installed and"; \
-               echo >&2 "* either qmake can be found or install pkg-config or set"; \
-               echo >&2 "* the QTDIR environment variable to the correct location."; \
-               echo >&2 "*"; \
-               false; \
-             fi; \
-             libpath=$$dir/lib; lib=qt; osdir=""; \
-             $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
-               osdir=x$$($(HOSTCXX) -print-multi-os-directory); \
-             test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \
-             test -f $$libpath/libqt-mt.so && lib=qt-mt; \
-             cflags="-I$$dir/include"; \
-             libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \
-             moc="$$dir/bin/moc"; \
-           fi; \
-           if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \
-             echo "*"; \
-             echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \
-             echo "*"; \
-             moc="/usr/bin/moc"; \
-           fi; \
+       @set -e; $(kecho) "  CHECK   qt"; \
+       if pkg-config --exists Qt5Core; then \
+           cflags="-std=c++11 -fPIC `pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets`"; \
+           libs=`pkg-config --libs Qt5Core Qt5Gui Qt5Widgets`; \
+           moc=`pkg-config --variable=host_bins Qt5Core`/moc; \
+       elif pkg-config --exists QtCore; then \
+           cflags=`pkg-config --cflags QtCore QtGui`; \
+           libs=`pkg-config --libs QtCore QtGui`; \
+           moc=`pkg-config --variable=moc_location QtCore`; \
        else \
-         cflags="\$$(shell pkg-config QtCore QtGui Qt3Support --cflags)"; \
-         libs="\$$(shell pkg-config QtCore QtGui Qt3Support --libs)"; \
-         moc="\$$(shell pkg-config QtCore --variable=moc_location)"; \
-         [ -n "$$moc" ] || moc="\$$(shell pkg-config QtCore --variable=prefix)/bin/moc"; \
+           echo >&2 "*"; \
+           echo >&2 "* Could not find Qt via pkg-config."; \
+           echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"; \
+           echo >&2 "*"; \
+           exit 1; \
        fi; \
        echo "KC_QT_CFLAGS=$$cflags" > $@; \
        echo "KC_QT_LIBS=$$libs" >> $@; \
index 667d1aa237114453c28bafac618e9552405a19c4..cbf4996dd9c1045ecc7ffa66a9ec79edd99b1038 100644 (file)
@@ -1113,7 +1113,7 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *
                        fn(data, e->left.sym, e->left.sym->name);
                else
                        fn(data, NULL, "<choice>");
-               fn(data, NULL, e->type == E_LEQ ? ">=" : ">");
+               fn(data, NULL, e->type == E_GEQ ? ">=" : ">");
                fn(data, e->right.sym, e->right.sym->name);
                break;
        case E_UNEQUAL:
index 0d883b37882a145b588a45f53f3be373849e7410..67d1314476314590f285a63700c13e047dc17c80 100755 (executable)
@@ -32,7 +32,7 @@ usage() {
        echo "  -m    only merge the fragments, do not execute the make command"
        echo "  -n    use allnoconfig instead of alldefconfig"
        echo "  -r    list redundant entries when merging fragments"
-       echo "  -O    dir to put generated output files"
+       echo "  -O    dir to put generated output files.  Consider setting \$KCONFIG_CONFIG instead."
 }
 
 RUNMAKE=true
@@ -77,11 +77,19 @@ while true; do
        esac
 done
 
-if [ "$#" -lt 2 ] ; then
+if [ "$#" -lt 1 ] ; then
        usage
        exit
 fi
 
+if [ -z "$KCONFIG_CONFIG" ]; then
+       if [ "$OUTPUT" != . ]; then
+               KCONFIG_CONFIG=$(readlink -m -- "$OUTPUT/.config")
+       else
+               KCONFIG_CONFIG=.config
+       fi
+fi
+
 INITFILE=$1
 shift;
 
@@ -124,9 +132,9 @@ for MERGE_FILE in $MERGE_LIST ; do
 done
 
 if [ "$RUNMAKE" = "false" ]; then
-       cp $TMP_FILE $OUTPUT/.config
+       cp -T -- "$TMP_FILE" "$KCONFIG_CONFIG"
        echo "#"
-       echo "# merged configuration written to $OUTPUT/.config (needs make)"
+       echo "# merged configuration written to $KCONFIG_CONFIG (needs make)"
        echo "#"
        clean_up
        exit
@@ -150,7 +158,7 @@ make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET
 for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do
 
        REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE)
-       ACTUAL_VAL=$(grep -w -e "$CFG" $OUTPUT/.config)
+       ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG")
        if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then
                echo "Value requested for $CFG not in final .config"
                echo "Requested value:  $REQUESTED_VAL"
index c3bb7fe8dfa68322bff34481b3de72b9ad2b2b3f..91b7e6fbc364ae53846130eb2a82517c422eb5d4 100644 (file)
@@ -1,32 +1,17 @@
 /*
  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
  * Released under the terms of the GNU GPL v2.0.
  */
 
 #include <qglobal.h>
 
-#if QT_VERSION < 0x040000
-#include <stddef.h>
-#include <qmainwindow.h>
-#include <qvbox.h>
-#include <qvaluelist.h>
+#include <QMainWindow>
+#include <QList>
 #include <qtextbrowser.h>
-#include <qaction.h>
-#include <qheader.h>
-#include <qfiledialog.h>
-#include <qdragobject.h>
-#include <qpopupmenu.h>
-#else
-#include <q3mainwindow.h>
-#include <q3vbox.h>
-#include <q3valuelist.h>
-#include <q3textbrowser.h>
-#include <q3action.h>
-#include <q3header.h>
-#include <q3filedialog.h>
-#include <q3dragobject.h>
-#include <q3popupmenu.h>
-#endif
+#include <QAction>
+#include <QFileDialog>
+#include <QMenu>
 
 #include <qapplication.h>
 #include <qdesktopwidget.h>
@@ -57,7 +42,7 @@
 static QApplication *configApp;
 static ConfigSettings *configSettings;
 
-Q3Action *ConfigMainWindow::saveAction;
+QAction *ConfigMainWindow::saveAction;
 
 static inline QString qgettext(const char* str)
 {
@@ -66,7 +51,7 @@ static inline QString qgettext(const char* str)
 
 static inline QString qgettext(const QString& str)
 {
-       return QString::fromLocal8Bit(gettext(str.latin1()));
+       return QString::fromLocal8Bit(gettext(str.toLatin1()));
 }
 
 ConfigSettings::ConfigSettings()
@@ -77,10 +62,10 @@ ConfigSettings::ConfigSettings()
 /**
  * Reads a list of integer values from the application settings.
  */
-Q3ValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
+QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
 {
-       Q3ValueList<int> result;
-       QStringList entryList = readListEntry(key, ok);
+       QList<int> result;
+       QStringList entryList = value(key).toStringList();
        QStringList::Iterator it;
 
        for (it = entryList.begin(); it != entryList.end(); ++it)
@@ -92,14 +77,16 @@ Q3ValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
 /**
  * Writes a list of integer values to the application settings.
  */
-bool ConfigSettings::writeSizes(const QString& key, const Q3ValueList<int>& value)
+bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
 {
        QStringList stringList;
-       Q3ValueList<int>::ConstIterator it;
+       QList<int>::ConstIterator it;
 
        for (it = value.begin(); it != value.end(); ++it)
                stringList.push_back(QString::number(*it));
-       return writeEntry(key, stringList);
+       setValue(key, stringList);
+
+       return true;
 }
 
 
@@ -109,9 +96,6 @@ bool ConfigSettings::writeSizes(const QString& key, const Q3ValueList<int>& valu
  */
 void ConfigItem::okRename(int col)
 {
-       Parent::okRename(col);
-       sym_set_string_value(menu->sym, text(dataColIdx).latin1());
-       listView()->updateList(this);
 }
 
 /*
@@ -149,11 +133,11 @@ void ConfigItem::updateMenu(void)
                } else {
                        if (sym)
                                break;
-                       setPixmap(promptColIdx, 0);
+                       setPixmap(promptColIdx, QIcon());
                }
                goto set_prompt;
        case P_COMMENT:
-               setPixmap(promptColIdx, 0);
+               setPixmap(promptColIdx, QIcon());
                goto set_prompt;
        default:
                ;
@@ -170,7 +154,7 @@ void ConfigItem::updateMenu(void)
                char ch;
 
                if (!sym_is_changable(sym) && list->optMode == normalOpt) {
-                       setPixmap(promptColIdx, 0);
+                       setPixmap(promptColIdx, QIcon());
                        setText(noColIdx, QString::null);
                        setText(modColIdx, QString::null);
                        setText(yesColIdx, QString::null);
@@ -216,9 +200,6 @@ void ConfigItem::updateMenu(void)
 
                data = sym_get_string_value(sym);
 
-               int i = list->mapIdx(dataColIdx);
-               if (i >= 0)
-                       setRenameEnabled(i, TRUE);
                setText(dataColIdx, data);
                if (type == S_STRING)
                        prompt = QString("%1: %2").arg(prompt).arg(data);
@@ -250,18 +231,6 @@ void ConfigItem::testUpdateMenu(bool v)
                updateMenu();
 }
 
-void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
-{
-       ConfigList* list = listView();
-
-       if (visible) {
-               if (isSelected() && !list->hasFocus() && list->mode == menuMode)
-                       Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
-               else
-                       Parent::paintCell(p, cg, column, width, align);
-       } else
-               Parent::paintCell(p, list->disabledColorGroup, column, width, align);
-}
 
 /*
  * construct a menu entry
@@ -274,7 +243,7 @@ void ConfigItem::init(void)
                menu->data = this;
 
                if (list->mode != fullMode)
-                       setOpen(TRUE);
+                       setExpanded(true);
                sym_calc_value(menu->sym);
        }
        updateMenu();
@@ -299,7 +268,7 @@ ConfigItem::~ConfigItem(void)
 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
        : Parent(parent)
 {
-       connect(this, SIGNAL(lostFocus()), SLOT(hide()));
+       connect(this, SIGNAL(editingFinished()), SLOT(hide()));
 }
 
 void ConfigLineEdit::show(ConfigItem* i)
@@ -320,7 +289,7 @@ void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
                break;
        case Qt::Key_Return:
        case Qt::Key_Enter:
-               sym_set_string_value(item->menu->sym, text().latin1());
+               sym_set_string_value(item->menu->sym, text().toLatin1());
                parent()->updateList(item);
                break;
        default:
@@ -333,39 +302,39 @@ void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
 }
 
 ConfigList::ConfigList(ConfigView* p, const char *name)
-       : Parent(p, name),
+       : Parent(p),
          updateAll(false),
          symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
          choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
          menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
-         showName(false), showRange(false), showData(false), optMode(normalOpt),
+         showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
          rootEntry(0), headerPopup(0)
 {
        int i;
 
-       setSorting(-1);
-       setRootIsDecorated(TRUE);
-       disabledColorGroup = palette().active();
-       disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
-       inactivedColorGroup = palette().active();
-       inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
+       setObjectName(name);
+       setSortingEnabled(false);
+       setRootIsDecorated(true);
+
+       setVerticalScrollMode(ScrollPerPixel);
+       setHorizontalScrollMode(ScrollPerPixel);
+
+       setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value"));
 
-       connect(this, SIGNAL(selectionChanged(void)),
+       connect(this, SIGNAL(itemSelectionChanged(void)),
                SLOT(updateSelection(void)));
 
        if (name) {
                configSettings->beginGroup(name);
-               showName = configSettings->readBoolEntry("/showName", false);
-               showRange = configSettings->readBoolEntry("/showRange", false);
-               showData = configSettings->readBoolEntry("/showData", false);
-               optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
+               showName = configSettings->value("/showName", false).toBool();
+               showRange = configSettings->value("/showRange", false).toBool();
+               showData = configSettings->value("/showData", false).toBool();
+               optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
                configSettings->endGroup();
                connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
        }
 
-       for (i = 0; i < colNr; i++)
-               colMap[i] = colRevMap[i] = -1;
-       addColumn(promptColIdx, _("Option"));
+       addColumn(promptColIdx);
 
        reinit();
 }
@@ -390,26 +359,26 @@ void ConfigList::reinit(void)
        removeColumn(nameColIdx);
 
        if (showName)
-               addColumn(nameColIdx, _("Name"));
+               addColumn(nameColIdx);
        if (showRange) {
-               addColumn(noColIdx, "N");
-               addColumn(modColIdx, "M");
-               addColumn(yesColIdx, "Y");
+               addColumn(noColIdx);
+               addColumn(modColIdx);
+               addColumn(yesColIdx);
        }
        if (showData)
-               addColumn(dataColIdx, _("Value"));
+               addColumn(dataColIdx);
 
        updateListAll();
 }
 
 void ConfigList::saveSettings(void)
 {
-       if (name()) {
-               configSettings->beginGroup(name());
-               configSettings->writeEntry("/showName", showName);
-               configSettings->writeEntry("/showRange", showRange);
-               configSettings->writeEntry("/showData", showData);
-               configSettings->writeEntry("/optionMode", (int)optMode);
+       if (!objectName().isEmpty()) {
+               configSettings->beginGroup(objectName());
+               configSettings->setValue("/showName", showName);
+               configSettings->setValue("/showRange", showRange);
+               configSettings->setValue("/showData", showData);
+               configSettings->setValue("/optionMode", (int)optMode);
                configSettings->endGroup();
        }
 }
@@ -431,7 +400,10 @@ void ConfigList::updateSelection(void)
        struct menu *menu;
        enum prop_type type;
 
-       ConfigItem* item = (ConfigItem*)selectedItem();
+       if (selectedItems().count() == 0)
+               return;
+
+       ConfigItem* item = (ConfigItem*)selectedItems().first();
        if (!item)
                return;
 
@@ -451,21 +423,23 @@ void ConfigList::updateList(ConfigItem* item)
        if (!rootEntry) {
                if (mode != listMode)
                        goto update;
-               Q3ListViewItemIterator it(this);
+               QTreeWidgetItemIterator it(this);
                ConfigItem* item;
 
-               for (; it.current(); ++it) {
-                       item = (ConfigItem*)it.current();
+               while (*it) {
+                       item = (ConfigItem*)(*it);
                        if (!item->menu)
                                continue;
                        item->testUpdateMenu(menu_is_visible(item->menu));
+
+                       ++it;
                }
                return;
        }
 
        if (rootEntry != &rootmenu && (mode == singleMode ||
            (mode == symbolMode && rootEntry->parent != &rootmenu))) {
-               item = firstChild();
+               item = (ConfigItem *)topLevelItem(0);
                if (!item)
                        item = new ConfigItem(this, 0, true);
                last = item;
@@ -479,12 +453,14 @@ void ConfigList::updateList(ConfigItem* item)
                        item->testUpdateMenu(true);
 
                updateMenuList(item, rootEntry);
-               triggerUpdate();
+               update();
+               resizeColumnToContents(0);
                return;
        }
 update:
        updateMenuList(this, rootEntry);
-       triggerUpdate();
+       update();
+       resizeColumnToContents(0);
 }
 
 void ConfigList::setValue(ConfigItem* item, tristate val)
@@ -506,7 +482,7 @@ void ConfigList::setValue(ConfigItem* item, tristate val)
                if (!sym_set_tristate_value(sym, val))
                        return;
                if (oldval == no && item->menu->list)
-                       item->setOpen(TRUE);
+                       item->setExpanded(true);
                parent()->updateList(item);
                break;
        }
@@ -524,7 +500,7 @@ void ConfigList::changeValue(ConfigItem* item)
        sym = menu->sym;
        if (!sym) {
                if (item->menu->list)
-                       item->setOpen(!item->isOpen());
+                       item->setExpanded(!item->isExpanded());
                return;
        }
 
@@ -536,9 +512,9 @@ void ConfigList::changeValue(ConfigItem* item)
                newexpr = sym_toggle_tristate_value(sym);
                if (item->menu->list) {
                        if (oldexpr == newexpr)
-                               item->setOpen(!item->isOpen());
+                               item->setExpanded(!item->isExpanded());
                        else if (oldexpr == no)
-                               item->setOpen(TRUE);
+                               item->setExpanded(true);
                }
                if (oldexpr != newexpr)
                        parent()->updateList(item);
@@ -546,10 +522,7 @@ void ConfigList::changeValue(ConfigItem* item)
        case S_INT:
        case S_HEX:
        case S_STRING:
-               if (colMap[dataColIdx] >= 0)
-                       item->startRename(colMap[dataColIdx]);
-               else
-                       parent()->lineEdit->show(item);
+               parent()->lineEdit->show(item);
                break;
        }
 }
@@ -566,8 +539,10 @@ void ConfigList::setRootMenu(struct menu *menu)
        updateMenuList(this, 0);
        rootEntry = menu;
        updateListAll();
-       setSelected(currentItem(), hasFocus());
-       ensureItemVisible(currentItem());
+       if (currentItem()) {
+               currentItem()->setSelected(hasFocus());
+               scrollToItem(currentItem());
+       }
 }
 
 void ConfigList::setParentMenu(void)
@@ -580,13 +555,16 @@ void ConfigList::setParentMenu(void)
                return;
        setRootMenu(menu_get_parent_menu(rootEntry->parent));
 
-       Q3ListViewItemIterator it(this);
-       for (; (item = (ConfigItem*)it.current()); it++) {
+       QTreeWidgetItemIterator it(this);
+       while (*it) {
+               item = (ConfigItem *)(*it);
                if (item->menu == oldroot) {
                        setCurrentItem(item);
-                       ensureItemVisible(item);
+                       scrollToItem(item);
                        break;
                }
+
+               ++it;
        }
 }
 
@@ -597,8 +575,7 @@ void ConfigList::setParentMenu(void)
  * parent: either the menu list widget or a menu entry widget
  * menu: entry to be updated
  */
-template <class P>
-void ConfigList::updateMenuList(P* parent, struct menu* menu)
+void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
 {
        struct menu* child;
        ConfigItem* item;
@@ -607,8 +584,11 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu)
        enum prop_type type;
 
        if (!menu) {
-               while ((item = parent->firstChild()))
-                       delete item;
+               while (parent->childCount() > 0)
+               {
+                       delete parent->takeChild(0);
+               }
+
                return;
        }
 
@@ -660,9 +640,74 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu)
        }
 }
 
+void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
+{
+       struct menu* child;
+       ConfigItem* item;
+       ConfigItem* last;
+       bool visible;
+       enum prop_type type;
+
+       if (!menu) {
+               while (parent->topLevelItemCount() > 0)
+               {
+                       delete parent->takeTopLevelItem(0);
+               }
+
+               return;
+       }
+
+       last = (ConfigItem*)parent->topLevelItem(0);
+       if (last && !last->goParent)
+               last = 0;
+       for (child = menu->list; child; child = child->next) {
+               item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
+               type = child->prompt ? child->prompt->type : P_UNKNOWN;
+
+               switch (mode) {
+               case menuMode:
+                       if (!(child->flags & MENU_ROOT))
+                               goto hide;
+                       break;
+               case symbolMode:
+                       if (child->flags & MENU_ROOT)
+                               goto hide;
+                       break;
+               default:
+                       break;
+               }
+
+               visible = menu_is_visible(child);
+               if (!menuSkip(child)) {
+                       if (!child->sym && !child->list && !child->prompt)
+                               continue;
+                       if (!item || item->menu != child)
+                               item = new ConfigItem(parent, last, child, visible);
+                       else
+                               item->testUpdateMenu(visible);
+
+                       if (mode == fullMode || mode == menuMode || type != P_MENU)
+                               updateMenuList(item, child);
+                       else
+                               updateMenuList(item, 0);
+                       last = item;
+                       continue;
+               }
+       hide:
+               if (item && item->menu == child) {
+                       last = (ConfigItem*)parent->topLevelItem(0);
+                       if (last == item)
+                               last = 0;
+                       else while (last->nextSibling() != item)
+                               last = last->nextSibling();
+                       delete item;
+               }
+       }
+}
+
 void ConfigList::keyPressEvent(QKeyEvent* ev)
 {
-       Q3ListViewItem* i = currentItem();
+       QTreeWidgetItem* i = currentItem();
        ConfigItem* item;
        struct menu *menu;
        enum prop_type type;
@@ -714,20 +759,20 @@ void ConfigList::keyPressEvent(QKeyEvent* ev)
        ev->accept();
 }
 
-void ConfigList::contentsMousePressEvent(QMouseEvent* e)
+void ConfigList::mousePressEvent(QMouseEvent* e)
 {
        //QPoint p(contentsToViewport(e->pos()));
        //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
-       Parent::contentsMousePressEvent(e);
+       Parent::mousePressEvent(e);
 }
 
-void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
+void ConfigList::mouseReleaseEvent(QMouseEvent* e)
 {
-       QPoint p(contentsToViewport(e->pos()));
+       QPoint p = e->pos();
        ConfigItem* item = (ConfigItem*)itemAt(p);
        struct menu *menu;
        enum prop_type ptype;
-       const QPixmap* pm;
+       QIcon icon;
        int idx, x;
 
        if (!item)
@@ -735,14 +780,13 @@ void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
 
        menu = item->menu;
        x = header()->offset() + p.x();
-       idx = colRevMap[header()->sectionAt(x)];
+       idx = header()->logicalIndexAt(x);
        switch (idx) {
        case promptColIdx:
-               pm = item->pixmap(promptColIdx);
-               if (pm) {
-                       int off = header()->sectionPos(0) + itemMargin() +
-                               treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
-                       if (x >= off && x < off + pm->width()) {
+               icon = item->pixmap(promptColIdx);
+               if (!icon.isNull()) {
+                       int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
+                       if (x >= off && x < off + icon.availableSizes().first().width()) {
                                if (item->goParent) {
                                        emit parentSelected();
                                        break;
@@ -773,19 +817,19 @@ void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
 
 skip:
        //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
-       Parent::contentsMouseReleaseEvent(e);
+       Parent::mouseReleaseEvent(e);
 }
 
-void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
+void ConfigList::mouseMoveEvent(QMouseEvent* e)
 {
        //QPoint p(contentsToViewport(e->pos()));
        //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
-       Parent::contentsMouseMoveEvent(e);
+       Parent::mouseMoveEvent(e);
 }
 
-void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
+void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
 {
-       QPoint p(contentsToViewport(e->pos()));
+       QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
        ConfigItem* item = (ConfigItem*)itemAt(p);
        struct menu *menu;
        enum prop_type ptype;
@@ -807,7 +851,7 @@ void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
 
 skip:
        //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
-       Parent::contentsMouseDoubleClickEvent(e);
+       Parent::mouseDoubleClickEvent(e);
 }
 
 void ConfigList::focusInEvent(QFocusEvent *e)
@@ -818,7 +862,7 @@ void ConfigList::focusInEvent(QFocusEvent *e)
 
        ConfigItem* item = (ConfigItem *)currentItem();
        if (item) {
-               setSelected(item, TRUE);
+               item->setSelected(true);
                menu = item->menu;
        }
        emit gotFocus(menu);
@@ -828,33 +872,33 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
 {
        if (e->y() <= header()->geometry().bottom()) {
                if (!headerPopup) {
-                       Q3Action *action;
+                       QAction *action;
 
-                       headerPopup = new Q3PopupMenu(this);
-                       action = new Q3Action(NULL, _("Show Name"), 0, this);
-                         action->setToggleAction(TRUE);
+                       headerPopup = new QMenu(this);
+                       action = new QAction(_("Show Name"), this);
+                         action->setCheckable(true);
                          connect(action, SIGNAL(toggled(bool)),
                                  parent(), SLOT(setShowName(bool)));
                          connect(parent(), SIGNAL(showNameChanged(bool)),
                                  action, SLOT(setOn(bool)));
-                         action->setOn(showName);
-                         action->addTo(headerPopup);
-                       action = new Q3Action(NULL, _("Show Range"), 0, this);
-                         action->setToggleAction(TRUE);
+                         action->setChecked(showName);
+                         headerPopup->addAction(action);
+                       action = new QAction(_("Show Range"), this);
+                         action->setCheckable(true);
                          connect(action, SIGNAL(toggled(bool)),
                                  parent(), SLOT(setShowRange(bool)));
                          connect(parent(), SIGNAL(showRangeChanged(bool)),
                                  action, SLOT(setOn(bool)));
-                         action->setOn(showRange);
-                         action->addTo(headerPopup);
-                       action = new Q3Action(NULL, _("Show Data"), 0, this);
-                         action->setToggleAction(TRUE);
+                         action->setChecked(showRange);
+                         headerPopup->addAction(action);
+                       action = new QAction(_("Show Data"), this);
+                         action->setCheckable(true);
                          connect(action, SIGNAL(toggled(bool)),
                                  parent(), SLOT(setShowData(bool)));
                          connect(parent(), SIGNAL(showDataChanged(bool)),
                                  action, SLOT(setOn(bool)));
-                         action->setOn(showData);
-                         action->addTo(headerPopup);
+                         action->setChecked(showData);
+                         headerPopup->addAction(action);
                }
                headerPopup->exec(e->globalPos());
                e->accept();
@@ -868,11 +912,17 @@ QAction *ConfigView::showAllAction;
 QAction *ConfigView::showPromptAction;
 
 ConfigView::ConfigView(QWidget* parent, const char *name)
-       : Parent(parent, name)
+       : Parent(parent)
 {
-       list = new ConfigList(this, name);
+       setObjectName(name);
+       QVBoxLayout *verticalLayout = new QVBoxLayout(this);
+       verticalLayout->setContentsMargins(0, 0, 0, 0);
+
+       list = new ConfigList(this);
+       verticalLayout->addWidget(list);
        lineEdit = new ConfigLineEdit(this);
        lineEdit->hide();
+       verticalLayout->addWidget(lineEdit);
 
        this->nextView = viewList;
        viewList = this;
@@ -931,10 +981,13 @@ void ConfigView::setShowData(bool b)
 
 void ConfigList::setAllOpen(bool open)
 {
-       Q3ListViewItemIterator it(this);
+       QTreeWidgetItemIterator it(this);
+
+       while (*it) {
+               (*it)->setExpanded(open);
 
-       for (; it.current(); it++)
-               it.current()->setOpen(open);
+               ++it;
+       }
 }
 
 void ConfigView::updateList(ConfigItem* item)
@@ -954,11 +1007,14 @@ void ConfigView::updateListAll(void)
 }
 
 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
-       : Parent(parent, name), sym(0), _menu(0)
+       : Parent(parent), sym(0), _menu(0)
 {
-       if (name) {
-               configSettings->beginGroup(name);
-               _showDebug = configSettings->readBoolEntry("/showDebug", false);
+       setObjectName(name);
+
+
+       if (!objectName().isEmpty()) {
+               configSettings->beginGroup(objectName());
+               _showDebug = configSettings->value("/showDebug", false).toBool();
                configSettings->endGroup();
                connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
        }
@@ -966,9 +1022,9 @@ ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
 
 void ConfigInfoView::saveSettings(void)
 {
-       if (name()) {
-               configSettings->beginGroup(name());
-               configSettings->writeEntry("/showDebug", showDebug());
+       if (!objectName().isEmpty()) {
+               configSettings->beginGroup(objectName());
+               configSettings->setValue("/showDebug", showDebug());
                configSettings->endGroup();
        }
 }
@@ -1127,8 +1183,8 @@ QString ConfigInfoView::print_filter(const QString &str)
 {
        QRegExp re("[<>&\"\\n]");
        QString res = str;
-       for (int i = 0; (i = res.find(re, i)) >= 0;) {
-               switch (res[i].latin1()) {
+       for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
+               switch (res[i].toLatin1()) {
                case '<':
                        res.replace(i, 1, "&lt;");
                        i += 4;
@@ -1167,37 +1223,42 @@ void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char
                *text += str2;
 }
 
-Q3PopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
+QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
 {
-       Q3PopupMenu* popup = Parent::createPopupMenu(pos);
-       Q3Action* action = new Q3Action(NULL, _("Show Debug Info"), 0, popup);
-         action->setToggleAction(TRUE);
+       QMenu* popup = Parent::createStandardContextMenu(pos);
+       QAction* action = new QAction(_("Show Debug Info"), popup);
+         action->setCheckable(true);
          connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
          connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
-         action->setOn(showDebug());
-       popup->insertSeparator();
-       action->addTo(popup);
+         action->setChecked(showDebug());
+       popup->addSeparator();
+       popup->addAction(action);
        return popup;
 }
 
-void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
+void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
 {
-       Parent::contentsContextMenuEvent(e);
+       Parent::contextMenuEvent(e);
 }
 
 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
-       : Parent(parent, name), result(NULL)
+       : Parent(parent), result(NULL)
 {
-       setCaption("Search Config");
+       setObjectName(name);
+       setWindowTitle("Search Config");
 
-       QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
-       QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
+       QVBoxLayout* layout1 = new QVBoxLayout(this);
+       layout1->setContentsMargins(11, 11, 11, 11);
+       layout1->setSpacing(6);
+       QHBoxLayout* layout2 = new QHBoxLayout(0);
+       layout2->setContentsMargins(0, 0, 0, 0);
+       layout2->setSpacing(6);
        layout2->addWidget(new QLabel(_("Find:"), this));
        editField = new QLineEdit(this);
        connect(editField, SIGNAL(returnPressed()), SLOT(search()));
        layout2->addWidget(editField);
        searchButton = new QPushButton(_("Search"), this);
-       searchButton->setAutoDefault(FALSE);
+       searchButton->setAutoDefault(false);
        connect(searchButton, SIGNAL(clicked()), SLOT(search()));
        layout2->addWidget(searchButton);
        layout1->addLayout(layout2);
@@ -1215,19 +1276,19 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam
        layout1->addWidget(split);
 
        if (name) {
-               int x, y, width, height;
+               QVariant x, y;
+               int width, height;
                bool ok;
 
                configSettings->beginGroup(name);
-               width = configSettings->readNumEntry("/window width", parent->width() / 2);
-               height = configSettings->readNumEntry("/window height", parent->height() / 2);
+               width = configSettings->value("/window width", parent->width() / 2).toInt();
+               height = configSettings->value("/window height", parent->height() / 2).toInt();
                resize(width, height);
-               x = configSettings->readNumEntry("/window x", 0, &ok);
-               if (ok)
-                       y = configSettings->readNumEntry("/window y", 0, &ok);
-               if (ok)
-                       move(x, y);
-               Q3ValueList<int> sizes = configSettings->readSizes("/split", &ok);
+               x = configSettings->value("/window x");
+               y = configSettings->value("/window y");
+               if ((x.isValid())&&(y.isValid()))
+                       move(x.toInt(), y.toInt());
+               QList<int> sizes = configSettings->readSizes("/split", &ok);
                if (ok)
                        split->setSizes(sizes);
                configSettings->endGroup();
@@ -1237,12 +1298,12 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam
 
 void ConfigSearchWindow::saveSettings(void)
 {
-       if (name()) {
-               configSettings->beginGroup(name());
-               configSettings->writeEntry("/window x", pos().x());
-               configSettings->writeEntry("/window y", pos().y());
-               configSettings->writeEntry("/window width", size().width());
-               configSettings->writeEntry("/window height", size().height());
+       if (!objectName().isEmpty()) {
+               configSettings->beginGroup(objectName());
+               configSettings->setValue("/window x", pos().x());
+               configSettings->setValue("/window y", pos().y());
+               configSettings->setValue("/window width", size().width());
+               configSettings->setValue("/window height", size().height());
                configSettings->writeSizes("/split", split->sizes());
                configSettings->endGroup();
        }
@@ -1258,7 +1319,7 @@ void ConfigSearchWindow::search(void)
        list->list->clear();
        info->clear();
 
-       result = sym_re_search(editField->text().latin1());
+       result = sym_re_search(editField->text().toLatin1());
        if (!result)
                return;
        for (p = result; *p; p++) {
@@ -1275,29 +1336,25 @@ ConfigMainWindow::ConfigMainWindow(void)
        : searchWindow(0)
 {
        QMenuBar* menu;
-       bool ok;
-       int x, y, width, height;
+       bool ok = true;
+       QVariant x, y;
+       int width, height;
        char title[256];
 
        QDesktopWidget *d = configApp->desktop();
        snprintf(title, sizeof(title), "%s%s",
                rootmenu.prompt->text,
-#if QT_VERSION < 0x040000
-               " (Qt3)"
-#else
                ""
-#endif
                );
-       setCaption(title);
+       setWindowTitle(title);
 
-       width = configSettings->readNumEntry("/window width", d->width() - 64);
-       height = configSettings->readNumEntry("/window height", d->height() - 64);
+       width = configSettings->value("/window width", d->width() - 64).toInt();
+       height = configSettings->value("/window height", d->height() - 64).toInt();
        resize(width, height);
-       x = configSettings->readNumEntry("/window x", 0, &ok);
-       if (ok)
-               y = configSettings->readNumEntry("/window y", 0, &ok);
-       if (ok)
-               move(x, y);
+       x = configSettings->value("/window x");
+       y = configSettings->value("/window y");
+       if ((x.isValid())&&(y.isValid()))
+               move(x.toInt(), y.toInt());
 
        split1 = new QSplitter(this);
        split1->setOrientation(Qt::Horizontal);
@@ -1314,127 +1371,115 @@ ConfigMainWindow::ConfigMainWindow(void)
        configList = configView->list;
 
        helpText = new ConfigInfoView(split2, "help");
-       helpText->setTextFormat(Qt::RichText);
 
        setTabOrder(configList, helpText);
        configList->setFocus();
 
        menu = menuBar();
-       toolBar = new Q3ToolBar("Tools", this);
-
-       backAction = new Q3Action("Back", QPixmap(xpm_back), _("Back"), 0, this);
-         connect(backAction, SIGNAL(activated()), SLOT(goBack()));
-         backAction->setEnabled(FALSE);
-       Q3Action *quitAction = new Q3Action("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this);
-         connect(quitAction, SIGNAL(activated()), SLOT(close()));
-       Q3Action *loadAction = new Q3Action("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this);
-         connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
-       saveAction = new Q3Action("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this);
-         connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
+       toolBar = new QToolBar("Tools", this);
+       addToolBar(toolBar);
+
+       backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
+         connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
+         backAction->setEnabled(false);
+       QAction *quitAction = new QAction(_("&Quit"), this);
+       quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
+         connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
+       QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
+       loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
+         connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
+       saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
+       saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
+         connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
        conf_set_changed_callback(conf_changed);
        // Set saveAction's initial state
        conf_changed();
-       Q3Action *saveAsAction = new Q3Action("Save As...", _("Save &As..."), 0, this);
-         connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
-       Q3Action *searchAction = new Q3Action("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this);
-         connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
-       Q3Action *singleViewAction = new Q3Action("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
-         connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
-       Q3Action *splitViewAction = new Q3Action("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
-         connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
-       Q3Action *fullViewAction = new Q3Action("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
-         connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
-
-       Q3Action *showNameAction = new Q3Action(NULL, _("Show Name"), 0, this);
-         showNameAction->setToggleAction(TRUE);
+       QAction *saveAsAction = new QAction(_("Save &As..."), this);
+         connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
+       QAction *searchAction = new QAction(_("&Find"), this);
+       searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
+         connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
+       singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
+       singleViewAction->setCheckable(true);
+         connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
+       splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
+       splitViewAction->setCheckable(true);
+         connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
+       fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
+       fullViewAction->setCheckable(true);
+         connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
+
+       QAction *showNameAction = new QAction(_("Show Name"), this);
+         showNameAction->setCheckable(true);
          connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
-         connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
-         showNameAction->setOn(configView->showName());
-       Q3Action *showRangeAction = new Q3Action(NULL, _("Show Range"), 0, this);
-         showRangeAction->setToggleAction(TRUE);
+         showNameAction->setChecked(configView->showName());
+       QAction *showRangeAction = new QAction(_("Show Range"), this);
+         showRangeAction->setCheckable(true);
          connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
-         connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
-         showRangeAction->setOn(configList->showRange);
-       Q3Action *showDataAction = new Q3Action(NULL, _("Show Data"), 0, this);
-         showDataAction->setToggleAction(TRUE);
+       QAction *showDataAction = new QAction(_("Show Data"), this);
+         showDataAction->setCheckable(true);
          connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
-         connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
-         showDataAction->setOn(configList->showData);
 
        QActionGroup *optGroup = new QActionGroup(this);
-       optGroup->setExclusive(TRUE);
-       connect(optGroup, SIGNAL(selected(QAction *)), configView,
+       optGroup->setExclusive(true);
+       connect(optGroup, SIGNAL(triggered(QAction*)), configView,
                SLOT(setOptionMode(QAction *)));
-       connect(optGroup, SIGNAL(selected(QAction *)), menuView,
+       connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
                SLOT(setOptionMode(QAction *)));
 
-#if QT_VERSION >= 0x040000
        configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
        configView->showAllAction = new QAction(_("Show All Options"), optGroup);
        configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
-#else
-       configView->showNormalAction = new QAction(_("Show Normal Options"), 0, optGroup);
-       configView->showAllAction = new QAction(_("Show All Options"), 0, optGroup);
-       configView->showPromptAction = new QAction(_("Show Prompt Options"), 0, optGroup);
-#endif
-       configView->showNormalAction->setToggleAction(TRUE);
-       configView->showNormalAction->setOn(configList->optMode == normalOpt);
-       configView->showAllAction->setToggleAction(TRUE);
-       configView->showAllAction->setOn(configList->optMode == allOpt);
-       configView->showPromptAction->setToggleAction(TRUE);
-       configView->showPromptAction->setOn(configList->optMode == promptOpt);
-
-       Q3Action *showDebugAction = new Q3Action(NULL, _("Show Debug Info"), 0, this);
-         showDebugAction->setToggleAction(TRUE);
+       configView->showNormalAction->setCheckable(true);
+       configView->showAllAction->setCheckable(true);
+       configView->showPromptAction->setCheckable(true);
+
+       QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
+         showDebugAction->setCheckable(true);
          connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
-         connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
-         showDebugAction->setOn(helpText->showDebug());
+         showDebugAction->setChecked(helpText->showDebug());
 
-       Q3Action *showIntroAction = new Q3Action(NULL, _("Introduction"), 0, this);
-         connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
-       Q3Action *showAboutAction = new Q3Action(NULL, _("About"), 0, this);
-         connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
+       QAction *showIntroAction = new QAction( _("Introduction"), this);
+         connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
+       QAction *showAboutAction = new QAction( _("About"), this);
+         connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
 
        // init tool bar
-       backAction->addTo(toolBar);
+       toolBar->addAction(backAction);
        toolBar->addSeparator();
-       loadAction->addTo(toolBar);
-       saveAction->addTo(toolBar);
+       toolBar->addAction(loadAction);
+       toolBar->addAction(saveAction);
        toolBar->addSeparator();
-       singleViewAction->addTo(toolBar);
-       splitViewAction->addTo(toolBar);
-       fullViewAction->addTo(toolBar);
+       toolBar->addAction(singleViewAction);
+       toolBar->addAction(splitViewAction);
+       toolBar->addAction(fullViewAction);
 
        // create config menu
-       Q3PopupMenu* config = new Q3PopupMenu(this);
-       menu->insertItem(_("&File"), config);
-       loadAction->addTo(config);
-       saveAction->addTo(config);
-       saveAsAction->addTo(config);
-       config->insertSeparator();
-       quitAction->addTo(config);
+       QMenu* config = menu->addMenu(_("&File"));
+       config->addAction(loadAction);
+       config->addAction(saveAction);
+       config->addAction(saveAsAction);
+       config->addSeparator();
+       config->addAction(quitAction);
 
        // create edit menu
-       Q3PopupMenu* editMenu = new Q3PopupMenu(this);
-       menu->insertItem(_("&Edit"), editMenu);
-       searchAction->addTo(editMenu);
+       QMenu* editMenu = menu->addMenu(_("&Edit"));
+       editMenu->addAction(searchAction);
 
        // create options menu
-       Q3PopupMenu* optionMenu = new Q3PopupMenu(this);
-       menu->insertItem(_("&Option"), optionMenu);
-       showNameAction->addTo(optionMenu);
-       showRangeAction->addTo(optionMenu);
-       showDataAction->addTo(optionMenu);
-       optionMenu->insertSeparator();
-       optGroup->addTo(optionMenu);
-       optionMenu->insertSeparator();
+       QMenu* optionMenu = menu->addMenu(_("&Option"));
+       optionMenu->addAction(showNameAction);
+       optionMenu->addAction(showRangeAction);
+       optionMenu->addAction(showDataAction);
+       optionMenu->addSeparator();
+       optionMenu->addActions(optGroup->actions());
+       optionMenu->addSeparator();
 
        // create help menu
-       Q3PopupMenu* helpMenu = new Q3PopupMenu(this);
-       menu->insertSeparator();
-       menu->insertItem(_("&Help"), helpMenu);
-       showIntroAction->addTo(helpMenu);
-       showAboutAction->addTo(helpMenu);
+       menu->addSeparator();
+       QMenu* helpMenu = menu->addMenu(_("&Help"));
+       helpMenu->addAction(showIntroAction);
+       helpMenu->addAction(showAboutAction);
 
        connect(configList, SIGNAL(menuChanged(struct menu *)),
                helpText, SLOT(setInfo(struct menu *)));
@@ -1456,7 +1501,7 @@ ConfigMainWindow::ConfigMainWindow(void)
        connect(helpText, SIGNAL(menuSelected(struct menu *)),
                SLOT(setMenuLink(struct menu *)));
 
-       QString listMode = configSettings->readEntry("/listMode", "symbol");
+       QString listMode = configSettings->value("/listMode", "symbol").toString();
        if (listMode == "single")
                showSingleView();
        else if (listMode == "full")
@@ -1465,7 +1510,7 @@ ConfigMainWindow::ConfigMainWindow(void)
                showSplitView();
 
        // UI setup done, restore splitter positions
-       Q3ValueList<int> sizes = configSettings->readSizes("/split1", &ok);
+       QList<int> sizes = configSettings->readSizes("/split1", &ok);
        if (ok)
                split1->setSizes(sizes);
 
@@ -1476,7 +1521,7 @@ ConfigMainWindow::ConfigMainWindow(void)
 
 void ConfigMainWindow::loadConfig(void)
 {
-       QString s = Q3FileDialog::getOpenFileName(conf_get_configname(), NULL, this);
+       QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
        if (s.isNull())
                return;
        if (conf_read(QFile::encodeName(s)))
@@ -1495,7 +1540,7 @@ bool ConfigMainWindow::saveConfig(void)
 
 void ConfigMainWindow::saveConfigAs(void)
 {
-       QString s = Q3FileDialog::getSaveFileName(conf_get_configname(), NULL, this);
+       QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
        if (s.isNull())
                return;
        saveConfig();
@@ -1512,9 +1557,9 @@ void ConfigMainWindow::changeMenu(struct menu *menu)
 {
        configList->setRootMenu(menu);
        if (configList->rootEntry->parent == &rootmenu)
-               backAction->setEnabled(FALSE);
+               backAction->setEnabled(false);
        else
-               backAction->setEnabled(TRUE);
+               backAction->setEnabled(true);
 }
 
 void ConfigMainWindow::setMenuLink(struct menu *menu)
@@ -1546,8 +1591,8 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
                                return;
                        item = menuList->findConfigItem(parent);
                        if (item) {
-                               menuList->setSelected(item, TRUE);
-                               menuList->ensureItemVisible(item);
+                               item->setSelected(true);
+                               menuList->scrollToItem(item);
                        }
                        list->setRootMenu(parent);
                }
@@ -1562,8 +1607,8 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
        if (list) {
                item = list->findConfigItem(menu);
                if (item) {
-                       list->setSelected(item, TRUE);
-                       list->ensureItemVisible(item);
+                       item->setSelected(true);
+                       list->scrollToItem(item);
                        list->setFocus();
                }
        }
@@ -1577,15 +1622,21 @@ void ConfigMainWindow::listFocusChanged(void)
 
 void ConfigMainWindow::goBack(void)
 {
-       ConfigItem* item;
+       ConfigItem* item, *oldSelection;
 
        configList->setParentMenu();
        if (configList->rootEntry == &rootmenu)
-               backAction->setEnabled(FALSE);
-       item = (ConfigItem*)menuList->selectedItem();
+               backAction->setEnabled(false);
+
+       if (menuList->selectedItems().count() == 0)
+               return;
+
+       item = (ConfigItem*)menuList->selectedItems().first();
+       oldSelection = item;
        while (item) {
                if (item->menu == configList->rootEntry) {
-                       menuList->setSelected(item, TRUE);
+                       oldSelection->setSelected(false);
+                       item->setSelected(true);
                        break;
                }
                item = (ConfigItem*)item->parent();
@@ -1594,6 +1645,13 @@ void ConfigMainWindow::goBack(void)
 
 void ConfigMainWindow::showSingleView(void)
 {
+       singleViewAction->setEnabled(false);
+       singleViewAction->setChecked(true);
+       splitViewAction->setEnabled(true);
+       splitViewAction->setChecked(false);
+       fullViewAction->setEnabled(true);
+       fullViewAction->setChecked(false);
+
        menuView->hide();
        menuList->setRootMenu(0);
        configList->mode = singleMode;
@@ -1601,28 +1659,41 @@ void ConfigMainWindow::showSingleView(void)
                configList->updateListAll();
        else
                configList->setRootMenu(&rootmenu);
-       configList->setAllOpen(TRUE);
        configList->setFocus();
 }
 
 void ConfigMainWindow::showSplitView(void)
 {
+       singleViewAction->setEnabled(true);
+       singleViewAction->setChecked(false);
+       splitViewAction->setEnabled(false);
+       splitViewAction->setChecked(true);
+       fullViewAction->setEnabled(true);
+       fullViewAction->setChecked(false);
+
        configList->mode = symbolMode;
        if (configList->rootEntry == &rootmenu)
                configList->updateListAll();
        else
                configList->setRootMenu(&rootmenu);
-       configList->setAllOpen(TRUE);
+       configList->setAllOpen(true);
        configApp->processEvents();
        menuList->mode = menuMode;
        menuList->setRootMenu(&rootmenu);
-       menuList->setAllOpen(TRUE);
+       menuList->setAllOpen(true);
        menuView->show();
        menuList->setFocus();
 }
 
 void ConfigMainWindow::showFullView(void)
 {
+       singleViewAction->setEnabled(true);
+       singleViewAction->setChecked(false);
+       splitViewAction->setEnabled(true);
+       splitViewAction->setChecked(false);
+       fullViewAction->setEnabled(false);
+       fullViewAction->setChecked(true);
+
        menuView->hide();
        menuList->setRootMenu(0);
        configList->mode = fullMode;
@@ -1630,7 +1701,6 @@ void ConfigMainWindow::showFullView(void)
                configList->updateListAll();
        else
                configList->setRootMenu(&rootmenu);
-       configList->setAllOpen(FALSE);
        configList->setFocus();
 }
 
@@ -1684,7 +1754,8 @@ void ConfigMainWindow::showIntro(void)
 
 void ConfigMainWindow::showAbout(void)
 {
-       static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
+       static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
+               "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
                "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
 
        QMessageBox::information(this, "qconf", str);
@@ -1692,10 +1763,10 @@ void ConfigMainWindow::showAbout(void)
 
 void ConfigMainWindow::saveSettings(void)
 {
-       configSettings->writeEntry("/window x", pos().x());
-       configSettings->writeEntry("/window y", pos().y());
-       configSettings->writeEntry("/window width", size().width());
-       configSettings->writeEntry("/window height", size().height());
+       configSettings->setValue("/window x", pos().x());
+       configSettings->setValue("/window y", pos().y());
+       configSettings->setValue("/window width", size().width());
+       configSettings->setValue("/window height", size().height());
 
        QString entry;
        switch(configList->mode) {
@@ -1714,7 +1785,7 @@ void ConfigMainWindow::saveSettings(void)
        default:
                break;
        }
-       configSettings->writeEntry("/listMode", entry);
+       configSettings->setValue("/listMode", entry);
 
        configSettings->writeSizes("/split1", split1->sizes());
        configSettings->writeSizes("/split2", split2->sizes());
@@ -1746,7 +1817,7 @@ static const char *progname;
 
 static void usage(void)
 {
-       printf(_("%s [-s] <config>\n"), progname);
+       printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
        exit(0);
 }
 
@@ -1785,7 +1856,6 @@ int main(int ac, char** av)
        v = new ConfigMainWindow();
 
        //zconfdump(stdout);
-       configApp->setMainWidget(v);
        configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
        configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
        v->show();
index bde0c6b6f9e87dbeff3004413123f6d2cef0d42f..a40036d1b059275153dad27f78b522212af97ca7 100644 (file)
@@ -3,26 +3,18 @@
  * Released under the terms of the GNU GPL v2.0.
  */
 
-#if QT_VERSION < 0x040000
-#include <qlistview.h>
-#else
-#include <q3listview.h>
-#endif
+#include <QTextBrowser>
+#include <QTreeWidget>
+#include <QMainWindow>
+#include <QHeaderView>
 #include <qsettings.h>
-
-#if QT_VERSION < 0x040000
-#define Q3ValueList             QValueList
-#define Q3PopupMenu             QPopupMenu
-#define Q3ListView              QListView
-#define Q3ListViewItem          QListViewItem
-#define Q3VBox                  QVBox
-#define Q3TextBrowser           QTextBrowser
-#define Q3MainWindow            QMainWindow
-#define Q3Action                QAction
-#define Q3ToolBar               QToolBar
-#define Q3ListViewItemIterator  QListViewItemIterator
-#define Q3FileDialog            QFileDialog
-#endif
+#include <QPushButton>
+#include <QSettings>
+#include <QLineEdit>
+#include <QSplitter>
+#include <QCheckBox>
+#include <QDialog>
+#include "expr.h"
 
 class ConfigView;
 class ConfigList;
@@ -33,8 +25,8 @@ class ConfigMainWindow;
 class ConfigSettings : public QSettings {
 public:
        ConfigSettings();
-       Q3ValueList<int> readSizes(const QString& key, bool *ok);
-       bool writeSizes(const QString& key, const Q3ValueList<int>& value);
+       QList<int> readSizes(const QString& key, bool *ok);
+       bool writeSizes(const QString& key, const QList<int>& value);
 };
 
 enum colIdx {
@@ -47,9 +39,9 @@ enum optionMode {
        normalOpt = 0, allOpt, promptOpt
 };
 
-class ConfigList : public Q3ListView {
+class ConfigList : public QTreeWidget {
        Q_OBJECT
-       typedef class Q3ListView Parent;
+       typedef class QTreeWidget Parent;
 public:
        ConfigList(ConfigView* p, const char *name = 0);
        void reinit(void);
@@ -61,10 +53,10 @@ public:
 
 protected:
        void keyPressEvent(QKeyEvent *e);
-       void contentsMousePressEvent(QMouseEvent *e);
-       void contentsMouseReleaseEvent(QMouseEvent *e);
-       void contentsMouseMoveEvent(QMouseEvent *e);
-       void contentsMouseDoubleClickEvent(QMouseEvent *e);
+       void mousePressEvent(QMouseEvent *e);
+       void mouseReleaseEvent(QMouseEvent *e);
+       void mouseMoveEvent(QMouseEvent *e);
+       void mouseDoubleClickEvent(QMouseEvent *e);
        void focusInEvent(QFocusEvent *e);
        void contextMenuEvent(QContextMenuEvent *e);
 
@@ -95,32 +87,23 @@ public:
        }
        ConfigItem* firstChild() const
        {
-               return (ConfigItem *)Parent::firstChild();
-       }
-       int mapIdx(colIdx idx)
-       {
-               return colMap[idx];
+               return (ConfigItem *)children().first();
        }
-       void addColumn(colIdx idx, const QString& label)
+       void addColumn(colIdx idx)
        {
-               colMap[idx] = Parent::addColumn(label);
-               colRevMap[colMap[idx]] = idx;
+               showColumn(idx);
        }
        void removeColumn(colIdx idx)
        {
-               int col = colMap[idx];
-               if (col >= 0) {
-                       Parent::removeColumn(col);
-                       colRevMap[col] = colMap[idx] = -1;
-               }
+               hideColumn(idx);
        }
        void setAllOpen(bool open);
        void setParentMenu(void);
 
        bool menuSkip(struct menu *);
 
-       template <class P>
-       void updateMenuList(P*, struct menu*);
+       void updateMenuList(ConfigItem *parent, struct menu*);
+       void updateMenuList(ConfigList *parent, struct menu*);
 
        bool updateAll;
 
@@ -132,30 +115,26 @@ public:
        enum listMode mode;
        enum optionMode optMode;
        struct menu *rootEntry;
-       QColorGroup disabledColorGroup;
-       QColorGroup inactivedColorGroup;
-       Q3PopupMenu* headerPopup;
-
-private:
-       int colMap[colNr];
-       int colRevMap[colNr];
+       QPalette disabledColorGroup;
+       QPalette inactivedColorGroup;
+       QMenu* headerPopup;
 };
 
-class ConfigItem : public Q3ListViewItem {
-       typedef class Q3ListViewItem Parent;
+class ConfigItem : public QTreeWidgetItem {
+       typedef class QTreeWidgetItem Parent;
 public:
-       ConfigItem(Q3ListView *parent, ConfigItem *after, struct menu *m, bool v)
-       : Parent(parent, after), menu(m), visible(v), goParent(false)
+       ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m, bool v)
+       : Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false)
        {
                init();
        }
        ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
-       : Parent(parent, after), menu(m), visible(v), goParent(false)
+       : Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false)
        {
                init();
        }
-       ConfigItem(Q3ListView *parent, ConfigItem *after, bool v)
-       : Parent(parent, after), menu(0), visible(v), goParent(true)
+       ConfigItem(ConfigList *parent, ConfigItem *after, bool v)
+       : Parent(parent, after), nextItem(0), menu(0), visible(v), goParent(true)
        {
                init();
        }
@@ -166,33 +145,43 @@ public:
        void testUpdateMenu(bool v);
        ConfigList* listView() const
        {
-               return (ConfigList*)Parent::listView();
+               return (ConfigList*)Parent::treeWidget();
        }
        ConfigItem* firstChild() const
        {
-               return (ConfigItem *)Parent::firstChild();
+               return (ConfigItem *)Parent::child(0);
        }
-       ConfigItem* nextSibling() const
+       ConfigItem* nextSibling()
        {
-               return (ConfigItem *)Parent::nextSibling();
+               ConfigItem *ret = NULL;
+               ConfigItem *_parent = (ConfigItem *)parent();
+
+               if(_parent) {
+                       ret = (ConfigItem *)_parent->child(_parent->indexOfChild(this)+1);
+               } else {
+                       QTreeWidget *_treeWidget = treeWidget();
+                       ret = (ConfigItem *)_treeWidget->topLevelItem(_treeWidget->indexOfTopLevelItem(this)+1);
+               }
+
+               return ret;
        }
        void setText(colIdx idx, const QString& text)
        {
-               Parent::setText(listView()->mapIdx(idx), text);
+               Parent::setText(idx, text);
        }
        QString text(colIdx idx) const
        {
-               return Parent::text(listView()->mapIdx(idx));
+               return Parent::text(idx);
        }
-       void setPixmap(colIdx idx, const QPixmap& pm)
+       void setPixmap(colIdx idx, const QIcon &icon)
        {
-               Parent::setPixmap(listView()->mapIdx(idx), pm);
+               Parent::setIcon(idx, icon);
        }
-       const QPixmap* pixmap(colIdx idx) const
+       const QIcon pixmap(colIdx idx) const
        {
-               return Parent::pixmap(listView()->mapIdx(idx));
+               return icon(idx);
        }
-       void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align);
+       // TODO: Implement paintCell
 
        ConfigItem* nextItem;
        struct menu *menu;
@@ -216,9 +205,9 @@ public:
        ConfigItem *item;
 };
 
-class ConfigView : public Q3VBox {
+class ConfigView : public QWidget {
        Q_OBJECT
-       typedef class Q3VBox Parent;
+       typedef class QWidget Parent;
 public:
        ConfigView(QWidget* parent, const char *name = 0);
        ~ConfigView(void);
@@ -249,9 +238,9 @@ public:
        static QAction *showPromptAction;
 };
 
-class ConfigInfoView : public Q3TextBrowser {
+class ConfigInfoView : public QTextBrowser {
        Q_OBJECT
-       typedef class Q3TextBrowser Parent;
+       typedef class QTextBrowser Parent;
 public:
        ConfigInfoView(QWidget* parent, const char *name = 0);
        bool showDebug(void) const { return _showDebug; }
@@ -271,8 +260,8 @@ protected:
        QString debug_info(struct symbol *sym);
        static QString print_filter(const QString &str);
        static void expr_print_help(void *data, struct symbol *sym, const char *str);
-       Q3PopupMenu* createPopupMenu(const QPoint& pos);
-       void contentsContextMenuEvent(QContextMenuEvent *e);
+       QMenu *createStandardContextMenu(const QPoint & pos);
+       void contextMenuEvent(QContextMenuEvent *e);
 
        struct symbol *sym;
        struct menu *_menu;
@@ -299,10 +288,10 @@ protected:
        struct symbol **result;
 };
 
-class ConfigMainWindow : public Q3MainWindow {
+class ConfigMainWindow : public QMainWindow {
        Q_OBJECT
 
-       static Q3Action *saveAction;
+       static QAction *saveAction;
        static void conf_changed(void);
 public:
        ConfigMainWindow(void);
@@ -331,8 +320,11 @@ protected:
        ConfigView *configView;
        ConfigList *configList;
        ConfigInfoView *helpText;
-       Q3ToolBar *toolBar;
-       Q3Action *backAction;
-       QSplitter* split1;
-       QSplitter* split2;
+       QToolBar *toolBar;
+       QAction *backAction;
+       QAction *singleViewAction;
+       QAction *splitViewAction;
+       QAction *fullViewAction;
+       QSplitter *split1;
+       QSplitter *split2;
 };
index 50878dc025a5746d51316c6f1bd4c1e1b8a41707..25cf0c2c0c795ac36658a2bfa061c9f3383630a1 100644 (file)
@@ -1116,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,
index 1a10d8ac81620faad519d4f95ca8552ac4a958c1..13efe9857a42f61f71d60ea0331eaf83c1bbca5a 100755 (executable)
@@ -53,7 +53,7 @@ vmlinux_link()
        local lds="${objtree}/${KBUILD_LDS}"
 
        if [ "${SRCARCH}" != "um" ]; then
-               ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2}                  \
+               ${LDFINAL} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2}                  \
                        -T ${lds} ${KBUILD_VMLINUX_INIT}                     \
                        --start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1}
        else
index b967e4f9fed2e6cc78b9538c79517a473fc375b8..6c3b038ef40d2c761c415f3d060d3b92ee489d02 100755 (executable)
@@ -52,7 +52,16 @@ set_debarch() {
        arm64)
                debarch=arm64 ;;
        arm*)
-               debarch=arm$(grep -q CONFIG_AEABI=y $KCONFIG_CONFIG && echo el || true) ;;
+               if grep -q CONFIG_AEABI=y $KCONFIG_CONFIG; then
+                   if grep -q CONFIG_VFP=y $KCONFIG_CONFIG; then
+                       debarch=armhf
+                   else
+                       debarch=armel
+                   fi
+               else
+                   debarch=arm
+               fi
+               ;;
        *)
                debarch=$(dpkg --print-architecture)
                echo "" >&2
index 8e5aee6d9da2be1d3a4c255947d07663c14c29d3..262889046703ea02055fcec52cfc6b3e2ebf1dd0 100755 (executable)
@@ -198,6 +198,8 @@ exuberant()
        --regex-c++='/TASK_PFA_TEST\([^,]*,\s*([^)]*)\)/task_\1/'       \
        --regex-c++='/TASK_PFA_SET\([^,]*,\s*([^)]*)\)/task_set_\1/'    \
        --regex-c++='/TASK_PFA_CLEAR\([^,]*,\s*([^)]*)\)/task_clear_\1/'\
+       --regex-c++='/DEF_MMIO_(IN|OUT)_(X|D)\(([^,]*),\s*[^)]*\)/\3/'  \
+       --regex-c++='/DEBUGGER_BOILERPLATE\(([^,]*)\)/\1/'              \
        --regex-c='/PCI_OP_READ\((\w*).*[1-4]\)/pci_bus_read_config_\1/' \
        --regex-c='/PCI_OP_WRITE\((\w*).*[1-4]\)/pci_bus_write_config_\1/' \
        --regex-c='/DEFINE_(MUTEX|SEMAPHORE|SPINLOCK)\((\w*)/\2/v/'     \