diff options
| -rw-r--r-- | kconfiglib.py | 72 | ||||
| -rw-r--r-- | tests/Klocation | 30 | ||||
| -rw-r--r-- | testsuite.py | 32 |
3 files changed, 85 insertions, 49 deletions
diff --git a/kconfiglib.py b/kconfiglib.py index ad02373..d1e090c 100644 --- a/kconfiglib.py +++ b/kconfiglib.py @@ -3099,38 +3099,68 @@ class _Feed(object): return True return False - def unget(self): - if self.i <= 0: - _internal_error("Attempt to move back in Feed while already at " - "the beginning.") - self.i -= 1 - def unget_all(self): self.i = 0 def __len__(self): return self.length -class _FileFeed(_Feed): +class _FileFeed(object): - """_Feed subclass that feeds lines from a file. Joins any line ending in - \\ with the following line. Keeps track of the filename and current line - number.""" + """Feeds lines from a file. Keeps track of the filename and current line + number. Joins any line ending in \\ with the following line. We need to be + careful to get the line number right in the presence of continuation + lines.""" def __init__(self, filename): self.filename = _clean_up_path(filename) - _Feed.__init__(self, _get_lines(filename)) + with open(filename, "r") as f: + # No interleaving of I/O and processing yet. Don't know if it would + # help. + self.lines = f.readlines() + self.length = len(self.lines) + self.linenr = 0 + + def get_next(self): + if self.linenr >= self.length: + return None + line = self.lines[self.linenr] + self.linenr += 1 + while line.endswith("\\\n"): + line = line[:-2] + self.lines[self.linenr] + self.linenr += 1 + return line + + def peek_next(self): + linenr = self.linenr + if linenr >= self.length: + return None + line = self.lines[linenr] + while line.endswith("\\\n"): + linenr += 1 + line = res[:-2] + self.lines[linenr] + return line + + def unget(self): + self.linenr -= 1 + while self.lines[self.linenr].endswith("\\\n"): + self.linenr -= 1 def remove_blank(self): """Removes lines until the first non-blank (not all-space) line.""" - while self.i < self.length and self.items[self.i].isspace(): - self.i += 1 + while 1: + line = self.get_next() + if line is None: + break + if not line.isspace(): + self.unget() + break def get_filename(self): return self.filename def get_linenr(self): - return self.i + return self.linenr # # Internal functions @@ -3348,20 +3378,6 @@ def _comment(s): return res + "#" return res -def _get_lines(filename): - """Returns a list of lines from 'filename', joining any line ending in \\ - with the following line.""" - with open(filename, "r") as f: - lines = [] - accum = "" - for line in f: - if line.endswith("\\\n"): - accum += line[:-2] - else: - lines.append(accum + line) - accum = "" - return lines - def _clean_up_path(path): """Strips an initial "./" and any trailing slashes from 'path'.""" if path.startswith("./"): diff --git a/tests/Klocation b/tests/Klocation index e445deb..76a886b 100644 --- a/tests/Klocation +++ b/tests/Klocation @@ -1,10 +1,15 @@ +# Include some line continuations to make sure they don't mess up line numbers + # Defined and referenced in multiple locations config A bool +# Throw in some line continuations too to make sure it doesn't mess up the line +# numbers menu "menu 1" depends on A - visible if A && NOT_DEFINED + visible if A && \ + NOT_DEFINED # Also defined in Klocation_included choice B @@ -16,6 +21,8 @@ config C config D bool "d" +\ + endchoice config A @@ -29,16 +36,29 @@ config E endmenu -config FOO +config \ + FOO string - option env="FOO" + option \ + env\ + =\ + "FOO" + +\ +\ config BAR string - default "_included" + default \ + "_included" # Expands to "tests/Klocation_included" -source "$FOO/Klocation$BAR" +source \ +"$FOO/Klocation$BAR" + +\ +\ +\ config I int diff --git a/testsuite.py b/testsuite.py index a4c9cb3..20974d0 100644 --- a/testsuite.py +++ b/testsuite.py @@ -710,12 +710,12 @@ def run_selftests(): verify_def_locations("y") verify_def_locations("A", - ("Kconfiglib/tests/Klocation", 2), - ("Kconfiglib/tests/Klocation", 21), + ("Kconfiglib/tests/Klocation", 4), + ("Kconfiglib/tests/Klocation", 28), ("Kconfiglib/tests/Klocation_included", 1), ("Kconfiglib/tests/Klocation_included", 3)) verify_def_locations("C", - ("Kconfiglib/tests/Klocation", 13)) + ("Kconfiglib/tests/Klocation", 18)) verify_def_locations("M", ("Kconfiglib/tests/Klocation_included", 6)) verify_def_locations("N", @@ -738,11 +738,11 @@ def run_selftests(): c = kconfiglib.Config("Kconfiglib/tests/Klocation", base_dir = "Kconfiglib") verify_ref_locations("A", - ("Kconfiglib/tests/Klocation", 6), - ("Kconfiglib/tests/Klocation", 7), - ("Kconfiglib/tests/Klocation", 11), - ("Kconfiglib/tests/Klocation", 27), - ("Kconfiglib/tests/Klocation", 28), + ("Kconfiglib/tests/Klocation", 10), + ("Kconfiglib/tests/Klocation", 12), + ("Kconfiglib/tests/Klocation", 16), + ("Kconfiglib/tests/Klocation", 34), + ("Kconfiglib/tests/Klocation", 35), ("Kconfiglib/tests/Klocation_included", 7), ("Kconfiglib/tests/Klocation_included", 8), ("Kconfiglib/tests/Klocation_included", 9), @@ -750,13 +750,13 @@ def run_selftests(): ("Kconfiglib/tests/Klocation_included", 13), ("Kconfiglib/tests/Klocation_included", 33), ("Kconfiglib/tests/Klocation_included", 38), - ("Kconfiglib/tests/Klocation", 45), - ("Kconfiglib/tests/Klocation", 46), - ("Kconfiglib/tests/Klocation", 47)) + ("Kconfiglib/tests/Klocation", 65), + ("Kconfiglib/tests/Klocation", 66), + ("Kconfiglib/tests/Klocation", 67)) verify_ref_locations("C") verify_ref_locations("NOT_DEFINED", - ("Kconfiglib/tests/Klocation", 7), - ("Kconfiglib/tests/Klocation", 22), + ("Kconfiglib/tests/Klocation", 12), + ("Kconfiglib/tests/Klocation", 29), ("Kconfiglib/tests/Klocation_included", 12), ("Kconfiglib/tests/Klocation_included", 33), ("Kconfiglib/tests/Klocation_included", 39)) @@ -781,7 +781,7 @@ def run_selftests(): "The second choice should have no name") verify_choice_locations(choice_1, - ("Kconfiglib/tests/Klocation", 10), + ("Kconfiglib/tests/Klocation", 15), ("Kconfiglib/tests/Klocation_included", 22)) verify_choice_locations(choice_2, ("Kconfiglib/tests/Klocation_included", 15)) @@ -802,9 +802,9 @@ def run_selftests(): menu_1, menu_2 = c.get_menus()[:-1] comment_1, comment_2 = c.get_comments() - verify_location(menu_1, ("Kconfiglib/tests/Klocation", 5)) + verify_location(menu_1, ("Kconfiglib/tests/Klocation", 9)) verify_location(menu_2, ("Kconfiglib/tests/Klocation_included", 5)) - verify_location(comment_1, ("Kconfiglib/tests/Klocation", 24)) + verify_location(comment_1, ("Kconfiglib/tests/Klocation", 31)) verify_location(comment_2, ("Kconfiglib/tests/Klocation_included", 34)) # |
