summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xgenconfig.py7
-rw-r--r--kconfiglib.py109
-rw-r--r--tests/Kheader5
-rw-r--r--testsuite.py49
4 files changed, 126 insertions, 44 deletions
diff --git a/genconfig.py b/genconfig.py
index bb3e6ff..96124c5 100755
--- a/genconfig.py
+++ b/genconfig.py
@@ -20,6 +20,13 @@ might save work depending on your build setup.
By default, the configuration is generated from '.config'. A different
configuration file can be passed in the KCONFIG_CONFIG environment variable.
+
+A custom header string can be inserted at the beginning of generated
+configuration and header files by setting the KCONFIG_CONFIG_HEADER and
+KCONFIG_AUTOHEADER_HEADER environment variables, respectively (this also works
+for other scripts). The string is not automatically made a comment (this is by
+design, to allow anything to be added), and no trailing newline is added, so
+add '/* */', '#', and newlines as appropriate.
"""
import argparse
import os
diff --git a/kconfiglib.py b/kconfiglib.py
index 37ba501..079c363 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -773,8 +773,8 @@ class Kconfig(object):
See Kconfig.load_config() as well.
srctree:
- The value of the $srctree environment variable when the configuration was
- loaded, or the empty string if $srctree wasn't set. This gives nice
+ The value the $srctree environment variable had when the Kconfig instance
+ was created, or the empty string if $srctree wasn't set. This gives nice
behavior with os.path.join(), which treats "" as the current directory,
without adding "./".
@@ -789,13 +789,22 @@ class Kconfig(object):
if multiple configurations are loaded with different values for $srctree.
config_prefix:
- The value of the $CONFIG_ environment variable when the configuration was
- loaded. This is the prefix used (and expected) on symbol names in .config
- files and C headers. Defaults to "CONFIG_". Used in the same way in the C
- tools.
-
- Like for srctree, only the value of $CONFIG_ when the configuration is
- loaded matters.
+ The value the CONFIG_ environment variable had when the Kconfig instance
+ was created, or "CONFIG_" if CONFIG_ wasn't set. This is the prefix used
+ (and expected) on symbol names in .config files and C headers. Used in
+ the same way in the C tools.
+
+ config_header:
+ The value the KCONFIG_CONFIG_HEADER environment variable had when the
+ Kconfig instance was created, or the empty string if
+ KCONFIG_CONFIG_HEADER wasn't set. This string is inserted verbatim at the
+ beginning of configuration files. See write_config().
+
+ header_header:
+ The value the KCONFIG_AUTOHEADER_HEADER environment variable had when the
+ Kconfig instance was created, or the empty string if
+ KCONFIG_AUTOHEADER_HEADER wasn't set. This string is inserted verbatim at
+ the beginning of header files. See write_autoconf().
filename/linenr:
The current parsing location, for use in Python preprocessor functions.
@@ -810,11 +819,13 @@ class Kconfig(object):
"_warn_assign_no_prompt",
"choices",
"comments",
+ "config_header",
"config_prefix",
"const_syms",
"defconfig_list",
"defined_syms",
"env_vars",
+ "header_header",
"kconfig_filenames",
"m",
"menus",
@@ -943,6 +954,9 @@ class Kconfig(object):
self._unset_match = _re_match(r"# {}([^ ]+) is not set".format(
self.config_prefix))
+ self.config_header = os.getenv("KCONFIG_CONFIG_HEADER", "")
+ self.header_header = os.getenv("KCONFIG_AUTOHEADER_HEADER", "")
+
self.syms = {}
self.const_syms = {}
self.defined_syms = []
@@ -1349,8 +1363,7 @@ class Kconfig(object):
elif self.warn_assign_override:
self._warn(msg, filename, linenr)
- def write_autoconf(self, filename,
- header="/* Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) */\n"):
+ def write_autoconf(self, filename, header=None):
r"""
Writes out symbol values as a C header file, matching the format used
by include/generated/autoconf.h in the kernel.
@@ -1367,19 +1380,26 @@ class Kconfig(object):
filename:
Self-explanatory.
- header (default: "/* Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) */\n"):
- Text that will be inserted verbatim at the beginning of the file. You
- would usually want it enclosed in '/* */' to make it a C comment,
- and include a final terminating newline.
+ header (default: None):
+ Text inserted verbatim at the beginning of the file. You would
+ usually want it enclosed in '/* */' to make it a C comment, and
+ include a trailing newline.
+
+ If None (the default), the value of the environment variable
+ KCONFIG_AUTOHEADER_HEADER had when the Kconfig instance was created
+ will be used if it was set, and no header otherwise. See the
+ Kconfig.header_header attribute.
"""
self._write_if_changed(filename, self._autoconf_contents(header))
def _autoconf_contents(self, header):
# write_autoconf() helper. Returns the contents to write as a string,
- # with 'header' at the beginning.
+ # with 'header' or KCONFIG_AUTOHEADER_HEADER at the beginning.
- # "".join()ed later
- chunks = [header]
+ if header is None:
+ header = self.header_header
+
+ chunks = [header] # "".join()ed later
add = chunks.append
for sym in self.unique_defined_syms:
@@ -1415,9 +1435,8 @@ class Kconfig(object):
return "".join(chunks)
- def write_config(self, filename=None,
- header="# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n",
- save_old=True, verbose=None):
+ def write_config(self, filename=None, header=None, save_old=True,
+ verbose=None):
r"""
Writes out symbol values in the .config format. The format matches the
C implementation, including ordering.
@@ -1445,10 +1464,15 @@ class Kconfig(object):
KCONFIG_CONFIG is used if set, and ".config" otherwise. See
standard_config_filename().
- header (default: "# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"):
- Text that will be inserted verbatim at the beginning of the file. You
- would usually want each line to start with '#' to make it a comment,
- and include a final terminating newline.
+ header (default: None):
+ Text inserted verbatim at the beginning of the file. You would
+ usually want each line to start with '#' to make it a comment, and
+ include a trailing newline.
+
+ if None (the default), the value of the environment variable
+ KCONFIG_CONFIG_HEADER had when the Kconfig instance was created will
+ be used if it was set, and no header otherwise. See the
+ Kconfig.config_header attribute.
save_old (default: True):
If True and <filename> already exists, a copy of it will be saved to
@@ -1493,7 +1517,7 @@ class Kconfig(object):
def _config_contents(self, header):
# write_config() helper. Returns the contents to write as a string,
- # with 'header' at the beginning.
+ # with 'header' or KCONFIG_CONFIG_HEADER at the beginning.
#
# More memory friendly would be to 'yield' the strings and
# "".join(_config_contents()), but it was a bit slower on my system.
@@ -1505,13 +1529,15 @@ class Kconfig(object):
for sym in self.unique_defined_syms:
sym._visited = False
- # Did we just print an '# end of ...' comment?
- after_end_comment = False
+ if header is None:
+ header = self.config_header
- # "".join()ed later
- chunks = [header]
+ chunks = [header] # "".join()ed later
add = chunks.append
+ # Did we just print an '# end of ...' comment?
+ after_end_comment = False
+
node = self.top_node
while 1:
# Jump to the next node with an iterative tree walk
@@ -1564,8 +1590,7 @@ class Kconfig(object):
add("\n#\n# {}\n#\n".format(node.prompt[0]))
after_end_comment = False
- def write_min_config(self, filename,
- header="# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"):
+ def write_min_config(self, filename, header=None):
"""
Writes out a "minimal" configuration file, omitting symbols whose value
matches their default value. The format matches the one produced by
@@ -1583,10 +1608,15 @@ class Kconfig(object):
filename:
Self-explanatory.
- header (default: "# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)\n"):
- Text that will be inserted verbatim at the beginning of the file. You
- would usually want each line to start with '#' to make it a comment,
- and include a final terminating newline.
+ header (default: None):
+ Text inserted verbatim at the beginning of the file. You would
+ usually want each line to start with '#' to make it a comment, and
+ include a final terminating newline.
+
+ if None (the default), the value of the environment variable
+ KCONFIG_CONFIG_HEADER had when the Kconfig instance was created will
+ be used if it was set, and no header otherwise. See the
+ Kconfig.config_header attribute.
Returns a string with a message saying which file got saved. This is
meant to reduce boilerplate in tools, which can do e.g.
@@ -1603,9 +1633,12 @@ class Kconfig(object):
def _min_config_contents(self, header):
# write_min_config() helper. Returns the contents to write as a string,
- # with 'header' at the beginning.
+ # with 'header' or KCONFIG_CONFIG_HEADER at the beginning.
+
+ if header is None:
+ header = self.config_header
- chunks = [header]
+ chunks = [header] # "".join()ed later
add = chunks.append
for sym in self.unique_defined_syms:
diff --git a/tests/Kheader b/tests/Kheader
new file mode 100644
index 0000000..495afc6
--- /dev/null
+++ b/tests/Kheader
@@ -0,0 +1,5 @@
+# Used to test headers in .config and header files
+
+config FOO
+ bool "foo"
+ default y
diff --git a/testsuite.py b/testsuite.py
index 6fd8d83..fc61a16 100644
--- a/testsuite.py
+++ b/testsuite.py
@@ -1926,12 +1926,12 @@ tests/Krecursive2:1
c = Kconfig("Kconfiglib/tests/Kescape")
# Test the default value
- c.write_config(config_test_file + "_from_def", header="")
+ c.write_config(config_test_file + "_from_def")
verify_file_contents(config_test_file + "_from_def",
r'''CONFIG_STRING="\"\\"''' "\n")
# Write our own value
c.syms["STRING"].set_value(r'''\"a'\\''')
- c.write_config(config_test_file + "_from_user", header="")
+ c.write_config(config_test_file + "_from_user")
verify_file_contents(config_test_file + "_from_user",
r'''CONFIG_STRING="\\\"a'\\\\"''' "\n")
@@ -1977,7 +1977,7 @@ tests/Krecursive2:1
c = Kconfig("Kconfiglib/tests/Korder")
- c.write_autoconf(config_test_file, header="")
+ c.write_autoconf(config_test_file)
verify_file_contents(config_test_file, """
#define CONFIG_O 0
#define CONFIG_R 1
@@ -1996,7 +1996,7 @@ tests/Krecursive2:1
c.syms["R2"].set_value("-1")
c.syms["N"].set_value("-1")
c.syms["G"].set_value("-1")
- c.write_min_config(config_test_file, header="")
+ c.write_min_config(config_test_file)
verify_file_contents(config_test_file, """
CONFIG_O=-1
CONFIG_R=-1
@@ -2006,6 +2006,44 @@ CONFIG_N=-1
CONFIG_G=-1
"""[1:])
+ # Test header strings in configuration files and headers
+
+ os.environ["KCONFIG_CONFIG_HEADER"] = "config header from env.\n"
+ os.environ["KCONFIG_AUTOHEADER_HEADER"] = "header header from env.\n"
+
+ c = Kconfig("Kconfiglib/tests/Kheader")
+ c.write_config(config_test_file, header="config header from param\n")
+ verify_file_contents(config_test_file, """\
+config header from param
+CONFIG_FOO=y
+""")
+ c.write_min_config(config_test_file, header="min. config header from param\n")
+ verify_file_contents(config_test_file, """\
+min. config header from param
+""")
+ c.write_config(config_test_file)
+ verify_file_contents(config_test_file, """\
+config header from env.
+CONFIG_FOO=y
+""")
+ c.write_min_config(config_test_file)
+ verify_file_contents(config_test_file, """\
+config header from env.
+""")
+ c.write_autoconf(config_test_file, header="header header from param\n")
+ verify_file_contents(config_test_file, """\
+header header from param
+#define CONFIG_FOO 1
+""")
+ c.write_autoconf(config_test_file)
+ verify_file_contents(config_test_file, """\
+header header from env.
+#define CONFIG_FOO 1
+""")
+
+ del os.environ["KCONFIG_CONFIG_HEADER"]
+ del os.environ["KCONFIG_AUTOHEADER_HEADER"]
+
print("Testing Kconfig fetching and separation")
@@ -3148,8 +3186,7 @@ def equal_configs():
return False
else:
with f:
- # [1:] strips the default header
- our = f.readlines()[1:]
+ our = f.readlines()
if their == our:
return True