From 4208aa21e2b829d260c807b0aefd8bc3009d0896 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 20 May 2024 20:35:54 -0500 Subject: [PATCH] Extended prettyasserts.py to support prefixed memcmp/strcmp The move to lfs_memcmp/lfs_strcmp highlighted an interesting hole in prettyasserts.py: the lack of support for custom memcmp/strcmp symbols. Rather than just adding more flags for an increasing number of symbols, I've added -p/--prefix and -P/--prefix-insensitive to generate relevant symbols based on a prefix. In littlefs's case, we use -Plfs_, which matches both lfs_memcmp and LFS_ASSERT (and LFS_MEMCMP and lfs_assert but ignore those): $ ./scripts/prettyasserts.py -Plfs_ lfs.t.c -o lfs.t.a.c Don't worry, you can still provide explicit symbols, but only via long-form flags. This gets a bit noisy: $ ./scripts/prettyasserts.py \ --assert=LFS_ASSERT \ --unreachable=LFS_UNREACHABLE \ --memcmp=lfs_memcmp \ --strcmp=lfs_strcmp \ lfs.t.c -o lfs.t.a.c This commit also finally gives the prettyasserts.py's symbols actual word boundaries, instead of the big error-prone hack of sorting by size. --- Makefile | 4 +-- scripts/prettyasserts.py | 74 +++++++++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 188e9457..e2848cb6 100644 --- a/Makefile +++ b/Makefile @@ -523,10 +523,10 @@ $(BUILDDIR)/%.s: %.c $(CC) -S $(CFLAGS) $< -o $@ $(BUILDDIR)/%.a.c: %.c - $(PRETTYASSERTS) -a LFS_ASSERT -u LFS_UNREACHABLE $< -o $@ + $(PRETTYASSERTS) -Plfs_ $< -o $@ $(BUILDDIR)/%.a.c: $(BUILDDIR)/%.c - $(PRETTYASSERTS) -a LFS_ASSERT -u LFS_UNREACHABLE $< -o $@ + $(PRETTYASSERTS) -Plfs_ $< -o $@ $(BUILDDIR)/%.t.c: %.toml ./scripts/test.py -c $< $(TESTCFLAGS) -o $@ diff --git a/scripts/prettyasserts.py b/scripts/prettyasserts.py index aa7eb687..d1d193ad 100755 --- a/scripts/prettyasserts.py +++ b/scripts/prettyasserts.py @@ -26,12 +26,14 @@ CMP = { LEXEMES = { 'ws': [r'(?:\s|\n|#.*?(?'], 'string': [r'"(?:\\.|[^"])*"', r"'(?:\\.|[^'])\'"], 'paren': ['\(', '\)'], - 'cmp': CMP.keys(), + 'cmp': list(CMP.keys()), 'logic': ['\&\&', '\|\|'], 'sep': [':', ';', '\{', '\}', ','], # specifically ops that conflict with cmp @@ -363,7 +365,7 @@ def p_expr(p): except ParseFailure: p.pop(state) res.append(p.expect('unreachable')) - elif p.accept('string', 'op', 'ws', None): + elif p.accept('memcmp', 'strcmp', 'string', 'op', 'ws', None): res.append(p.m) else: return ''.join(res) @@ -421,23 +423,45 @@ def p_stmt(p): else: return ws + lh -def main(input=None, output=None, +def main(input=None, output=None, *, + prefix=[], + prefix_insensitive=[], assert_=[], unreachable=[], - arrow=False, + memcmp=[], + strcmp=[], no_defaults=False, + no_upper=False, + no_arrows=False, limit=LIMIT): with openio(input or '-', 'r') as in_f: # create parser - lexemes = LEXEMES.copy() + lexemes = {n: l.copy() for n, l in LEXEMES.items()} if no_defaults: lexemes['assert'] = [] lexemes['unreachable'] = [] + lexemes['memcmp'] = [] + lexemes['strcmp'] = [] + if no_arrows: lexemes['arrow'] = [] - lexemes['assert'] += assert_ - lexemes['unreachable'] += unreachable - if arrow and no_defaults: - lexemes['arrow'].append('=>') + for p in prefix + prefix_insensitive: + lexemes['assert'].append(r'\b%sassert\b' % p) + lexemes['unreachable'].append(r'\b%sunreachable\b' % p) + lexemes['memcmp'].append(r'\b%smemcmp\b' % p) + lexemes['strcmp'].append(r'\b%sstrcmp\b' % p) + for p in prefix_insensitive: + lexemes['assert'].append(r'\b%sassert\b' % p.lower()) + lexemes['unreachable'].append(r'\b%sunreachable\b' % p.lower()) + lexemes['memcmp'].append(r'\b%smemcmp\b' % p.lower()) + lexemes['strcmp'].append(r'\b%sstrcmp\b' % p.lower()) + lexemes['assert'].append(r'\b%sASSERT\b' % p.upper()) + lexemes['unreachable'].append(r'\b%sUNREACHABLE\b' % p.upper()) + lexemes['memcmp'].append(r'\b%sMEMCMP\b' % p.upper()) + lexemes['strcmp'].append(r'\b%sSTRCMP\b' % p.upper()) + lexemes['assert'].extend(r'\b%s\b' % r for r in assert_) + lexemes['unreachable'].extend(r'\b%s\b' % r for r in unreachable) + lexemes['memcmp'].extend(r'\b%s\b' % r for r in memcmp) + lexemes['strcmp'].extend(r'\b%s\b' % r for r in strcmp) p = Parser(in_f, lexemes) with openio(output or '-', 'w') as f: @@ -481,22 +505,38 @@ if __name__ == "__main__": required=True, help="Output C file.") parser.add_argument( - '-a', '--assert', + '-p', '--prefix', + action='append', + help="Additional prefixes for symbols.") + parser.add_argument( + '-P', '--prefix-insensitive', + action='append', + help="Additional prefixes for lower/upper case symbol variants.") + parser.add_argument( + '--assert', dest='assert_', action='append', help="Additional symbols for assert statements.") parser.add_argument( - '-u', '--unreachable', + '--unreachable', action='append', help="Additional symbols for unreachable statements.") parser.add_argument( - '-A', '--arrow', - action='store_true', - help="Enable arrow (=>) expressions, this is enabled by default.") + '--memcmp', + action='append', + help="Additional symbols for memcmp expressions.") + parser.add_argument( + '--strcmp', + action='append', + help="Additional symbols for strcmp expressions.") parser.add_argument( '-n', '--no-defaults', action='store_true', - help="Disable the default statements/expressions.") + help="Disable default symbols.") + parser.add_argument( + '-A', '--no-arrows', + action='store_true', + help="Disable arrow (=>) expressions.") parser.add_argument( '-l', '--limit', type=lambda x: int(x, 0),