#!/usr/bin/perl -w # # $Id$ # # Copyright 1989-2016 MINES ParisTech # # This file is part of PIPS. # # PIPS is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # # PIPS is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. # # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with PIPS. If not, see . # # This takes a PIPS output file in the GRAPH format as a file name # and generates a new one in the daVinci format on stdout. # # Ronan.Keryell@cri.ensmp.fr, 5/09/1995. $statement_number = 0; $indent_level = 0; $output_statement_buffer = ""; $this_is_the_unstructured_entry_p = 0; %node_attribute_to_add = (); %edge_attribute_to_add = (); sub indent_string { local($i) = $indent_level; return " " x $indent_level; } sub output_indent { print &indent_string; } sub indent_plus { $indent_level += 2; } sub indent_minus { $indent_level -= 2; } sub output_a_statement_begin { local($label, $comment) = @_; &output_indent; print "l(\"$label\",\n"; $indent_level += 2; &output_indent; print "n(\"$comment\",\n"; $indent_level += 2; &output_indent; # Remove the \ and n at the end: chop $output_statement_buffer; chop $output_statement_buffer; print "[\n"; &indent_plus; if ($this_is_the_unstructured_entry_p == 1) { &add_a_node_attribute("_GO", "ellipse"); } &add_a_node_attribute("OBJECT", $output_statement_buffer); &add_a_node_attribute("FONTFAMILY", "courier"); $output_statement_buffer = ""; &output_some_other_node_attributes; &indent_minus ; &output_indent; print "],\n"; &output_indent; print "[\n"; &indent_plus ; } sub output_a_successor { local($successor, $comment) = @_; &output_indent; print "e(\"$comment\", ["; &output_some_other_edge_attributes; print "], r(\"$successor\")),\n"; } sub output_a_statement_end { &indent_minus; &output_indent; print "]\n"; &indent_minus; &output_indent; print " )\n"; &indent_minus; &output_indent; print " ),\n"; $this_is_the_unstructured_entry_p = 0; } sub output_some_other_node_attributes { while (($attribute, $value) = each %node_attribute_to_add) { &output_indent; print "a(\"$attribute\", \"$value\"),\n"; } %node_attribute_to_add = (); } sub add_a_node_attribute { local($attribute, $value) = @_; # Keep only the last value for this attribute: $node_attribute_to_add{$attribute} = $value; } sub output_some_other_edge_attributes { while (($attribute, $value) = each %edge_attribute_to_add) { &output_indent; print "a(\"$attribute\", \"$value\"),\n"; } %edge_attribute_to_add = (); } sub add_an_edge_attribute { local($attribute, $value) = @_; # Keep only the last value for this attribute: $edge_attribute_to_add{$attribute} = $value; } sub output_a_node { local($label, $name, $successors, $comment) = @_; &output_indent; print "l(\"$label\",\n"; $indent_level += 2; &output_indent; print "n(\"$comment\",\n"; $indent_level += 2; &output_indent; # Remove the \ and n at the end: chop $output_statement_buffer; chop $output_statement_buffer; print "[\n"; &indent_plus ; &add_a_node_attribute("OBJECT", $name); &output_some_other_node_attributes; &indent_minus ; &output_indent; print "],\n"; &output_indent; print "[\n"; &indent_plus ; foreach $successor (split(/ /, $successors)) { &output_a_successor($successor, $comment); } &indent_minus; &output_indent; print "]\n"; &indent_minus; &output_indent; print " )\n"; &indent_minus; &output_indent; print " ),\n"; } # If the node given to this procedure is an entry node of an # unstructured that has an unreachable exit node, display a dashed arrow # from the entry node to the exit: sub output_an_eventual_unreachable_arrow { my($control) = @_; if ($unreachable_exit{$control}) { $exit_node = $unreachable_exit{$control}; &add_an_edge_attribute("EDGEPATTERN", "dashed"); &add_an_edge_attribute("EDGECOLOR", "violet"); &output_a_successor($exit_node, "Unreachable from $control to $exit_node"); } } sub keep_for_output { my($string) = @_; $output_statement_buffer .= $string . "\\n"; } $input_file_name = $ARGV[0]; shift; # First build a map of unstructured with unreachable exit: open(INPUT, "<$input_file_name") || die "Cannot open \"$input_file_name\"."; while () { /^\204Unstructured Unreachable (.*) -> (.*)$/ && do { # \204Unstructured Unreachable 0xf4a3e8 -> 0xf4a8a8 $entry_control = $1; $exit_control = $2; $unreachable_exit{$entry_control} = $exit_control; } } close INPUT || die "Cannot close \"$input_file_name\"."; print "[\n"; $indent_level += 2; # The label of the statement: $control = $statement_number; # Entry node of the module: &add_a_node_attribute("COLOR", "yellow"); # Open again the imput file: open(INPUT, "<$input_file_name") || die "Cannot open \"$input_file_name\"."; while () { #print; chop; # daVinci do not like at all TABs: s/\t/ /g; # Protect the "" : s/"/\\"/g; ($a_command_line = $_) =~ s/.(.*)/$1/; /^\200Unstructured (.*) end: (.*)$/ && do { # €Unstructured 0x3c79f0 end: 0x3c8f30 $unstructured_begin = $1; $unstructured_end = $2; &output_a_statement_begin($control, "Statement not from an unstructured"); &output_a_successor($unstructured_begin, "Go to the entry of the unstructured"); &output_a_statement_end(); $statement_number ++; # Keep track of the number of the statement that should follow # this unstructured at its exit: push(@statement_number_stack, $statement_number); # Since the first node could be an IF, delay the _GO $this_is_the_unstructured_entry_p = 1; #&add_a_node_attribute("_GO", "ellipse"); &add_a_node_attribute("COLOR", "lightgreen"); next; }; /^\201Unstructured End (.*) end: (.*)$/ && do { # Unstructured End 0x3cfa40 end: 0x3cfa40 $unstructured_begin = $1; $unstructured_end = $2; $control = pop(@statement_number_stack); next; }; /^\202Unstructured Item (.*)$/ && do { # \202Unstructured Item 0x3c79f0 # Should use a stack here ? $control = $1; next; }; /^\203Unstructured Successor ->(.*)$/ && do { # \203Unstructured Successor 0x3c8280 @successors = split(/ /, $1); # Be careful, if there is something in the the successors, the first # blank generated a void element... # print "\n**** @successors, $#successors\n"; if ($#successors == -1) { &add_a_node_attribute("_GO", "ellipse"); &add_a_node_attribute("COLOR", "lightgray"); &output_a_statement_begin($control, $a_command_line); &output_a_successor($statement_number_stack[$#statement_number_stack], "The unstructured end point to the statement following the unstructured"); } elsif ($#successors == 2) { # 2 successors, that is an "if then else": &add_a_node_attribute("_GO", "rhombus"); if ($this_is_the_unstructured_entry_p == 0) { &add_a_node_attribute("COLOR", "cyan"); } else { # Display a lightgreen rhombus to mark the IF at the unstructured entry: $this_is_the_unstructured_entry_p = 0; } &output_a_statement_begin($control, $a_command_line); &output_an_eventual_unreachable_arrow($control); &add_an_edge_attribute("EDGECOLOR", "red"); &output_a_successor("then_$statement_number", $a_command_line); &add_an_edge_attribute("EDGECOLOR", "blue"); &output_a_successor("else_$statement_number", $a_command_line); &output_a_statement_end(); &add_a_node_attribute("COLOR", "lightred"); &add_a_node_attribute("_GO", "text"); &add_a_node_attribute("FONTFAMILY", "helvetica"); &add_a_node_attribute("FONTSTYLE", "bold_italic"); &add_an_edge_attribute("EDGECOLOR", "red"); &output_a_node("then_$statement_number", "THEN", $successors[1], $a_command_line); &add_a_node_attribute("COLOR", "lightblue"); &add_a_node_attribute("_GO", "text"); &add_a_node_attribute("FONTFAMILY", "helvetica"); &add_a_node_attribute("FONTSTYLE", "bold_italic"); &add_an_edge_attribute("EDGECOLOR", "blue"); &output_a_node("else_$statement_number", "ELSE", $successors[2], $a_command_line); $statement_number ++; next; } else { # Just a sequence I guess: */ &output_a_statement_begin($control, $a_command_line); &output_a_successor($successors[1], $a_command_line); &output_an_eventual_unreachable_arrow($control); } &output_a_statement_end(); next; }; # By default, put the statement with a an explicit \ n for daVinci: &keep_for_output($_); } close INPUT || die "Cannot close \"$input_file_name\"."; &output_a_statement_begin($control, "Statement not from an unstructured"); &output_a_statement_end(); print "]\n";