summaryrefslogtreecommitdiff
path: root/libmisc/wrap-cc
diff options
context:
space:
mode:
Diffstat (limited to 'libmisc/wrap-cc')
-rwxr-xr-xlibmisc/wrap-cc73
1 files changed, 73 insertions, 0 deletions
diff --git a/libmisc/wrap-cc b/libmisc/wrap-cc
new file mode 100755
index 0000000..5124689
--- /dev/null
+++ b/libmisc/wrap-cc
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+# libmisc/wrap-cc - Wrapper around GCC to enhance the preprocessor
+#
+# Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+import os
+import sys
+import typing
+
+
+def preprocess(all_args: list[str]) -> typing.NoReturn:
+ _args = all_args
+
+ def shift(n: int) -> list[str]:
+ nonlocal _args
+ ret = _args[:n]
+ _args = _args[n:]
+ return ret
+
+ arg0 = shift(1)[0]
+ flags: list[str] = []
+ positional: list[str] = []
+ while _args:
+ if len(_args[0]) > 2 and _args[0][0] == "-" and _args[0][1] in "IDU":
+ _args = [_args[0][:2], _args[0][2:], *_args[1:]]
+ match _args[0]:
+ # Mode
+ case "-E" | "-quiet" | "-lang-asm":
+ flags += shift(1)
+ # Search path
+ case "-I" | "-imultilib" | "-isystem":
+ flags += shift(2)
+ # Define/Undefine
+ case "-D" | "-U":
+ flags += shift(2)
+ # Optimization
+ case "-O0" | "-O1" | "-O2" | "-O3" | "-Os" | "-Ofast" | "-Og" | "-Oz":
+ flags += shift(1)
+ case "-g":
+ flags += shift(1)
+ # Output files
+ case "-MD" | "-MF" | "-MT" | "-dumpbase" | "-dumpbase-ext":
+ flags += shift(2)
+ case "-o":
+ flags += shift(2)
+ # Other
+ case _:
+ if _args[0].startswith("-"):
+ if _args[0].startswith("-std="):
+ flags += shift(1)
+ elif _args[0].startswith("-m"):
+ flags += shift(1)
+ elif _args[0].startswith("-f"):
+ flags += shift(1)
+ elif _args[0].startswith("-W"):
+ flags += shift(1)
+ else:
+ raise ValueError(f"unknown flag: {_args!r}")
+ else:
+ positional += shift(1)
+ os.execvp(arg0, [arg0, *flags, *positional])
+
+
+def main(all_args: list[str]) -> typing.NoReturn:
+ if len(all_args) >= 2 and all_args[0].endswith("cc1") and all_args[1] == "-E":
+ preprocess(all_args)
+ else:
+ os.execvp(all_args[0], all_args)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])