+ // XXX: This is grossly over-simplified. We assume that every way generates
+ // at most one symbol, which is definitely not the case for ways rendered
+ // with casing. But it should be sufficient for now.
+
+ uint nrefs = clist_size(&s->way_refs);
+ if (nrefs != 2)
+ return;
+
+ struct simp_way_ref *wr1, *wr2, *wr;
+ wr1 = clist_head(&s->way_refs);
+ wr2 = clist_tail(&s->way_refs);
+ if (!(!wr1->prev_on_way != !wr1->next_on_way && !wr2->prev_on_way != !wr2->next_on_way))
+ return;
+ if (wr1->merge_done || wr2->merge_done)
+ return;
+
+ wr = wr1;
+ DBG("Merge: Starting with wr %p", wr);
+
+ for (;;)
+ {
+ wr->merge_done = 1;
+ struct simp_way_ref *or = wref_other_end(wr);
+ struct simp_node *on = or->snode;
+
+ struct simp_way_ref *cr = wref_only_other(on, or);
+ DBG("XXX: wr=%p or=%p cr=%p", wr, or, cr);
+ if (!cr || !sym_same_attrs_p(or->sym, cr->sym))
+ {
+ DBG("Merge: Back stop at %p", cr);
+ break;
+ }
+
+ DBG("Merge: Back to %p", cr);
+ wr = cr;
+
+ if (wr == wr1)
+ {
+ DBG("Merge: Loop detected");
+ return;
+ }
+ }
+
+ // Now, we are at the beginning/end of a single way
+
+ DBG("Merge: Back to %p", wr);
+ wr = wref_other_end(wr);
+ DBG("Merge: Other end is %p", wr);
+ GARY_RESIZE(merge_wrefs, 0);
+ *GARY_PUSH(merge_wrefs) = wr;
+
+ for (;;)
+ {
+ wr->merge_done = 1;
+ struct simp_way_ref *or = wref_other_end(wr);
+ struct simp_node *on = or->snode;
+
+ struct simp_way_ref *cr = wref_only_other(on, or);
+ if (!cr || !sym_same_attrs_p(or->sym, cr->sym))
+ {
+ DBG("Merge: Fwd stop at %p", cr);
+ break;
+ }
+
+ DBG("Merge: Fwd to %p", cr);
+ *GARY_PUSH(merge_wrefs) = cr;
+ wr = cr;
+ }
+
+ if (GARY_SIZE(merge_wrefs) < 2)
+ return;
+
+ DBG("Will merge");
+ num_merged_ways++;