int
np_stream_formatted_node(struct state *st, npath_node_t *npath_node, npath_node_t *npath_node_deeper) {
- fprintf(st->node_stream, "N %lu %u ", npath_node->seqn,
- (unsigned)npath_node->depth
+ fprintf(st->node_stream, "-%u %lu %u ",
+ npath_node->type, npath_node->seqn, (unsigned)npath_node->depth
);
np_print_node_name(st->node_stream, npath_node);
fprintf(st->node_stream, "\n");
GetOptions(
'json!' => \my $opt_json,
+ 'dot!' => \my $opt_dot,
'db=s' => \my $opt_db,
'verbose|v!' => \my $opt_verbose,
'debug|d!' => \my $opt_debug,
my @stack;
my %seqn2node;
+ my $dotnode = sub {
+ my $name = shift;
+ $name =~ s/"/\\"/g;
+ return '"'.$name.'"';
+ };
+
+print "memnodes = [" if $opt_json;
+
+if ($opt_dot) {
+ print "digraph {\n"; # }
+ print "graph [overlap=false]\n"; # target="???", URL="???"
+}
+
+
sub enter_node {
my $x = shift;
if ($opt_json) {
print " " x $x->{depth};
print qq({ "id": "$x->{id}", "name": "$x->{name}", "depth":$x->{depth}, "children":[ \n);
}
+ if ($opt_dot) {
+ #printf $fh qq{\tn%d [ %s ]\n}, $x->{id}, $dotnode->($x->{name});
+ #print qq({ "id": "$x->{id}", "name": "$x->{name}", "depth":$x->{depth}, "children":[ \n);
+ }
return;
}
sub leave_node {
my $x = shift;
delete $seqn2node{$x->{id}};
+
my $self_size = 0; $self_size += $_ for values %{$x->{leaves}};
$x->{self_size} = $self_size;
- if (my $parent = $stack[-1]) {
+
+ my $parent = $stack[-1];
+ if ($parent) {
# link to parent
$x->{parent_id} = $parent->{id};
# accumulate into parent
my $size = $self_size + $x->{kids_size};
print qq(], "data":{ "\$area": $size } },\n);
}
+ if ($opt_dot) {
+ my @attr = (sprintf "label=%s", $dotnode->($x->{name}));
+ push @attr, "shape=point" if $x->{type} == 2;
+ printf qq{n%d [ %s ];\n}, $x->{id}, join(",", @attr);
+ printf qq{n%d -> n%d;\n}, $parent->{id}, $x->{id} if $parent;
+ }
if ($dbh) {
my $attr_json = $j->encode($x->{attr});
my $leaves_json = $j->encode($x->{leaves});
return;
}
-print "memnodes = [" if $opt_json;
while (<>) {
chomp;
my ($type, $id, $val, $name, $extra) = split / /, $_, 5;
- if ($type eq "N") { # Node ($val is depth)
+ if ($type =~ s/^-//) { # Node type ($val is depth)
while ($val < @stack) {
leave_node(my $x = pop @stack);
warn "N $id d$val ends $x->{id} d$x->{depth}: size $x->{self_size}+$x->{kids_size}\n"
if $opt_verbose;
}
die 1 if $stack[$val];
- my $node = $stack[$val] = { id => $id, name => $name, extra => $extra, attr => {}, leaves => {}, depth => $val, self_size=>0, kids_size=>0 };
+ my $node = $stack[$val] = { id => $id, type => $type, name => $name, extra => $extra, attr => {}, leaves => {}, depth => $val, self_size=>0, kids_size=>0 };
enter_node($node);
$seqn2node{$id} = $node;
}
warn "EOF ends $x->{id} d$x->{depth}: size $x->{self_size}+$x->{kids_size}\n";
}
print " ];\n" if $opt_json;
+print "}\n" if $opt_dot;
$dbh->commit if $dbh;