$conf{MinClearAngle}= 5.0;
$conf{MaxTolerAngle}= 0.5;
$conf{LayerKinds}= ','; # comma-separated list as for split /\,/, ..., -1;
+$conf{EvenUnknownSegments}= 0;
our @layerkinds;
@layerkinds= split /\,/, $conf{LayerKinds}, -1;
# $edges[]{Dist}
# $edges[]{SubSegSpec}
+our %segments;
+# $segments{$segname}{MovFeats}[$movfeatnum]{Name}
+# $segments{$segname}{MovFeats}[$movfeatnum]{Positions}
+# $segments{$segname}{MovFeatMap}{$movfeatname}= $movfeatnum
+
sub comment ($) {
print "/* $_[0] */\n";
}
die unless m/^\%L segmentpart ([A-Za-z_]*)(\d+) (\S+) ([-.eE0-9 ]+)$/;
($layerkind, $level, $subsegspec, $numbers) = ($1,$2,$3,$4);
next unless grep { $layerkind eq $_ } @layerkinds;
+ next unless $subsegspec =~ m,^[^/], or $conf{EvenUnknownSegments};
@numbers = map { $_ + 0 } split / /, $numbers;
$dist= shift @numbers;
@numbers == 6 or die;
}
}
+sub o ($@) {
+ print join('',@_) or die $!;
+}
+
sub pr ($$) {
- my ($kind,$wh) = @_;
+ my ($kind,$ref) = @_;
$ref= "$ref";
$ref =~ y/()/__/;
- return $ref
+ return lc $ref.lc $kind;
+}
+
+sub pr_edgeend ($) {
+ my ($edgeend) = @_;
+ my ($edge,$end) = @$edgeend;
+ my ($endnum);
+ $endnum= $end ^ !!($edge->{SubSegSpec} =~ m/^\-/);
+ return pr(Edge,$edge).".ends[$endnum]";
+}
+
+sub segments () {
+ my ($edge, $sss);
+ my ($segname, $movfeatpos, $movfeat, $movpos);
+ my ($movfeatnum, $movfeatref);
+ for $edge (@edges) {
+ $sss= $edge->{SubSegSpec};
+ $sss =~ m,^\-?(\w*)/(([A-Za-z]*)(\d*))$, or die "$sss ?";
+ ($segname, $movfeatpos, $movfeat, $movpos) = ($1,$2,$3,$4);
+ if (!exists $segments{$segname}) {
+ $segments{$segname}= {
+ MovFeatMap => { '' => 0 },
+ MovFeats => [ { Name => '', Positions => 1 } ]
+ };
+ }
+ $movfeatnum= $segments{$segname}{MovFeatMap}{$movfeat};
+ if (!defined $movfeatnum) {
+ $movfeatnum= @{ $segments{$segname}{MovFeats} };
+ push @{ $segments{$segname}{MovFeats} },
+ { Name => $movfeat, Positions => 0 };
+ $segments{$segname}{MovFeatMap}{$movfeat}= $movfeatnum;
+ }
+ $movfeatref= $segments{$segname}{MovFeats}[$movfeatnum];
+ if (length $movfeat && $movpos >= $movfeatref->{Positions}) {
+ $movfeatref->{Positions}= $movpos + 1;
+ }
+ }
+}
sub writeout () {
- my ($node);
- for $node (@nodes) {
- print "Node ",pr(Node,$node),";\n";
+ my ($node, $edge, $i, $side, $sideedges);
+ my ($end, $endnum, $sss, $reverse, $nodeside, $connectnum, $j, $edgeend);
+ my ($segname, $segment, $movfeats, $movfeat, $delim);
+ my ($movfeatpos, $movpos);
+ o("\n");
+ o("#include \"graph-data.h\"\n");
+ for $node (@nodes) { o("static Node ",pr(Node,$node),";\n"); }
+ for $edge (@edges) { o("static Edge ",pr(Edge,$edge),";\n"); }
+ o("\n");
+ for $segname (keys %segments) {
+ $segment= $segments{$segname};
+ $movfeats= $segment->{MovFeats};
+ o("static MovFeat movfeats_${segname}[];\n");
+ o("static Segment segment_$segname= {");
+ o(" \"$segname\",");
+ o(" ",scalar(@$movfeats),", movfeats_$segname");
+ o(" };\n");
+ o("static MovFeat movfeats_${segname}[]= {");
+ $delim= "";
+ for $movfeat (@$movfeats) {
+ o("$delim\n");
+ o(" { &segment_$segname, ");
+ o(length $movfeat->{Name} ? "\"$movfeat->{Name}\"" : 0);
+ o(", ", $movfeat->{Positions}+0);
+ o(" }");
+ $delim= ",";
+ }
+ o("\n};\n");
+ }
+ o("\n");
+ for ($i=0; $i<@nodes; $i++) {
+ $node= $nodes[$i];
+ o("static Node ",pr(Node,$node),"= { \n");
+ o(" ".($i>0 ? '&'.pr(Node,$nodes[$i-1]) : '0').
+ ", ".($i<$#nodes ? '&'.pr(Node,$nodes[$i+1]) : '0'));
+ o(", {");
+ $delim= '';
+ for ($side=0; $side<2; $side++) {
+ o("$delim\n { &".pr(Node,$node).", $side,");
+ $sideedges= $node->{"Edges$side"};
+ if (defined $sideedges && @$sideedges) {
+ o("\n ",
+ '&'.pr_edgeend($sideedges->[0]),
+ ", ",
+ '&'.pr_edgeend($sideedges->[$#$sideedges]));
+ } else {
+ o(' 0, 0');
+ }
+ o(" }");
+ $delim= ',';
+ }
+ o("\n }\n};\n");
+ }
+ o("\n");
+ for $edge (@edges) {
+ o("static Edge ",pr(Edge,$edge),"= {\n");
+ o(" $edge->{Dist}, ");
+ $sss= $edge->{SubSegSpec};
+ $reverse= !!($sss =~ s/^\-//);
+ if ($reverse) { o("/*reverse*/ "); }
+ $sss =~ m,^(\w*)/(([A-Za-z]*)(\d*))$, or die;
+ ($segname, $movfeatpos, $movfeat, $movpos) = ($1,$2,$3,$4);
+ o("&movfeats_${segname}[",
+ $segments{$segname}{MovFeatMap}{$movfeat},
+ "], ",
+ (length $movfeat ? $movpos : 0),
+ ", {");
+ $delim= '';
+ for ($endnum=0; $endnum<2; $endnum++) {
+ $end= $endnum ^ $reverse;
+ o("$delim\n {");
+ $nodeside= $edge->{"Node$end"};
+ $node= $nodeside->[0]; $side= $nodeside->[1];
+ $sideedges= $node->{"Edges$side"};
+ undef $connectnum;
+ for ($j=0; $j<@$sideedges; $j++) {
+ $edgeend= $sideedges->[$j];
+ if ($edgeend->[0] == $edge &&
+ $edgeend->[1] == $end) {
+ die if defined $connectnum;
+ $connectnum= $j;
+ }
+ }
+ die unless defined $connectnum;
+ o(" ".($connectnum > 0 ?
+ '&'.pr_edgeend($sideedges->[$connectnum-1]) : '0'),
+ ", ".($connectnum < $#$sideedges ?
+ '&'.pr_edgeend($sideedges->[$connectnum+1]) : '0'));
+ o(",\n &".pr(Edge,$edge),", $end, ",
+ "&".pr(Node,$node).".sides[$side]");
+ o(" }");
+ $delim= ',';
+ }
+ o("\n }\n};\n");
}
+ o("\n");
+ o("Node *nodes_head= ",(@nodes ? '&'.pr(Node,$nodes[0]) : 0),";\n");
+ o("Node *nodes_tail= ",(@nodes ? '&'.pr(Node,$nodes[$#nodes]) : 0),";\n");
}
+o("/*autogenerated - do not edit*/\n\n");
readin();
+segments();
writeout();