diff options
Diffstat (limited to 'lib9p/idl.gen')
-rwxr-xr-x | lib9p/idl.gen | 98 |
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" ) |