diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-01-14 19:26:13 -0700 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-01-14 20:02:28 -0700 |
commit | 7f4b9794efb591c9de9906340fe2c26c838c2f52 (patch) | |
tree | 3d3c90a3357ea8e8f2fb1e92840af525a3dc3669 /lib9p/idl | |
parent | af308395c6cea756c9911865137ed29e0fb34aae (diff) |
lib9p: idl: Add numeric constants
Diffstat (limited to 'lib9p/idl')
-rw-r--r-- | lib9p/idl/2002-9P2000.9p | 2 | ||||
-rw-r--r-- | lib9p/idl/2005-9P2000.u.9p | 1 | ||||
-rw-r--r-- | lib9p/idl/__init__.py | 20 |
3 files changed, 23 insertions, 0 deletions
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<name>{re_symname})\\s*=\\s*(?P<val>\\S+)" + re_bitspec_bit = f"(?P<bit>[0-9]+)\\s*=\\s*(?P<name>{re_symname})" re_bitspec_alias = f"(?P<name>{re_symname})\\s*=\\s*(?P<val>\\S+)" re_memberspec = f"(?:(?P<cnt>{re_symname})\\*\\()?(?P<name>{re_symname})\\[(?P<typ>{re_memtype})(?:,max=(?P<max>{re_expr})|,val=(?P<val>{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 _: |