This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Neels Hofmeyr gerrit-no-reply at lists.osmocom.orgReview at https://gerrit.osmocom.org/4377 contrib/fsm-to-dot.py: some tweaks that help with osmo-bsc's new FSMs Combine the C source file name and the string name into the fsm's internal name token, and use it in most places instead of the plain struct name: osmo-bsc's new FSMs have identical struct names in each static c context. Output in a file name that includes all of these more detailed name tokens. Also parse '(1 << EVENT)' as event names. Note that besides this patch, there are also some tweaks to the osmo-bsc patch that improve the fsm-to-dot experience... - call fsm-to-dot for single files to avoid name conflicts, or rename each struct as a unique name. - Add comments for the event name a callback is intended for, so that not all transitions are interpreted as TEARDOWN (because it is invoked in common error handling, which causes the script to interpret it as the causing event). (or change the event-checking if into a switch that names the valid event and has a default case for all others.) Change-Id: Ib60df7fd19efc99ba9fe797f14c0e3239c4bea20 --- M contrib/fsm-to-dot.py 1 file changed, 40 insertions(+), 13 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/77/4377/1 diff --git a/contrib/fsm-to-dot.py b/contrib/fsm-to-dot.py index 3549d1e..06d2df1 100755 --- a/contrib/fsm-to-dot.py +++ b/contrib/fsm-to-dot.py @@ -5,7 +5,7 @@ Usage: ./fsm-to-dot.py ~/openbsc/openbsc/src/libvlr/*.c - for f in *.dot ; do dot -Tpng $f > $f.png; done + for f in *.dot ; do dot -Tpng "$f" > "$f.png"; done # dot comes from 'apt-get install graphviz' Looks for osmo_fsm finite state machine definitions and madly parses .c files @@ -13,7 +13,7 @@ No proper C parsing is done here (pycparser sucked, unfortunately). ''' -import sys, re +import sys, re, os def err(msg): sys.stderr.write(msg + '\n') @@ -63,8 +63,13 @@ return ld re_state_start = re.compile(r'\[([A-Z_][A-Z_0-9]*)\]') -re_event = re.compile(r'S\(([A-Z_][A-Z_0-9]*)\)') +re_event_alternatives = [ + re.compile(r'\(1 *<< *([A-Z_][A-Z_0-9]*)\)'), + re.compile(r'S\(([A-Z_][A-Z_0-9]*)\)'), + ] re_action = re.compile(r'.action *= *([a-z_][a-z_0-9]*)') + +re_insane_dot_name_chars = re.compile('[^a-zA-Z_]') def state_starts(line): m = re_state_start.search(line) @@ -79,7 +84,10 @@ return line.find('out_state_mask') >= 0 def states_or_events(line): - return re_event.findall(line) + results = [] + for one_re in re_event_alternatives: + results.extend(one_re.findall(line)) + return results def parse_action(line): a = re_action.findall(line) @@ -224,13 +232,15 @@ return 'State(name=%r,short_name=%r,out=%d)' % (state.name, state.short_name, len(state.out_edges)) class Fsm: - def __init__(fsm, struct_name, states_struct_name, from_file=None): + def __init__(fsm, struct_name, string_name, states_struct_name, from_file=None): fsm.states = [] fsm.struct_name = struct_name + fsm.string_name = string_name fsm.states_struct_name = states_struct_name fsm.from_file = from_file fsm.action_funcs = set() fsm.event_names = set() + fsm.dot_name = fsm.all_names_sanitized() def parse_states(fsm, src): state = None @@ -462,8 +472,8 @@ edge_action = caller if calling_state.action == edge_action: edge_action = None - calling_fsm.add_special_state(calling_fsm.states, fsm.struct_name, - calling_state, kind=KIND_FSM, edge_action=edge_action, label=label) + calling_fsm.add_special_state(calling_fsm.states, fsm.dot_name, + calling_state, kind=KIND_FSM, edge_action=edge_action, label=' '.join(fsm.all_names())) label = None if calling_state.kind == KIND_STATE: @@ -471,13 +481,13 @@ edge_action = caller if state.action == edge_action: edge_action = None - fsm.add_special_state(fsm.states, calling_fsm.struct_name, None, + fsm.add_special_state(fsm.states, calling_fsm.dot_name, None, state, kind=KIND_FSM, edge_action=edge_action, label=label) # meta overview - meta_called_fsm = fsm_meta.have_state(fsm.struct_name, KIND_FSM) - meta_calling_fsm = fsm_meta.have_state(calling_fsm.struct_name, KIND_FSM) + meta_called_fsm = fsm_meta.have_state(fsm.dot_name, KIND_FSM) + meta_calling_fsm = fsm_meta.have_state(calling_fsm.dot_name, KIND_FSM) meta_calling_fsm.add_out_edge(Edge(meta_called_fsm)) @@ -519,8 +529,23 @@ return '\n'.join(out) + def all_names(fsm): + n = [] + if fsm.from_file: + n.append(os.path.basename(fsm.from_file.path)) + if fsm.struct_name: + n.append(fsm.struct_name) + if fsm.string_name: + n.append(fsm.string_name) + return n + + def all_names_sanitized(fsm, sep='_'): + n = sep.join(fsm.all_names()) + n = re_insane_dot_name_chars.sub('_', n) + return n + def write_dot_file(fsm): - dot_path = '%s.dot' % fsm.struct_name + dot_path = '%s.dot' % ('_'.join(fsm.all_names())) f = open(dot_path, 'w') f.write(fsm.to_dot()) f.close() @@ -528,6 +553,7 @@ re_fsm = re.compile(r'struct osmo_fsm ([a-z_][a-z_0-9]*) =') +re_fsm_string_name = re.compile(r'\bname = "([^"]*)"') re_fsm_states_struct_name = re.compile(r'\bstates = ([a-z_][a-z_0-9]*)\W*,') re_fsm_states = re.compile(r'struct osmo_fsm_state ([a-z_][a-z_0-9]*)\[\] =') re_func = re.compile(r'(\b[a-z_][a-z_0-9]*\b)\([^)]*\)\W*^{', re.MULTILINE) @@ -575,8 +601,9 @@ for m in re_fsm.finditer(c_file.src): struct_name = m.group(1) struct_def = c_file.extract_block('{', '}', m.start()) + string_name = (re_fsm_string_name.findall(struct_def) or [None])[0] states_struct_name = re_fsm_states_struct_name.findall(struct_def)[0] - fsm = Fsm(struct_name, states_struct_name, c_file) + fsm = Fsm(struct_name, string_name, states_struct_name, c_file) fsms.append(fsm) return fsms @@ -694,7 +721,7 @@ fsm.find_event_edges(c_files) fsm.add_fsm_alloc(c_files) -fsm_meta = Fsm("meta", "meta") +fsm_meta = Fsm("meta", None, "meta") for fsm in fsms: fsm.add_cross_fsm_links(fsms, c_files, fsm_meta) -- To view, visit https://gerrit.osmocom.org/4377 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib60df7fd19efc99ba9fe797f14c0e3239c4bea20 Gerrit-PatchSet: 1 Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Owner: Neels Hofmeyr <nhofmeyr at sysmocom.de>