summaryrefslogtreecommitdiff
path: root/lib9p/idl.gen
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/idl.gen')
-rwxr-xr-xlib9p/idl.gen98
1 files changed, 67 insertions, 31 deletions
diff --git a/lib9p/idl.gen b/lib9p/idl.gen
index b75ffd6..af70097 100755
--- a/lib9p/idl.gen
+++ b/lib9p/idl.gen
@@ -499,45 +499,75 @@ enum {idprefix}version {{
ret += f"#define {prefix}{name.ljust(namewidth)} (({c_typename(typ)})UINT{typ.static_size*8}_C({val}))\n"
case idl.Bitfield():
ret += f"typedef {c_typename(typ.prim)} {c_typename(typ)};\n"
- names = [
- typ.bits[n] or f" {n}" for n in reversed(range(0, len(typ.bits)))
- ]
- if aliases := [k for k in typ.names if k not in typ.bits]:
- names.append("")
- names.extend(aliases)
- prefix = f"{idprefix.upper()}{typ.typname.upper()}_"
- namewidth = max(len(add_prefix(prefix, name)) for name in names)
- ret += "\n"
- for name in names:
- if name == "":
- ret += "\n"
- continue
+ def bitname(val: idl.Bit | idl.BitAlias) -> str:
+ s = val.bitname
+ match val:
+ case idl.Bit(cat=idl.BitCat.RESERVED):
+ s = "_RESERVED_" + s
+ case idl.Bit(cat=idl.BitCat.SUBFIELD):
+ assert isinstance(typ, idl.Bitfield)
+ n = sum(
+ 1
+ for b in typ.bits[: val.num]
+ if b.cat == idl.BitCat.SUBFIELD
+ and b.bitname == val.bitname
+ )
+ s = f"_{s}_{n}"
+ case idl.Bit(cat=idl.BitCat.UNUSED):
+ return ""
+ return add_prefix(f"{idprefix.upper()}{typ.typname.upper()}_", s)
- if name.startswith(" "):
- vers = typ.in_versions
- c_name = ""
- c_val = f"1<<{name[1:]}"
- else:
- vers = typ.names[name].in_versions
- c_name = add_prefix(prefix, name)
- c_val = f"{typ.names[name].val}"
+ namewidth = max(
+ len(bitname(val)) for val in [*typ.bits, *typ.names.values()]
+ )
+ ret += "\n"
+ for bit in reversed(typ.bits):
+ vers = bit.in_versions
+ if bit.cat == idl.BitCat.UNUSED:
+ vers = typ.in_versions
ret += ifdef_push(2, c_ver_ifdef(vers))
# It is important all of the `beg` strings have
# the same length.
end = ""
- if name.startswith(" "):
- beg = "/* unused"
- end = " */"
- elif _ifdef_stack[-1]:
- beg = "# define"
- else:
- beg = "#define "
+ match bit.cat:
+ case (
+ idl.BitCat.USED | idl.BitCat.RESERVED | idl.BitCat.SUBFIELD
+ ):
+ if _ifdef_stack[-1]:
+ beg = "# define"
+ else:
+ beg = "#define "
+ case idl.BitCat.UNUSED:
+ beg = "/* unused"
+ end = " */"
+
+ c_name = bitname(bit)
+ c_val = f"1<<{bit.num}"
+ ret += f"{beg} {c_name:<{namewidth}} (({c_typename(typ)})({c_val})){end}\n"
+ if aliases := [
+ alias
+ for alias in typ.names.values()
+ if isinstance(alias, idl.BitAlias)
+ ]:
+ ret += "\n"
- ret += f"{beg} {c_name.ljust(namewidth)} (({c_typename(typ)})({c_val})){end}\n"
+ for alias in aliases:
+ ret += ifdef_push(2, c_ver_ifdef(alias.in_versions))
+
+ end = ""
+ if _ifdef_stack[-1]:
+ beg = "# define"
+ else:
+ beg = "#define "
+
+ c_name = bitname(alias)
+ c_val = alias.val
+ ret += f"{beg} {c_name:<{namewidth}} (({c_typename(typ)})({c_val})){end}\n"
ret += ifdef_pop(1)
+ del bitname
case idl.Struct(): # and idl.Message():
ret += c_typename(typ) + " {"
if not typ.members:
@@ -554,6 +584,7 @@ enum {idprefix}version {{
ret += f"\t{c_typename(member.typ, member).ljust(typewidth)} {'*' if member.cnt else ' '}{member.membname};\n"
ret += ifdef_pop(1)
ret += "};\n"
+ del typ
ret += ifdef_pop(0)
ret += """
@@ -746,8 +777,13 @@ const char *const _{idprefix}table_ver_name[{c_ver_enum('NUM')}] = {{
ret += (
f"\t[{c_ver_enum(ver)}]{' '*(verwidth-len(ver))} = 0b"
+ "".join(
- "1" if typ.bit_is_valid(bitname, ver) else "0"
- for bitname in reversed(typ.bits)
+ (
+ "1"
+ if bit.cat in (idl.BitCat.USED, idl.BitCat.SUBFIELD)
+ and ver in bit.in_versions
+ else "0"
+ )
+ for bit in reversed(typ.bits)
)
+ ",\n"
)