From 7f4b9794efb591c9de9906340fe2c26c838c2f52 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Tue, 14 Jan 2025 19:26:13 -0700 Subject: lib9p: idl: Add numeric constants --- lib9p/idl/2002-9P2000.9p | 2 ++ lib9p/idl/2005-9P2000.u.9p | 1 + lib9p/idl/__init__.py | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+) (limited to 'lib9p/idl') diff --git a/lib9p/idl/2002-9P2000.9p b/lib9p/idl/2002-9P2000.9p index 4b0738f..c1cd74b 100644 --- a/lib9p/idl/2002-9P2000.9p +++ b/lib9p/idl/2002-9P2000.9p @@ -21,9 +21,11 @@ version "9P2000" # tag - identify a request/response pair num tag = 2 + "NOTAG = ~0" # file identifier - like a UNIX file-descriptor num fid = 4 + "NOFID = ~0" # data - s32le `n`, then `n` bytes of data struct d = "len[4,max=s32_max] len*(dat[1])" diff --git a/lib9p/idl/2005-9P2000.u.9p b/lib9p/idl/2005-9P2000.u.9p index 0529e47..d96bbce 100644 --- a/lib9p/idl/2005-9P2000.u.9p +++ b/lib9p/idl/2005-9P2000.u.9p @@ -12,6 +12,7 @@ from ./2002-9P2000.9p import * # numeric user ID num nuid = 4 + "NONUID = ~0" struct stat += "file_extension[s]" "file_owner_n_uid[nuid]" diff --git a/lib9p/idl/__init__.py b/lib9p/idl/__init__.py index c08a89e..ab45ed0 100644 --- a/lib9p/idl/__init__.py +++ b/lib9p/idl/__init__.py @@ -50,8 +50,11 @@ class Number: prim: Primitive + vals: dict[str, str] + def __init__(self) -> None: self.in_versions = set() + self.vals = {} @property def static_size(self) -> int: @@ -195,12 +198,27 @@ re_memtype = f"(?:{re_symname}|{re_priname})" # typenames that a struct member re_expr = f"(?:(?:-|\\+|[0-9]+|&?{re_symname})+)" +re_numspec = f"(?P{re_symname})\\s*=\\s*(?P\\S+)" + re_bitspec_bit = f"(?P[0-9]+)\\s*=\\s*(?P{re_symname})" re_bitspec_alias = f"(?P{re_symname})\\s*=\\s*(?P\\S+)" re_memberspec = f"(?:(?P{re_symname})\\*\\()?(?P{re_symname})\\[(?P{re_memtype})(?:,max=(?P{re_expr})|,val=(?P{re_expr}))*\\]\\)?" +def parse_numspec(ver: str, n: Number, spec: str) -> None: + spec = spec.strip() + + if m := re.fullmatch(re_numspec, spec): + name = m.group("name") + val = m.group("val") + if name in n.vals: + raise ValueError(f"{n.name}: name {repr(name)} already assigned") + n.vals[name] = val + else: + raise SyntaxError(f"invalid num spec {repr(spec)}") + + def parse_bitspec(ver: str, bf: Bitfield, spec: str) -> None: spec = spec.strip() @@ -433,6 +451,8 @@ def parse_file( match prev: case Bitfield(): parse_bitspec(version, prev, m.group("specs")) + case Number(): + parse_numspec(version, prev, m.group("specs")) case Struct(): # and Message() parse_members(version, env, prev, m.group("specs")) case _: -- cgit v1.2.3-2-g168b