summaryrefslogtreecommitdiff
path: root/lib9p/idl
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/idl')
-rw-r--r--lib9p/idl/2002-9P2000.9p2
-rw-r--r--lib9p/idl/2005-9P2000.u.9p1
-rw-r--r--lib9p/idl/__init__.py20
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 _: