chiark / gitweb /
builds ours.graph.o !
authorian <ian>
Sat, 19 Mar 2005 15:55:39 +0000 (15:55 +0000)
committerian <ian>
Sat, 19 Mar 2005 15:55:39 +0000 (15:55 +0000)
layout/Makefile
layout/extractgraph
layout/graph-data.h [new file with mode: 0644]
layout/redactgraph.c

index 9b90c83402d1a0499b7ae870c5c7652e06a3e48a..e2e70bb25e527465230b261055cff0ac3a35b06c 100644 (file)
@@ -35,12 +35,14 @@ include segencolayers.m
 o=>$@.new && mv -f $@.new $@
 
 LINK=          $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ $(LIBS)
+NETPBM=                -lnetpbm
+# -lppm
 
 subseg2display:        subseg2display.o
-               $(LINK) -lnetpbm -lppm -lpub -lm
+               $(LINK) $(NETPBM) -lpub -lm
 
 compose-segenco: compose-segenco.o
-               $(LINK) -lnetpbm -lppm
+               $(LINK) $(NETPBM)
 
 %.d4:          %.m4 $(M4INCS) Makefile
                m4 -s <$< $o
index a021635db15e8d18e9e9e2e3b84a77aacd5188e8..d34be3ed2ffc1e90f13a523abdbf141754795a39 100755 (executable)
@@ -53,6 +53,7 @@ $conf{MaxTolerDist}= 0.05;
 $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;
@@ -70,6 +71,11 @@ our @edges;
 # $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";
 }
@@ -140,6 +146,7 @@ sub readin () {
        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;
@@ -154,20 +161,157 @@ sub readin () {
     }
 }
 
+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();
 
 
diff --git a/layout/graph-data.h b/layout/graph-data.h
new file mode 100644 (file)
index 0000000..977d9d2
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ */
+
+#ifndef GRAPH_DATA_H
+#define GRAPH_DATA_H
+
+
+typedef struct Edge Edge;
+typedef struct Segment Segment;
+typedef struct MovFeat MovFeat;
+typedef struct EdgeEnd EdgeEnd;
+typedef struct Node Node;
+typedef struct NodeSide NodeSide;
+
+struct Segment {
+  const char *name; /* 0 if unknown (usually elided by extractgraph) */
+  int n_movfeats;
+  MovFeat *movfeats; /* [0] is fixed */
+};
+
+struct MovFeat {
+  Segment *segment;
+  const char *name; /* 0 if fixed */
+  int n_positions;
+};
+
+struct EdgeEnd {
+  EdgeEnd *back, *next; /* other ends at same side of same node */
+  Edge *edge; /* edge->ends[end].edge==edge */
+  int end; /* edge->ends[end].edge==end */
+  NodeSide *node;
+};
+
+struct Edge {
+  double distance;
+  MovFeat *segment;
+  int movpos; /* 0 if fixed */
+  EdgeEnd ends[2];
+};
+
+struct NodeSide {
+  Node *node; /* node->edges[side].node==node */
+  int side; /* node->edges[side].side==side */
+  EdgeEnd *head, *tail;
+};
+
+struct Node {
+  Node *back, *next;
+  NodeSide sides[2];
+};
+
+extern Node *nodes_head, *nodes_tail;
+
+
+#endif /*GRAPH_DATA_H*/
index b165a2c5d0dc929ba27d50812830bb0d94ed55e3..21070608ab891e6d4af8c804dcadf776d5079dff 100644 (file)
@@ -1,36 +1,5 @@
 /**/
 
-typedef struct Edge Edge;
-typedef struct EdgeEnd EdgeEnd;
-typedef struct Node Node;
-typedef struct NodeSideRef NodeSideRef;
-
-struct EdgeEnd {
-  EdgeNode *back, *next; /* other ends at same side of same node */
-  Edge *edge; /* edge->ends[end].edge==edge */
-  int end; /* edge->ends[end].edge==end */
-  NodeSide *node;
-};
-
-struct Edge {
-  double distance;
-  const char *segment, *movfeatpos;
-  EdgeEnd ends[2];
-};
-
-typedef struct {
-  Node *node; /* node->edges[side].node==node */
-  int side; /* node->edges[side].side==side */
-  EdgeEnd *head, *tail;
-} NodeSide;
-
-struct Node {
-  Node *back, *next;
-  NodeSide sides[2];
-};
-
-static Node *nodes_head, *nodes_tail;
-
 static void extendsplits(void) {
   /*
    * Whenever we have a node which has one or more moveable feature