Skip to content

Instantly share code, notes, and snippets.

@syohex
Created May 31, 2011 09:17
Show Gist options
  • Save syohex/1000224 to your computer and use it in GitHub Desktop.
Save syohex/1000224 to your computer and use it in GitHub Desktop.
clowの出力結果から blockdiag形式に変換する
#!/usr/bin/env perl
use strict;
use warnings;
package App::cflow2blockdiag;
use Carp ();
use File::Which ();
sub new {
my ($class, $files_ref, $ignores_regexp) = @_;
Carp::croak("Please install cflow\n") unless File::Which::which('cflow');
bless { files => $files_ref, ignore => $ignores_regexp }, $class;
}
sub run {
my $self = shift;
my $cflow_ref = $self->_exec_cflow;
$self->cflow_to_blockdiag($cflow_ref);
}
sub cflow_to_blockdiag {
my ($self, $cflow_ref) = @_;
my (@flows, @current_flow);
my $prev_indent = -1;
open my $fh, "<", $cflow_ref or Carp::croak("Can't open strref\n");
while ( my $line = <$fh> ) {
chomp $line;
my $indent_num = $line =~ s{\s{4}}{}gxms;
$indent_num ||= 0;
my ($func) = $line =~ m{^(\w+)\(\)};
next if $func =~ $self->{ignore};
if ($indent_num <= $prev_indent) {
push @flows, join ' -> ', @current_flow;
pop @current_flow for 0..($prev_indent - $indent_num);
}
push @current_flow, $func;
$prev_indent = $indent_num;
}
close $fh;
my $flow = join ";\n\t", @flows;
print <<__DIAG__
diagram {
fontsize = 20;
default_shape = roundedbox;
\t$flow
}
__DIAG__
}
sub _exec_cflow {
my $self = shift;
my @cmd = ('cflow', '--omit-arguments', @{$self->{files}});
open my $cflow, "-|", @cmd or Carp::croak("Can't exec cflow\n");
my $output = do { local $/; <$cflow>; };
close $cflow;
return \$output;
}
package main;
use Regexp::Assemble;
my $ra = Regexp::Assemble->new;
$ra->add('printf$');
$ra->add('^[mc]alloc$', 'free');
$ra->add('^strn?(?:cmp|cpy)$');
$ra->add('^mem(?:set|cpy)$');
unless (caller) {
my $app = App::cflow2blockdiag->new(\@ARGV, $ra->re);
$app->run;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment