Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[Contribs] Add command-line utility for looking up gPXE error codes.
- Loading branch information
Showing
2 changed files
with
129 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#!/usr/bin/env python | ||
import sys | ||
import re | ||
|
||
pxenv_status_files = ('../../src/include/errno.h', ) | ||
errfile_files = ('../../src/include/gpxe/errfile.h', | ||
'../../src/arch/i386/include/bits/errfile.h') | ||
posix_errno_files = ('../../src/include/errno.h', ) | ||
|
||
PXENV_STATUS_RE = re.compile(r'^#define\s+(PXENV_STATUS_[^\s]+)\s+(.+)$') | ||
ERRFILE_RE = re.compile(r'^#define\s+(ERRFILE_[^\s]+)\s+(.+)$') | ||
POSIX_ERRNO_RE = re.compile(r'^#define\s+(E[A-Z]+)\s+.*(0x[0-9a-f]+).*$') | ||
|
||
def err(msg): | ||
sys.stderr.write('%s: %s\n' % (sys.argv[0], msg)) | ||
sys.exit(1) | ||
|
||
def load_header_file(filename, regexp): | ||
defines = {} | ||
for line in open(filename, 'r'): | ||
m = regexp.match(line) | ||
if m: | ||
key, val = m.groups() | ||
defines[key] = val | ||
return defines | ||
|
||
def evaluate(defines, expr): | ||
pyexpr = '' | ||
for token in expr.split(): | ||
if token in '()': | ||
pass | ||
elif token.startswith('/*') or token.startswith('//'): | ||
break | ||
elif token.startswith('0x') or token == '|': | ||
pyexpr += token | ||
else: | ||
if token in defines: | ||
pyexpr += '0x%x' % defines[token] | ||
else: | ||
return -1 | ||
if not re.match(r'^[0-9a-zA-Z_|]+$', pyexpr): | ||
err('invalid expression') | ||
return eval(pyexpr) | ||
|
||
def build(filenames, regexp): | ||
unevaluated = {} | ||
for filename in filenames: | ||
unevaluated.update(load_header_file(filename, regexp)) | ||
|
||
evaluated = {} | ||
changed = True | ||
while changed: | ||
changed = False | ||
for key in list(unevaluated.keys()): | ||
val = evaluate(evaluated, unevaluated[key]) | ||
if val != -1: | ||
del unevaluated[key] | ||
evaluated[key] = val | ||
changed = True | ||
if unevaluated: | ||
err('unable to evaluate all #defines') | ||
return evaluated | ||
|
||
print 'pxenv_status =', repr(build(pxenv_status_files, PXENV_STATUS_RE)) | ||
print 'errfile =', repr(build(errfile_files, ERRFILE_RE)) | ||
print 'posix_errno =', repr(build(posix_errno_files, POSIX_ERRNO_RE)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#!/usr/bin/env python | ||
import sys | ||
|
||
try: | ||
import errcodedb | ||
except ImportError: | ||
sys.stderr.write('Please run this first: ./build_errcodedb.py >errcodedb.py\n') | ||
sys.exit(1) | ||
|
||
def to_pxenv_status(errno): | ||
return errno & 0xff | ||
|
||
def to_uniq(errno): | ||
return (errno >> 8) & 0x1f | ||
|
||
def to_errfile(errno): | ||
return (errno >> 13) & 0x7ff | ||
|
||
def to_posix_errno(errno): | ||
return (errno >> 24) & 0x7f | ||
|
||
def lookup_errno_component(defines, selector, component): | ||
for key, val in defines.iteritems(): | ||
if selector(val) == component: | ||
return key | ||
return '0x%x' % component | ||
|
||
class Errno(object): | ||
def __init__(self, errno): | ||
self.pxenv_status = to_pxenv_status(errno) | ||
self.uniq = to_uniq(errno) | ||
self.errfile = to_errfile(errno) | ||
self.posix_errno = to_posix_errno(errno) | ||
|
||
def rawstr(self): | ||
return 'pxenv_status=0x%x uniq=%d errfile=0x%x posix_errno=0x%x' % (self.pxenv_status, self.uniq, self.errfile, self.posix_errno) | ||
|
||
def prettystr(self): | ||
return 'pxenv_status=%s uniq=%d errfile=%s posix_errno=%s' % ( | ||
lookup_errno_component(errcodedb.pxenv_status, to_pxenv_status, self.pxenv_status), | ||
self.uniq, | ||
lookup_errno_component(errcodedb.errfile, to_errfile, self.errfile), | ||
lookup_errno_component(errcodedb.posix_errno, to_posix_errno, self.posix_errno) | ||
) | ||
|
||
def __str__(self): | ||
return self.prettystr() | ||
|
||
def usage(): | ||
sys.stderr.write('usage: %s ERROR_NUMBER\n' % sys.argv[0]) | ||
sys.exit(1) | ||
|
||
if __name__ == '__main__': | ||
if len(sys.argv) != 2: | ||
usage() | ||
|
||
try: | ||
errno = int(sys.argv[1], 16) | ||
except ValueError: | ||
usage() | ||
|
||
print Errno(errno) | ||
sys.exit(0) |