contrib/fsm-to-dot: mark illegal states in red

If an FSM transitions to a state that actually belongs to a different FSM,
print an error and mark it red, instead of exiting with exception.

Change-Id: I73d95a0c65ca1ea586ad55234610671a53d6220f
This commit is contained in:
Neels Hofmeyr 2018-03-26 14:59:18 +02:00
parent ec0f334e99
commit 338d174399
1 changed files with 29 additions and 5 deletions

View File

@ -193,6 +193,7 @@ class State:
out_state_names = None
out_edges = None
kind = None
color = None
def __init__(state):
state.in_event_names = []
@ -236,6 +237,11 @@ class State:
return ''
return ',shape=%s' % shape
def color_str(state):
if state.color is None:
return ''
return ',color="%s"' % state.color
def __repr__(state):
return 'State(name=%r,short_name=%r,out=%d)' % (state.name, state.short_name, len(state.out_edges))
@ -250,6 +256,12 @@ class Fsm:
fsm.event_names = set()
fsm.dot_name = fsm.all_names_sanitized()
def __repr__(fsm):
return str(fsm)
def __str__(fsm):
return 'Fsm(%r,%r)' % (fsm.struct_name, fsm.from_file)
def parse_states(fsm, src):
state = None
started = None
@ -312,8 +324,13 @@ class Fsm:
def ref_out_states(fsm):
for state in fsm.states:
for e in [Edge(fsm.find_state_by_name(n, True)) for n in state.out_state_names]:
state.add_out_edge(e)
for out_state_name in state.out_state_names:
out_state = fsm.find_state_by_name(out_state_name, False)
if out_state is None:
print('ERROR: fsm %r has a transition to state not part of the FSM: %r'
% (fsm, out_state_name))
out_state = fsm.have_state(out_state_name, KIND_STATE, color='red')
state.add_out_edge(Edge(out_state))
def find_state_by_name(fsm, name, strict=False):
for state in fsm.states:
@ -509,13 +526,14 @@ class Fsm:
meta_calling_fsm.add_out_edge(Edge(meta_called_fsm))
def have_state(fsm, name, kind=KIND_STATE):
def have_state(fsm, name, kind=KIND_STATE, color=None):
state = fsm.find_state_by_name(name)
if not state:
state = State()
state.name = name
state.short_name = name
state.kind = kind
state.color = color
fsm.states.append(state)
return state
@ -523,8 +541,8 @@ class Fsm:
out = ['digraph G {', 'rankdir=LR;']
for state in fsm.states:
out.append('%s [label="%s"%s]' % (state.short_name, state.get_label(),
state.shape_str()))
out.append('%s [label="%s"%s%s]' % (state.short_name, state.get_label(),
state.shape_str(), state.color_str()))
for state in fsm.states:
for out_edge in state.out_edges:
@ -596,6 +614,12 @@ class CFile():
c_file.funcs = {}
c_file.fsm_allocators = listdict()
def __repr__(c_file):
return str(c_file)
def __str__(c_file):
return 'CFile(%r)' % c_file.path
def extract_block(c_file, brace_open, brace_close, start):
pos = 0
try: