scripts: Added -U/--undefine as inverse -D/--define to most scripts

This adds -U/--undefine as an inverse -D/--define, allowing you to
select results where a given field does _not_ match a set of
values/globs.

For example, make bench-marks, which need to ignore stack/heap/usage
probes as a special case, can easily filter like so:

  $ ./scripts/csv.py test.csv -Uprobe=stack,heap,usage

---

One thing globbing is pretty bad at is inverse matches. This is
_usually_ easy enough to work around, but has been an annoyance enough
times that I think _some_ option to inverse filter is warranted.

I'm not sure -U/--undefine is the best name for this, since field isn't
really "undefined" as a result (well kinda? if you're relying on
implicit by/field rules?), but it gets the job done.
This commit is contained in:
Christopher Haster
2026-02-07 00:16:00 -06:00
parent 37288fceab
commit ba1f5e730d
14 changed files with 438 additions and 101 deletions
+27 -5
View File
@@ -529,6 +529,7 @@ class Rev(co.namedtuple('Rev', 'a')):
def fold(Result, results, *,
by=None,
defines=[],
undefines=[],
sort=None,
depth=1,
**_):
@@ -540,20 +541,27 @@ def fold(Result, results, *,
if by is None:
by = Result._by
for k in it.chain(by or [], (k for k, _ in defines)):
for k in it.chain(by or [],
(k for k, _ in defines),
(k for k, _ in undefines)):
if k not in Result._by and k not in Result._fields:
print("error: could not find field %r?" % k,
file=sys.stderr)
sys.exit(-1)
# filter by matching defines
if defines:
if defines or undefines:
results_ = []
for r in results:
if all(any(fnmatch.fnmatchcase(str(getattr(r, k, '')), v)
if not all(any(fnmatch.fnmatchcase(str(getattr(r, k, '')), v)
for v in vs)
for k, vs in defines):
results_.append(r)
continue
if any(any(fnmatch.fnmatchcase(str(getattr(r, k, '')), v)
for v in vs)
for k, vs in undefines):
continue
results_.append(r)
results = results_
# organize results into conflicts
@@ -1048,6 +1056,7 @@ def main(obj_paths, *,
by=None,
fields=None,
defines=[],
undefines=[],
sort=None,
**args):
# figure out what fields we're interested in
@@ -1080,6 +1089,7 @@ def main(obj_paths, *,
results = fold(DataResult, results,
by=by,
defines=defines,
undefines=undefines,
sort=sort)
# find previous results?
@@ -1096,7 +1106,8 @@ def main(obj_paths, *,
# fold
diff_results = fold(DataResult, diff_results,
by=by,
defines=defines)
defines=defines,
undefines=undefines)
# write results to JSON
if args.get('output_json'):
@@ -1188,6 +1199,17 @@ if __name__ == "__main__":
)(*x.split('=', 1)),
help="Only include results where this field is this value. May "
"include comma-separated options and globs.")
parser.add_argument(
'-U', '--undefine',
dest='undefines',
action='append',
type=lambda x: (
lambda k, vs: (
k.strip(),
{v.strip() for v in vs.split(',')})
)(*x.split('=', 1)),
help="Don't include results where this field is this value. May "
"include comma-separated options and globs.")
class AppendSort(argparse.Action):
def __call__(self, parser, namespace, value, option):
if namespace.sort is None: