forked from UTulsa-Research/ag_gen
136 lines
5.2 KiB
Python
136 lines
5.2 KiB
Python
#!/usr/bin/env python4
|
|
|
|
import re
|
|
import argparse
|
|
import io
|
|
import os
|
|
|
|
from sys import argv, exit
|
|
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument("-m", "--manual", dest = "manual", default = None, help="Manual Mode {node #}")
|
|
parser.add_argument("-s", "--state_info", dest="state_info", help="State Info File")
|
|
parser.add_argument("-i", "--input", dest = "input_d", help="Input Dot File")
|
|
parser.add_argument("-o", "--output", dest = "output_d", help="Output Dot File.")
|
|
parser.add_argument("-q", "--quality", dest = "quality", help="Quality to Search for in Auto Mode")
|
|
|
|
args=parser.parse_args()
|
|
#if len(argv) != 4:
|
|
# print("Usage: %s [node ID to path walk from] [input DOT file] [output DOT file]" %argv[0])
|
|
# exit(1)
|
|
if (args.manual == "0"):
|
|
print("This is the root!")
|
|
exit(1)
|
|
|
|
crit_nodes = []
|
|
if(args.manual !=None):
|
|
crit_nodes.append(args.manual)
|
|
else:
|
|
with open(args.state_info, 'r') as myfile:
|
|
text = myfile.read()
|
|
splits = text.split("ID:")
|
|
states = len(splits) -1
|
|
|
|
for i in range(states):
|
|
if "is_critical=true" in splits[i] or (args.quality !=None and args.quality in splits[i]):
|
|
crit_nodes.append(str(i-1))
|
|
print(str(i-1))
|
|
|
|
for crits in crit_nodes:
|
|
|
|
with open(args.input_d, 'r') as in_file:
|
|
text=in_file.read()
|
|
in_file.close()
|
|
|
|
# Splits input file line by line, except for first and last line
|
|
line_splits = text.split(";")
|
|
total_lines = len(line_splits)
|
|
|
|
# The first part of the file - contains the declaration of each state and any coloring
|
|
state_info = text.split("->")[0][:-2].strip('\n')
|
|
num_states=len((state_info.split(";")))-1
|
|
|
|
# The last part of the file - contains all of the edge info
|
|
path_info = text.split("->",1)[0]
|
|
|
|
# Delete all of the state_info except for the first from_node, edge text, then add the path info back
|
|
path_info = path_info[(len(path_info)-2):].strip('\n') +"->" + (text.split("->",1)[1])
|
|
|
|
# declare and init the array - num_states x num_states is probably overkill. Init with -1 since we know that will never be a valid value
|
|
node_paths = [ [-1]*num_states for i in range(num_states)]
|
|
|
|
# length * 3 since it splits into 3 parts: first part is the from_node
|
|
# second part is the to_node
|
|
# third part is the edge label. Delete the trailing '}' and new line character. i+=3 to jump to the next line
|
|
for i in range(0,(3*len(path_info.split(";")))-3,3):
|
|
|
|
# iterate through node_paths[0] to node_paths[num_states] and append the to node and label each time
|
|
# Since it could be out of order, it can't be 0 through num_states - each line you have to check what the from_node actually is, and access that node_paths[#]
|
|
node_paths[int(path_info.replace('->',' ').replace(';',' ').split()[i])].append((path_info.replace('->',' ').replace(';',' ').split()[i+1])+' ' +(path_info.replace('->',' ').replace(';',' ').split()[i+2]))
|
|
|
|
# Remove all the initialized -1's from the array
|
|
for i in range(num_states):
|
|
while -1 in node_paths[i]:
|
|
node_paths[i].remove(-1)
|
|
|
|
#node_paths[x] contains the nodes that x goes to, plus the edge label.
|
|
|
|
curr_node=crits
|
|
next_nodes = []
|
|
parsed_nodes = []
|
|
remove_nodes = []
|
|
|
|
with open("temp.dot", 'w') as tmpDOT:
|
|
tmpDOT.write(state_info+"\n")
|
|
while True:
|
|
for i in range(num_states):
|
|
#if curr_node is the to_node, log the from_node
|
|
# if (re.sub(r'^.*?', curr_node+" ", curr_node+" ")) in repr(node_paths[i]):
|
|
if (str(curr_node) + " ") in repr(node_paths[i]):
|
|
from_node=i
|
|
index =[j for j, s in enumerate(node_paths[i]) if (str(curr_node)+" ") in s]
|
|
if (node_paths[i][index[0]].index(str(curr_node) + " ")) != 0:
|
|
continue
|
|
if from_node not in next_nodes:
|
|
next_nodes.append(from_node)
|
|
tmpDOT.write(str(from_node)+"->"+node_paths[i][index[0]]+";"+"\n")
|
|
if len(next_nodes)>0:
|
|
next_nodes.sort()
|
|
parsed_nodes.append(str(curr_node))
|
|
curr_node=next_nodes.pop()
|
|
else:
|
|
break
|
|
tmpDOT.write("\n")
|
|
parsed_nodes.append('0')
|
|
tmpDOT.close()
|
|
|
|
# Delete the unused states from the dot file so there aren't floating nodes
|
|
for i in range(num_states):
|
|
if repr(i) not in parsed_nodes:
|
|
remove_nodes.append(i)
|
|
|
|
# Count -1 for the new line char, written to make sure there's not a leading new line in the file
|
|
count = -1
|
|
written=0
|
|
|
|
pwd=os.getcwd()
|
|
# Remove all duplicate lines
|
|
#with open(args.output_d, 'w') as outDOT:
|
|
with io.open(pwd +'/path_walk/' + "node_" + str(crits)+".dot", 'w', encoding='utf-8') as outDOT:
|
|
lines_seen = set()
|
|
for line in open("temp.dot", 'r'):
|
|
if count not in remove_nodes:
|
|
if line not in lines_seen:
|
|
if written == 0:
|
|
outDOT.write(line.strip('\n'))
|
|
written=1
|
|
else:
|
|
outDOT.write('\n'+ line.strip('\n'))
|
|
lines_seen.add(line)
|
|
count+=1
|
|
outDOT.write("}")
|
|
outDOT.close()
|
|
|