summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-04-13 10:07:12 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-04-13 10:24:16 +0200
commit9e7ee2687d8f0189564b9e72a2d598444a8433d2 (patch)
tree427955f68e9a72eeb2fd86aaaf48c25cc01deea3
parentspec: New cases for /rtems/sem/req/obtain (diff)
downloadrtems-central-9e7ee2687d8f0189564b9e72a2d598444a8433d2.tar.bz2
validation: Add get_post_conditions()
-rw-r--r--rtemsspec/tests/spec-validation/action2.yml10
-rw-r--r--rtemsspec/tests/test_validation.py19
-rw-r--r--rtemsspec/validation.py49
-rwxr-xr-xspecview.py45
4 files changed, 79 insertions, 44 deletions
diff --git a/rtemsspec/tests/spec-validation/action2.yml b/rtemsspec/tests/spec-validation/action2.yml
index 822a4701..8c269a12 100644
--- a/rtemsspec/tests/spec-validation/action2.yml
+++ b/rtemsspec/tests/spec-validation/action2.yml
@@ -272,4 +272,14 @@ transition-map:
- B0
C:
- C0
+- enabled-by: BOOM
+ post-conditions:
+ A: N/A
+ B: B0
+ pre-conditions:
+ A: N/A
+ B:
+ - B0
+ C:
+ - C0
type: requirement
diff --git a/rtemsspec/tests/test_validation.py b/rtemsspec/tests/test_validation.py
index 938762c3..a35ff371 100644
--- a/rtemsspec/tests/test_validation.py
+++ b/rtemsspec/tests/test_validation.py
@@ -49,8 +49,13 @@ def test_validation(tmpdir):
assert len(list(transition_map.get_variants([]))) == 36
assert len(list(transition_map.get_variants(["RTEMS_MULTIPROCESSING"
]))) == 36
+ assert len(list(transition_map.get_post_conditions([]))) == 4
+ assert len(
+ list(transition_map.get_post_conditions(["RTEMS_MULTIPROCESSING"
+ ]))) == 5
transition_map = TransitionMap(item_cache["/action2"])
assert transition_map.skip_idx_to_name(1) == "SkipReason"
+ assert len(list(transition_map.get_post_conditions(["BOOM"]))) == 6
generate(validation_config, item_cache)
@@ -2109,14 +2114,24 @@ static const Action2_Entry
Action2_Entries[] = {
{ 0, 1, 0, 0, Action2_Post_A_A1, Action2_Post_B_NA },
{ 0, 0, 0, 0, Action2_Post_A_A2, Action2_Post_B_B0 },
- { 0, 0, 0, 0, Action2_Post_A_A1, Action2_Post_B_B0 },
{ 1, 0, 0, 0, Action2_Post_A_NA, Action2_Post_B_NA },
+ { 0, 0, 0, 0, Action2_Post_A_A1, Action2_Post_B_B0 },
+#if defined(BOOM)
+ { 0, 1, 0, 0, Action2_Post_A_NA, Action2_Post_B_B0 },
+#else
+ { 0, 0, 0, 0, Action2_Post_A_A1, Action2_Post_B_B0 },
+#endif
+#if defined(BOOM)
+ { 0, 1, 0, 0, Action2_Post_A_NA, Action2_Post_B_B0 },
+#else
+ { 0, 0, 0, 0, Action2_Post_A_A2, Action2_Post_B_B0 },
+#endif
{ 0, 0, 0, 0, Action2_Post_A_A3, Action2_Post_B_B0 }
};
static const uint8_t
Action2_Map[] = {
- 2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 4, 0, 0, 0, 3, 3, 3
+ 4, 3, 3, 0, 0, 0, 1, 1, 1, 5, 1, 6, 0, 0, 0, 2, 2, 2
};
static size_t Action2_Scope( void *arg, char *buf, size_t n )
diff --git a/rtemsspec/validation.py b/rtemsspec/validation.py
index 944764f6..baff5305 100644
--- a/rtemsspec/validation.py
+++ b/rtemsspec/validation.py
@@ -615,6 +615,10 @@ _POST_COND_OP = {
"specified-by": _post_cond_specified_by,
}
+PostCond = Tuple[int, ...]
+
+PreCondsOfPostCond = List[Tuple[List[int], ...]]
+
class TransitionMap:
""" Representation of an action requirement transition map. """
@@ -677,6 +681,51 @@ class TransitionMap:
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]))):
+ while True:
+ last = pre_conds[0]
+ combined_pre_conds = [last]
+ combined_count = 0
+ for row in pre_conds[1:]:
+ if row == last:
+ continue
+ 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
+ yield post_cond, pre_conds
+
def _post_process(self) -> None:
for map_idx, transitions in enumerate(self):
if not transitions or not isinstance(
diff --git a/specview.py b/specview.py
index 40c988d1..5ef0f731 100755
--- a/specview.py
+++ b/specview.py
@@ -28,7 +28,7 @@
import argparse
import itertools
import sys
-from typing import Dict, Iterator, List, Set, Tuple
+from typing import List, Set, Tuple
from rtemsspec.items import Item, ItemCache, Link
from rtemsspec.sphinxcontent import SphinxContent
@@ -124,48 +124,9 @@ def _to_name(transition_map, co_idx: int, st_idx: int) -> str:
f"{transition_map.post_co_idx_st_idx_to_st_name(co_idx, st_idx)}")
-_PostCond = Tuple[int, ...]
-_Entries = List[Tuple[List[int], ...]]
-
-
-def _get_entries(transition_map: TransitionMap,
- enabled: List[str]) -> Iterator[Tuple[_PostCond, _Entries]]:
- entries = {} # type: Dict[_PostCond, _Entries]
- for map_idx, variant in transition_map.get_variants(enabled):
- key = (variant.skip, ) + variant.post_cond
- entry = entries.setdefault(key, [])
- entry.append(
- tuple([state] for state in transition_map.map_idx_to_pre_co_states(
- map_idx, variant.pre_cond_na)))
- for post_cond, entry in sorted(entries.items(),
- key=lambda x: (x[0][0], len(x[1]))):
- while True:
- last = entry[0]
- combined_entry = [last]
- combined_count = 0
- for row in entry[1:]:
- if row == last:
- continue
- 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_entry.append(row)
- last = row
- entry = combined_entry
- if combined_count == 0:
- break
- yield post_cond, entry
-
-
def _action_list(enabled: List[str], item: Item) -> None:
transition_map = TransitionMap(item)
- for post_cond, entry in _get_entries(transition_map, enabled):
+ for post_cond, pre_conds in transition_map.get_post_conditions(enabled):
print("")
if post_cond[0]:
print(transition_map.skip_idx_to_name(post_cond[0]))
@@ -173,7 +134,7 @@ def _action_list(enabled: List[str], item: Item) -> None:
print(", ".join(
_to_name(transition_map, co_idx, st_idx)
for co_idx, st_idx in enumerate(post_cond[1:])))
- for row in entry:
+ for row in pre_conds:
entries = []
for co_idx, co_states in enumerate(row):
co_name = transition_map.pre_co_idx_to_co_name(co_idx)