scripts: Adopted double-indent on multiline expressions
This matches the style used in C, which is good for consistency:
a_really_long_function_name(
double_indent_after_first_newline(
single_indent_nested_newlines))
We were already doing this for multiline control-flow statements, simply
because I'm not sure how else you could indent this without making
things really confusing:
if a_really_long_function_name(
double_indent_after_first_newline(
single_indent_nested_newlines)):
do_the_thing()
This was the only real difference style-wise between the Python code and
C code, so now both should be following roughly the same style (80 cols,
double-indent multiline exprs, prefix multiline binary ops, etc).
This commit is contained in:
+10
-10
@@ -108,8 +108,7 @@ def main(csv_paths, output, *,
|
|||||||
# if by not specified, guess it's anything not in
|
# if by not specified, guess it's anything not in
|
||||||
# iter/size/fields/renames/defines
|
# iter/size/fields/renames/defines
|
||||||
if by is None:
|
if by is None:
|
||||||
by = [
|
by = [k for k in fields_
|
||||||
k for k in fields_
|
|
||||||
if k != iter
|
if k != iter
|
||||||
and k != size
|
and k != size
|
||||||
and k not in (fields or [])
|
and k not in (fields or [])
|
||||||
@@ -119,8 +118,7 @@ def main(csv_paths, output, *,
|
|||||||
# if fields not specified, guess it's anything not in
|
# if fields not specified, guess it's anything not in
|
||||||
# by/iter/size/renames/defines
|
# by/iter/size/renames/defines
|
||||||
if fields is None:
|
if fields is None:
|
||||||
fields = [
|
fields = [k for k in fields_
|
||||||
k for k in fields_
|
|
||||||
if k not in (by or [])
|
if k not in (by or [])
|
||||||
and k != iter
|
and k != iter
|
||||||
and k != size
|
and k != size
|
||||||
@@ -214,11 +212,12 @@ if __name__ == "__main__":
|
|||||||
tuple(v.strip() for v in vs.split(','))
|
tuple(v.strip() for v in vs.split(','))
|
||||||
if vs is not None else ())
|
if vs is not None else ())
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
help="Group by this field. Can rename fields with new_name=old_name.")
|
help="Group by this field. Can rename fields with "
|
||||||
|
"new_name=old_name.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-m', '--meas',
|
'-m', '--meas',
|
||||||
help="Optional name of measurement name field. If provided, the name "
|
help="Optional name of measurement name field. If provided, the "
|
||||||
"will be modified with +amor or +per.")
|
"name will be modified with +amor or +per.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-i', '--iter',
|
'-i', '--iter',
|
||||||
required=True,
|
required=True,
|
||||||
@@ -236,7 +235,8 @@ if __name__ == "__main__":
|
|||||||
tuple(v.strip() for v in vs.split(','))
|
tuple(v.strip() for v in vs.split(','))
|
||||||
if vs is not None else ())
|
if vs is not None else ())
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
help="Field to amortize. Can rename fields with new_name=old_name.")
|
help="Field to amortize. Can rename fields with "
|
||||||
|
"new_name=old_name.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-D', '--define',
|
'-D', '--define',
|
||||||
dest='defines',
|
dest='defines',
|
||||||
@@ -246,8 +246,8 @@ if __name__ == "__main__":
|
|||||||
k.strip(),
|
k.strip(),
|
||||||
{v.strip() for v in vs.split(',')})
|
{v.strip() for v in vs.split(',')})
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
help="Only include results where this field is this value. May include "
|
help="Only include results where this field is this value. May "
|
||||||
"comma-separated options.")
|
"include comma-separated options.")
|
||||||
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}))
|
||||||
|
|||||||
+11
-12
@@ -128,8 +128,7 @@ def main(csv_paths, output, *,
|
|||||||
# if by not specified, guess it's anything not in
|
# if by not specified, guess it's anything not in
|
||||||
# seeds/fields/renames/defines
|
# seeds/fields/renames/defines
|
||||||
if by is None:
|
if by is None:
|
||||||
by = [
|
by = [k for k in fields_
|
||||||
k for k in fields_
|
|
||||||
if k not in (seeds or [])
|
if k not in (seeds or [])
|
||||||
and k not in (fields or [])
|
and k not in (fields or [])
|
||||||
and not any(k == old_k for _, old_k in renames)
|
and not any(k == old_k for _, old_k in renames)
|
||||||
@@ -138,8 +137,7 @@ def main(csv_paths, output, *,
|
|||||||
# if fields not specified, guess it's anything not in
|
# if fields not specified, guess it's anything not in
|
||||||
# by/seeds/renames/defines
|
# by/seeds/renames/defines
|
||||||
if fields is None:
|
if fields is None:
|
||||||
fields = [
|
fields = [k for k in fields_
|
||||||
k for k in fields_
|
|
||||||
if k not in (by or [])
|
if k not in (by or [])
|
||||||
and k not in (seeds or [])
|
and k not in (seeds or [])
|
||||||
and not any(k == old_k for _, old_k in renames)
|
and not any(k == old_k for _, old_k in renames)
|
||||||
@@ -174,8 +172,7 @@ def main(csv_paths, output, *,
|
|||||||
meas__ = r[meas]
|
meas__ = r[meas]
|
||||||
|
|
||||||
def append(meas_, f_):
|
def append(meas_, f_):
|
||||||
avgs.append(
|
avgs.append({k: v for k, v in zip(by, key)}
|
||||||
{k: v for k, v in zip(by, key)}
|
|
||||||
| {f: f_(vs_) for f, vs_ in vs.items()}
|
| {f: f_(vs_) for f, vs_ in vs.items()}
|
||||||
| ({} if meas is None
|
| ({} if meas is None
|
||||||
else {meas: meas_} if meas__ is None
|
else {meas: meas_} if meas__ is None
|
||||||
@@ -267,11 +264,12 @@ if __name__ == "__main__":
|
|||||||
tuple(v.strip() for v in vs.split(','))
|
tuple(v.strip() for v in vs.split(','))
|
||||||
if vs is not None else ())
|
if vs is not None else ())
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
help="Group by this field. Can rename fields with new_name=old_name.")
|
help="Group by this field. Can rename fields with "
|
||||||
|
"new_name=old_name.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-m', '--meas',
|
'-m', '--meas',
|
||||||
help="Optional name of measurement name field. If provided, the name "
|
help="Optional name of measurement name field. If provided, the "
|
||||||
"will be modified with +amor or +per.")
|
"name will be modified with +amor or +per.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-s', '--seed',
|
'-s', '--seed',
|
||||||
dest='seeds',
|
dest='seeds',
|
||||||
@@ -294,7 +292,8 @@ if __name__ == "__main__":
|
|||||||
tuple(v.strip() for v in vs.split(','))
|
tuple(v.strip() for v in vs.split(','))
|
||||||
if vs is not None else ())
|
if vs is not None else ())
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
help="Field to amortize. Can rename fields with new_name=old_name.")
|
help="Field to amortize. Can rename fields with "
|
||||||
|
"new_name=old_name.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-D', '--define',
|
'-D', '--define',
|
||||||
dest='defines',
|
dest='defines',
|
||||||
@@ -304,8 +303,8 @@ if __name__ == "__main__":
|
|||||||
k.strip(),
|
k.strip(),
|
||||||
{v.strip() for v in vs.split(',')})
|
{v.strip() for v in vs.split(',')})
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
help="Only include results where this field is this value. May include "
|
help="Only include results where this field is this value. May "
|
||||||
"comma-separated options.")
|
"include comma-separated options.")
|
||||||
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}))
|
||||||
|
|||||||
+81
-74
@@ -192,7 +192,8 @@ class BenchSuite:
|
|||||||
case_linenos, case_linenos[1:],
|
case_linenos, case_linenos[1:],
|
||||||
fillvalue=(float('inf'), None)):
|
fillvalue=(float('inf'), None)):
|
||||||
code_lineno = min(
|
code_lineno = min(
|
||||||
(l for l in code_linenos if l >= lineno and l < nlineno),
|
(l for l in code_linenos
|
||||||
|
if l >= lineno and l < nlineno),
|
||||||
default=None)
|
default=None)
|
||||||
cases[name]['lineno'] = lineno
|
cases[name]['lineno'] = lineno
|
||||||
cases[name]['code_lineno'] = code_lineno
|
cases[name]['code_lineno'] = code_lineno
|
||||||
@@ -221,7 +222,8 @@ class BenchSuite:
|
|||||||
|
|
||||||
self.cases = []
|
self.cases = []
|
||||||
for name, case in cases.items():
|
for name, case in cases.items():
|
||||||
self.cases.append(BenchCase(config={
|
self.cases.append(BenchCase(
|
||||||
|
config={
|
||||||
'name': name,
|
'name': name,
|
||||||
'path': path + (':%d' % case['lineno']
|
'path': path + (':%d' % case['lineno']
|
||||||
if 'lineno' in case else ''),
|
if 'lineno' in case else ''),
|
||||||
@@ -374,23 +376,21 @@ def compile(bench_paths, **args):
|
|||||||
for k, vs in sorted(permutation.items()):
|
for k, vs in sorted(permutation.items()):
|
||||||
f.writeln('intmax_t __bench__%s__%s__%d('
|
f.writeln('intmax_t __bench__%s__%s__%d('
|
||||||
'__attribute__((unused)) void *data, '
|
'__attribute__((unused)) void *data, '
|
||||||
'size_t i) {'
|
'size_t i) {' % (
|
||||||
% (case.name, k, i))
|
case.name, k, i))
|
||||||
j = 0
|
j = 0
|
||||||
for v in vs:
|
for v in vs:
|
||||||
# generate range
|
# generate range
|
||||||
if isinstance(v, range):
|
if isinstance(v, range):
|
||||||
f.writeln(
|
f.writeln(4*' '+'if (i < %d) '
|
||||||
4*' '+'if (i < %d) '
|
'return (i-%d)*%d + %d;' % (
|
||||||
'return (i-%d)*%d + %d;'
|
j+len(v), j, v.step, v.start))
|
||||||
% (j+len(v), j, v.step, v.start))
|
|
||||||
j += len(v)
|
j += len(v)
|
||||||
# translate index to define
|
# translate index to define
|
||||||
else:
|
else:
|
||||||
f.writeln(
|
f.writeln(4*' '+'if (i == %d) '
|
||||||
4*' '+'if (i == %d) '
|
'return %s;' % (
|
||||||
'return %s;'
|
j, v))
|
||||||
% (j, v))
|
|
||||||
j += 1;
|
j += 1;
|
||||||
|
|
||||||
f.writeln(4*' '+'__builtin_unreachable();')
|
f.writeln(4*' '+'__builtin_unreachable();')
|
||||||
@@ -399,8 +399,8 @@ def compile(bench_paths, **args):
|
|||||||
|
|
||||||
# create case if function
|
# create case if function
|
||||||
if suite.if_ or case.if_:
|
if suite.if_ or case.if_:
|
||||||
f.writeln('bool __bench__%s__if(void) {'
|
f.writeln('bool __bench__%s__if(void) {' % (
|
||||||
% (case.name))
|
case.name))
|
||||||
for if_ in it.chain(suite.if_, case.if_):
|
for if_ in it.chain(suite.if_, case.if_):
|
||||||
f.writeln(4*' '+'if (!(%s)) return false;' % (
|
f.writeln(4*' '+'if (!(%s)) return false;' % (
|
||||||
'true' if if_ is True
|
'true' if if_ is True
|
||||||
@@ -412,16 +412,17 @@ def compile(bench_paths, **args):
|
|||||||
|
|
||||||
# create case run function
|
# create case run function
|
||||||
f.writeln('void __bench__%s__run('
|
f.writeln('void __bench__%s__run('
|
||||||
'__attribute__((unused)) struct lfs_config *CFG) {'
|
'__attribute__((unused)) '
|
||||||
% (case.name))
|
'struct lfs_config *CFG) {' % (
|
||||||
|
case.name))
|
||||||
f.writeln(4*' '+'// bench case %s' % case.name)
|
f.writeln(4*' '+'// bench case %s' % case.name)
|
||||||
if case.code_lineno is not None:
|
if case.code_lineno is not None:
|
||||||
f.writeln(4*' '+'#line %d "%s"'
|
f.writeln(4*' '+'#line %d "%s"' % (
|
||||||
% (case.code_lineno, suite.path))
|
case.code_lineno, suite.path))
|
||||||
f.write(case.code)
|
f.write(case.code)
|
||||||
if case.code_lineno is not None:
|
if case.code_lineno is not None:
|
||||||
f.writeln(4*' '+'#line %d "%s"'
|
f.writeln(4*' '+'#line %d "%s"' % (
|
||||||
% (f.lineno+1, args['output']))
|
f.lineno+1, args['output']))
|
||||||
f.writeln('}')
|
f.writeln('}')
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
@@ -441,19 +442,19 @@ def compile(bench_paths, **args):
|
|||||||
# write any suite defines
|
# write any suite defines
|
||||||
if suite.defines:
|
if suite.defines:
|
||||||
for define in sorted(suite.defines):
|
for define in sorted(suite.defines):
|
||||||
f.writeln('__attribute__((weak)) intmax_t %s;'
|
f.writeln('__attribute__((weak)) intmax_t %s;' % (
|
||||||
% define)
|
define))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
# write any suite code
|
# write any suite code
|
||||||
if suite.code is not None and suite.in_ is None:
|
if suite.code is not None and suite.in_ is None:
|
||||||
if suite.code_lineno is not None:
|
if suite.code_lineno is not None:
|
||||||
f.writeln('#line %d "%s"'
|
f.writeln('#line %d "%s"' % (
|
||||||
% (suite.code_lineno, suite.path))
|
suite.code_lineno, suite.path))
|
||||||
f.write(suite.code)
|
f.write(suite.code)
|
||||||
if suite.code_lineno is not None:
|
if suite.code_lineno is not None:
|
||||||
f.writeln('#line %d "%s"'
|
f.writeln('#line %d "%s"' % (
|
||||||
% (f.lineno+1, args['output']))
|
f.lineno+1, args['output']))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
# create case functions
|
# create case functions
|
||||||
@@ -464,15 +465,15 @@ def compile(bench_paths, **args):
|
|||||||
for i, permutation in enumerate(case.permutations):
|
for i, permutation in enumerate(case.permutations):
|
||||||
for k, vs in sorted(permutation.items()):
|
for k, vs in sorted(permutation.items()):
|
||||||
f.writeln('extern intmax_t __bench__%s__%s__%d('
|
f.writeln('extern intmax_t __bench__%s__%s__%d('
|
||||||
'void *data, size_t i);'
|
'void *data, size_t i);' % (
|
||||||
% (case.name, k, i))
|
case.name, k, i))
|
||||||
if suite.if_ or case.if_:
|
if suite.if_ or case.if_:
|
||||||
f.writeln('extern bool __bench__%s__if('
|
f.writeln('extern bool __bench__%s__if('
|
||||||
'void);'
|
'void);' % (
|
||||||
% (case.name))
|
case.name))
|
||||||
f.writeln('extern void __bench__%s__run('
|
f.writeln('extern void __bench__%s__run('
|
||||||
'struct lfs_config *CFG);'
|
'struct lfs_config *CFG);' % (
|
||||||
% (case.name))
|
case.name))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
# write any ifdef epilogues
|
# write any ifdef epilogues
|
||||||
@@ -482,12 +483,12 @@ def compile(bench_paths, **args):
|
|||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
# create suite struct
|
# create suite struct
|
||||||
f.writeln('const struct bench_suite __bench__%s__suite = {'
|
f.writeln('const struct bench_suite __bench__%s__suite = {' % (
|
||||||
% suite.name)
|
suite.name))
|
||||||
f.writeln(4*' '+'.name = "%s",' % suite.name)
|
f.writeln(4*' '+'.name = "%s",' % suite.name)
|
||||||
f.writeln(4*' '+'.path = "%s",' % suite.path)
|
f.writeln(4*' '+'.path = "%s",' % suite.path)
|
||||||
f.writeln(4*' '+'.flags = %s,'
|
f.writeln(4*' '+'.flags = %s,' % (
|
||||||
% (' | '.join(filter(None, [
|
' | '.join(filter(None, [
|
||||||
'BENCH_INTERNAL' if suite.internal else None]))
|
'BENCH_INTERNAL' if suite.internal else None]))
|
||||||
or 0))
|
or 0))
|
||||||
for ifdef in suite.ifdef:
|
for ifdef in suite.ifdef:
|
||||||
@@ -496,8 +497,8 @@ def compile(bench_paths, **args):
|
|||||||
if suite.defines:
|
if suite.defines:
|
||||||
f.writeln(4*' '+'.defines = (const bench_define_t[]){')
|
f.writeln(4*' '+'.defines = (const bench_define_t[]){')
|
||||||
for k in sorted(suite.defines):
|
for k in sorted(suite.defines):
|
||||||
f.writeln(8*' '+'{"%s", &%s, NULL, NULL, 0},'
|
f.writeln(8*' '+'{"%s", &%s, NULL, NULL, 0},' % (
|
||||||
% (k, k))
|
k, k))
|
||||||
f.writeln(4*' '+'},')
|
f.writeln(4*' '+'},')
|
||||||
f.writeln(4*' '+'.define_count = %d,' % len(suite.defines))
|
f.writeln(4*' '+'.define_count = %d,' % len(suite.defines))
|
||||||
for ifdef in suite.ifdef:
|
for ifdef in suite.ifdef:
|
||||||
@@ -509,9 +510,10 @@ def compile(bench_paths, **args):
|
|||||||
f.writeln(8*' '+'{')
|
f.writeln(8*' '+'{')
|
||||||
f.writeln(12*' '+'.name = "%s",' % case.name)
|
f.writeln(12*' '+'.name = "%s",' % case.name)
|
||||||
f.writeln(12*' '+'.path = "%s",' % case.path)
|
f.writeln(12*' '+'.path = "%s",' % case.path)
|
||||||
f.writeln(12*' '+'.flags = %s,'
|
f.writeln(12*' '+'.flags = %s,' % (
|
||||||
% (' | '.join(filter(None, [
|
' | '.join(filter(None, [
|
||||||
'BENCH_INTERNAL' if suite.internal else None]))
|
'BENCH_INTERNAL' if suite.internal
|
||||||
|
else None]))
|
||||||
or 0))
|
or 0))
|
||||||
for ifdef in it.chain(suite.ifdef, case.ifdef):
|
for ifdef in it.chain(suite.ifdef, case.ifdef):
|
||||||
f.writeln(12*' '+'#ifdef %s' % ifdef)
|
f.writeln(12*' '+'#ifdef %s' % ifdef)
|
||||||
@@ -519,15 +521,16 @@ def compile(bench_paths, **args):
|
|||||||
if case.defines:
|
if case.defines:
|
||||||
f.writeln(12*' '+'.defines'
|
f.writeln(12*' '+'.defines'
|
||||||
' = (const bench_define_t*)'
|
' = (const bench_define_t*)'
|
||||||
'(const bench_define_t[][%d]){'
|
'(const bench_define_t[][%d]){' % (
|
||||||
% (len(suite.defines)))
|
len(suite.defines)))
|
||||||
for i, permutation in enumerate(case.permutations):
|
for i, permutation in enumerate(case.permutations):
|
||||||
f.writeln(16*' '+'{')
|
f.writeln(16*' '+'{')
|
||||||
for k, vs in sorted(permutation.items()):
|
for k, vs in sorted(permutation.items()):
|
||||||
f.writeln(20*' '+'[%d] = {'
|
f.writeln(20*' '+'[%d] = {'
|
||||||
'"%s", &%s, '
|
'"%s", &%s, '
|
||||||
'__bench__%s__%s__%d, NULL, %d},'
|
'__bench__%s__%s__%d, '
|
||||||
% (sorted(suite.defines).index(k),
|
'NULL, %d},' % (
|
||||||
|
sorted(suite.defines).index(k),
|
||||||
k, k, case.name, k, i,
|
k, k, case.name, k, i,
|
||||||
sum(len(v)
|
sum(len(v)
|
||||||
if isinstance(v, range)
|
if isinstance(v, range)
|
||||||
@@ -535,13 +538,13 @@ def compile(bench_paths, **args):
|
|||||||
for v in vs)))
|
for v in vs)))
|
||||||
f.writeln(16*' '+'},')
|
f.writeln(16*' '+'},')
|
||||||
f.writeln(12*' '+'},')
|
f.writeln(12*' '+'},')
|
||||||
f.writeln(12*' '+'.permutations = %d,'
|
f.writeln(12*' '+'.permutations = %d,' % (
|
||||||
% len(case.permutations))
|
len(case.permutations)))
|
||||||
if suite.if_ or case.if_:
|
if suite.if_ or case.if_:
|
||||||
f.writeln(12*' '+'.if_ = __bench__%s__if,'
|
f.writeln(12*' '+'.if_ = __bench__%s__if,' % (
|
||||||
% (case.name))
|
case.name))
|
||||||
f.writeln(12*' '+'.run = __bench__%s__run,'
|
f.writeln(12*' '+'.run = __bench__%s__run,' % (
|
||||||
% (case.name))
|
case.name))
|
||||||
for ifdef in it.chain(suite.ifdef, case.ifdef):
|
for ifdef in it.chain(suite.ifdef, case.ifdef):
|
||||||
f.writeln(12*' '+'#endif')
|
f.writeln(12*' '+'#endif')
|
||||||
f.writeln(8*' '+'},')
|
f.writeln(8*' '+'},')
|
||||||
@@ -570,8 +573,8 @@ def compile(bench_paths, **args):
|
|||||||
for define in case.defines})
|
for define in case.defines})
|
||||||
if defines:
|
if defines:
|
||||||
for define in sorted(defines):
|
for define in sorted(defines):
|
||||||
f.writeln('__attribute__((weak)) intmax_t %s;'
|
f.writeln('__attribute__((weak)) intmax_t %s;' % (
|
||||||
% define)
|
define))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
# write any internal benches
|
# write any internal benches
|
||||||
@@ -585,12 +588,12 @@ def compile(bench_paths, **args):
|
|||||||
# any suite code
|
# any suite code
|
||||||
if suite.isin(args['source']):
|
if suite.isin(args['source']):
|
||||||
if suite.code_lineno is not None:
|
if suite.code_lineno is not None:
|
||||||
f.writeln('#line %d "%s"'
|
f.writeln('#line %d "%s"' % (
|
||||||
% (suite.code_lineno, suite.path))
|
suite.code_lineno, suite.path))
|
||||||
f.write(suite.code)
|
f.write(suite.code)
|
||||||
if suite.code_lineno is not None:
|
if suite.code_lineno is not None:
|
||||||
f.writeln('#line %d "%s"'
|
f.writeln('#line %d "%s"' % (
|
||||||
% (f.lineno+1, args['output']))
|
f.lineno+1, args['output']))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
# any case functions
|
# any case functions
|
||||||
@@ -611,11 +614,12 @@ def compile(bench_paths, **args):
|
|||||||
# will be linked
|
# will be linked
|
||||||
for suite in suites:
|
for suite in suites:
|
||||||
f.writeln('extern const struct bench_suite '
|
f.writeln('extern const struct bench_suite '
|
||||||
'__bench__%s__suite;' % suite.name)
|
'__bench__%s__suite;' % (
|
||||||
|
suite.name))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
f.writeln('__attribute__((weak))')
|
f.writeln('__attribute__((weak))')
|
||||||
f.writeln('const struct bench_suite *const bench_suites[] = {');
|
f.writeln('const struct bench_suite *const bench_suites[] = {')
|
||||||
for suite in suites:
|
for suite in suites:
|
||||||
f.writeln(4*' '+'&__bench__%s__suite,' % suite.name)
|
f.writeln(4*' '+'&__bench__%s__suite,' % suite.name)
|
||||||
if len(suites) == 0:
|
if len(suites) == 0:
|
||||||
@@ -768,8 +772,7 @@ def find_perms(runner, bench_ids=[], **args):
|
|||||||
expected_suite_perms.get(suite, 0)
|
expected_suite_perms.get(suite, 0)
|
||||||
+ expected_case_perms.get(case, 0))
|
+ expected_case_perms.get(case, 0))
|
||||||
|
|
||||||
return (
|
return (case_suites,
|
||||||
case_suites,
|
|
||||||
expected_suite_perms,
|
expected_suite_perms,
|
||||||
expected_case_perms,
|
expected_case_perms,
|
||||||
expected_perms,
|
expected_perms,
|
||||||
@@ -1246,8 +1249,7 @@ def run_stage(name, runner, bench_ids, stdout_, trace_, output_, **args):
|
|||||||
for r in runners:
|
for r in runners:
|
||||||
r.join()
|
r.join()
|
||||||
|
|
||||||
return (
|
return (expected_perms,
|
||||||
expected_perms,
|
|
||||||
passed_perms,
|
passed_perms,
|
||||||
failed_perms,
|
failed_perms,
|
||||||
readed,
|
readed,
|
||||||
@@ -1381,7 +1383,8 @@ def run(runner, bench_ids=[], **args):
|
|||||||
'\x1b[01;31m' if args['color'] else '',
|
'\x1b[01;31m' if args['color'] else '',
|
||||||
'\x1b[m' if args['color'] else '',
|
'\x1b[m' if args['color'] else '',
|
||||||
failure.id,
|
failure.id,
|
||||||
' (%s)' % ', '.join('%s=%s' % (k,v) for k,v in defines.items())
|
' (%s)' % ', '.join('%s=%s' % (k,v)
|
||||||
|
for k,v in defines.items())
|
||||||
if defines else ''))
|
if defines else ''))
|
||||||
|
|
||||||
if failure.stdout:
|
if failure.stdout:
|
||||||
@@ -1495,7 +1498,8 @@ if __name__ == "__main__":
|
|||||||
'-R', '--runner',
|
'-R', '--runner',
|
||||||
type=lambda x: x.split(),
|
type=lambda x: x.split(),
|
||||||
default=RUNNER_PATH,
|
default=RUNNER_PATH,
|
||||||
help="Bench runner to use for benching. Defaults to %r." % RUNNER_PATH)
|
help="Bench runner to use for benching. Defaults to "
|
||||||
|
"%r." % RUNNER_PATH)
|
||||||
bench_parser.add_argument(
|
bench_parser.add_argument(
|
||||||
'-Y', '--summary',
|
'-Y', '--summary',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -1557,7 +1561,8 @@ if __name__ == "__main__":
|
|||||||
help="Sample trace output at this frequency in hz.")
|
help="Sample trace output at this frequency in hz.")
|
||||||
bench_parser.add_argument(
|
bench_parser.add_argument(
|
||||||
'-O', '--stdout',
|
'-O', '--stdout',
|
||||||
help="Direct stdout to this file. Note stderr is already merged here.")
|
help="Direct stdout to this file. Note stderr is already merged "
|
||||||
|
"here.")
|
||||||
bench_parser.add_argument(
|
bench_parser.add_argument(
|
||||||
'-o', '--output',
|
'-o', '--output',
|
||||||
help="CSV file to store results.")
|
help="CSV file to store results.")
|
||||||
@@ -1575,7 +1580,8 @@ if __name__ == "__main__":
|
|||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
const=0,
|
const=0,
|
||||||
help="Number of parallel runners to run. 0 runs one runner per core.")
|
help="Number of parallel runners to run. 0 runs one runner per "
|
||||||
|
"core.")
|
||||||
bench_parser.add_argument(
|
bench_parser.add_argument(
|
||||||
'-k', '--keep-going',
|
'-k', '--keep-going',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -1644,12 +1650,12 @@ if __name__ == "__main__":
|
|||||||
"Defaults to %r." % VALGRIND_PATH)
|
"Defaults to %r." % VALGRIND_PATH)
|
||||||
bench_parser.add_argument(
|
bench_parser.add_argument(
|
||||||
'-p', '--perf',
|
'-p', '--perf',
|
||||||
help="Run under Linux's perf to sample performance counters, writing "
|
help="Run under Linux's perf to sample performance counters, "
|
||||||
"samples to this file.")
|
"writing samples to this file.")
|
||||||
bench_parser.add_argument(
|
bench_parser.add_argument(
|
||||||
'--perf-freq',
|
'--perf-freq',
|
||||||
help="perf sampling frequency. This is passed directly to the perf "
|
help="perf sampling frequency. This is passed directly to the "
|
||||||
"script.")
|
"perf script.")
|
||||||
bench_parser.add_argument(
|
bench_parser.add_argument(
|
||||||
'--perf-period',
|
'--perf-period',
|
||||||
help="perf sampling period. This is passed directly to the perf "
|
help="perf sampling period. This is passed directly to the perf "
|
||||||
@@ -1662,12 +1668,13 @@ if __name__ == "__main__":
|
|||||||
'--perf-script',
|
'--perf-script',
|
||||||
type=lambda x: x.split(),
|
type=lambda x: x.split(),
|
||||||
default=PERF_SCRIPT,
|
default=PERF_SCRIPT,
|
||||||
help="Path to the perf script to use. Defaults to %r." % PERF_SCRIPT)
|
help="Path to the perf script to use. Defaults to "
|
||||||
|
"%r." % PERF_SCRIPT)
|
||||||
bench_parser.add_argument(
|
bench_parser.add_argument(
|
||||||
'--perf-path',
|
'--perf-path',
|
||||||
type=lambda x: x.split(),
|
type=lambda x: x.split(),
|
||||||
help="Path to the perf executable, may include flags. This is passed "
|
help="Path to the perf executable, may include flags. This is "
|
||||||
"directly to the perf script")
|
"passed directly to the perf script")
|
||||||
|
|
||||||
# compilation flags
|
# compilation flags
|
||||||
comp_parser = parser.add_argument_group('compilation options')
|
comp_parser = parser.add_argument_group('compilation options')
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import shutil
|
|||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
|
||||||
GIT_PATH = ['git']
|
GIT_PATH = ['git']
|
||||||
|
|
||||||
|
|
||||||
@@ -79,7 +80,8 @@ def changefile(from_prefix, to_prefix, from_path, to_path, *,
|
|||||||
|
|
||||||
# Summary
|
# Summary
|
||||||
print('%s: %d replacements' % (
|
print('%s: %d replacements' % (
|
||||||
'%s -> %s' % (from_path, to_path) if not to_path_temp else from_path,
|
'%s -> %s' % (from_path, to_path) if not to_path_temp
|
||||||
|
else from_path,
|
||||||
count))
|
count))
|
||||||
|
|
||||||
def main(from_prefix, to_prefix, paths=[], *,
|
def main(from_prefix, to_prefix, paths=[], *,
|
||||||
@@ -130,9 +132,9 @@ if __name__ == "__main__":
|
|||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Change prefixes in files/filenames. Useful for creating "
|
description="Change prefixes in files/filenames. Useful for "
|
||||||
"different versions of a codebase that don't conflict at compile "
|
"creating different versions of a codebase that don't "
|
||||||
"time.",
|
"conflict at compile time.",
|
||||||
allow_abbrev=False)
|
allow_abbrev=False)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'from_prefix',
|
'from_prefix',
|
||||||
|
|||||||
+22
-17
@@ -140,9 +140,9 @@ def collect(obj_paths, *,
|
|||||||
everything=False,
|
everything=False,
|
||||||
**args):
|
**args):
|
||||||
size_pattern = re.compile(
|
size_pattern = re.compile(
|
||||||
'^(?P<size>[0-9a-fA-F]+)' +
|
'^(?P<size>[0-9a-fA-F]+)'
|
||||||
' (?P<type>[%s])' % re.escape(nm_types) +
|
+ ' (?P<type>[%s])' % re.escape(nm_types)
|
||||||
' (?P<func>.+?)$')
|
+ ' (?P<func>.+?)$')
|
||||||
line_pattern = re.compile(
|
line_pattern = re.compile(
|
||||||
'^\s+(?P<no>[0-9]+)'
|
'^\s+(?P<no>[0-9]+)'
|
||||||
'(?:\s+(?P<dir>[0-9]+))?'
|
'(?:\s+(?P<dir>[0-9]+))?'
|
||||||
@@ -288,8 +288,7 @@ def collect(obj_paths, *,
|
|||||||
|
|
||||||
# ignore filtered sources
|
# ignore filtered sources
|
||||||
if sources is not None:
|
if sources is not None:
|
||||||
if not any(
|
if not any(os.path.abspath(file) == os.path.abspath(s)
|
||||||
os.path.abspath(file) == os.path.abspath(s)
|
|
||||||
for s in sources):
|
for s in sources):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@@ -386,7 +385,8 @@ def table(Result, results, diff_results=None, *,
|
|||||||
# sort again, now with diff info, note that python's sort is stable
|
# sort again, now with diff info, note that python's sort is stable
|
||||||
names.sort()
|
names.sort()
|
||||||
if diff_results is not None:
|
if diff_results is not None:
|
||||||
names.sort(key=lambda n: tuple(
|
names.sort(
|
||||||
|
key=lambda n: tuple(
|
||||||
types[k].ratio(
|
types[k].ratio(
|
||||||
getattr(table.get(n), k, None),
|
getattr(table.get(n), k, None),
|
||||||
getattr(diff_table.get(n), k, None))
|
getattr(diff_table.get(n), k, None))
|
||||||
@@ -397,9 +397,12 @@ def table(Result, results, diff_results=None, *,
|
|||||||
names.sort(
|
names.sort(
|
||||||
key=lambda n: tuple(
|
key=lambda n: tuple(
|
||||||
(getattr(table[n], k),)
|
(getattr(table[n], k),)
|
||||||
if getattr(table.get(n), k, None) is not None else ()
|
if getattr(table.get(n), k, None) is not None
|
||||||
for k in ([k] if k else [
|
else ()
|
||||||
k for k in Result._sort if k in fields])),
|
for k in (
|
||||||
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])),
|
||||||
reverse=reverse ^ (not k or k in Result._fields))
|
reverse=reverse ^ (not k or k in Result._fields))
|
||||||
|
|
||||||
|
|
||||||
@@ -407,8 +410,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
# header
|
# header
|
||||||
header = [
|
header = ['%s%s' % (
|
||||||
'%s%s' % (
|
|
||||||
','.join(by),
|
','.join(by),
|
||||||
' (%d added, %d removed)' % (
|
' (%d added, %d removed)' % (
|
||||||
sum(1 for n in table if n not in diff_table),
|
sum(1 for n in table if n not in diff_table),
|
||||||
@@ -566,14 +568,16 @@ def main(obj_paths, *,
|
|||||||
writer = csv.DictWriter(f,
|
writer = csv.DictWriter(f,
|
||||||
(by if by is not None else CodeResult._by)
|
(by if by is not None else CodeResult._by)
|
||||||
+ [k for k in (
|
+ [k for k in (
|
||||||
fields if fields is not None else CodeResult._fields)])
|
fields if fields is not None
|
||||||
|
else CodeResult._fields)])
|
||||||
writer.writeheader()
|
writer.writeheader()
|
||||||
for r in results:
|
for r in results:
|
||||||
writer.writerow(
|
writer.writerow(
|
||||||
{k: getattr(r, k) for k in (
|
{k: getattr(r, k) for k in (
|
||||||
by if by is not None else CodeResult._by)}
|
by if by is not None else CodeResult._by)}
|
||||||
| {k: getattr(r, k) for k in (
|
| {k: getattr(r, k) for k in (
|
||||||
fields if fields is not None else CodeResult._fields)})
|
fields if fields is not None
|
||||||
|
else CodeResult._fields)})
|
||||||
|
|
||||||
# find previous results?
|
# find previous results?
|
||||||
if args.get('diff'):
|
if args.get('diff'):
|
||||||
@@ -692,8 +696,8 @@ if __name__ == "__main__":
|
|||||||
'-F', '--source',
|
'-F', '--source',
|
||||||
dest='sources',
|
dest='sources',
|
||||||
action='append',
|
action='append',
|
||||||
help="Only consider definitions in this file. Defaults to anything "
|
help="Only consider definitions in this file. Defaults to "
|
||||||
"in the current directory.")
|
"anything in the current directory.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--everything',
|
'--everything',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -701,8 +705,9 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--nm-types',
|
'--nm-types',
|
||||||
default=NM_TYPES,
|
default=NM_TYPES,
|
||||||
help="Type of symbols to report, this uses the same single-character "
|
help="Type of symbols to report, this uses the same "
|
||||||
"type-names emitted by nm. Defaults to %r." % NM_TYPES)
|
"single-character type-names emitted by nm. Defaults to "
|
||||||
|
"%r." % NM_TYPES)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--nm-path',
|
'--nm-path',
|
||||||
type=lambda x: x.split(),
|
type=lambda x: x.split(),
|
||||||
|
|||||||
+21
-17
@@ -22,6 +22,7 @@ import re
|
|||||||
import shlex
|
import shlex
|
||||||
import subprocess as sp
|
import subprocess as sp
|
||||||
|
|
||||||
|
|
||||||
# TODO use explode_asserts to avoid counting assert branches?
|
# TODO use explode_asserts to avoid counting assert branches?
|
||||||
# TODO use dwarf=info to find functions for inline functions?
|
# TODO use dwarf=info to find functions for inline functions?
|
||||||
|
|
||||||
@@ -243,8 +244,7 @@ def collect(gcda_paths, *,
|
|||||||
for file in data['files']:
|
for file in data['files']:
|
||||||
# ignore filtered sources
|
# ignore filtered sources
|
||||||
if sources is not None:
|
if sources is not None:
|
||||||
if not any(
|
if not any(os.path.abspath(file['file']) == os.path.abspath(s)
|
||||||
os.path.abspath(file['file']) == os.path.abspath(s)
|
|
||||||
for s in sources):
|
for s in sources):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@@ -374,7 +374,8 @@ def table(Result, results, diff_results=None, *,
|
|||||||
# sort again, now with diff info, note that python's sort is stable
|
# sort again, now with diff info, note that python's sort is stable
|
||||||
names.sort()
|
names.sort()
|
||||||
if diff_results is not None:
|
if diff_results is not None:
|
||||||
names.sort(key=lambda n: tuple(
|
names.sort(
|
||||||
|
key=lambda n: tuple(
|
||||||
types[k].ratio(
|
types[k].ratio(
|
||||||
getattr(table.get(n), k, None),
|
getattr(table.get(n), k, None),
|
||||||
getattr(diff_table.get(n), k, None))
|
getattr(diff_table.get(n), k, None))
|
||||||
@@ -385,9 +386,12 @@ def table(Result, results, diff_results=None, *,
|
|||||||
names.sort(
|
names.sort(
|
||||||
key=lambda n: tuple(
|
key=lambda n: tuple(
|
||||||
(getattr(table[n], k),)
|
(getattr(table[n], k),)
|
||||||
if getattr(table.get(n), k, None) is not None else ()
|
if getattr(table.get(n), k, None) is not None
|
||||||
for k in ([k] if k else [
|
else ()
|
||||||
k for k in Result._sort if k in fields])),
|
for k in (
|
||||||
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])),
|
||||||
reverse=reverse ^ (not k or k in Result._fields))
|
reverse=reverse ^ (not k or k in Result._fields))
|
||||||
|
|
||||||
|
|
||||||
@@ -395,8 +399,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
# header
|
# header
|
||||||
header = [
|
header = ['%s%s' % (
|
||||||
'%s%s' % (
|
|
||||||
','.join(by),
|
','.join(by),
|
||||||
' (%d added, %d removed)' % (
|
' (%d added, %d removed)' % (
|
||||||
sum(1 for n in table if n not in diff_table),
|
sum(1 for n in table if n not in diff_table),
|
||||||
@@ -639,14 +642,16 @@ def main(gcda_paths, *,
|
|||||||
writer = csv.DictWriter(f,
|
writer = csv.DictWriter(f,
|
||||||
(by if by is not None else CovResult._by)
|
(by if by is not None else CovResult._by)
|
||||||
+ [k for k in (
|
+ [k for k in (
|
||||||
fields if fields is not None else CovResult._fields)])
|
fields if fields is not None
|
||||||
|
else CovResult._fields)])
|
||||||
writer.writeheader()
|
writer.writeheader()
|
||||||
for r in results:
|
for r in results:
|
||||||
writer.writerow(
|
writer.writerow(
|
||||||
{k: getattr(r, k) for k in (
|
{k: getattr(r, k) for k in (
|
||||||
by if by is not None else CovResult._by)}
|
by if by is not None else CovResult._by)}
|
||||||
| {k: getattr(r, k) for k in (
|
| {k: getattr(r, k) for k in (
|
||||||
fields if fields is not None else CovResult._fields)})
|
fields if fields is not None
|
||||||
|
else CovResult._fields)})
|
||||||
|
|
||||||
# find previous results?
|
# find previous results?
|
||||||
if args.get('diff'):
|
if args.get('diff'):
|
||||||
@@ -666,8 +671,7 @@ def main(gcda_paths, *,
|
|||||||
diff_results.append(CovResult(
|
diff_results.append(CovResult(
|
||||||
**{k: r[k] for k in CovResult._by
|
**{k: r[k] for k in CovResult._by
|
||||||
if k in r and r[k].strip()},
|
if k in r and r[k].strip()},
|
||||||
**{k: r[k]
|
**{k: r[k] for k in CovResult._fields
|
||||||
for k in CovResult._fields
|
|
||||||
if k in r and r[k].strip()}))
|
if k in r and r[k].strip()}))
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
@@ -675,8 +679,7 @@ def main(gcda_paths, *,
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
# fold
|
# fold
|
||||||
diff_results = fold(CovResult, diff_results,
|
diff_results = fold(CovResult, diff_results, by=by, defines=defines)
|
||||||
by=by, defines=defines)
|
|
||||||
|
|
||||||
# print table
|
# print table
|
||||||
if not args.get('quiet'):
|
if not args.get('quiet'):
|
||||||
@@ -784,8 +787,8 @@ if __name__ == "__main__":
|
|||||||
'-F', '--source',
|
'-F', '--source',
|
||||||
dest='sources',
|
dest='sources',
|
||||||
action='append',
|
action='append',
|
||||||
help="Only consider definitions in this file. Defaults to anything "
|
help="Only consider definitions in this file. Defaults to "
|
||||||
"in the current directory.")
|
"anything in the current directory.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--everything',
|
'--everything',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -815,7 +818,8 @@ if __name__ == "__main__":
|
|||||||
'-W', '--width',
|
'-W', '--width',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
default=80,
|
default=80,
|
||||||
help="Assume source is styled with this many columns. Defaults to 80.")
|
help="Assume source is styled with this many columns. Defaults "
|
||||||
|
"to 80.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--color',
|
'--color',
|
||||||
choices=['never', 'always', 'auto'],
|
choices=['never', 'always', 'auto'],
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ def main(paths, **args):
|
|||||||
else:
|
else:
|
||||||
print('%08x' % crc)
|
print('%08x' % crc)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
+22
-17
@@ -140,9 +140,9 @@ def collect(obj_paths, *,
|
|||||||
everything=False,
|
everything=False,
|
||||||
**args):
|
**args):
|
||||||
size_pattern = re.compile(
|
size_pattern = re.compile(
|
||||||
'^(?P<size>[0-9a-fA-F]+)' +
|
'^(?P<size>[0-9a-fA-F]+)'
|
||||||
' (?P<type>[%s])' % re.escape(nm_types) +
|
+ ' (?P<type>[%s])' % re.escape(nm_types)
|
||||||
' (?P<func>.+?)$')
|
+ ' (?P<func>.+?)$')
|
||||||
line_pattern = re.compile(
|
line_pattern = re.compile(
|
||||||
'^\s+(?P<no>[0-9]+)'
|
'^\s+(?P<no>[0-9]+)'
|
||||||
'(?:\s+(?P<dir>[0-9]+))?'
|
'(?:\s+(?P<dir>[0-9]+))?'
|
||||||
@@ -288,8 +288,7 @@ def collect(obj_paths, *,
|
|||||||
|
|
||||||
# ignore filtered sources
|
# ignore filtered sources
|
||||||
if sources is not None:
|
if sources is not None:
|
||||||
if not any(
|
if not any(os.path.abspath(file) == os.path.abspath(s)
|
||||||
os.path.abspath(file) == os.path.abspath(s)
|
|
||||||
for s in sources):
|
for s in sources):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@@ -386,7 +385,8 @@ def table(Result, results, diff_results=None, *,
|
|||||||
# sort again, now with diff info, note that python's sort is stable
|
# sort again, now with diff info, note that python's sort is stable
|
||||||
names.sort()
|
names.sort()
|
||||||
if diff_results is not None:
|
if diff_results is not None:
|
||||||
names.sort(key=lambda n: tuple(
|
names.sort(
|
||||||
|
key=lambda n: tuple(
|
||||||
types[k].ratio(
|
types[k].ratio(
|
||||||
getattr(table.get(n), k, None),
|
getattr(table.get(n), k, None),
|
||||||
getattr(diff_table.get(n), k, None))
|
getattr(diff_table.get(n), k, None))
|
||||||
@@ -397,9 +397,12 @@ def table(Result, results, diff_results=None, *,
|
|||||||
names.sort(
|
names.sort(
|
||||||
key=lambda n: tuple(
|
key=lambda n: tuple(
|
||||||
(getattr(table[n], k),)
|
(getattr(table[n], k),)
|
||||||
if getattr(table.get(n), k, None) is not None else ()
|
if getattr(table.get(n), k, None) is not None
|
||||||
for k in ([k] if k else [
|
else ()
|
||||||
k for k in Result._sort if k in fields])),
|
for k in (
|
||||||
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])),
|
||||||
reverse=reverse ^ (not k or k in Result._fields))
|
reverse=reverse ^ (not k or k in Result._fields))
|
||||||
|
|
||||||
|
|
||||||
@@ -407,8 +410,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
# header
|
# header
|
||||||
header = [
|
header = ['%s%s' % (
|
||||||
'%s%s' % (
|
|
||||||
','.join(by),
|
','.join(by),
|
||||||
' (%d added, %d removed)' % (
|
' (%d added, %d removed)' % (
|
||||||
sum(1 for n in table if n not in diff_table),
|
sum(1 for n in table if n not in diff_table),
|
||||||
@@ -563,14 +565,16 @@ def main(obj_paths, *,
|
|||||||
writer = csv.DictWriter(f,
|
writer = csv.DictWriter(f,
|
||||||
(by if by is not None else DataResult._by)
|
(by if by is not None else DataResult._by)
|
||||||
+ [k for k in (
|
+ [k for k in (
|
||||||
fields if fields is not None else DataResult._fields)])
|
fields if fields is not None
|
||||||
|
else DataResult._fields)])
|
||||||
writer.writeheader()
|
writer.writeheader()
|
||||||
for r in results:
|
for r in results:
|
||||||
writer.writerow(
|
writer.writerow(
|
||||||
{k: getattr(r, k) for k in (
|
{k: getattr(r, k) for k in (
|
||||||
by if by is not None else DataResult._by)}
|
by if by is not None else DataResult._by)}
|
||||||
| {k: getattr(r, k) for k in (
|
| {k: getattr(r, k) for k in (
|
||||||
fields if fields is not None else DataResult._fields)})
|
fields if fields is not None
|
||||||
|
else DataResult._fields)})
|
||||||
|
|
||||||
# find previous results?
|
# find previous results?
|
||||||
if args.get('diff'):
|
if args.get('diff'):
|
||||||
@@ -689,8 +693,8 @@ if __name__ == "__main__":
|
|||||||
'-F', '--source',
|
'-F', '--source',
|
||||||
dest='sources',
|
dest='sources',
|
||||||
action='append',
|
action='append',
|
||||||
help="Only consider definitions in this file. Defaults to anything "
|
help="Only consider definitions in this file. Defaults to "
|
||||||
"in the current directory.")
|
"anything in the current directory.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--everything',
|
'--everything',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -698,8 +702,9 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--nm-types',
|
'--nm-types',
|
||||||
default=NM_TYPES,
|
default=NM_TYPES,
|
||||||
help="Type of symbols to report, this uses the same single-character "
|
help="Type of symbols to report, this uses the same "
|
||||||
"type-names emitted by nm. Defaults to %r." % NM_TYPES)
|
"single-character type-names emitted by nm. Defaults to "
|
||||||
|
"%r." % NM_TYPES)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--nm-path',
|
'--nm-path',
|
||||||
type=lambda x: x.split(),
|
type=lambda x: x.split(),
|
||||||
|
|||||||
+3
-1
@@ -121,7 +121,8 @@ def main(disk, block=None, *,
|
|||||||
size[1] - size[0] if isinstance(size, tuple) and len(size) > 1
|
size[1] - size[0] if isinstance(size, tuple) and len(size) > 1
|
||||||
else size[0] if isinstance(size, tuple)
|
else size[0] if isinstance(size, tuple)
|
||||||
else size if size is not None
|
else size if size is not None
|
||||||
else off[1] - off[0] if isinstance(off, tuple) and len(off) > 1
|
else off[1] - off[0]
|
||||||
|
if isinstance(off, tuple) and len(off) > 1
|
||||||
else block_size)
|
else block_size)
|
||||||
|
|
||||||
# read the block
|
# read the block
|
||||||
@@ -143,6 +144,7 @@ def main(disk, block=None, *,
|
|||||||
for o, line in enumerate(xxd(data)):
|
for o, line in enumerate(xxd(data)):
|
||||||
print('%08x: %s' % ((off or 0) + 16*o, line))
|
print('%08x: %s' % ((off or 0) + 16*o, line))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
+21
-12
@@ -621,7 +621,8 @@ class Rbyd:
|
|||||||
|
|
||||||
if len(blocks) > 1:
|
if len(blocks) > 1:
|
||||||
# fetch all blocks
|
# fetch all blocks
|
||||||
rbyds = [cls.fetch(f, block_size, block, trunk) for block in blocks]
|
rbyds = [cls.fetch(f, block_size, block, trunk)
|
||||||
|
for block in blocks]
|
||||||
# determine most recent revision
|
# determine most recent revision
|
||||||
i = 0
|
i = 0
|
||||||
for i_, rbyd in enumerate(rbyds):
|
for i_, rbyd in enumerate(rbyds):
|
||||||
@@ -634,7 +635,8 @@ class Rbyd:
|
|||||||
i = i_
|
i = i_
|
||||||
# keep track of the other blocks
|
# keep track of the other blocks
|
||||||
rbyd = rbyds[i]
|
rbyd = rbyds[i]
|
||||||
rbyd.redund_blocks = [rbyds[(i+1+j) % len(rbyds)].block
|
rbyd.redund_blocks = [
|
||||||
|
rbyds[(i+1+j) % len(rbyds)].block
|
||||||
for j in range(len(rbyds)-1)]
|
for j in range(len(rbyds)-1)]
|
||||||
return rbyd
|
return rbyd
|
||||||
else:
|
else:
|
||||||
@@ -789,7 +791,9 @@ class Rbyd:
|
|||||||
|
|
||||||
done = not tag_ or (rid_, tag_) < (rid, tag)
|
done = not tag_ or (rid_, tag_) < (rid, tag)
|
||||||
|
|
||||||
return done, rid_, tag_, w_, j, d, self.data[j+d:j+d+jump], path
|
return (done, rid_, tag_, w_, j, d,
|
||||||
|
self.data[j+d:j+d+jump],
|
||||||
|
path)
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
return bool(self.trunk)
|
return bool(self.trunk)
|
||||||
@@ -884,7 +888,8 @@ class Rbyd:
|
|||||||
if done:
|
if done:
|
||||||
return True, -1, 0, None
|
return True, -1, 0, None
|
||||||
|
|
||||||
mdir = next(((tag, j, d, data)
|
mdir = next(
|
||||||
|
((tag, j, d, data)
|
||||||
for tag, j, d, data in tags
|
for tag, j, d, data in tags
|
||||||
if tag == TAG_MDIR),
|
if tag == TAG_MDIR),
|
||||||
None)
|
None)
|
||||||
@@ -1040,7 +1045,8 @@ def main(disk, mroots=None, *,
|
|||||||
off_window=off_window,
|
off_window=off_window,
|
||||||
# scale if we're printing with dots or braille
|
# scale if we're printing with dots or braille
|
||||||
width=2*width_ if braille else width_,
|
width=2*width_ if braille else width_,
|
||||||
height=max(1,
|
height=max(
|
||||||
|
1,
|
||||||
4*height_ if braille
|
4*height_ if braille
|
||||||
else 2*height_ if dots
|
else 2*height_ if dots
|
||||||
else height_))
|
else height_))
|
||||||
@@ -1129,7 +1135,8 @@ def main(disk, mroots=None, *,
|
|||||||
# mark mdir in our bmap
|
# mark mdir in our bmap
|
||||||
for block in mdir.blocks:
|
for block in mdir.blocks:
|
||||||
bmap.mdir(block,
|
bmap.mdir(block,
|
||||||
mdir.eoff if args.get('in_use') else block_size)
|
mdir.eoff if args.get('in_use')
|
||||||
|
else block_size)
|
||||||
mdirs_ += 1
|
mdirs_ += 1
|
||||||
|
|
||||||
# find any file btrees in our mdir
|
# find any file btrees in our mdir
|
||||||
@@ -1190,7 +1197,8 @@ def main(disk, mroots=None, *,
|
|||||||
mdir__ = None
|
mdir__ = None
|
||||||
if (not args.get('depth')
|
if (not args.get('depth')
|
||||||
or mdepth+len(path) < args.get('depth')):
|
or mdepth+len(path) < args.get('depth')):
|
||||||
mdir__ = next(((tag, j, d, data)
|
mdir__ = next(
|
||||||
|
((tag, j, d, data)
|
||||||
for tag, j, d, data in tags
|
for tag, j, d, data in tags
|
||||||
if tag == TAG_MDIR),
|
if tag == TAG_MDIR),
|
||||||
None)
|
None)
|
||||||
@@ -1299,7 +1307,8 @@ def main(disk, mroots=None, *,
|
|||||||
bptr__ = None
|
bptr__ = None
|
||||||
if (not args.get('depth')
|
if (not args.get('depth')
|
||||||
or mdepth+len(path) < args.get('depth')):
|
or mdepth+len(path) < args.get('depth')):
|
||||||
bptr__ = next(((tag, j, d, data)
|
bptr__ = next(
|
||||||
|
((tag, j, d, data)
|
||||||
for tag, j, d, data in tags
|
for tag, j, d, data in tags
|
||||||
if tag & 0xfff == TAG_BLOCK),
|
if tag & 0xfff == TAG_BLOCK),
|
||||||
None)
|
None)
|
||||||
@@ -1418,8 +1427,8 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-⣿', '--braille',
|
'-⣿', '--braille',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help="Use 2x4 unicode braille characters. Note that braille characters "
|
help="Use 2x4 unicode braille characters. Note that braille "
|
||||||
"sometimes suffer from inconsistent widths.")
|
"characters sometimes suffer from inconsistent widths.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--chars',
|
'--chars',
|
||||||
help="Characters to use for mdir, btree, data, unused blocks.")
|
help="Characters to use for mdir, btree, data, unused blocks.")
|
||||||
@@ -1445,8 +1454,8 @@ if __name__ == "__main__":
|
|||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
const=0,
|
const=0,
|
||||||
help="Show this many lines of history. 0 uses the terminal height. "
|
help="Show this many lines of history. 0 uses the terminal "
|
||||||
"Defaults to 5.")
|
"height. Defaults to 5.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-U', '--hilbert',
|
'-U', '--hilbert',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
|
|||||||
+13
-6
@@ -289,7 +289,8 @@ class Rbyd:
|
|||||||
|
|
||||||
if len(blocks) > 1:
|
if len(blocks) > 1:
|
||||||
# fetch all blocks
|
# fetch all blocks
|
||||||
rbyds = [cls.fetch(f, block_size, block, trunk) for block in blocks]
|
rbyds = [cls.fetch(f, block_size, block, trunk)
|
||||||
|
for block in blocks]
|
||||||
# determine most recent revision
|
# determine most recent revision
|
||||||
i = 0
|
i = 0
|
||||||
for i_, rbyd in enumerate(rbyds):
|
for i_, rbyd in enumerate(rbyds):
|
||||||
@@ -302,7 +303,8 @@ class Rbyd:
|
|||||||
i = i_
|
i = i_
|
||||||
# keep track of the other blocks
|
# keep track of the other blocks
|
||||||
rbyd = rbyds[i]
|
rbyd = rbyds[i]
|
||||||
rbyd.redund_blocks = [rbyds[(i+1+j) % len(rbyds)].block
|
rbyd.redund_blocks = [
|
||||||
|
rbyds[(i+1+j) % len(rbyds)].block
|
||||||
for j in range(len(rbyds)-1)]
|
for j in range(len(rbyds)-1)]
|
||||||
return rbyd
|
return rbyd
|
||||||
else:
|
else:
|
||||||
@@ -457,7 +459,9 @@ class Rbyd:
|
|||||||
|
|
||||||
done = not tag_ or (rid_, tag_) < (rid, tag)
|
done = not tag_ or (rid_, tag_) < (rid, tag)
|
||||||
|
|
||||||
return done, rid_, tag_, w_, j, d, self.data[j+d:j+d+jump], path
|
return (done, rid_, tag_, w_, j, d,
|
||||||
|
self.data[j+d:j+d+jump],
|
||||||
|
path)
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
return bool(self.trunk)
|
return bool(self.trunk)
|
||||||
@@ -758,7 +762,8 @@ def main(disk, roots=None, *,
|
|||||||
|
|
||||||
d_ += max(bdepths.get(d, 0), 1)
|
d_ += max(bdepths.get(d, 0), 1)
|
||||||
leaf = (bid-(w-1), d, rid-(w-1),
|
leaf = (bid-(w-1), d, rid-(w-1),
|
||||||
next((tag for tag, _, _, _ in tags
|
next(
|
||||||
|
(tag for tag, _, _, _ in tags
|
||||||
if tag & 0xfff == TAG_BRANCH),
|
if tag & 0xfff == TAG_BRANCH),
|
||||||
TAG_BRANCH))
|
TAG_BRANCH))
|
||||||
|
|
||||||
@@ -937,7 +942,8 @@ def main(disk, roots=None, *,
|
|||||||
treerepr(bid, w, bd, rid, tag)
|
treerepr(bid, w, bd, rid, tag)
|
||||||
if args.get('tree')
|
if args.get('tree')
|
||||||
or args.get('rbyd')
|
or args.get('rbyd')
|
||||||
or args.get('btree') else '',
|
or args.get('btree')
|
||||||
|
else '',
|
||||||
2*w_width+1, '' if i != 0
|
2*w_width+1, '' if i != 0
|
||||||
else '%d-%d' % (bid-(w-1), bid) if w > 1
|
else '%d-%d' % (bid-(w-1), bid) if w > 1
|
||||||
else bid if w > 0
|
else bid if w > 0
|
||||||
@@ -945,7 +951,8 @@ def main(disk, roots=None, *,
|
|||||||
21+w_width, tagrepr(
|
21+w_width, tagrepr(
|
||||||
tag, w if i == 0 else 0, len(data), None),
|
tag, w if i == 0 else 0, len(data), None),
|
||||||
next(xxd(data, 8), '')
|
next(xxd(data, 8), '')
|
||||||
if not args.get('raw') and not args.get('no_truncate')
|
if not args.get('raw')
|
||||||
|
and not args.get('no_truncate')
|
||||||
else ''))
|
else ''))
|
||||||
prbyd = rbyd
|
prbyd = rbyd
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -109,14 +109,16 @@ def main(disk, blocks=None, *,
|
|||||||
for block in blocks],
|
for block in blocks],
|
||||||
[off[0] if isinstance(off, tuple)
|
[off[0] if isinstance(off, tuple)
|
||||||
else off if off is not None
|
else off if off is not None
|
||||||
else size[0] if isinstance(size, tuple) and len(size) > 1
|
else size[0]
|
||||||
|
if isinstance(size, tuple) and len(size) > 1
|
||||||
else block[1] if isinstance(block, tuple)
|
else block[1] if isinstance(block, tuple)
|
||||||
else None
|
else None
|
||||||
for block in blocks],
|
for block in blocks],
|
||||||
size[1] - size[0] if isinstance(size, tuple) and len(size) > 1
|
size[1] - size[0] if isinstance(size, tuple) and len(size) > 1
|
||||||
else size[0] if isinstance(size, tuple)
|
else size[0] if isinstance(size, tuple)
|
||||||
else size if size is not None
|
else size if size is not None
|
||||||
else off[1] - off[0] if isinstance(off, tuple) and len(off) > 1
|
else off[1] - off[0]
|
||||||
|
if isinstance(off, tuple) and len(off) > 1
|
||||||
else block_size)
|
else block_size)
|
||||||
|
|
||||||
# cat the blocks
|
# cat the blocks
|
||||||
@@ -126,6 +128,7 @@ def main(disk, blocks=None, *,
|
|||||||
sys.stdout.buffer.write(data)
|
sys.stdout.buffer.write(data)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ def main(errs, *,
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
print('%s ?' % err)
|
print('%s ?' % err)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
+56
-32
@@ -320,7 +320,8 @@ class Rbyd:
|
|||||||
|
|
||||||
if len(blocks) > 1:
|
if len(blocks) > 1:
|
||||||
# fetch all blocks
|
# fetch all blocks
|
||||||
rbyds = [cls.fetch(f, block_size, block, trunk) for block in blocks]
|
rbyds = [cls.fetch(f, block_size, block, trunk)
|
||||||
|
for block in blocks]
|
||||||
# determine most recent revision
|
# determine most recent revision
|
||||||
i = 0
|
i = 0
|
||||||
for i_, rbyd in enumerate(rbyds):
|
for i_, rbyd in enumerate(rbyds):
|
||||||
@@ -333,7 +334,8 @@ class Rbyd:
|
|||||||
i = i_
|
i = i_
|
||||||
# keep track of the other blocks
|
# keep track of the other blocks
|
||||||
rbyd = rbyds[i]
|
rbyd = rbyds[i]
|
||||||
rbyd.redund_blocks = [rbyds[(i+1+j) % len(rbyds)].block
|
rbyd.redund_blocks = [
|
||||||
|
rbyds[(i+1+j) % len(rbyds)].block
|
||||||
for j in range(len(rbyds)-1)]
|
for j in range(len(rbyds)-1)]
|
||||||
return rbyd
|
return rbyd
|
||||||
else:
|
else:
|
||||||
@@ -488,7 +490,9 @@ class Rbyd:
|
|||||||
|
|
||||||
done = not tag_ or (rid_, tag_) < (rid, tag)
|
done = not tag_ or (rid_, tag_) < (rid, tag)
|
||||||
|
|
||||||
return done, rid_, tag_, w_, j, d, self.data[j+d:j+d+jump], path
|
return (done, rid_, tag_, w_, j, d,
|
||||||
|
self.data[j+d:j+d+jump],
|
||||||
|
path)
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
return bool(self.trunk)
|
return bool(self.trunk)
|
||||||
@@ -750,7 +754,8 @@ class Rbyd:
|
|||||||
|
|
||||||
d_ += max(bdepths.get(d, 0), 1)
|
d_ += max(bdepths.get(d, 0), 1)
|
||||||
leaf = (bid-(w-1), d, rid-(w-1),
|
leaf = (bid-(w-1), d, rid-(w-1),
|
||||||
next((tag for tag, _, _, _ in tags
|
next(
|
||||||
|
(tag for tag, _, _, _ in tags
|
||||||
if tag & 0xfff == TAG_BRANCH),
|
if tag & 0xfff == TAG_BRANCH),
|
||||||
TAG_BRANCH))
|
TAG_BRANCH))
|
||||||
|
|
||||||
@@ -878,7 +883,8 @@ class Rbyd:
|
|||||||
if done:
|
if done:
|
||||||
return True, -1, 0, None
|
return True, -1, 0, None
|
||||||
|
|
||||||
mdir = next(((tag, j, d, data)
|
mdir = next(
|
||||||
|
((tag, j, d, data)
|
||||||
for tag, j, d, data in tags
|
for tag, j, d, data in tags
|
||||||
if tag == TAG_MDIR),
|
if tag == TAG_MDIR),
|
||||||
None)
|
None)
|
||||||
@@ -1181,7 +1187,8 @@ class GState:
|
|||||||
# xor gstate
|
# xor gstate
|
||||||
if tag not in self.gstate:
|
if tag not in self.gstate:
|
||||||
self.gstate[tag] = b''
|
self.gstate[tag] = b''
|
||||||
self.gstate[tag] = bytes(a^b for a,b in it.zip_longest(
|
self.gstate[tag] = bytes(
|
||||||
|
a^b for a,b in it.zip_longest(
|
||||||
self.gstate[tag], data, fillvalue=0))
|
self.gstate[tag], data, fillvalue=0))
|
||||||
|
|
||||||
# parsers for some gstate
|
# parsers for some gstate
|
||||||
@@ -1208,7 +1215,8 @@ class GState:
|
|||||||
count, _ = fromleb128(data)
|
count, _ = fromleb128(data)
|
||||||
return 'grm %s' % (
|
return 'grm %s' % (
|
||||||
'none' if count == 0
|
'none' if count == 0
|
||||||
else ' '.join('%d.%d' % (mbid//self.mleaf_weight, rid)
|
else ' '.join(
|
||||||
|
'%d.%d' % (mbid//self.mleaf_weight, rid)
|
||||||
for mbid, rid in self.grm)
|
for mbid, rid in self.grm)
|
||||||
if count <= 2
|
if count <= 2
|
||||||
else '0x%x %d' % (count, len(data)))
|
else '0x%x %d' % (count, len(data)))
|
||||||
@@ -1479,15 +1487,18 @@ def dbg_fstruct(f, block_size, mdir, rid, tag, j, d, data, *,
|
|||||||
treerepr(bid, w, bd, rid, False, tag)
|
treerepr(bid, w, bd, rid, False, tag)
|
||||||
if args.get('tree')
|
if args.get('tree')
|
||||||
or args.get('rbyd')
|
or args.get('rbyd')
|
||||||
or args.get('btree') else '',
|
or args.get('btree')
|
||||||
'%*s ' % (2*w_width+1, '' if i != 0
|
else '',
|
||||||
|
'%*s ' % (
|
||||||
|
2*w_width+1, '' if i != 0
|
||||||
else '%d-%d' % (bid-(w-1), bid) if w > 1
|
else '%d-%d' % (bid-(w-1), bid) if w > 1
|
||||||
else bid if w > 0
|
else bid if w > 0
|
||||||
else ''),
|
else ''),
|
||||||
21+2*w_width+1,
|
21+2*w_width+1, tagrepr(
|
||||||
tagrepr(tag, w if i == 0 else 0, len(data), None),
|
tag, w if i == 0 else 0, len(data), None),
|
||||||
next(xxd(data, 8), '')
|
next(xxd(data, 8), '')
|
||||||
if not args.get('raw') and not args.get('no_truncate')
|
if not args.get('raw')
|
||||||
|
and not args.get('no_truncate')
|
||||||
else ''))
|
else ''))
|
||||||
prbyd = rbyd
|
prbyd = rbyd
|
||||||
|
|
||||||
@@ -1526,9 +1537,11 @@ def dbg_fstruct(f, block_size, mdir, rid, tag, j, d, data, *,
|
|||||||
treerepr(bid, w, bd, rid, True, tag)
|
treerepr(bid, w, bd, rid, True, tag)
|
||||||
if args.get('tree')
|
if args.get('tree')
|
||||||
or args.get('rbyd')
|
or args.get('rbyd')
|
||||||
or args.get('btree') else '',
|
or args.get('btree')
|
||||||
|
else '',
|
||||||
'\x1b[31m' if color and notes else '',
|
'\x1b[31m' if color and notes else '',
|
||||||
'%*s ' % (2*w_width+1, '%d-%d' % (bid-(w-1), bid) if w > 1
|
'%*s ' % (
|
||||||
|
2*w_width+1, '%d-%d' % (bid-(w-1), bid) if w > 1
|
||||||
else bid if w > 0
|
else bid if w > 0
|
||||||
else ''),
|
else ''),
|
||||||
56+2*w_width+1, '%-*s %s' % (
|
56+2*w_width+1, '%-*s %s' % (
|
||||||
@@ -1538,7 +1551,8 @@ def dbg_fstruct(f, block_size, mdir, rid, tag, j, d, data, *,
|
|||||||
' w%d' % w if w else '',
|
' w%d' % w if w else '',
|
||||||
block, off, size),
|
block, off, size),
|
||||||
next(xxd(data, 8), '')
|
next(xxd(data, 8), '')
|
||||||
if not args.get('raw') and not args.get('no_truncate')
|
if not args.get('raw')
|
||||||
|
and not args.get('no_truncate')
|
||||||
else ''),
|
else ''),
|
||||||
' (%s)' % ', '.join(notes) if notes else '',
|
' (%s)' % ', '.join(notes) if notes else '',
|
||||||
'\x1b[m' if color and notes else ''))
|
'\x1b[m' if color and notes else ''))
|
||||||
@@ -1652,7 +1666,8 @@ def dbg_fstruct(f, block_size, mdir, rid, tag, j, d, data, *,
|
|||||||
bptr = None
|
bptr = None
|
||||||
if (not args.get('struct_depth')
|
if (not args.get('struct_depth')
|
||||||
or len(path) < args.get('struct_depth')):
|
or len(path) < args.get('struct_depth')):
|
||||||
bptr = next(((tag, j, d, data)
|
bptr = next(
|
||||||
|
((tag, j, d, data)
|
||||||
for tag, j, d, data in tags
|
for tag, j, d, data in tags
|
||||||
if (tag & 0xfff) == TAG_BLOCK),
|
if (tag & 0xfff) == TAG_BLOCK),
|
||||||
None)
|
None)
|
||||||
@@ -1754,12 +1769,12 @@ def main(disk, mroots=None, *,
|
|||||||
for rid, tag, w, j, d, data in mroot:
|
for rid, tag, w, j, d, data in mroot:
|
||||||
if tag == TAG_DID:
|
if tag == TAG_DID:
|
||||||
did, d = fromleb128(data)
|
did, d = fromleb128(data)
|
||||||
dir_dids.append(
|
dir_dids.append((
|
||||||
(did, data[d:], -1, 0, mroot, rid, tag, w))
|
did, data[d:], -1, 0, mroot, rid, tag, w))
|
||||||
elif tag == TAG_BOOKMARK:
|
elif tag == TAG_BOOKMARK:
|
||||||
did, d = fromleb128(data)
|
did, d = fromleb128(data)
|
||||||
bookmark_dids.append(
|
bookmark_dids.append((
|
||||||
(did, data[d:], -1, 0, mroot, rid, tag, w))
|
did, data[d:], -1, 0, mroot, rid, tag, w))
|
||||||
|
|
||||||
# fetch the next mroot
|
# fetch the next mroot
|
||||||
done, rid, tag, w, j, d, data, _ = mroot.lookup(-1, TAG_MROOT)
|
done, rid, tag, w, j, d, data, _ = mroot.lookup(-1, TAG_MROOT)
|
||||||
@@ -1817,7 +1832,8 @@ def main(disk, mroots=None, *,
|
|||||||
corrupted = True
|
corrupted = True
|
||||||
continue
|
continue
|
||||||
|
|
||||||
mdir__ = next(((tag, j, d, data)
|
mdir__ = next(
|
||||||
|
((tag, j, d, data)
|
||||||
for tag, j, d, data in tags
|
for tag, j, d, data in tags
|
||||||
if tag == TAG_MDIR),
|
if tag == TAG_MDIR),
|
||||||
None)
|
None)
|
||||||
@@ -1916,7 +1932,8 @@ def main(disk, mroots=None, *,
|
|||||||
for i, (repr_, tag, j, data) in enumerate(config.repr()):
|
for i, (repr_, tag, j, data) in enumerate(config.repr()):
|
||||||
print('%12s %*s %-*s %s' % (
|
print('%12s %*s %-*s %s' % (
|
||||||
'{%s}:' % ','.join('%04x' % block
|
'{%s}:' % ','.join('%04x' % block
|
||||||
for block in it.chain([mroot.block],
|
for block in it.chain(
|
||||||
|
[mroot.block],
|
||||||
mroot.redund_blocks))
|
mroot.redund_blocks))
|
||||||
if i == 0 else '',
|
if i == 0 else '',
|
||||||
2*w_width+1, '%d.%d' % (-1, -1)
|
2*w_width+1, '%d.%d' % (-1, -1)
|
||||||
@@ -1924,7 +1941,8 @@ def main(disk, mroots=None, *,
|
|||||||
21+w_width, repr_,
|
21+w_width, repr_,
|
||||||
next(xxd(data, 8), '')
|
next(xxd(data, 8), '')
|
||||||
if not args.get('raw')
|
if not args.get('raw')
|
||||||
and not args.get('no_truncate') else ''))
|
and not args.get('no_truncate')
|
||||||
|
else ''))
|
||||||
|
|
||||||
# show on-disk encoding
|
# show on-disk encoding
|
||||||
if args.get('raw') or args.get('no_truncate'):
|
if args.get('raw') or args.get('no_truncate'):
|
||||||
@@ -1943,7 +1961,8 @@ def main(disk, mroots=None, *,
|
|||||||
21+w_width, repr_,
|
21+w_width, repr_,
|
||||||
next(xxd(data, 8), '')
|
next(xxd(data, 8), '')
|
||||||
if not args.get('raw')
|
if not args.get('raw')
|
||||||
and not args.get('no_truncate') else ''))
|
and not args.get('no_truncate')
|
||||||
|
else ''))
|
||||||
|
|
||||||
# show on-disk encoding
|
# show on-disk encoding
|
||||||
if args.get('raw') or args.get('no_truncate'):
|
if args.get('raw') or args.get('no_truncate'):
|
||||||
@@ -1959,13 +1978,16 @@ def main(disk, mroots=None, *,
|
|||||||
print('%s%12s %*s %-*s %s%s' % (
|
print('%s%12s %*s %-*s %s%s' % (
|
||||||
'\x1b[90m' if color else '',
|
'\x1b[90m' if color else '',
|
||||||
'{%s}:' % ','.join('%04x' % block
|
'{%s}:' % ','.join('%04x' % block
|
||||||
for block in it.chain([mdir.block],
|
for block in it.chain(
|
||||||
|
[mdir.block],
|
||||||
mdir.redund_blocks)),
|
mdir.redund_blocks)),
|
||||||
2*w_width+1, '%d.%d' % (mbid//mleaf_weight, -1),
|
2*w_width+1, '%d.%d' % (
|
||||||
|
mbid//mleaf_weight, -1),
|
||||||
21+w_width, tagrepr(tag, 0, len(data)),
|
21+w_width, tagrepr(tag, 0, len(data)),
|
||||||
next(xxd(data, 8), '')
|
next(xxd(data, 8), '')
|
||||||
if not args.get('raw')
|
if not args.get('raw')
|
||||||
and not args.get('no_truncate') else '',
|
and not args.get('no_truncate')
|
||||||
|
else '',
|
||||||
'\x1b[m' if color else ''))
|
'\x1b[m' if color else ''))
|
||||||
|
|
||||||
# show on-disk encoding
|
# show on-disk encoding
|
||||||
@@ -2053,13 +2075,16 @@ def main(disk, mroots=None, *,
|
|||||||
or tag == TAG_ORPHAN)
|
or tag == TAG_ORPHAN)
|
||||||
else '',
|
else '',
|
||||||
'{%s}:' % ','.join('%04x' % block
|
'{%s}:' % ','.join('%04x' % block
|
||||||
for block in it.chain([mdir.block],
|
for block in it.chain(
|
||||||
|
[mdir.block],
|
||||||
mdir.redund_blocks))
|
mdir.redund_blocks))
|
||||||
if mbid != pmbid else '',
|
if mbid != pmbid else '',
|
||||||
2*w_width+1, '%d.%d-%d' % (
|
2*w_width+1, '%d.%d-%d' % (
|
||||||
mbid//mleaf_weight, rid-(w-1), rid)
|
mbid//mleaf_weight, rid-(w-1), rid)
|
||||||
if w > 1 else '%d.%d' % (mbid//mleaf_weight, rid)
|
if w > 1
|
||||||
if w > 0 else '',
|
else '%d.%d' % (mbid//mleaf_weight, rid)
|
||||||
|
if w > 0
|
||||||
|
else '',
|
||||||
f_width, '%s%s' % (
|
f_width, '%s%s' % (
|
||||||
prefixes[0+(i==len(dir)-1)],
|
prefixes[0+(i==len(dir)-1)],
|
||||||
name.decode('utf8')),
|
name.decode('utf8')),
|
||||||
@@ -2154,8 +2179,7 @@ def main(disk, mroots=None, *,
|
|||||||
rid, TAG_DID)
|
rid, TAG_DID)
|
||||||
if not done and rid_ == rid and tag_ == TAG_DID:
|
if not done and rid_ == rid and tag_ == TAG_DID:
|
||||||
did_, _ = fromleb128(data)
|
did_, _ = fromleb128(data)
|
||||||
rec_dir(
|
rec_dir(did_,
|
||||||
did_,
|
|
||||||
depth-1,
|
depth-1,
|
||||||
(prefixes[2+(i==len(dir)-1)] + "|-> ",
|
(prefixes[2+(i==len(dir)-1)] + "|-> ",
|
||||||
prefixes[2+(i==len(dir)-1)] + "'-> ",
|
prefixes[2+(i==len(dir)-1)] + "'-> ",
|
||||||
|
|||||||
+39
-19
@@ -304,7 +304,8 @@ class Rbyd:
|
|||||||
|
|
||||||
if len(blocks) > 1:
|
if len(blocks) > 1:
|
||||||
# fetch all blocks
|
# fetch all blocks
|
||||||
rbyds = [cls.fetch(f, block_size, block, trunk) for block in blocks]
|
rbyds = [cls.fetch(f, block_size, block, trunk)
|
||||||
|
for block in blocks]
|
||||||
# determine most recent revision
|
# determine most recent revision
|
||||||
i = 0
|
i = 0
|
||||||
for i_, rbyd in enumerate(rbyds):
|
for i_, rbyd in enumerate(rbyds):
|
||||||
@@ -317,7 +318,8 @@ class Rbyd:
|
|||||||
i = i_
|
i = i_
|
||||||
# keep track of the other blocks
|
# keep track of the other blocks
|
||||||
rbyd = rbyds[i]
|
rbyd = rbyds[i]
|
||||||
rbyd.redund_blocks = [rbyds[(i+1+j) % len(rbyds)].block
|
rbyd.redund_blocks = [
|
||||||
|
rbyds[(i+1+j) % len(rbyds)].block
|
||||||
for j in range(len(rbyds)-1)]
|
for j in range(len(rbyds)-1)]
|
||||||
return rbyd
|
return rbyd
|
||||||
else:
|
else:
|
||||||
@@ -472,7 +474,9 @@ class Rbyd:
|
|||||||
|
|
||||||
done = not tag_ or (rid_, tag_) < (rid, tag)
|
done = not tag_ or (rid_, tag_) < (rid, tag)
|
||||||
|
|
||||||
return done, rid_, tag_, w_, j, d, self.data[j+d:j+d+jump], path
|
return (done, rid_, tag_, w_, j, d,
|
||||||
|
self.data[j+d:j+d+jump],
|
||||||
|
path)
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
return bool(self.trunk)
|
return bool(self.trunk)
|
||||||
@@ -734,7 +738,8 @@ class Rbyd:
|
|||||||
|
|
||||||
d_ += max(bdepths.get(d, 0), 1)
|
d_ += max(bdepths.get(d, 0), 1)
|
||||||
leaf = (bid-(w-1), d, rid-(w-1),
|
leaf = (bid-(w-1), d, rid-(w-1),
|
||||||
next((tag for tag, _, _, _ in tags
|
next(
|
||||||
|
(tag for tag, _, _, _ in tags
|
||||||
if tag & 0xfff == TAG_BRANCH),
|
if tag & 0xfff == TAG_BRANCH),
|
||||||
TAG_BRANCH))
|
TAG_BRANCH))
|
||||||
|
|
||||||
@@ -947,7 +952,8 @@ def main(disk, mroots=None, *,
|
|||||||
mdir__ = None
|
mdir__ = None
|
||||||
if (not args.get('depth')
|
if (not args.get('depth')
|
||||||
or mdepth+len(path) < args.get('depth')):
|
or mdepth+len(path) < args.get('depth')):
|
||||||
mdir__ = next(((tag, j, d, data)
|
mdir__ = next(
|
||||||
|
((tag, j, d, data)
|
||||||
for tag, j, d, data in tags
|
for tag, j, d, data in tags
|
||||||
if tag == TAG_MDIR),
|
if tag == TAG_MDIR),
|
||||||
None)
|
None)
|
||||||
@@ -1098,7 +1104,8 @@ def main(disk, mroots=None, *,
|
|||||||
mdir__ = None
|
mdir__ = None
|
||||||
if (not args.get('depth')
|
if (not args.get('depth')
|
||||||
or mdepth+len(path) < args.get('depth')):
|
or mdepth+len(path) < args.get('depth')):
|
||||||
mdir__ = next(((tag, j, d, data)
|
mdir__ = next(
|
||||||
|
((tag, j, d, data)
|
||||||
for tag, j, d, data in tags
|
for tag, j, d, data in tags
|
||||||
if tag == TAG_MDIR),
|
if tag == TAG_MDIR),
|
||||||
None)
|
None)
|
||||||
@@ -1128,7 +1135,8 @@ def main(disk, mroots=None, *,
|
|||||||
mdir__ = None
|
mdir__ = None
|
||||||
if (not args.get('depth')
|
if (not args.get('depth')
|
||||||
or mdepth+len(path) < args.get('depth')):
|
or mdepth+len(path) < args.get('depth')):
|
||||||
mdir__ = next(((tag, j, d, data)
|
mdir__ = next(
|
||||||
|
((tag, j, d, data)
|
||||||
for tag, j, d, data in tags
|
for tag, j, d, data in tags
|
||||||
if tag == TAG_MDIR),
|
if tag == TAG_MDIR),
|
||||||
None)
|
None)
|
||||||
@@ -1318,7 +1326,8 @@ def main(disk, mroots=None, *,
|
|||||||
mdir__ = None
|
mdir__ = None
|
||||||
if (not args.get('depth')
|
if (not args.get('depth')
|
||||||
or mdepth+len(path) < args.get('depth')):
|
or mdepth+len(path) < args.get('depth')):
|
||||||
mdir__ = next(((tag, j, d, data)
|
mdir__ = next(
|
||||||
|
((tag, j, d, data)
|
||||||
for tag, j, d, data in tags
|
for tag, j, d, data in tags
|
||||||
if tag == TAG_MDIR),
|
if tag == TAG_MDIR),
|
||||||
None)
|
None)
|
||||||
@@ -1397,7 +1406,8 @@ def main(disk, mroots=None, *,
|
|||||||
was = None
|
was = None
|
||||||
for d in range(t_depth):
|
for d in range(t_depth):
|
||||||
t, c, was = branchrepr(
|
t, c, was = branchrepr(
|
||||||
(mbid-max(mw-1, 0), md, mrid-max(mw-1, 0), rid, tag),
|
(mbid-max(mw-1, 0), md,
|
||||||
|
mrid-max(mw-1, 0), rid, tag),
|
||||||
d, was)
|
d, was)
|
||||||
|
|
||||||
trunk.append('%s%s%s%s' % (
|
trunk.append('%s%s%s%s' % (
|
||||||
@@ -1417,18 +1427,22 @@ def main(disk, mroots=None, *,
|
|||||||
# show human-readable tag representation
|
# show human-readable tag representation
|
||||||
print('%12s %s%s' % (
|
print('%12s %s%s' % (
|
||||||
'{%s}:' % ','.join('%04x' % block
|
'{%s}:' % ','.join('%04x' % block
|
||||||
for block in it.chain([mdir.block],
|
for block in it.chain(
|
||||||
|
[mdir.block],
|
||||||
mdir.redund_blocks))
|
mdir.redund_blocks))
|
||||||
if i == 0 else '',
|
if i == 0 else '',
|
||||||
treerepr(mbid-max(mw-1, 0), 0, md, 0, rid, tag)
|
treerepr(mbid-max(mw-1, 0), 0, md, 0, rid, tag)
|
||||||
if args.get('tree')
|
if args.get('tree')
|
||||||
or args.get('rbyd')
|
or args.get('rbyd')
|
||||||
or args.get('btree') else '',
|
or args.get('btree')
|
||||||
|
else '',
|
||||||
'%*s %-*s%s' % (
|
'%*s %-*s%s' % (
|
||||||
2*w_width+1, '%d.%d-%d' % (
|
2*w_width+1, '%d.%d-%d' % (
|
||||||
mbid//mleaf_weight, rid-(w-1), rid)
|
mbid//mleaf_weight, rid-(w-1), rid)
|
||||||
if w > 1 else '%d.%d' % (mbid//mleaf_weight, rid)
|
if w > 1
|
||||||
if w > 0 or i == 0 else '',
|
else '%d.%d' % (mbid//mleaf_weight, rid)
|
||||||
|
if w > 0 or i == 0
|
||||||
|
else '',
|
||||||
21+w_width, tagrepr(tag, w, len(data), j),
|
21+w_width, tagrepr(tag, w, len(data), j),
|
||||||
' %s' % next(xxd(data, 8), '')
|
' %s' % next(xxd(data, 8), '')
|
||||||
if not args.get('raw')
|
if not args.get('raw')
|
||||||
@@ -1467,7 +1481,8 @@ def main(disk, mroots=None, *,
|
|||||||
treerepr(bid, w, bd, rid, 0, tag)
|
treerepr(bid, w, bd, rid, 0, tag)
|
||||||
if args.get('tree')
|
if args.get('tree')
|
||||||
or args.get('rbyd')
|
or args.get('rbyd')
|
||||||
or args.get('btree') else '',
|
or args.get('btree')
|
||||||
|
else '',
|
||||||
2*w_width+1, '' if i != 0
|
2*w_width+1, '' if i != 0
|
||||||
else '%d-%d' % (
|
else '%d-%d' % (
|
||||||
(bid-(w-1))//mleaf_weight,
|
(bid-(w-1))//mleaf_weight,
|
||||||
@@ -1478,7 +1493,8 @@ def main(disk, mroots=None, *,
|
|||||||
21+w_width, tagrepr(
|
21+w_width, tagrepr(
|
||||||
tag, w if i == 0 else 0, len(data), None),
|
tag, w if i == 0 else 0, len(data), None),
|
||||||
next(xxd(data, 8), '')
|
next(xxd(data, 8), '')
|
||||||
if not args.get('raw') and not args.get('no_truncate')
|
if not args.get('raw')
|
||||||
|
and not args.get('no_truncate')
|
||||||
else ''))
|
else ''))
|
||||||
prbyd = rbyd
|
prbyd = rbyd
|
||||||
|
|
||||||
@@ -1526,7 +1542,8 @@ def main(disk, mroots=None, *,
|
|||||||
if not mroot:
|
if not mroot:
|
||||||
print('{%s}: %s%s%s' % (
|
print('{%s}: %s%s%s' % (
|
||||||
','.join('%04x' % block
|
','.join('%04x' % block
|
||||||
for block in it.chain([mroot.block],
|
for block in it.chain(
|
||||||
|
[mroot.block],
|
||||||
mroot.redund_blocks)),
|
mroot.redund_blocks)),
|
||||||
'\x1b[31m' if color else '',
|
'\x1b[31m' if color else '',
|
||||||
'(corrupted mroot %s)' % mroot.addr(),
|
'(corrupted mroot %s)' % mroot.addr(),
|
||||||
@@ -1561,7 +1578,8 @@ def main(disk, mroots=None, *,
|
|||||||
if not mdir:
|
if not mdir:
|
||||||
print('{%s}: %s%s%s' % (
|
print('{%s}: %s%s%s' % (
|
||||||
','.join('%04x' % block
|
','.join('%04x' % block
|
||||||
for block in it.chain([mdir.block],
|
for block in it.chain(
|
||||||
|
[mdir.block],
|
||||||
mdir.redund_blocks)),
|
mdir.redund_blocks)),
|
||||||
'\x1b[31m' if color else '',
|
'\x1b[31m' if color else '',
|
||||||
'(corrupted mdir %s)' % mdir.addr(),
|
'(corrupted mdir %s)' % mdir.addr(),
|
||||||
@@ -1637,7 +1655,8 @@ def main(disk, mroots=None, *,
|
|||||||
mdir__ = None
|
mdir__ = None
|
||||||
if (not args.get('depth')
|
if (not args.get('depth')
|
||||||
or mdepth+len(path) < args.get('depth')):
|
or mdepth+len(path) < args.get('depth')):
|
||||||
mdir__ = next(((tag, j, d, data)
|
mdir__ = next(
|
||||||
|
((tag, j, d, data)
|
||||||
for tag, j, d, data in tags
|
for tag, j, d, data in tags
|
||||||
if tag == TAG_MDIR),
|
if tag == TAG_MDIR),
|
||||||
None)
|
None)
|
||||||
@@ -1658,7 +1677,8 @@ def main(disk, mroots=None, *,
|
|||||||
if not mdir_:
|
if not mdir_:
|
||||||
print('{%s}: %*s%s%s%s' % (
|
print('{%s}: %*s%s%s%s' % (
|
||||||
','.join('%04x' % block
|
','.join('%04x' % block
|
||||||
for block in it.chain([mdir_.block],
|
for block in it.chain(
|
||||||
|
[mdir_.block],
|
||||||
mdir_.redund_blocks)),
|
mdir_.redund_blocks)),
|
||||||
t_width, '',
|
t_width, '',
|
||||||
'\x1b[31m' if color else '',
|
'\x1b[31m' if color else '',
|
||||||
|
|||||||
+19
-10
@@ -7,6 +7,7 @@ import math as mt
|
|||||||
import os
|
import os
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
|
|
||||||
COLORS = [
|
COLORS = [
|
||||||
'34', # blue
|
'34', # blue
|
||||||
'31', # red
|
'31', # red
|
||||||
@@ -585,7 +586,9 @@ def dbg_log(data, block_size, rev, eoff, weight, *,
|
|||||||
'\x1b[90m' if color and j >= eoff else '',
|
'\x1b[90m' if color and j >= eoff else '',
|
||||||
j,
|
j,
|
||||||
'\x1b[m' if color and j >= eoff else '',
|
'\x1b[m' if color and j >= eoff else '',
|
||||||
lifetime_width, lifetimerepr(j) if args.get('lifetimes') else '',
|
lifetime_width, lifetimerepr(j)
|
||||||
|
if args.get('lifetimes')
|
||||||
|
else '',
|
||||||
'\x1b[90m' if color and j >= eoff else '',
|
'\x1b[90m' if color and j >= eoff else '',
|
||||||
2*w_width+1, '' if (tag & 0xe000) != 0x0000
|
2*w_width+1, '' if (tag & 0xe000) != 0x0000
|
||||||
else '%d-%d' % (rid-(w-1), rid) if w > 1
|
else '%d-%d' % (rid-(w-1), rid) if w > 1
|
||||||
@@ -593,12 +596,15 @@ def dbg_log(data, block_size, rev, eoff, weight, *,
|
|||||||
56+w_width, '%-*s %s' % (
|
56+w_width, '%-*s %s' % (
|
||||||
21+w_width, tagrepr(tag, w, size, j),
|
21+w_width, tagrepr(tag, w, size, j),
|
||||||
next(xxd(data[j+d:j+d+min(size, 8)], 8), '')
|
next(xxd(data[j+d:j+d+min(size, 8)], 8), '')
|
||||||
if not args.get('raw') and not args.get('no_truncate')
|
if not args.get('raw')
|
||||||
and not tag & TAG_ALT else ''),
|
and not args.get('no_truncate')
|
||||||
|
and not tag & TAG_ALT
|
||||||
|
else ''),
|
||||||
' (%s)' % ', '.join(notes) if notes else '',
|
' (%s)' % ', '.join(notes) if notes else '',
|
||||||
'\x1b[m' if color and j >= eoff else '',
|
'\x1b[m' if color and j >= eoff else '',
|
||||||
' %s' % jumprepr(j)
|
' %s' % jumprepr(j)
|
||||||
if args.get('jumps') and not notes else ''))
|
if args.get('jumps') and not notes
|
||||||
|
else ''))
|
||||||
|
|
||||||
# show on-disk encoding of tags
|
# show on-disk encoding of tags
|
||||||
if args.get('raw'):
|
if args.get('raw'):
|
||||||
@@ -852,14 +858,17 @@ def dbg_tree(data, block_size, rev, trunk, weight, *,
|
|||||||
print('%08x: %s%*s %-*s %s' % (
|
print('%08x: %s%*s %-*s %s' % (
|
||||||
j,
|
j,
|
||||||
treerepr(rid, tag)
|
treerepr(rid, tag)
|
||||||
if args.get('tree') or args.get('rbyd') else '',
|
if args.get('tree') or args.get('rbyd')
|
||||||
2*w_width+1, '%d-%d' % (rid-(w-1), rid)
|
else '',
|
||||||
if w > 1 else rid
|
2*w_width+1, '%d-%d' % (rid-(w-1), rid) if w > 1
|
||||||
if w > 0 or i == 0 else '',
|
else rid if w > 0 or i == 0
|
||||||
|
else '',
|
||||||
21+w_width, tagrepr(tag, w, size, j),
|
21+w_width, tagrepr(tag, w, size, j),
|
||||||
next(xxd(data[j+d:j+d+min(size, 8)], 8), '')
|
next(xxd(data[j+d:j+d+min(size, 8)], 8), '')
|
||||||
if not args.get('raw') and not args.get('no_truncate')
|
if not args.get('raw')
|
||||||
and not tag & TAG_ALT else ''))
|
and not args.get('no_truncate')
|
||||||
|
and not tag & TAG_ALT
|
||||||
|
else ''))
|
||||||
|
|
||||||
# show on-disk encoding of tags
|
# show on-disk encoding of tags
|
||||||
if args.get('raw'):
|
if args.get('raw'):
|
||||||
|
|||||||
@@ -319,6 +319,7 @@ def main(tags, *,
|
|||||||
data = f.read(2+5+5)
|
data = f.read(2+5+5)
|
||||||
dbg_tag(data)
|
dbg_tag(data)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ def main(paths, **args):
|
|||||||
else:
|
else:
|
||||||
print('%01x' % parity(xor))
|
print('%01x' % parity(xor))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
+47
-35
@@ -27,8 +27,8 @@ import subprocess as sp
|
|||||||
import tempfile
|
import tempfile
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
# TODO support non-zip perf results?
|
|
||||||
|
|
||||||
|
# TODO support non-zip perf results?
|
||||||
|
|
||||||
PERF_PATH = ['perf']
|
PERF_PATH = ['perf']
|
||||||
PERF_EVENTS = 'cycles,branch-misses,branches,cache-misses,cache-references'
|
PERF_EVENTS = 'cycles,branch-misses,branches,cache-misses,cache-references'
|
||||||
@@ -249,15 +249,15 @@ def collect_syms_and_lines(obj_path, *,
|
|||||||
'\s+.*'
|
'\s+.*'
|
||||||
'\s+(?P<path>[^\s]+)'
|
'\s+(?P<path>[^\s]+)'
|
||||||
# matches line opcodes
|
# matches line opcodes
|
||||||
'|' '\[[^\]]*\]\s+'
|
'|' '\[[^\]]*\]\s+' '(?:'
|
||||||
'(?:'
|
|
||||||
'(?P<op_special>Special)'
|
'(?P<op_special>Special)'
|
||||||
'|' '(?P<op_copy>Copy)'
|
'|' '(?P<op_copy>Copy)'
|
||||||
'|' '(?P<op_end>End of Sequence)'
|
'|' '(?P<op_end>End of Sequence)'
|
||||||
'|' 'File .*?to (?:entry )?(?P<op_file>\d+)'
|
'|' 'File .*?to (?:entry )?(?P<op_file>\d+)'
|
||||||
'|' 'Line .*?to (?P<op_line>[0-9]+)'
|
'|' 'Line .*?to (?P<op_line>[0-9]+)'
|
||||||
'|' '(?:Address|PC) .*?to (?P<op_addr>[0x0-9a-fA-F]+)'
|
'|' '(?:Address|PC) .*?to (?P<op_addr>[0x0-9a-fA-F]+)'
|
||||||
'|' '.' ')*'
|
'|' '.'
|
||||||
|
')*'
|
||||||
')$', re.IGNORECASE)
|
')$', re.IGNORECASE)
|
||||||
|
|
||||||
# figure out symbol addresses and file+line ranges
|
# figure out symbol addresses and file+line ranges
|
||||||
@@ -616,7 +616,8 @@ def collect(perf_paths, *,
|
|||||||
with mp.Pool(jobs) as p:
|
with mp.Pool(jobs) as p:
|
||||||
for results_ in p.imap_unordered(
|
for results_ in p.imap_unordered(
|
||||||
starapply,
|
starapply,
|
||||||
((collect_job, (path, i), args) for path, i in records)):
|
((collect_job, (path, i), args)
|
||||||
|
for path, i in records)):
|
||||||
results.extend(results_)
|
results.extend(results_)
|
||||||
else:
|
else:
|
||||||
results = []
|
results = []
|
||||||
@@ -690,12 +691,13 @@ def table(Result, results, diff_results=None, *,
|
|||||||
|
|
||||||
r = max(results_,
|
r = max(results_,
|
||||||
key=lambda r: tuple(
|
key=lambda r: tuple(
|
||||||
tuple(
|
tuple((getattr(r, k),)
|
||||||
(getattr(r, k),)
|
|
||||||
if getattr(r, k, None) is not None
|
if getattr(r, k, None) is not None
|
||||||
else ()
|
else ()
|
||||||
for k in ([k] if k else [
|
for k in (
|
||||||
k for k in Result._sort if k in fields])
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])
|
||||||
if k in fields)
|
if k in fields)
|
||||||
for k in it.chain(hot, [None])))
|
for k in it.chain(hot, [None])))
|
||||||
|
|
||||||
@@ -729,7 +731,8 @@ def table(Result, results, diff_results=None, *,
|
|||||||
# sort again, now with diff info, note that python's sort is stable
|
# sort again, now with diff info, note that python's sort is stable
|
||||||
names.sort()
|
names.sort()
|
||||||
if diff_results is not None:
|
if diff_results is not None:
|
||||||
names.sort(key=lambda n: tuple(
|
names.sort(
|
||||||
|
key=lambda n: tuple(
|
||||||
types[k].ratio(
|
types[k].ratio(
|
||||||
getattr(table.get(n), k, None),
|
getattr(table.get(n), k, None),
|
||||||
getattr(diff_table.get(n), k, None))
|
getattr(diff_table.get(n), k, None))
|
||||||
@@ -740,9 +743,12 @@ def table(Result, results, diff_results=None, *,
|
|||||||
names.sort(
|
names.sort(
|
||||||
key=lambda n: tuple(
|
key=lambda n: tuple(
|
||||||
(getattr(table[n], k),)
|
(getattr(table[n], k),)
|
||||||
if getattr(table.get(n), k, None) is not None else ()
|
if getattr(table.get(n), k, None) is not None
|
||||||
for k in ([k] if k else [
|
else ()
|
||||||
k for k in Result._sort if k in fields])),
|
for k in (
|
||||||
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])),
|
||||||
reverse=reverse ^ (not k or k in Result._fields))
|
reverse=reverse ^ (not k or k in Result._fields))
|
||||||
|
|
||||||
|
|
||||||
@@ -750,8 +756,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
# header
|
# header
|
||||||
header = [
|
header = ['%s%s' % (
|
||||||
'%s%s' % (
|
|
||||||
','.join(by),
|
','.join(by),
|
||||||
' (%d added, %d removed)' % (
|
' (%d added, %d removed)' % (
|
||||||
sum(1 for n in table if n not in diff_table),
|
sum(1 for n in table if n not in diff_table),
|
||||||
@@ -835,10 +840,13 @@ def table(Result, results, diff_results=None, *,
|
|||||||
names_.sort(
|
names_.sort(
|
||||||
key=lambda n: tuple(
|
key=lambda n: tuple(
|
||||||
(getattr(table_[n], k),)
|
(getattr(table_[n], k),)
|
||||||
if getattr(table_.get(n), k, None) is not None
|
if getattr(table_.get(n), k, None)
|
||||||
|
is not None
|
||||||
else ()
|
else ()
|
||||||
for k in ([k] if k else [
|
for k in (
|
||||||
k for k in Result._sort if k in fields])),
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])),
|
||||||
reverse=reverse ^ (not k or k in Result._fields))
|
reverse=reverse ^ (not k or k in Result._fields))
|
||||||
|
|
||||||
for i, name in enumerate(names_):
|
for i, name in enumerate(names_):
|
||||||
@@ -860,8 +868,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
|
|
||||||
# recurse?
|
# recurse?
|
||||||
if depth_ > 1:
|
if depth_ > 1:
|
||||||
recurse(
|
recurse(r.children,
|
||||||
r.children,
|
|
||||||
depth_-1,
|
depth_-1,
|
||||||
seen | {name},
|
seen | {name},
|
||||||
(prefixes[2+is_last] + "|-> ",
|
(prefixes[2+is_last] + "|-> ",
|
||||||
@@ -881,8 +888,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
|
|
||||||
# recursive entries
|
# recursive entries
|
||||||
if name in table and depth > 1:
|
if name in table and depth > 1:
|
||||||
recurse(
|
recurse(table[name].children,
|
||||||
table[name].children,
|
|
||||||
depth-1,
|
depth-1,
|
||||||
{name},
|
{name},
|
||||||
("|-> ",
|
("|-> ",
|
||||||
@@ -1006,9 +1012,11 @@ def annotate(Result, results, *,
|
|||||||
line,
|
line,
|
||||||
'%s cycles' % r.cycles
|
'%s cycles' % r.cycles
|
||||||
if not branches and not caches
|
if not branches and not caches
|
||||||
else '%s bmisses, %s branches' % (r.bmisses, r.branches)
|
else '%s bmisses, %s branches' % (
|
||||||
|
r.bmisses, r.branches)
|
||||||
if branches
|
if branches
|
||||||
else '%s cmisses, %s caches' % (r.cmisses, r.caches))
|
else '%s cmisses, %s caches' % (
|
||||||
|
r.cmisses, r.caches))
|
||||||
|
|
||||||
if args['color']:
|
if args['color']:
|
||||||
if float(getattr(r, tk)) / max_ >= t1:
|
if float(getattr(r, tk)) / max_ >= t1:
|
||||||
@@ -1084,14 +1092,16 @@ def report(perf_paths, *,
|
|||||||
writer = csv.DictWriter(f,
|
writer = csv.DictWriter(f,
|
||||||
(by if by is not None else PerfResult._by)
|
(by if by is not None else PerfResult._by)
|
||||||
+ [k for k in (
|
+ [k for k in (
|
||||||
fields if fields is not None else PerfResult._fields)])
|
fields if fields is not None
|
||||||
|
else PerfResult._fields)])
|
||||||
writer.writeheader()
|
writer.writeheader()
|
||||||
for r in results:
|
for r in results:
|
||||||
writer.writerow(
|
writer.writerow(
|
||||||
{k: getattr(r, k) for k in (
|
{k: getattr(r, k) for k in (
|
||||||
by if by is not None else PerfResult._by)}
|
by if by is not None else PerfResult._by)}
|
||||||
| {k: getattr(r, k) for k in (
|
| {k: getattr(r, k) for k in (
|
||||||
fields if fields is not None else PerfResult._fields)})
|
fields if fields is not None
|
||||||
|
else PerfResult._fields)})
|
||||||
|
|
||||||
# find previous results?
|
# find previous results?
|
||||||
if args.get('diff'):
|
if args.get('diff'):
|
||||||
@@ -1240,8 +1250,8 @@ if __name__ == "__main__":
|
|||||||
'-F', '--source',
|
'-F', '--source',
|
||||||
dest='sources',
|
dest='sources',
|
||||||
action='append',
|
action='append',
|
||||||
help="Only consider definitions in this file. Defaults to anything "
|
help="Only consider definitions in this file. Defaults to "
|
||||||
"in the current directory.")
|
"anything in the current directory.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--everything',
|
'--everything',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -1257,15 +1267,15 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-g', '--propagate',
|
'-g', '--propagate',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
help="Depth to propagate samples up the call-stack. 0 propagates up "
|
help="Depth to propagate samples up the call-stack. 0 propagates "
|
||||||
"to the entry point, 1 does no propagation. Defaults to 0.")
|
"up to the entry point, 1 does no propagation. Defaults to 0.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-z', '--depth',
|
'-z', '--depth',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
const=0,
|
const=0,
|
||||||
help="Depth of function calls to show. 0 shows all calls unless we "
|
help="Depth of function calls to show. 0 shows all calls unless "
|
||||||
"find a cycle. Defaults to 0.")
|
"we find a cycle. Defaults to 0.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-t', '--hot',
|
'-t', '--hot',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
@@ -1280,8 +1290,9 @@ if __name__ == "__main__":
|
|||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: tuple(float(x) for x in x.split(',')),
|
type=lambda x: tuple(float(x) for x in x.split(',')),
|
||||||
const=THRESHOLD,
|
const=THRESHOLD,
|
||||||
help="Show lines with samples above this threshold as a percent of "
|
help="Show lines with samples above this threshold as a percent "
|
||||||
"all lines. Defaults to %s." % ','.join(str(t) for t in THRESHOLD))
|
"of all lines. Defaults to "
|
||||||
|
"%s." % ','.join(str(t) for t in THRESHOLD))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-C', '--context',
|
'-C', '--context',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
@@ -1291,7 +1302,8 @@ if __name__ == "__main__":
|
|||||||
'-W', '--width',
|
'-W', '--width',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
default=80,
|
default=80,
|
||||||
help="Assume source is styled with this many columns. Defaults to 80.")
|
help="Assume source is styled with this many columns. Defaults "
|
||||||
|
"to 80.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--color',
|
'--color',
|
||||||
choices=['never', 'always', 'auto'],
|
choices=['never', 'always', 'auto'],
|
||||||
|
|||||||
+59
-46
@@ -155,15 +155,15 @@ def collect_syms_and_lines(obj_path, *,
|
|||||||
'\s+.*'
|
'\s+.*'
|
||||||
'\s+(?P<path>[^\s]+)'
|
'\s+(?P<path>[^\s]+)'
|
||||||
# matches line opcodes
|
# matches line opcodes
|
||||||
'|' '\[[^\]]*\]\s+'
|
'|' '\[[^\]]*\]\s+' '(?:'
|
||||||
'(?:'
|
|
||||||
'(?P<op_special>Special)'
|
'(?P<op_special>Special)'
|
||||||
'|' '(?P<op_copy>Copy)'
|
'|' '(?P<op_copy>Copy)'
|
||||||
'|' '(?P<op_end>End of Sequence)'
|
'|' '(?P<op_end>End of Sequence)'
|
||||||
'|' 'File .*?to (?:entry )?(?P<op_file>\d+)'
|
'|' 'File .*?to (?:entry )?(?P<op_file>\d+)'
|
||||||
'|' 'Line .*?to (?P<op_line>[0-9]+)'
|
'|' 'Line .*?to (?P<op_line>[0-9]+)'
|
||||||
'|' '(?:Address|PC) .*?to (?P<op_addr>[0x0-9a-fA-F]+)'
|
'|' '(?:Address|PC) .*?to (?P<op_addr>[0x0-9a-fA-F]+)'
|
||||||
'|' '.' ')*'
|
'|' '.'
|
||||||
|
')*'
|
||||||
')$', re.IGNORECASE)
|
')$', re.IGNORECASE)
|
||||||
|
|
||||||
# figure out symbol addresses
|
# figure out symbol addresses
|
||||||
@@ -296,7 +296,8 @@ def collect_job(path, start, stop, syms, sym_at, lines, line_at, *,
|
|||||||
depth=1,
|
depth=1,
|
||||||
**args):
|
**args):
|
||||||
trace_pattern = re.compile(
|
trace_pattern = re.compile(
|
||||||
'^(?P<file>[^:]*):(?P<line>[0-9]+):trace:\s*(?P<prefix>[^\s]*?bd_)(?:'
|
'^(?P<file>[^:]*):(?P<line>[0-9]+):trace:\s*'
|
||||||
|
'(?P<prefix>[^\s]*?bd_)(?:'
|
||||||
'(?P<read>read)\('
|
'(?P<read>read)\('
|
||||||
'\s*(?P<read_ctx>\w+)' '\s*,'
|
'\s*(?P<read_ctx>\w+)' '\s*,'
|
||||||
'\s*(?P<read_block>\w+)' '\s*,'
|
'\s*(?P<read_block>\w+)' '\s*,'
|
||||||
@@ -312,7 +313,8 @@ def collect_job(path, start, stop, syms, sym_at, lines, line_at, *,
|
|||||||
'|' '(?P<erase>erase)\('
|
'|' '(?P<erase>erase)\('
|
||||||
'\s*(?P<erase_ctx>\w+)' '\s*,'
|
'\s*(?P<erase_ctx>\w+)' '\s*,'
|
||||||
'\s*(?P<erase_block>\w+)'
|
'\s*(?P<erase_block>\w+)'
|
||||||
'\s*\(\s*(?P<erase_size>\w+)\s*\)' '\s*\)' ')\s*$')
|
'\s*\(\s*(?P<erase_size>\w+)\s*\)' '\s*\)'
|
||||||
|
')\s*$')
|
||||||
frame_pattern = re.compile(
|
frame_pattern = re.compile(
|
||||||
'^\s+at (?P<addr>\w+)\s*$')
|
'^\s+at (?P<addr>\w+)\s*$')
|
||||||
|
|
||||||
@@ -338,9 +340,7 @@ def collect_job(path, start, stop, syms, sym_at, lines, line_at, *,
|
|||||||
|
|
||||||
# ignore filtered sources
|
# ignore filtered sources
|
||||||
if sources is not None:
|
if sources is not None:
|
||||||
if not any(
|
if not any(os.path.abspath(file) == os.path.abspath(s)
|
||||||
os.path.abspath(file)
|
|
||||||
== os.path.abspath(s)
|
|
||||||
for s in sources):
|
for s in sources):
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
@@ -492,8 +492,7 @@ def collect_job(path, start, stop, syms, sym_at, lines, line_at, *,
|
|||||||
# ignore filtered sources
|
# ignore filtered sources
|
||||||
if sources is not None:
|
if sources is not None:
|
||||||
if not any(
|
if not any(
|
||||||
os.path.abspath(file)
|
os.path.abspath(file) == os.path.abspath(s)
|
||||||
== os.path.abspath(s)
|
|
||||||
for s in sources):
|
for s in sources):
|
||||||
at_cache[addr] = None
|
at_cache[addr] = None
|
||||||
continue
|
continue
|
||||||
@@ -573,7 +572,8 @@ def collect(obj_path, trace_paths, *,
|
|||||||
with mp.Pool(jobs) as p:
|
with mp.Pool(jobs) as p:
|
||||||
for results_ in p.imap_unordered(
|
for results_ in p.imap_unordered(
|
||||||
starapply,
|
starapply,
|
||||||
((collect_job, (path, start, stop,
|
((collect_job,
|
||||||
|
(path, start, stop,
|
||||||
syms, sym_at, lines, line_at),
|
syms, sym_at, lines, line_at),
|
||||||
args)
|
args)
|
||||||
for path, ranges in zip(trace_paths, trace_ranges)
|
for path, ranges in zip(trace_paths, trace_ranges)
|
||||||
@@ -583,7 +583,8 @@ def collect(obj_path, trace_paths, *,
|
|||||||
else:
|
else:
|
||||||
results = []
|
results = []
|
||||||
for path in trace_paths:
|
for path in trace_paths:
|
||||||
results.extend(collect_job(path, None, None,
|
results.extend(collect_job(
|
||||||
|
path, None, None,
|
||||||
syms, sym_at, lines, line_at,
|
syms, sym_at, lines, line_at,
|
||||||
**args))
|
**args))
|
||||||
|
|
||||||
@@ -654,12 +655,13 @@ def table(Result, results, diff_results=None, *,
|
|||||||
|
|
||||||
r = max(results_,
|
r = max(results_,
|
||||||
key=lambda r: tuple(
|
key=lambda r: tuple(
|
||||||
tuple(
|
tuple((getattr(r, k),)
|
||||||
(getattr(r, k),)
|
|
||||||
if getattr(r, k, None) is not None
|
if getattr(r, k, None) is not None
|
||||||
else ()
|
else ()
|
||||||
for k in ([k] if k else [
|
for k in (
|
||||||
k for k in Result._sort if k in fields])
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])
|
||||||
if k in fields)
|
if k in fields)
|
||||||
for k in it.chain(hot, [None])))
|
for k in it.chain(hot, [None])))
|
||||||
|
|
||||||
@@ -693,7 +695,8 @@ def table(Result, results, diff_results=None, *,
|
|||||||
# sort again, now with diff info, note that python's sort is stable
|
# sort again, now with diff info, note that python's sort is stable
|
||||||
names.sort()
|
names.sort()
|
||||||
if diff_results is not None:
|
if diff_results is not None:
|
||||||
names.sort(key=lambda n: tuple(
|
names.sort(
|
||||||
|
key=lambda n: tuple(
|
||||||
types[k].ratio(
|
types[k].ratio(
|
||||||
getattr(table.get(n), k, None),
|
getattr(table.get(n), k, None),
|
||||||
getattr(diff_table.get(n), k, None))
|
getattr(diff_table.get(n), k, None))
|
||||||
@@ -704,9 +707,12 @@ def table(Result, results, diff_results=None, *,
|
|||||||
names.sort(
|
names.sort(
|
||||||
key=lambda n: tuple(
|
key=lambda n: tuple(
|
||||||
(getattr(table[n], k),)
|
(getattr(table[n], k),)
|
||||||
if getattr(table.get(n), k, None) is not None else ()
|
if getattr(table.get(n), k, None) is not None
|
||||||
for k in ([k] if k else [
|
else ()
|
||||||
k for k in Result._sort if k in fields])),
|
for k in (
|
||||||
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])),
|
||||||
reverse=reverse ^ (not k or k in Result._fields))
|
reverse=reverse ^ (not k or k in Result._fields))
|
||||||
|
|
||||||
|
|
||||||
@@ -714,8 +720,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
# header
|
# header
|
||||||
header = [
|
header = ['%s%s' % (
|
||||||
'%s%s' % (
|
|
||||||
','.join(by),
|
','.join(by),
|
||||||
' (%d added, %d removed)' % (
|
' (%d added, %d removed)' % (
|
||||||
sum(1 for n in table if n not in diff_table),
|
sum(1 for n in table if n not in diff_table),
|
||||||
@@ -799,10 +804,13 @@ def table(Result, results, diff_results=None, *,
|
|||||||
names_.sort(
|
names_.sort(
|
||||||
key=lambda n: tuple(
|
key=lambda n: tuple(
|
||||||
(getattr(table_[n], k),)
|
(getattr(table_[n], k),)
|
||||||
if getattr(table_.get(n), k, None) is not None
|
if getattr(table_.get(n), k, None)
|
||||||
|
is not None
|
||||||
else ()
|
else ()
|
||||||
for k in ([k] if k else [
|
for k in (
|
||||||
k for k in Result._sort if k in fields])),
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])),
|
||||||
reverse=reverse ^ (not k or k in Result._fields))
|
reverse=reverse ^ (not k or k in Result._fields))
|
||||||
|
|
||||||
for i, name in enumerate(names_):
|
for i, name in enumerate(names_):
|
||||||
@@ -824,8 +832,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
|
|
||||||
# recurse?
|
# recurse?
|
||||||
if depth_ > 1:
|
if depth_ > 1:
|
||||||
recurse(
|
recurse(r.children,
|
||||||
r.children,
|
|
||||||
depth_-1,
|
depth_-1,
|
||||||
seen | {name},
|
seen | {name},
|
||||||
(prefixes[2+is_last] + "|-> ",
|
(prefixes[2+is_last] + "|-> ",
|
||||||
@@ -845,8 +852,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
|
|
||||||
# recursive entries
|
# recursive entries
|
||||||
if name in table and depth > 1:
|
if name in table and depth > 1:
|
||||||
recurse(
|
recurse(table[name].children,
|
||||||
table[name].children,
|
|
||||||
depth-1,
|
depth-1,
|
||||||
{name},
|
{name},
|
||||||
("|-> ",
|
("|-> ",
|
||||||
@@ -1062,14 +1068,16 @@ def report(obj_path='', trace_paths=[], *,
|
|||||||
writer = csv.DictWriter(f,
|
writer = csv.DictWriter(f,
|
||||||
(by if by is not None else PerfBdResult._by)
|
(by if by is not None else PerfBdResult._by)
|
||||||
+ [k for k in (
|
+ [k for k in (
|
||||||
fields if fields is not None else PerfBdResult._fields)])
|
fields if fields is not None
|
||||||
|
else PerfBdResult._fields)])
|
||||||
writer.writeheader()
|
writer.writeheader()
|
||||||
for r in results:
|
for r in results:
|
||||||
writer.writerow(
|
writer.writerow(
|
||||||
{k: getattr(r, k) for k in (
|
{k: getattr(r, k) for k in (
|
||||||
by if by is not None else PerfBdResult._by)}
|
by if by is not None else PerfBdResult._by)}
|
||||||
| {k: getattr(r, k) for k in (
|
| {k: getattr(r, k) for k in (
|
||||||
fields if fields is not None else PerfBdResult._fields)})
|
fields if fields is not None
|
||||||
|
else PerfBdResult._fields)})
|
||||||
|
|
||||||
# find previous results?
|
# find previous results?
|
||||||
if args.get('diff'):
|
if args.get('diff'):
|
||||||
@@ -1209,8 +1217,8 @@ if __name__ == "__main__":
|
|||||||
'-F', '--source',
|
'-F', '--source',
|
||||||
dest='sources',
|
dest='sources',
|
||||||
action='append',
|
action='append',
|
||||||
help="Only consider definitions in this file. Defaults to anything "
|
help="Only consider definitions in this file. Defaults to "
|
||||||
"in the current directory.")
|
"anything in the current directory.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--everything',
|
'--everything',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -1218,15 +1226,15 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-g', '--propagate',
|
'-g', '--propagate',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
help="Depth to propagate samples up the call-stack. 0 propagates up "
|
help="Depth to propagate samples up the call-stack. 0 propagates "
|
||||||
"to the entry point, 1 does no propagation. Defaults to 0.")
|
"up to the entry point, 1 does no propagation. Defaults to 0.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-z', '--depth',
|
'-z', '--depth',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
const=0,
|
const=0,
|
||||||
help="Depth of function calls to show. 0 shows all calls unless we "
|
help="Depth of function calls to show. 0 shows all calls unless "
|
||||||
"find a cycle. Defaults to 0.")
|
"we find a cycle. Defaults to 0.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-t', '--hot',
|
'-t', '--hot',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
@@ -1241,29 +1249,33 @@ if __name__ == "__main__":
|
|||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: tuple(float(x) for x in x.split(',')),
|
type=lambda x: tuple(float(x) for x in x.split(',')),
|
||||||
const=THRESHOLD,
|
const=THRESHOLD,
|
||||||
help="Show lines with any ops above this threshold as a percent of "
|
help="Show lines with any ops above this threshold as a percent "
|
||||||
"all lines. Defaults to %s." % ','.join(str(t) for t in THRESHOLD))
|
"of all lines. Defaults to "
|
||||||
|
"%s." % ','.join(str(t) for t in THRESHOLD))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--read-threshold',
|
'--read-threshold',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: tuple(float(x) for x in x.split(',')),
|
type=lambda x: tuple(float(x) for x in x.split(',')),
|
||||||
const=THRESHOLD,
|
const=THRESHOLD,
|
||||||
help="Show lines with reads above this threshold as a percent of "
|
help="Show lines with reads above this threshold as a percent "
|
||||||
"all lines. Defaults to %s." % ','.join(str(t) for t in THRESHOLD))
|
"of all lines. Defaults to "
|
||||||
|
"%s." % ','.join(str(t) for t in THRESHOLD))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--prog-threshold',
|
'--prog-threshold',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: tuple(float(x) for x in x.split(',')),
|
type=lambda x: tuple(float(x) for x in x.split(',')),
|
||||||
const=THRESHOLD,
|
const=THRESHOLD,
|
||||||
help="Show lines with progs above this threshold as a percent of "
|
help="Show lines with progs above this threshold as a percent "
|
||||||
"all lines. Defaults to %s." % ','.join(str(t) for t in THRESHOLD))
|
"of all lines. Defaults to "
|
||||||
|
"%s." % ','.join(str(t) for t in THRESHOLD))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--erase-threshold',
|
'--erase-threshold',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: tuple(float(x) for x in x.split(',')),
|
type=lambda x: tuple(float(x) for x in x.split(',')),
|
||||||
const=THRESHOLD,
|
const=THRESHOLD,
|
||||||
help="Show lines with erases above this threshold as a percent of "
|
help="Show lines with erases above this threshold as a percent "
|
||||||
"all lines. Defaults to %s." % ','.join(str(t) for t in THRESHOLD))
|
"of all lines. Defaults to "
|
||||||
|
"%s." % ','.join(str(t) for t in THRESHOLD))
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-C', '--context',
|
'-C', '--context',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
@@ -1273,7 +1285,8 @@ if __name__ == "__main__":
|
|||||||
'-W', '--width',
|
'-W', '--width',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
default=80,
|
default=80,
|
||||||
help="Assume source is styled with this many columns. Defaults to 80.")
|
help="Assume source is styled with this many columns. Defaults "
|
||||||
|
"to 80.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--color',
|
'--color',
|
||||||
choices=['never', 'always', 'auto'],
|
choices=['never', 'always', 'auto'],
|
||||||
|
|||||||
+46
-34
@@ -684,7 +684,8 @@ class Grid:
|
|||||||
|
|
||||||
self.xweights = new_xweights
|
self.xweights = new_xweights
|
||||||
self.yweights = self_yweights + other.yweights
|
self.yweights = self_yweights + other.yweights
|
||||||
self.map = self_map | {(x, y+len(self_yweights)): s
|
self.map = self_map | {
|
||||||
|
(x, y+len(self_yweights)): s
|
||||||
for (x, y), s in other_map.items()}
|
for (x, y), s in other_map.items()}
|
||||||
else:
|
else:
|
||||||
for s in self.subplots:
|
for s in self.subplots:
|
||||||
@@ -693,7 +694,8 @@ class Grid:
|
|||||||
|
|
||||||
self.xweights = new_xweights
|
self.xweights = new_xweights
|
||||||
self.yweights = other.yweights + self_yweights
|
self.yweights = other.yweights + self_yweights
|
||||||
self.map = other_map | {(x, y+len(other.yweights)): s
|
self.map = other_map | {
|
||||||
|
(x, y+len(other.yweights)): s
|
||||||
for (x, y), s in self_map.items()}
|
for (x, y), s in self_map.items()}
|
||||||
|
|
||||||
if dir in ['right', 'left']:
|
if dir in ['right', 'left']:
|
||||||
@@ -782,7 +784,8 @@ class Grid:
|
|||||||
|
|
||||||
self.xweights = self_xweights + other.xweights
|
self.xweights = self_xweights + other.xweights
|
||||||
self.yweights = new_yweights
|
self.yweights = new_yweights
|
||||||
self.map = self_map | {(x+len(self_xweights), y): s
|
self.map = self_map | {
|
||||||
|
(x+len(self_xweights), y): s
|
||||||
for (x, y), s in other_map.items()}
|
for (x, y), s in other_map.items()}
|
||||||
else:
|
else:
|
||||||
for s in self.subplots:
|
for s in self.subplots:
|
||||||
@@ -791,7 +794,8 @@ class Grid:
|
|||||||
|
|
||||||
self.xweights = other.xweights + self_xweights
|
self.xweights = other.xweights + self_xweights
|
||||||
self.yweights = new_yweights
|
self.yweights = new_yweights
|
||||||
self.map = other_map | {(x+len(other.xweights), y): s
|
self.map = other_map | {
|
||||||
|
(x+len(other.xweights), y): s
|
||||||
for (x, y), s in self_map.items()}
|
for (x, y), s in self_map.items()}
|
||||||
|
|
||||||
|
|
||||||
@@ -1012,8 +1016,7 @@ def main(csv_paths, *,
|
|||||||
# if y not specified, guess it's anything not in by/defines/x/renames
|
# if y not specified, guess it's anything not in by/defines/x/renames
|
||||||
all_y_ = all_y
|
all_y_ = all_y
|
||||||
if not all_y:
|
if not all_y:
|
||||||
all_y_ = [
|
all_y_ = [k for k in fields_
|
||||||
k for k in fields_
|
|
||||||
if k not in all_by
|
if k not in all_by
|
||||||
and not any(k == k_ for k_, _ in all_defines)
|
and not any(k == k_ for k_, _ in all_defines)
|
||||||
and not any(k == old_k for _, old_k in all_renames)]
|
and not any(k == old_k for _, old_k in all_renames)]
|
||||||
@@ -1048,7 +1051,8 @@ def main(csv_paths, *,
|
|||||||
else '%s ' % dataline_chars_[name]
|
else '%s ' % dataline_chars_[name]
|
||||||
if line_chars is not None
|
if line_chars is not None
|
||||||
else '',
|
else '',
|
||||||
all_labels_[name] if all_labels
|
all_labels_[name]
|
||||||
|
if all_labels
|
||||||
else ','.join(name))
|
else ','.join(name))
|
||||||
|
|
||||||
if label:
|
if label:
|
||||||
@@ -1092,7 +1096,9 @@ def main(csv_paths, *,
|
|||||||
for i in range(legend_cols)]
|
for i in range(legend_cols)]
|
||||||
if (legend_cols <= 1
|
if (legend_cols <= 1
|
||||||
or sum(legend_widths)+2*(legend_cols-1)
|
or sum(legend_widths)+2*(legend_cols-1)
|
||||||
+ max(sum(s.xmargin[:2]) for s in grid if s.x == 0)
|
+ max(sum(s.xmargin[:2])
|
||||||
|
for s in grid
|
||||||
|
if s.x == 0)
|
||||||
<= width_):
|
<= width_):
|
||||||
break
|
break
|
||||||
legend_cols -= 1
|
legend_cols -= 1
|
||||||
@@ -1105,7 +1111,9 @@ def main(csv_paths, *,
|
|||||||
for i in range(legend_cols)]
|
for i in range(legend_cols)]
|
||||||
if (legend_cols <= 1
|
if (legend_cols <= 1
|
||||||
or sum(legend_widths)+2*(legend_cols-1)
|
or sum(legend_widths)+2*(legend_cols-1)
|
||||||
+ max(sum(s.xmargin[:2]) for s in grid if s.x == 0)
|
+ max(sum(s.xmargin[:2])
|
||||||
|
for s in grid
|
||||||
|
if s.x == 0)
|
||||||
<= width_):
|
<= width_):
|
||||||
break
|
break
|
||||||
legend_cols -= 1
|
legend_cols -= 1
|
||||||
@@ -1125,7 +1133,8 @@ def main(csv_paths, *,
|
|||||||
# but that's the best we can do
|
# but that's the best we can do
|
||||||
for s in grid:
|
for s in grid:
|
||||||
# fit xunits
|
# fit xunits
|
||||||
minwidth = sum(s.xmargin) + max(2,
|
minwidth = sum(s.xmargin) + max(
|
||||||
|
2,
|
||||||
2*((5 if s.x2 else 4)+len(s.xunits))
|
2*((5 if s.x2 else 4)+len(s.xunits))
|
||||||
if s.xticklabels is None
|
if s.xticklabels is None
|
||||||
else sum(len(t) for t in s.xticklabels))
|
else sum(len(t) for t in s.xticklabels))
|
||||||
@@ -1172,7 +1181,8 @@ def main(csv_paths, *,
|
|||||||
for name, dataset in subdatasets.items()
|
for name, dataset in subdatasets.items()
|
||||||
if len(all_x) <= 1
|
if len(all_x) <= 1
|
||||||
or name[-(1 if len(all_y_) <= 1 else 2)] in x_
|
or name[-(1 if len(all_y_) <= 1 else 2)] in x_
|
||||||
if len(all_y_) <= 1 or name[-1] in y_])
|
if len(all_y_) <= 1
|
||||||
|
or name[-1] in y_])
|
||||||
|
|
||||||
# find actual xlim/ylim
|
# find actual xlim/ylim
|
||||||
xlim_ = (
|
xlim_ = (
|
||||||
@@ -1250,7 +1260,8 @@ def main(csv_paths, *,
|
|||||||
if legend_above and legend_:
|
if legend_above and legend_:
|
||||||
for i in range(0, len(legend_), legend_cols):
|
for i in range(0, len(legend_), legend_cols):
|
||||||
f.writeln('%*s%s' % (
|
f.writeln('%*s%s' % (
|
||||||
max(sum(xmargin[:2])
|
max(
|
||||||
|
sum(xmargin[:2])
|
||||||
+ (width_-xmargin[1]
|
+ (width_-xmargin[1]
|
||||||
- (sum(legend_widths)+2*(legend_cols-1)))
|
- (sum(legend_widths)+2*(legend_cols-1)))
|
||||||
// 2,
|
// 2,
|
||||||
@@ -1263,8 +1274,7 @@ def main(csv_paths, *,
|
|||||||
|
|
||||||
for row in range(height_):
|
for row in range(height_):
|
||||||
# draw ylabel?
|
# draw ylabel?
|
||||||
f.write(
|
f.write('%s ' % ''.join(
|
||||||
'%s ' % ''.join(
|
|
||||||
('%*s%s%*s' % (
|
('%*s%s%*s' % (
|
||||||
ymargin[-1], '',
|
ymargin[-1], '',
|
||||||
line.center(height_-sum(ymargin)),
|
line.center(height_-sum(ymargin)),
|
||||||
@@ -1344,7 +1354,8 @@ def main(csv_paths, *,
|
|||||||
else s.xticklabels[0],
|
else s.xticklabels[0],
|
||||||
s.width - (2*((5 if s.x2 else 4)+len(s.xunits))
|
s.width - (2*((5 if s.x2 else 4)+len(s.xunits))
|
||||||
if s.xticklabels is None
|
if s.xticklabels is None
|
||||||
else sum(len(t) for t in s.xticklabels)), '',
|
else sum(len(t)
|
||||||
|
for t in s.xticklabels)), '',
|
||||||
(5 if s.x2 else 4) + len(s.xunits)
|
(5 if s.x2 else 4) + len(s.xunits)
|
||||||
if s.xticklabels is None
|
if s.xticklabels is None
|
||||||
else len(s.xticklabels[1]),
|
else len(s.xticklabels[1]),
|
||||||
@@ -1384,17 +1395,16 @@ def main(csv_paths, *,
|
|||||||
if legend_below and legend_:
|
if legend_below and legend_:
|
||||||
for i in range(0, len(legend_), legend_cols):
|
for i in range(0, len(legend_), legend_cols):
|
||||||
f.writeln('%*s%s' % (
|
f.writeln('%*s%s' % (
|
||||||
max(sum(xmargin[:2])
|
max(
|
||||||
|
sum(xmargin[:2])
|
||||||
+ (width_-xmargin[1]
|
+ (width_-xmargin[1]
|
||||||
- (sum(legend_widths)+2*(legend_cols-1)))
|
- (sum(legend_widths)+2*(legend_cols-1)))
|
||||||
// 2,
|
// 2,
|
||||||
0), '',
|
0), '',
|
||||||
' '.join('%s%s%s' % (
|
' '.join('%s%s%s' % (
|
||||||
'\x1b[%sm' % legend_[i+j][1]
|
'\x1b[%sm' % legend_[i+j][1] if color else '',
|
||||||
if color else '',
|
|
||||||
'%-*s' % (legend_widths[j], legend_[i+j][0]),
|
'%-*s' % (legend_widths[j], legend_[i+j][0]),
|
||||||
'\x1b[m'
|
'\x1b[m' if color else '')
|
||||||
if color else '')
|
|
||||||
for j in range(min(legend_cols, len(legend_)-i)))))
|
for j in range(min(legend_cols, len(legend_)-i)))))
|
||||||
|
|
||||||
|
|
||||||
@@ -1452,7 +1462,8 @@ if __name__ == "__main__":
|
|||||||
tuple(v.strip() for v in vs.split(','))
|
tuple(v.strip() for v in vs.split(','))
|
||||||
if vs is not None else ())
|
if vs is not None else ())
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
help="Group by this field. Can rename fields with new_name=old_name.")
|
help="Group by this field. Can rename fields with "
|
||||||
|
"new_name=old_name.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-x',
|
'-x',
|
||||||
action='append',
|
action='append',
|
||||||
@@ -1483,8 +1494,8 @@ if __name__ == "__main__":
|
|||||||
{v.strip() for v in vs.split(',')})
|
{v.strip() for v in vs.split(',')})
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
action='append',
|
action='append',
|
||||||
help="Only include results where this field is this value. May include "
|
help="Only include results where this field is this value. May "
|
||||||
"comma-separated options.")
|
"include comma-separated options.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-L', '--label',
|
'-L', '--label',
|
||||||
action='append',
|
action='append',
|
||||||
@@ -1493,9 +1504,9 @@ if __name__ == "__main__":
|
|||||||
re.sub(r'\\([=\\])', r'\1', k.strip()),
|
re.sub(r'\\([=\\])', r'\1', k.strip()),
|
||||||
tuple(v.strip() for v in vs.split(',')))
|
tuple(v.strip() for v in vs.split(',')))
|
||||||
)(*re.split(r'(?<!\\)=', x, 1)),
|
)(*re.split(r'(?<!\\)=', x, 1)),
|
||||||
help="Use this label for a given group, where a group is roughly the "
|
help="Use this label for a given group, where a group is roughly "
|
||||||
"comma-separated values in the -b/--by, -x, and -y fields. Also "
|
"the comma-separated values in the -b/--by, -x, and -y "
|
||||||
"provides an ordering. Accepts escaped equals.")
|
"fields. Also provides an ordering. Accepts escaped equals.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--color',
|
'--color',
|
||||||
choices=['never', 'always', 'auto'],
|
choices=['never', 'always', 'auto'],
|
||||||
@@ -1504,8 +1515,8 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-⣿', '--braille',
|
'-⣿', '--braille',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help="Use 2x4 unicode braille characters. Note that braille characters "
|
help="Use 2x4 unicode braille characters. Note that braille "
|
||||||
"sometimes suffer from inconsistent widths.")
|
"characters sometimes suffer from inconsistent widths.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-.', '--points',
|
'-.', '--points',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -1626,10 +1637,11 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--subplot-above',
|
'--subplot-above',
|
||||||
action=AppendSubplot,
|
action=AppendSubplot,
|
||||||
help="Add subplot above with the same dataset. Takes an arg string to "
|
help="Add subplot above with the same dataset. Takes an arg "
|
||||||
"control the subplot which supports most (but not all) of the "
|
"string to control the subplot which supports most (but "
|
||||||
"parameters listed here. The relative dimensions of the subplot "
|
"not all) of the parameters listed here. The relative "
|
||||||
"can be controlled with -W/-H which now take a percentage.")
|
"dimensions of the subplot can be controlled with -W/-H "
|
||||||
|
"which now take a percentage.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--subplot-below',
|
'--subplot-below',
|
||||||
action=AppendSubplot,
|
action=AppendSubplot,
|
||||||
@@ -1661,8 +1673,8 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-s', '--sleep',
|
'-s', '--sleep',
|
||||||
type=float,
|
type=float,
|
||||||
help="Time in seconds to sleep between redraws when running with -k. "
|
help="Time in seconds to sleep between redraws when running "
|
||||||
"Defaults to 0.01.")
|
"with -k. Defaults to 0.01.")
|
||||||
|
|
||||||
def dictify(ns):
|
def dictify(ns):
|
||||||
if hasattr(ns, 'subplots'):
|
if hasattr(ns, 'subplots'):
|
||||||
|
|||||||
+26
-19
@@ -25,6 +25,7 @@ import time
|
|||||||
import matplotlib as mpl
|
import matplotlib as mpl
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
|
||||||
# some nicer colors borrowed from Seaborn
|
# some nicer colors borrowed from Seaborn
|
||||||
# note these include a non-opaque alpha
|
# note these include a non-opaque alpha
|
||||||
COLORS = [
|
COLORS = [
|
||||||
@@ -148,8 +149,8 @@ class AutoMultipleLocator(mpl.ticker.MultipleLocator):
|
|||||||
nbins = np.clip(self.axis.get_tick_space(), 1, 9)
|
nbins = np.clip(self.axis.get_tick_space(), 1, 9)
|
||||||
|
|
||||||
# find the best power, use this as our locator's actual base
|
# find the best power, use this as our locator's actual base
|
||||||
scale = self.base
|
scale = (self.base
|
||||||
** (mt.ceil(mt.log((vmax-vmin) / (nbins+1), self.base)))
|
** (mt.ceil(mt.log((vmax-vmin) / (nbins+1), self.base))))
|
||||||
self.set_params(scale)
|
self.set_params(scale)
|
||||||
|
|
||||||
return super().__call__()
|
return super().__call__()
|
||||||
@@ -423,7 +424,8 @@ class Grid:
|
|||||||
|
|
||||||
self.xweights = new_xweights
|
self.xweights = new_xweights
|
||||||
self.yweights = self_yweights + other.yweights
|
self.yweights = self_yweights + other.yweights
|
||||||
self.map = self_map | {(x, y+len(self_yweights)): s
|
self.map = self_map | {
|
||||||
|
(x, y+len(self_yweights)): s
|
||||||
for (x, y), s in other_map.items()}
|
for (x, y), s in other_map.items()}
|
||||||
else:
|
else:
|
||||||
for s in self.subplots:
|
for s in self.subplots:
|
||||||
@@ -432,7 +434,8 @@ class Grid:
|
|||||||
|
|
||||||
self.xweights = new_xweights
|
self.xweights = new_xweights
|
||||||
self.yweights = other.yweights + self_yweights
|
self.yweights = other.yweights + self_yweights
|
||||||
self.map = other_map | {(x, y+len(other.yweights)): s
|
self.map = other_map | {
|
||||||
|
(x, y+len(other.yweights)): s
|
||||||
for (x, y), s in self_map.items()}
|
for (x, y), s in self_map.items()}
|
||||||
|
|
||||||
if dir in ['right', 'left']:
|
if dir in ['right', 'left']:
|
||||||
@@ -521,7 +524,8 @@ class Grid:
|
|||||||
|
|
||||||
self.xweights = self_xweights + other.xweights
|
self.xweights = self_xweights + other.xweights
|
||||||
self.yweights = new_yweights
|
self.yweights = new_yweights
|
||||||
self.map = self_map | {(x+len(self_xweights), y): s
|
self.map = self_map | {
|
||||||
|
(x+len(self_xweights), y): s
|
||||||
for (x, y), s in other_map.items()}
|
for (x, y), s in other_map.items()}
|
||||||
else:
|
else:
|
||||||
for s in self.subplots:
|
for s in self.subplots:
|
||||||
@@ -530,7 +534,8 @@ class Grid:
|
|||||||
|
|
||||||
self.xweights = other.xweights + self_xweights
|
self.xweights = other.xweights + self_xweights
|
||||||
self.yweights = new_yweights
|
self.yweights = new_yweights
|
||||||
self.map = other_map | {(x+len(other.xweights), y): s
|
self.map = other_map | {
|
||||||
|
(x+len(other.xweights), y): s
|
||||||
for (x, y), s in self_map.items()}
|
for (x, y), s in self_map.items()}
|
||||||
|
|
||||||
|
|
||||||
@@ -743,8 +748,7 @@ def main(csv_paths, output, *,
|
|||||||
|
|
||||||
# if y not specified, guess it's anything not in by/defines/x/renames
|
# if y not specified, guess it's anything not in by/defines/x/renames
|
||||||
if not all_y:
|
if not all_y:
|
||||||
all_y = [
|
all_y = [k for k in fields_
|
||||||
k for k in fields_
|
|
||||||
if k not in all_by
|
if k not in all_by
|
||||||
and not any(k == k_ for k_, _ in all_defines)
|
and not any(k == k_ for k_, _ in all_defines)
|
||||||
and not any(k == old_k for _, old_k in all_renames)]
|
and not any(k == old_k for _, old_k in all_renames)]
|
||||||
@@ -767,7 +771,8 @@ def main(csv_paths, output, *,
|
|||||||
grid = Grid.fromargs(**subplot, subplots=subplots)
|
grid = Grid.fromargs(**subplot, subplots=subplots)
|
||||||
|
|
||||||
# create a matplotlib plot
|
# create a matplotlib plot
|
||||||
fig = plt.figure(figsize=(
|
fig = plt.figure(
|
||||||
|
figsize=(
|
||||||
width/plt.rcParams['figure.dpi'],
|
width/plt.rcParams['figure.dpi'],
|
||||||
height/plt.rcParams['figure.dpi']),
|
height/plt.rcParams['figure.dpi']),
|
||||||
layout='constrained',
|
layout='constrained',
|
||||||
@@ -1103,7 +1108,8 @@ if __name__ == "__main__":
|
|||||||
tuple(v.strip() for v in vs.split(','))
|
tuple(v.strip() for v in vs.split(','))
|
||||||
if vs is not None else ())
|
if vs is not None else ())
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
help="Group by this field. Can rename fields with new_name=old_name.")
|
help="Group by this field. Can rename fields with "
|
||||||
|
"new_name=old_name.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-x',
|
'-x',
|
||||||
action='append',
|
action='append',
|
||||||
@@ -1134,8 +1140,8 @@ if __name__ == "__main__":
|
|||||||
{v.strip() for v in vs.split(',')})
|
{v.strip() for v in vs.split(',')})
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
action='append',
|
action='append',
|
||||||
help="Only include results where this field is this value. May include "
|
help="Only include results where this field is this value. May "
|
||||||
"comma-separated options.")
|
"include comma-separated options.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-L', '--label',
|
'-L', '--label',
|
||||||
action='append',
|
action='append',
|
||||||
@@ -1144,9 +1150,9 @@ if __name__ == "__main__":
|
|||||||
re.sub(r'\\([=\\])', r'\1', k.strip()),
|
re.sub(r'\\([=\\])', r'\1', k.strip()),
|
||||||
tuple(v.strip() for v in vs.split(',')))
|
tuple(v.strip() for v in vs.split(',')))
|
||||||
)(*re.split(r'(?<!\\)=', x, 1)),
|
)(*re.split(r'(?<!\\)=', x, 1)),
|
||||||
help="Use this label for a given group, where a group is roughly the "
|
help="Use this label for a given group, where a group is roughly "
|
||||||
"comma-separated values in the -b/--by, -x, and -y fields. Also "
|
"the comma-separated values in the -b/--by, -x, and -y "
|
||||||
"provides an ordering. Accepts escaped equals.")
|
"fields. Also provides an ordering. Accepts escaped equals.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-.', '--points',
|
'-.', '--points',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -1302,10 +1308,11 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--subplot-above',
|
'--subplot-above',
|
||||||
action=AppendSubplot,
|
action=AppendSubplot,
|
||||||
help="Add subplot above with the same dataset. Takes an arg string to "
|
help="Add subplot above with the same dataset. Takes an arg "
|
||||||
"control the subplot which supports most (but not all) of the "
|
"string to control the subplot which supports most (but "
|
||||||
"parameters listed here. The relative dimensions of the subplot "
|
"not all) of the parameters listed here. The relative "
|
||||||
"can be controlled with -W/-H which now take a percentage.")
|
"dimensions of the subplot can be controlled with -W/-H "
|
||||||
|
"which now take a percentage.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--subplot-below',
|
'--subplot-below',
|
||||||
action=AppendSubplot,
|
action=AppendSubplot,
|
||||||
|
|||||||
+19
-22
@@ -13,6 +13,7 @@
|
|||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
LIMIT = 16
|
LIMIT = 16
|
||||||
|
|
||||||
CMP = {
|
CMP = {
|
||||||
@@ -133,15 +134,14 @@ def write_header(f, limit=LIMIT):
|
|||||||
|
|
||||||
# write assert macros
|
# write assert macros
|
||||||
for op, cmp in sorted(CMP.items()):
|
for op, cmp in sorted(CMP.items()):
|
||||||
f.writeln("#define __PRETTY_ASSERT_BOOL_%s(lh, rh) do { \\"
|
f.writeln("#define __PRETTY_ASSERT_BOOL_%s(lh, rh) do { \\" % (
|
||||||
% cmp.upper())
|
cmp.upper()))
|
||||||
f.writeln(" bool _lh = !!(lh); \\")
|
f.writeln(" bool _lh = !!(lh); \\")
|
||||||
f.writeln(" bool _rh = !!(rh); \\")
|
f.writeln(" bool _rh = !!(rh); \\")
|
||||||
f.writeln(" if (!(_lh %s _rh)) { \\" % op)
|
f.writeln(" if (!(_lh %s _rh)) { \\" % op)
|
||||||
f.writeln(" __pretty_assert_print( \\")
|
f.writeln(" __pretty_assert_print( \\")
|
||||||
f.writeln(" __FILE__, __LINE__, \\")
|
f.writeln(" __FILE__, __LINE__, \\")
|
||||||
f.writeln(" __pretty_assert_bool, \"%s\", \\"
|
f.writeln(" __pretty_assert_bool, \"%s\", \\" % cmp)
|
||||||
% cmp)
|
|
||||||
f.writeln(" &_lh, 0, \\")
|
f.writeln(" &_lh, 0, \\")
|
||||||
f.writeln(" &_rh, 0); \\")
|
f.writeln(" &_rh, 0); \\")
|
||||||
f.writeln(" __builtin_trap(); \\")
|
f.writeln(" __builtin_trap(); \\")
|
||||||
@@ -149,15 +149,14 @@ def write_header(f, limit=LIMIT):
|
|||||||
f.writeln("} while (0)")
|
f.writeln("} while (0)")
|
||||||
f.writeln()
|
f.writeln()
|
||||||
for op, cmp in sorted(CMP.items()):
|
for op, cmp in sorted(CMP.items()):
|
||||||
f.writeln("#define __PRETTY_ASSERT_INT_%s(lh, rh) do { \\"
|
f.writeln("#define __PRETTY_ASSERT_INT_%s(lh, rh) do { \\" % (
|
||||||
% cmp.upper())
|
cmp.upper()))
|
||||||
f.writeln(" __typeof__(rh) _lh = lh; \\")
|
f.writeln(" __typeof__(rh) _lh = lh; \\")
|
||||||
f.writeln(" __typeof__(rh) _rh = rh; \\")
|
f.writeln(" __typeof__(rh) _rh = rh; \\")
|
||||||
f.writeln(" if (!(_lh %s _rh)) { \\" % op)
|
f.writeln(" if (!(_lh %s _rh)) { \\" % op)
|
||||||
f.writeln(" __pretty_assert_print( \\")
|
f.writeln(" __pretty_assert_print( \\")
|
||||||
f.writeln(" __FILE__, __LINE__, \\")
|
f.writeln(" __FILE__, __LINE__, \\")
|
||||||
f.writeln(" __pretty_assert_int, \"%s\", \\"
|
f.writeln(" __pretty_assert_int, \"%s\", \\" % cmp)
|
||||||
% cmp)
|
|
||||||
f.writeln(" &(intmax_t){(intmax_t)_lh}, 0, \\")
|
f.writeln(" &(intmax_t){(intmax_t)_lh}, 0, \\")
|
||||||
f.writeln(" &(intmax_t){(intmax_t)_rh}, 0); \\")
|
f.writeln(" &(intmax_t){(intmax_t)_rh}, 0); \\")
|
||||||
f.writeln(" __builtin_trap(); \\")
|
f.writeln(" __builtin_trap(); \\")
|
||||||
@@ -165,15 +164,14 @@ def write_header(f, limit=LIMIT):
|
|||||||
f.writeln("} while (0)")
|
f.writeln("} while (0)")
|
||||||
f.writeln()
|
f.writeln()
|
||||||
for op, cmp in sorted(CMP.items()):
|
for op, cmp in sorted(CMP.items()):
|
||||||
f.writeln("#define __PRETTY_ASSERT_MEM_%s(lh, rh, size) do { \\"
|
f.writeln("#define __PRETTY_ASSERT_MEM_%s(lh, rh, size) do { \\" % (
|
||||||
% cmp.upper())
|
cmp.upper()))
|
||||||
f.writeln(" const void *_lh = lh; \\")
|
f.writeln(" const void *_lh = lh; \\")
|
||||||
f.writeln(" const void *_rh = rh; \\")
|
f.writeln(" const void *_rh = rh; \\")
|
||||||
f.writeln(" if (!(memcmp(_lh, _rh, size) %s 0)) { \\" % op)
|
f.writeln(" if (!(memcmp(_lh, _rh, size) %s 0)) { \\" % op)
|
||||||
f.writeln(" __pretty_assert_print( \\")
|
f.writeln(" __pretty_assert_print( \\")
|
||||||
f.writeln(" __FILE__, __LINE__, \\")
|
f.writeln(" __FILE__, __LINE__, \\")
|
||||||
f.writeln(" __pretty_assert_mem, \"%s\", \\"
|
f.writeln(" __pretty_assert_mem, \"%s\", \\" % cmp)
|
||||||
% cmp)
|
|
||||||
f.writeln(" _lh, size, \\")
|
f.writeln(" _lh, size, \\")
|
||||||
f.writeln(" _rh, size); \\")
|
f.writeln(" _rh, size); \\")
|
||||||
f.writeln(" __builtin_trap(); \\")
|
f.writeln(" __builtin_trap(); \\")
|
||||||
@@ -181,15 +179,14 @@ def write_header(f, limit=LIMIT):
|
|||||||
f.writeln("} while (0)")
|
f.writeln("} while (0)")
|
||||||
f.writeln()
|
f.writeln()
|
||||||
for op, cmp in sorted(CMP.items()):
|
for op, cmp in sorted(CMP.items()):
|
||||||
f.writeln("#define __PRETTY_ASSERT_STR_%s(lh, rh) do { \\"
|
f.writeln("#define __PRETTY_ASSERT_STR_%s(lh, rh) do { \\" % (
|
||||||
% cmp.upper())
|
cmp.upper()))
|
||||||
f.writeln(" const char *_lh = lh; \\")
|
f.writeln(" const char *_lh = lh; \\")
|
||||||
f.writeln(" const char *_rh = rh; \\")
|
f.writeln(" const char *_rh = rh; \\")
|
||||||
f.writeln(" if (!(strcmp(_lh, _rh) %s 0)) { \\" % op)
|
f.writeln(" if (!(strcmp(_lh, _rh) %s 0)) { \\" % op)
|
||||||
f.writeln(" __pretty_assert_print( \\")
|
f.writeln(" __pretty_assert_print( \\")
|
||||||
f.writeln(" __FILE__, __LINE__, \\")
|
f.writeln(" __FILE__, __LINE__, \\")
|
||||||
f.writeln(" __pretty_assert_str, \"%s\", \\"
|
f.writeln(" __pretty_assert_str, \"%s\", \\" % cmp)
|
||||||
% cmp)
|
|
||||||
f.writeln(" _lh, strlen(_lh), \\")
|
f.writeln(" _lh, strlen(_lh), \\")
|
||||||
f.writeln(" _rh, strlen(_rh)); \\")
|
f.writeln(" _rh, strlen(_rh)); \\")
|
||||||
f.writeln(" __builtin_trap(); \\")
|
f.writeln(" __builtin_trap(); \\")
|
||||||
@@ -206,11 +203,11 @@ def write_header(f, limit=LIMIT):
|
|||||||
|
|
||||||
def mkassert(type, cmp, lh, rh, size=None):
|
def mkassert(type, cmp, lh, rh, size=None):
|
||||||
if size is not None:
|
if size is not None:
|
||||||
return ("__PRETTY_ASSERT_%s_%s(%s, %s, %s)"
|
return ("__PRETTY_ASSERT_%s_%s(%s, %s, %s)" % (
|
||||||
% (type.upper(), cmp.upper(), lh, rh, size))
|
type.upper(), cmp.upper(), lh, rh, size))
|
||||||
else:
|
else:
|
||||||
return ("__PRETTY_ASSERT_%s_%s(%s, %s)"
|
return ("__PRETTY_ASSERT_%s_%s(%s, %s)" % (
|
||||||
% (type.upper(), cmp.upper(), lh, rh))
|
type.upper(), cmp.upper(), lh, rh))
|
||||||
|
|
||||||
def mkunreachable():
|
def mkunreachable():
|
||||||
return "__PRETTY_ASSERT_UNREACHABLE()"
|
return "__PRETTY_ASSERT_UNREACHABLE()"
|
||||||
@@ -542,8 +539,8 @@ if __name__ == "__main__":
|
|||||||
'-l', '--limit',
|
'-l', '--limit',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
default=LIMIT,
|
default=LIMIT,
|
||||||
help="Maximum number of characters to display in strcmp and memcmp. "
|
help="Maximum number of characters to display in strcmp and "
|
||||||
"Defaults to %r." % LIMIT)
|
"memcmp. Defaults to %r." % LIMIT)
|
||||||
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}))
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import subprocess as sp
|
import subprocess as sp
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
def main(args):
|
||||||
with open(args.disk, 'rb') as f:
|
with open(args.disk, 'rb') as f:
|
||||||
f.seek(args.block * args.block_size)
|
f.seek(args.block * args.block_size)
|
||||||
@@ -12,6 +13,7 @@ def main(args):
|
|||||||
print("%-8s %-s" % ('off', 'data'))
|
print("%-8s %-s" % ('off', 'data'))
|
||||||
return sp.run(['xxd', '-g1', '-'], input=block).returncode
|
return sp.run(['xxd', '-g1', '-'], input=block).returncode
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
+9
-6
@@ -5,6 +5,7 @@ import binascii
|
|||||||
import sys
|
import sys
|
||||||
import itertools as it
|
import itertools as it
|
||||||
|
|
||||||
|
|
||||||
TAG_TYPES = {
|
TAG_TYPES = {
|
||||||
'splice': (0x700, 0x400),
|
'splice': (0x700, 0x400),
|
||||||
'create': (0x7ff, 0x401),
|
'create': (0x7ff, 0x401),
|
||||||
@@ -104,8 +105,9 @@ class Tag:
|
|||||||
try:
|
try:
|
||||||
if ' ' in type:
|
if ' ' in type:
|
||||||
type1, type3 = type.split()
|
type1, type3 = type.split()
|
||||||
return (self.is_(type1) and
|
return (self.is_(type1)
|
||||||
(self.type & ~TAG_TYPES[type1][0]) == int(type3, 0))
|
and (self.type & ~TAG_TYPES[type1][0])
|
||||||
|
== int(type3, 0))
|
||||||
|
|
||||||
return self.type == int(type, 0)
|
return self.type == int(type, 0)
|
||||||
|
|
||||||
@@ -286,16 +288,16 @@ class MetadataPair:
|
|||||||
|
|
||||||
gdiff = 0
|
gdiff = 0
|
||||||
for tag in reversed(self.log):
|
for tag in reversed(self.log):
|
||||||
if (gmask.id != 0 and tag.is_('splice') and
|
if (gmask.id != 0 and tag.is_('splice')
|
||||||
tag.id <= gtag.id - gdiff):
|
and tag.id <= gtag.id - gdiff):
|
||||||
if tag.is_('create') and tag.id == gtag.id - gdiff:
|
if tag.is_('create') and tag.id == gtag.id - gdiff:
|
||||||
# creation point
|
# creation point
|
||||||
break
|
break
|
||||||
|
|
||||||
gdiff += tag.schunk
|
gdiff += tag.schunk
|
||||||
|
|
||||||
if ((int(gmask) & int(tag)) ==
|
if ((int(gmask) & int(tag))
|
||||||
(int(gmask) & int(gtag.chid(gtag.id - gdiff)))):
|
== (int(gmask) & int(gtag.chid(gtag.id - gdiff)))):
|
||||||
if tag.size == 0x3ff:
|
if tag.size == 0x3ff:
|
||||||
# deleted
|
# deleted
|
||||||
break
|
break
|
||||||
@@ -377,6 +379,7 @@ def main(args):
|
|||||||
|
|
||||||
return 0 if mdir else 1
|
return 0 if mdir else 1
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
+10
-4
@@ -7,6 +7,7 @@ import io
|
|||||||
import itertools as it
|
import itertools as it
|
||||||
from readmdir import Tag, MetadataPair
|
from readmdir import Tag, MetadataPair
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
def main(args):
|
||||||
superblock = None
|
superblock = None
|
||||||
gstate = b'\0\0\0\0\0\0\0\0\0\0\0\0'
|
gstate = b'\0\0\0\0\0\0\0\0\0\0\0\0'
|
||||||
@@ -103,10 +104,13 @@ def main(args):
|
|||||||
version = ('?', '?')
|
version = ('?', '?')
|
||||||
if superblock:
|
if superblock:
|
||||||
version = tuple(reversed(
|
version = tuple(reversed(
|
||||||
struct.unpack('<HH', superblock[1].data[0:4].ljust(4, b'\xff'))))
|
struct.unpack('<HH',
|
||||||
print("%-47s%s" % ("littlefs v%s.%s" % version,
|
superblock[1].data[0:4].ljust(4, b'\xff'))))
|
||||||
|
print("%-47s%s" % (
|
||||||
|
"littlefs v%s.%s" % version,
|
||||||
"data (truncated, if it fits)"
|
"data (truncated, if it fits)"
|
||||||
if not any([args.no_truncate, args.log, args.all]) else ""))
|
if not any([args.no_truncate, args.log, args.all])
|
||||||
|
else ""))
|
||||||
|
|
||||||
# print gstate
|
# print gstate
|
||||||
print("gstate 0x%s" % ''.join('%02x' % c for c in gstate))
|
print("gstate 0x%s" % ''.join('%02x' % c for c in gstate))
|
||||||
@@ -159,11 +163,13 @@ def main(args):
|
|||||||
|
|
||||||
return errcode
|
return errcode
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Dump semantic info about the metadata tree in littlefs")
|
description="Dump semantic info about the metadata tree in "
|
||||||
|
"littlefs")
|
||||||
parser.add_argument('disk',
|
parser.add_argument('disk',
|
||||||
help="File representing the block device.")
|
help="File representing the block device.")
|
||||||
parser.add_argument('block_size', type=lambda x: int(x, 0),
|
parser.add_argument('block_size', type=lambda x: int(x, 0),
|
||||||
|
|||||||
+33
-28
@@ -18,7 +18,6 @@ import os
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# integer fields
|
# integer fields
|
||||||
class RInt(co.namedtuple('RInt', 'x')):
|
class RInt(co.namedtuple('RInt', 'x')):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
@@ -179,8 +178,8 @@ def collect(ci_paths, *,
|
|||||||
if (not args.get('quiet')
|
if (not args.get('quiet')
|
||||||
and 'static' not in type
|
and 'static' not in type
|
||||||
and 'bounded' not in type):
|
and 'bounded' not in type):
|
||||||
print("warning: "
|
print("warning: found non-static stack "
|
||||||
"found non-static stack for %s (%s, %s)" % (
|
"for %s (%s, %s)" % (
|
||||||
function, type, size))
|
function, type, size))
|
||||||
_, _, _, targets = callgraph[info['title']]
|
_, _, _, targets = callgraph[info['title']]
|
||||||
callgraph[info['title']] = (
|
callgraph[info['title']] = (
|
||||||
@@ -199,8 +198,7 @@ def collect(ci_paths, *,
|
|||||||
continue
|
continue
|
||||||
# ignore filtered sources
|
# ignore filtered sources
|
||||||
if sources is not None:
|
if sources is not None:
|
||||||
if not any(
|
if not any(os.path.abspath(s_file) == os.path.abspath(s)
|
||||||
os.path.abspath(s_file) == os.path.abspath(s)
|
|
||||||
for s in sources):
|
for s in sources):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@@ -339,12 +337,13 @@ def table(Result, results, diff_results=None, *,
|
|||||||
|
|
||||||
r = max(results_,
|
r = max(results_,
|
||||||
key=lambda r: tuple(
|
key=lambda r: tuple(
|
||||||
tuple(
|
tuple((getattr(r, k),)
|
||||||
(getattr(r, k),)
|
|
||||||
if getattr(r, k, None) is not None
|
if getattr(r, k, None) is not None
|
||||||
else ()
|
else ()
|
||||||
for k in ([k] if k else [
|
for k in (
|
||||||
k for k in Result._sort if k in fields])
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])
|
||||||
if k in fields)
|
if k in fields)
|
||||||
for k in it.chain(hot, [None])))
|
for k in it.chain(hot, [None])))
|
||||||
|
|
||||||
@@ -378,7 +377,8 @@ def table(Result, results, diff_results=None, *,
|
|||||||
# sort again, now with diff info, note that python's sort is stable
|
# sort again, now with diff info, note that python's sort is stable
|
||||||
names.sort()
|
names.sort()
|
||||||
if diff_results is not None:
|
if diff_results is not None:
|
||||||
names.sort(key=lambda n: tuple(
|
names.sort(
|
||||||
|
key=lambda n: tuple(
|
||||||
types[k].ratio(
|
types[k].ratio(
|
||||||
getattr(table.get(n), k, None),
|
getattr(table.get(n), k, None),
|
||||||
getattr(diff_table.get(n), k, None))
|
getattr(diff_table.get(n), k, None))
|
||||||
@@ -389,9 +389,12 @@ def table(Result, results, diff_results=None, *,
|
|||||||
names.sort(
|
names.sort(
|
||||||
key=lambda n: tuple(
|
key=lambda n: tuple(
|
||||||
(getattr(table[n], k),)
|
(getattr(table[n], k),)
|
||||||
if getattr(table.get(n), k, None) is not None else ()
|
if getattr(table.get(n), k, None) is not None
|
||||||
for k in ([k] if k else [
|
else ()
|
||||||
k for k in Result._sort if k in fields])),
|
for k in (
|
||||||
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])),
|
||||||
reverse=reverse ^ (not k or k in Result._fields))
|
reverse=reverse ^ (not k or k in Result._fields))
|
||||||
|
|
||||||
|
|
||||||
@@ -399,8 +402,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
# header
|
# header
|
||||||
header = [
|
header = ['%s%s' % (
|
||||||
'%s%s' % (
|
|
||||||
','.join(by),
|
','.join(by),
|
||||||
' (%d added, %d removed)' % (
|
' (%d added, %d removed)' % (
|
||||||
sum(1 for n in table if n not in diff_table),
|
sum(1 for n in table if n not in diff_table),
|
||||||
@@ -484,10 +486,13 @@ def table(Result, results, diff_results=None, *,
|
|||||||
names_.sort(
|
names_.sort(
|
||||||
key=lambda n: tuple(
|
key=lambda n: tuple(
|
||||||
(getattr(table_[n], k),)
|
(getattr(table_[n], k),)
|
||||||
if getattr(table_.get(n), k, None) is not None
|
if getattr(table_.get(n), k, None)
|
||||||
|
is not None
|
||||||
else ()
|
else ()
|
||||||
for k in ([k] if k else [
|
for k in (
|
||||||
k for k in Result._sort if k in fields])),
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])),
|
||||||
reverse=reverse ^ (not k or k in Result._fields))
|
reverse=reverse ^ (not k or k in Result._fields))
|
||||||
|
|
||||||
for i, name in enumerate(names_):
|
for i, name in enumerate(names_):
|
||||||
@@ -509,8 +514,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
|
|
||||||
# recurse?
|
# recurse?
|
||||||
if depth_ > 1:
|
if depth_ > 1:
|
||||||
recurse(
|
recurse(r.children,
|
||||||
r.children,
|
|
||||||
depth_-1,
|
depth_-1,
|
||||||
seen | {name},
|
seen | {name},
|
||||||
(prefixes[2+is_last] + "|-> ",
|
(prefixes[2+is_last] + "|-> ",
|
||||||
@@ -530,8 +534,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
|
|
||||||
# recursive entries
|
# recursive entries
|
||||||
if name in table and depth > 1:
|
if name in table and depth > 1:
|
||||||
recurse(
|
recurse(table[name].children,
|
||||||
table[name].children,
|
|
||||||
depth-1,
|
depth-1,
|
||||||
{name},
|
{name},
|
||||||
("|-> ",
|
("|-> ",
|
||||||
@@ -626,14 +629,16 @@ def main(ci_paths,
|
|||||||
writer = csv.DictWriter(f,
|
writer = csv.DictWriter(f,
|
||||||
(by if by is not None else StackResult._by)
|
(by if by is not None else StackResult._by)
|
||||||
+ [k for k in (
|
+ [k for k in (
|
||||||
fields if fields is not None else StackResult._fields)])
|
fields if fields is not None
|
||||||
|
else StackResult._fields)])
|
||||||
writer.writeheader()
|
writer.writeheader()
|
||||||
for r in results:
|
for r in results:
|
||||||
writer.writerow(
|
writer.writerow(
|
||||||
{k: getattr(r, k) for k in (
|
{k: getattr(r, k) for k in (
|
||||||
by if by is not None else StackResult._by)}
|
by if by is not None else StackResult._by)}
|
||||||
| {k: getattr(r, k) for k in (
|
| {k: getattr(r, k) for k in (
|
||||||
fields if fields is not None else StackResult._fields)})
|
fields if fields is not None
|
||||||
|
else StackResult._fields)})
|
||||||
|
|
||||||
# find previous results?
|
# find previous results?
|
||||||
if args.get('diff'):
|
if args.get('diff'):
|
||||||
@@ -757,8 +762,8 @@ if __name__ == "__main__":
|
|||||||
'-F', '--source',
|
'-F', '--source',
|
||||||
dest='sources',
|
dest='sources',
|
||||||
action='append',
|
action='append',
|
||||||
help="Only consider definitions in this file. Defaults to anything "
|
help="Only consider definitions in this file. Defaults to "
|
||||||
"in the current directory.")
|
"anything in the current directory.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--everything',
|
'--everything',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -768,8 +773,8 @@ if __name__ == "__main__":
|
|||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
const=0,
|
const=0,
|
||||||
help="Depth of function calls to show. 0 shows all calls unless we "
|
help="Depth of function calls to show. 0 shows all calls unless "
|
||||||
"find a cycle. Defaults to 0.")
|
"we find a cycle. Defaults to 0.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-t', '--hot',
|
'-t', '--hot',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
|
|||||||
+19
-14
@@ -23,7 +23,6 @@ import subprocess as sp
|
|||||||
OBJDUMP_PATH = ['objdump']
|
OBJDUMP_PATH = ['objdump']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# integer fields
|
# integer fields
|
||||||
class RInt(co.namedtuple('RInt', 'x')):
|
class RInt(co.namedtuple('RInt', 'x')):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
@@ -100,7 +99,9 @@ class RInt(co.namedtuple('RInt', 'x')):
|
|||||||
return self.__class__(self.x * other.x)
|
return self.__class__(self.x * other.x)
|
||||||
|
|
||||||
# struct size results
|
# struct size results
|
||||||
class StructResult(co.namedtuple('StructResult', ['file', 'struct', 'size'])):
|
class StructResult(co.namedtuple('StructResult', [
|
||||||
|
'file', 'struct',
|
||||||
|
'size'])):
|
||||||
_by = ['file', 'struct']
|
_by = ['file', 'struct']
|
||||||
_fields = ['size']
|
_fields = ['size']
|
||||||
_sort = ['size']
|
_sort = ['size']
|
||||||
@@ -233,8 +234,7 @@ def collect(obj_paths, *,
|
|||||||
for r in results_:
|
for r in results_:
|
||||||
# ignore filtered sources
|
# ignore filtered sources
|
||||||
if sources is not None:
|
if sources is not None:
|
||||||
if not any(
|
if not any(os.path.abspath(r.file) == os.path.abspath(s)
|
||||||
os.path.abspath(r.file) == os.path.abspath(s)
|
|
||||||
for s in sources):
|
for s in sources):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
@@ -335,7 +335,8 @@ def table(Result, results, diff_results=None, *,
|
|||||||
# sort again, now with diff info, note that python's sort is stable
|
# sort again, now with diff info, note that python's sort is stable
|
||||||
names.sort()
|
names.sort()
|
||||||
if diff_results is not None:
|
if diff_results is not None:
|
||||||
names.sort(key=lambda n: tuple(
|
names.sort(
|
||||||
|
key=lambda n: tuple(
|
||||||
types[k].ratio(
|
types[k].ratio(
|
||||||
getattr(table.get(n), k, None),
|
getattr(table.get(n), k, None),
|
||||||
getattr(diff_table.get(n), k, None))
|
getattr(diff_table.get(n), k, None))
|
||||||
@@ -346,9 +347,12 @@ def table(Result, results, diff_results=None, *,
|
|||||||
names.sort(
|
names.sort(
|
||||||
key=lambda n: tuple(
|
key=lambda n: tuple(
|
||||||
(getattr(table[n], k),)
|
(getattr(table[n], k),)
|
||||||
if getattr(table.get(n), k, None) is not None else ()
|
if getattr(table.get(n), k, None) is not None
|
||||||
for k in ([k] if k else [
|
else ()
|
||||||
k for k in Result._sort if k in fields])),
|
for k in (
|
||||||
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])),
|
||||||
reverse=reverse ^ (not k or k in Result._fields))
|
reverse=reverse ^ (not k or k in Result._fields))
|
||||||
|
|
||||||
|
|
||||||
@@ -356,8 +360,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
# header
|
# header
|
||||||
header = [
|
header = ['%s%s' % (
|
||||||
'%s%s' % (
|
|
||||||
','.join(by),
|
','.join(by),
|
||||||
' (%d added, %d removed)' % (
|
' (%d added, %d removed)' % (
|
||||||
sum(1 for n in table if n not in diff_table),
|
sum(1 for n in table if n not in diff_table),
|
||||||
@@ -516,14 +519,16 @@ def main(obj_paths, *,
|
|||||||
writer = csv.DictWriter(f,
|
writer = csv.DictWriter(f,
|
||||||
(by if by is not None else StructResult._by)
|
(by if by is not None else StructResult._by)
|
||||||
+ [k for k in (
|
+ [k for k in (
|
||||||
fields if fields is not None else StructResult._fields)])
|
fields if fields is not None
|
||||||
|
else StructResult._fields)])
|
||||||
writer.writeheader()
|
writer.writeheader()
|
||||||
for r in results:
|
for r in results:
|
||||||
writer.writerow(
|
writer.writerow(
|
||||||
{k: getattr(r, k) for k in (
|
{k: getattr(r, k) for k in (
|
||||||
by if by is not None else StructResult._by)}
|
by if by is not None else StructResult._by)}
|
||||||
| {k: getattr(r, k) for k in (
|
| {k: getattr(r, k) for k in (
|
||||||
fields if fields is not None else StructResult._fields)})
|
fields if fields is not None
|
||||||
|
else StructResult._fields)})
|
||||||
|
|
||||||
# find previous results?
|
# find previous results?
|
||||||
if args.get('diff'):
|
if args.get('diff'):
|
||||||
@@ -643,8 +648,8 @@ if __name__ == "__main__":
|
|||||||
'-F', '--source',
|
'-F', '--source',
|
||||||
dest='sources',
|
dest='sources',
|
||||||
action='append',
|
action='append',
|
||||||
help="Only consider definitions in this file. Defaults to anything "
|
help="Only consider definitions in this file. Defaults to "
|
||||||
"in the current directory.")
|
"anything in the current directory.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--everything',
|
'--everything',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
|
|||||||
+19
-15
@@ -302,16 +302,14 @@ def infer(fields_, results,
|
|||||||
defines=[]):
|
defines=[]):
|
||||||
# if by not specified, guess it's anything not in fields/renames/defines
|
# if by not specified, guess it's anything not in fields/renames/defines
|
||||||
if by is None:
|
if by is None:
|
||||||
by = [
|
by = [k for k in fields_
|
||||||
k for k in fields_
|
|
||||||
if k not in (fields or [])
|
if k not in (fields or [])
|
||||||
and not any(k == old_k for _, old_k in renames)
|
and not any(k == old_k for _, old_k in renames)
|
||||||
and not any(k == k_ for k_, _ in defines)]
|
and not any(k == k_ for k_, _ in defines)]
|
||||||
|
|
||||||
# if fields not specified, guess it's anything not in by/renames/defines
|
# if fields not specified, guess it's anything not in by/renames/defines
|
||||||
if fields is None:
|
if fields is None:
|
||||||
fields = [
|
fields = [k for k in fields_
|
||||||
k for k in fields_
|
|
||||||
if k not in (by or [])
|
if k not in (by or [])
|
||||||
and not any(k == old_k for _, old_k in renames)
|
and not any(k == old_k for _, old_k in renames)
|
||||||
and not any(k == k_ for k_, _ in defines)]
|
and not any(k == k_ for k_, _ in defines)]
|
||||||
@@ -468,7 +466,8 @@ def table(Result, results, diff_results=None, *,
|
|||||||
# sort again, now with diff info, note that python's sort is stable
|
# sort again, now with diff info, note that python's sort is stable
|
||||||
names.sort()
|
names.sort()
|
||||||
if diff_results is not None:
|
if diff_results is not None:
|
||||||
names.sort(key=lambda n: tuple(
|
names.sort(
|
||||||
|
key=lambda n: tuple(
|
||||||
types[k].ratio(
|
types[k].ratio(
|
||||||
getattr(table.get(n), k, None),
|
getattr(table.get(n), k, None),
|
||||||
getattr(diff_table.get(n), k, None))
|
getattr(diff_table.get(n), k, None))
|
||||||
@@ -479,9 +478,12 @@ def table(Result, results, diff_results=None, *,
|
|||||||
names.sort(
|
names.sort(
|
||||||
key=lambda n: tuple(
|
key=lambda n: tuple(
|
||||||
(getattr(table[n], k),)
|
(getattr(table[n], k),)
|
||||||
if getattr(table.get(n), k, None) is not None else ()
|
if getattr(table.get(n), k, None) is not None
|
||||||
for k in ([k] if k else [
|
else ()
|
||||||
k for k in Result._sort if k in fields])),
|
for k in (
|
||||||
|
[k] if k else [
|
||||||
|
k for k in Result._sort
|
||||||
|
if k in fields])),
|
||||||
reverse=reverse ^ (not k or k in Result._fields))
|
reverse=reverse ^ (not k or k in Result._fields))
|
||||||
|
|
||||||
|
|
||||||
@@ -489,8 +491,7 @@ def table(Result, results, diff_results=None, *,
|
|||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
# header
|
# header
|
||||||
header = [
|
header = ['%s%s' % (
|
||||||
'%s%s' % (
|
|
||||||
','.join(by),
|
','.join(by),
|
||||||
' (%d added, %d removed)' % (
|
' (%d added, %d removed)' % (
|
||||||
sum(1 for n in table if n not in diff_table),
|
sum(1 for n in table if n not in diff_table),
|
||||||
@@ -702,7 +703,8 @@ def main(csv_paths, *,
|
|||||||
for r in results:
|
for r in results:
|
||||||
# note we need to go through getattr to resolve lazy fields
|
# note we need to go through getattr to resolve lazy fields
|
||||||
writer.writerow({
|
writer.writerow({
|
||||||
k: getattr(r, k) for k in Result._by + Result._fields})
|
k: getattr(r, k)
|
||||||
|
for k in Result._by + Result._fields})
|
||||||
|
|
||||||
# find previous results?
|
# find previous results?
|
||||||
if args.get('diff'):
|
if args.get('diff'):
|
||||||
@@ -773,7 +775,8 @@ if __name__ == "__main__":
|
|||||||
tuple(v.strip() for v in vs.split(','))
|
tuple(v.strip() for v in vs.split(','))
|
||||||
if vs is not None else ())
|
if vs is not None else ())
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
help="Group by this field. Can rename fields with new_name=old_name.")
|
help="Group by this field. Can rename fields with "
|
||||||
|
"new_name=old_name.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-f', '--field',
|
'-f', '--field',
|
||||||
dest='fields',
|
dest='fields',
|
||||||
@@ -784,7 +787,8 @@ if __name__ == "__main__":
|
|||||||
tuple(v.strip() for v in vs.split(','))
|
tuple(v.strip() for v in vs.split(','))
|
||||||
if vs is not None else ())
|
if vs is not None else ())
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
help="Show this field. Can rename fields with new_name=old_name.")
|
help="Show this field. Can rename fields with "
|
||||||
|
"new_name=old_name.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-D', '--define',
|
'-D', '--define',
|
||||||
dest='defines',
|
dest='defines',
|
||||||
@@ -794,8 +798,8 @@ if __name__ == "__main__":
|
|||||||
k.strip(),
|
k.strip(),
|
||||||
{v.strip() for v in vs.split(',')})
|
{v.strip() for v in vs.split(',')})
|
||||||
)(*x.split('=', 1)),
|
)(*x.split('=', 1)),
|
||||||
help="Only include results where this field is this value. May include "
|
help="Only include results where this field is this value. May "
|
||||||
"comma-separated options.")
|
"include comma-separated options.")
|
||||||
class AppendSort(argparse.Action):
|
class AppendSort(argparse.Action):
|
||||||
def __call__(self, parser, namespace, value, option):
|
def __call__(self, parser, namespace, value, option):
|
||||||
if namespace.sort is None:
|
if namespace.sort is None:
|
||||||
|
|||||||
+4
-3
@@ -157,7 +157,8 @@ if __name__ == "__main__":
|
|||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Efficiently displays the last n lines of a file/pipe.",
|
description="Efficiently displays the last n lines of a "
|
||||||
|
"file/pipe.",
|
||||||
allow_abbrev=False)
|
allow_abbrev=False)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'path',
|
'path',
|
||||||
@@ -168,8 +169,8 @@ if __name__ == "__main__":
|
|||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
const=0,
|
const=0,
|
||||||
help="Show this many lines of history. 0 uses the terminal height. "
|
help="Show this many lines of history. 0 uses the terminal "
|
||||||
"Defaults to 5.")
|
"height. Defaults to 5.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-z', '--cat',
|
'-z', '--cat',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
|
|||||||
+84
-75
@@ -198,7 +198,8 @@ class TestSuite:
|
|||||||
case_linenos, case_linenos[1:],
|
case_linenos, case_linenos[1:],
|
||||||
fillvalue=(float('inf'), None)):
|
fillvalue=(float('inf'), None)):
|
||||||
code_lineno = min(
|
code_lineno = min(
|
||||||
(l for l in code_linenos if l >= lineno and l < nlineno),
|
(l for l in code_linenos
|
||||||
|
if l >= lineno and l < nlineno),
|
||||||
default=None)
|
default=None)
|
||||||
cases[name]['lineno'] = lineno
|
cases[name]['lineno'] = lineno
|
||||||
cases[name]['code_lineno'] = code_lineno
|
cases[name]['code_lineno'] = code_lineno
|
||||||
@@ -229,7 +230,8 @@ class TestSuite:
|
|||||||
|
|
||||||
self.cases = []
|
self.cases = []
|
||||||
for name, case in cases.items():
|
for name, case in cases.items():
|
||||||
self.cases.append(TestCase(config={
|
self.cases.append(TestCase(
|
||||||
|
config={
|
||||||
'name': name,
|
'name': name,
|
||||||
'path': path + (':%d' % case['lineno']
|
'path': path + (':%d' % case['lineno']
|
||||||
if 'lineno' in case else ''),
|
if 'lineno' in case else ''),
|
||||||
@@ -386,23 +388,21 @@ def compile(test_paths, **args):
|
|||||||
for k, vs in sorted(permutation.items()):
|
for k, vs in sorted(permutation.items()):
|
||||||
f.writeln('intmax_t __test__%s__%s__%d('
|
f.writeln('intmax_t __test__%s__%s__%d('
|
||||||
'__attribute__((unused)) void *data, '
|
'__attribute__((unused)) void *data, '
|
||||||
'size_t i) {'
|
'size_t i) {' % (
|
||||||
% (case.name, k, i))
|
case.name, k, i))
|
||||||
j = 0
|
j = 0
|
||||||
for v in vs:
|
for v in vs:
|
||||||
# generate range
|
# generate range
|
||||||
if isinstance(v, range):
|
if isinstance(v, range):
|
||||||
f.writeln(
|
f.writeln(4*' '+'if (i < %d) '
|
||||||
4*' '+'if (i < %d) '
|
'return (i-%d)*%d + %d;' % (
|
||||||
'return (i-%d)*%d + %d;'
|
j+len(v), j, v.step, v.start))
|
||||||
% (j+len(v), j, v.step, v.start))
|
|
||||||
j += len(v)
|
j += len(v)
|
||||||
# translate index to define
|
# translate index to define
|
||||||
else:
|
else:
|
||||||
f.writeln(
|
f.writeln(4*' '+'if (i == %d) '
|
||||||
4*' '+'if (i == %d) '
|
'return %s;' % (
|
||||||
'return %s;'
|
j, v))
|
||||||
% (j, v))
|
|
||||||
j += 1;
|
j += 1;
|
||||||
|
|
||||||
f.writeln(4*' '+'__builtin_unreachable();')
|
f.writeln(4*' '+'__builtin_unreachable();')
|
||||||
@@ -411,8 +411,8 @@ def compile(test_paths, **args):
|
|||||||
|
|
||||||
# create case if function
|
# create case if function
|
||||||
if suite.if_ or case.if_:
|
if suite.if_ or case.if_:
|
||||||
f.writeln('bool __test__%s__if(void) {'
|
f.writeln('bool __test__%s__if(void) {' % (
|
||||||
% (case.name))
|
case.name))
|
||||||
for if_ in it.chain(suite.if_, case.if_):
|
for if_ in it.chain(suite.if_, case.if_):
|
||||||
f.writeln(4*' '+'if (!(%s)) return false;' % (
|
f.writeln(4*' '+'if (!(%s)) return false;' % (
|
||||||
'true' if if_ is True
|
'true' if if_ is True
|
||||||
@@ -424,16 +424,17 @@ def compile(test_paths, **args):
|
|||||||
|
|
||||||
# create case run function
|
# create case run function
|
||||||
f.writeln('void __test__%s__run('
|
f.writeln('void __test__%s__run('
|
||||||
'__attribute__((unused)) struct lfs_config *CFG) {'
|
'__attribute__((unused)) '
|
||||||
% (case.name))
|
'struct lfs_config *CFG) {' % (
|
||||||
|
case.name))
|
||||||
f.writeln(4*' '+'// test case %s' % case.name)
|
f.writeln(4*' '+'// test case %s' % case.name)
|
||||||
if case.code_lineno is not None:
|
if case.code_lineno is not None:
|
||||||
f.writeln(4*' '+'#line %d "%s"'
|
f.writeln(4*' '+'#line %d "%s"' % (
|
||||||
% (case.code_lineno, suite.path))
|
case.code_lineno, suite.path))
|
||||||
f.write(case.code)
|
f.write(case.code)
|
||||||
if case.code_lineno is not None:
|
if case.code_lineno is not None:
|
||||||
f.writeln(4*' '+'#line %d "%s"'
|
f.writeln(4*' '+'#line %d "%s"' % (
|
||||||
% (f.lineno+1, args['output']))
|
f.lineno+1, args['output']))
|
||||||
f.writeln('}')
|
f.writeln('}')
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
@@ -453,19 +454,19 @@ def compile(test_paths, **args):
|
|||||||
# write any suite defines
|
# write any suite defines
|
||||||
if suite.defines:
|
if suite.defines:
|
||||||
for define in sorted(suite.defines):
|
for define in sorted(suite.defines):
|
||||||
f.writeln('__attribute__((weak)) intmax_t %s;'
|
f.writeln('__attribute__((weak)) intmax_t %s;' % (
|
||||||
% define)
|
define))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
# write any suite code
|
# write any suite code
|
||||||
if suite.code is not None and suite.in_ is None:
|
if suite.code is not None and suite.in_ is None:
|
||||||
if suite.code_lineno is not None:
|
if suite.code_lineno is not None:
|
||||||
f.writeln('#line %d "%s"'
|
f.writeln('#line %d "%s"' % (
|
||||||
% (suite.code_lineno, suite.path))
|
suite.code_lineno, suite.path))
|
||||||
f.write(suite.code)
|
f.write(suite.code)
|
||||||
if suite.code_lineno is not None:
|
if suite.code_lineno is not None:
|
||||||
f.writeln('#line %d "%s"'
|
f.writeln('#line %d "%s"' % (
|
||||||
% (f.lineno+1, args['output']))
|
f.lineno+1, args['output']))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
# create case functions
|
# create case functions
|
||||||
@@ -476,15 +477,15 @@ def compile(test_paths, **args):
|
|||||||
for i, permutation in enumerate(case.permutations):
|
for i, permutation in enumerate(case.permutations):
|
||||||
for k, vs in sorted(permutation.items()):
|
for k, vs in sorted(permutation.items()):
|
||||||
f.writeln('extern intmax_t __test__%s__%s__%d('
|
f.writeln('extern intmax_t __test__%s__%s__%d('
|
||||||
'void *data, size_t i);'
|
'void *data, size_t i);' % (
|
||||||
% (case.name, k, i))
|
case.name, k, i))
|
||||||
if suite.if_ or case.if_:
|
if suite.if_ or case.if_:
|
||||||
f.writeln('extern bool __test__%s__if('
|
f.writeln('extern bool __test__%s__if('
|
||||||
'void);'
|
'void);' % (
|
||||||
% (case.name))
|
case.name))
|
||||||
f.writeln('extern void __test__%s__run('
|
f.writeln('extern void __test__%s__run('
|
||||||
'struct lfs_config *CFG);'
|
'struct lfs_config *CFG);' % (
|
||||||
% (case.name))
|
case.name))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
# write any ifdef epilogues
|
# write any ifdef epilogues
|
||||||
@@ -494,12 +495,12 @@ def compile(test_paths, **args):
|
|||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
# create suite struct
|
# create suite struct
|
||||||
f.writeln('const struct test_suite __test__%s__suite = {'
|
f.writeln('const struct test_suite __test__%s__suite = {' % (
|
||||||
% suite.name)
|
suite.name))
|
||||||
f.writeln(4*' '+'.name = "%s",' % suite.name)
|
f.writeln(4*' '+'.name = "%s",' % suite.name)
|
||||||
f.writeln(4*' '+'.path = "%s",' % suite.path)
|
f.writeln(4*' '+'.path = "%s",' % suite.path)
|
||||||
f.writeln(4*' '+'.flags = %s,'
|
f.writeln(4*' '+'.flags = %s,' % (
|
||||||
% (' | '.join(filter(None, [
|
' | '.join(filter(None, [
|
||||||
'TEST_INTERNAL' if suite.internal else None,
|
'TEST_INTERNAL' if suite.internal else None,
|
||||||
'TEST_REENTRANT' if suite.reentrant else None,
|
'TEST_REENTRANT' if suite.reentrant else None,
|
||||||
'TEST_FUZZ' if suite.fuzz else None]))
|
'TEST_FUZZ' if suite.fuzz else None]))
|
||||||
@@ -510,8 +511,8 @@ def compile(test_paths, **args):
|
|||||||
if suite.defines:
|
if suite.defines:
|
||||||
f.writeln(4*' '+'.defines = (const test_define_t[]){')
|
f.writeln(4*' '+'.defines = (const test_define_t[]){')
|
||||||
for k in sorted(suite.defines):
|
for k in sorted(suite.defines):
|
||||||
f.writeln(8*' '+'{"%s", &%s, NULL, NULL, 0},'
|
f.writeln(8*' '+'{"%s", &%s, NULL, NULL, 0},' % (
|
||||||
% (k, k))
|
k, k))
|
||||||
f.writeln(4*' '+'},')
|
f.writeln(4*' '+'},')
|
||||||
f.writeln(4*' '+'.define_count = %d,' % len(suite.defines))
|
f.writeln(4*' '+'.define_count = %d,' % len(suite.defines))
|
||||||
for ifdef in suite.ifdef:
|
for ifdef in suite.ifdef:
|
||||||
@@ -523,11 +524,14 @@ def compile(test_paths, **args):
|
|||||||
f.writeln(8*' '+'{')
|
f.writeln(8*' '+'{')
|
||||||
f.writeln(12*' '+'.name = "%s",' % case.name)
|
f.writeln(12*' '+'.name = "%s",' % case.name)
|
||||||
f.writeln(12*' '+'.path = "%s",' % case.path)
|
f.writeln(12*' '+'.path = "%s",' % case.path)
|
||||||
f.writeln(12*' '+'.flags = %s,'
|
f.writeln(12*' '+'.flags = %s,' % (
|
||||||
% (' | '.join(filter(None, [
|
' | '.join(filter(None, [
|
||||||
'TEST_INTERNAL' if case.internal else None,
|
'TEST_INTERNAL' if case.internal
|
||||||
'TEST_REENTRANT' if case.reentrant else None,
|
else None,
|
||||||
'TEST_FUZZ' if case.fuzz else None]))
|
'TEST_REENTRANT' if case.reentrant
|
||||||
|
else None,
|
||||||
|
'TEST_FUZZ' if case.fuzz
|
||||||
|
else None]))
|
||||||
or 0))
|
or 0))
|
||||||
for ifdef in it.chain(suite.ifdef, case.ifdef):
|
for ifdef in it.chain(suite.ifdef, case.ifdef):
|
||||||
f.writeln(12*' '+'#ifdef %s' % ifdef)
|
f.writeln(12*' '+'#ifdef %s' % ifdef)
|
||||||
@@ -535,15 +539,16 @@ def compile(test_paths, **args):
|
|||||||
if case.defines:
|
if case.defines:
|
||||||
f.writeln(12*' '+'.defines'
|
f.writeln(12*' '+'.defines'
|
||||||
' = (const test_define_t*)'
|
' = (const test_define_t*)'
|
||||||
'(const test_define_t[][%d]){'
|
'(const test_define_t[][%d]){' % (
|
||||||
% (len(suite.defines)))
|
len(suite.defines)))
|
||||||
for i, permutation in enumerate(case.permutations):
|
for i, permutation in enumerate(case.permutations):
|
||||||
f.writeln(16*' '+'{')
|
f.writeln(16*' '+'{')
|
||||||
for k, vs in sorted(permutation.items()):
|
for k, vs in sorted(permutation.items()):
|
||||||
f.writeln(20*' '+'[%d] = {'
|
f.writeln(20*' '+'[%d] = {'
|
||||||
'"%s", &%s, '
|
'"%s", &%s, '
|
||||||
'__test__%s__%s__%d, NULL, %d},'
|
'__test__%s__%s__%d, '
|
||||||
% (sorted(suite.defines).index(k),
|
'NULL, %d},' % (
|
||||||
|
sorted(suite.defines).index(k),
|
||||||
k, k, case.name, k, i,
|
k, k, case.name, k, i,
|
||||||
sum(len(v)
|
sum(len(v)
|
||||||
if isinstance(v, range)
|
if isinstance(v, range)
|
||||||
@@ -551,13 +556,13 @@ def compile(test_paths, **args):
|
|||||||
for v in vs)))
|
for v in vs)))
|
||||||
f.writeln(16*' '+'},')
|
f.writeln(16*' '+'},')
|
||||||
f.writeln(12*' '+'},')
|
f.writeln(12*' '+'},')
|
||||||
f.writeln(12*' '+'.permutations = %d,'
|
f.writeln(12*' '+'.permutations = %d,' % (
|
||||||
% len(case.permutations))
|
len(case.permutations)))
|
||||||
if suite.if_ or case.if_:
|
if suite.if_ or case.if_:
|
||||||
f.writeln(12*' '+'.if_ = __test__%s__if,'
|
f.writeln(12*' '+'.if_ = __test__%s__if,' % (
|
||||||
% (case.name))
|
case.name))
|
||||||
f.writeln(12*' '+'.run = __test__%s__run,'
|
f.writeln(12*' '+'.run = __test__%s__run,' % (
|
||||||
% (case.name))
|
case.name))
|
||||||
for ifdef in it.chain(suite.ifdef, case.ifdef):
|
for ifdef in it.chain(suite.ifdef, case.ifdef):
|
||||||
f.writeln(12*' '+'#endif')
|
f.writeln(12*' '+'#endif')
|
||||||
f.writeln(8*' '+'},')
|
f.writeln(8*' '+'},')
|
||||||
@@ -586,8 +591,8 @@ def compile(test_paths, **args):
|
|||||||
for define in case.defines})
|
for define in case.defines})
|
||||||
if defines:
|
if defines:
|
||||||
for define in sorted(defines):
|
for define in sorted(defines):
|
||||||
f.writeln('__attribute__((weak)) intmax_t %s;'
|
f.writeln('__attribute__((weak)) intmax_t %s;' % (
|
||||||
% define)
|
define))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
# write any internal tests
|
# write any internal tests
|
||||||
@@ -601,12 +606,12 @@ def compile(test_paths, **args):
|
|||||||
# any suite code
|
# any suite code
|
||||||
if suite.isin(args['source']):
|
if suite.isin(args['source']):
|
||||||
if suite.code_lineno is not None:
|
if suite.code_lineno is not None:
|
||||||
f.writeln('#line %d "%s"'
|
f.writeln('#line %d "%s"' % (
|
||||||
% (suite.code_lineno, suite.path))
|
suite.code_lineno, suite.path))
|
||||||
f.write(suite.code)
|
f.write(suite.code)
|
||||||
if suite.code_lineno is not None:
|
if suite.code_lineno is not None:
|
||||||
f.writeln('#line %d "%s"'
|
f.writeln('#line %d "%s"' % (
|
||||||
% (f.lineno+1, args['output']))
|
f.lineno+1, args['output']))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
# any case functions
|
# any case functions
|
||||||
@@ -627,7 +632,8 @@ def compile(test_paths, **args):
|
|||||||
# will be linked
|
# will be linked
|
||||||
for suite in suites:
|
for suite in suites:
|
||||||
f.writeln('extern const struct test_suite '
|
f.writeln('extern const struct test_suite '
|
||||||
'__test__%s__suite;' % suite.name)
|
'__test__%s__suite;' % (
|
||||||
|
suite.name))
|
||||||
f.writeln()
|
f.writeln()
|
||||||
|
|
||||||
f.writeln('__attribute__((weak))')
|
f.writeln('__attribute__((weak))')
|
||||||
@@ -786,8 +792,7 @@ def find_perms(runner, test_ids=[], **args):
|
|||||||
expected_suite_perms.get(suite, 0)
|
expected_suite_perms.get(suite, 0)
|
||||||
+ expected_case_perms.get(case, 0))
|
+ expected_case_perms.get(case, 0))
|
||||||
|
|
||||||
return (
|
return (case_suites,
|
||||||
case_suites,
|
|
||||||
expected_suite_perms,
|
expected_suite_perms,
|
||||||
expected_case_perms,
|
expected_case_perms,
|
||||||
expected_perms,
|
expected_perms,
|
||||||
@@ -1240,8 +1245,7 @@ def run_stage(name, runner, test_ids, stdout_, trace_, output_, **args):
|
|||||||
for r in runners:
|
for r in runners:
|
||||||
r.join()
|
r.join()
|
||||||
|
|
||||||
return (
|
return (expected_perms,
|
||||||
expected_perms,
|
|
||||||
passed_perms,
|
passed_perms,
|
||||||
failed_perms,
|
failed_perms,
|
||||||
powerlosses,
|
powerlosses,
|
||||||
@@ -1367,7 +1371,8 @@ def run(runner, test_ids=[], **args):
|
|||||||
'\x1b[01;31m' if args['color'] else '',
|
'\x1b[01;31m' if args['color'] else '',
|
||||||
'\x1b[m' if args['color'] else '',
|
'\x1b[m' if args['color'] else '',
|
||||||
failure.id,
|
failure.id,
|
||||||
' (%s)' % ', '.join('%s=%s' % (k,v) for k,v in defines.items())
|
' (%s)' % ', '.join('%s=%s' % (k,v)
|
||||||
|
for k,v in defines.items())
|
||||||
if defines else ''))
|
if defines else ''))
|
||||||
|
|
||||||
if failure.stdout:
|
if failure.stdout:
|
||||||
@@ -1519,7 +1524,8 @@ if __name__ == "__main__":
|
|||||||
'-R', '--runner',
|
'-R', '--runner',
|
||||||
type=lambda x: x.split(),
|
type=lambda x: x.split(),
|
||||||
default=RUNNER_PATH,
|
default=RUNNER_PATH,
|
||||||
help="Test runner to use for testing. Defaults to %r." % RUNNER_PATH)
|
help="Test runner to use for testing. Defaults to "
|
||||||
|
"%r." % RUNNER_PATH)
|
||||||
test_parser.add_argument(
|
test_parser.add_argument(
|
||||||
'-Y', '--summary',
|
'-Y', '--summary',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -1588,7 +1594,8 @@ if __name__ == "__main__":
|
|||||||
help="Sample trace output at this frequency in hz.")
|
help="Sample trace output at this frequency in hz.")
|
||||||
test_parser.add_argument(
|
test_parser.add_argument(
|
||||||
'-O', '--stdout',
|
'-O', '--stdout',
|
||||||
help="Direct stdout to this file. Note stderr is already merged here.")
|
help="Direct stdout to this file. Note stderr is already merged "
|
||||||
|
"here.")
|
||||||
test_parser.add_argument(
|
test_parser.add_argument(
|
||||||
'-o', '--output',
|
'-o', '--output',
|
||||||
help="CSV file to store results.")
|
help="CSV file to store results.")
|
||||||
@@ -1606,7 +1613,8 @@ if __name__ == "__main__":
|
|||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
const=0,
|
const=0,
|
||||||
help="Number of parallel runners to run. 0 runs one runner per core.")
|
help="Number of parallel runners to run. 0 runs one runner per "
|
||||||
|
"core.")
|
||||||
test_parser.add_argument(
|
test_parser.add_argument(
|
||||||
'-k', '--keep-going',
|
'-k', '--keep-going',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -1687,12 +1695,12 @@ if __name__ == "__main__":
|
|||||||
"Defaults to %r." % VALGRIND_PATH)
|
"Defaults to %r." % VALGRIND_PATH)
|
||||||
test_parser.add_argument(
|
test_parser.add_argument(
|
||||||
'-p', '--perf',
|
'-p', '--perf',
|
||||||
help="Run under Linux's perf to sample performance counters, writing "
|
help="Run under Linux's perf to sample performance counters, "
|
||||||
"samples to this file.")
|
"writing samples to this file.")
|
||||||
test_parser.add_argument(
|
test_parser.add_argument(
|
||||||
'--perf-freq',
|
'--perf-freq',
|
||||||
help="perf sampling frequency. This is passed directly to the perf "
|
help="perf sampling frequency. This is passed directly to the "
|
||||||
"script.")
|
"perf script.")
|
||||||
test_parser.add_argument(
|
test_parser.add_argument(
|
||||||
'--perf-period',
|
'--perf-period',
|
||||||
help="perf sampling period. This is passed directly to the perf "
|
help="perf sampling period. This is passed directly to the perf "
|
||||||
@@ -1705,12 +1713,13 @@ if __name__ == "__main__":
|
|||||||
'--perf-script',
|
'--perf-script',
|
||||||
type=lambda x: x.split(),
|
type=lambda x: x.split(),
|
||||||
default=PERF_SCRIPT,
|
default=PERF_SCRIPT,
|
||||||
help="Path to the perf script to use. Defaults to %r." % PERF_SCRIPT)
|
help="Path to the perf script to use. Defaults to "
|
||||||
|
"%r." % PERF_SCRIPT)
|
||||||
test_parser.add_argument(
|
test_parser.add_argument(
|
||||||
'--perf-path',
|
'--perf-path',
|
||||||
type=lambda x: x.split(),
|
type=lambda x: x.split(),
|
||||||
help="Path to the perf executable, may include flags. This is passed "
|
help="Path to the perf executable, may include flags. This is "
|
||||||
"directly to the perf script")
|
"passed directly to the perf script")
|
||||||
|
|
||||||
# compilation flags
|
# compilation flags
|
||||||
comp_parser = parser.add_argument_group('compilation options')
|
comp_parser = parser.add_argument_group('compilation options')
|
||||||
|
|||||||
+15
-11
@@ -363,8 +363,7 @@ class Pixel(int):
|
|||||||
f = [colors[3]]
|
f = [colors[3]]
|
||||||
|
|
||||||
if wear:
|
if wear:
|
||||||
w = min(
|
w = min(self.worn(
|
||||||
self.worn(
|
|
||||||
max_wear,
|
max_wear,
|
||||||
block_cycles=block_cycles,
|
block_cycles=block_cycles,
|
||||||
wear_chars=wear_chars),
|
wear_chars=wear_chars),
|
||||||
@@ -793,7 +792,8 @@ def main(path='-', *,
|
|||||||
bmap.resize(
|
bmap.resize(
|
||||||
# scale if we're printing with dots or braille
|
# scale if we're printing with dots or braille
|
||||||
width=2*width_ if braille else width_,
|
width=2*width_ if braille else width_,
|
||||||
height=max(1,
|
height=max(
|
||||||
|
1,
|
||||||
4*height_ if braille
|
4*height_ if braille
|
||||||
else 2*height_ if dots
|
else 2*height_ if dots
|
||||||
else height_))
|
else height_))
|
||||||
@@ -811,7 +811,8 @@ def main(path='-', *,
|
|||||||
'(?:'
|
'(?:'
|
||||||
'block_size=(?P<block_size>\w+)'
|
'block_size=(?P<block_size>\w+)'
|
||||||
'|' 'block_count=(?P<block_count>\w+)'
|
'|' 'block_count=(?P<block_count>\w+)'
|
||||||
'|' '.*?' ')*' '\)'
|
'|' '.*?' ')*'
|
||||||
|
'\)'
|
||||||
'|' '(?P<read>read)\('
|
'|' '(?P<read>read)\('
|
||||||
'\s*(?P<read_ctx>\w+)' '\s*,'
|
'\s*(?P<read_ctx>\w+)' '\s*,'
|
||||||
'\s*(?P<read_block>\w+)' '\s*,'
|
'\s*(?P<read_block>\w+)' '\s*,'
|
||||||
@@ -829,7 +830,8 @@ def main(path='-', *,
|
|||||||
'\s*(?P<erase_block>\w+)'
|
'\s*(?P<erase_block>\w+)'
|
||||||
'\s*\(\s*(?P<erase_size>\w+)\s*\)' '\s*\)'
|
'\s*\(\s*(?P<erase_size>\w+)\s*\)' '\s*\)'
|
||||||
'|' '(?P<sync>sync)\('
|
'|' '(?P<sync>sync)\('
|
||||||
'\s*(?P<sync_ctx>\w+)' '\s*\)' ')\s*$')
|
'\s*(?P<sync_ctx>\w+)' '\s*\)'
|
||||||
|
')\s*$')
|
||||||
def parse(line):
|
def parse(line):
|
||||||
nonlocal bmap
|
nonlocal bmap
|
||||||
nonlocal readed
|
nonlocal readed
|
||||||
@@ -1074,7 +1076,8 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-c', '--block-cycles',
|
'-c', '--block-cycles',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
help="Assumed maximum number of erase cycles when measuring wear.")
|
help="Assumed maximum number of erase cycles when measuring "
|
||||||
|
"wear.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-@', '--block',
|
'-@', '--block',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
@@ -1130,8 +1133,8 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-⣿', '--braille',
|
'-⣿', '--braille',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help="Use 2x4 unicode braille characters. Note that braille characters "
|
help="Use 2x4 unicode braille characters. Note that braille "
|
||||||
"sometimes suffer from inconsistent widths.")
|
"characters sometimes suffer from inconsistent widths.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--chars',
|
'--chars',
|
||||||
help="Characters to use for read, prog, erase, noop operations.")
|
help="Characters to use for read, prog, erase, noop operations.")
|
||||||
@@ -1164,8 +1167,8 @@ if __name__ == "__main__":
|
|||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
const=0,
|
const=0,
|
||||||
help="Show this many lines of history. 0 uses the terminal height. "
|
help="Show this many lines of history. 0 uses the terminal "
|
||||||
"Defaults to 5.")
|
"height. Defaults to 5.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-^', '--head',
|
'-^', '--head',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -1189,7 +1192,8 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-s', '--sleep',
|
'-s', '--sleep',
|
||||||
type=float,
|
type=float,
|
||||||
help="Time in seconds to sleep between reads, coalescing operations.")
|
help="Time in seconds to sleep between reads, coalescing "
|
||||||
|
"operations.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-k', '--keep-open',
|
'-k', '--keep-open',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
|
|||||||
+5
-4
@@ -261,8 +261,9 @@ if __name__ == "__main__":
|
|||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Traditional watch command, but with higher resolution "
|
description="Traditional watch command, but with higher "
|
||||||
"updates and a bit different options/output format.",
|
"resolution updates and a bit different options/output "
|
||||||
|
"format.",
|
||||||
allow_abbrev=False)
|
allow_abbrev=False)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'command',
|
'command',
|
||||||
@@ -273,8 +274,8 @@ if __name__ == "__main__":
|
|||||||
nargs='?',
|
nargs='?',
|
||||||
type=lambda x: int(x, 0),
|
type=lambda x: int(x, 0),
|
||||||
const=0,
|
const=0,
|
||||||
help="Show this many lines of history. 0 uses the terminal height. "
|
help="Show this many lines of history. 0 uses the terminal "
|
||||||
"Defaults to 0.")
|
"height. Defaults to 0.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-^', '--head',
|
'-^', '--head',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
|
|||||||
Reference in New Issue
Block a user