summaryrefslogtreecommitdiffstats
path: root/rtemsspec/validation.py
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-06-16 19:06:38 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-06-16 19:08:46 +0200
commitcdb62c9f8cd591297bff1c3384dc56d5c752a7bd (patch)
treeec4512df23ea8f4b0414d71a43f7e179ea222e54 /rtemsspec/validation.py
parentinterface: Fix mapper prefix (diff)
downloadrtems-central-cdb62c9f8cd591297bff1c3384dc56d5c752a7bd.tar.bz2
validation: Split file
Diffstat (limited to 'rtemsspec/validation.py')
-rw-r--r--rtemsspec/validation.py645
1 files changed, 5 insertions, 640 deletions
diff --git a/rtemsspec/validation.py b/rtemsspec/validation.py
index 70ed7380..24efc210 100644
--- a/rtemsspec/validation.py
+++ b/rtemsspec/validation.py
@@ -24,20 +24,17 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-# pylint: disable=too-many-lines
-
import itertools
-import math
import os
import re
-import textwrap
-from typing import Any, Dict, Iterator, List, NamedTuple, Optional, Tuple
+from typing import Any, Dict, List, Optional, Tuple
-from rtemsspec.content import CContent, CInclude, enabled_by_to_exp, \
- ExpressionMapper, GenericContent, get_value_params, get_value_plural, \
+from rtemsspec.content import CContent, CInclude, \
+ GenericContent, get_value_params, get_value_plural, \
get_value_doxygen_group, get_value_doxygen_function, to_camel_case
-from rtemsspec.items import is_enabled, Item, ItemCache, \
+from rtemsspec.items import Item, ItemCache, \
ItemGetValueContext, ItemMapper
+from rtemsspec.transitionmap import TransitionMap
ItemMap = Dict[str, Item]
@@ -466,639 +463,7 @@ class _TestSuiteItem(_TestItem):
content.add("/** @} */")
-class Transition(NamedTuple):
- """ Represents a action requirement transition map entry. """
- desc_idx: int
- enabled_by: Any
- skip: int
- pre_cond_na: Tuple[int, ...]
- post_cond: Tuple[Any, ...]
-
-
-def _variant_to_key(variant: Transition) -> str:
- return "".join((enabled_by_to_exp(variant.enabled_by,
- ExpressionMapper()), str(variant.skip),
- str(variant.pre_cond_na), str(variant.post_cond)))
-
-
-class _TransitionEntry:
- def __init__(self):
- self.key = ""
- self.variants = [] # type: List[Transition]
-
- def __bool__(self):
- return bool(self.variants)
-
- def __getitem__(self, key):
- return self.variants[key]
-
- def __len__(self):
- return len(self.variants)
-
- def add(self, variant: Transition) -> None:
- """ Adds the variant to the transitions of the entry. """
- self.key += _variant_to_key(variant)
- self.variants.append(variant)
-
- def replace(self, index: int, variant: Transition) -> None:
- """ Replace the variant at transition variant index. """
- self.key = self.key.replace(_variant_to_key(self.variants[index]),
- _variant_to_key(variant))
- self.variants[index] = variant
-
-
_IdxToX = Tuple[Tuple[str, ...], ...]
-_TransitionMap = List[_TransitionEntry]
-
-
-def _to_st_idx(conditions: List[Any]) -> Tuple[Dict[str, int], ...]:
- return tuple(
- dict((state["name"], st_idx) for st_idx, state in enumerate(
- itertools.chain(condition["states"], [{
- "name": "N/A"
- }]))) for condition in conditions)
-
-
-def _to_st_name(conditions: List[Any]) -> _IdxToX:
- return tuple(
- tuple(
- itertools.chain((state["name"]
- for state in condition["states"]), ["NA"]))
- for condition in conditions)
-
-
-class _PostCondContext(NamedTuple):
- transition_map: "TransitionMap"
- map_idx: int
- pre_co_states: Tuple[int, ...]
- post_co_states: Tuple[Any, ...]
- post_co_idx: int
- ops: Any
-
-
-def _post_cond_bool_and(ctx: _PostCondContext, exp: Any) -> bool:
- for element in exp:
- if not _post_cond_bool_exp(ctx, element):
- return False
- return True
-
-
-def _post_cond_bool_not(ctx: _PostCondContext, exp: Any) -> bool:
- return not _post_cond_bool_exp(ctx, exp)
-
-
-def _post_cond_bool_or(ctx: _PostCondContext, exp: Any) -> bool:
- for element in exp:
- if _post_cond_bool_exp(ctx, element):
- return True
- return False
-
-
-def _post_cond_bool_post_cond(ctx: _PostCondContext, exp: Any) -> bool:
- for post_co_name, status in exp.items():
- if isinstance(status, str):
- status = [status]
- post_co_idx = ctx.transition_map.post_co_name_to_co_idx(post_co_name)
- st_idx = [
- ctx.transition_map.post_co_idx_st_name_to_st_idx(
- post_co_idx, st_name) for st_name in status
- ]
- if ctx.post_co_states[post_co_idx] not in st_idx:
- return False
- return True
-
-
-def _post_cond_bool_pre_cond(ctx: _PostCondContext, exp: Any) -> bool:
- for pre_co_name, status in exp.items():
- if isinstance(status, str):
- status = [status]
- pre_co_idx = ctx.transition_map.pre_co_name_to_co_idx(pre_co_name)
- st_idx = [
- ctx.transition_map.pre_co_idx_st_name_to_st_idx(
- pre_co_idx, st_name) for st_name in status
- ]
- if ctx.pre_co_states[pre_co_idx] not in st_idx:
- return False
- return True
-
-
-_POST_COND_BOOL_OPS = {
- "and": _post_cond_bool_and,
- "not": _post_cond_bool_not,
- "or": _post_cond_bool_or,
- "post-conditions": _post_cond_bool_post_cond,
- "pre-conditions": _post_cond_bool_pre_cond,
-}
-
-
-def _post_cond_bool_exp(ctx: _PostCondContext, exp: Any) -> Optional[int]:
- if isinstance(exp, list):
- return _post_cond_bool_or(ctx, exp)
- key = next(iter(exp))
- return _POST_COND_BOOL_OPS[key](ctx, exp[key])
-
-
-def _post_cond_do_specified_by(ctx: _PostCondContext, pre_co_name: str) -> int:
- pre_co_idx = ctx.transition_map.pre_co_name_to_co_idx(pre_co_name)
- st_name = ctx.transition_map.pre_co_idx_st_idx_to_st_name(
- pre_co_idx, ctx.pre_co_states[pre_co_idx])
- return ctx.transition_map.post_co_idx_st_name_to_st_idx(
- ctx.post_co_idx, st_name)
-
-
-def _post_cond_if(ctx: _PostCondContext) -> Optional[int]:
- if _post_cond_bool_exp(ctx, ctx.ops["if"]):
- if "then-specified-by" in ctx.ops:
- return _post_cond_do_specified_by(ctx,
- ctx.ops["then-specified-by"])
- return ctx.transition_map.post_co_idx_st_name_to_st_idx(
- ctx.post_co_idx, ctx.ops["then"])
- return None
-
-
-def _post_cond_specified_by(ctx: _PostCondContext) -> Optional[int]:
- return _post_cond_do_specified_by(ctx, ctx.ops["specified-by"])
-
-
-def _post_cond_else(ctx: _PostCondContext) -> Optional[int]:
- return ctx.transition_map.post_co_idx_st_name_to_st_idx(
- ctx.post_co_idx, ctx.ops["else"])
-
-
-_POST_COND_OP = {
- "else": _post_cond_else,
- "if": _post_cond_if,
- "specified-by": _post_cond_specified_by,
-}
-
-PostCond = Tuple[int, ...]
-
-PreCondsOfPostCond = List[Tuple[List[int], ...]]
-
-
-def _compact(pre_conds: PreCondsOfPostCond) -> PreCondsOfPostCond:
- while True:
- last = pre_conds[0]
- combined_pre_conds = [last]
- combined_count = 0
- for row in pre_conds[1:]:
- diff = [
- index for index, states in enumerate(last)
- if states != row[index]
- ]
- if len(diff) == 1:
- index = diff[0]
- combined_count += 1
- last[index].extend(row[index])
- else:
- combined_pre_conds.append(row)
- last = row
- pre_conds = combined_pre_conds
- if combined_count == 0:
- break
- return pre_conds
-
-
-def _compact_more(pre_conds: PreCondsOfPostCond) -> PreCondsOfPostCond:
- while True:
- combined_count = 0
- next_pre_conds = []
- while pre_conds:
- first = pre_conds.pop(0)
- next_pre_conds.append(first)
- for row in pre_conds:
- diff = [
- index for index, states in enumerate(first)
- if states != row[index]
- ]
- if len(diff) <= 1:
- if diff:
- index = diff[0]
- first[index].extend(row[index])
- combined_count += 1
- pre_conds.remove(row)
- pre_conds = next_pre_conds
- if combined_count == 0:
- break
- return pre_conds
-
-
-class TransitionMap:
- """ Representation of an action requirement transition map. """
-
- # pylint: disable=too-many-instance-attributes
- def __init__(self, item: Item):
- self._item = item
- self._pre_co_count = len(item["pre-conditions"])
- self._post_co_count = len(item["post-conditions"])
- self.pre_co_summary = tuple(0 for _ in range(self._pre_co_count + 1))
- self._pre_co_idx_st_idx_to_st_name = _to_st_name(
- item["pre-conditions"])
- self._post_co_idx_st_idx_to_st_name = _to_st_name(
- item["post-conditions"])
- self._pre_co_idx_st_name_to_st_idx = _to_st_idx(item["pre-conditions"])
- self._post_co_idx_st_name_to_st_idx = _to_st_idx(
- item["post-conditions"])
- self._pre_co_idx_to_cond = dict(
- (co_idx, condition)
- for co_idx, condition in enumerate(item["pre-conditions"]))
- self._pre_co_name_to_co_idx = dict(
- (condition["name"], co_idx)
- for co_idx, condition in enumerate(item["pre-conditions"]))
- self._post_co_name_to_co_idx = dict(
- (condition["name"], co_idx)
- for co_idx, condition in enumerate(item["post-conditions"]))
- self._post_co_idx_to_co_name = dict(
- (co_idx, condition["name"])
- for co_idx, condition in enumerate(item["post-conditions"]))
- self._skip_idx_to_name = dict(
- (skip_idx + 1, key)
- for skip_idx, key in enumerate(item["skip-reasons"].keys()))
- self._skip_name_to_idx = dict(
- (key, skip_idx + 1)
- for skip_idx, key in enumerate(item["skip-reasons"].keys()))
- self._entries = {} # type: Dict[str, List[Any]]
- self._map = self._build_map()
- self._post_process()
-
- def __getitem__(self, key: str):
- return self._item[key]
-
- def __iter__(self):
- yield from self._map
-
- def entries(self) -> Iterator[List[Any]]:
- """ Yields the transition map entry variants sorted by frequency. """
- yield from sorted(self._entries.values(), key=lambda x: x[1])
-
- def get_variants(self,
- enabled: List[str]) -> Iterator[Tuple[int, Transition]]:
- """
- Yields the map index and the transition variants enabled by the enabled
- list.
- """
- for map_idx, transitions in enumerate(self._map):
- for variant in transitions[1:]:
- if is_enabled(enabled, variant.enabled_by):
- break
- else:
- variant = transitions[0]
- yield map_idx, variant
-
- def get_post_conditions(
- self, enabled: List[str]
- ) -> Iterator[Tuple[PostCond, PreCondsOfPostCond]]:
- """
- Yields tuples of post-condition variants and the corresponding
- pre-condition variants which are enabled by the enabled list.
-
- The first entry of the post-condition variant is the skip index. The
- remaining entries are post-condition indices. The pre-condition
- variants are a list of tuples. Each tuple entry corresponds to a
- pre-condition and provides a list of corresponding pre-condition state
- indices.
- """
- entries = {} # type: Dict[PostCond, PreCondsOfPostCond]
- for map_idx, variant in self.get_variants(enabled):
- key = (variant.skip, ) + variant.post_cond
- entry = entries.setdefault(key, [])
- entry.append(
- tuple([state] for state in self.map_idx_to_pre_co_states(
- map_idx, variant.pre_cond_na)))
- for post_cond, pre_conds in sorted(entries.items(),
- key=lambda x: (x[0][0], len(x[1]))):
- pre_conds = _compact_more(_compact(pre_conds))
- yield post_cond, pre_conds
-
- def _post_process(self) -> None:
- for map_idx, transitions in enumerate(self):
- if not transitions or not isinstance(
- transitions[0].enabled_by,
- bool) or not transitions[0].enabled_by:
- raise ValueError(
- f"transition map of {self._item.spec} contains no default "
- "entry for pre-condition set "
- f"{{{self._map_index_to_pre_conditions(map_idx)}}}")
- entry = self._entries.setdefault(transitions.key,
- [0, 0, transitions, []])
- entry[0] += 1
- entry[3].append(map_idx)
- for index, entry in enumerate(
- sorted(self._entries.values(),
- key=lambda x: x[0],
- reverse=True)):
- entry[1] = index
-
- def _map_index_to_pre_conditions(self, map_idx: int) -> str:
- conditions = []
- for condition in reversed(self._item["pre-conditions"]):
- states = condition["states"]
- count = len(states)
- st_idx = int(map_idx % count)
- conditions.append(f"{condition['name']}={states[st_idx]['name']}")
- map_idx //= count
- return ", ".join(reversed(conditions))
-
- def map_idx_to_pre_co_states(
- self, map_idx: int, pre_cond_na: Tuple[int,
- ...]) -> Tuple[int, ...]:
- """
- Maps the transition map index and the associated pre-condition state
- indices.
- """
- co_states = []
- for condition in reversed(self._item["pre-conditions"]):
- count = len(condition["states"])
- co_states.append(count if pre_cond_na[self._pre_co_name_to_co_idx[
- condition["name"]]] else int(map_idx % count))
- map_idx //= count
- return tuple(reversed(co_states))
-
- def pre_co_name_to_co_idx(self, co_name: str) -> int:
- """
- Maps the pre-condition name to the associated pre-condition index.
- """
- return self._pre_co_name_to_co_idx[co_name]
-
- def pre_co_idx_to_co_name(self, co_idx: int) -> str:
- """
- Maps the pre-condition index to the associated pre-condition name.
- """
- return self._pre_co_idx_to_cond[co_idx]["name"]
-
- def post_co_name_to_co_idx(self, co_name: str) -> int:
- """
- Maps the post-condition name to the associated post-condition index.
- """
- return self._post_co_name_to_co_idx[co_name]
-
- def post_co_idx_to_co_name(self, co_idx: int) -> str:
- """
- Maps the post-condition index to the associated post-condition name.
- """
- return self._post_co_idx_to_co_name[co_idx]
-
- def pre_co_idx_st_idx_to_st_name(self, co_idx: int, st_idx: int) -> str:
- """
- Maps the pre-condition name and state index to the associated state
- name.
- """
- return self._pre_co_idx_st_idx_to_st_name[co_idx][st_idx]
-
- def post_co_idx_st_idx_to_st_name(self, co_idx: int, st_idx: int) -> str:
- """
- Maps the post-condition name and state index to the associated state
- name.
- """
- return self._post_co_idx_st_idx_to_st_name[co_idx][st_idx]
-
- def pre_co_idx_st_name_to_st_idx(self, co_idx: int, st_name: str) -> int:
- """
- Maps the pre-condition index and state name to the associated state
- index.
- """
- return self._pre_co_idx_st_name_to_st_idx[co_idx][st_name]
-
- def post_co_idx_st_name_to_st_idx(self, co_idx: int, st_name: str) -> int:
- """
- Maps the post-condition index and state name to the associated state
- index.
- """
- return self._post_co_idx_st_name_to_st_idx[co_idx][st_name]
-
- def skip_idx_to_name(self, skip_idx: int) -> str:
- """
- Maps the skip index the associated skip name index.
- """
- return self._skip_idx_to_name[skip_idx]
-
- def _map_post_cond(self, map_idx: int, co_idx: int,
- variant: Transition) -> Transition:
- if isinstance(variant.post_cond[co_idx], int):
- return variant
- pre_co_states = self.map_idx_to_pre_co_states(map_idx,
- variant.pre_cond_na)
- for ops in variant.post_cond[co_idx]:
- idx = _POST_COND_OP[next(iter(ops))](_PostCondContext(
- self, map_idx, pre_co_states, variant.post_cond, co_idx, ops))
- if idx is not None:
- return Transition(
- variant.desc_idx, variant.enabled_by, variant.skip,
- variant.pre_cond_na, variant.post_cond[0:co_idx] +
- (idx, ) + variant.post_cond[co_idx + 1:])
- raise ValueError(
- "cannot determine state for post-condition "
- f"'{self._post_co_idx_to_co_name[co_idx]}' of transition map "
- f"descriptor {variant.desc_idx} of {self._item.spec} for "
- "pre-condition set "
- f"{{{self._map_index_to_pre_conditions(map_idx)}}}")
-
- def _make_post_cond(self, map_idx: int, variant: Transition) -> Transition:
- for co_idx in range(len(variant.post_cond)):
- variant = self._map_post_cond(map_idx, co_idx, variant)
- return variant
-
- def _add_variant(self, transition_map: _TransitionMap, map_idx: int,
- variant: Transition) -> None:
- if transition_map[map_idx]:
- for index, existing in enumerate(transition_map[map_idx].variants):
- if existing.enabled_by == variant.enabled_by:
- if variant.skip:
- # Allow transition map variants with a skip reason to
- # overwrite existing variants with the same enabled-by
- # attribute. This is important if variants use N/A for
- # some pre-conditions. It makes it also easier to skip
- # pre-conditon states which are controlled by build
- # options.
- transition_map[map_idx].replace(index, variant)
- return
- raise ValueError(
- f"transition map descriptor {variant.desc_idx} of "
- f"{self._item.spec} duplicates pre-condition set "
- f"{{{self._map_index_to_pre_conditions(map_idx)}}}"
- " defined by transition map descriptor "
- f"{existing.desc_idx}")
- default = transition_map[map_idx][0]
- if (default.post_cond, default.skip,
- default.pre_cond_na) == (variant.post_cond, variant.skip,
- variant.pre_cond_na):
- return
- elif not isinstance(variant.enabled_by,
- bool) or not variant.enabled_by:
- raise ValueError(
- f"transition map descriptor {variant.desc_idx} of "
- f"{self._item.spec} is the first variant for "
- f"{{{self._map_index_to_pre_conditions(map_idx)}}} "
- "and it is not enabled by default")
- self.pre_co_summary = tuple(
- a + b for a, b in zip(self.pre_co_summary, (variant.skip, ) +
- variant.pre_cond_na))
- transition_map[map_idx].add(variant)
-
- def _add_transitions(self, transition_map: _TransitionMap,
- desc: Dict[str, Any], desc_idx: int,
- skip_post_cond: Tuple[Any, ...], co_idx: int,
- map_idx: int, pre_cond_na: Tuple[int, ...]) -> None:
- # pylint: disable=too-many-arguments
- # pylint: disable=too-many-locals
- if co_idx < self._pre_co_count:
- condition = self._pre_co_idx_to_cond[co_idx]
- state_count = len(condition["states"])
- map_idx *= state_count
- states = desc["pre-conditions"][condition["name"]]
- if isinstance(states, str):
- assert states in ["all", "N/A"]
- for st_idx in range(state_count):
- self._add_transitions(
- transition_map, desc, desc_idx, skip_post_cond,
- co_idx + 1, map_idx + st_idx,
- pre_cond_na + (int(states == "N/A"), ))
- else:
- for st_name in states:
- try:
- st_idx = self._pre_co_idx_st_name_to_st_idx[co_idx][
- st_name]
- except KeyError as err:
- msg = (f"transition map descriptor {desc_idx} of "
- f"{self._item.spec} refers to non-existent "
- f"state {err} of pre-condition "
- f"'{condition['name']}'")
- raise ValueError(msg) from err
- self._add_transitions(transition_map, desc, desc_idx,
- skip_post_cond, co_idx + 1,
- map_idx + st_idx,
- pre_cond_na + (0, ))
- else:
- variant = self._make_post_cond(
- map_idx,
- Transition(desc_idx, desc["enabled-by"], skip_post_cond[0],
- pre_cond_na, skip_post_cond[1:]))
- self._add_variant(transition_map, map_idx, variant)
-
- def _add_default(self, transition_map: _TransitionMap, desc: Dict[str,
- Any],
- desc_idx: int, skip_post_cond: Tuple[int, ...]) -> None:
- enabled_by = desc["enabled-by"]
- for map_idx, transition in enumerate(transition_map):
- if not transition:
- transition.add(
- self._make_post_cond(
- map_idx,
- Transition(desc_idx, enabled_by, skip_post_cond[0],
- (0, ) * self._pre_co_count,
- skip_post_cond[1:])))
-
- def _get_post_cond(self, desc: Dict[str, Any], co_idx: int) -> Any:
- info = desc["post-conditions"][self._post_co_idx_to_co_name[co_idx]]
- if isinstance(info, str):
- return self._post_co_idx_st_name_to_st_idx[co_idx][info]
- return info
-
- def _build_map(self) -> _TransitionMap:
- transition_count = 1
- for condition in self["pre-conditions"]:
- state_count = len(condition["states"])
- if state_count == 0:
- raise ValueError(f"pre-condition '{condition['name']}' of "
- f"{self._item.spec} has no states")
- transition_count *= state_count
- transition_map = [_TransitionEntry() for _ in range(transition_count)]
- for desc_idx, desc in enumerate(self["transition-map"]):
- if isinstance(desc["post-conditions"], dict):
- try:
- skip_post_cond = (0, ) + tuple(
- self._get_post_cond(desc, co_idx)
- for co_idx in range(self._post_co_count))
- except KeyError as err:
- msg = (f"transition map descriptor {desc_idx} of "
- f"{self._item.spec} refers to non-existent "
- f"post-condition state {err}")
- raise ValueError(msg) from err
- else:
- skip_post_cond = (
- self._skip_name_to_idx[desc["post-conditions"]], ) + tuple(
- self._post_co_idx_st_name_to_st_idx[co_idx]["N/A"]
- for co_idx in range(self._post_co_count))
- if isinstance(desc["pre-conditions"], dict):
- self._add_transitions(transition_map, desc, desc_idx,
- skip_post_cond, 0, 0, ())
- else:
- assert desc["pre-conditions"] == "default"
- self._add_default(transition_map, desc, desc_idx,
- skip_post_cond)
- return transition_map
-
- def _get_entry(self, ident: str, variant: Transition) -> str:
- text = "{ " + ", ".join(
- itertools.chain(
- map(str, (int(variant.skip != 0), ) + variant.pre_cond_na),
- ((f"{ident}_Post_{self._post_co_idx_to_co_name[co_idx]}"
- f"_{self._post_co_idx_st_idx_to_st_name[co_idx][st_idx]}")
- for co_idx, st_idx in enumerate(variant.post_cond))))
- wrapper = textwrap.TextWrapper()
- wrapper.initial_indent = " "
- wrapper.subsequent_indent = " "
- wrapper.width = 79
- return "\n".join(wrapper.wrap(text)) + " },"
-
- def _get_entry_bits(self) -> int:
- bits = self._pre_co_count + 1
- for st_idx_to_st_name in self._post_co_idx_st_idx_to_st_name:
- bits += math.ceil(math.log2(len(st_idx_to_st_name)))
- return 2**max(math.ceil(math.log2(bits)), 3)
-
- def add_map(self, content: CContent, ident: str) -> None:
- """ Adds the transition map definitions to the content. """
- entries = []
- mapper = ExpressionMapper()
- for entry in self.entries():
- transitions = entry[2]
- if len(transitions) == 1:
- entries.append(self._get_entry(ident, transitions[0]))
- else:
- ifelse = "#if "
- enumerators = [] # type: List[str]
- for variant in transitions[1:]:
- enumerators.append(
- ifelse + enabled_by_to_exp(variant.enabled_by, mapper))
- enumerators.append(self._get_entry(ident, variant))
- ifelse = "#elif "
- enumerators.append("#else")
- enumerators.append(self._get_entry(ident, transitions[0]))
- enumerators.append("#endif")
- entries.append("\n".join(enumerators))
- bits = self._get_entry_bits()
- content.add("typedef struct {")
- with content.indent():
- content.append(f"uint{bits}_t Skip : 1;")
- for condition in self["pre-conditions"]:
- content.append(f"uint{bits}_t Pre_{condition['name']}_NA : 1;")
- for condition in self["post-conditions"]:
- state_bits = math.ceil(math.log2(len(condition["states"]) + 1))
- content.append(
- f"uint{bits}_t Post_{condition['name']} : {state_bits};")
- content.add(f"}} {ident}_Entry;")
- content.add([f"static const {ident}_Entry", f"{ident}_Entries[] = {{"])
- entries[-1] = entries[-1].replace("},", "}")
- content.append(entries)
- bits = max(8, math.ceil(math.log2(len(self._entries)) / 8) * 8)
- content.append(
- ["};", "", f"static const uint{bits}_t", f"{ident}_Map[] = {{"])
- text = ", ".join(
- str(self._entries[transitions.key][1])
- for transitions in self._map)
- wrapper = textwrap.TextWrapper()
- wrapper.initial_indent = " "
- wrapper.subsequent_indent = " "
- wrapper.width = 79
- content.append(wrapper.wrap(text))
- content.append("};")
-
- def get_post_entry_member(self, co_idx: int) -> str:
- """
- Gets the post-condition entry member name for the post-condition index.
- """
- return f"Post_{self._post_co_idx_to_co_name[co_idx]}"
def _to_enum(prefix: str, conditions: List[Any]) -> _IdxToX: