mirror of
https://github.com/littlefs-project/littlefs.git
synced 2025-12-05 15:15:30 +00:00
I don't know how I completely missed that this doesn't actually work! Using del _does_ work in Python's repl, but it makes sense the repl may differ from actual function execution in this case. The problem is Python still thinks the relevant builtin is a local variables after deletion, raising an UnboundLocalError instead of performing a global lookup. In theory this would work if the variable could be made global, but since global/nonlocal statements are lifted, Python complains with "SyntaxError: name 'list' is parameter and global". And that's A-Ok! Intentionally shadowing language builtins already puts this code deep into ugly hacks territory.
122 lines
3.0 KiB
Python
Executable File
122 lines
3.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# prevent local imports
|
|
if __name__ == "__main__":
|
|
__import__('sys').path.pop(0)
|
|
|
|
import io
|
|
import math as mt
|
|
import os
|
|
import struct
|
|
import sys
|
|
|
|
|
|
# open with '-' for stdin/stdout
|
|
def openio(path, mode='r', buffering=-1):
|
|
import os
|
|
if path == '-':
|
|
if 'r' in mode:
|
|
return os.fdopen(os.dup(sys.stdin.fileno()), mode, buffering)
|
|
else:
|
|
return os.fdopen(os.dup(sys.stdout.fileno()), mode, buffering)
|
|
else:
|
|
return open(path, mode, buffering)
|
|
|
|
def fromleb128(data, j=0):
|
|
word = 0
|
|
d = 0
|
|
while j+d < len(data):
|
|
b = data[j+d]
|
|
word |= (b & 0x7f) << 7*d
|
|
word &= 0xffffffff
|
|
if not b & 0x80:
|
|
return word, d+1
|
|
d += 1
|
|
return word, d
|
|
|
|
def dbg_leb128s(data, *,
|
|
word_bits=32):
|
|
# figure out leb128 size in bytes
|
|
if word_bits != 0:
|
|
n = mt.ceil(word_bits / 7)
|
|
|
|
# parse leb128s
|
|
lines = []
|
|
j = 0
|
|
while j < len(data):
|
|
# bounded leb128s?
|
|
if word_bits != 0:
|
|
word, d = fromleb128(data[j:j+n])
|
|
# unbounded?
|
|
else:
|
|
word, d = fromleb128(data, j)
|
|
|
|
lines.append((
|
|
' '.join('%02x' % b for b in data[j:j+d]),
|
|
word))
|
|
j += d
|
|
|
|
# figure out widths
|
|
w = [0]
|
|
for l in lines:
|
|
w[0] = max(w[0], len(l[0]))
|
|
|
|
# then print results
|
|
for l in lines:
|
|
print('%-*s %s' % (
|
|
w[0], l[0],
|
|
l[1]))
|
|
|
|
def main(leb128s, *,
|
|
hex=False,
|
|
input=None,
|
|
word_bits=32):
|
|
import builtins
|
|
hex_, hex = hex, builtins.hex
|
|
|
|
# interpret as a sequence of hex bytes
|
|
if hex_:
|
|
bytes_ = [b for leb128 in leb128s for b in leb128.split()]
|
|
dbg_leb128s(bytes(int(b, 16) for b in bytes_),
|
|
word_bits=word_bits)
|
|
|
|
# parse leb128s in a file
|
|
elif input:
|
|
with openio(input, 'rb') as f:
|
|
dbg_leb128s(f.read(),
|
|
word_bits=word_bits)
|
|
|
|
# we don't currently have a default interpretation
|
|
else:
|
|
print("error: no -x/--hex or -i/--input?",
|
|
file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import argparse
|
|
import sys
|
|
parser = argparse.ArgumentParser(
|
|
description="Decode leb128s.",
|
|
allow_abbrev=False)
|
|
parser.add_argument(
|
|
'leb128s',
|
|
nargs='*',
|
|
help="Leb128s to decode.")
|
|
parser.add_argument(
|
|
'-x', '--hex',
|
|
action='store_true',
|
|
help="Interpret as a sequence of hex bytes.")
|
|
parser.add_argument(
|
|
'-i', '--input',
|
|
help="Read leb128s from this file. Can use - for stdin.")
|
|
parser.add_argument(
|
|
'-w', '--word-bits',
|
|
nargs='?',
|
|
type=lambda x: int(x, 0),
|
|
const=0,
|
|
help="Word size in bits. 0 is unbounded. Defaults to 32.")
|
|
sys.exit(main(**{k: v
|
|
for k, v in vars(parser.parse_intermixed_args()).items()
|
|
if v is not None}))
|