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:
Christopher Haster
2025-10-21 16:27:17 -05:00
parent 8a58954828
commit 0c0643d5d7
2 changed files with 444 additions and 280 deletions
+111 -51
View File
@@ -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]