Commit 01542e56 authored by Marius Bozga's avatar Marius Bozga
Browse files

fix state name binding in hierarchical / concurrent states

parent 69e5942b
......@@ -874,53 +874,14 @@ void IfNextstateAction::PreCompile() {
int ok = 1;
/*
*
* state name ~ literal_1 @ literal_2 @ ... @ literal_n
*
* implemented too early ;-)
IfState* base[3] = {NULL, NULL, NULL};
base[0] = (IfState*) CONTEXT.Top(-3);
base[1] = ((IfProcessEntity*) CONTEXT[1])->GetEntry();
if (base[0] == base[1]) base[1] = NULL;
for(int i = 0; base[i]; i++) {
IfState* current = base[i];
for(int k = 0, j;; ) {
char literal[256] = "";
for(j = 0; m_pStateName[k] != '\0' &&
m_pStateName[k] != '@'; j++, k++)
literal[j] = m_pStateName[k];
literal[j] = '\0';
if (m_pStateName[k] == '@')
k++;
current = current->GetStates()->Find(literal);
if (current == NULL)
break;
if (m_pStateName[k] == '\0') {
m_pState = current;
break;
}
}
if (m_pState)
IfState* context_state = NULL;
for(int i = CONTEXT.GetCount() - 1; i >= 0; i--)
if (CONTEXT[i]->IsState()) {
context_state = (IfState*) CONTEXT[i];
break;
}
*
*
*/
}
IfState* top = ((IfProcessEntity*) CONTEXT[1])->GetEntry();
m_pState = top->Find(m_pStateName);
m_pState = context_state->FindVisible(m_pStateName);
ok &= m_pState != NULL;
......
......@@ -96,6 +96,37 @@ IfState* IfState::Find(const char* Name) const {
return state;
}
IfState* IfState::FindVisibleRec(const char* Name) const {
IfState* state = NULL;
if (!strcmp(m_pName, Name))
state = (IfState*) this;
if (!state && !IsConcurrent())
for(int i = 0; i < m_pStates->GetCount() && !state; i++)
state = m_pStates->GetAt(i)->FindVisibleRec(Name);
return state;
}
IfState* IfState::FindVisible(const char* Name) const {
IfState* state = NULL;
if (!strcmp(m_pName, Name))
state = (IfState*) this;
if (!state && m_pParent != NULL && !m_pParent->IsConcurrent())
for(int i = 0; i < m_pParent->GetStates()->GetCount() && !state; i++) {
IfState* brother = m_pParent->GetStates()->GetAt(i);
if (!strcmp(brother->GetName(), Name))
state = brother;
}
if (!state)
state = this->FindVisibleRec(Name);
if (!state && m_pParent != NULL && !m_pParent->IsConcurrent()) {
IfState* ancestor = m_pParent;
while (ancestor->m_pParent != NULL && !ancestor->m_pParent->IsConcurrent())
ancestor = ancestor->m_pParent;
state = ancestor->FindVisibleRec(Name);
}
return state;
}
void IfState::Dump(FILE* file) const {
fprintf(file, "%sstate %s%s%s%s%s%s;\n", indent(DEPTH), m_pName,
IsStart() ? " #start " : "",
......
......@@ -79,7 +79,8 @@ class IfState : public IfObject {
inline IfAutomatonEntity* GetProcess() const { return m_pProcess; }
IfState* Find(const char*) const;
IfState* FindVisible(const char*) const;
IfState* FindVisibleRec(const char*) const;
virtual const char* GetClass() const
{ return "state"; }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment