Commit 152813e6 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild

Pull kconfig updates from Michal Marek:

 - 'make xconfig' ported to Qt5, dropping support for Qt3

 - merge_config.sh supports a single-input-file mode and also respects
   $KCONFIG_CONFIG

 - Fix for incorrect display of >= and > in dependency expressions

* 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild: (44 commits)
  Add current selection check.
  Use pkg-config to find Qt 4 and 5 instead of direct qmake
  kconfig: Fix copy&paste error
  kconfig/merge_config.sh: Accept a single file
  kconfig/merge_config.sh: Support KCONFIG_CONFIG
  Update the buildsystem for KConfig finding Qt
  Port xconfig to Qt5 - Update copyright.
  Port xconfig to Qt5 - Fix goParent issue.
  Port xconfig to Qt5 - on Back clicked, deselect old item.
  Port xconfig to Qt5 - Add(back) one click checkbox toggle.
  Port xconfig to Qt5 - Add(back) lineedit editing.
  Port xconfig to Qt5 - Remove some commented code.
  Port xconfig to Qt5 - Source format.
  Port xconfig to Qt5 - Add horizontal scrollbar, and scroll per pixel.
  Port xconfig to Qt5 - Change ConfigItem constructor parent type.
  Port xconfig to Qt5 - Disable ConfigList soring
  Port xconfig to Qt5 - Remove ConfigList::updateMenuList template.
  Port xconfig to Qt5 - Add ConfigList::mode to initializer list.
  Port xconfig to Qt5 - Add ConfigItem::nextItem to initializer list.
  Port xconfig to Qt5 - Tree widget set column titles.
  ...
parents c34e6e0b be596aaa
# 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
# 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
# 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
...@@ -393,3 +393,164 @@ config FOO ...@@ -393,3 +393,164 @@ config FOO
depends on BAR && m depends on BAR && m
limits FOO to module (=m) or disabled (=n). 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
...@@ -229,49 +229,21 @@ $(obj)/.tmp_qtcheck: $(src)/Makefile ...@@ -229,49 +229,21 @@ $(obj)/.tmp_qtcheck: $(src)/Makefile
# Qt needs some extra effort... # Qt needs some extra effort...
$(obj)/.tmp_qtcheck: $(obj)/.tmp_qtcheck:
@set -e; $(kecho) " CHECK qt"; dir=""; pkg=""; \ @set -e; $(kecho) " CHECK qt"; \
if ! pkg-config --exists QtCore 2> /dev/null; then \ if pkg-config --exists Qt5Core; then \
echo "* Unable to find the Qt4 tool qmake. Trying to use Qt3"; \ cflags="-std=c++11 -fPIC `pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets`"; \
pkg-config --exists qt 2> /dev/null && pkg=qt; \ libs=`pkg-config --libs Qt5Core Qt5Gui Qt5Widgets`; \
pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \ moc=`pkg-config --variable=host_bins Qt5Core`/moc; \
if [ -n "$$pkg" ]; then \ elif pkg-config --exists QtCore; then \
cflags="\$$(shell pkg-config $$pkg --cflags)"; \ cflags=`pkg-config --cflags QtCore QtGui`; \
libs="\$$(shell pkg-config $$pkg --libs)"; \ libs=`pkg-config --libs QtCore QtGui`; \
moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \ moc=`pkg-config --variable=moc_location QtCore`; \
dir="$$(pkg-config $$pkg --variable=prefix)"; \
else \ 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 "*"; \
echo >&2 "* Unable to find any Qt installation. Please make sure that"; \ echo >&2 "* Could not find Qt via pkg-config."; \
echo >&2 "* the Qt4 or Qt3 development package is correctly installed and"; \ echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"; \
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 "*"; \ echo >&2 "*"; \
false; \ exit 1; \
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; \
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"; \
fi; \ fi; \
echo "KC_QT_CFLAGS=$$cflags" > $@; \ echo "KC_QT_CFLAGS=$$cflags" > $@; \
echo "KC_QT_LIBS=$$libs" >> $@; \ echo "KC_QT_LIBS=$$libs" >> $@; \
......
...@@ -1113,7 +1113,7 @@ void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char * ...@@ -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); fn(data, e->left.sym, e->left.sym->name);
else else
fn(data, NULL, "<choice>"); 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); fn(data, e->right.sym, e->right.sym->name);
break; break;
case E_UNEQUAL: case E_UNEQUAL:
......
...@@ -32,7 +32,7 @@ usage() { ...@@ -32,7 +32,7 @@ usage() {
echo " -m only merge the fragments, do not execute the make command" echo " -m only merge the fragments, do not execute the make command"
echo " -n use allnoconfig instead of alldefconfig" echo " -n use allnoconfig instead of alldefconfig"
echo " -r list redundant entries when merging fragments" 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 RUNMAKE=true
...@@ -77,11 +77,19 @@ while true; do ...@@ -77,11 +77,19 @@ while true; do
esac esac
done done
if [ "$#" -lt 2 ] ; then if [ "$#" -lt 1 ] ; then
usage usage
exit exit
fi fi
if [ -z "$KCONFIG_CONFIG" ]; then
if [ "$OUTPUT" != . ]; then
KCONFIG_CONFIG=$(readlink -m -- "$OUTPUT/.config")
else
KCONFIG_CONFIG=.config
fi
fi
INITFILE=$1 INITFILE=$1
shift; shift;
...@@ -124,9 +132,9 @@ for MERGE_FILE in $MERGE_LIST ; do ...@@ -124,9 +132,9 @@ for MERGE_FILE in $MERGE_LIST ; do
done done
if [ "$RUNMAKE" = "false" ]; then if [ "$RUNMAKE" = "false" ]; then
cp $TMP_FILE $OUTPUT/.config cp -T -- "$TMP_FILE" "$KCONFIG_CONFIG"
echo "#" echo "#"
echo "# merged configuration written to $OUTPUT/.config (needs make)" echo "# merged configuration written to $KCONFIG_CONFIG (needs make)"
echo "#" echo "#"
clean_up clean_up
exit exit
...@@ -150,7 +158,7 @@ make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET ...@@ -150,7 +158,7 @@ make KCONFIG_ALLCONFIG=$TMP_FILE $OUTPUT_ARG $ALLTARGET
for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do
REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE) 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 if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then
echo "Value requested for $CFG not in final .config" echo "Value requested for $CFG not in final .config"
echo "Requested value: $REQUESTED_VAL" echo "Requested value: $REQUESTED_VAL"
......
This diff is collapsed.
...@@ -3,26 +3,18 @@ ...@@ -3,26 +3,18 @@
* Released under the terms of the GNU GPL v2.0. * Released under the terms of the GNU GPL v2.0.
*/ */
#if QT_VERSION < 0x040000 #include <QTextBrowser>
#include <qlistview.h> #include <QTreeWidget>
#else #include <QMainWindow>
#include <q3listview.h> #include <QHeaderView>
#endif
#include <qsettings.h> #include <qsettings.h>
#include <QPushButton>
#if QT_VERSION < 0x040000 #include <QSettings>
#define Q3ValueList QValueList #include <QLineEdit>
#define Q3PopupMenu QPopupMenu #include <QSplitter>
#define Q3ListView QListView #include <QCheckBox>
#define Q3ListViewItem QListViewItem #include <QDialog>
#define Q3VBox QVBox #include "expr.h"
#define Q3TextBrowser QTextBrowser
#define Q3MainWindow QMainWindow
#define Q3Action QAction
#define Q3ToolBar QToolBar
#define Q3ListViewItemIterator QListViewItemIterator
#define Q3FileDialog QFileDialog
#endif
class ConfigView; class ConfigView;
class ConfigList; class ConfigList;
...@@ -33,8 +25,8 @@ class ConfigMainWindow; ...@@ -33,8 +25,8 @@ class ConfigMainWindow;
class ConfigSettings : public QSettings { class ConfigSettings : public QSettings {
public: public:
ConfigSettings(); ConfigSettings();
Q3ValueList<int> readSizes(const QString& key, bool *ok); QList<int> readSizes(const QString& key, bool *ok);
bool writeSizes(const QString& key, const Q3ValueList<int>& value); bool writeSizes(const QString& key, const QList<int>& value);
}; };
enum colIdx { enum colIdx {
...@@ -47,9 +39,9 @@ enum optionMode { ...@@ -47,9 +39,9 @@ enum optionMode {
normalOpt = 0, allOpt, promptOpt normalOpt = 0, allOpt, promptOpt
}; };
class ConfigList : public Q3ListView { class ConfigList : public QTreeWidget {
Q_OBJECT Q_OBJECT
typedef class Q3ListView Parent; typedef class QTreeWidget Parent;
public: public:
ConfigList(ConfigView* p, const char *name = 0); ConfigList(ConfigView* p, const char *name = 0);
void reinit(void); void reinit(void);
...@@ -61,10 +53,10 @@ class ConfigList : public Q3ListView { ...@@ -61,10 +53,10 @@ class ConfigList : public Q3ListView {
protected: protected:
void keyPressEvent(QKeyEvent *e); void keyPressEvent(QKeyEvent *e);
void contentsMousePressEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e);
void contentsMouseReleaseEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e);
void contentsMouseMoveEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e);
void contentsMouseDoubleClickEvent(QMouseEvent *e); void mouseDoubleClickEvent(QMouseEvent *e);
void focusInEvent(QFocusEvent *e); void focusInEvent(QFocusEvent *e);
void contextMenuEvent(QContextMenuEvent *e); void contextMenuEvent(QContextMenuEvent *e);
...@@ -95,32 +87,23 @@ public slots: ...@@ -95,32 +87,23 @@ public slots:
} }
ConfigItem* firstChild() const ConfigItem* firstChild() const
{ {
return (ConfigItem *)Parent::firstChild(); return (ConfigItem *)children().first();
}
int mapIdx(colIdx idx)
{
return colMap[idx];
} }
void addColumn(colIdx idx, const QString& label) void addColumn(colIdx idx)
{ {
colMap[idx] = Parent::addColumn(label); showColumn(idx);
colRevMap[colMap[idx]] = idx;
} }
void removeColumn(colIdx idx) void removeColumn(colIdx idx)
{ {
int col = colMap[idx]; hideColumn(idx);
if (col >= 0) {
Parent::removeColumn(col);
colRevMap[col] = colMap[idx] = -1;
}
} }
void setAllOpen(bool open); void setAllOpen(bool open);
void setParentMenu(void); void setParentMenu(void);
bool menuSkip(struct menu *); bool menuSkip(struct menu *);
template <class P> void updateMenuList(ConfigItem *parent, struct menu*);
void updateMenuList(P*, struct menu*); void updateMenuList(ConfigList *parent, struct menu*);
bool updateAll; bool updateAll;
...@@ -132,30 +115,26 @@ public slots: ...@@ -132,30 +115,26 @@ public slots:
enum listMode mode; enum listMode mode;
enum optionMode optMode; enum optionMode optMode;
struct menu *rootEntry; struct menu *rootEntry;
QColorGroup disabledColorGroup; QPalette disabledColorGroup;
QColorGroup inactivedColorGroup; QPalette inactivedColorGroup;
Q3PopupMenu* headerPopup; QMenu* headerPopup;
private:
int colMap[colNr];
int colRevMap[colNr];
}; };
class ConfigItem : public Q3ListViewItem { class ConfigItem : public QTreeWidgetItem {
typedef class Q3ListViewItem Parent; typedef class QTreeWidgetItem Parent;
public: public:
ConfigItem(Q3ListView *parent, ConfigItem *after, struct menu *m, bool v) ConfigItem(ConfigList *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(); init();
} }
ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v) 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(); init();
} }
ConfigItem(Q3ListView *parent, ConfigItem *after, bool v) ConfigItem(ConfigList *parent, ConfigItem *after, bool v)
: Parent(parent, after), menu(0), visible(v), goParent(true) : Parent(parent, after), nextItem(0), menu(0), visible(v), goParent(true)
{ {
init(); init();
} }
...@@ -166,33 +145,43 @@ class ConfigItem : public Q3ListViewItem { ...@@ -166,33 +145,43 @@ class ConfigItem : public Q3ListViewItem {
void testUpdateMenu(bool v); void testUpdateMenu(bool v);
ConfigList* listView() const ConfigList* listView() const
{ {
return (ConfigList*)Parent::listView(); return (ConfigList*)Parent::treeWidget();
} }
ConfigItem* firstChild() const 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) void setText(colIdx idx, const QString& text)
{ {
Parent::setText(listView()->mapIdx(idx), text); Parent::setText(idx, text);
} }
QString text(colIdx idx) const 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; ConfigItem* nextItem;
struct menu *menu; struct menu *menu;
...@@ -216,9 +205,9 @@ class ConfigLineEdit : public QLineEdit { ...@@ -216,9 +205,9 @@ class ConfigLineEdit : public QLineEdit {
ConfigItem *item; ConfigItem *item;
}; };
class ConfigView : public Q3VBox { class ConfigView : public QWidget {
Q_OBJECT Q_OBJECT
typedef class Q3VBox Parent; typedef class QWidget Parent;
public: public:
ConfigView(QWidget* parent, const char *name = 0); ConfigView(QWidget* parent, const char *name = 0);
~ConfigView(void); ~ConfigView(void);
...@@ -249,9 +238,9 @@ public slots: ...@@ -249,9 +238,9 @@ public slots:
static QAction *showPromptAction; static QAction *showPromptAction;
}; };
class ConfigInfoView : public Q3TextBrowser { class ConfigInfoView : public QTextBrowser {
Q_OBJECT Q_OBJECT
typedef class Q3TextBrowser Parent; typedef class QTextBrowser Parent;
public: public:
ConfigInfoView(QWidget* parent, const char *name = 0); ConfigInfoView(QWidget* parent, const char *name = 0);
bool showDebug(void) const { return _showDebug; } bool showDebug(void) const { return _showDebug; }
...@@ -271,8 +260,8 @@ public slots: ...@@ -271,8 +260,8 @@ public slots:
QString debug_info(struct symbol *sym); QString debug_info(struct symbol *sym);
static QString print_filter(const QString &str); static QString print_filter(const QString &str);
static void expr_print_help(void *data, struct symbol *sym, const char *str); static void expr_print_help(void *data, struct symbol *sym, const char *str);
Q3PopupMenu* createPopupMenu(const QPoint& pos); QMenu *createStandardContextMenu(const QPoint & pos);
void contentsContextMenuEvent(QContextMenuEvent *e); void contextMenuEvent(QContextMenuEvent *e);
struct symbol *sym; struct symbol *sym;
struct menu *_menu; struct menu *_menu;
...@@ -299,10 +288,10 @@ public slots: ...@@ -299,10 +288,10 @@ public slots:
struct symbol **result; struct symbol **result;
}; };
class ConfigMainWindow : public Q3MainWindow { class ConfigMainWindow : public QMainWindow {
Q_OBJECT Q_OBJECT
static Q3Action *saveAction; static QAction *saveAction;
static void conf_changed(void); static void conf_changed(void);
public: public:
ConfigMainWindow(void); ConfigMainWindow(void);
...@@ -331,8 +320,11 @@ public slots: ...@@ -331,8 +320,11 @@ public slots:
ConfigView *configView; ConfigView *configView;
ConfigList *configList; ConfigList *configList;
ConfigInfoView *helpText; ConfigInfoView *helpText;
Q3ToolBar *toolBar; QToolBar *toolBar;
Q3Action *backAction; QAction *backAction;
QSplitter* split1; QAction *singleViewAction;
QSplitter* split2; QAction *splitViewAction;
QAction *fullViewAction;
QSplitter *split1;
QSplitter *split2;
}; };
...@@ -1116,6 +1116,8 @@ static void sym_check_print_recursive(struct symbol *last_sym) ...@@ -1116,6 +1116,8 @@ static void sym_check_print_recursive(struct symbol *last_sym)
if (stack->sym == last_sym) if (stack->sym == last_sym)
fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
prop->file->name, prop->lineno); 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) { if (stack->expr) {
fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
prop->file->name, prop->lineno, prop->file->name, prop->lineno,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment