Skip to content

Commit 8709f98

Browse files
authored
4.4.4 - Use uppercase namespace (#93)
* 4.4.4 - Use uppercase namespace * some work on enum default * WIP * svd structs need ids for ifgen_struct assertion * use new runtimepy * new stuff
1 parent a7ff7b7 commit 8709f98

File tree

20 files changed

+126
-56
lines changed

20 files changed

+126
-56
lines changed

.github/workflows/python-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ jobs:
8484
8585
- run: |
8686
mk python-release owner=libre-embedded \
87-
repo=ifgen version=4.4.3
87+
repo=ifgen version=4.4.4
8888
if: |
8989
matrix.python-version == '3.12'
9090
&& matrix.system == 'ubuntu-latest'

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
=====================================
33
generator=datazen
44
version=3.2.3
5-
hash=72371e50c5b57b71bee199190854d8db
5+
hash=8ee0ca6fb45a3831f000ce66e553d694
66
=====================================
77
-->
88

9-
# ifgen ([4.4.3](https://pypi.org/project/ifgen/))
9+
# ifgen ([4.4.4](https://pypi.org/project/ifgen/))
1010

1111
[![python](https://img.shields.io/pypi/pyversions/ifgen.svg)](https://pypi.org/project/ifgen/)
1212
![Build Status](https://github.com/libre-embedded/ifgen/workflows/Python%20Package/badge.svg)

ifgen/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# =====================================
22
# generator=datazen
33
# version=3.2.3
4-
# hash=520db3f30066c96a8613f5361eca3772
4+
# hash=df27db53be175c0270252c83f57d166d
55
# =====================================
66

77
"""
@@ -10,4 +10,4 @@
1010

1111
DESCRIPTION = "An interface generator for distributed computing."
1212
PKG_NAME = "ifgen"
13-
VERSION = "4.4.3"
13+
VERSION = "4.4.4"

ifgen/common/__init__.py

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ def endianness_single(writer: IndentedFileWriter) -> None:
2525

2626
writer.c_comment("No action for byte-sized primitives.")
2727
writer.write(
28-
"template <byte_size T, std::endian endianness> "
28+
"template <std::endian endianness, byte_size T> "
2929
"inline void handle_endian_p(T *)"
3030
)
3131
with writer.scope():
3232
pass
3333

3434
writer.write(
35-
"template <byte_size T, std::endian endianness> "
35+
"template <std::endian endianness, byte_size T> "
3636
"inline T handle_endian(T elem)"
3737
)
3838
with writer.scope():
@@ -43,7 +43,7 @@ def endianness_native(writer: IndentedFileWriter) -> None:
4343
"""Add methods for native endianness (no swap)."""
4444

4545
writer.c_comment("No action if endianness is native.")
46-
writer.write("template <std::integral T, std::endian endianness>")
46+
writer.write("template <std::endian endianness, std::integral T>")
4747
writer.write("inline void handle_endian_p(T *)")
4848
with writer.indented():
4949
writer.write(
@@ -53,7 +53,7 @@ def endianness_native(writer: IndentedFileWriter) -> None:
5353
with writer.scope():
5454
pass
5555

56-
writer.write("template <std::integral T, std::endian endianness>")
56+
writer.write("template <std::endian endianness, std::integral T>")
5757
writer.write("inline T handle_endian(T elem)")
5858
with writer.indented():
5959
writer.write(
@@ -69,7 +69,7 @@ def endianness_integral(writer: IndentedFileWriter) -> None:
6969

7070
writer.c_comment("Swap any integral type.")
7171

72-
writer.write("template <std::integral T, std::endian endianness>")
72+
writer.write("template <std::endian endianness, std::integral T>")
7373
writer.write("inline T handle_endian(T elem)")
7474
with writer.indented():
7575
writer.write(
@@ -78,7 +78,7 @@ def endianness_integral(writer: IndentedFileWriter) -> None:
7878
with writer.scope():
7979
writer.write("return std::byteswap(elem);")
8080

81-
writer.write("template <std::integral T, std::endian endianness>")
81+
writer.write("template <std::endian endianness, std::integral T>")
8282
writer.write("inline void handle_endian_p(T *elem)")
8383
with writer.indented():
8484
writer.write(
@@ -92,25 +92,22 @@ def endianness_enum(writer: IndentedFileWriter) -> None:
9292
"""Add methods for enum types that require swapping."""
9393

9494
writer.c_comment("Handler for enum class types.")
95-
writer.write("template <typename T, std::endian endianness>")
95+
writer.write("template <std::endian endianness, typename T>")
9696
writer.write("inline void handle_endian_p(T *elem)")
9797
with writer.indented():
9898
writer.write("requires(std::is_enum_v<T>)")
9999
with writer.scope():
100100
writer.write("using underlying = std::underlying_type_t<T>;")
101-
writer.write("handle_endian_p<underlying, endianness>(")
101+
writer.write("handle_endian_p<endianness>(")
102102
with writer.indented():
103103
writer.write("reinterpret_cast<underlying *>(elem));")
104104

105-
writer.write("template <typename T, std::endian endianness>")
105+
writer.write("template <std::endian endianness, typename T>")
106106
writer.write("inline T handle_endian(T elem)")
107107
with writer.indented():
108108
writer.write("requires(std::is_enum_v<T>)")
109109
with writer.scope():
110-
writer.write(
111-
"return static_cast<T>(handle_endian<std::underlying_type_t<T>, "
112-
"endianness>("
113-
)
110+
writer.write("return static_cast<T>(handle_endian<endianness>(")
114111
with writer.indented():
115112
writer.write("std::to_underlying(elem)));")
116113

@@ -122,7 +119,7 @@ def endianness_float(writer: IndentedFileWriter) -> None:
122119
writer.empty()
123120
writer.c_comment(f"Handler for {width}-bit float.")
124121
writer.write(
125-
"template <std::floating_point T, std::endian endianness>"
122+
"template <std::endian endianness, std::floating_point T>"
126123
)
127124
writer.write("inline void handle_endian_p(T *elem)")
128125

@@ -132,12 +129,12 @@ def endianness_float(writer: IndentedFileWriter) -> None:
132129
writer.write(f"requires(sizeof(T) == sizeof({prim}))")
133130
with writer.scope():
134131
writer.write(
135-
f"handle_endian_p<{prim}, endianness>"
132+
f"handle_endian_p<endianness>"
136133
f"(reinterpret_cast<{prim} *>(elem));"
137134
)
138135

139136
writer.write(
140-
"template <std::floating_point T, std::endian endianness>"
137+
"template <std::endian endianness, std::floating_point T>"
141138
)
142139
writer.write("inline T handle_endian(T elem)")
143140
with writer.indented():
@@ -146,7 +143,7 @@ def endianness_float(writer: IndentedFileWriter) -> None:
146143
writer.write("return std::bit_cast<T>(")
147144
with writer.indented():
148145
writer.write(
149-
f"handle_endian<{prim}, endianness>"
146+
"handle_endian<endianness>"
150147
f"(std::bit_cast<{prim}>(elem)));"
151148
)
152149

ifgen/data/schemas/Enum.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ properties:
2929
unit_test:
3030
type: boolean
3131

32+
default:
33+
type: string
34+
3235
underlying:
3336
type: string
3437
default: uint8_t

ifgen/enum/header.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ def cpp_enum_neader(task: GenerateTask, writer: IndentedFileWriter) -> None:
6060
)
6161
writer.empty()
6262

63+
if runtime.default:
64+
writer.write(
65+
f"static constexpr auto {task.name}_default = "
66+
f"{task.name}::{task.instance['default']};"
67+
)
68+
writer.empty()
69+
6370
enum_to_string_function(
6471
task, writer, task.instance["use_map"], definition=True
6572
)

ifgen/enum/python/__init__.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,15 @@ def python_enum_header(task: GenerateTask, writer: IndentedFileWriter) -> None:
4848
built_in["enum"] = ["auto"]
4949
built_in["typing"] = ["Optional"]
5050

51+
runtime = task.enum()
52+
5153
# Write imports.
54+
imports = ["RuntimeIntEnum"]
55+
if runtime.default:
56+
imports.append("T")
5257
python_imports(
5358
writer,
54-
third_party={"runtimepy.enum.registry": ["RuntimeIntEnum"]},
59+
third_party={"runtimepy.enum.registry": imports},
5560
built_in=built_in,
5661
)
5762

@@ -100,4 +105,19 @@ def python_enum_header(task: GenerateTask, writer: IndentedFileWriter) -> None:
100105
final_empty=0,
101106
decorators=["classmethod"],
102107
):
103-
writer.write(f"return {task.enum().id}")
108+
writer.write(f"return {runtime.id}")
109+
110+
if runtime.default:
111+
writer.empty()
112+
with python_function(
113+
writer,
114+
"default",
115+
"Get a possible default value for this enumeration.",
116+
params="cls: type[T]",
117+
return_type="Optional[T]",
118+
final_empty=0,
119+
decorators=["classmethod"],
120+
):
121+
writer.write(
122+
f"return cls.normalize(\"{task.instance['default']}\")"
123+
)

ifgen/environment/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ def _register_enums(self) -> None:
148148
runtime_enum_data(enum["enum"]),
149149
*enum["namespace"],
150150
primitive=type_string(enum["underlying"]),
151+
default=enum.get("default"),
151152
)
152153

153154
self.logger.info(

ifgen/generation/interface.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,13 +298,19 @@ def boilerplate(
298298
writer.empty()
299299
if not is_test:
300300
writer.write("#pragma once")
301-
302301
stack.enter_context(
303302
ifndef_guard(
304303
writer,
305-
f"{self.namespace().replace('::', '_')}"
306-
f"_{path.parent.name.upper()}_"
307-
f"{self.path.name.upper().replace('.', '_')}",
304+
"_".join(
305+
[
306+
x.upper()
307+
for x in [
308+
self.namespace().replace("::", "_"),
309+
path.parent.name,
310+
self.path.name.replace(".", "_"),
311+
]
312+
]
313+
),
308314
)
309315
)
310316
else:

ifgen/plugins/struct_receiver/__init__.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@
22
A struct-receiver interface implementation.
33
"""
44

5+
# built-in
6+
from typing import Any
7+
58
# third-party
9+
from vcorelib.io.arbiter import ARBITER
610
from vcorelib.names import to_snake
11+
from vcorelib.paths import rel
712

813
# internal
14+
from ifgen.enums import Language
915
from ifgen.generation.interface import GenerateTask
1016
from ifgen.generation.python import python_imports
1117
from ifgen.struct import header_for_type
@@ -35,6 +41,30 @@ def python_struct_receiver(task: GenerateTask) -> None:
3541
writer.write(struct + ",")
3642
writer.write(")")
3743

44+
runtimepy_structs: list[Any] = []
45+
for struct in structs:
46+
snake = to_snake(struct)
47+
runtimepy_structs.append(
48+
{
49+
"name": snake,
50+
"config": {
51+
"protocol_factory": ".".join(
52+
list(
53+
rel(
54+
task.env.directories[Language.PYTHON].output,
55+
base=task.env.root_path,
56+
).parts
57+
)
58+
+ ["structs", snake, struct]
59+
)
60+
},
61+
}
62+
)
63+
64+
assert ARBITER.encode(
65+
task.path.with_suffix(".yaml"), {"structs": runtimepy_structs}
66+
)[0]
67+
3868

3969
# pylint: disable=too-many-statements
4070
def cpp_struct_receiver(task: GenerateTask) -> None:

0 commit comments

Comments
 (0)