Passing an error reoter hook into WmlIterator was dumb.
This sort of thing is what subclassing is for.
This commit is contained in:
parent
7800a69318
commit
90e8b6e052
2 changed files with 26 additions and 20 deletions
|
@ -74,6 +74,11 @@ class WmlIterator(object):
|
|||
Initialize with a list of lines or a file; if the the line list is
|
||||
empty and the filename is specified, lines will be read from the file.
|
||||
|
||||
This is meant to be subclassed. It needs a printError method but
|
||||
does not have one. The method should take any number of string arguments,
|
||||
compose them into an error notification, and deliver it. It may fire
|
||||
more than once during the instance lifetime.
|
||||
|
||||
Note: if changes are made to lines while iterating, this may produce
|
||||
unexpected results. In such case, seek() to the linenumber of a
|
||||
scope behind where changes were made.
|
||||
|
@ -92,7 +97,7 @@ Important Attributes:
|
|||
always 1, unless text contains a multi-line quoted string
|
||||
lineno - a zero-based line index marking where this text begins
|
||||
"""
|
||||
def __init__(self, lines=None, filename=None, begin=-1, onerr=None):
|
||||
def __init__(self, lines=None, filename=None, begin=-1):
|
||||
"Initialize a new WmlIterator."
|
||||
self.fname = filename
|
||||
if lines is None:
|
||||
|
@ -103,9 +108,8 @@ Important Attributes:
|
|||
lines = ifp.readlines()
|
||||
ifp.close()
|
||||
except Exception:
|
||||
self.onerr(self, 'error opening file')
|
||||
self.printError('error opening file')
|
||||
self.lines = lines
|
||||
self.onerr = onerr
|
||||
self.reset()
|
||||
self.seek(begin)
|
||||
|
||||
|
@ -124,7 +128,7 @@ Important Attributes:
|
|||
endquote = text.find('"', beginofend)
|
||||
if endquote < 0:
|
||||
if self.lineno + span >= len(lines):
|
||||
self.onerr(self, 'reached EOF due to unterminated string')
|
||||
self.printError('reached EOF due to unterminated string')
|
||||
return text, span
|
||||
text += lines[self.lineno + span]
|
||||
span += 1
|
||||
|
@ -151,7 +155,7 @@ Important Attributes:
|
|||
if ((isOpener(elem) and closerElement != '[/'+elem[1:]
|
||||
and '+'+closerElement != elem[1]+'[/'+elem[2:])
|
||||
or (elem.startswith('{') and closerElement.find('macro')<0)):
|
||||
self.onerr(self, 'reached', closerElement, 'before closing scope', elem)
|
||||
self.printError('reached', closerElement, 'before closing scope', elem)
|
||||
scopes.append(closed) # to reduce additional errors (hopefully)
|
||||
return True
|
||||
except IndexError:
|
||||
|
@ -247,7 +251,7 @@ Important Attributes:
|
|||
|
||||
def printScopeError(self, elementType):
|
||||
"""Print out warning if a scope was unable to close"""
|
||||
self.onerr(self, 'attempt to close empty scope at', elementType)
|
||||
self.printError('attempt to close empty scope at', elementType)
|
||||
|
||||
def __iter__(self):
|
||||
"""The magic iterator method"""
|
||||
|
@ -324,7 +328,7 @@ Important Attributes:
|
|||
note: May raise StopIteration"""
|
||||
if not self.hasNext():
|
||||
if self.scopes:
|
||||
self.onerr(self, "reached EOF with open scopes", self.scopes)
|
||||
self.printError("reached EOF with open scopes", self.scopes)
|
||||
raise StopIteration
|
||||
self.lineno = self.lineno + self.span
|
||||
self.text, self.span = self.parseQuotes(self.lines)
|
||||
|
|
|
@ -333,19 +333,21 @@ declared_spellings = {"GLOBAL":["I'm", "I've", "I'd", "I'll",
|
|||
"princeling", "wilderlands", "ensorcels"
|
||||
]}
|
||||
|
||||
def printError(nav, *misc):
|
||||
"""Emit an error locator compatible with Emacs compilation mode."""
|
||||
if nav.lineno == -1:
|
||||
print >>sys.stderr, '"%s":' % nav.fname
|
||||
else:
|
||||
print >>sys.stderr, '"%s", line %d:' % (nav.fname, nav.lineno+1)
|
||||
for item in misc:
|
||||
print >>sys.stderr, item,
|
||||
print >>sys.stderr #terminate line
|
||||
class WmllintIterator(WmlIterator):
|
||||
"Fold an Emacs-compatible error reporter into WmlIterator."
|
||||
def printError(self, *misc):
|
||||
"""Emit an error locator compatible with Emacs compilation mode."""
|
||||
if self.lineno == -1:
|
||||
print >>sys.stderr, '"%s":' % self.fname
|
||||
else:
|
||||
print >>sys.stderr, '"%s", line %d:' % (self.fname, self.lineno+1)
|
||||
for item in misc:
|
||||
print >>sys.stderr, item,
|
||||
print >>sys.stderr #terminate line
|
||||
|
||||
def sanity_check(filename, lines):
|
||||
"Perform sanity and consistency checks on input lines."
|
||||
for nav in WmlIterator(filename=fn, onerr=printError):
|
||||
for nav in WmllintIterator(filename=fn):
|
||||
# Check for things marked translated that aren't strings
|
||||
if "_" in nav.text and not "wmllint: ignore" in nav.text:
|
||||
m = re.search(r'[=(]\s*_\s+("?)', nav.text)
|
||||
|
@ -1198,7 +1200,7 @@ def spellcheck(fn, d):
|
|||
map(d.add_to_session, local_spellings)
|
||||
|
||||
# Process this individual file
|
||||
for nav in WmlIterator(filename=fn, onerr=printError):
|
||||
for nav in WmllintIterator(filename=fn):
|
||||
#print "element=%s, text=%s" % (nav.element, `nav.text`)
|
||||
# Recognize local spelling exceptions
|
||||
if not nav.element and "#" in nav.text:
|
||||
|
@ -1211,11 +1213,11 @@ def spellcheck(fn, d):
|
|||
d.add_to_session(word)
|
||||
local_spellings.append(word)
|
||||
else:
|
||||
printError(nav, " %s already declared" % word)
|
||||
nav.printError(" %s already declared" % word)
|
||||
#if local_spellings:
|
||||
# print "%s: with this file's local spellings: %s" % (fn,local_spellings)
|
||||
|
||||
for nav in WmlIterator(filename=fn, onerr=printError):
|
||||
for nav in WmllintIterator(filename=fn):
|
||||
# Spell-check message and story parts
|
||||
if nav.element in spellcheck_these:
|
||||
# Special case, beyond us until we can do better filtering..
|
||||
|
|
Loading…
Add table
Reference in a new issue