summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kconfiglib.py72
-rw-r--r--tests/Klocation30
-rw-r--r--testsuite.py32
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))
#