diff options
| author | Ulf Magnusson <ulfalizer@gmail.com> | 2018-08-23 02:43:00 +0200 |
|---|---|---|
| committer | Ulf Magnusson <ulfalizer@gmail.com> | 2018-08-24 01:01:36 +0200 |
| commit | 13884e934ec8eda928234c6506ae27f0334ec31b (patch) | |
| tree | 0f42365dad68240c5ebe0d81f7a7327affd1bf20 /kconfiglib.py | |
| parent | 4b8805df373abebdf8e940b9511b2602640ff518 (diff) | |
Show include paths in menuconfig symbol information
Add a MenuNode.include_path attribute that holds a tuple of
(filename, linenr) tuples, giving the locations of the 'source'
statements via which the node's Kconfig file was included, starting from
the top-level Kconfig file.
Use MenuNode.include_path to give the include path for symbols and other
items in the help display in the menuconfig interface. This is useful
for figuring out how Kconfig files are organized, and when reorganizing
things.
Diffstat (limited to 'kconfiglib.py')
| -rw-r--r-- | kconfiglib.py | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/kconfiglib.py b/kconfiglib.py index a16a215..3d46630 100644 --- a/kconfiglib.py +++ b/kconfiglib.py @@ -590,6 +590,7 @@ class Kconfig(object): "_file", "_filename", "_linenr", + "_include_path", "_filestack", "_line", "_saved_line", @@ -752,6 +753,7 @@ class Kconfig(object): self.top_node.dep = self.y self.top_node.filename = filename self.top_node.linenr = 1 + self.top_node.include_path = () # Parse the Kconfig files @@ -760,8 +762,9 @@ class Kconfig(object): self._has_tokens = False # Keeps track of the location in the parent Kconfig files. Kconfig - # files usually source other Kconfig files. + # files usually source other Kconfig files. See _enter_file(). self._filestack = [] + self._include_path = () # The current parsing location self._filename = filename @@ -1542,19 +1545,35 @@ class Kconfig(object): # self._filename (which makes it indirectly show up in # MenuNode.filename). Equals full_filename for absolute paths. - self._filestack.append((self._filename, self._linenr, self._file)) + # The parent Kconfig files are represented as a list of + # (<include path>, <Python 'file' object for Kconfig file>) tuples. + # + # <include path> is immutable and holds a *tuple* of + # (<filename>, <linenr>) tuples, giving the locations of the 'source' + # statements in the parent Kconfig files. The current include path is + # also available in Kconfig._include_path. + # + # The point of this redundant setup is to allow Kconfig._include_path + # to be assigned directly to MenuNode.include_path without having to + # copy it, sharing it wherever possible. + + # Save include path and 'file' object before entering the file + self._filestack.append((self._include_path, self._file)) + + # _include_path is a tuple, so this rebinds the variable instead of + # doing in-place modification + self._include_path += ((self._filename, self._linenr),) # Check for recursive 'source' - for name, _, _ in self._filestack: + for name, _ in self._include_path: if name == rel_filename: raise KconfigError( "\n{}:{}: Recursive 'source' of '{}' detected. Check that " "environment variables are set correctly.\n" - "Backtrace:\n{}" + "Include path:\n{}" .format(self._filename, self._linenr, rel_filename, "\n".join("{}:{}".format(name, linenr) - for name, linenr, _ - in reversed(self._filestack)))) + for name, linenr in self._include_path))) # Note: We already know that the file exists @@ -1569,10 +1588,14 @@ class Kconfig(object): self._linenr = 0 def _leave_file(self): - # Returns from a Kconfig file to the file that sourced it + # Returns from a Kconfig file to the file that sourced it. See + # _enter_file(). self._file.close() - self._filename, self._linenr, self._file = self._filestack.pop() + # Restore location from parent Kconfig file + self._filename, self._linenr = self._include_path[-1] + # Restore include path and 'file' object + self._include_path, self._file = self._filestack.pop() def _next_line(self): # Fetches and tokenizes the next line from the current Kconfig file. @@ -2221,6 +2244,7 @@ class Kconfig(object): node.parent = parent node.filename = self._filename node.linenr = self._linenr + node.include_path = self._include_path sym.nodes.append(node) @@ -2304,6 +2328,7 @@ class Kconfig(object): node.parent = parent node.filename = self._filename node.linenr = self._linenr + node.include_path = self._include_path self.menus.append(node) @@ -2323,6 +2348,7 @@ class Kconfig(object): node.parent = parent node.filename = self._filename node.linenr = self._linenr + node.include_path = self._include_path self.comments.append(node) @@ -2358,6 +2384,7 @@ class Kconfig(object): node.parent = parent node.filename = self._filename node.linenr = self._linenr + node.include_path = self._include_path choice.nodes.append(node) @@ -3112,11 +3139,12 @@ class Kconfig(object): # Hint printed when Kconfig files can't be found or .config files can't # be opened - return ". Perhaps the $srctree environment variable (set to '{}') " \ + return ". Perhaps the $srctree environment variable ({}) " \ "is set incorrectly. Note that the current value of $srctree " \ "is saved when the Kconfig instance is created (for " \ "consistency and to cleanly separate instances)." \ - .format(self.srctree if self.srctree else "unset or blank") + .format("set to '{}'".format(self.srctree) if self.srctree + else "unset or blank") class Symbol(object): """ @@ -3868,7 +3896,7 @@ class Symbol(object): self._dependents = set() # Used during dependency loop detection and (independently) in - # write_config() + # node_iter() self._visited = 0 def _assignable(self): @@ -4615,6 +4643,15 @@ class MenuNode(object): $srctree (or to the current directory if $srctree isn't set), except absolute paths passed to 'source' and Kconfig.__init__() are preserved. + include_path: + A tuple of (filename, linenr) tuples, giving the locations of the + 'source' statements via which the Kconfig file containing this menu node + was included. The first element is the location of the 'source' statement + in the top-level Kconfig file passed to Kconfig.__init__(), etc. + + Note that the Kconfig file of the menu node itself isn't included. Check + 'filename' and 'linenr' for that. + kconfig: The Kconfig instance the menu node is from. """ @@ -4622,6 +4659,7 @@ class MenuNode(object): "dep", "filename", "help", + "include_path", "is_menuconfig", "item", "kconfig", |
