X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fdoc%2Fscripts%2Fgen_state_diagram.py;fp=src%2Fceph%2Fdoc%2Fscripts%2Fgen_state_diagram.py;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=fccde26295c4cf6ff93b22d930843c76418b64b0;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/doc/scripts/gen_state_diagram.py b/src/ceph/doc/scripts/gen_state_diagram.py deleted file mode 100755 index fccde26..0000000 --- a/src/ceph/doc/scripts/gen_state_diagram.py +++ /dev/null @@ -1,214 +0,0 @@ -#!/usr/bin/env python -import re -import sys - - -def do_filter(generator): - return acc_lines(remove_multiline_comments(to_char(remove_single_line_comments(generator)))) - - -def acc_lines(generator): - current = "" - for i in generator: - current += i - if i == ';' or \ - i == '{' or \ - i == '}': - yield current.lstrip("\n") - current = "" - - -def to_char(generator): - for line in generator: - for char in line: - if char is not '\n': - yield char - else: - yield ' ' - - -def remove_single_line_comments(generator): - for i in generator: - if len(i) and i[0] == '#': - continue - yield re.sub(r'//.*', '', i) - - -def remove_multiline_comments(generator): - saw = "" - in_comment = False - for char in generator: - if in_comment: - if saw is "*": - if char is "/": - in_comment = False - saw = "" - if char is "*": - saw = "*" - continue - if saw is "/": - if char is '*': - in_comment = True - saw = "" - continue - else: - yield saw - saw = "" - if char is '/': - saw = "/" - continue - yield char - - -class StateMachineRenderer(object): - def __init__(self): - self.states = {} # state -> parent - self.machines = {} # state-> initial - self.edges = {} # event -> [(state, state)] - - self.context = [] # [(context, depth_encountered)] - self.context_depth = 0 - self.state_contents = {} - self.subgraphnum = 0 - self.clusterlabel = {} - - def __str__(self): - return "-------------------\n\nstates: %s\n\n machines: %s\n\n edges: %s\n\n context %s\n\n state_contents %s\n\n--------------------" % ( - self.states, - self.machines, - self.edges, - self.context, - self.state_contents - ) - - def read_input(self, input_lines): - previous_line = None - for line in input_lines: - self.get_state(line) - self.get_event(line) - # pass two lines at a time to get the context so that regexes can - # match on split signatures - self.get_context(line, previous_line) - previous_line = line - - def get_context(self, line, previous_line): - match = re.search(r"(\w+::)*::(?P\w+)::\w+\(const (?P\w+)", line) - if match is None and previous_line is not None: - # it is possible that we need to match on the previous line as well, so join - # them to make them one line and try and get this matching - joined_line = ' '.join([previous_line, line]) - match = re.search(r"(\w+::)*::(?P\w+)::\w+\(\s*const (?P\w+)", joined_line) - if match is not None: - self.context.append((match.group('tag'), self.context_depth, match.group('event'))) - if '{' in line: - self.context_depth += 1 - if '}' in line: - self.context_depth -= 1 - while len(self.context) and self.context[-1][1] == self.context_depth: - self.context.pop() - - def get_state(self, line): - if "boost::statechart::state_machine" in line: - tokens = re.search( - r"boost::statechart::state_machine<\s*(\w*),\s*(\w*)\s*>", - line) - if tokens is None: - raise Exception("Error: malformed state_machine line: " + line) - self.machines[tokens.group(1)] = tokens.group(2) - self.context.append((tokens.group(1), self.context_depth, "")) - return - if "boost::statechart::state" in line: - tokens = re.search( - r"boost::statechart::state<\s*(\w*),\s*(\w*)\s*,?\s*(\w*)\s*>", - line) - if tokens is None: - raise Exception("Error: malformed state line: " + line) - self.states[tokens.group(1)] = tokens.group(2) - if tokens.group(2) not in self.state_contents.keys(): - self.state_contents[tokens.group(2)] = [] - self.state_contents[tokens.group(2)].append(tokens.group(1)) - if tokens.group(3) is not "": - self.machines[tokens.group(1)] = tokens.group(3) - self.context.append((tokens.group(1), self.context_depth, "")) - return - - def get_event(self, line): - if "boost::statechart::transition" in line: - for i in re.finditer(r'boost::statechart::transition<\s*([\w:]*)\s*,\s*(\w*)\s*>', - line): - if i.group(1) not in self.edges.keys(): - self.edges[i.group(1)] = [] - if len(self.context) is 0: - raise Exception("no context at line: " + line) - self.edges[i.group(1)].append((self.context[-1][0], i.group(2))) - i = re.search("return\s+transit<\s*(\w*)\s*>()", line) - if i is not None: - if len(self.context) is 0: - raise Exception("no context at line: " + line) - if self.context[-1][2] is "": - raise Exception("no event in context at line: " + line) - if self.context[-1][2] not in self.edges.keys(): - self.edges[self.context[-1][2]] = [] - self.edges[self.context[-1][2]].append((self.context[-1][0], i.group(1))) - - def emit_dot(self): - top_level = [] - for state in self.machines.keys(): - if state not in self.states.keys(): - top_level.append(state) - print >> sys.stderr, "Top Level States: ", str(top_level) - print """digraph G {""" - print '\tsize="7,7"' - print """\tcompound=true;""" - for i in self.emit_state(top_level[0]): - print '\t' + i - for i in self.edges.keys(): - for j in self.emit_event(i): - print j - print """}""" - - def emit_state(self, state): - if state in self.state_contents.keys(): - self.clusterlabel[state] = "cluster%s" % (str(self.subgraphnum),) - yield "subgraph cluster%s {" % (str(self.subgraphnum),) - self.subgraphnum += 1 - yield """\tlabel = "%s";""" % (state,) - yield """\tcolor = "blue";""" - for j in self.state_contents[state]: - for i in self.emit_state(j): - yield "\t"+i - yield "}" - else: - found = False - for (k, v) in self.machines.items(): - if v == state: - yield state+"[shape=Mdiamond];" - found = True - break - if not found: - yield state+";" - - def emit_event(self, event): - def append(app): - retval = "[" - for i in app: - retval += (i + ",") - retval += "]" - return retval - for (fro, to) in self.edges[event]: - appendix = ['label="%s"' % (event,)] - if fro in self.machines.keys(): - appendix.append("ltail=%s" % (self.clusterlabel[fro],)) - while fro in self.machines.keys(): - fro = self.machines[fro] - if to in self.machines.keys(): - appendix.append("lhead=%s" % (self.clusterlabel[to],)) - while to in self.machines.keys(): - to = self.machines[to] - yield("%s -> %s %s;" % (fro, to, append(appendix))) - - -INPUT_GENERATOR = do_filter(sys.stdin.xreadlines()) -RENDERER = StateMachineRenderer() -RENDERER.read_input(INPUT_GENERATOR) -RENDERER.emit_dot()