summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kconfiglib.py72
-rw-r--r--tests/Klocation20
-rw-r--r--tests/sub/Klocation_grsourced11
-rw-r--r--tests/sub/Klocation_grsourced21
-rw-r--r--tests/sub/Klocation_gsourced11
-rw-r--r--tests/sub/Klocation_gsourced21
-rw-r--r--testsuite.py8
7 files changed, 98 insertions, 6 deletions
diff --git a/kconfiglib.py b/kconfiglib.py
index 85a0054..99bdf80 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -313,8 +313,13 @@ If a condition is missing (e.g., <cond> when the 'if <cond>' is removed from
functions just avoid printing 'if y' conditions to give cleaner output.
+Kconfig extensions
+==================
+
+Kconfiglib implements two Kconfig extensions related to 'source':
+
'source' with relative path
-===========================
+---------------------------
The library implements a custom 'rsource' statement that allows to import
Kconfig file by specifying path relative to directory of the currently parsed
@@ -347,6 +352,26 @@ Using 'rsource' it can be rewritten as:
If absolute path is given to 'rsource' then it follows behavior of 'source'.
+Globbed sourcing with 'gsource' and 'grsource'
+----------------------------------------------
+
+The 'gsource' statement works like 'source', but takes a glob pattern and
+sources all matching Kconfig files. For example, the following statement might
+source 'sub1/foofoofoo' and 'sub2/foobarfoo':
+
+ gsource "sub[12]/foo*foo"
+
+The glob patterns accepted are the same as for the standard glob.glob()
+function.
+
+If no file matches the pattern, gsource is a no-op, and hence doubles as an
+include-if-exists function when given a plain filename (similar to '-include'
+in 'make'). It might help to think of the 'g' as "generalized" in that case.
+
+'grsource' is the 'rsource' version of 'gsource' and globs relative to the
+directory of the current Kconfig file.
+
+
Feedback
========
@@ -354,6 +379,7 @@ Send bug reports, suggestions, and questions to ulfalizer a.t Google's email
service, or open a ticket on the GitHub page.
"""
import errno
+import glob
import os
import platform
import re
@@ -1822,7 +1848,7 @@ class Kconfig(object):
elif t0 == _T_SOURCE:
self._enter_file(self._expand_syms(self._expect_str_and_eol()))
- prev_node = self._parse_block(None, # end_token
+ prev_node = self._parse_block(None, # end_token
parent,
visible_if_deps,
prev_node)
@@ -1833,12 +1859,44 @@ class Kconfig(object):
os.path.dirname(self._filename),
self._expand_syms(self._expect_str_and_eol())
))
- prev_node = self._parse_block(None, # end_token
+ prev_node = self._parse_block(None, # end_token
parent,
visible_if_deps,
prev_node)
self._leave_file()
+ elif t0 in (_T_GSOURCE, _T_GRSOURCE):
+ pattern = self._expand_syms(self._expect_str_and_eol())
+ if t0 == _T_GRSOURCE:
+ # Relative gsource
+ pattern = os.path.join(os.path.dirname(self._filename),
+ pattern)
+
+ # If $srctree is set, glob relative to it
+ if self.srctree is not None:
+ pattern = os.path.join(self.srctree, pattern)
+
+ # Sort the glob results to ensure a consistent ordering of
+ # Kconfig symbols, which indirectly ensures a consistent
+ # ordering in e.g. .config files
+ for filename in sorted(glob.glob(pattern)):
+ if self.srctree is not None and not os.path.isabs(filename):
+ # Strip the $srctree prefix from the filename and let
+ # the normal $srctree logic find the file. This makes
+ # the globbed filenames appear without a $srctree
+ # prefix in MenuNode.filename, which is consistent with
+ # how 'source' and 'rsource' work. We get the same
+ # behavior as if the files had been 'source'd one by
+ # one.
+ filename = os.path.relpath(filename, self.srctree)
+
+ self._enter_file(filename)
+ prev_node = self._parse_block(None, # end_token
+ parent,
+ visible_if_deps,
+ prev_node)
+ self._leave_file()
+
elif t0 == end_token:
# We have reached the end of the block. Terminate the final
# node and return it.
@@ -4699,6 +4757,8 @@ STR_TO_TRI = {
_T_EQUAL,
_T_GREATER,
_T_GREATER_EQUAL,
+ _T_GRSOURCE,
+ _T_GSOURCE,
_T_HELP,
_T_HEX,
_T_IF,
@@ -4725,7 +4785,7 @@ STR_TO_TRI = {
_T_TRISTATE,
_T_UNEQUAL,
_T_VISIBLE,
-) = range(45)
+) = range(47)
# Public integers representing expression types
#
@@ -4759,6 +4819,8 @@ _get_keyword = {
"endif": _T_ENDIF,
"endmenu": _T_ENDMENU,
"env": _T_ENV,
+ "grsource": _T_GRSOURCE,
+ "gsource": _T_GSOURCE,
"help": _T_HELP,
"hex": _T_HEX,
"if": _T_IF,
@@ -4792,6 +4854,8 @@ _STRING_LEX = frozenset((
_T_BOOL,
_T_CHOICE,
_T_COMMENT,
+ _T_GRSOURCE,
+ _T_GSOURCE,
_T_HEX,
_T_INT,
_T_MAINMENU,
diff --git a/tests/Klocation b/tests/Klocation
index aa176b2..99a8ee0 100644
--- a/tests/Klocation
+++ b/tests/Klocation
@@ -49,9 +49,29 @@ config _RSOURCED
string
default "_rsourced"
+config _GSOURCED
+ string
+ default "_gsourced"
+
+config _GRSOURCED
+ string
+ default "_grsourced"
+
# Expands to "tests/Klocation_sourced"
source "$TESTS_DIR_FROM_ENV/Klocation$_SOURCED"
+
# Expands to "sub/Klocation_rsourced"
rsource "$SUB_DIR_FROM_ENV/Klocation$_RSOURCED"
+# Expands to "tests/*ub/Klocation_gsourced[12]", matching
+# tests/sub/Klocation_gsourced{1,2}
+gsource "$TESTS_DIR_FROM_ENV/*ub/Klocation$_GSOURCED[12]"
+
+# Expands to "sub/Klocation_grsourced[12]", matching
+# tests/sub/Klocation_grsourced{1,2}
+grsource "$SUB_DIR_FROM_ENV/Klocation$_GRSOURCED[12]"
+
+# No-op
+gsource "nonexisting file"
+
config MULTI_DEF
diff --git a/tests/sub/Klocation_grsourced1 b/tests/sub/Klocation_grsourced1
new file mode 100644
index 0000000..49dac36
--- /dev/null
+++ b/tests/sub/Klocation_grsourced1
@@ -0,0 +1 @@
+config MULTI_DEF
diff --git a/tests/sub/Klocation_grsourced2 b/tests/sub/Klocation_grsourced2
new file mode 100644
index 0000000..49dac36
--- /dev/null
+++ b/tests/sub/Klocation_grsourced2
@@ -0,0 +1 @@
+config MULTI_DEF
diff --git a/tests/sub/Klocation_gsourced1 b/tests/sub/Klocation_gsourced1
new file mode 100644
index 0000000..49dac36
--- /dev/null
+++ b/tests/sub/Klocation_gsourced1
@@ -0,0 +1 @@
+config MULTI_DEF
diff --git a/tests/sub/Klocation_gsourced2 b/tests/sub/Klocation_gsourced2
new file mode 100644
index 0000000..49dac36
--- /dev/null
+++ b/tests/sub/Klocation_gsourced2
@@ -0,0 +1 @@
+config MULTI_DEF
diff --git a/testsuite.py b/testsuite.py
index 4b3d0f2..b3f43b4 100644
--- a/testsuite.py
+++ b/testsuite.py
@@ -792,7 +792,7 @@ g
""")
- print("Testing locations and 'source', 'rsource'")
+ print("Testing locations and source/rsource/gsource/grsource")
def verify_locations(nodes, *expected_locs):
verify(len(nodes) == len(expected_locs),
@@ -823,7 +823,11 @@ g
"tests/Klocation:31",
"tests/Klocation_sourced:3",
"tests/sub/Klocation_rsourced:2",
- "tests/Klocation:57")
+ "tests/sub/Klocation_gsourced1:1",
+ "tests/sub/Klocation_gsourced2:1",
+ "tests/sub/Klocation_grsourced1:1",
+ "tests/sub/Klocation_grsourced2:1",
+ "tests/Klocation:77")
verify_locations(c.named_choices["CHOICE"].nodes,
"tests/Klocation_sourced:5")