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__":
|
if __name__ == "__main__":
|
||||||
__import__('sys').path.pop(0)
|
__import__('sys').path.pop(0)
|
||||||
|
|
||||||
|
import functools as ft
|
||||||
|
|
||||||
ERRS = [
|
|
||||||
('OK', 0, "No error" ),
|
# Error codes
|
||||||
('UNKNOWN', -1, "Unknown error" ),
|
ERR_OK = 0 # No error
|
||||||
('INVAL', -22, "Invalid parameter" ),
|
ERR_UNKNOWN = -1 # Unknown error
|
||||||
('NOTSUP', -95, "Operation not supported" ),
|
ERR_INVAL = -22 # Invalid parameter
|
||||||
('IO', -5, "Error during device operation" ),
|
ERR_NOTSUP = -95 # Operation not supported
|
||||||
('CORRUPT', -84, "Corrupted" ),
|
ERR_IO = -5 # Error during device operation
|
||||||
('NOENT', -2, "No directory entry" ),
|
ERR_CORRUPT = -84 # Corrupted
|
||||||
('EXIST', -17, "Entry already exists" ),
|
ERR_NOENT = -2 # No directory entry
|
||||||
('NOTDIR', -20, "Entry is not a dir" ),
|
ERR_EXIST = -17 # Entry already exists
|
||||||
('ISDIR', -21, "Entry is a dir" ),
|
ERR_NOTDIR = -20 # Entry is not a dir
|
||||||
('NOTEMPTY', -39, "Dir is not empty" ),
|
ERR_ISDIR = -21 # Entry is a dir
|
||||||
('FBIG', -27, "File too large" ),
|
ERR_NOTEMPTY = -39 # Dir is not empty
|
||||||
('NOSPC', -28, "No space left on device" ),
|
ERR_FBIG = -27 # File too large
|
||||||
('NOMEM', -12, "No more memory available" ),
|
ERR_NOSPC = -28 # No space left on device
|
||||||
('NOATTR', -61, "No data/attr available" ),
|
ERR_NOMEM = -12 # No more memory available
|
||||||
('NAMETOOLONG', -36, "File name too long" ),
|
ERR_NOATTR = -61 # No data/attr available
|
||||||
('RANGE', -34, "Result out of range" ),
|
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, *,
|
def main(errs, *,
|
||||||
@@ -31,51 +78,64 @@ def main(errs, *,
|
|||||||
import builtins
|
import builtins
|
||||||
list_, list = list, builtins.list
|
list_, list = list, builtins.list
|
||||||
|
|
||||||
|
# find errs
|
||||||
|
errs__ = globals()['errs']()
|
||||||
|
|
||||||
lines = []
|
lines = []
|
||||||
# list all known error codes
|
# list all known error codes
|
||||||
if list_:
|
if list_:
|
||||||
for n, e, h in ERRS:
|
for e in errs__:
|
||||||
lines.append(('LFS3_ERR_'+n, str(e), h))
|
lines.append(e.line())
|
||||||
|
|
||||||
# find these errors
|
# find errs by name or value
|
||||||
else:
|
else:
|
||||||
def find_err(err):
|
for e_ in errs:
|
||||||
|
found = False
|
||||||
# find by LFS3_ERR_+name
|
# find by LFS3_ERR_+name
|
||||||
for n, e, h in ERRS:
|
for e in errs__:
|
||||||
if 'LFS3_ERR_'+n == err.upper():
|
if 'LFS3_%s' % e.name.upper() == e_.upper():
|
||||||
return n, e, h
|
lines.append(e.line())
|
||||||
|
found = True
|
||||||
|
if found:
|
||||||
|
continue
|
||||||
# find by ERR_+name
|
# find by ERR_+name
|
||||||
for n, e, h in ERRS:
|
for e in errs__:
|
||||||
if 'ERR_'+n == err.upper():
|
if e.name.upper() == e_.upper():
|
||||||
return n, e, h
|
lines.append(e.line())
|
||||||
|
found = True
|
||||||
|
if found:
|
||||||
|
continue
|
||||||
# find by name
|
# find by name
|
||||||
for n, e, h in ERRS:
|
for e in errs__:
|
||||||
if n == err.upper():
|
if e.name.split('_', 1)[1] == e_.upper():
|
||||||
return n, e, h
|
lines.append(e.line())
|
||||||
|
found = True
|
||||||
|
if found:
|
||||||
|
continue
|
||||||
# find by E+name
|
# find by E+name
|
||||||
for n, e, h in ERRS:
|
for e in errs__:
|
||||||
if 'E'+n == err.upper():
|
if 'E%s' % e.name.split('_', 1)[1].upper() == e_.upper():
|
||||||
return n, e, h
|
lines.append(e.line())
|
||||||
|
found = True
|
||||||
|
if found:
|
||||||
|
continue
|
||||||
try:
|
try:
|
||||||
# find by err code
|
# find by err code
|
||||||
for n, e, h in ERRS:
|
for e in errs__:
|
||||||
if e == int(err, 0):
|
if e.code == int(e_, 0):
|
||||||
return n, e, h
|
lines.append(e.line())
|
||||||
|
found = True
|
||||||
|
if found:
|
||||||
|
continue
|
||||||
# find by negated err code
|
# find by negated err code
|
||||||
for n, e, h in ERRS:
|
for e in errs__:
|
||||||
if e == -int(err, 0):
|
if e.code == -int(e_, 0):
|
||||||
return n, e, h
|
lines.append(e.line())
|
||||||
|
found = True
|
||||||
|
if found:
|
||||||
|
continue
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
lines.append(('?', e_, 'Unknown err code'))
|
||||||
# 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'))
|
|
||||||
|
|
||||||
# first find widths
|
# first find widths
|
||||||
w = [0, 0]
|
w = [0, 0]
|
||||||
|
|||||||
+333
-229
@@ -5,268 +5,372 @@ if __name__ == "__main__":
|
|||||||
__import__('sys').path.pop(0)
|
__import__('sys').path.pop(0)
|
||||||
|
|
||||||
import collections as co
|
import collections as co
|
||||||
|
import functools as ft
|
||||||
|
|
||||||
|
|
||||||
FILTERS = [
|
# Flag prefixes
|
||||||
(['--o', '--open'], 'O', "Filter by LFS3_O_* flags."),
|
PREFIX_O = ['--o', '--open'] # Filter by LFS3_O_* flags
|
||||||
(['--a', '--attr'], 'A', "Filter by LFS3_A_* flags."),
|
PREFIX_A = ['--a', '--attr'] # Filter by LFS3_A_* flags
|
||||||
(['--f', '--format'], 'F', "Filter by LFS3_F_* flags."),
|
PREFIX_F = ['--f', '--format'] # Filter by LFS3_F_* flags
|
||||||
(['--m', '--mount'], 'M', "Filter by LFS3_M_* flags."),
|
PREFIX_M = ['--m', '--mount'] # Filter by LFS3_M_* flags
|
||||||
('--gc', 'GC', "Filter by LFS3_GC_* flags."),
|
PREFIX_GC = ['--gc'] # Filter by LFS3_GC_* flags
|
||||||
(['--i', '--info'], 'I', "Filter by LFS3_I_* flags."),
|
PREFIX_I = ['--i', '--info'] # Filter by LFS3_I_* flags
|
||||||
(['--t', '--traversal'], 'T', "Filter by LFS3_T_* flags."),
|
PREFIX_T = ['--t', '--trv'] # Filter by LFS3_T_* flags
|
||||||
('--alloc', 'ALLOC', "Filter by LFS3_ALLOC_* flags."),
|
PREFIX_ALLOC = ['--alloc'] # Filter by LFS3_ALLOC_* flags
|
||||||
(['--rc', '--rcompat'], 'RCOMPAT', "Filter by LFS3_RCOMPAT_* flags."),
|
PREFIX_RCOMPAT = ['--rc', '--rcompat'] # Filter by LFS3_RCOMPAT_* flags
|
||||||
(['--wc', '--wcompat'], 'WCOMPAT', "Filter by LFS3_WCOMPAT_* flags."),
|
PREFIX_WCOMPAT = ['--wc', '--wcompat'] # Filter by LFS3_WCOMPAT_* flags
|
||||||
(['--oc', '--ocompat'], 'OCOMPAT', "Filter by LFS3_OCOMPAT_* flags."),
|
PREFIX_OCOMPAT = ['--oc', '--ocompat'] # Filter by LFS3_OCOMPAT_* flags
|
||||||
]
|
|
||||||
|
|
||||||
FLAGS = [
|
|
||||||
# File open flags
|
|
||||||
('O_MODE', 3, "The file's access mode" ),
|
|
||||||
('^_RDONLY', 0, "Open a file as read only" ),
|
|
||||||
('^_WRONLY', 1, "Open a file as write only" ),
|
|
||||||
('^_RDWR', 2, "Open a file as read and write" ),
|
|
||||||
('O_CREAT', 0x00000004, "Create a file if it does not exist" ),
|
|
||||||
('O_EXCL', 0x00000008, "Fail if a file already exists" ),
|
|
||||||
('O_TRUNC', 0x00000010, "Truncate the existing file to zero size" ),
|
|
||||||
('O_APPEND', 0x00000020, "Move to end of file on every write" ),
|
|
||||||
('O_FLUSH', 0x00000040, "Flush data on every write" ),
|
|
||||||
('O_SYNC', 0x00000080, "Sync metadata on every write" ),
|
|
||||||
('O_DESYNC', 0x04000000, "Do not sync or recieve file updates" ),
|
|
||||||
('O_CKMETA', 0x00001000, "Check metadata checksums" ),
|
|
||||||
('O_CKDATA', 0x00002000, "Check metadata + data checksums" ),
|
|
||||||
|
|
||||||
('o_WRSET', 3, "Open a file as an atomic write" ),
|
# File open flags
|
||||||
('o_TYPE', 0xf0000000, "The file's type" ),
|
O_MODE = 3 # -m The file's access mode
|
||||||
('^_REG', 0x10000000, "Type = regular-file" ),
|
O_RDONLY = 0 # -^ Open a file as read only
|
||||||
('^_DIR', 0x20000000, "Type = directory" ),
|
O_WRONLY = 1 # -^ Open a file as write only
|
||||||
('^_STICKYNOTE', 0x30000000, "Type = stickynote" ),
|
O_RDWR = 2 # -^ Open a file as read and write
|
||||||
('^_BOOKMARK', 0x40000000, "Type = bookmark" ),
|
O_CREAT = 0x00000004 # -- Create a file if it does not exist
|
||||||
('^_ORPHAN', 0x50000000, "Type = orphan" ),
|
O_EXCL = 0x00000008 # -- Fail if a file already exists
|
||||||
('^_TRAVERSAL', 0x60000000, "Type = traversal" ),
|
O_TRUNC = 0x00000010 # -- Truncate the existing file to zero size
|
||||||
('^_UNKNOWN', 0x70000000, "Type = unknown" ),
|
O_APPEND = 0x00000020 # -- Move to end of file on every write
|
||||||
('o_ZOMBIE', 0x08000000, "File has been removed" ),
|
O_FLUSH = 0x00000040 # y- Flush data on every write
|
||||||
('o_UNCREAT', 0x02000000, "File does not exist yet" ),
|
O_SYNC = 0x00000080 # y- Sync metadata on every write
|
||||||
('o_UNSYNC', 0x01000000, "File's metadata does not match disk" ),
|
O_DESYNC = 0x04000000 # -- Do not sync or recieve file updates
|
||||||
('o_UNCRYST', 0x00800000, "File's leaf not fully crystallized" ),
|
O_CKMETA = 0x00001000 # -- Check metadata checksums
|
||||||
('o_UNGRAFT', 0x00400000, "File's leaf does not match disk" ),
|
O_CKDATA = 0x00002000 # -- Check metadata + data checksums
|
||||||
('o_UNFLUSH', 0x00200000, "File's cache does not match disk" ),
|
|
||||||
|
|
||||||
# Custom attribute flags
|
o_WRSET = 3 # i- Open a file as an atomic write
|
||||||
('A_MODE', 3, "The attr's access mode" ),
|
o_TYPE = 0xf0000000 # im The file's type
|
||||||
('^_RDONLY', 0, "Open an attr as read only" ),
|
o_REG = 0x10000000 # i^ Type = regular-file
|
||||||
('^_WRONLY', 1, "Open an attr as write only" ),
|
o_DIR = 0x20000000 # i^ Type = directory
|
||||||
('^_RDWR', 2, "Open an attr as read and write" ),
|
o_STICKYNOTE = 0x30000000 # i^ Type = stickynote
|
||||||
('A_LAZY', 0x04, "Only write attr if file changed" ),
|
o_BOOKMARK = 0x40000000 # i^ Type = bookmark
|
||||||
|
o_ORPHAN = 0x50000000 # i^ Type = orphan
|
||||||
|
o_TRAVERSAL = 0x60000000 # i^ Type = traversal
|
||||||
|
o_UNKNOWN = 0x70000000 # i^ Type = unknown
|
||||||
|
o_ZOMBIE = 0x08000000 # i- File has been removed
|
||||||
|
o_UNCREAT = 0x02000000 # i- File does not exist yet
|
||||||
|
o_UNSYNC = 0x01000000 # i- File's metadata does not match disk
|
||||||
|
o_UNCRYST = 0x00800000 # i- File's leaf not fully crystallized
|
||||||
|
o_UNGRAFT = 0x00400000 # i- File's leaf does not match disk
|
||||||
|
o_UNFLUSH = 0x00200000 # i- File's cache does not match disk
|
||||||
|
|
||||||
# Filesystem format flags
|
# Custom attribute flags
|
||||||
('F_MODE', 1, "Format's access mode" ),
|
A_MODE = 3 # -m The attr's access mode
|
||||||
('^_RDWR', 0, "Format the filesystem as read and write" ),
|
A_RDONLY = 0 # -^ Open an attr as read only
|
||||||
('F_REVDBG', 0x00000010, "Add debug info to revision counts" ),
|
A_WRONLY = 1 # -^ Open an attr as write only
|
||||||
('F_REVNOISE', 0x00000020, "Add noise to revision counts" ),
|
A_RDWR = 2 # -^ Open an attr as read and write
|
||||||
('F_CKPROGS', 0x00080000, "Check progs by reading back progged data" ),
|
A_LAZY = 0x04 # -- Only write attr if file changed
|
||||||
('F_CKFETCHES', 0x00100000, "Check block checksums before first use" ),
|
|
||||||
('F_CKMETAPARITY', 0x00200000, "Check metadata tag parity bits" ),
|
|
||||||
('F_CKDATACKSUMS', 0x00800000, "Check data checksums on reads" ),
|
|
||||||
|
|
||||||
('F_CKMETA', 0x00001000, "Check metadata checksums" ),
|
# Filesystem format flags
|
||||||
('F_CKDATA', 0x00002000, "Check metadata + data checksums" ),
|
F_MODE = 1 # -m Format's access mode
|
||||||
|
F_RDWR = 0 # -^ Format the filesystem as read and write
|
||||||
|
F_REVDBG = 0x00000010 # y- Add debug info to revision counts
|
||||||
|
F_REVNOISE = 0x00000020 # y- Add noise to revision counts
|
||||||
|
F_CKPROGS = 0x00080000 # y- Check progs by reading back progged data
|
||||||
|
F_CKFETCHES = 0x00100000 # y- Check block checksums before first use
|
||||||
|
F_CKMETAPARITY = 0x00200000 # y- Check metadata tag parity bits
|
||||||
|
F_CKDATACKSUMS = 0x00800000 # y- Check data checksums on reads
|
||||||
|
|
||||||
('F_GBMAP', 0x01000000, "Use the global on-disk block-map" ),
|
F_CKMETA = 0x00001000 # y- Check metadata checksums
|
||||||
|
F_CKDATA = 0x00002000 # y- Check metadata + data checksums
|
||||||
|
|
||||||
# Filesystem mount flags
|
F_GBMAP = 0x01000000 # y- Use the global on-disk block-map
|
||||||
('M_MODE', 1, "Mount's access mode" ),
|
|
||||||
('^_RDWR', 0, "Mount the filesystem as read and write" ),
|
|
||||||
('^_RDONLY', 1, "Mount the filesystem as read only" ),
|
|
||||||
('M_FLUSH', 0x00000040, "Open all files with LFS3_O_FLUSH" ),
|
|
||||||
('M_SYNC', 0x00000080, "Open all files with LFS3_O_SYNC" ),
|
|
||||||
('M_REVDBG', 0x00000010, "Add debug info to revision counts" ),
|
|
||||||
('M_REVNOISE', 0x00000020, "Add noise to revision counts" ),
|
|
||||||
('M_CKPROGS', 0x00080000, "Check progs by reading back progged data" ),
|
|
||||||
('M_CKFETCHES', 0x00100000, "Check block checksums before first use" ),
|
|
||||||
('M_CKMETAPARITY', 0x00200000, "Check metadata tag parity bits" ),
|
|
||||||
('M_CKDATACKSUMS', 0x00800000, "Check data checksums on reads" ),
|
|
||||||
|
|
||||||
('M_MKCONSISTENT', 0x00000100, "Make the filesystem consistent" ),
|
# Filesystem mount flags
|
||||||
('M_REPOPLOOKAHEAD',
|
M_MODE = 1 # -m Mount's access mode
|
||||||
0x00000200, "Repopulate lookahead buffer" ),
|
M_RDWR = 0 # -^ Mount the filesystem as read and write
|
||||||
('M_REPOPGBMAP', 0x00000400, "Repopulate the gbmap" ),
|
M_RDONLY = 1 # -^ Mount the filesystem as read only
|
||||||
('M_COMPACTMETA', 0x00000800, "Compact metadata logs" ),
|
M_FLUSH = 0x00000040 # y- Open all files with LFS3_O_FLUSH
|
||||||
('M_CKMETA', 0x00001000, "Check metadata checksums" ),
|
M_SYNC = 0x00000080 # y- Open all files with LFS3_O_SYNC
|
||||||
('M_CKDATA', 0x00002000, "Check metadata + data checksums" ),
|
M_REVDBG = 0x00000010 # y- Add debug info to revision counts
|
||||||
|
M_REVNOISE = 0x00000020 # y- Add noise to revision counts
|
||||||
|
M_CKPROGS = 0x00080000 # y- Check progs by reading back progged data
|
||||||
|
M_CKFETCHES = 0x00100000 # y- Check block checksums before first use
|
||||||
|
M_CKMETAPARITY = 0x00200000 # y- Check metadata tag parity bits
|
||||||
|
M_CKDATACKSUMS = 0x00800000 # y- Check data checksums on reads
|
||||||
|
|
||||||
# GC flags
|
M_MKCONSISTENT = 0x00000100 # y- Make the filesystem consistent
|
||||||
('GC_MKCONSISTENT',0x00000100, "Make the filesystem consistent" ),
|
M_REPOPLOOKAHEAD \
|
||||||
('GC_REPOPLOOKAHEAD',
|
= 0x00000200 # y- Repopulate lookahead buffer
|
||||||
0x00000200, "Repopulate lookahead buffer" ),
|
M_REPOPGBMAP = 0x00000400 # y- Repopulate the gbmap
|
||||||
('GC_REPOPGBMAP', 0x00000400, "Repopulate the gbmap" ),
|
M_COMPACTMETA = 0x00000800 # y- Compact metadata logs
|
||||||
('GC_COMPACTMETA', 0x00000800, "Compact metadata logs" ),
|
M_CKMETA = 0x00001000 # y- Check metadata checksums
|
||||||
('GC_CKMETA', 0x00001000, "Check metadata checksums" ),
|
M_CKDATA = 0x00002000 # y- Check metadata + data checksums
|
||||||
('GC_CKDATA', 0x00002000, "Check metadata + data checksums" ),
|
|
||||||
|
|
||||||
# Filesystem info flags
|
# GC flags
|
||||||
('I_RDONLY', 0x00000001, "Mounted read only" ),
|
GC_MKCONSISTENT = 0x00000100 # -- Make the filesystem consistent
|
||||||
('I_FLUSH', 0x00000040, "Mounted with LFS3_M_FLUSH" ),
|
GC_REPOPLOOKAHEAD \
|
||||||
('I_SYNC', 0x00000080, "Mounted with LFS3_M_SYNC" ),
|
= 0x00000200 # -- Repopulate lookahead buffer
|
||||||
('I_REVDBG', 0x00000010, "Mounted with LFS3_M_REVDBG" ),
|
GC_REPOPGBMAP = 0x00000400 # -- Repopulate the gbmap
|
||||||
('I_REVNOISE', 0x00000020, "Mounted with LFS3_M_REVNOISE" ),
|
GC_COMPACTMETA = 0x00000800 # -- Compact metadata logs
|
||||||
('I_CKPROGS', 0x00080000, "Mounted with LFS3_M_CKPROGS" ),
|
GC_CKMETA = 0x00001000 # -- Check metadata checksums
|
||||||
('I_CKFETCHES', 0x00100000, "Mounted with LFS3_M_CKFETCHES" ),
|
GC_CKDATA = 0x00002000 # -- Check metadata + data checksums
|
||||||
('I_CKMETAPARITY', 0x00200000, "Mounted with LFS3_M_CKMETAPARITY" ),
|
|
||||||
('I_CKDATACKSUMS', 0x00800000, "Mounted with LFS3_M_CKDATACKSUMS" ),
|
|
||||||
|
|
||||||
('I_MKCONSISTENT', 0x00000100, "Filesystem needs mkconsistent to write" ),
|
# Filesystem info flags
|
||||||
('I_REPOPLOOKAHEAD',
|
I_RDONLY = 0x00000001 # -- Mounted read only
|
||||||
0x00000200, "Lookahead buffer is not full" ),
|
I_FLUSH = 0x00000040 # -- Mounted with LFS3_M_FLUSH
|
||||||
('I_REPOPGBMAP', 0x00000400, "The gbmap is not full" ),
|
I_SYNC = 0x00000080 # -- Mounted with LFS3_M_SYNC
|
||||||
('I_COMPACTMETA', 0x00000800, "Filesystem may have uncompacted metadata" ),
|
I_REVDBG = 0x00000010 # -- Mounted with LFS3_M_REVDBG
|
||||||
('I_CKMETA', 0x00001000, "Metadata checksums not checked recently" ),
|
I_REVNOISE = 0x00000020 # -- Mounted with LFS3_M_REVNOISE
|
||||||
('I_CKDATA', 0x00002000, "Data checksums not checked recently" ),
|
I_CKPROGS = 0x00080000 # -- Mounted with LFS3_M_CKPROGS
|
||||||
|
I_CKFETCHES = 0x00100000 # -- Mounted with LFS3_M_CKFETCHES
|
||||||
|
I_CKMETAPARITY = 0x00200000 # -- Mounted with LFS3_M_CKMETAPARITY
|
||||||
|
I_CKDATACKSUMS = 0x00800000 # -- Mounted with LFS3_M_CKDATACKSUMS
|
||||||
|
|
||||||
('I_GBMAP', 0x01000000, "Global on-disk block-map in use" ),
|
I_MKCONSISTENT = 0x00000100 # -- Filesystem needs mkconsistent to write
|
||||||
|
I_REPOPLOOKAHEAD \
|
||||||
|
= 0x00000200 # -- Lookahead buffer is not full
|
||||||
|
I_REPOPGBMAP = 0x00000400 # -- The gbmap is not full
|
||||||
|
I_COMPACTMETA = 0x00000800 # -- Filesystem may have uncompacted metadata
|
||||||
|
I_CKMETA = 0x00001000 # -- Metadata checksums not checked recently
|
||||||
|
I_CKDATA = 0x00002000 # -- Data checksums not checked recently
|
||||||
|
|
||||||
('i_INMODE', 0x00030000, "Btree commit mode" ),
|
I_GBMAP = 0x01000000 # -- Global on-disk block-map in use
|
||||||
('^_INMTREE', 0x00010000, "Committing to mtree" ),
|
|
||||||
('^_INGBMAP', 0x00020000, "Committing to gbmap" ),
|
|
||||||
|
|
||||||
# Traversal flags
|
i_INMODE = 0x00030000 # im Btree commit mode
|
||||||
('T_MODE', 1, "The traversal's access mode" ),
|
i_INMTREE = 0x00010000 # i^ Committing to mtree
|
||||||
('^_RDWR', 0, "Open traversal as read and write" ),
|
i_INGBMAP = 0x00020000 # i^ Committing to gbmap
|
||||||
('^_RDONLY', 1, "Open traversal as read only" ),
|
|
||||||
('T_MTREEONLY', 0x00000002, "Only traverse the mtree" ),
|
|
||||||
('T_MKCONSISTENT',
|
|
||||||
0x00000100, "Make the filesystem consistent" ),
|
|
||||||
('T_REPOPLOOKAHEAD',
|
|
||||||
0x00000200, "Repopulate lookahead buffer" ),
|
|
||||||
('T_REPOPGBMAP', 0x00000400, "Repopulate the gbmap" ),
|
|
||||||
('T_COMPACTMETA', 0x00000800, "Compact metadata logs" ),
|
|
||||||
('T_CKMETA', 0x00001000, "Check metadata checksums" ),
|
|
||||||
('T_CKDATA', 0x00002000, "Check metadata + data checksums" ),
|
|
||||||
|
|
||||||
('t_TYPE', 0xf0000000, "The traversal's type" ),
|
# Traversal flags
|
||||||
('^_REG', 0x10000000, "Type = regular-file" ),
|
T_MODE = 1 # -m The traversal's access mode
|
||||||
('^_DIR', 0x20000000, "Type = directory" ),
|
T_RDWR = 0 # -^ Open traversal as read and write
|
||||||
('^_STICKYNOTE', 0x30000000, "Type = stickynote" ),
|
T_RDONLY = 1 # -^ Open traversal as read only
|
||||||
('^_BOOKMARK', 0x40000000, "Type = bookmark" ),
|
T_MTREEONLY = 0x00000002 # -- Only traverse the mtree
|
||||||
('^_ORPHAN', 0x50000000, "Type = orphan" ),
|
T_MKCONSISTENT = 0x00000100 # -- Make the filesystem consistent
|
||||||
('^_TRAVERSAL', 0x60000000, "Type = traversal" ),
|
T_REPOPLOOKAHEAD \
|
||||||
('^_UNKNOWN', 0x70000000, "Type = unknown" ),
|
= 0x00000200 # -- Repopulate lookahead buffer
|
||||||
('t_TSTATE', 0x000f0000, "The current traversal state" ),
|
T_REPOPGBMAP = 0x00000400 # -- Repopulate the gbmap
|
||||||
('^_MROOTANCHOR',
|
T_COMPACTMETA = 0x00000800 # -- Compact metadata logs
|
||||||
0x00000000, "Tstate = mroot-anchor" ),
|
T_CKMETA = 0x00001000 # -- Check metadata checksums
|
||||||
('^_MROOTCHAIN', 0x00010000, "Tstate = mroot-chain" ),
|
T_CKDATA = 0x00002000 # -- Check metadata + data checksums
|
||||||
('^_MTREE', 0x00020000, "Tstate = mtree" ),
|
|
||||||
('^_MDIRS', 0x00030000, "Tstate = mtree-mdirs" ),
|
|
||||||
('^_MDIR', 0x00040000, "Tstate = mdir" ),
|
|
||||||
('^_BTREE', 0x00050000, "Tstate = btree" ),
|
|
||||||
('^_HANDLES', 0x00060000, "Tstate = open-mdirs" ),
|
|
||||||
('^_HBTREE', 0x00070000, "Tstate = open-btree" ),
|
|
||||||
('^_GBMAP', 0x00080000, "Tstate = gbmap" ),
|
|
||||||
('^_GBMAP_P', 0x00090000, "Tstate = gbmap_p" ),
|
|
||||||
('^_DONE', 0x000a0000, "Tstate = done" ),
|
|
||||||
('t_BTYPE', 0x00f00000, "The current block type" ),
|
|
||||||
('^_MDIR', 0x00100000, "Btype = mdir" ),
|
|
||||||
('^_BTREE', 0x00200000, "Btype = btree" ),
|
|
||||||
('^_DATA', 0x00300000, "Btype = data" ),
|
|
||||||
('t_ZOMBIE', 0x08000000, "File has been removed" ),
|
|
||||||
('t_DIRTY', 0x04000000, "Filesystem ckpointed outside traversal" ),
|
|
||||||
('t_CKPOINTED', 0x02000000, "Filesystem ckpointed during traversal" ),
|
|
||||||
|
|
||||||
# Block allocator flags
|
t_TYPE = 0xf0000000 # im The traversal's type
|
||||||
('alloc_ERASE', 0x00000001, "Please erase the block" ),
|
t_REG = 0x10000000 # i^ Type = regular-file
|
||||||
|
t_DIR = 0x20000000 # i^ Type = directory
|
||||||
|
t_STICKYNOTE = 0x30000000 # i^ Type = stickynote
|
||||||
|
t_BOOKMARK = 0x40000000 # i^ Type = bookmark
|
||||||
|
t_ORPHAN = 0x50000000 # i^ Type = orphan
|
||||||
|
t_TRAVERSAL = 0x60000000 # i^ Type = traversal
|
||||||
|
t_UNKNOWN = 0x70000000 # i^ Type = unknown
|
||||||
|
t_TSTATE = 0x000f0000 # im The current traversal state
|
||||||
|
t_MROOTANCHOR = 0x00000000 # i^ Tstate = mroot-anchor
|
||||||
|
t_MROOTCHAIN = 0x00010000 # i^ Tstate = mroot-chain
|
||||||
|
t_MTREE = 0x00020000 # i^ Tstate = mtree
|
||||||
|
t_MDIRS = 0x00030000 # i^ Tstate = mtree-mdirs
|
||||||
|
t_MDIR = 0x00040000 # i^ Tstate = mdir
|
||||||
|
t_BTREE = 0x00050000 # i^ Tstate = btree
|
||||||
|
t_HANDLES = 0x00060000 # i^ Tstate = open-mdirs
|
||||||
|
t_HBTREE = 0x00070000 # i^ Tstate = open-btree
|
||||||
|
t_GBMAP = 0x00080000 # i^ Tstate = gbmap
|
||||||
|
t_GBMAP_P = 0x00090000 # i^ Tstate = gbmap_p
|
||||||
|
t_DONE = 0x000a0000 # i^ Tstate = done
|
||||||
|
t_BTYPE = 0x00f00000 # im The current block type
|
||||||
|
t_MDIR = 0x00100000 # i^ Btype = mdir
|
||||||
|
t_BTREE = 0x00200000 # i^ Btype = btree
|
||||||
|
t_DATA = 0x00300000 # i^ Btype = data
|
||||||
|
t_ZOMBIE = 0x08000000 # i- File has been removed
|
||||||
|
t_DIRTY = 0x04000000 # i- Filesystem ckpointed outside traversal
|
||||||
|
t_CKPOINTED = 0x02000000 # i- Filesystem ckpointed during traversal
|
||||||
|
|
||||||
# Read-compat flags
|
# Block allocator flags
|
||||||
('RCOMPAT_NONSTANDARD',
|
alloc_ERASE = 0x00000001 # i- Please erase the block
|
||||||
0x00000001, "Non-standard filesystem format" ),
|
|
||||||
('RCOMPAT_WRONLY', 0x00000002, "Reading is disallowed" ),
|
|
||||||
('RCOMPAT_BMOSS', 0x00000010, "Files may use inlined data" ),
|
|
||||||
('RCOMPAT_BSPROUT',0x00000020, "Files may use block pointers" ),
|
|
||||||
('RCOMPAT_BSHRUB', 0x00000040, "Files may use inlined btrees" ),
|
|
||||||
('RCOMPAT_BTREE', 0x00000080, "Files may use btrees" ),
|
|
||||||
('RCOMPAT_MMOSS', 0x00000100, "May use an inlined mdir" ),
|
|
||||||
('RCOMPAT_MSPROUT',0x00000200, "May use an mdir pointer" ),
|
|
||||||
('RCOMPAT_MSHRUB', 0x00000400, "May use an inlined mtree" ),
|
|
||||||
('RCOMPAT_MTREE', 0x00000800, "May use an mdir btree" ),
|
|
||||||
('RCOMPAT_GRM', 0x00001000, "Global-remove in use" ),
|
|
||||||
('rcompat_OVERFLOW',
|
|
||||||
0x80000000, "Can't represent all flags" ),
|
|
||||||
|
|
||||||
# Write-compat flags
|
# Read-compat flags
|
||||||
('WCOMPAT_NONSTANDARD',
|
RCOMPAT_NONSTANDARD \
|
||||||
0x00000001, "Non-standard filesystem format" ),
|
= 0x00000001 # -- Non-standard filesystem format
|
||||||
('WCOMPAT_RDONLY', 0x00000002, "Writing is disallowed" ),
|
RCOMPAT_WRONLY = 0x00000002 # -- Reading is disallowed
|
||||||
('WCOMPAT_DIR', 0x00000010, "Directory file types in use" ),
|
RCOMPAT_BMOSS = 0x00000010 # -- Files may use inlined data
|
||||||
('WCOMPAT_GCKSUM', 0x00001000, "Global-checksum in use" ),
|
RCOMPAT_BSPROUT = 0x00000020 # -- Files may use block pointers
|
||||||
('WCOMPAT_GBMAP', 0x00002000, "Global on-disk block-map in use" ),
|
RCOMPAT_BSHRUB = 0x00000040 # -- Files may use inlined btrees
|
||||||
('wcompat_OVERFLOW',
|
RCOMPAT_BTREE = 0x00000080 # -- Files may use btrees
|
||||||
0x80000000, "Can't represent all flags" ),
|
RCOMPAT_MMOSS = 0x00000100 # -- May use an inlined mdir
|
||||||
|
RCOMPAT_MSPROUT = 0x00000200 # -- May use an mdir pointer
|
||||||
|
RCOMPAT_MSHRUB = 0x00000400 # -- May use an inlined mtree
|
||||||
|
RCOMPAT_MTREE = 0x00000800 # -- May use an mdir btree
|
||||||
|
RCOMPAT_GRM = 0x00001000 # -- Global-remove in use
|
||||||
|
rcompat_OVERFLOW \
|
||||||
|
= 0x80000000 # i- Can't represent all flags
|
||||||
|
|
||||||
# Optional-compat flags
|
# Write-compat flags
|
||||||
('OCOMPAT_NONSTANDARD',
|
WCOMPAT_NONSTANDARD \
|
||||||
0x00000001, "Non-standard filesystem format" ),
|
= 0x00000001 # -- Non-standard filesystem format
|
||||||
('ocompat_OVERFLOW',
|
WCOMPAT_RDONLY = 0x00000002 # -- Writing is disallowed
|
||||||
0x80000000, "Can't represent all flags" ),
|
WCOMPAT_DIR = 0x00000010 # -- Directory file types in use
|
||||||
]
|
WCOMPAT_GCKSUM = 0x00001000 # -- Global-checksum in use
|
||||||
|
WCOMPAT_GBMAP = 0x00002000 # -- Global on-disk block-map in use
|
||||||
|
wcompat_OVERFLOW \
|
||||||
|
= 0x80000000 # i- Can't represent all flags
|
||||||
|
|
||||||
|
# Optional-compat flags
|
||||||
|
OCOMPAT_NONSTANDARD \
|
||||||
|
= 0x00000001 # -- Non-standard filesystem format
|
||||||
|
ocompat_OVERFLOW \
|
||||||
|
= 0x80000000 # i- Can't represent all flags
|
||||||
|
|
||||||
|
|
||||||
|
# self-parsing prefixes
|
||||||
|
class Prefix:
|
||||||
|
def __init__(self, name, aliases, help):
|
||||||
|
self.name = name
|
||||||
|
self.aliases = aliases
|
||||||
|
self.help = help
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return 'Prefix(%r, %r, %r)' % (
|
||||||
|
self.name,
|
||||||
|
self.aliases,
|
||||||
|
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)
|
||||||
|
|
||||||
|
@ft.cache
|
||||||
|
def prefixes():
|
||||||
|
# parse our script's source to figure out prefixes
|
||||||
|
import inspect
|
||||||
|
import re
|
||||||
|
prefixes = []
|
||||||
|
prefix_pattern = re.compile(
|
||||||
|
'^(?P<name>PREFIX_[^ ]*) *= *(?P<aliases>[^#]*?) *'
|
||||||
|
'#+ *(?P<help>.*)$')
|
||||||
|
for line in (inspect.getsource(inspect.getmodule(inspect.currentframe()))
|
||||||
|
.replace('\\\n', '')
|
||||||
|
.splitlines()):
|
||||||
|
m = prefix_pattern.match(line)
|
||||||
|
if m:
|
||||||
|
prefixes.append(Prefix(
|
||||||
|
m.group('name'),
|
||||||
|
globals()[m.group('name')],
|
||||||
|
m.group('help')))
|
||||||
|
return prefixes
|
||||||
|
|
||||||
|
# self-parsing flags
|
||||||
|
class Flag:
|
||||||
|
def __init__(self, name, flag, help, *,
|
||||||
|
prefix=None,
|
||||||
|
yes=False,
|
||||||
|
internal=False,
|
||||||
|
mask=False,
|
||||||
|
type=False):
|
||||||
|
self.name = name
|
||||||
|
self.flag = flag
|
||||||
|
self.help = help
|
||||||
|
self.prefix = prefix
|
||||||
|
self.yes = yes
|
||||||
|
self.internal = internal
|
||||||
|
self.mask = mask
|
||||||
|
self.type = type
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return 'Flag(%r, %r, %r)' % (
|
||||||
|
self.name,
|
||||||
|
self.flag,
|
||||||
|
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, '0x%08x' % self.flag, self.help)
|
||||||
|
|
||||||
|
@ft.cache
|
||||||
|
def flags():
|
||||||
|
# parse our script's source to figure out flags
|
||||||
|
import inspect
|
||||||
|
import re
|
||||||
|
|
||||||
|
# limit to known prefixes
|
||||||
|
prefixes_ = {p.name.split('_', 1)[1].upper(): p for p in prefixes()}
|
||||||
|
# keep track of last mask
|
||||||
|
mask_ = None
|
||||||
|
|
||||||
|
flags = []
|
||||||
|
flag_pattern = re.compile(
|
||||||
|
'^(?P<name>(?i:%s)_[^ ]*) '
|
||||||
|
'*= *(?P<flag>[^#]*?) *'
|
||||||
|
'#+ (?P<mode>[^ ]+) *(?P<help>.*)$'
|
||||||
|
% '|'.join(prefixes_.keys()))
|
||||||
|
for line in (inspect.getsource(inspect.getmodule(inspect.currentframe()))
|
||||||
|
.replace('\\\n', '')
|
||||||
|
.splitlines()):
|
||||||
|
m = flag_pattern.match(line)
|
||||||
|
if m:
|
||||||
|
flags.append(Flag(
|
||||||
|
m.group('name'),
|
||||||
|
globals()[m.group('name')],
|
||||||
|
m.group('help'),
|
||||||
|
# associate flags -> prefix
|
||||||
|
prefix=prefixes_[m.group('name').split('_', 1)[0].upper()],
|
||||||
|
yes='y' in m.group('mode'),
|
||||||
|
internal='i' in m.group('mode'),
|
||||||
|
mask='m' in m.group('mode'),
|
||||||
|
# associate types -> mask
|
||||||
|
type=mask_ if '^' in m.group('mode') else False))
|
||||||
|
|
||||||
|
# keep track of last mask
|
||||||
|
if flags[-1].mask:
|
||||||
|
mask_ = flags[-1]
|
||||||
|
|
||||||
|
return flags
|
||||||
|
|
||||||
|
|
||||||
def main(flags, *,
|
def main(flags, *,
|
||||||
list=False,
|
list=False,
|
||||||
all=False,
|
all=False,
|
||||||
filter=[]):
|
prefixes=[]):
|
||||||
import builtins
|
import builtins
|
||||||
list_, list = list, builtins.list
|
list_, list = list, builtins.list
|
||||||
all_, all = all, builtins.all
|
all_, all = all, builtins.all
|
||||||
filter_, filter = filter, builtins.filter
|
|
||||||
|
|
||||||
# filter by prefix if there are any filters
|
# find flags
|
||||||
filter__ = set(filter_)
|
flags__ = globals()['flags']()
|
||||||
flags__ = []
|
|
||||||
types__ = co.defaultdict(lambda: set())
|
|
||||||
for n, f, h in FLAGS:
|
|
||||||
p, n = n.split('_', 1)
|
|
||||||
if p == '^':
|
|
||||||
p = last_p
|
|
||||||
t = last_t
|
|
||||||
types__[p].add(t)
|
|
||||||
else:
|
|
||||||
t = None
|
|
||||||
last_p = p
|
|
||||||
last_t = f
|
|
||||||
|
|
||||||
if not filter__ or p.upper() in filter__:
|
# filter by prefixes if there are any prefixes
|
||||||
flags__.append((p, t, n, f, h))
|
if prefixes:
|
||||||
|
prefixes = set(prefixes)
|
||||||
|
flags__ = [f for f in flags__ if f.prefix in prefixes]
|
||||||
|
|
||||||
lines = []
|
lines = []
|
||||||
# list all known flags
|
# list all known flags
|
||||||
if list_:
|
if list_:
|
||||||
for p, t, n, f, h in flags__:
|
for f in flags__:
|
||||||
if not all_ and (t is not None or p[0].islower()):
|
if not all_ and (f.internal or f.type):
|
||||||
continue
|
continue
|
||||||
lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
|
lines.append(f.line())
|
||||||
|
|
||||||
# find flags by name or value
|
# find flags by name or value
|
||||||
else:
|
else:
|
||||||
for f_ in flags:
|
for f_ in flags:
|
||||||
found = False
|
found = False
|
||||||
# find by LFS3_+prefix+_+name
|
# find by LFS3_+prefix+_+name
|
||||||
for p, t, n, f, h in flags__:
|
for f in flags__:
|
||||||
if 'LFS3_%s_%s' % (p, n) == f_.upper():
|
if 'LFS3_%s' % f.name.upper() == f_.upper():
|
||||||
lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
|
lines.append(f.line())
|
||||||
found = True
|
found = True
|
||||||
if found:
|
if found:
|
||||||
continue
|
continue
|
||||||
# find by prefix+_+name
|
# find by prefix+_+name
|
||||||
for p, t, n, f, h in flags__:
|
for f in flags__:
|
||||||
if '%s_%s' % (p, n) == f_.upper():
|
if '%s' % f.name.upper() == f_.upper():
|
||||||
lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
|
lines.append(f.line())
|
||||||
found = True
|
found = True
|
||||||
if found:
|
if found:
|
||||||
continue
|
continue
|
||||||
# find by name
|
# find by name
|
||||||
for p, t, n, f, h in flags__:
|
for f in flags__:
|
||||||
if n == f_.upper():
|
if f.name.split('_', 1)[1].upper() == f_.upper():
|
||||||
lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
|
lines.append(f.line())
|
||||||
found = True
|
found = True
|
||||||
if found:
|
if found:
|
||||||
continue
|
continue
|
||||||
@@ -274,18 +378,18 @@ def main(flags, *,
|
|||||||
try:
|
try:
|
||||||
f__ = int(f_, 0)
|
f__ = int(f_, 0)
|
||||||
f___ = f__
|
f___ = f__
|
||||||
for p, t, n, f, h in flags__:
|
for f in flags__:
|
||||||
# ignore type masks here
|
# ignore type masks here
|
||||||
if t is None and f in types__[p]:
|
if f.mask:
|
||||||
continue
|
continue
|
||||||
# matches flag?
|
# matches flag?
|
||||||
if t is None and (f__ & f) == f:
|
if not f.type and (f__ & f.flag) == f.flag:
|
||||||
lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
|
lines.append(f.line())
|
||||||
f___ &= ~f
|
f___ &= ~f.flag
|
||||||
# matches type?
|
# matches type?
|
||||||
elif t is not None and (f__ & t) == f:
|
elif f.type and (f__ & f.type.flag) == f.flag:
|
||||||
lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
|
lines.append(f.line())
|
||||||
f___ &= ~t
|
f___ &= ~f.type.flag
|
||||||
if f___:
|
if f___:
|
||||||
lines.append(('?', '0x%08x' % f___, 'Unknown flags'))
|
lines.append(('?', '0x%08x' % f___, 'Unknown flags'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@@ -323,19 +427,19 @@ if __name__ == "__main__":
|
|||||||
'-a', '--all',
|
'-a', '--all',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help="Also show internal flags and types.")
|
help="Also show internal flags and types.")
|
||||||
class AppendFilter(argparse.Action):
|
class AppendPrefix(argparse.Action):
|
||||||
def __init__(self, nargs=None, **kwargs):
|
def __init__(self, nargs=None, **kwargs):
|
||||||
super().__init__(nargs=0, **kwargs)
|
super().__init__(nargs=0, **kwargs)
|
||||||
def __call__(self, parser, namespace, value, option):
|
def __call__(self, parser, namespace, value, option):
|
||||||
if getattr(namespace, 'filter', None) is None:
|
if getattr(namespace, 'prefixes', None) is None:
|
||||||
namespace.filter = []
|
namespace.prefixes = []
|
||||||
namespace.filter.append(self.const)
|
namespace.prefixes.append(self.const)
|
||||||
for flag, prefix, help in FILTERS:
|
for p in prefixes():
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
*([flag] if isinstance(flag, str) else flag),
|
*p.aliases,
|
||||||
action=AppendFilter,
|
action=AppendPrefix,
|
||||||
const=prefix,
|
const=p,
|
||||||
help=help)
|
help=p.help+'.')
|
||||||
sys.exit(main(**{k: v
|
sys.exit(main(**{k: v
|
||||||
for k, v in vars(parser.parse_intermixed_args()).items()
|
for k, v in vars(parser.parse_intermixed_args()).items()
|
||||||
if v is not None}))
|
if v is not None}))
|
||||||
|
|||||||
Reference in New Issue
Block a user