scripts: Adopted self-parsing script for dgbflags/err.py encoding
This has just proven much easier to tweak in dbgtag.py, so adopting the same self-parsing pattern in dbgflags.py/dbgerr.py. This makes editing easier by (1) not needing to worry about parens/quotes/commas, and (2) allowing for non-python expressions, such as the mode flags in dbgflags.py. The only concern is script startup may be slightly slower, but we really don't care.
This commit is contained in:
+111
-51
@@ -4,26 +4,73 @@
|
||||
if __name__ == "__main__":
|
||||
__import__('sys').path.pop(0)
|
||||
|
||||
import functools as ft
|
||||
|
||||
ERRS = [
|
||||
('OK', 0, "No error" ),
|
||||
('UNKNOWN', -1, "Unknown error" ),
|
||||
('INVAL', -22, "Invalid parameter" ),
|
||||
('NOTSUP', -95, "Operation not supported" ),
|
||||
('IO', -5, "Error during device operation" ),
|
||||
('CORRUPT', -84, "Corrupted" ),
|
||||
('NOENT', -2, "No directory entry" ),
|
||||
('EXIST', -17, "Entry already exists" ),
|
||||
('NOTDIR', -20, "Entry is not a dir" ),
|
||||
('ISDIR', -21, "Entry is a dir" ),
|
||||
('NOTEMPTY', -39, "Dir is not empty" ),
|
||||
('FBIG', -27, "File too large" ),
|
||||
('NOSPC', -28, "No space left on device" ),
|
||||
('NOMEM', -12, "No more memory available" ),
|
||||
('NOATTR', -61, "No data/attr available" ),
|
||||
('NAMETOOLONG', -36, "File name too long" ),
|
||||
('RANGE', -34, "Result out of range" ),
|
||||
]
|
||||
|
||||
# Error codes
|
||||
ERR_OK = 0 # No error
|
||||
ERR_UNKNOWN = -1 # Unknown error
|
||||
ERR_INVAL = -22 # Invalid parameter
|
||||
ERR_NOTSUP = -95 # Operation not supported
|
||||
ERR_IO = -5 # Error during device operation
|
||||
ERR_CORRUPT = -84 # Corrupted
|
||||
ERR_NOENT = -2 # No directory entry
|
||||
ERR_EXIST = -17 # Entry already exists
|
||||
ERR_NOTDIR = -20 # Entry is not a dir
|
||||
ERR_ISDIR = -21 # Entry is a dir
|
||||
ERR_NOTEMPTY = -39 # Dir is not empty
|
||||
ERR_FBIG = -27 # File too large
|
||||
ERR_NOSPC = -28 # No space left on device
|
||||
ERR_NOMEM = -12 # No more memory available
|
||||
ERR_NOATTR = -61 # No data/attr available
|
||||
ERR_NAMETOOLONG = -36 # File name too long
|
||||
ERR_RANGE = -34 # Result out of range
|
||||
|
||||
|
||||
# self-parsing error codes
|
||||
class Err:
|
||||
def __init__(self, name, code, help):
|
||||
self.name = name
|
||||
self.code = code
|
||||
self.help = help
|
||||
|
||||
def __repr__(self):
|
||||
return 'Err(%r, %r, %r)' % (
|
||||
self.name,
|
||||
self.code,
|
||||
self.help)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.name == other.name
|
||||
|
||||
def __ne__(self, other):
|
||||
return self.name != other.name
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.name)
|
||||
|
||||
def line(self):
|
||||
return ('LFS3_%s' % self.name, '%d' % self.code, self.help)
|
||||
|
||||
@ft.cache
|
||||
def errs():
|
||||
# parse our script's source to figure out errs
|
||||
import inspect
|
||||
import re
|
||||
errs = []
|
||||
err_pattern = re.compile(
|
||||
'^(?P<name>ERR_[^ ]*) *= *(?P<code>[^#]*?) *'
|
||||
'#+ *(?P<help>.*)$')
|
||||
for line in (inspect.getsource(inspect.getmodule(inspect.currentframe()))
|
||||
.replace('\\\n', '')
|
||||
.splitlines()):
|
||||
m = err_pattern.match(line)
|
||||
if m:
|
||||
errs.append(Err(
|
||||
m.group('name'),
|
||||
globals()[m.group('name')],
|
||||
m.group('help')))
|
||||
return errs
|
||||
|
||||
|
||||
def main(errs, *,
|
||||
@@ -31,51 +78,64 @@ def main(errs, *,
|
||||
import builtins
|
||||
list_, list = list, builtins.list
|
||||
|
||||
# find errs
|
||||
errs__ = globals()['errs']()
|
||||
|
||||
lines = []
|
||||
# list all known error codes
|
||||
if list_:
|
||||
for n, e, h in ERRS:
|
||||
lines.append(('LFS3_ERR_'+n, str(e), h))
|
||||
for e in errs__:
|
||||
lines.append(e.line())
|
||||
|
||||
# find these errors
|
||||
# find errs by name or value
|
||||
else:
|
||||
def find_err(err):
|
||||
for e_ in errs:
|
||||
found = False
|
||||
# find by LFS3_ERR_+name
|
||||
for n, e, h in ERRS:
|
||||
if 'LFS3_ERR_'+n == err.upper():
|
||||
return n, e, h
|
||||
for e in errs__:
|
||||
if 'LFS3_%s' % e.name.upper() == e_.upper():
|
||||
lines.append(e.line())
|
||||
found = True
|
||||
if found:
|
||||
continue
|
||||
# find by ERR_+name
|
||||
for n, e, h in ERRS:
|
||||
if 'ERR_'+n == err.upper():
|
||||
return n, e, h
|
||||
for e in errs__:
|
||||
if e.name.upper() == e_.upper():
|
||||
lines.append(e.line())
|
||||
found = True
|
||||
if found:
|
||||
continue
|
||||
# find by name
|
||||
for n, e, h in ERRS:
|
||||
if n == err.upper():
|
||||
return n, e, h
|
||||
for e in errs__:
|
||||
if e.name.split('_', 1)[1] == e_.upper():
|
||||
lines.append(e.line())
|
||||
found = True
|
||||
if found:
|
||||
continue
|
||||
# find by E+name
|
||||
for n, e, h in ERRS:
|
||||
if 'E'+n == err.upper():
|
||||
return n, e, h
|
||||
for e in errs__:
|
||||
if 'E%s' % e.name.split('_', 1)[1].upper() == e_.upper():
|
||||
lines.append(e.line())
|
||||
found = True
|
||||
if found:
|
||||
continue
|
||||
try:
|
||||
# find by err code
|
||||
for n, e, h in ERRS:
|
||||
if e == int(err, 0):
|
||||
return n, e, h
|
||||
for e in errs__:
|
||||
if e.code == int(e_, 0):
|
||||
lines.append(e.line())
|
||||
found = True
|
||||
if found:
|
||||
continue
|
||||
# find by negated err code
|
||||
for n, e, h in ERRS:
|
||||
if e == -int(err, 0):
|
||||
return n, e, h
|
||||
for e in errs__:
|
||||
if e.code == -int(e_, 0):
|
||||
lines.append(e.line())
|
||||
found = True
|
||||
if found:
|
||||
continue
|
||||
except ValueError:
|
||||
pass
|
||||
# not found
|
||||
raise KeyError(err)
|
||||
|
||||
for err in errs:
|
||||
try:
|
||||
n, e, h = find_err(err)
|
||||
lines.append(('LFS3_ERR_'+n, str(e), h))
|
||||
except KeyError:
|
||||
lines.append(('?', err, 'Unknown err code'))
|
||||
lines.append(('?', e_, 'Unknown err code'))
|
||||
|
||||
# first find widths
|
||||
w = [0, 0]
|
||||
|
||||
Reference in New Issue
Block a user