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