specware 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,48 @@
1
+ Metadata-Version: 2.4
2
+ Name: specware
3
+ Version: 1.1.0
4
+ Summary: Provides utilities to specify software.
5
+ Keywords: certification,documentation,markdown,qualification,requirements-management,traceability
6
+ Author: The specware Authors
7
+ Author-email: The specware Authors <specthings@embedded-brains.de>
8
+ License-Expression: BSD-2-Clause
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: POSIX
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Topic :: Software Development :: Documentation
19
+ Classifier: Topic :: Software Development :: Quality Assurance
20
+ Classifier: Topic :: Software Development :: Testing :: Acceptance
21
+ Classifier: Topic :: Text Processing :: Markup
22
+ Classifier: Typing :: Typed
23
+ Requires-Dist: specitems>=1.1.1
24
+ Requires-Python: >=3.11
25
+ Project-URL: Source Code, https://github.com/specthings/specware
26
+ Project-URL: Bug Tracker, https://github.com/specthings/specware/issues
27
+ Description-Content-Type: text/markdown
28
+
29
+ <!--
30
+ SPDX-License-Identifier: CC-BY-SA-4.0
31
+
32
+ Copyright (C) 2026 embedded brains GmbH & Co. KG
33
+ -->
34
+ ## Overview
35
+
36
+ The *specware* Python package provides utilities to specify software and
37
+ generate source code for interfaces and validation tests from the
38
+ specification. The package uses the specification item framework provided by
39
+ [specitems](https://github.com/specthings/specitems).
40
+
41
+ The package is maintained by the
42
+ [specthings](https://github.com/specthings)
43
+ project.
44
+
45
+ ## Contributing
46
+
47
+ Please refer to our
48
+ [Contributing Guidelines](https://github.com/specthings/specware/blob/main/CONTRIBUTING.md).
@@ -0,0 +1,20 @@
1
+ <!--
2
+ SPDX-License-Identifier: CC-BY-SA-4.0
3
+
4
+ Copyright (C) 2026 embedded brains GmbH & Co. KG
5
+ -->
6
+ ## Overview
7
+
8
+ The *specware* Python package provides utilities to specify software and
9
+ generate source code for interfaces and validation tests from the
10
+ specification. The package uses the specification item framework provided by
11
+ [specitems](https://github.com/specthings/specitems).
12
+
13
+ The package is maintained by the
14
+ [specthings](https://github.com/specthings)
15
+ project.
16
+
17
+ ## Contributing
18
+
19
+ Please refer to our
20
+ [Contributing Guidelines](https://github.com/specthings/specware/blob/main/CONTRIBUTING.md).
@@ -0,0 +1,74 @@
1
+ # SPDX-License-Identifier: BSD-2-Clause
2
+
3
+ # Copyright (C) 2026 embedded brains GmbH & Co. KG
4
+
5
+ [project]
6
+ name = "specware"
7
+ version = "1.1.0"
8
+ description = "Provides utilities to specify software."
9
+ authors = [
10
+ {name = "The specware Authors", email = "specthings@embedded-brains.de"}
11
+ ]
12
+ license = "BSD-2-Clause"
13
+ readme = "README.md"
14
+ requires-python = ">=3.11"
15
+ dependencies = [
16
+ "specitems >=1.1.1",
17
+ ]
18
+ keywords = [
19
+ "certification",
20
+ "documentation",
21
+ "markdown",
22
+ "qualification",
23
+ "requirements-management",
24
+ "traceability",
25
+ ]
26
+ classifiers = [
27
+ "Development Status :: 5 - Production/Stable",
28
+ "Environment :: Console",
29
+ "Intended Audience :: Developers",
30
+ "Operating System :: POSIX",
31
+ "Programming Language :: Python :: 3",
32
+ "Programming Language :: Python :: 3.11",
33
+ "Programming Language :: Python :: 3.12",
34
+ "Programming Language :: Python :: 3.13",
35
+ "Programming Language :: Python :: 3.14",
36
+ "Topic :: Software Development :: Documentation",
37
+ "Topic :: Software Development :: Quality Assurance",
38
+ "Topic :: Software Development :: Testing :: Acceptance",
39
+ "Topic :: Text Processing :: Markup",
40
+ "Typing :: Typed",
41
+ ]
42
+
43
+ [project.urls]
44
+ "Source Code" = "https://github.com/specthings/specware"
45
+ "Bug Tracker" = "https://github.com/specthings/specware/issues"
46
+
47
+ [project.scripts]
48
+ specwareexport = "specware.cliexport:cliexport"
49
+ specwareexportheader = "specware.cliexportheader:cliexportheader"
50
+ specwareverify = "specware.cliverify:cliverify"
51
+ specwareview = "specware.cliview:cliview"
52
+
53
+ [build-system]
54
+ requires = ["uv_build>=0.10.0,<0.11.0"]
55
+ build-backend = "uv_build"
56
+
57
+ [dependency-groups]
58
+ dev = [
59
+ "coverage>=7.13.3",
60
+ "flake8>=7.3.0",
61
+ "mypy>=1.19.1",
62
+ "pylint>=4.0.4",
63
+ "pytest>=9.0.2",
64
+ "pytest-cov>=7.0.0",
65
+ "sphinx>=9.0.4",
66
+ "sphinx-autodoc-napoleon-typehints>=2.1.6",
67
+ "sphinx-autodoc-typehints>=3.6.1",
68
+ "sphinx-rtd-theme>=3.1.0",
69
+ "types-pyyaml>=6.0.12.20250915",
70
+ "yapf>=0.43.0",
71
+ ]
72
+
73
+ [tool.pytest.ini_options]
74
+ addopts = "--cov=specware --cov-fail-under=100 --cov-branch --cov-report=term-missing --cov-config=.coveragerc"
@@ -0,0 +1,36 @@
1
+ # SPDX-License-Identifier: BSD-2-Clause
2
+ """ This is the specware package. """
3
+
4
+ # Copyright (C) 2019, 2025 embedded brains GmbH & Co. KG
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions
8
+ # are met:
9
+ # 1. Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # 2. Redistributions in binary form must reproduce the above copyright
12
+ # notice, this list of conditions and the following disclaimer in the
13
+ # documentation and/or other materials provided with the distribution.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
+ # POSSIBILITY OF SUCH DAMAGE.
26
+
27
+ from .applconfig import * # noqa: F401, F403
28
+ from .build import * # noqa: F401, F403
29
+ from .contentc import * # noqa: F401, F403
30
+ from .interface import * # noqa: F401, F403
31
+ from .interfacedoc import * # noqa: F401, F403
32
+ from .interfacemapper import * # noqa: F401, F403
33
+ from .rtems import * # noqa: F401, F403
34
+ from .transitionmap import * # noqa: F401, F403
35
+ from .util import * # noqa: F401, F403
36
+ from .validation import * # noqa: F401, F403
@@ -0,0 +1,396 @@
1
+ # SPDX-License-Identifier: BSD-2-Clause
2
+ """
3
+ Provides methods to generate the application configuration documentation.
4
+ """
5
+
6
+ # Copyright (C) 2019, 2025 embedded brains GmbH & Co. KG
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions
10
+ # are met:
11
+ # 1. Redistributions of source code must retain the above copyright
12
+ # notice, this list of conditions and the following disclaimer.
13
+ # 2. Redistributions in binary form must reproduce the above copyright
14
+ # notice, this list of conditions and the following disclaimer in the
15
+ # documentation and/or other materials provided with the distribution.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
+ # POSSIBILITY OF SUCH DAMAGE.
28
+
29
+ from typing import Any, Callable, Optional
30
+
31
+ from specitems import (Content, EnabledSet, GenericContent, get_value_plural,
32
+ Item, ItemCache, ItemGetValueContext, ItemMapper,
33
+ TextContent)
34
+
35
+ from .contentc import (CContent, get_value_double_colon,
36
+ get_value_doxygen_function, get_value_doxygen_group,
37
+ get_value_doxygen_ref, get_value_hash,
38
+ get_value_header_file)
39
+
40
+ _FEATURE = "This configuration option is a boolean feature define."
41
+
42
+ _OPTION_TYPES = {
43
+ "feature": _FEATURE,
44
+ "feature-enable": _FEATURE,
45
+ "integer": "This configuration option is an integer define.",
46
+ "initializer": "This configuration option is an initializer define."
47
+ }
48
+
49
+ _OPTION_DEFAULT_CONFIG = {
50
+ "feature":
51
+ lambda item: item["default"],
52
+ "feature-enable":
53
+ lambda item:
54
+ """If this configuration option is undefined, then the described feature \
55
+ is not
56
+ enabled."""
57
+ }
58
+
59
+
60
+ class _ContentAdaptor:
61
+ """
62
+ Provides a specialized interface to a content class.
63
+
64
+ By default, Sphinx content is generated.
65
+ """
66
+
67
+ def __init__(self, mapper: ItemMapper, content: Any) -> None:
68
+ self.mapper = mapper
69
+ self.content = content
70
+
71
+ def substitute(self, text: Optional[str]) -> str:
72
+ """ Substitute the optional text using the item mapper. """
73
+ return self.mapper.substitute(text)
74
+
75
+ def add_group(self, uid: str, name: str, description: str) -> None:
76
+ """ Add the option group. """
77
+ self.content.add_automatically_generated_warning()
78
+ with self.content.comment_block():
79
+ self.content.add(f"Generated from spec:{uid}")
80
+ self.content.add_header(name, level=self.content.section_level)
81
+ self.content.add(description)
82
+
83
+ def _add_rubric(self,
84
+ name: str,
85
+ text: GenericContent,
86
+ wrap: bool = False) -> None:
87
+ if not text:
88
+ return
89
+ self.content.add_rubric(f"{name}:")
90
+ if wrap:
91
+ self.content.wrap(text)
92
+ else:
93
+ self.content.add(text)
94
+
95
+ def add_option(self, uid: str, name: str,
96
+ index_entries: list[str]) -> None:
97
+ """ Add the option. """
98
+ with self.content.comment_block():
99
+ self.content.add(f"Generated from spec:{uid}")
100
+ with self.content.directive("raw", "latex"):
101
+ self.content.add("\\clearpage")
102
+ self.content.add_index_entries([name] + index_entries)
103
+ self.content.add_header(name,
104
+ level=self.content.section_level + 1,
105
+ label=name)
106
+ self._add_rubric("CONSTANT", self.content.code(name))
107
+
108
+ def add_option_type(self, option_type: str) -> None:
109
+ """ Add the option type. """
110
+ self._add_rubric("OPTION TYPE", option_type)
111
+
112
+ def add_option_default_value(self, value: str) -> None:
113
+ """ Add the option default value. """
114
+ self._add_rubric("DEFAULT VALUE", value)
115
+
116
+ def add_option_default_config(self, config: str) -> None:
117
+ """ Add the option default configuration. """
118
+ self._add_rubric("DEFAULT CONFIGURATION", config)
119
+
120
+ def add_option_description(self, description: str) -> None:
121
+ """ Add the option description. """
122
+ self._add_rubric("DESCRIPTION", description)
123
+
124
+ def add_option_notes(self, notes: str) -> None:
125
+ """ Add the option notes. """
126
+ self._add_rubric("NOTES", notes)
127
+
128
+ def add_option_constraints(self, lines: list[str]) -> None:
129
+ """ Add the option value constraints. """
130
+ self._add_rubric("CONSTRAINTS", lines, wrap=True)
131
+
132
+ def add_licence_and_copyrights(self) -> None:
133
+ """ Add the license and copyrights. """
134
+ self.content.add_licence_and_copyrights()
135
+
136
+ def register_license_and_copyrights_of_item(self, item: Item) -> None:
137
+ """ Register the license and copyrights of the item. """
138
+ self.content.register_license_and_copyrights_of_item(item)
139
+
140
+ def write(self, filename: str):
141
+ """ Write the content to the file specified by the path. """
142
+ self.content.write(filename, beautify=True)
143
+
144
+
145
+ class _TextContentAdaptor(_ContentAdaptor):
146
+
147
+ def __init__(self, mapper: ItemMapper, content: TextContent) -> None:
148
+ super().__init__(mapper, content)
149
+
150
+
151
+ class _DoxygenContentAdaptor(_ContentAdaptor):
152
+ # pylint: disable=attribute-defined-outside-init
153
+
154
+ def __init__(self, mapper: ItemMapper) -> None:
155
+ super().__init__(mapper, CContent())
156
+ self._reset()
157
+
158
+ def _reset(self) -> None:
159
+ self._name = ""
160
+ self._option_type = ""
161
+ self._default_value = ""
162
+ self._default_config = ""
163
+ self._notes = ""
164
+ self._description = ""
165
+
166
+ def add_group(self, uid: str, name: str, description: str) -> None:
167
+ identifier = f"RTEMSApplConfig{name.replace(' ', '')}"
168
+ self.content.add(f"/* Generated from spec:{uid} */")
169
+ with self.content.defgroup_block(identifier, name):
170
+ self.content.add("@ingroup RTEMSApplConfig")
171
+ self.content.wrap(description)
172
+ self.content.add("@{")
173
+
174
+ def add_option(self, uid: str, name: str,
175
+ _index_entries: list[str]) -> None:
176
+ self.content.add(f"/* Generated from spec:{uid} */")
177
+ self.content.open_doxygen_block()
178
+ self._name = name
179
+
180
+ def add_option_type(self, option_type: str) -> None:
181
+ self._option_type = option_type
182
+
183
+ def add_option_default_value(self, value: str) -> None:
184
+ self._default_value = value
185
+
186
+ def add_option_default_config(self, config: str) -> None:
187
+ self._default_config = config
188
+
189
+ def add_option_description(self, description: str) -> None:
190
+ self._description = description
191
+
192
+ def add_option_notes(self, notes: str) -> None:
193
+ self._notes = notes
194
+
195
+ def add_option_constraints(self, lines: list[str]) -> None:
196
+ self.content.add_brief_description(self._option_type)
197
+ self.content.add(f"@anchor {self._name}")
198
+ self.content.wrap(self._description)
199
+ self.content.add_paragraph("Default Value", self._default_value)
200
+ self.content.add_paragraph("Default Configuration",
201
+ self._default_config)
202
+ self.content.add_paragraph("Constraints", lines)
203
+ self.content.add_paragraph("Notes", self._notes)
204
+ self.content.close_comment_block()
205
+ self.content.append(f"#define {self._name}")
206
+ self._reset()
207
+
208
+ def add_licence_and_copyrights(self) -> None:
209
+ self.content.add("/** @} */")
210
+
211
+
212
+ def _generate_feature(content: _ContentAdaptor, item: Item,
213
+ option_type: str) -> None:
214
+ content.add_option_default_config(
215
+ content.substitute(_OPTION_DEFAULT_CONFIG[option_type](item)))
216
+
217
+
218
+ def _get_constraints(content: _ContentAdaptor, item: Item,
219
+ enabled_set: EnabledSet) -> list[str]:
220
+ constraints: list[str] = []
221
+ for parent in item.parents("constraint"):
222
+ if not parent.is_enabled(enabled_set):
223
+ continue
224
+ content.register_license_and_copyrights_of_item(parent)
225
+ constraints.append(
226
+ content.substitute(parent["text"]).replace(
227
+ "application configuration option", "configuration option"))
228
+ return constraints
229
+
230
+
231
+ def _generate_constraints(content: _ContentAdaptor, item: Item,
232
+ enabled_set: EnabledSet) -> None:
233
+ constraints = _get_constraints(content, item, enabled_set)
234
+ if len(constraints) > 1:
235
+ constraint_list = Content("BSD-2-Clause")
236
+ prologue = ("The following constraints apply "
237
+ "to this configuration option:")
238
+ constraint_list.add_list(constraints, prologue)
239
+ constraints = constraint_list.lines
240
+ content.add_option_constraints(constraints)
241
+
242
+
243
+ def _generate_initializer_or_integer(content: _ContentAdaptor, item: Item,
244
+ _option_type: str) -> None:
245
+ default_value = item["default-value"]
246
+ if not isinstance(default_value, str) or " " not in default_value:
247
+ default_value = f"The default value is {default_value}."
248
+ content.add_option_default_value(content.substitute(default_value))
249
+
250
+
251
+ _OPTION_GENERATORS = {
252
+ "feature": _generate_feature,
253
+ "feature-enable": _generate_feature,
254
+ "initializer": _generate_initializer_or_integer,
255
+ "integer": _generate_initializer_or_integer
256
+ }
257
+
258
+
259
+ def _document_option(item: Item, enabled_set: EnabledSet,
260
+ content: _ContentAdaptor) -> None:
261
+ option_type = item["appl-config-option-type"]
262
+ content.add_option_type(_OPTION_TYPES[option_type])
263
+ _OPTION_GENERATORS[option_type](content, item, option_type)
264
+ content.add_option_description(content.substitute(item["description"]))
265
+ content.add_option_notes(content.substitute(item["notes"]))
266
+ _generate_constraints(content, item, enabled_set)
267
+
268
+
269
+ def document_option(content: TextContent, mapper: ItemMapper, item: Item,
270
+ enabled_set: EnabledSet) -> None:
271
+ """
272
+ Document the option specified by the item using the item mapper and enabled
273
+ set.
274
+ """
275
+ _document_option(item, enabled_set, _TextContentAdaptor(mapper, content))
276
+
277
+
278
+ def _generate(group: Item, options: dict[str, Item], enabled_set: EnabledSet,
279
+ content: _ContentAdaptor) -> None:
280
+ content.register_license_and_copyrights_of_item(group)
281
+ content.add_group(group.uid, group["name"],
282
+ content.substitute(group["description"]))
283
+ for item in sorted(options.values(), key=lambda x: x["name"]):
284
+ content.mapper.item = item
285
+ content.register_license_and_copyrights_of_item(item)
286
+ content.add_option(item.uid, item["name"], item["index-entries"])
287
+ _document_option(item, enabled_set, content)
288
+ content.add_licence_and_copyrights()
289
+
290
+
291
+ def _get_value(ctx: ItemGetValueContext) -> str:
292
+ return ctx.value[ctx.key]
293
+
294
+
295
+ def _get_value_doxygen_url(
296
+ ctx: ItemGetValueContext,
297
+ get_value: Callable[[ItemGetValueContext],
298
+ str] = _get_value) -> Optional[str]:
299
+ for ref in ctx.item["references"]:
300
+ if ref["type"] == "url":
301
+ return f"<a href=\"{ref['identifier']}\">{get_value(ctx)}</a>"
302
+ return None
303
+
304
+
305
+ def _get_value_doxygen_unspecified_define(ctx: ItemGetValueContext) -> Any:
306
+ return _get_value_doxygen_url(ctx) or get_value_hash(ctx)
307
+
308
+
309
+ def _get_value_doxygen_unspecified_function(ctx: ItemGetValueContext) -> Any:
310
+ return _get_value_doxygen_url(
311
+ ctx, get_value_doxygen_function) or get_value_doxygen_function(ctx)
312
+
313
+
314
+ def _get_value_doxygen_unspecified_group(ctx: ItemGetValueContext) -> Any:
315
+ return _get_value_doxygen_url(ctx) or ctx.value[ctx.key]
316
+
317
+
318
+ def _get_value_doxygen_unspecfied_type(ctx: ItemGetValueContext) -> Any:
319
+ return _get_value_doxygen_url(ctx) or get_value_double_colon(ctx)
320
+
321
+
322
+ def _add_doxygen_get_values(mapper: ItemMapper) -> None:
323
+ for opt in ["feature-enable", "feature", "initializer", "integer"]:
324
+ name = f"interface/appl-config-option/{opt}:/name"
325
+ mapper.add_get_value(name, get_value_doxygen_ref)
326
+ mapper.add_get_value("glossary/term:/plural", get_value_plural)
327
+ mapper.add_get_value("interface/define:/name", get_value_hash)
328
+ mapper.add_get_value("interface/function:/name",
329
+ get_value_doxygen_function)
330
+ mapper.add_get_value("interface/group:/name", get_value_doxygen_group)
331
+ mapper.add_get_value("interface/header-file:/path", get_value_header_file)
332
+ mapper.add_get_value("interface/macro:/name", get_value_doxygen_function)
333
+ mapper.add_get_value("interface/struct:/name", get_value_double_colon)
334
+ mapper.add_get_value("interface/typedef:/name", get_value_double_colon)
335
+ mapper.add_get_value("interface/union:/name", get_value_double_colon)
336
+ mapper.add_get_value("interface/unspecified-define:/name",
337
+ _get_value_doxygen_unspecified_define)
338
+ mapper.add_get_value("interface/unspecified-function:/name",
339
+ _get_value_doxygen_unspecified_function)
340
+ mapper.add_get_value("interface/unspecified-group:/name",
341
+ _get_value_doxygen_unspecified_group)
342
+ mapper.add_get_value("interface/unspecified-enum:/name",
343
+ _get_value_doxygen_unspecfied_type)
344
+ mapper.add_get_value("interface/unspecified-struct:/name",
345
+ _get_value_doxygen_unspecfied_type)
346
+ mapper.add_get_value("interface/unspecified-typedef:/name",
347
+ _get_value_doxygen_unspecfied_type)
348
+ mapper.add_get_value("interface/unspecified-union:/name",
349
+ _get_value_doxygen_unspecfied_type)
350
+
351
+
352
+ def generate_application_configuration(
353
+ config: dict, group_uids: list[str], item_cache: ItemCache,
354
+ create_mapper: Callable[[Item, list[str]], ItemMapper],
355
+ create_content: Callable[[], TextContent]) -> None:
356
+ """
357
+ Generate the application configuration documentation sources according to
358
+ the configuration.
359
+
360
+ Args:
361
+ config: The application configuration generation configuration.
362
+ item_cache: The item cache containing the application configuration
363
+ groups and options.
364
+ create_mapper: The item mapper constructor to create mappers used for
365
+ content substitutions.
366
+ create_content: The content builder constructor.
367
+ """
368
+ some_item = next(iter(item_cache.values()))
369
+ text_mapper = create_mapper(some_item, group_uids)
370
+ doxygen_mapper = ItemMapper(some_item)
371
+ _add_doxygen_get_values(doxygen_mapper)
372
+ doxygen_content = _DoxygenContentAdaptor(doxygen_mapper)
373
+ doxygen_content.content.add_automatically_generated_warning()
374
+ with doxygen_content.content.defgroup_block(
375
+ "RTEMSApplConfig", "Application Configuration Options"):
376
+ doxygen_content.content.add("@ingroup RTEMSAPI")
377
+ for group_config in config["groups"]:
378
+ group = item_cache[group_config["uid"]]
379
+ assert group.type == "interface/appl-config-group"
380
+ options: dict[str, Item] = {}
381
+ for child in group.children("interface-ingroup"):
382
+ if child.type.startswith("interface/appl-config-option"):
383
+ options[child.uid] = child
384
+ text_content = _TextContentAdaptor(text_mapper, create_content())
385
+ _generate(group, options, config["enabled-documentation"],
386
+ text_content)
387
+ text_content.write(group_config["target"])
388
+ _generate(group, options, config["enabled-source"], doxygen_content)
389
+ doxygen_content.content.prepend_copyrights_and_licenses()
390
+ doxygen_content.content.prepend([
391
+ "/**", " * @file", " *", " * @ingroup RTEMSImplDoxygen", " *",
392
+ " * @brief This header file documents "
393
+ "the application configuration options.", " */", ""
394
+ ])
395
+ doxygen_content.content.prepend_spdx_license_identifier()
396
+ doxygen_content.write(config["doxygen-target"])