diff options
Diffstat (limited to 'lib9p/protogen/c9util.py')
-rw-r--r-- | lib9p/protogen/c9util.py | 134 |
1 files changed, 0 insertions, 134 deletions
diff --git a/lib9p/protogen/c9util.py b/lib9p/protogen/c9util.py deleted file mode 100644 index cf91951..0000000 --- a/lib9p/protogen/c9util.py +++ /dev/null @@ -1,134 +0,0 @@ -# lib9p/protogen/c9util.py - Utilities for generating lib9p-specific C -# -# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> -# SPDX-License-Identifier: AGPL-3.0-or-later - -import re -import typing - -import idl - -# This strives to be "general-purpose" in that it just acts on the -# *.9p inputs; but (unfortunately?) there are a few special-cases in -# this script, marked with "SPECIAL". - -# pylint: disable=unused-variable -__all__ = [ - "add_prefix", - "ident", - "Ident", - "IDENT", - "ver_enum", - "ver_ifdef", - "ver_cond", - "typename", - "idl_expr", -] - -# idents ####################################################################### - - -def add_prefix(p: str, s: str) -> str: - if s.startswith("_"): - return "_" + p + s[1:] - return p + s - - -def _ident(p: str, s: str) -> str: - return add_prefix(p, s.replace(".", "_")) - - -def ident(s: str) -> str: - return _ident("lib9p_", s) - - -def Ident(s: str) -> str: - return _ident("lib9p_".upper(), s) - - -def IDENT(s: str) -> str: - return _ident("lib9p_", s).upper() - - -# versions ##################################################################### - - -def ver_enum(ver: str) -> str: - return Ident("VER_" + ver) - - -def ver_ifdef(versions: typing.Collection[str]) -> str: - return " || ".join( - f"CONFIG_9P_ENABLE_{v.replace('.', '_')}" for v in sorted(versions) - ) - - -def ver_cond(versions: typing.Collection[str]) -> str: - if len(versions) == 1: - v = next(v for v in versions) - return f"is_ver(ctx, {v.replace('.', '_')})" - return "( " + (" || ".join(ver_cond({v}) for v in sorted(versions))) + " )" - - -# misc ######################################################################### - - -def basename(typ: idl.UserType) -> str: - match typ: - case idl.Number(): - return ident(typ.typname) - case idl.Bitfield(): - return ident(typ.typname) - case idl.Message(): - return ident(f"msg_{typ.typname}") - case idl.Struct(): - return ident(typ.typname) - case _: - raise ValueError(f"not a defined type: {typ.__class__.__name__}") - - -def typename(typ: idl.Type, parent: idl.StructMember | None = None) -> str: - match typ: - case idl.Primitive(): - if typ.value == 1 and parent and parent.cnt: # SPECIAL (string) - return "[[gnu::nonstring]] char" - return f"uint{typ.value*8}_t" - case idl.Number(): - return f"{basename(typ)}_t" - case idl.Bitfield(): - return f"{basename(typ)}_t" - case idl.Message(): - return f"struct {basename(typ)}" - case idl.Struct(): - return f"struct {basename(typ)}" - case _: - raise ValueError(f"not a type: {typ.__class__.__name__}") - - -def idl_expr( - expr: idl.Expr, lookup_sym: typing.Callable[[str], str], bitwidth: int = 0 -) -> str: - ret: list[str] = [] - for tok in expr.tokens: - match tok: - case idl.ExprOp(): - ret.append(tok.op) - case idl.ExprLit(): - if bitwidth: - ret.append(f"{tok.val:#0{bitwidth}b}") - else: - ret.append(str(tok.val)) - case idl.ExprSym(): - if m := re.fullmatch(r"^u(8|16|32|64)_max$", tok.symname): - ret.append(f"UINT{m.group(1)}_MAX") - elif m := re.fullmatch(r"^s(8|16|32|64)_max$", tok.symname): - ret.append(f"INT{m.group(1)}_MAX") - else: - ret.append(lookup_sym(tok.symname)) - case idl.ExprOff(): - ret.append(lookup_sym("&" + tok.membname)) - case idl.ExprNum(): - ret.append(Ident(add_prefix(f"{tok.numname}_".upper(), tok.valname))) - case _: - assert False - return " ".join(ret) |