#!/usr/bin/perl # # Copyright (C) 2000 Brad Chapman # # modified by Jean-Marc Valin # # # Parses javadoc-like comments from C++ files and writes them into well-formed # (hopefully) XML NodeClass definitions, that can then be used by Overflow to # extract info about the nodes. # # Usage: # Takes a file as input and prints out the XML, so the read the info from # to_read.cc and output it to nice_xml.def you would need to do something like: # 'perl info2def2.pl to_read.cc > nice_xml.def.' # hash_copy # # a little function to copy over a hash since I couldn't figure out how # to do this in perl. sub hash_copy { my $to_copy = shift(@_); my $new_hash = {}; while (($key, $value) = each (%{$to_copy})) { $$new_hash{$key} = $value; } return $new_hash; } print "\n"; print "\n"; # data structures to store the info for a node. They look like the following: # # info{name} -> name # info{category} -> category # info{description} -> description # info{inputs} -> list of input info # info{inputs}[n]{input_name} -> name # info{inputs}[n]{input_type} -> type # info{inputs}[n]{input_description} -> description # info{outputs} -> list of output info # info{outputs}[n]{output_name} -> name # info{outputs}[n]{output_type} -> type # info{outputs}[n]{output_description} -> description # info{params} -> list of parameter info # info{params}[n]{parameter_name} -> name # info{params}[n]{parameter_type} -> type # info{params}[n]{parameter_value} -> value # info{params}[n]{parameter_description} -> description $default_input = {input_name => "No Name", input_type => "any", input_description => "No Description Available"}; $default_output = {output_name => "No Name", output_type => "any", output_description => "No Description Available"}; $default_param = {parameter_name => "No Name", parameter_type => "any", parameter_value => "", parameter_description => "No Description Available"}; %node_info = (name => "No Name", category => "No Category", description => "No Description Available", inputs => [], outputs => [], params => []); # the last info parsed, so we can deal with carryovers. $last_info = ""; $last_name = ""; # flag so we know if we are in a javadoc comment $in_comment = 0; # assign the inputs and outputs to the default value $current_input = hash_copy($default_input); $current_output = hash_copy($default_output); $current_param = hash_copy($default_param); $curr_filename=$ARGV[0]; $next_filename=$ARGV[1]; $base_filename = $curr_filename; $base_filename =~ s/.*\///; # read through the file while (<>) { if ($next_filename ne $ARGV[0]) { $curr_filename = $next_filename; $next_filename = $ARGV[0]; $base_filename = $curr_filename; $base_filename =~ s/.*\///; } # if we are in a comment, look for the information to parse. if ($in_comment == 1) { # look for a '* @something info', then we need to process the item. if (/\* (@[a-zA-Z:_0-9]+) +([\<\>a-zA-Z:_0-9 .,;\"\'\/\*\!\+=\-\(\)\[\]\{\}]+)/) { $pname = $1; $pval = $2; $pval =~ s//>/g; if ($pname eq '@name') { #print '@name : ', $pname, "\n"; $node_info{substr($pname, 1)} = $pval; } elsif ($pname eq '@category') { $node_info{substr($pname, 1)} = $pval; } elsif ($pname eq '@require') { push @{$filedep{$base_filename}}, $pval; $node_info{substr($pname, 1)} = $pval; } elsif ($pname eq '@description') { $node_info{substr($pname, 1)} = $pval; } # start of a new input elsif ($pname eq '@input_name') { # check if we have an old input we need to append if ($$current_input{input_name} ne 'No Name') { # add the current input to the inputs push @{$node_info{inputs}}, $current_input; # clear the input $current_input = hash_copy($default_input); } $$current_input{substr($pname, 1)} = $pval; } elsif ($pname eq '@input_type') { $$current_input{substr($pname, 1)} = $pval; } elsif ($pname eq '@input_description') { $$current_input{substr($pname, 1)} = $pval; } # start of a new output elsif ($pname eq '@output_name') { # check if we have an old output we need to append if ($$current_output{output_name} ne 'No Name') { # add the current output to the outputs push @{$node_info{outputs}}, $current_output; # clear the info $current_output = hash_copy($default_output); } $$current_output{substr($pname, 1)} = $pval; } elsif ($pname eq '@output_type') { $$current_output{substr($pname, 1)} = $pval; } elsif ($pname eq '@output_description') { $$current_output{substr($pname, 1)} = $pval; } # start of a new parameter elsif ($pname eq '@parameter_name') { # check if we have an old parameter to append to the info if ($$current_param{parameter_name} ne 'No Name') { # add the current parameter to the parameter list push @{$node_info{params}}, $current_param; # clear the parameter info $current_param = hash_copy($default_param); } $$current_param{substr($pname, 1)} = $pval; } elsif ($pname eq '@parameter_type') { $$current_param{substr($pname, 1)} = $pval; } elsif ($pname eq '@parameter_value') { $$current_param{substr($pname, 1)} = $pval; } elsif ($pname eq '@parameter_description') { $$current_param{substr($pname, 1)} = $pval; } else { die 'Unrecognized "@" tag: ', $pname, "\n"; } # set the added information as the last info added $last_name = substr($pname, 1); $last_info = $pval; } elsif (/END\*\// ) { # look for the trailing '*/' if ($$current_input{input_name} ne 'No Name') { push @{$node_info{inputs}}, $current_input; } if ($$current_output{output_name} ne 'No Name') { push @{$node_info{outputs}}, $current_output; } if ($$current_param{parameter_name} ne 'No Name') { push @{$node_info{params}}, $current_param; } print " \n"; foreach $input (@{$node_info{inputs}}) { print " "; print "$$input{input_description}"; print "\n"; } foreach $output (@{$node_info{outputs}}) { print " "; print "$$output{output_description}"; print "\n"; } foreach $param (@{$node_info{params}}) { print " "; print "$$param{parameter_description}"; print "\n"; } print " "; print "$node_info{description}"; print "\n"; print " \n"; # the last info parsed, so we can deal with carryovers. $last_info = ""; $last_name = ""; # flag so we know if we are in a javadoc comment $in_comment = 0; # assign the inputs and outputs to the default value $current_input = ""; $current_output = ""; $current_param = ""; $current_input = hash_copy($default_input); $current_output = hash_copy($default_output); $current_param = hash_copy($default_param); %node_info=0; $in_comment = 0; } # line spill over from the previous comment. Need to add this # info to the previous value elsif (/\* ([\<\>a-zA-Z:_0-9 .,;\"\'\/\*\!\+=\-\(\)\[\]\{\}]+)/) { $new_info = $last_info . "\n" . $1; # if it is input info add it to the current_input if (substr($last_name, 0, 5) eq 'input') { $$current_input{$last_name} = $new_info; } # if it is an output, add it to the current output elsif (substr($last_name, 0, 6) eq 'output') { $$current_output{$last_name} = $new_info; } # if it is a param, add it to the current param elsif (substr($last_name, 0, 9) eq 'parameter') { $$current_param{$last_name} = $new_info; } # otherwise, we can add it directly to the node info else { $node_info{$last_name} = $new_info; } # keep expanding last_info for multiple carryovers $last_info = $new_info; } elsif (/\*/) { # print "blank line \n"; } } # if we aren't in a comment, then keep looking for the beginning elsif (/\/\*Node/) { # look for the initial '/*Node' # print "comment\n"; $in_comment = 1; } #Added by JMV 2001/07/31 elsif (/\/\/\@implements ([a-zA-Z0-9_]*)/) { push @{$dep{$1}}, $base_filename; } elsif (/\/\/\@require ([a-zA-Z0-9_]*)/) { push @{$filedep{$base_filename}}, $1; } elsif (/^\#include \"([a-zA-Z_0-9\.]*)\"/) { push @{$headerdep{$base_filename}}, $1; } } #Added by JMV 2001/07/31 #print "\n"; foreach $module (keys %dep) { print " \n"; foreach $depend (@{$dep{$module}}) { print " \n"; } print " \n"; } foreach $file (keys %filedep) { print " \n"; foreach $module (@{$filedep{$file}}) { print " \n"; } print " \n"; } foreach $file (keys %headerdep) { print " \n"; foreach $header (@{$headerdep{$file}}) { print " \n"; } print " \n"; } #print "\n"; print "\n";