From c67997b294afe15ed126dcdb41bbf5e2de6ad131 Mon Sep 17 00:00:00 2001 From: sorgom <110917257+sorgom@users.noreply.github.com> Date: Thu, 25 Jan 2024 12:01:03 +0100 Subject: [PATCH] Som devel (#33) * list -> TransEvent * devel comments / TODO * StackArray refactor; StackArray tests * more protection, comments * details * spelling * typos * typos --- .gitignore | 2 +- CLOC.md | 10 +- .../BAS/{I_Searchable.h => I_Array.h} | 31 ++-- application/components/BAS/NtpArray.h | 36 ++++- application/components/BAS/README.md | 20 ++- application/components/BAS/StackArray.h | 70 ++++----- application/components/LCR/LCR_Provider.h | 2 +- application/components/SIG/SIG_Provider.h | 2 +- application/components/SYS/src/Dispatcher.cpp | 7 +- application/components/TSW/TSW_Provider.h | 2 +- devel/TODO.md | 14 -- devel/qnd/README.md | 4 + devel/qnd/useCout.h | 4 + scripts/mdjStateCharts.py | 20 +-- scripts/modTransCsv.py | 72 ++------- scripts/modTransTable.py | 147 ++++++++++++------ specification/ifs/I_Dispatcher.h | 4 +- specification/ifs/I_Loader.h | 4 +- specification/ifs/README.md | 8 +- testing/coverage.md | 8 +- testing/testenv/testlib/GenProjData.h | 14 +- testing/tests/moduletests/BAS/BAS_02.cpp | 63 +++++--- testing/tests/moduletests/BAS/BAS_03.cpp | 1 - testing/tests/moduletests/BAS/README.md | 2 +- testing/tests/moduletests/SYS/SYS_02.cpp | 16 ++ 25 files changed, 312 insertions(+), 251 deletions(-) rename application/components/BAS/{I_Searchable.h => I_Array.h} (75%) diff --git a/.gitignore b/.gitignore index 264ccac0..6dd4cce0 100644 --- a/.gitignore +++ b/.gitignore @@ -73,5 +73,5 @@ html _*.* # depracated gen -transitions_*.mod +transitions_*.md *_states.md \ No newline at end of file diff --git a/CLOC.md b/CLOC.md index a0a70119..7ec25492 100644 --- a/CLOC.md +++ b/CLOC.md @@ -4,10 +4,10 @@ ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- -C++ 16 100 5 909 -C/C++ Header 23 243 190 801 +C++ 16 100 5 914 +C/C++ Header 23 248 197 806 ------------------------------------------------------------------------------- -SUM: 39 343 195 1710 +SUM: 39 348 202 1720 ------------------------------------------------------------------------------- ``` **testenv** @@ -26,9 +26,9 @@ SUM: 34 267 193 1242 ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- -C++ 15 208 213 1813 +C++ 15 214 217 1841 ------------------------------------------------------------------------------- -SUM: 15 208 213 1813 +SUM: 15 214 217 1841 ------------------------------------------------------------------------------- ``` **systemtests** diff --git a/application/components/BAS/I_Searchable.h b/application/components/BAS/I_Array.h similarity index 75% rename from application/components/BAS/I_Searchable.h rename to application/components/BAS/I_Array.h index 62380288..83214d56 100644 --- a/application/components/BAS/I_Searchable.h +++ b/application/components/BAS/I_Array.h @@ -1,32 +1,39 @@ // ============================================================ -// defintion of interface I_Searchable to apply: +// defintion of interface I_Array to apply: // - bubble sort // - b-tree search // - uniqueness check / duplicates count // ============================================================ #pragma once -#ifndef I_SEARCHABLE_H -#define I_SEARCHABLE_H +#ifndef I_ARRAY_H +#define I_ARRAY_H #include #include template -class I_Searchable +class I_Array { public: // current number of objects virtual UINT32 size() const = 0; + // object access by position virtual const T& at(UINT32 pos) const = 0; + // definition object a is greater than object b - virtual bool isGreater(const T& a, const T& b) const = 0; + inline virtual bool isGreater(const T& a, const T& b) const + { + return false; + } + // swap content of position a and b - virtual void swap(UINT32 posA, UINT32 posB) = 0; + inline virtual void swap(UINT32 posA, UINT32 posB) + {} }; template -void bSort(I_Searchable& src) +void bSort(I_Array& src) { for (UINT32 n = src.size(); n > 1; --n) { @@ -47,7 +54,7 @@ void bSort(I_Searchable& src) } template -INT32 bSearch(const I_Searchable& src, const T& obj) +INT32 bSearch(const I_Array& src, const T& obj) { INT32 pMin = 0; INT32 pMax = src.size() - 1; @@ -74,15 +81,15 @@ INT32 bSearch(const I_Searchable& src, const T& obj) return res; } -// apply duplicates count to I_Searchable +// apply duplicates count to I_Array // precondition: bSort applied before template -UINT32 dupCnt(const I_Searchable& src) +UINT32 dupCnt(const I_Array& src) { UINT32 ndups = 0; - for (UINT32 p = 0; p < src.size() - 1; ++p) + for (UINT32 p = 1; p < src.size(); ++p) { - if (not src.isGreater(src.at(p + 1), src.at(p))) + if (not src.isGreater(src.at(p), src.at(p - 1))) { ++ndups; } diff --git a/application/components/BAS/NtpArray.h b/application/components/BAS/NtpArray.h index 1fad7dde..d81cd23c 100644 --- a/application/components/BAS/NtpArray.h +++ b/application/components/BAS/NtpArray.h @@ -1,5 +1,5 @@ // ============================================================ -// Storage of Name Type Position +// name, type, position // ============================================================ // created by Manfred Sorgo @@ -7,10 +7,12 @@ #ifndef NTPARRAY_H #define NTPARRAY_H -#include -#include +#include #include +#include +#include +// name, type, position struct Ntp { ElementName name; @@ -18,6 +20,7 @@ struct Ntp UINT32 pos; }; +// generates Ntp struct from name [, type, position] class GenNtp { protected: @@ -26,20 +29,34 @@ class GenNtp INT32 type = 0, UINT32 pos = 0 ); + + inline GenNtp() {} + + NOCOPY(GenNtp) }; +// ============================================================ +// - storage of name, type, position +// ============================================================ template class NtpArray : - public SimpleStackArray, + public StackArray, private GenNtp { public: + inline NtpArray() {} + inline UINT32 addNtp(const ElementName& name, INT32 type, UINT32 pos) { return this->add(genNtp(name, type, pos)); } + + NOCOPY(NtpArray) }; +// ============================================================ +// - index of name, type, position by name +// ============================================================ template class NtpIndex : public StackArrayIndex, @@ -50,15 +67,18 @@ class NtpIndex : StackArrayIndex(a) {} + inline INT32 findNtp(const ElementName& name) const + { + return this->findRef(genNtp(name)); + } +protected: inline bool isGreater(const Ntp& a, const Ntp& b) const { return Mem::cmp(a.name, b.name) > 0; } - inline INT32 findNtp(const ElementName& name) const - { - return this->findRef(genNtp(name)); - } + NOCOPY(NtpIndex) + NtpIndex(); }; #endif // H_ \ No newline at end of file diff --git a/application/components/BAS/README.md b/application/components/BAS/README.md index d97977e0..887dbfa3 100644 --- a/application/components/BAS/README.md +++ b/application/components/BAS/README.md @@ -5,9 +5,9 @@ basic integral types and limits ``` -**I_Searchable.h** +**I_Array.h** ``` -defintion of interface I_Searchable to apply: +defintion of interface I_Array to apply: - bubble sort - b-tree search - uniqueness check / duplicates count @@ -20,7 +20,11 @@ type safe memset & memcpy **NtpArray.h** ``` -Storage of Name Type Position +name, type, position + +- storage of name, type, position + +- index of name, type, position by name ``` **StackArray.h** @@ -31,24 +35,24 @@ StackArrays - can be filled with objects at runtime - do not provide any overflow protection -SimpleStackArray +StackArray keeps objects in the same order as they were added. -StackArray +SortableStackArray - can be sorted - can search for elements Derived classes have to provide the isGreater method for objects of their type -See interface I_Searchable +See interface I_Array class CRef enables to store references as objects StackArrayIndex -provides search for unsorted SimpleStackArray. +provides search for unsorted StackArray. Derived classes have to provide the isGreater method for objects of their type -See interface I_Searchable +See interface I_Array ``` **coding.h** diff --git a/application/components/BAS/StackArray.h b/application/components/BAS/StackArray.h index 6adc59f2..45358195 100644 --- a/application/components/BAS/StackArray.h +++ b/application/components/BAS/StackArray.h @@ -11,16 +11,19 @@ #ifndef STACKARRAY_H #define STACKARRAY_H -#include +#include #include #include -// base class for StackArray classes +// ============================================================ +// StackArray +// keeps objects in the same order as they were added. +// ============================================================ template -class BaseStackArray : public I_Searchable +class StackArray : public I_Array { public: - inline BaseStackArray(): + inline StackArray(): mData(reinterpret_cast(mBytes)), mSize(0) {} @@ -82,28 +85,7 @@ class BaseStackArray : public I_Searchable T* mData; UINT32 mSize; - NOCOPY(BaseStackArray) -}; - -// ============================================================ -// SimpleStackArray -// keeps objects in the same order as they were added. -// ============================================================ -template -class SimpleStackArray : public BaseStackArray -{ -public: - inline SimpleStackArray() - {} - - inline bool isGreater(const T& a, const T& b) const - { - return false; - } - - inline void swap(UINT32 posA, UINT32 posB) {} - - NOCOPY(SimpleStackArray) + NOCOPY(StackArray) }; // provides static byte swapping for template based classes @@ -114,20 +96,20 @@ class SwapBytes }; // ============================================================ -// StackArray +// SortableStackArray // - can be sorted // - can search for elements // Derived classes have to provide // the isGreater method for objects of their type -// See interface I_Searchable +// See interface I_Array // ============================================================ template -class StackArray : - public BaseStackArray, +class SortableStackArray : + public StackArray, private SwapBytes { public: - inline StackArray() + inline SortableStackArray() {} inline void sort() @@ -153,7 +135,7 @@ class StackArray : private: BYTE mSwap[sizeof(T)]; - NOCOPY(StackArray) + NOCOPY(SortableStackArray) }; // ============================================================ @@ -180,20 +162,26 @@ class CRef // ============================================================ // StackArrayIndex -// provides search for unsorted SimpleStackArray. +// provides search for unsorted StackArray. // Derived classes have to provide // the isGreater method for objects of their type -// See interface I_Searchable +// See interface I_Array // ============================================================ + template -class StackArrayIndex : public StackArray, CAP> +class StackArrayIndex : private SortableStackArray, CAP> { public: - inline StackArrayIndex(const SimpleStackArray& a): + inline StackArrayIndex(const StackArray& a): mArray(a) {} - void index() + inline void reset() + { + SortableStackArray, CAP>::reset(); + } + + bool index() { this->reset(); for (UINT32 p = 0; p < mArray.size(); ++p) @@ -201,10 +189,9 @@ class StackArrayIndex : public StackArray, CAP> this->add(CRef(mArray.at(p))); } this->sort(); + return this->dupCnt() == 0; } - virtual bool isGreater(const T& a, const T& b) const = 0; - inline bool isGreater(const CRef& a, const CRef& b) const { return isGreater(a.ref(), b.ref()); @@ -220,8 +207,11 @@ class StackArrayIndex : public StackArray, CAP> return this->at(pos).ref(); } +protected: + virtual bool isGreater(const T& a, const T& b) const = 0; + private: - const SimpleStackArray& mArray; + const StackArray& mArray; NOCOPY(StackArrayIndex) StackArrayIndex(); diff --git a/application/components/LCR/LCR_Provider.h b/application/components/LCR/LCR_Provider.h index cd9c489e..09f4545e 100644 --- a/application/components/LCR/LCR_Provider.h +++ b/application/components/LCR/LCR_Provider.h @@ -33,7 +33,7 @@ class LCR_Provider : public I_LCR_Provider IL_INSTANCE_DEC(LCR_Provider) private: - SimpleStackArray mLCRs; + StackArray mLCRs; NOCOPY(LCR_Provider) }; diff --git a/application/components/SIG/SIG_Provider.h b/application/components/SIG/SIG_Provider.h index babc3381..bd9a0086 100644 --- a/application/components/SIG/SIG_Provider.h +++ b/application/components/SIG/SIG_Provider.h @@ -33,7 +33,7 @@ class SIG_Provider : public I_SIG_Provider IL_INSTANCE_DEC(SIG_Provider) private: - SimpleStackArray mSIGs; + StackArray mSIGs; NOCOPY(SIG_Provider) }; diff --git a/application/components/SYS/src/Dispatcher.cpp b/application/components/SYS/src/Dispatcher.cpp index db2c435b..337bccbf 100644 --- a/application/components/SYS/src/Dispatcher.cpp +++ b/application/components/SYS/src/Dispatcher.cpp @@ -13,7 +13,12 @@ void Dispatcher::reset() void Dispatcher::index() { - mIndx.index(); + if (mIndx.index()) + { pass();} + else + { + IL::getLog().log(MOD_DISPATCHER, ERR_STARTUP); + } } INT32 Dispatcher::assign( diff --git a/application/components/TSW/TSW_Provider.h b/application/components/TSW/TSW_Provider.h index e7e8a0d3..716fffcd 100644 --- a/application/components/TSW/TSW_Provider.h +++ b/application/components/TSW/TSW_Provider.h @@ -33,7 +33,7 @@ class TSW_Provider : public I_TSW_Provider IL_INSTANCE_DEC(TSW_Provider) private: - SimpleStackArray mTSWs; + StackArray mTSWs; NOCOPY(TSW_Provider) }; diff --git a/devel/TODO.md b/devel/TODO.md index fa4c8961..6ab1cb6a 100644 --- a/devel/TODO.md +++ b/devel/TODO.md @@ -5,17 +5,3 @@ A collection of things to do that are not big enough to create an issue. ## TODO list - safe casts -- capacity check for containers -- DATASIZE -- rename IL -- make use of md tables like: - -|hello|world|wumpel| -|:--|:--|--:| -|paul|mike|zardoz| -|paul|mike|11111| -|total||30075| - -**2023-10-27** -- correct svg links in mds - diff --git a/devel/qnd/README.md b/devel/qnd/README.md index 67972a5a..e3660e5e 100644 --- a/devel/qnd/README.md +++ b/devel/qnd/README.md @@ -5,4 +5,8 @@ **useCout.h** ``` use cout for quick and dirty temporary traces +note +CI application build will fail +with this file (still) included +and merge request will be blocked ``` diff --git a/devel/qnd/useCout.h b/devel/qnd/useCout.h index 721f32a2..393a7586 100644 --- a/devel/qnd/useCout.h +++ b/devel/qnd/useCout.h @@ -1,5 +1,9 @@ // ============================================================ // use cout for quick and dirty temporary traces +// note +// CI application build will fail +// with this file (still) included +// and merge request will be blocked // ============================================================ // created by Manfred Sorgo diff --git a/scripts/mdjStateCharts.py b/scripts/mdjStateCharts.py index 5a82a2f0..421c2f70 100644 --- a/scripts/mdjStateCharts.py +++ b/scripts/mdjStateCharts.py @@ -4,7 +4,7 @@ # ============================================================ # created by Manfred Sorgo -from modTransTable import TransTable +from modTransTable import TransTable, TransEvent import json, re from sys import argv from getopt import getopt @@ -63,12 +63,12 @@ def fuse(self, region): transitions = self.transitions.get(region) stateNames = self.stateNames.get(region) if stateNames is None: return - transitions = [ - [src, trg, self.event(trg, evt) ] - for src, trg, evt in [[stateNames.get(src), stateNames.get(trg), evt] - for src, trg, evt in transitions] + transEvents = [ + TransEvent(self.event(trg, evt), src, trg) + for evt, src, trg in [[evt, stateNames.get(src), stateNames.get(trg)] + for evt, src, trg in transitions] ] - return transitions + return transEvents def getRef(self, data, key): ref = data.get(key) @@ -85,10 +85,10 @@ def traverse(self, data:dict): if pr: src = self.getRef(data, 'source') trg = self.getRef(data, 'target') - trs = data.get('triggers', []) - for tr in trs: - if tr.get('_type', '') == 'UMLEvent': - self.transitions.setdefault(pr, list()).append([src, trg, tr.get('name')]) + evs = data.get('triggers', []) + for evt in evs: + if evt.get('_type', '') == 'UMLEvent': + self.transitions.setdefault(pr, list()).append([evt.get('name'), src, trg]) elif tp == 'UMLState': if pr: self.stateNames.setdefault(pr, dict())[id] = nm diff --git a/scripts/modTransCsv.py b/scripts/modTransCsv.py index b3a16aa7..75991ed4 100644 --- a/scripts/modTransCsv.py +++ b/scripts/modTransCsv.py @@ -5,7 +5,7 @@ # ============================================================ # created by Manfred Sorgo -from modTransTable import TransTable +from modTransTable import TransTable, TransEvent from modMdTable import mdTable from modUtilz import repoDir import re, csv @@ -18,10 +18,8 @@ class TransCsv(object): def __init__(self): self.transTable = TransTable() self.mdData = '' - self.statePrefix = '' self.delimiter = ';' self.info = False - self.rxInd = re.compile(r'^', re.M) self.rxCsv = re.compile(r'\.csv$', re.I) self.rxJsn = re.compile(r'\.json$', re.I) @@ -36,7 +34,7 @@ def transition(self, src, trg, evt): evt = ' '.join([*a, trg][0:2]) return [src, trg, evt] - def genTransitions(self, srcCsv): + def genTransEvents(self, srcCsv): data = list() with open(srcCsv, 'r') as fh: @@ -48,18 +46,18 @@ def genTransitions(self, srcCsv): data = self.pivot(data) - transitions = list() + transEvents = list() for p in range(0, len(data), 2): evt = data[p][0] srcs = self.values(data[p][1:]) trgs = self.values(data[p + 1][1:]) for src in srcs: for trg in trgs: - if trg != src: transitions.append(self.transition(src, trg, evt)) - return transitions + if trg != src: transEvents.append(TransEvent(evt, src, trg)) + return transEvents def genMd(self, srcCsv): - transitions = self.genTransitions(srcCsv) + transEvents = self.genTransEvents(srcCsv) trgMd = re.sub(r'\.\w+$', '.md', srcCsv) ttl = re.sub(r'\.\w+$', '', basename(srcCsv)).replace('_', ' ') @@ -69,31 +67,12 @@ def genMd(self, srcCsv): '## transition table', self.mdData, '', - self.transTable.genMd(transitions) + self.transTable.genMd(transEvents) ])) - def statOut(self, pref, num, desc): - print("%1s %4d %s" % (pref, num, desc)) - def genInfo(self, srcCsv): print(basename(srcCsv)) - transitions = self.genTransitions(srcCsv) - table = self.transTable.genTable(transitions) - nGlue = 0 - nNoTrans = 0 - nTrans = len(transitions) - for tr in table: - if len(tr) > 3: nGlue += 1 - elif not tr[0]: nNoTrans += 1 - - self.statOut('', nTrans, 'test steps for transitions') - self.statOut('+', nNoTrans, 'test steps without transition') - self.statOut('=', nTrans + nNoTrans, 'relevant test steps') - self.statOut('+', nGlue, 'test steps as glue') - self.statOut('=', len(table), 'test steps total') - - def cppName(self, prefix:str, state:str): - return "%s_%s" % (prefix, state.replace(' ', '_')) + self.transTable.genInfo(self.genTransEvents(srcCsv)) def genJsonCpp(self, file): with open (file, 'r') as fh: @@ -119,39 +98,8 @@ def genJsonCpp(self, file): ) print('\n\n'.join(res)) - def genCpp(self, srcCsv, - prefixState = 'SIG_STATE', - prefixCmd = 'SIG_STATE', - cmd1 = 'CMD(_VAL_, 0, _VAL_, 0, _TRG_, 0);', - cmd0 = 'CMD(_VAL_, 0);', - fld1 = 'FLD(_VAL_, 0, _VAL_, 0);', - fld0 = 'FLD(_VAL_, 0);' - - ): - transitions = self.genTransitions(srcCsv) - tbl = self.transTable.genTable(transitions) - step = 0 - res = list() - for row in tbl: - src, gui, evt = row[0:3] - call, val = evt.split(' ', 1) - fld = gui.replace('WAIT ', '') - istr = src and gui - templ = '' - if call == 'CMD': - templ = cmd1 if istr else cmd0 - elif call == 'FLD': - templ = fld1 if istr else fld0 - - if templ: - templ = templ.replace('_VAL_', self.cppName(prefixState, val)) - templ = templ.replace('_GUI_', self.cppName(prefixState, gui)) - templ = templ.replace('_FLD_', self.cppName(prefixState, fld)) - templ = templ.replace('_CMD_', self.cppName(prefixCmd, val)) - step += 1 - res.append(f'STEP({step})') - res.append(templ) - return self.rxInd.sub(' ', '\n'.join(res)) + def genCpp(self, srcCsv, **args): + return self.transTable.genCpp(self.genTransEvents(srcCsv), **args) def fromFile(self, fp): if self.rxCsv.search(fp): diff --git a/scripts/modTransTable.py b/scripts/modTransTable.py index a55a2701..a5ec703e 100644 --- a/scripts/modTransTable.py +++ b/scripts/modTransTable.py @@ -8,35 +8,44 @@ import re from modMdTable import mdTable +class TransEvent(object): + def __init__(self, evt:str, src:str='', trg:str='', glue:str=''): + self.evt = re.sub(r'\*', trg, evt) + self.src = src + self.trg = trg + self.glu = glue + def toList(self) -> list: + return [self.evt, self.src, self.trg, self.glu] + def isNone(self) -> bool: + return not self.trg + def isGlue(self) -> bool: + return self.glu == '*' + def glueCopy(self): + return TransEvent(self.evt, self.src, self.trg, '*') + class TransTable(object): def __init__(self): self.heading = ['STEP', 'EVENT', 'FROM', 'TO', 'GLUE'] - self.rxWild = re.compile(r'\*') - def noTrans(self, evt): - return ['', '', evt] - - def glue(self, src, trg, transitions:list): - for src1, trg1, evt1 in transitions: - for src2, trg2, evt2 in transitions: - if src1 == src and trg1 == src2 and trg2 == trg: + self.rxInd = re.compile(r'^', re.M) + + def glue(self, src, trg, transEvents:list): + for tre1 in transEvents: + for tre2 in transEvents: + if tre1.src == src and tre1.trg == tre2.src and tre2.trg == trg: return [ - [src1, trg1, evt1, '*'], - [src2, trg2, evt2, '*'] + tre1.glueCopy(), + tre2.glueCopy() ] - def transition(self, src, trg, evt): - return [src, trg, self.rxWild.sub(trg, evt)] - - def genTable(self, transitions:list): - transitions = [self.transition(*tr) for tr in transitions] + def genTable(self, transEvents:list): events = set() states = set() fromEvt = dict() - for src, trg, evt in transitions: - events.add(evt) - states.add(src) - states.add(trg) - fromEvt.setdefault(src, dict())[evt] = trg + for tre in transEvents: + events.add(tre.evt) + states.add(tre.src) + states.add(tre.trg) + fromEvt.setdefault(tre.src, dict())[tre.evt] = tre.trg noTrans = dict() for src in sorted(states): @@ -45,25 +54,25 @@ def genTable(self, transitions:list): noTrans.setdefault(src, list()).append(evt) next = dict() - for n, tr in enumerate(transitions): - next.setdefault(tr[0], list()).append(n) + for n, tre in enumerate(transEvents): + next.setdefault(tre.src, list()).append(n) # build sequences using every transition once - ln = len(transitions) + ln = len(transEvents) todo = set(range(ln)) seqs = [] while todo: n = todo.pop() - seq = [transitions[n]] + seq = [transEvents[n]] found = True while found: found = False - nxs = next.get(transitions[n][1]) + nxs = next.get(transEvents[n].trg) if nxs: for nx in nxs: if nx in todo: - seq.append(transitions[nx]) + seq.append(transEvents[nx]) todo.remove(nx) found = True n = nx @@ -73,49 +82,42 @@ def genTable(self, transitions:list): # try to connect sequences with transitions if len(seqs) > 1: next = dict() - for n, tr in enumerate(transitions): - next.setdefault(tr[0], dict())[tr[1]] = n + for n, tre in enumerate(transEvents): + next.setdefault(tre.src, dict())[tre.trg] = n for n in range(len(seqs) - 1): - src = seqs[n][-1][1] - trg = seqs[n + 1][0][0] + src = seqs[n][-1].trg + trg = seqs[n + 1][0].src con = next.get(src, dict()).get(trg) if con: - seqs[n].append([*transitions[con], '*']) + seqs[n].append(transEvents[con].glueCopy()) else: - con = self.glue(src, trg, transitions) + con = self.glue(src, trg, transEvents) if con: seqs[n].extend(con) else: - seqs[n].append(self.noTrans('NO TRANSITION')) + seqs[n].append(TransEvent('NO TRANSITION')) # flatten res = [tr for seq in seqs for tr in seq] tbl = list() - for tr in res: - tbl.append(tr) - trg = tr[1] - ntr = noTrans.get(trg) + for tre in res: + tbl.append(tre) + ntr = noTrans.get(tre.trg) if ntr: for evt in ntr: - tbl.append(self.noTrans(evt)) - del noTrans[trg] + tbl.append(TransEvent(evt)) + del noTrans[tre.trg] return tbl - def mdStep(self, n, trIn:list): - trOut = trIn.copy() - trOut[0] = trIn[2] - trOut[1] = trIn[0] - trOut[2] = trIn[1] - return [n + 1, *trOut] def genMd(self, transitions:list, name = 'test steps'): tbl = self.genTable(transitions) data = [ self.heading, *[ - self.mdStep(n, tr) for n, tr in enumerate(tbl) + [n + 1, *tre.toList()] for n, tre in enumerate(tbl) ] ] @@ -123,3 +125,56 @@ def genMd(self, transitions:list, name = 'test steps'): f'## {name}', mdTable(data) ]) + + def cppName(self, prefix:str, state:str): + return "%s_%s" % (prefix, state.replace(' ', '_')) + + def genCpp(self, transEvents:list, + prefixState = 'SIG_STATE', + prefixCmd = 'SIG_STATE', + cmd1 = 'CMD(_VAL_, 0, _VAL_, 0, _TRG_, 0);', + cmd0 = 'CMD(_VAL_, 0);', + fld1 = 'FLD(_VAL_, 0, _VAL_, 0);', + fld0 = 'FLD(_VAL_, 0);' + + ): + tbl = self.genTable(transEvents) + step = 0 + res = list() + for tre in tbl: + call, val = tre.evt.split(' ', 1) + fld = tre.trg.replace('WAIT ', '') + gui = tre.trg + templ = '' + if call == 'CMD': + templ = cmd0 if tre.isNone() else cmd1 + elif call == 'FLD': + templ = fld0 if tre.isNone() else fld1 + + if templ: + templ = templ.replace('_VAL_', self.cppName(prefixState, val)) + templ = templ.replace('_GUI_', self.cppName(prefixState, gui)) + templ = templ.replace('_FLD_', self.cppName(prefixState, fld)) + templ = templ.replace('_CMD_', self.cppName(prefixCmd, val)) + step += 1 + res.append(f'STEP({step})') + res.append(templ) + return self.rxInd.sub(' ', '\n'.join(res)) + + def statOut(self, pref, num, desc): + print("%1s %4d %s" % (pref, num, desc)) + + def genInfo(self, transEvents): + table = self.genTable(transEvents) + nGlue = 0 + nNoTrans = 0 + nTrans = len(transEvents) + for tre in table: + if tre.isGlue(): nGlue += 1 + elif tre.isNone(): nNoTrans += 1 + + self.statOut('', nTrans, 'test steps for transitions') + self.statOut('+', nNoTrans, 'test steps without transition') + self.statOut('=', nTrans + nNoTrans, 'relevant test steps') + self.statOut('+', nGlue, 'test steps as glue') + self.statOut('=', len(table), 'test steps total') diff --git a/specification/ifs/I_Dispatcher.h b/specification/ifs/I_Dispatcher.h index a1bf99b3..b4f09ee7 100644 --- a/specification/ifs/I_Dispatcher.h +++ b/specification/ifs/I_Dispatcher.h @@ -18,11 +18,11 @@ class I_Dispatcher // ============================================================ // when loading project data - // subsytems assign themselfs with: + // subsystems assign themselves with: // - element name // - subsystem id // - own processing element position - // and shall recieve: + // and shall receive: // - dispatcher id // ============================================================ virtual INT32 assign(const ElementName& name, E_Subsys subs, UINT32 pos) = 0; diff --git a/specification/ifs/I_Loader.h b/specification/ifs/I_Loader.h index 04dc0e4e..91b097f4 100644 --- a/specification/ifs/I_Loader.h +++ b/specification/ifs/I_Loader.h @@ -1,8 +1,8 @@ // ============================================================ // interface Loader -// the Loader is called at sytem start and shall: +// the Loader is called at system start and shall: // - reset I_Dispatcher -// - distribute load to subsytems +// - distribute load to subsystems // - call indexing of I_Dispatcher // ============================================================ // created by Manfred Sorgo diff --git a/specification/ifs/README.md b/specification/ifs/README.md index 97d50568..5d67dda2 100644 --- a/specification/ifs/README.md +++ b/specification/ifs/README.md @@ -17,11 +17,11 @@ Interface Com interface Dispatcher when loading project data -subsytems assign themselfs with: +subsystems assign themselves with: - element name - subsystem id - own processing element position -and shall recieve: +and shall receive: - dispatcher id field states shall be dispatched to subsystems @@ -51,9 +51,9 @@ interface LCR_Provider **I_Loader.h** ``` interface Loader -the Loader is called at sytem start and shall: +the Loader is called at system start and shall: - reset I_Dispatcher -- distribute load to subsytems +- distribute load to subsystems - call indexing of I_Dispatcher ``` diff --git a/testing/coverage.md b/testing/coverage.md index 469a86cd..4338a84a 100644 --- a/testing/coverage.md +++ b/testing/coverage.md @@ -5,7 +5,7 @@ Source Function Coverage C/D Coverage Com.h 3 / 3 = 100% 0 / 0 Dispatcher.cpp 7 / 7 = 100% 20 / 20 = 100% Dispatcher.h 1 / 1 = 100% 0 / 0 -I_Searchable.h 3 / 3 = 100% 18 / 18 = 100% +I_Array.h 3 / 3 = 100% 18 / 18 = 100% LCR_Hub.cpp 4 / 4 = 100% 4 / 4 = 100% LCR_Hub.h 1 / 1 = 100% 0 / 0 LCR_Provider.cpp 1 / 1 = 100% 15 / 15 = 100% @@ -24,7 +24,7 @@ SIG_Provider.cpp 1 / 1 = 100% 16 / 16 = 100% SIG_Provider.h 3 / 3 = 100% 0 / 0 SIG_X.cpp 18 / 18 = 100% 93 / 93 = 100% SIG_X.h 9 / 9 = 100% 0 / 0 -StackArray.cpp 1 / 1 = 100% 0 / 0 +SortableStackArray.cpp 1 / 1 = 100% 0 / 0 StackArray.h 26 / 26 = 100% 2 / 2 = 100% TSW.cpp 7 / 7 = 100% 22 / 22 = 100% TSW.h 1 / 1 = 100% 0 / 0 @@ -51,11 +51,11 @@ SIG/src/SIG_Hub.cpp 40 -- -- SIG/src/SIG_Provider.cpp 50 -- -- SIG/src/SIG_X.cpp 278 -- -- SYS/src/Com.cpp 2 -- -- -SYS/src/Dispatcher.cpp 108 -- -- +SYS/src/Dispatcher.cpp 113 -- -- SYS/src/Loader.cpp 11 -- -- SYS/src/Log.cpp 2 -- -- TSW/src/TSW.cpp 91 -- -- TSW/src/TSW_Hub.cpp 38 -- -- TSW/src/TSW_Provider.cpp 35 -- -- -total 882 -- -- +total 887 -- -- ``` diff --git a/testing/testenv/testlib/GenProjData.h b/testing/testenv/testlib/GenProjData.h index 0f4d7eb5..72ab9296 100644 --- a/testing/testenv/testlib/GenProjData.h +++ b/testing/testenv/testlib/GenProjData.h @@ -83,13 +83,13 @@ namespace test } private: - SimpleStackArray mTSWs; - SimpleStackArray mSIGs; - SimpleStackArray mLCRs; - SimpleStackArray mSEGs; + StackArray mTSWs; + StackArray mSIGs; + StackArray mLCRs; + StackArray mSEGs; template - void preset(SimpleStackArray& array, CONST_C_STRING what) + void preset(StackArray& array, CONST_C_STRING what) { for (UINT32 n = 0; n < CAP; ++n) { @@ -100,13 +100,13 @@ namespace test } template - void setType(SimpleStackArray& array, UINT32 pos, INT32 type) + void setType(StackArray& array, UINT32 pos, INT32 type) { array.at(pos).type = type; } template - void setType(SimpleStackArray& array, INT32 type) + void setType(StackArray& array, INT32 type) { for (UINT32 p = 0; p < CAP; ++p) { diff --git a/testing/tests/moduletests/BAS/BAS_02.cpp b/testing/tests/moduletests/BAS/BAS_02.cpp index 761d1b0e..df2f7fde 100644 --- a/testing/tests/moduletests/BAS/BAS_02.cpp +++ b/testing/tests/moduletests/BAS/BAS_02.cpp @@ -1,5 +1,5 @@ // ============================================================ -// test of StackArray, StackArrayIndex +// test of SortableStackArray, StackArrayIndex // ============================================================ // created by Manfred Sorgo @@ -21,7 +21,7 @@ namespace test {} }; - class IdataArray : public StackArray + class IdataSortableArray : public SortableStackArray { public: inline bool isGreater(const Idata& a, const Idata& b) const @@ -30,14 +30,15 @@ namespace test } }; - typedef SimpleStackArray IdataSimpleArray; + typedef StackArray IdataArray; class IdataIndex : public StackArrayIndex { public: - inline IdataIndex(const IdataSimpleArray& a): + inline IdataIndex(const IdataArray& a): StackArrayIndex(a) {} + protected: inline bool isGreater(const Idata& a, const Idata& b) const { return a.m1 > b.m1; @@ -45,13 +46,13 @@ namespace test }; // test type: equivalence class test - // test of StackArray + // test of SortableStackArray TEST(BAS_02, T01) { STEP(1) // create array // load data - IdataArray a; + IdataSortableArray a; L_CHECK_EQUAL(20, a.capacity()) L_CHECK_EQUAL( 0, a.size()) @@ -95,7 +96,7 @@ namespace test STEP(5) // apply find() to const object - const IdataArray& c = a; + const IdataSortableArray& c = a; SUBSTEPS() for (INT32 i = 0; i < c.size(); ++i) { @@ -107,17 +108,17 @@ namespace test } // test type: equivalence class test - // test of StackArray dupCnt + // test of SortableStackArray dupCnt TEST(BAS_02, T02) { SETUP() - IdataArray a; + IdataSortableArray a; a.add(Idata(1, 2)); a.add(Idata(2, 2)); a.add(Idata(1, 2)); a.add(Idata(2, 2)); a.sort(); - const IdataArray& c = a; + const IdataSortableArray& c = a; STEP(1) const UINT32 cnt = c.dupCnt(); @@ -128,41 +129,63 @@ namespace test // test of StackArrayIndex TEST(BAS_02, T03) { - STEP(1) + SETUP() // create array - // load data - IdataSimpleArray a; + IdataArray a; IdataIndex ix(a); - L_CHECK_EQUAL(a.capacity(), ix.capacity()) + bool ok = false; + + STEP(1) + // index of empty array + { + ok = ix.index(); + L_CHECK_TRUE(ok) + const Idata d(1, 2); + const INT32 f = ix.findRef(d); + L_CHECK_EQUAL(-1, f) + } + STEP(2) + // load data for (INT32 i = 0; i < a.capacity(); ++i) { a.add(Idata(-i, i)); } L_CHECK_FALSE(a.hasSpace()) - STEP(2) - // index index + STEP(3) + // index // find all data in index - ix.index(); - L_CHECK_FALSE(ix.hasSpace()) + ok = ix.index(); + L_CHECK_TRUE(ok) + SUBSTEPS() for (INT32 i = 0; i < a.size(); ++i) { LSTEP(i) const Idata& d = a.at(i); const INT32 f = ix.findRef(d); + L_CHECK_FALSE(f < 0) const Idata& r = ix.getRef(f); L_CHECK_EQUAL(d.m1, r.m1) L_CHECK_EQUAL(d.m2, r.m2) } ENDSTEPS() + + STEP(4) + // duplicates + a.reset(); + a.add(Idata(1, 1)); + a.add(Idata(1, 2)); + ok = ix.index(); + L_CHECK_FALSE(ok) } + // test type: coverage - // SimpleStackArray isGreater / swap + // StackArray isGreater / swap TEST(BAS_02, T04) { - IdataSimpleArray a; + IdataArray a; const bool res = a.isGreater(Idata(2, 2), Idata(1, 2)); L_CHECK_FALSE(res) a.swap(0, 1); diff --git a/testing/tests/moduletests/BAS/BAS_03.cpp b/testing/tests/moduletests/BAS/BAS_03.cpp index b94046d0..8436fdea 100644 --- a/testing/tests/moduletests/BAS/BAS_03.cpp +++ b/testing/tests/moduletests/BAS/BAS_03.cpp @@ -20,7 +20,6 @@ namespace test NtpArray data; NtpIndex indx(data); L_CHECK_EQUAL(CAPACITY_DSP, data.capacity()) - L_CHECK_EQUAL(CAPACITY_DSP, indx.capacity()) Ntp tNtp; const UINT32 tSize = 10; diff --git a/testing/tests/moduletests/BAS/README.md b/testing/tests/moduletests/BAS/README.md index 49a04652..29fc4913 100644 --- a/testing/tests/moduletests/BAS/README.md +++ b/testing/tests/moduletests/BAS/README.md @@ -13,7 +13,7 @@ test of basic functionality **BAS_02.cpp** ``` -test of StackArray, StackArrayIndex +test of SortableStackArray, StackArrayIndex ``` **BAS_03.cpp** diff --git a/testing/tests/moduletests/SYS/SYS_02.cpp b/testing/tests/moduletests/SYS/SYS_02.cpp index 5a07d92a..6260ffc6 100644 --- a/testing/tests/moduletests/SYS/SYS_02.cpp +++ b/testing/tests/moduletests/SYS/SYS_02.cpp @@ -234,4 +234,20 @@ namespace test CHECK_N_CLEAR() } + + // test type: equivalence class test + // Dispatcher duplicate assignments -> index error + TEST(SYS_02, T08) + { + mSUT.reset(); + mSUT.assign(genElementName(1, "TSW"), SUBSYS_TSW, 1); + mSUT.assign(genElementName(1, "TSW"), SUBSYS_TSW, 2); + mSUT.assign(genElementName(3, "LCR"), SUBSYS_LCR, 3); + mSUT.assign(genElementName(4, "SEG"), SUBSYS_SEG, 4); + CHECK_N_CLEAR() + + m_Log().expectLog(MOD_DISPATCHER, ERR_STARTUP); + mSUT.index(); + CHECK_N_CLEAR() + } }