+/* Routine to add an interval to a sorted list of intervals
+ extermities. Returns the number of extremities. This is an effing
+ nightmare */
+
+int add_interval(int n, int *switches, int start, int end) {
+ int f, g, k;
+
+ f = 0;
+ while(f < n && switches[f] <= start) { f++; }
+ g = f;
+ while(g < n && switches[g] <= end) { g++; }
+
+ if(f == n) {
+ /* switches[n] start end */
+ /* XXXXXXXXXX| */
+ switches[f] = start;
+ switches[f+1] = end;
+ return n + 2;
+ }
+
+ if(f%2) {
+
+ if(f == g) {
+ /* switches[f-1] start end switches[f] */
+ /* |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX| */
+ return n;
+ }
+
+ if(g%2) {
+ /* switches[f-1] start switches[f] switches[g-1] end switches[g] */
+ /* |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX| ... |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX| */
+ for(k = f; k < n; k++) { switches[k] = switches[(k - f) + g]; }
+ return n - (g - f);
+ } else {
+ /* switches[f-1] start switches[f] switches[g-1] end switches[g] */
+ /* |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX| ... XXXXXXXXXXXX| |XXXXXXXXXX */
+ switches[g - 1] = end;
+ for(k = f; k < n; k++) { switches[k] = switches[(k - f) + (g - 1)]; }
+ return n - ((g - 1) - f);
+ }
+
+ } else {
+
+ if(f == g) {
+ /* switches[f-1] start end switches[f] */
+ /* XXXXXXXXXXXX| |XXXXXXXXXX */
+ for(k = n; k >= f; k--) {
+ switches[k + 2] = switches[k];
+ }
+ switches[f] = start;
+ switches[f + 1] = end;
+ return n + 2;
+ }
+
+ if(g%2) {
+ /* switches[f-1] start switches[f] switches[g-1] end switches[g] */
+ /* XXXXXXXXXXXX| |XXXXXXXXXX ... |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX| */
+ switches[f] = start;
+ for(k = f + 1; k < n; k++) { switches[k] = switches[(k - (f + 1)) + g]; }
+ return n - (g - (f + 1));
+ } else {
+ /* switches[f-1] start switches[f] switches[g-1] end switches[g] */
+ /* XXXXXXXXXXXX| |XXXXXXXXXX ... XXXXXXXXXXXX| |XXXXXXXXXX */
+ switches[f] = start;
+ switches[g - 1] = end;
+ for(k = f + 1; k < n; k++) { switches[k] = switches[(k - (f + 1)) + (g - 1)]; }
+ return n - ((g - 1) - (f + 1));
+ }
+ }
+}
+
+int match(struct matcher *matcher, char *string, int *switches) {
+ int n, nb_switches = 0;
+ char *where;