summaryrefslogtreecommitdiff
path: root/lib9p/protogen/cutil.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/protogen/cutil.py')
-rw-r--r--lib9p/protogen/cutil.py84
1 files changed, 84 insertions, 0 deletions
diff --git a/lib9p/protogen/cutil.py b/lib9p/protogen/cutil.py
new file mode 100644
index 0000000..a78cd17
--- /dev/null
+++ b/lib9p/protogen/cutil.py
@@ -0,0 +1,84 @@
+# lib9p/protogen/cutil.py - Utilities for generating C code
+#
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+# pylint: disable=unused-variable
+__all__ = [
+ "UINT32_MAX",
+ "UINT64_MAX",
+ "macro",
+ "ifdef_init",
+ "ifdef_push",
+ "ifdef_pop",
+ "ifdef_leaf_is_noop",
+]
+
+UINT32_MAX = (1 << 32) - 1
+UINT64_MAX = (1 << 64) - 1
+
+
+def tab_ljust(s: str, width: int) -> str:
+ cur = len(s.expandtabs(tabsize=8))
+ if cur >= width:
+ return s
+ return s + " " * (width - cur)
+
+
+def macro(full: str) -> str:
+ full = full.rstrip()
+ assert "\n" in full
+ lines = [l.rstrip() for l in full.split("\n")]
+ width = max(len(l.expandtabs(tabsize=8)) for l in lines[:-1])
+ lines = [tab_ljust(l, width) for l in lines]
+ return " \\\n".join(lines).rstrip() + "\n"
+
+
+_ifdef_stack: list[str | None] = []
+
+
+def ifdef_init() -> None:
+ global _ifdef_stack
+ _ifdef_stack = []
+
+
+def ifdef_push(n: int, _newval: str) -> str:
+ # Grow the stack as needed
+ while len(_ifdef_stack) < n:
+ _ifdef_stack.append(None)
+
+ # Set some variables
+ parentval: str | None = None
+ for x in _ifdef_stack[:-1]:
+ if x is not None:
+ parentval = x
+ oldval = _ifdef_stack[-1]
+ newval: str | None = _newval
+ if newval == parentval:
+ newval = None
+
+ # Put newval on the stack.
+ _ifdef_stack[-1] = newval
+
+ # Build output.
+ ret = ""
+ if newval != oldval:
+ if oldval is not None:
+ ret += f"#endif /* {oldval} */\n"
+ if newval is not None:
+ ret += f"#if {newval}\n"
+ return ret
+
+
+def ifdef_pop(n: int) -> str:
+ global _ifdef_stack
+ ret = ""
+ while len(_ifdef_stack) > n:
+ if _ifdef_stack[-1] is not None:
+ ret += f"#endif /* {_ifdef_stack[-1]} */\n"
+ _ifdef_stack = _ifdef_stack[:-1]
+ return ret
+
+
+def ifdef_leaf_is_noop() -> bool:
+ return not _ifdef_stack[-1]