fix
[oweals/gnunet.git] / src / regex / regex.c
1 /*
2      This file is part of GNUnet
3      (C) 2012 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20 /**
21  * @file src/regex/regex.c
22  * @brief library to create automatons from regular expressions
23  * @author Maximilian Szengel
24  */
25 #include "platform.h"
26 #include "gnunet_container_lib.h"
27 #include "gnunet_crypto_lib.h"
28 #include "gnunet_regex_lib.h"
29 #include "regex_internal.h"
30
31
32 /**
33  * Set of states.
34  */
35 struct GNUNET_REGEX_StateSet
36 {
37   /**
38    * Array of states.
39    */
40   struct GNUNET_REGEX_State **states;
41
42   /**
43    * Length of the 'states' array.
44    */
45   unsigned int len;
46 };
47
48
49 /**
50  * Compare two strings for equality. If either is NULL they are not equal.
51  *
52  * @param str1 first string for comparison.
53  * @param str2 second string for comparison.
54  *
55  * @return 0 if the strings are the same or both NULL, 1 or -1 if not.
56  */
57 static int
58 nullstrcmp (const char *str1, const char *str2)
59 {
60   if ((NULL == str1) != (NULL == str2))
61     return -1;
62   if ((NULL == str1) && (NULL == str2))
63     return 0;
64
65   return strcmp (str1, str2);
66 }
67
68
69 /**
70  * Adds a transition from one state to another on 'label'. Does not add
71  * duplicate states.
72  *
73  * @param ctx context
74  * @param from_state starting state for the transition
75  * @param label transition label
76  * @param to_state state to where the transition should point to
77  */
78 static void
79 state_add_transition (struct GNUNET_REGEX_Context *ctx,
80                       struct GNUNET_REGEX_State *from_state, const char *label,
81                       struct GNUNET_REGEX_State *to_state)
82 {
83   struct GNUNET_REGEX_Transition *t;
84   struct GNUNET_REGEX_Transition *oth;
85
86   if (NULL == from_state)
87   {
88     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not create Transition.\n");
89     return;
90   }
91
92   // Do not add duplicate state transitions
93   for (t = from_state->transitions_head; NULL != t; t = t->next)
94   {
95     if (t->to_state == to_state && 0 == nullstrcmp (t->label, label) &&
96         t->from_state == from_state)
97       return;
98   }
99
100   // sort transitions by label
101   for (oth = from_state->transitions_head; NULL != oth; oth = oth->next)
102   {
103     if (0 < nullstrcmp (oth->label, label))
104       break;
105   }
106
107   t = GNUNET_malloc (sizeof (struct GNUNET_REGEX_Transition));
108   if (NULL != ctx)
109     t->id = ctx->transition_id++;
110   if (NULL != label)
111     t->label = GNUNET_strdup (label);
112   else
113     t->label = NULL;
114   t->to_state = to_state;
115   t->from_state = from_state;
116
117   // Add outgoing transition to 'from_state'
118   from_state->transition_count++;
119   GNUNET_CONTAINER_DLL_insert_before (from_state->transitions_head,
120                                       from_state->transitions_tail, oth, t);
121 }
122
123
124 /**
125  * Remove a 'transition' from 'state'.
126  *
127  * @param state state from which the to-be-removed transition originates.
128  * @param transition transition that should be removed from state 'state'.
129  */
130 static void
131 state_remove_transition (struct GNUNET_REGEX_State *state,
132                          struct GNUNET_REGEX_Transition *transition)
133 {
134   if (NULL == state || NULL == transition)
135     return;
136
137   if (transition->from_state != state)
138     return;
139
140   GNUNET_free_non_null (transition->label);
141
142   state->transition_count--;
143   GNUNET_CONTAINER_DLL_remove (state->transitions_head, state->transitions_tail,
144                                transition);
145
146   GNUNET_free (transition);
147 }
148
149
150 /**
151  * Compare two states. Used for sorting.
152  *
153  * @param a first state
154  * @param b second state
155  *
156  * @return an integer less than, equal to, or greater than zero
157  *         if the first argument is considered to be respectively
158  *         less than, equal to, or greater than the second.
159  */
160 static int
161 state_compare (const void *a, const void *b)
162 {
163   struct GNUNET_REGEX_State **s1;
164   struct GNUNET_REGEX_State **s2;
165
166   s1 = (struct GNUNET_REGEX_State **) a;
167   s2 = (struct GNUNET_REGEX_State **) b;
168
169   return (*s1)->id - (*s2)->id;
170 }
171
172
173 /**
174  * Get all edges leaving state 's'.
175  *
176  * @param s state.
177  * @param edges all edges leaving 's', expected to be allocated and have enough
178  *        space for s->transitions_count elements.
179  *
180  * @return number of edges.
181  */
182 static unsigned int
183 state_get_edges (struct GNUNET_REGEX_State *s, struct GNUNET_REGEX_Edge *edges)
184 {
185   struct GNUNET_REGEX_Transition *t;
186   unsigned int count;
187
188   if (NULL == s)
189     return 0;
190
191   count = 0;
192
193   for (t = s->transitions_head; NULL != t; t = t->next)
194   {
195     if (NULL != t->to_state)
196     {
197       edges[count].label = t->label;
198       edges[count].destination = t->to_state->hash;
199       count++;
200     }
201   }
202   return count;
203 }
204
205
206 /**
207  * Compare to state sets by comparing the id's of the states that are contained
208  * in each set. Both sets are expected to be sorted by id!
209  *
210  * @param sset1 first state set
211  * @param sset2 second state set
212  *
213  * @return an integer less than, equal to, or greater than zero
214  *         if the first argument is considered to be respectively
215  *         less than, equal to, or greater than the second.
216  */
217 static int
218 state_set_compare (struct GNUNET_REGEX_StateSet *sset1,
219                    struct GNUNET_REGEX_StateSet *sset2)
220 {
221   int result;
222   unsigned int i;
223
224   if (NULL == sset1 || NULL == sset2)
225     return 1;
226
227   result = sset1->len - sset2->len;
228
229   for (i = 0; i < sset1->len; i++)
230   {
231     if (0 != result)
232       break;
233
234     result = state_compare (&sset1->states[i], &sset2->states[i]);
235   }
236   return result;
237 }
238
239
240 /**
241  * Clears the given StateSet 'set'
242  *
243  * @param set set to be cleared
244  */
245 static void
246 state_set_clear (struct GNUNET_REGEX_StateSet *set)
247 {
248   if (NULL == set)
249     return;
250
251   if (set->len > 0)
252     GNUNET_array_grow (set->states, set->len, 0);
253   GNUNET_free (set);
254 }
255
256
257 /**
258  * Clears an automaton fragment. Does not destroy the states inside the
259  * automaton.
260  *
261  * @param a automaton to be cleared
262  */
263 static void
264 automaton_fragment_clear (struct GNUNET_REGEX_Automaton *a)
265 {
266   if (NULL == a)
267     return;
268
269   a->start = NULL;
270   a->end = NULL;
271   a->states_head = NULL;
272   a->states_tail = NULL;
273   a->state_count = 0;
274   GNUNET_free (a);
275 }
276
277
278 /**
279  * Frees the memory used by State 's'
280  *
281  * @param s state that should be destroyed
282  */
283 static void
284 automaton_destroy_state (struct GNUNET_REGEX_State *s)
285 {
286   struct GNUNET_REGEX_Transition *t;
287   struct GNUNET_REGEX_Transition *next_t;
288
289   if (NULL == s)
290     return;
291
292   GNUNET_free_non_null (s->name);
293   GNUNET_free_non_null (s->proof);
294   state_set_clear (s->nfa_set);
295
296   for (t = s->transitions_head; NULL != t; t = next_t)
297   {
298     next_t = t->next;
299     state_remove_transition (s, t);
300   }
301
302   GNUNET_free (s);
303 }
304
305
306 /**
307  * Remove a state from the given automaton 'a'. Always use this function when
308  * altering the states of an automaton. Will also remove all transitions leading
309  * to this state, before destroying it.
310  *
311  * @param a automaton
312  * @param s state to remove
313  */
314 static void
315 automaton_remove_state (struct GNUNET_REGEX_Automaton *a,
316                         struct GNUNET_REGEX_State *s)
317 {
318   struct GNUNET_REGEX_State *s_check;
319   struct GNUNET_REGEX_Transition *t_check;
320   struct GNUNET_REGEX_Transition *t_check_next;
321
322   if (NULL == a || NULL == s)
323     return;
324
325   // remove all transitions leading to this state
326   for (s_check = a->states_head; NULL != s_check; s_check = s_check->next)
327   {
328     for (t_check = s_check->transitions_head; NULL != t_check;
329          t_check = t_check_next)
330     {
331       t_check_next = t_check->next;
332       if (t_check->to_state == s)
333         state_remove_transition (s_check, t_check);
334     }
335   }
336
337   // remove state
338   GNUNET_CONTAINER_DLL_remove (a->states_head, a->states_tail, s);
339   a->state_count--;
340
341   automaton_destroy_state (s);
342 }
343
344
345 /**
346  * Merge two states into one. Will merge 's1' and 's2' into 's1' and destroy
347  * 's2'.
348  *
349  * @param ctx context
350  * @param a automaton
351  * @param s1 first state
352  * @param s2 second state, will be destroyed
353  */
354 static void
355 automaton_merge_states (struct GNUNET_REGEX_Context *ctx,
356                         struct GNUNET_REGEX_Automaton *a,
357                         struct GNUNET_REGEX_State *s1,
358                         struct GNUNET_REGEX_State *s2)
359 {
360   struct GNUNET_REGEX_State *s_check;
361   struct GNUNET_REGEX_Transition *t_check;
362   struct GNUNET_REGEX_Transition *t;
363   struct GNUNET_REGEX_Transition *t_next;
364   char *new_name;
365   int is_dup;
366
367   GNUNET_assert (NULL != ctx && NULL != a && NULL != s1 && NULL != s2);
368
369   if (s1 == s2)
370     return;
371
372   // 1. Make all transitions pointing to s2 point to s1, unless this transition
373   // does not already exists, if it already exists remove transition.
374   for (s_check = a->states_head; NULL != s_check; s_check = s_check->next)
375   {
376     for (t_check = s_check->transitions_head; NULL != t_check; t_check = t_next)
377     {
378       t_next = t_check->next;
379
380       if (s2 == t_check->to_state)
381       {
382         is_dup = GNUNET_NO;
383         for (t = t_check->from_state->transitions_head; NULL != t; t = t->next)
384         {
385           if (t->to_state == s1 && 0 == strcmp (t_check->label, t->label))
386             is_dup = GNUNET_YES;
387         }
388         if (GNUNET_NO == is_dup)
389           t_check->to_state = s1;
390         else
391           state_remove_transition (t_check->from_state, t_check);
392       }
393     }
394   }
395
396   // 2. Add all transitions from s2 to sX to s1
397   for (t_check = s2->transitions_head; NULL != t_check; t_check = t_check->next)
398   {
399     if (t_check->to_state != s1)
400       state_add_transition (ctx, s1, t_check->label, t_check->to_state);
401   }
402
403   // 3. Rename s1 to {s1,s2}
404   new_name = s1->name;
405   GNUNET_asprintf (&s1->name, "{%s,%s}", new_name, s2->name);
406   GNUNET_free (new_name);
407
408   // remove state
409   GNUNET_CONTAINER_DLL_remove (a->states_head, a->states_tail, s2);
410   a->state_count--;
411   automaton_destroy_state (s2);
412 }
413
414
415 /**
416  * Add a state to the automaton 'a', always use this function to alter the
417  * states DLL of the automaton.
418  *
419  * @param a automaton to add the state to
420  * @param s state that should be added
421  */
422 static void
423 automaton_add_state (struct GNUNET_REGEX_Automaton *a,
424                      struct GNUNET_REGEX_State *s)
425 {
426   GNUNET_CONTAINER_DLL_insert (a->states_head, a->states_tail, s);
427   a->state_count++;
428 }
429
430
431 /**
432  * Depth-first traversal (DFS) of all states that are reachable from state
433  * 's'. Performs 'action' on each visited state.
434  *
435  * @param s start state.
436  * @param marks an array of size a->state_count to remember which state was
437  *        already visited.
438  * @param count current count of the state.
439  * @param check function that is checked before advancing on each transition
440  *              in the DFS.
441  * @param check_cls closure for check.
442  * @param action action to be performed on each state.
443  * @param action_cls closure for action.
444  */
445 static void
446 automaton_state_traverse (struct GNUNET_REGEX_State *s, int *marks,
447                           unsigned int *count,
448                           GNUNET_REGEX_traverse_check check, void *check_cls,
449                           GNUNET_REGEX_traverse_action action, void *action_cls)
450 {
451   struct GNUNET_REGEX_Transition *t;
452
453   if (GNUNET_YES == marks[s->traversal_id])
454     return;
455
456   marks[s->traversal_id] = GNUNET_YES;
457
458   if (NULL != action)
459     action (action_cls, *count, s);
460
461   (*count)++;
462
463   for (t = s->transitions_head; NULL != t; t = t->next)
464   {
465     if (NULL == check ||
466         (NULL != check && GNUNET_YES == check (check_cls, s, t)))
467     {
468       automaton_state_traverse (t->to_state, marks, count, check, check_cls,
469                                 action, action_cls);
470     }
471   }
472 }
473
474
475 /**
476  * Traverses the given automaton using depth-first-search (DFS) from it's start
477  * state, visiting all reachable states and calling 'action' on each one of
478  * them.
479  *
480  * @param a automaton to be traversed.
481  * @param start start state, pass a->start or NULL to traverse the whole automaton.
482  * @param check function that is checked before advancing on each transition
483  *              in the DFS.
484  * @param check_cls closure for check.
485  * @param action action to be performed on each state.
486  * @param action_cls closure for action
487  */
488 void
489 GNUNET_REGEX_automaton_traverse (const struct GNUNET_REGEX_Automaton *a,
490                                  struct GNUNET_REGEX_State *start,
491                                  GNUNET_REGEX_traverse_check check,
492                                  void *check_cls,
493                                  GNUNET_REGEX_traverse_action action,
494                                  void *action_cls)
495 {
496   unsigned int count;
497   struct GNUNET_REGEX_State *s;
498
499   if (NULL == a || 0 == a->state_count)
500     return;
501
502   int marks[a->state_count];
503
504   for (count = 0, s = a->states_head; NULL != s && count < a->state_count;
505        s = s->next, count++)
506   {
507     s->traversal_id = count;
508     marks[s->traversal_id] = GNUNET_NO;
509   }
510
511   count = 0;
512
513   if (NULL == start)
514     s = a->start;
515   else
516     s = start;
517
518   automaton_state_traverse (s, marks, &count, check, check_cls, action,
519                             action_cls);
520 }
521
522
523 /**
524  * Check if the given string 'str' needs parentheses around it when
525  * using it to generate a regex.
526  *
527  * @param str string
528  *
529  * @return GNUNET_YES if parentheses are needed, GNUNET_NO otherwise
530  */
531 static int
532 needs_parentheses (const char *str)
533 {
534   size_t slen;
535   const char *op;
536   const char *cl;
537   const char *pos;
538   unsigned int cnt;
539
540   if ((NULL == str) || ((slen = strlen (str)) < 2))
541     return GNUNET_NO;
542
543   if ('(' != str[0])
544     return GNUNET_YES;
545   cnt = 1;
546   pos = &str[1];
547   while (cnt > 0)
548   {
549     cl = strchr (pos, ')');
550     if (NULL == cl)
551     {
552       GNUNET_break (0);
553       return GNUNET_YES;
554     }
555     op = strchr (pos, '(');
556     if ((NULL != op) && (op < cl))
557     {
558       cnt++;
559       pos = op + 1;
560       continue;
561     }
562     /* got ')' first */
563     cnt--;
564     pos = cl + 1;
565   }
566   return (*pos == '\0') ? GNUNET_NO : GNUNET_YES;
567 }
568
569
570 /**
571  * Remove parentheses surrounding string 'str'.
572  * Example: "(a)" becomes "a", "(a|b)|(a|c)" stays the same.
573  * You need to GNUNET_free the returned string.
574  *
575  * @param str string, free'd or re-used by this function, can be NULL
576  *
577  * @return string without surrounding parentheses, string 'str' if no preceding
578  *         epsilon could be found, NULL if 'str' was NULL
579  */
580 static char *
581 remove_parentheses (char *str)
582 {
583   size_t slen;
584   const char *pos;
585
586   if ((NULL == str) || ('(' != str[0]) ||
587       (str[(slen = strlen (str)) - 1] != ')'))
588     return str;
589
590   pos = strchr (&str[1], ')');
591   if (pos == &str[slen - 1])
592   {
593     memmove (str, &str[1], slen - 2);
594     str[slen - 2] = '\0';
595   }
596   return str;
597 }
598
599
600 /**
601  * Check if the string 'str' starts with an epsilon (empty string).
602  * Example: "(|a)" is starting with an epsilon.
603  *
604  * @param str string to test
605  *
606  * @return 0 if str has no epsilon, 1 if str starts with '(|' and ends with ')'
607  */
608 static int
609 has_epsilon (const char *str)
610 {
611   return (NULL != str) && ('(' == str[0]) && ('|' == str[1]) &&
612       (')' == str[strlen (str) - 1]);
613 }
614
615
616 /**
617  * Remove an epsilon from the string str. Where epsilon is an empty string
618  * Example: str = "(|a|b|c)", result: "a|b|c"
619  * The returned string needs to be freed.
620  *
621  * @param str string
622  *
623  * @return string without preceding epsilon, string 'str' if no preceding
624  *         epsilon could be found, NULL if 'str' was NULL
625  */
626 static char *
627 remove_epsilon (const char *str)
628 {
629   size_t len;
630
631   if (NULL == str)
632     return NULL;
633   if (('(' == str[0]) && ('|' == str[1]))
634   {
635     len = strlen (str);
636     if (')' == str[len - 1])
637       return GNUNET_strndup (&str[2], len - 3);
638   }
639   return GNUNET_strdup (str);
640 }
641
642
643 /**
644  * Compare 'str1', starting from position 'k',  with whole 'str2'
645  *
646  * @param str1 first string to compare, starting from position 'k'
647  * @param str2 second string for comparison
648  * @param k starting position in 'str1'
649  *
650  * @return -1 if any of the strings is NULL, 0 if equal, non 0 otherwise
651  */
652 static int
653 strkcmp (const char *str1, const char *str2, size_t k)
654 {
655   if ((NULL == str1) || (NULL == str2) || (strlen (str1) < k))
656     return -1;
657   return strcmp (&str1[k], str2);
658 }
659
660
661 /**
662  * Helper function used as 'action' in 'GNUNET_REGEX_automaton_traverse'
663  * function to create the depth-first numbering of the states.
664  *
665  * @param cls states array.
666  * @param count current state counter.
667  * @param s current state.
668  */
669 void
670 number_states (void *cls, const unsigned int count,
671                struct GNUNET_REGEX_State *s)
672 {
673   struct GNUNET_REGEX_State **states = cls;
674
675   s->dfs_id = count;
676   if (NULL != states)
677     states[count] = s;
678 }
679
680
681 /**
682  * Construct the regular expression given the inductive step,
683  * $R^{(k)}_{ij} = R^{(k-1)}_{ij} | R^{(k-1)}_{ik} ( R^{(k-1)}_{kk} )^*
684  * R^{(k-1)}_{kj}, and simplify the resulting expression saved in R_cur_ij.
685  *
686  * @param R_last_ij value of  $R^{(k-1)_{ij}.
687  * @param R_last_ik value of  $R^{(k-1)_{ik}.
688  * @param R_last_kk value of  $R^{(k-1)_{kk}.
689  * @param R_last_kj value of  $R^{(k-1)_{kj}.
690  * @param R_cur_ij result for this inductive step is saved in R_cur_ij, R_cur_ij
691  *                 is expected to be NULL when called!
692  */
693 static void
694 automaton_create_proofs_simplify (char *R_last_ij, char *R_last_ik,
695                                   char *R_last_kk, char *R_last_kj,
696                                   char **R_cur_ij)
697 {
698   char *R_cur_l;
699   char *R_cur_r;
700   char *temp_a;
701   char *temp_b;
702   char *R_temp_ij;
703   char *R_temp_ik;
704   char *R_temp_kj;
705   char *R_temp_kk;
706
707   int eps_check;
708   int ij_ik_cmp;
709   int ij_kj_cmp;
710
711   int ik_kk_cmp;
712   int kk_kj_cmp;
713   int clean_ik_kk_cmp;
714   int clean_kk_kj_cmp;
715   unsigned int cnt;
716
717   size_t length;
718   size_t length_l;
719   size_t length_r;
720
721   GNUNET_assert (NULL == *R_cur_ij && NULL != R_cur_ij);
722
723   // $R^{(k)}_{ij} = R^{(k-1)}_{ij} | R^{(k-1)}_{ik} ( R^{(k-1)}_{kk} )^* R^{(k-1)}_{kj}
724   // R_last == R^{(k-1)}, R_cur == R^{(k)}
725   // R_cur_ij = R_cur_l | R_cur_r
726   // R_cur_l == R^{(k-1)}_{ij}
727   // R_cur_r == R^{(k-1)}_{ik} ( R^{(k-1)}_{kk} )^* R^{(k-1)}_{kj}
728
729   if ((NULL == R_last_ij) && ((NULL == R_last_ik) || (NULL == R_last_kk) ||     /* technically cannot happen, but looks saner */
730                               (NULL == R_last_kj)))
731   {
732     /* R^{(k)}_{ij} = N | N */
733     *R_cur_ij = NULL;
734     return;
735   }
736
737   if ((NULL == R_last_ik) || (NULL == R_last_kk) ||     /* technically cannot happen, but looks saner */
738       (NULL == R_last_kj))
739   {
740     /*  R^{(k)}_{ij} = R^{(k-1)}_{ij} | N */
741     *R_cur_ij = GNUNET_strdup (R_last_ij);
742     return;
743   }
744
745   // $R^{(k)}_{ij} = N | R^{(k-1)}_{ik} ( R^{(k-1)}_{kk} )^* R^{(k-1)}_{kj} OR
746   // $R^{(k)}_{ij} = R^{(k-1)}_{ij} | R^{(k-1)}_{ik} ( R^{(k-1)}_{kk} )^* R^{(k-1)}_{kj}
747
748   R_cur_r = NULL;
749   R_cur_l = NULL;
750
751   // cache results from strcmp, we might need these many times
752   ij_kj_cmp = nullstrcmp (R_last_ij, R_last_kj);
753   ij_ik_cmp = nullstrcmp (R_last_ij, R_last_ik);
754   ik_kk_cmp = nullstrcmp (R_last_ik, R_last_kk);
755   kk_kj_cmp = nullstrcmp (R_last_kk, R_last_kj);
756
757   // Assign R_temp_(ik|kk|kj) to R_last[][] and remove epsilon as well
758   // as parentheses, so we can better compare the contents
759   R_temp_ik = remove_parentheses (remove_epsilon (R_last_ik));
760   R_temp_kk = remove_parentheses (remove_epsilon (R_last_kk));
761   R_temp_kj = remove_parentheses (remove_epsilon (R_last_kj));
762
763   clean_ik_kk_cmp = nullstrcmp (R_last_ik, R_temp_kk);
764   clean_kk_kj_cmp = nullstrcmp (R_temp_kk, R_last_kj);
765
766   // construct R_cur_l (and, if necessary R_cur_r)
767   if (NULL != R_last_ij)
768   {
769     // Assign R_temp_ij to R_last_ij and remove epsilon as well
770     // as parentheses, so we can better compare the contents
771     R_temp_ij = remove_parentheses (remove_epsilon (R_last_ij));
772
773     if (0 == strcmp (R_temp_ij, R_temp_ik) && 0 == strcmp (R_temp_ik, R_temp_kk)
774         && 0 == strcmp (R_temp_kk, R_temp_kj))
775     {
776       if (0 == strlen (R_temp_ij))
777       {
778         R_cur_r = GNUNET_strdup ("");
779       }
780       else if ((0 == strncmp (R_last_ij, "(|", 2)) ||
781                (0 == strncmp (R_last_ik, "(|", 2) &&
782                 0 == strncmp (R_last_kj, "(|", 2)))
783       {
784         // a|(e|a)a*(e|a) = a*
785         // a|(e|a)(e|a)*(e|a) = a*
786         // (e|a)|aa*a = a*
787         // (e|a)|aa*(e|a) = a*
788         // (e|a)|(e|a)a*a = a*
789         // (e|a)|(e|a)a*(e|a) = a*
790         // (e|a)|(e|a)(e|a)*(e|a) = a*
791         if (GNUNET_YES == needs_parentheses (R_temp_ij))
792           GNUNET_asprintf (&R_cur_r, "(%s)*", R_temp_ij);
793         else
794           GNUNET_asprintf (&R_cur_r, "%s*", R_temp_ij);
795       }
796       else
797       {
798         // a|aa*a = a+
799         // a|(e|a)a*a = a+
800         // a|aa*(e|a) = a+
801         // a|(e|a)(e|a)*a = a+
802         // a|a(e|a)*(e|a) = a+
803         if (GNUNET_YES == needs_parentheses (R_temp_ij))
804           GNUNET_asprintf (&R_cur_r, "(%s)+", R_temp_ij);
805         else
806           GNUNET_asprintf (&R_cur_r, "%s+", R_temp_ij);
807       }
808     }
809     else if (0 == ij_ik_cmp && 0 == clean_kk_kj_cmp && 0 != clean_ik_kk_cmp)
810     {
811       // a|ab*b = ab*
812       if (strlen (R_last_kk) < 1)
813         R_cur_r = GNUNET_strdup (R_last_ij);
814       else if (GNUNET_YES == needs_parentheses (R_temp_kk))
815         GNUNET_asprintf (&R_cur_r, "%s(%s)*", R_last_ij, R_temp_kk);
816       else
817         GNUNET_asprintf (&R_cur_r, "%s%s*", R_last_ij, R_last_kk);
818
819       R_cur_l = NULL;
820     }
821     else if (0 == ij_kj_cmp && 0 == clean_ik_kk_cmp && 0 != clean_kk_kj_cmp)
822     {
823       // a|bb*a = b*a
824       if (strlen (R_last_kk) < 1)
825         R_cur_r = GNUNET_strdup (R_last_kj);
826       else if (GNUNET_YES == needs_parentheses (R_temp_kk))
827         GNUNET_asprintf (&R_cur_r, "(%s)*%s", R_temp_kk, R_last_kj);
828       else
829         GNUNET_asprintf (&R_cur_r, "%s*%s", R_temp_kk, R_last_kj);
830
831       R_cur_l = NULL;
832     }
833     else if (0 == ij_ik_cmp && 0 == kk_kj_cmp && !has_epsilon (R_last_ij) &&
834              has_epsilon (R_last_kk))
835     {
836       // a|a(e|b)*(e|b) = a|ab* = a|a|ab|abb|abbb|... = ab*
837       if (needs_parentheses (R_temp_kk))
838         GNUNET_asprintf (&R_cur_r, "%s(%s)*", R_last_ij, R_temp_kk);
839       else
840         GNUNET_asprintf (&R_cur_r, "%s%s*", R_last_ij, R_temp_kk);
841
842       R_cur_l = NULL;
843     }
844     else if (0 == ij_kj_cmp && 0 == ik_kk_cmp && !has_epsilon (R_last_ij) &&
845              has_epsilon (R_last_kk))
846     {
847       // a|(e|b)(e|b)*a = a|b*a = a|a|ba|bba|bbba|...  = b*a
848       if (needs_parentheses (R_temp_kk))
849         GNUNET_asprintf (&R_cur_r, "(%s)*%s", R_temp_kk, R_last_ij);
850       else
851         GNUNET_asprintf (&R_cur_r, "%s*%s", R_temp_kk, R_last_ij);
852
853       R_cur_l = NULL;
854     }
855     else
856     {
857       temp_a = (NULL == R_last_ij) ? NULL : GNUNET_strdup (R_last_ij);
858       temp_a = remove_parentheses (temp_a);
859       R_cur_l = temp_a;
860     }
861
862     GNUNET_free_non_null (R_temp_ij);
863   }
864   else
865   {
866     // we have no left side
867     R_cur_l = NULL;
868   }
869
870   // construct R_cur_r, if not already constructed
871   if (NULL == R_cur_r)
872   {
873     length = strlen (R_temp_kk) - strlen (R_last_ik);
874
875     // a(ba)*bx = (ab)+x
876     if (length > 0 && NULL != R_last_kk && 0 < strlen (R_last_kk) &&
877         NULL != R_last_kj && 0 < strlen (R_last_kj) && NULL != R_last_ik &&
878         0 < strlen (R_last_ik) && 0 == strkcmp (R_temp_kk, R_last_ik, length) &&
879         0 == strncmp (R_temp_kk, R_last_kj, length))
880     {
881       temp_a = GNUNET_malloc (length + 1);
882       temp_b = GNUNET_malloc ((strlen (R_last_kj) - length) + 1);
883
884       length_l = 0;
885       length_r = 0;
886
887       for (cnt = 0; cnt < strlen (R_last_kj); cnt++)
888       {
889         if (cnt < length)
890         {
891           temp_a[length_l] = R_last_kj[cnt];
892           length_l++;
893         }
894         else
895         {
896           temp_b[length_r] = R_last_kj[cnt];
897           length_r++;
898         }
899       }
900       temp_a[length_l] = '\0';
901       temp_b[length_r] = '\0';
902
903       // e|(ab)+ = (ab)*
904       if (NULL != R_cur_l && 0 == strlen (R_cur_l) && 0 == strlen (temp_b))
905       {
906         GNUNET_asprintf (&R_cur_r, "(%s%s)*", R_last_ik, temp_a);
907         GNUNET_free (R_cur_l);
908         R_cur_l = NULL;
909       }
910       else
911       {
912         GNUNET_asprintf (&R_cur_r, "(%s%s)+%s", R_last_ik, temp_a, temp_b);
913       }
914       GNUNET_free (temp_a);
915       GNUNET_free (temp_b);
916     }
917     else if (0 == strcmp (R_temp_ik, R_temp_kk) &&
918              0 == strcmp (R_temp_kk, R_temp_kj))
919     {
920       // (e|a)a*(e|a) = a*
921       // (e|a)(e|a)*(e|a) = a*
922       if (has_epsilon (R_last_ik) && has_epsilon (R_last_kj))
923       {
924         if (needs_parentheses (R_temp_kk))
925           GNUNET_asprintf (&R_cur_r, "(%s)*", R_temp_kk);
926         else
927           GNUNET_asprintf (&R_cur_r, "%s*", R_temp_kk);
928       }
929       // aa*a = a+a
930       else if (0 == clean_ik_kk_cmp && 0 == clean_kk_kj_cmp &&
931                !has_epsilon (R_last_ik))
932       {
933         if (needs_parentheses (R_temp_kk))
934           GNUNET_asprintf (&R_cur_r, "(%s)+%s", R_temp_kk, R_temp_kk);
935         else
936           GNUNET_asprintf (&R_cur_r, "(%s)+%s", R_temp_kk, R_temp_kk);
937       }
938       // (e|a)a*a = a+
939       // aa*(e|a) = a+
940       // a(e|a)*(e|a) = a+
941       // (e|a)a*a = a+
942       else
943       {
944         eps_check =
945             (has_epsilon (R_last_ik) + has_epsilon (R_last_kk) +
946              has_epsilon (R_last_kj));
947
948         if (eps_check == 1)
949         {
950           if (needs_parentheses (R_temp_kk))
951             GNUNET_asprintf (&R_cur_r, "(%s)+", R_temp_kk);
952           else
953             GNUNET_asprintf (&R_cur_r, "%s+", R_temp_kk);
954         }
955       }
956     }
957     // aa*b = a+b
958     // (e|a)(e|a)*b = a*b
959     else if (0 == strcmp (R_temp_ik, R_temp_kk))
960     {
961       if (has_epsilon (R_last_ik))
962       {
963         if (needs_parentheses (R_temp_kk))
964           GNUNET_asprintf (&R_cur_r, "(%s)*%s", R_temp_kk, R_last_kj);
965         else
966           GNUNET_asprintf (&R_cur_r, "%s*%s", R_temp_kk, R_last_kj);
967       }
968       else
969       {
970         if (needs_parentheses (R_temp_kk))
971           GNUNET_asprintf (&R_cur_r, "(%s)+%s", R_temp_kk, R_last_kj);
972         else
973           GNUNET_asprintf (&R_cur_r, "%s+%s", R_temp_kk, R_last_kj);
974       }
975     }
976     // ba*a = ba+
977     // b(e|a)*(e|a) = ba*
978     else if (0 == strcmp (R_temp_kk, R_temp_kj))
979     {
980       if (has_epsilon (R_last_kj))
981       {
982         if (needs_parentheses (R_temp_kk))
983           GNUNET_asprintf (&R_cur_r, "%s(%s)*", R_last_ik, R_temp_kk);
984         else
985           GNUNET_asprintf (&R_cur_r, "%s%s*", R_last_ik, R_temp_kk);
986       }
987       else
988       {
989         if (needs_parentheses (R_temp_kk))
990           GNUNET_asprintf (&R_cur_r, "(%s)+%s", R_last_ik, R_temp_kk);
991         else
992           GNUNET_asprintf (&R_cur_r, "%s+%s", R_last_ik, R_temp_kk);
993       }
994     }
995     else
996     {
997       if (strlen (R_temp_kk) > 0)
998       {
999         if (needs_parentheses (R_temp_kk))
1000         {
1001           GNUNET_asprintf (&R_cur_r, "%s(%s)*%s", R_last_ik, R_temp_kk,
1002                            R_last_kj);
1003         }
1004         else
1005         {
1006           GNUNET_asprintf (&R_cur_r, "%s%s*%s", R_last_ik, R_temp_kk,
1007                            R_last_kj);
1008         }
1009       }
1010       else
1011       {
1012         GNUNET_asprintf (&R_cur_r, "%s%s", R_last_ik, R_last_kj);
1013       }
1014     }
1015   }
1016
1017   GNUNET_free_non_null (R_temp_ik);
1018   GNUNET_free_non_null (R_temp_kk);
1019   GNUNET_free_non_null (R_temp_kj);
1020
1021   if (NULL == R_cur_l && NULL == R_cur_r)
1022   {
1023     *R_cur_ij = NULL;
1024     return;
1025   }
1026
1027   if (NULL != R_cur_l && NULL == R_cur_r)
1028   {
1029     *R_cur_ij = R_cur_l;
1030     return;
1031   }
1032
1033   if (NULL == R_cur_l && NULL != R_cur_r)
1034   {
1035     *R_cur_ij = R_cur_r;
1036     return;
1037   }
1038
1039   if (0 == nullstrcmp (R_cur_l, R_cur_r))
1040   {
1041     *R_cur_ij = R_cur_l;
1042     GNUNET_free (R_cur_r);
1043     return;
1044   }
1045
1046   GNUNET_asprintf (R_cur_ij, "(%s|%s)", R_cur_l, R_cur_r);
1047
1048   GNUNET_free (R_cur_l);
1049   GNUNET_free (R_cur_r);
1050 }
1051
1052
1053 /**
1054  * create proofs for all states in the given automaton. Implementation of the
1055  * algorithm descriped in chapter 3.2.1 of "Automata Theory, Languages, and
1056  * Computation 3rd Edition" by Hopcroft, Motwani and Ullman.
1057  *
1058  * @param a automaton.
1059  */
1060 static void
1061 automaton_create_proofs (struct GNUNET_REGEX_Automaton *a)
1062 {
1063   if (NULL == a)
1064   {
1065     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1066                 "Could not create proofs, automaton was NULL\n");
1067     return;
1068   }
1069
1070   unsigned int n = a->state_count;
1071   struct GNUNET_REGEX_State *states[n];
1072   char *R_last[n][n];
1073   char *R_cur[n][n];
1074   char *temp;
1075   struct GNUNET_REGEX_Transition *t;
1076   char *complete_regex;
1077   unsigned int i;
1078   unsigned int j;
1079   unsigned int k;
1080
1081   /* create depth-first numbering of the states, initializes 'state' */
1082   GNUNET_REGEX_automaton_traverse (a, a->start, NULL, NULL, &number_states,
1083                                    states);
1084
1085   for (i = 0; i < n; i++)
1086     GNUNET_assert (NULL != states[i]);
1087
1088   /* Compute regular expressions of length "1" between each pair of states */
1089   for (i = 0; i < n; i++)
1090   {
1091     for (j = 0; j < n; j++)
1092     {
1093       R_cur[i][j] = NULL;
1094       R_last[i][j] = NULL;
1095     }
1096     for (t = states[i]->transitions_head; NULL != t; t = t->next)
1097     {
1098       j = t->to_state->dfs_id;
1099       if (NULL == R_last[i][j])
1100         GNUNET_asprintf (&R_last[i][j], "%s", t->label);
1101       else
1102       {
1103         temp = R_last[i][j];
1104         GNUNET_asprintf (&R_last[i][j], "%s|%s", R_last[i][j], t->label);
1105         GNUNET_free (temp);
1106       }
1107     }
1108     if (NULL == R_last[i][i])
1109       GNUNET_asprintf (&R_last[i][i], "");
1110     else
1111     {
1112       temp = R_last[i][i];
1113       GNUNET_asprintf (&R_last[i][i], "(|%s)", R_last[i][i]);
1114       GNUNET_free (temp);
1115     }
1116   }
1117   for (i = 0; i < n; i++)
1118     for (j = 0; j < n; j++)
1119       if (needs_parentheses (R_last[i][j]))
1120       {
1121         temp = R_last[i][j];
1122         GNUNET_asprintf (&R_last[i][j], "(%s)", R_last[i][j]);
1123         GNUNET_free (temp);
1124       }
1125
1126   /* Compute regular expressions of length "k" between each pair of states per
1127    * induction */
1128   for (k = 0; k < n; k++)
1129   {
1130     for (i = 0; i < n; i++)
1131     {
1132       for (j = 0; j < n; j++)
1133       {
1134         // Basis for the recursion:
1135         // $R^{(k)}_{ij} = R^{(k-1)}_{ij} | R^{(k-1)}_{ik} ( R^{(k-1)}_{kk} )^* R^{(k-1)}_{kj}
1136         // R_last == R^{(k-1)}, R_cur == R^{(k)}
1137
1138         // Create R_cur[i][j] and simplify the expression
1139         automaton_create_proofs_simplify (R_last[i][j], R_last[i][k],
1140                                           R_last[k][k], R_last[k][j],
1141                                           &R_cur[i][j]);
1142       }
1143     }
1144
1145     // set R_last = R_cur
1146     for (i = 0; i < n; i++)
1147     {
1148       for (j = 0; j < n; j++)
1149       {
1150         GNUNET_free_non_null (R_last[i][j]);
1151         R_last[i][j] = R_cur[i][j];
1152         R_cur[i][j] = NULL;
1153       }
1154     }
1155   }
1156
1157   // assign proofs and hashes
1158   for (i = 0; i < n; i++)
1159   {
1160     if (NULL != R_last[a->start->dfs_id][i])
1161     {
1162       states[i]->proof = GNUNET_strdup (R_last[a->start->dfs_id][i]);
1163       GNUNET_CRYPTO_hash (states[i]->proof, strlen (states[i]->proof),
1164                           &states[i]->hash);
1165     }
1166   }
1167
1168   // complete regex for whole DFA: union of all pairs (start state/accepting
1169   // state(s)).
1170   complete_regex = NULL;
1171   for (i = 0; i < n; i++)
1172   {
1173     if (states[i]->accepting)
1174     {
1175       if (NULL == complete_regex && 0 < strlen (R_last[a->start->dfs_id][i]))
1176       {
1177         GNUNET_asprintf (&complete_regex, "%s", R_last[a->start->dfs_id][i]);
1178       }
1179       else if (NULL != R_last[a->start->dfs_id][i] &&
1180                0 < strlen (R_last[a->start->dfs_id][i]))
1181       {
1182         temp = complete_regex;
1183         GNUNET_asprintf (&complete_regex, "%s|%s", complete_regex,
1184                          R_last[a->start->dfs_id][i]);
1185         GNUNET_free (temp);
1186       }
1187     }
1188   }
1189   a->canonical_regex = complete_regex;
1190
1191   // cleanup
1192   for (i = 0; i < n; i++)
1193   {
1194     for (j = 0; j < n; j++)
1195       GNUNET_free_non_null (R_last[i][j]);
1196   }
1197 }
1198
1199
1200 /**
1201  * Creates a new DFA state based on a set of NFA states. Needs to be freed using
1202  * automaton_destroy_state.
1203  *
1204  * @param ctx context
1205  * @param nfa_states set of NFA states on which the DFA should be based on
1206  *
1207  * @return new DFA state
1208  */
1209 static struct GNUNET_REGEX_State *
1210 dfa_state_create (struct GNUNET_REGEX_Context *ctx,
1211                   struct GNUNET_REGEX_StateSet *nfa_states)
1212 {
1213   struct GNUNET_REGEX_State *s;
1214   char *name;
1215   int len = 0;
1216   struct GNUNET_REGEX_State *cstate;
1217   struct GNUNET_REGEX_Transition *ctran;
1218   unsigned int i;
1219
1220   s = GNUNET_malloc (sizeof (struct GNUNET_REGEX_State));
1221   s->id = ctx->state_id++;
1222   s->accepting = 0;
1223   s->marked = GNUNET_NO;
1224   s->name = NULL;
1225   s->scc_id = 0;
1226   s->index = -1;
1227   s->lowlink = -1;
1228   s->contained = 0;
1229   s->proof = NULL;
1230
1231   if (NULL == nfa_states)
1232   {
1233     GNUNET_asprintf (&s->name, "s%i", s->id);
1234     return s;
1235   }
1236
1237   s->nfa_set = nfa_states;
1238
1239   if (nfa_states->len < 1)
1240     return s;
1241
1242   // Create a name based on 'nfa_states'
1243   s->name = GNUNET_malloc (sizeof (char) * 2);
1244   strcat (s->name, "{");
1245   name = NULL;
1246
1247   for (i = 0; i < nfa_states->len; i++)
1248   {
1249     cstate = nfa_states->states[i];
1250     GNUNET_asprintf (&name, "%i,", cstate->id);
1251
1252     if (NULL != name)
1253     {
1254       len = strlen (s->name) + strlen (name) + 1;
1255       s->name = GNUNET_realloc (s->name, len);
1256       strcat (s->name, name);
1257       GNUNET_free (name);
1258       name = NULL;
1259     }
1260
1261     // Add a transition for each distinct label to NULL state
1262     for (ctran = cstate->transitions_head; NULL != ctran; ctran = ctran->next)
1263     {
1264       if (NULL != ctran->label)
1265         state_add_transition (ctx, s, ctran->label, NULL);
1266     }
1267
1268     // If the nfa_states contain an accepting state, the new dfa state is also
1269     // accepting
1270     if (cstate->accepting)
1271       s->accepting = 1;
1272   }
1273
1274   s->name[strlen (s->name) - 1] = '}';
1275
1276   return s;
1277 }
1278
1279
1280 /**
1281  * Move from the given state 's' to the next state on transition 'str'. Consumes
1282  * as much of the given 'str' as possible (usefull for strided DFAs). On return
1283  * 's' will point to the next state, and the length of the substring used for
1284  * this transition will be returned. If no transition possible 0 is returned and
1285  * 's' points to NULL.
1286  *
1287  * @param s starting state, will point to the next state or NULL (if no
1288  * transition possible)
1289  * @param str edge label to follow (will match longest common prefix)
1290  *
1291  * @return length of the substring comsumed from 'str'
1292  */
1293 static unsigned int
1294 dfa_move (struct GNUNET_REGEX_State **s, const char *str)
1295 {
1296   struct GNUNET_REGEX_Transition *t;
1297   struct GNUNET_REGEX_State *new_s;
1298   unsigned int len;
1299   unsigned int max_len;
1300
1301   if (NULL == s)
1302     return 0;
1303
1304   new_s = NULL;
1305   max_len = 0;
1306   for (t = (*s)->transitions_head; NULL != t; t = t->next)
1307   {
1308     len = strlen (t->label);
1309
1310     if (0 == strncmp (t->label, str, len))
1311     {
1312       if (len >= max_len)
1313       {
1314         max_len = len;
1315         new_s = t->to_state;
1316       }
1317     }
1318   }
1319
1320   *s = new_s;
1321   return max_len;
1322 }
1323
1324 /**
1325  * Set the given state 'marked' to GNUNET_YES. Used by the
1326  * 'dfa_remove_unreachable_states' function to detect unreachable states in the
1327  * automaton.
1328  *
1329  * @param cls closure, not used.
1330  * @param count count, not used.
1331  * @param s state where the marked attribute will be set to GNUNET_YES.
1332  */
1333 void
1334 mark_states (void *cls, const unsigned int count, struct GNUNET_REGEX_State *s)
1335 {
1336   s->marked = GNUNET_YES;
1337 }
1338
1339 /**
1340  * Remove all unreachable states from DFA 'a'. Unreachable states are those
1341  * states that are not reachable from the starting state.
1342  *
1343  * @param a DFA automaton
1344  */
1345 static void
1346 dfa_remove_unreachable_states (struct GNUNET_REGEX_Automaton *a)
1347 {
1348   struct GNUNET_REGEX_State *s;
1349   struct GNUNET_REGEX_State *s_next;
1350
1351   // 1. unmark all states
1352   for (s = a->states_head; NULL != s; s = s->next)
1353     s->marked = GNUNET_NO;
1354
1355   // 2. traverse dfa from start state and mark all visited states
1356   GNUNET_REGEX_automaton_traverse (a, a->start, NULL, NULL, &mark_states, NULL);
1357
1358   // 3. delete all states that were not visited
1359   for (s = a->states_head; NULL != s; s = s_next)
1360   {
1361     s_next = s->next;
1362     if (GNUNET_NO == s->marked)
1363       automaton_remove_state (a, s);
1364   }
1365 }
1366
1367
1368 /**
1369  * Remove all dead states from the DFA 'a'. Dead states are those states that do
1370  * not transition to any other state but themselves.
1371  *
1372  * @param a DFA automaton
1373  */
1374 static void
1375 dfa_remove_dead_states (struct GNUNET_REGEX_Automaton *a)
1376 {
1377   struct GNUNET_REGEX_State *s;
1378   struct GNUNET_REGEX_Transition *t;
1379   int dead;
1380
1381   GNUNET_assert (DFA == a->type);
1382
1383   for (s = a->states_head; NULL != s; s = s->next)
1384   {
1385     if (s->accepting)
1386       continue;
1387
1388     dead = 1;
1389     for (t = s->transitions_head; NULL != t; t = t->next)
1390     {
1391       if (NULL != t->to_state && t->to_state != s)
1392       {
1393         dead = 0;
1394         break;
1395       }
1396     }
1397
1398     if (0 == dead)
1399       continue;
1400
1401     // state s is dead, remove it
1402     automaton_remove_state (a, s);
1403   }
1404 }
1405
1406
1407 /**
1408  * Merge all non distinguishable states in the DFA 'a'
1409  *
1410  * @param ctx context
1411  * @param a DFA automaton
1412  */
1413 static void
1414 dfa_merge_nondistinguishable_states (struct GNUNET_REGEX_Context *ctx,
1415                                      struct GNUNET_REGEX_Automaton *a)
1416 {
1417   int table[a->state_count][a->state_count];
1418   struct GNUNET_REGEX_State *s1;
1419   struct GNUNET_REGEX_State *s2;
1420   struct GNUNET_REGEX_Transition *t1;
1421   struct GNUNET_REGEX_Transition *t2;
1422   struct GNUNET_REGEX_State *s1_next;
1423   struct GNUNET_REGEX_State *s2_next;
1424   int change;
1425   unsigned int num_equal_edges;
1426   unsigned int i;
1427
1428   for (i = 0, s1 = a->states_head; i < a->state_count && NULL != s1;
1429        i++, s1 = s1->next)
1430   {
1431     s1->marked = i;
1432   }
1433
1434   // Mark all pairs of accepting/!accepting states
1435   for (s1 = a->states_head; NULL != s1; s1 = s1->next)
1436   {
1437     for (s2 = a->states_head; NULL != s2; s2 = s2->next)
1438     {
1439       table[s1->marked][s2->marked] = 0;
1440
1441       if ((s1->accepting && !s2->accepting) ||
1442           (!s1->accepting && s2->accepting))
1443       {
1444         table[s1->marked][s2->marked] = 1;
1445       }
1446     }
1447   }
1448
1449   // Find all equal states
1450   change = 1;
1451   while (0 != change)
1452   {
1453     change = 0;
1454     for (s1 = a->states_head; NULL != s1; s1 = s1->next)
1455     {
1456       for (s2 = a->states_head; NULL != s2 && s1 != s2; s2 = s2->next)
1457       {
1458         if (0 != table[s1->marked][s2->marked])
1459           continue;
1460
1461         num_equal_edges = 0;
1462         for (t1 = s1->transitions_head; NULL != t1; t1 = t1->next)
1463         {
1464           for (t2 = s2->transitions_head; NULL != t2; t2 = t2->next)
1465           {
1466             if (0 == strcmp (t1->label, t2->label))
1467             {
1468               num_equal_edges++;
1469               if (0 != table[t1->to_state->marked][t2->to_state->marked] ||
1470                   0 != table[t2->to_state->marked][t1->to_state->marked])
1471               {
1472                 table[s1->marked][s2->marked] = 1;
1473                 change = 1;
1474               }
1475             }
1476           }
1477         }
1478         if (num_equal_edges != s1->transition_count ||
1479             num_equal_edges != s2->transition_count)
1480         {
1481           // Make sure ALL edges of possible equal states are the same
1482           table[s1->marked][s2->marked] = -2;
1483         }
1484       }
1485     }
1486   }
1487
1488   // Merge states that are equal
1489   for (s1 = a->states_head; NULL != s1; s1 = s1_next)
1490   {
1491     s1_next = s1->next;
1492     for (s2 = a->states_head; NULL != s2 && s1 != s2; s2 = s2_next)
1493     {
1494       s2_next = s2->next;
1495       if (table[s1->marked][s2->marked] == 0)
1496         automaton_merge_states (ctx, a, s1, s2);
1497     }
1498   }
1499 }
1500
1501
1502 /**
1503  * Minimize the given DFA 'a' by removing all unreachable states, removing all
1504  * dead states and merging all non distinguishable states
1505  *
1506  * @param ctx context
1507  * @param a DFA automaton
1508  */
1509 static void
1510 dfa_minimize (struct GNUNET_REGEX_Context *ctx,
1511               struct GNUNET_REGEX_Automaton *a)
1512 {
1513   if (NULL == a)
1514     return;
1515
1516   GNUNET_assert (DFA == a->type);
1517
1518   // 1. remove unreachable states
1519   dfa_remove_unreachable_states (a);
1520
1521   // 2. remove dead states
1522   dfa_remove_dead_states (a);
1523
1524   // 3. Merge nondistinguishable states
1525   dfa_merge_nondistinguishable_states (ctx, a);
1526 }
1527
1528
1529 /**
1530  * Context for adding strided transitions to a DFA.
1531  */
1532 struct GNUNET_REGEX_Strided_Context
1533 {
1534   /**
1535    * Length of the strides.
1536    */
1537   const unsigned int stride;
1538
1539   /**
1540    * Strided transitions DLL. New strided transitions will be stored in this DLL
1541    * and afterwards added to the DFA.
1542    */
1543   struct GNUNET_REGEX_Transition *transitions_head;
1544
1545   /**
1546    * Strided transitions DLL.
1547    */
1548   struct GNUNET_REGEX_Transition *transitions_tail;
1549 };
1550
1551
1552 /**
1553  * Recursive helper function to add strides to a DFA.
1554  *
1555  * @param cls context, contains stride length and strided transitions DLL.
1556  * @param depth current depth of the depth-first traversal of the graph.
1557  * @param label current label, string that contains all labels on the path from
1558  *        'start' to 's'.
1559  * @param start start state for the depth-first traversal of the graph.
1560  * @param s current state in the depth-first traversal
1561  */
1562 void
1563 dfa_add_multi_strides_helper (void *cls, const unsigned int depth, char *label,
1564                               struct GNUNET_REGEX_State *start,
1565                               struct GNUNET_REGEX_State *s)
1566 {
1567   struct GNUNET_REGEX_Strided_Context *ctx = cls;
1568   struct GNUNET_REGEX_Transition *t;
1569   char *new_label;
1570
1571   if (depth == ctx->stride)
1572   {
1573     t = GNUNET_malloc (sizeof (struct GNUNET_REGEX_Transition));
1574     t->label = GNUNET_strdup (label);
1575     t->to_state = s;
1576     t->from_state = start;
1577     GNUNET_CONTAINER_DLL_insert (ctx->transitions_head, ctx->transitions_tail,
1578                                  t);
1579   }
1580   else
1581   {
1582     for (t = s->transitions_head; NULL != t; t = t->next)
1583     {
1584       /* Do not consider self-loops, because it end's up in too many
1585        * transitions */
1586       if (t->to_state == t->from_state)
1587         continue;
1588
1589       if (NULL != label)
1590       {
1591         GNUNET_asprintf (&new_label, "%s%s", label, t->label);
1592       }
1593       else
1594         new_label = GNUNET_strdup (t->label);
1595
1596       dfa_add_multi_strides_helper (cls, (depth + 1), new_label, start,
1597                                     t->to_state);
1598     }
1599   }
1600   GNUNET_free_non_null (label);
1601 }
1602
1603
1604 /**
1605  * Function called for each state in the DFA. Starts a traversal of depth set in
1606  * context starting from state 's'.
1607  *
1608  * @param cls context.
1609  * @param count not used.
1610  * @param s current state.
1611  */
1612 void
1613 dfa_add_multi_strides (void *cls, const unsigned int count,
1614                        struct GNUNET_REGEX_State *s)
1615 {
1616   dfa_add_multi_strides_helper (cls, 0, NULL, s, s);
1617 }
1618
1619
1620 /**
1621  * Adds multi-strided transitions to the given 'dfa'.
1622  *
1623  * @param regex_ctx regex context needed to add transitions to the automaton.
1624  * @param dfa DFA to which the multi strided transitions should be added.
1625  * @param stride_len length of the strides.
1626  */
1627 void
1628 GNUNET_REGEX_dfa_add_multi_strides (struct GNUNET_REGEX_Context *regex_ctx,
1629                                     struct GNUNET_REGEX_Automaton *dfa,
1630                                     const unsigned int stride_len)
1631 {
1632   struct GNUNET_REGEX_Strided_Context ctx = { stride_len, NULL, NULL };
1633   struct GNUNET_REGEX_Transition *t;
1634   struct GNUNET_REGEX_Transition *t_next;
1635
1636   if (1 > stride_len || GNUNET_YES == dfa->is_multistrided)
1637     return;
1638
1639   // Compute the new transitions of given stride_len
1640   GNUNET_REGEX_automaton_traverse (dfa, dfa->start, NULL, NULL,
1641                                    &dfa_add_multi_strides, &ctx);
1642
1643   // Add all the new transitions to the automaton.
1644   for (t = ctx.transitions_head; NULL != t; t = t_next)
1645   {
1646     t_next = t->next;
1647     state_add_transition (regex_ctx, t->from_state, t->label, t->to_state);
1648     GNUNET_CONTAINER_DLL_remove (ctx.transitions_head, ctx.transitions_tail, t);
1649     GNUNET_free_non_null (t->label);
1650     GNUNET_free (t);
1651   }
1652
1653   // Mark this automaton as multistrided
1654   dfa->is_multistrided = GNUNET_YES;
1655 }
1656
1657 /**
1658  * Recursive Helper function for DFA path compression. Does DFS on the DFA graph
1659  * and adds new transitions to the given transitions DLL and marks states that
1660  * should be removed by setting state->contained to GNUNET_YES.
1661  *
1662  * @param dfa DFA for which the paths should be compressed.
1663  * @param start starting state for linear path search.
1664  * @param cur current state in the recursive DFS.
1665  * @param label current label (string of traversed labels).
1666  * @param max_len maximal path compression length.
1667  * @param transitions_head transitions DLL.
1668  * @param transitions_tail transitions DLL.
1669  */
1670 void
1671 dfa_compress_paths_helper (struct GNUNET_REGEX_Automaton *dfa,
1672                            struct GNUNET_REGEX_State *start,
1673                            struct GNUNET_REGEX_State *cur, char *label,
1674                            unsigned int max_len,
1675                            struct GNUNET_REGEX_Transition **transitions_head,
1676                            struct GNUNET_REGEX_Transition **transitions_tail)
1677 {
1678   struct GNUNET_REGEX_Transition *t;
1679   char *new_label;
1680
1681
1682   if (NULL != label &&
1683       ((cur->incoming_transition_count > 1 || GNUNET_YES == cur->accepting
1684 //        || cur->transition_count > 1
1685         || GNUNET_YES == cur->marked) || (start != dfa->start && max_len > 0 &&
1686                                           max_len == strlen (label)) ||
1687        (start == dfa->start && GNUNET_REGEX_INITIAL_BITS == strlen (label))))
1688   {
1689     t = GNUNET_malloc (sizeof (struct GNUNET_REGEX_Transition));
1690     t->label = GNUNET_strdup (label);
1691     t->to_state = cur;
1692     t->from_state = start;
1693     GNUNET_CONTAINER_DLL_insert (*transitions_head, *transitions_tail, t);
1694
1695     if (GNUNET_NO == cur->marked)
1696     {
1697       dfa_compress_paths_helper (dfa, cur, cur, NULL, max_len, transitions_head,
1698                                  transitions_tail);
1699     }
1700     return;
1701   }
1702   else if (cur != start)
1703     cur->contained = GNUNET_YES;
1704
1705   if (GNUNET_YES == cur->marked && cur != start)
1706     return;
1707
1708   cur->marked = GNUNET_YES;
1709
1710
1711   for (t = cur->transitions_head; NULL != t; t = t->next)
1712   {
1713     if (NULL != label)
1714       GNUNET_asprintf (&new_label, "%s%s", label, t->label);
1715     else
1716       new_label = GNUNET_strdup (t->label);
1717
1718     if (t->to_state != cur)
1719     {
1720       dfa_compress_paths_helper (dfa, start, t->to_state, new_label, max_len,
1721                                  transitions_head, transitions_tail);
1722     }
1723     GNUNET_free (new_label);
1724   }
1725 }
1726
1727 /**
1728  * Compress paths in the given 'dfa'. Linear paths like 0->1->2->3 will be
1729  * compressed to 0->3 by combining transitions.
1730  *
1731  * @param regex_ctx context for adding new transitions.
1732  * @param dfa DFA representation, will directly modify the given DFA.
1733  * @param max_len maximal length of the compressed paths.
1734  */
1735 static void
1736 dfa_compress_paths (struct GNUNET_REGEX_Context *regex_ctx,
1737                     struct GNUNET_REGEX_Automaton *dfa, unsigned int max_len)
1738 {
1739   struct GNUNET_REGEX_State *s;
1740   struct GNUNET_REGEX_State *s_next;
1741   struct GNUNET_REGEX_Transition *t;
1742   struct GNUNET_REGEX_Transition *t_next;
1743   struct GNUNET_REGEX_Transition *transitions_head = NULL;
1744   struct GNUNET_REGEX_Transition *transitions_tail = NULL;
1745
1746   if (NULL == dfa)
1747     return;
1748
1749   // Count the incoming transitions on each state.
1750   for (s = dfa->states_head; NULL != s; s = s->next)
1751   {
1752     for (t = s->transitions_head; NULL != t; t = t->next)
1753     {
1754       if (NULL != t->to_state)
1755         t->to_state->incoming_transition_count++;
1756     }
1757   }
1758
1759   // Unmark all states.
1760   for (s = dfa->states_head; NULL != s; s = s->next)
1761   {
1762     s->marked = GNUNET_NO;
1763     s->contained = GNUNET_NO;
1764   }
1765
1766   // Add strides and mark states that can be deleted.
1767   dfa_compress_paths_helper (dfa, dfa->start, dfa->start, NULL, max_len,
1768                              &transitions_head, &transitions_tail);
1769
1770   // Add all the new transitions to the automaton.
1771   for (t = transitions_head; NULL != t; t = t_next)
1772   {
1773     t_next = t->next;
1774     state_add_transition (regex_ctx, t->from_state, t->label, t->to_state);
1775     GNUNET_CONTAINER_DLL_remove (transitions_head, transitions_tail, t);
1776     GNUNET_free_non_null (t->label);
1777     GNUNET_free (t);
1778   }
1779
1780   // Remove marked states (including their incoming and outgoing transitions).
1781   for (s = dfa->states_head; NULL != s; s = s_next)
1782   {
1783     s_next = s->next;
1784     if (GNUNET_YES == s->contained)
1785       automaton_remove_state (dfa, s);
1786   }
1787 }
1788
1789
1790 /**
1791  * Creates a new NFA fragment. Needs to be cleared using
1792  * automaton_fragment_clear.
1793  *
1794  * @param start starting state
1795  * @param end end state
1796  *
1797  * @return new NFA fragment
1798  */
1799 static struct GNUNET_REGEX_Automaton *
1800 nfa_fragment_create (struct GNUNET_REGEX_State *start,
1801                      struct GNUNET_REGEX_State *end)
1802 {
1803   struct GNUNET_REGEX_Automaton *n;
1804
1805   n = GNUNET_malloc (sizeof (struct GNUNET_REGEX_Automaton));
1806
1807   n->type = NFA;
1808   n->start = NULL;
1809   n->end = NULL;
1810   n->state_count = 0;
1811
1812   if (NULL == start || NULL == end)
1813     return n;
1814
1815   automaton_add_state (n, end);
1816   automaton_add_state (n, start);
1817
1818   n->state_count = 2;
1819
1820   n->start = start;
1821   n->end = end;
1822
1823   return n;
1824 }
1825
1826
1827 /**
1828  * Adds a list of states to the given automaton 'n'.
1829  *
1830  * @param n automaton to which the states should be added
1831  * @param states_head head of the DLL of states
1832  * @param states_tail tail of the DLL of states
1833  */
1834 static void
1835 nfa_add_states (struct GNUNET_REGEX_Automaton *n,
1836                 struct GNUNET_REGEX_State *states_head,
1837                 struct GNUNET_REGEX_State *states_tail)
1838 {
1839   struct GNUNET_REGEX_State *s;
1840
1841   if (NULL == n || NULL == states_head)
1842   {
1843     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not add states\n");
1844     return;
1845   }
1846
1847   if (NULL == n->states_head)
1848   {
1849     n->states_head = states_head;
1850     n->states_tail = states_tail;
1851     return;
1852   }
1853
1854   if (NULL != states_head)
1855   {
1856     n->states_tail->next = states_head;
1857     n->states_tail = states_tail;
1858   }
1859
1860   for (s = states_head; NULL != s; s = s->next)
1861     n->state_count++;
1862 }
1863
1864
1865 /**
1866  * Creates a new NFA state. Needs to be freed using automaton_destroy_state.
1867  *
1868  * @param ctx context
1869  * @param accepting is it an accepting state or not
1870  *
1871  * @return new NFA state
1872  */
1873 static struct GNUNET_REGEX_State *
1874 nfa_state_create (struct GNUNET_REGEX_Context *ctx, int accepting)
1875 {
1876   struct GNUNET_REGEX_State *s;
1877
1878   s = GNUNET_malloc (sizeof (struct GNUNET_REGEX_State));
1879   s->id = ctx->state_id++;
1880   s->accepting = accepting;
1881   s->marked = GNUNET_NO;
1882   s->contained = 0;
1883   s->index = -1;
1884   s->lowlink = -1;
1885   s->scc_id = 0;
1886   s->name = NULL;
1887   GNUNET_asprintf (&s->name, "s%i", s->id);
1888
1889   return s;
1890 }
1891
1892
1893 /**
1894  * Calculates the NFA closure set for the given state.
1895  *
1896  * @param nfa the NFA containing 's'
1897  * @param s starting point state
1898  * @param label transitioning label on which to base the closure on,
1899  *                pass NULL for epsilon transition
1900  *
1901  * @return sorted nfa closure on 'label' (epsilon closure if 'label' is NULL)
1902  */
1903 static struct GNUNET_REGEX_StateSet *
1904 nfa_closure_create (struct GNUNET_REGEX_Automaton *nfa,
1905                     struct GNUNET_REGEX_State *s, const char *label)
1906 {
1907   struct GNUNET_REGEX_StateSet *cls;
1908   struct GNUNET_REGEX_StateSet *cls_check;
1909   struct GNUNET_REGEX_State *clsstate;
1910   struct GNUNET_REGEX_State *currentstate;
1911   struct GNUNET_REGEX_Transition *ctran;
1912
1913   if (NULL == s)
1914     return NULL;
1915
1916   cls = GNUNET_malloc (sizeof (struct GNUNET_REGEX_StateSet));
1917   cls_check = GNUNET_malloc (sizeof (struct GNUNET_REGEX_StateSet));
1918
1919   for (clsstate = nfa->states_head; NULL != clsstate; clsstate = clsstate->next)
1920     clsstate->contained = 0;
1921
1922   // Add start state to closure only for epsilon closure
1923   if (NULL == label)
1924     GNUNET_array_append (cls->states, cls->len, s);
1925
1926   GNUNET_array_append (cls_check->states, cls_check->len, s);
1927   while (cls_check->len > 0)
1928   {
1929     currentstate = cls_check->states[cls_check->len - 1];
1930     GNUNET_array_grow (cls_check->states, cls_check->len, cls_check->len - 1);
1931
1932     for (ctran = currentstate->transitions_head; NULL != ctran;
1933          ctran = ctran->next)
1934     {
1935       if (NULL != ctran->to_state && 0 == nullstrcmp (label, ctran->label))
1936       {
1937         clsstate = ctran->to_state;
1938
1939         if (NULL != clsstate && 0 == clsstate->contained)
1940         {
1941           GNUNET_array_append (cls->states, cls->len, clsstate);
1942           GNUNET_array_append (cls_check->states, cls_check->len, clsstate);
1943           clsstate->contained = 1;
1944         }
1945       }
1946     }
1947   }
1948   GNUNET_assert (0 == cls_check->len);
1949   GNUNET_free (cls_check);
1950
1951   // sort the states
1952   if (cls->len > 1)
1953     qsort (cls->states, cls->len, sizeof (struct GNUNET_REGEX_State *),
1954            state_compare);
1955
1956   return cls;
1957 }
1958
1959
1960 /**
1961  * Calculates the closure set for the given set of states.
1962  *
1963  * @param nfa the NFA containing 's'
1964  * @param states list of states on which to base the closure on
1965  * @param label transitioning label for which to base the closure on,
1966  *                pass NULL for epsilon transition
1967  *
1968  * @return sorted nfa closure on 'label' (epsilon closure if 'label' is NULL)
1969  */
1970 static struct GNUNET_REGEX_StateSet *
1971 nfa_closure_set_create (struct GNUNET_REGEX_Automaton *nfa,
1972                         struct GNUNET_REGEX_StateSet *states, const char *label)
1973 {
1974   struct GNUNET_REGEX_State *s;
1975   struct GNUNET_REGEX_StateSet *sset;
1976   struct GNUNET_REGEX_StateSet *cls;
1977   unsigned int i;
1978   unsigned int j;
1979   unsigned int k;
1980   unsigned int contains;
1981
1982   if (NULL == states)
1983     return NULL;
1984
1985   cls = GNUNET_malloc (sizeof (struct GNUNET_REGEX_StateSet));
1986
1987   for (i = 0; i < states->len; i++)
1988   {
1989     s = states->states[i];
1990     sset = nfa_closure_create (nfa, s, label);
1991
1992     for (j = 0; j < sset->len; j++)
1993     {
1994       contains = 0;
1995       for (k = 0; k < cls->len; k++)
1996       {
1997         if (sset->states[j]->id == cls->states[k]->id)
1998         {
1999           contains = 1;
2000           break;
2001         }
2002       }
2003       if (!contains)
2004         GNUNET_array_append (cls->states, cls->len, sset->states[j]);
2005     }
2006     state_set_clear (sset);
2007   }
2008
2009   if (cls->len > 1)
2010     qsort (cls->states, cls->len, sizeof (struct GNUNET_REGEX_State *),
2011            state_compare);
2012
2013   return cls;
2014 }
2015
2016
2017 /**
2018  * Pops two NFA fragments (a, b) from the stack and concatenates them (ab)
2019  *
2020  * @param ctx context
2021  */
2022 static void
2023 nfa_add_concatenation (struct GNUNET_REGEX_Context *ctx)
2024 {
2025   struct GNUNET_REGEX_Automaton *a;
2026   struct GNUNET_REGEX_Automaton *b;
2027   struct GNUNET_REGEX_Automaton *new_nfa;
2028
2029   b = ctx->stack_tail;
2030   GNUNET_assert (NULL != b);
2031   GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, b);
2032   a = ctx->stack_tail;
2033   GNUNET_assert (NULL != a);
2034   GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, a);
2035
2036   state_add_transition (ctx, a->end, NULL, b->start);
2037   a->end->accepting = 0;
2038   b->end->accepting = 1;
2039
2040   new_nfa = nfa_fragment_create (NULL, NULL);
2041   nfa_add_states (new_nfa, a->states_head, a->states_tail);
2042   nfa_add_states (new_nfa, b->states_head, b->states_tail);
2043   new_nfa->start = a->start;
2044   new_nfa->end = b->end;
2045   new_nfa->state_count += a->state_count + b->state_count;
2046   automaton_fragment_clear (a);
2047   automaton_fragment_clear (b);
2048
2049   GNUNET_CONTAINER_DLL_insert_tail (ctx->stack_head, ctx->stack_tail, new_nfa);
2050 }
2051
2052
2053 /**
2054  * Pops a NFA fragment from the stack (a) and adds a new fragment (a*)
2055  *
2056  * @param ctx context
2057  */
2058 static void
2059 nfa_add_star_op (struct GNUNET_REGEX_Context *ctx)
2060 {
2061   struct GNUNET_REGEX_Automaton *a;
2062   struct GNUNET_REGEX_Automaton *new_nfa;
2063   struct GNUNET_REGEX_State *start;
2064   struct GNUNET_REGEX_State *end;
2065
2066   a = ctx->stack_tail;
2067
2068   if (NULL == a)
2069   {
2070     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2071                 "nfa_add_star_op failed, because there was no element on the stack");
2072     return;
2073   }
2074
2075   GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, a);
2076
2077   start = nfa_state_create (ctx, 0);
2078   end = nfa_state_create (ctx, 1);
2079
2080   state_add_transition (ctx, start, NULL, a->start);
2081   state_add_transition (ctx, start, NULL, end);
2082   state_add_transition (ctx, a->end, NULL, a->start);
2083   state_add_transition (ctx, a->end, NULL, end);
2084
2085   a->end->accepting = 0;
2086   end->accepting = 1;
2087
2088   new_nfa = nfa_fragment_create (start, end);
2089   nfa_add_states (new_nfa, a->states_head, a->states_tail);
2090   automaton_fragment_clear (a);
2091
2092   GNUNET_CONTAINER_DLL_insert_tail (ctx->stack_head, ctx->stack_tail, new_nfa);
2093 }
2094
2095
2096 /**
2097  * Pops an NFA fragment (a) from the stack and adds a new fragment (a+)
2098  *
2099  * @param ctx context
2100  */
2101 static void
2102 nfa_add_plus_op (struct GNUNET_REGEX_Context *ctx)
2103 {
2104   struct GNUNET_REGEX_Automaton *a;
2105
2106   a = ctx->stack_tail;
2107
2108   if (NULL == a)
2109   {
2110     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2111                 "nfa_add_plus_op failed, because there was no element on the stack");
2112     return;
2113   }
2114
2115   GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, a);
2116
2117   state_add_transition (ctx, a->end, NULL, a->start);
2118
2119   GNUNET_CONTAINER_DLL_insert_tail (ctx->stack_head, ctx->stack_tail, a);
2120 }
2121
2122
2123 /**
2124  * Pops an NFA fragment (a) from the stack and adds a new fragment (a?)
2125  *
2126  * @param ctx context
2127  */
2128 static void
2129 nfa_add_question_op (struct GNUNET_REGEX_Context *ctx)
2130 {
2131   struct GNUNET_REGEX_Automaton *a;
2132   struct GNUNET_REGEX_Automaton *new_nfa;
2133   struct GNUNET_REGEX_State *start;
2134   struct GNUNET_REGEX_State *end;
2135
2136   a = ctx->stack_tail;
2137
2138   if (NULL == a)
2139   {
2140     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2141                 "nfa_add_question_op failed, because there was no element on the stack");
2142     return;
2143   }
2144
2145   GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, a);
2146
2147   start = nfa_state_create (ctx, 0);
2148   end = nfa_state_create (ctx, 1);
2149
2150   state_add_transition (ctx, start, NULL, a->start);
2151   state_add_transition (ctx, start, NULL, end);
2152   state_add_transition (ctx, a->end, NULL, end);
2153
2154   a->end->accepting = 0;
2155
2156   new_nfa = nfa_fragment_create (start, end);
2157   nfa_add_states (new_nfa, a->states_head, a->states_tail);
2158   automaton_fragment_clear (a);
2159
2160   GNUNET_CONTAINER_DLL_insert_tail (ctx->stack_head, ctx->stack_tail, new_nfa);
2161 }
2162
2163
2164 /**
2165  * Pops two NFA fragments (a, b) from the stack and adds a new NFA fragment that
2166  * alternates between a and b (a|b)
2167  *
2168  * @param ctx context
2169  */
2170 static void
2171 nfa_add_alternation (struct GNUNET_REGEX_Context *ctx)
2172 {
2173   struct GNUNET_REGEX_Automaton *a;
2174   struct GNUNET_REGEX_Automaton *b;
2175   struct GNUNET_REGEX_Automaton *new_nfa;
2176   struct GNUNET_REGEX_State *start;
2177   struct GNUNET_REGEX_State *end;
2178
2179   b = ctx->stack_tail;
2180   GNUNET_assert (NULL != b);
2181   GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, b);
2182   a = ctx->stack_tail;
2183   GNUNET_assert (NULL != a);
2184   GNUNET_CONTAINER_DLL_remove (ctx->stack_head, ctx->stack_tail, a);
2185
2186   start = nfa_state_create (ctx, 0);
2187   end = nfa_state_create (ctx, 1);
2188   state_add_transition (ctx, start, NULL, a->start);
2189   state_add_transition (ctx, start, NULL, b->start);
2190
2191   state_add_transition (ctx, a->end, NULL, end);
2192   state_add_transition (ctx, b->end, NULL, end);
2193
2194   a->end->accepting = 0;
2195   b->end->accepting = 0;
2196   end->accepting = 1;
2197
2198   new_nfa = nfa_fragment_create (start, end);
2199   nfa_add_states (new_nfa, a->states_head, a->states_tail);
2200   nfa_add_states (new_nfa, b->states_head, b->states_tail);
2201   automaton_fragment_clear (a);
2202   automaton_fragment_clear (b);
2203
2204   GNUNET_CONTAINER_DLL_insert_tail (ctx->stack_head, ctx->stack_tail, new_nfa);
2205 }
2206
2207
2208 /**
2209  * Adds a new nfa fragment to the stack
2210  *
2211  * @param ctx context
2212  * @param label label for nfa transition
2213  */
2214 static void
2215 nfa_add_label (struct GNUNET_REGEX_Context *ctx, const char *label)
2216 {
2217   struct GNUNET_REGEX_Automaton *n;
2218   struct GNUNET_REGEX_State *start;
2219   struct GNUNET_REGEX_State *end;
2220
2221   GNUNET_assert (NULL != ctx);
2222
2223   start = nfa_state_create (ctx, 0);
2224   end = nfa_state_create (ctx, 1);
2225   state_add_transition (ctx, start, label, end);
2226   n = nfa_fragment_create (start, end);
2227   GNUNET_assert (NULL != n);
2228   GNUNET_CONTAINER_DLL_insert_tail (ctx->stack_head, ctx->stack_tail, n);
2229 }
2230
2231
2232 /**
2233  * Initialize a new context
2234  *
2235  * @param ctx context
2236  */
2237 static void
2238 GNUNET_REGEX_context_init (struct GNUNET_REGEX_Context *ctx)
2239 {
2240   if (NULL == ctx)
2241   {
2242     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Context was NULL!");
2243     return;
2244   }
2245   ctx->state_id = 0;
2246   ctx->transition_id = 0;
2247   ctx->stack_head = NULL;
2248   ctx->stack_tail = NULL;
2249 }
2250
2251
2252 /**
2253  * Construct an NFA by parsing the regex string of length 'len'.
2254  *
2255  * @param regex regular expression string
2256  * @param len length of the string
2257  *
2258  * @return NFA, needs to be freed using GNUNET_REGEX_destroy_automaton
2259  */
2260 struct GNUNET_REGEX_Automaton *
2261 GNUNET_REGEX_construct_nfa (const char *regex, const size_t len)
2262 {
2263   struct GNUNET_REGEX_Context ctx;
2264   struct GNUNET_REGEX_Automaton *nfa;
2265   const char *regexp;
2266   char curlabel[2];
2267   char *error_msg;
2268   unsigned int count;
2269   unsigned int altcount;
2270   unsigned int atomcount;
2271   unsigned int pcount;
2272   struct
2273   {
2274     int altcount;
2275     int atomcount;
2276   }     *p;
2277
2278   if (NULL == regex || 0 == strlen (regex) || 0 == len)
2279   {
2280     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2281                 "Could not parse regex. Empty regex string provided.\n");
2282
2283     return NULL;
2284   }
2285
2286   GNUNET_REGEX_context_init (&ctx);
2287
2288   regexp = regex;
2289   curlabel[1] = '\0';
2290   p = NULL;
2291   error_msg = NULL;
2292   altcount = 0;
2293   atomcount = 0;
2294   pcount = 0;
2295
2296   for (count = 0; count < len && *regexp; count++, regexp++)
2297   {
2298     switch (*regexp)
2299     {
2300     case '(':
2301       if (atomcount > 1)
2302       {
2303         --atomcount;
2304         nfa_add_concatenation (&ctx);
2305       }
2306       GNUNET_array_grow (p, pcount, pcount + 1);
2307       p[pcount - 1].altcount = altcount;
2308       p[pcount - 1].atomcount = atomcount;
2309       altcount = 0;
2310       atomcount = 0;
2311       break;
2312     case '|':
2313       if (0 == atomcount)
2314       {
2315         error_msg = "Cannot append '|' to nothing";
2316         goto error;
2317       }
2318       while (--atomcount > 0)
2319         nfa_add_concatenation (&ctx);
2320       altcount++;
2321       break;
2322     case ')':
2323       if (0 == pcount)
2324       {
2325         error_msg = "Missing opening '('";
2326         goto error;
2327       }
2328       if (0 == atomcount)
2329       {
2330         // Ignore this: "()"
2331         pcount--;
2332         altcount = p[pcount].altcount;
2333         atomcount = p[pcount].atomcount;
2334         break;
2335       }
2336       while (--atomcount > 0)
2337         nfa_add_concatenation (&ctx);
2338       for (; altcount > 0; altcount--)
2339         nfa_add_alternation (&ctx);
2340       pcount--;
2341       altcount = p[pcount].altcount;
2342       atomcount = p[pcount].atomcount;
2343       atomcount++;
2344       break;
2345     case '*':
2346       if (atomcount == 0)
2347       {
2348         error_msg = "Cannot append '*' to nothing";
2349         goto error;
2350       }
2351       nfa_add_star_op (&ctx);
2352       break;
2353     case '+':
2354       if (atomcount == 0)
2355       {
2356         error_msg = "Cannot append '+' to nothing";
2357         goto error;
2358       }
2359       nfa_add_plus_op (&ctx);
2360       break;
2361     case '?':
2362       if (atomcount == 0)
2363       {
2364         error_msg = "Cannot append '?' to nothing";
2365         goto error;
2366       }
2367       nfa_add_question_op (&ctx);
2368       break;
2369     default:
2370       if (atomcount > 1)
2371       {
2372         --atomcount;
2373         nfa_add_concatenation (&ctx);
2374       }
2375       curlabel[0] = *regexp;
2376       nfa_add_label (&ctx, curlabel);
2377       atomcount++;
2378       break;
2379     }
2380   }
2381   if (0 != pcount)
2382   {
2383     error_msg = "Unbalanced parenthesis";
2384     goto error;
2385   }
2386   while (--atomcount > 0)
2387     nfa_add_concatenation (&ctx);
2388   for (; altcount > 0; altcount--)
2389     nfa_add_alternation (&ctx);
2390
2391   GNUNET_free_non_null (p);
2392
2393   nfa = ctx.stack_tail;
2394   GNUNET_CONTAINER_DLL_remove (ctx.stack_head, ctx.stack_tail, nfa);
2395
2396   if (NULL != ctx.stack_head)
2397   {
2398     error_msg = "Creating the NFA failed. NFA stack was not empty!";
2399     goto error;
2400   }
2401
2402   /* Remember the regex that was used to generate this NFA */
2403   nfa->regex = GNUNET_strdup (regex);
2404
2405   /* create depth-first numbering of the states for pretty printing */
2406   GNUNET_REGEX_automaton_traverse (nfa, NULL, NULL, NULL, &number_states, NULL);
2407
2408   /* No multistriding added so far */
2409   nfa->is_multistrided = GNUNET_NO;
2410
2411   return nfa;
2412
2413 error:
2414   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not parse regex: %s\n", regex);
2415   if (NULL != error_msg)
2416     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", error_msg);
2417
2418   GNUNET_free_non_null (p);
2419
2420   while (NULL != (nfa = ctx.stack_head))
2421   {
2422     GNUNET_CONTAINER_DLL_remove (ctx.stack_head, ctx.stack_tail, nfa);
2423     GNUNET_REGEX_automaton_destroy (nfa);
2424   }
2425
2426   return NULL;
2427 }
2428
2429
2430 /**
2431  * Create DFA states based on given 'nfa' and starting with 'dfa_state'.
2432  *
2433  * @param ctx context.
2434  * @param nfa NFA automaton.
2435  * @param dfa DFA automaton.
2436  * @param dfa_state current dfa state, pass epsilon closure of first nfa state
2437  *                  for starting.
2438  */
2439 static void
2440 construct_dfa_states (struct GNUNET_REGEX_Context *ctx,
2441                       struct GNUNET_REGEX_Automaton *nfa,
2442                       struct GNUNET_REGEX_Automaton *dfa,
2443                       struct GNUNET_REGEX_State *dfa_state)
2444 {
2445   struct GNUNET_REGEX_Transition *ctran;
2446   struct GNUNET_REGEX_State *state_iter;
2447   struct GNUNET_REGEX_State *new_dfa_state;
2448   struct GNUNET_REGEX_State *state_contains;
2449   struct GNUNET_REGEX_StateSet *tmp;
2450   struct GNUNET_REGEX_StateSet *nfa_set;
2451
2452   for (ctran = dfa_state->transitions_head; NULL != ctran; ctran = ctran->next)
2453   {
2454     if (NULL == ctran->label || NULL != ctran->to_state)
2455       continue;
2456
2457     tmp = nfa_closure_set_create (nfa, dfa_state->nfa_set, ctran->label);
2458     nfa_set = nfa_closure_set_create (nfa, tmp, 0);
2459     state_set_clear (tmp);
2460     new_dfa_state = dfa_state_create (ctx, nfa_set);
2461     state_contains = NULL;
2462     for (state_iter = dfa->states_head; NULL != state_iter;
2463          state_iter = state_iter->next)
2464     {
2465       if (0 == state_set_compare (state_iter->nfa_set, new_dfa_state->nfa_set))
2466         state_contains = state_iter;
2467     }
2468
2469     if (NULL == state_contains)
2470     {
2471       automaton_add_state (dfa, new_dfa_state);
2472       ctran->to_state = new_dfa_state;
2473       construct_dfa_states (ctx, nfa, dfa, new_dfa_state);
2474     }
2475     else
2476     {
2477       ctran->to_state = state_contains;
2478       automaton_destroy_state (new_dfa_state);
2479     }
2480   }
2481 }
2482
2483
2484 /**
2485  * Construct DFA for the given 'regex' of length 'len'
2486  *
2487  * @param regex regular expression string
2488  * @param len length of the regular expression
2489  *
2490  * @return DFA, needs to be freed using GNUNET_REGEX_destroy_automaton
2491  */
2492 struct GNUNET_REGEX_Automaton *
2493 GNUNET_REGEX_construct_dfa (const char *regex, const size_t len)
2494 {
2495   struct GNUNET_REGEX_Context ctx;
2496   struct GNUNET_REGEX_Automaton *dfa;
2497   struct GNUNET_REGEX_Automaton *nfa;
2498   struct GNUNET_REGEX_StateSet *nfa_start_eps_cls;
2499
2500   GNUNET_REGEX_context_init (&ctx);
2501
2502   // Create NFA
2503   nfa = GNUNET_REGEX_construct_nfa (regex, len);
2504
2505   if (NULL == nfa)
2506   {
2507     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2508                 "Could not create DFA, because NFA creation failed\n");
2509     return NULL;
2510   }
2511
2512   dfa = GNUNET_malloc (sizeof (struct GNUNET_REGEX_Automaton));
2513   dfa->type = DFA;
2514   dfa->state_count = 0;
2515   dfa->states_head = NULL;
2516   dfa->states_tail = NULL;
2517   dfa->regex = GNUNET_strdup (regex);
2518   dfa->is_multistrided = GNUNET_NO;
2519
2520   // Create DFA start state from epsilon closure
2521   nfa_start_eps_cls = nfa_closure_create (nfa, nfa->start, 0);
2522   dfa->start = dfa_state_create (&ctx, nfa_start_eps_cls);
2523   automaton_add_state (dfa, dfa->start);
2524
2525   construct_dfa_states (&ctx, nfa, dfa, dfa->start);
2526
2527   GNUNET_REGEX_automaton_destroy (nfa);
2528
2529   // Minimize DFA
2530   dfa_minimize (&ctx, dfa);
2531
2532   // Create proofs for all states
2533   automaton_create_proofs (dfa);
2534
2535   // Compress DFA paths
2536   dfa_compress_paths (&ctx, dfa, 8);
2537
2538   // Add strides to DFA
2539   //GNUNET_REGEX_dfa_add_multi_strides (&ctx, dfa, 2);
2540
2541   return dfa;
2542 }
2543
2544
2545 /**
2546  * Free the memory allocated by constructing the GNUNET_REGEX_Automaton data
2547  * structure.
2548  *
2549  * @param a automaton to be destroyed
2550  */
2551 void
2552 GNUNET_REGEX_automaton_destroy (struct GNUNET_REGEX_Automaton *a)
2553 {
2554   struct GNUNET_REGEX_State *s;
2555   struct GNUNET_REGEX_State *next_state;
2556
2557   if (NULL == a)
2558     return;
2559
2560   GNUNET_free_non_null (a->regex);
2561   GNUNET_free_non_null (a->canonical_regex);
2562
2563   for (s = a->states_head; NULL != s; s = next_state)
2564   {
2565     next_state = s->next;
2566     GNUNET_CONTAINER_DLL_remove (a->states_head, a->states_tail, s);
2567     automaton_destroy_state (s);
2568   }
2569
2570   GNUNET_free (a);
2571 }
2572
2573
2574 /**
2575  * Evaluates the given string using the given DFA automaton
2576  *
2577  * @param a automaton, type must be DFA
2578  * @param string string that should be evaluated
2579  *
2580  * @return 0 if string matches, non 0 otherwise
2581  */
2582 static int
2583 evaluate_dfa (struct GNUNET_REGEX_Automaton *a, const char *string)
2584 {
2585   const char *strp;
2586   struct GNUNET_REGEX_State *s;
2587   unsigned int step_len;
2588
2589   if (DFA != a->type)
2590   {
2591     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2592                 "Tried to evaluate DFA, but NFA automaton given");
2593     return -1;
2594   }
2595
2596   s = a->start;
2597
2598   // If the string is empty but the starting state is accepting, we accept.
2599   if ((NULL == string || 0 == strlen (string)) && s->accepting)
2600     return 0;
2601
2602   for (strp = string; NULL != strp && *strp; strp += step_len)
2603   {
2604     step_len = dfa_move (&s, strp);
2605
2606     if (NULL == s)
2607       break;
2608   }
2609
2610   if (NULL != s && s->accepting)
2611     return 0;
2612
2613   return 1;
2614 }
2615
2616
2617 /**
2618  * Evaluates the given string using the given NFA automaton
2619  *
2620  * @param a automaton, type must be NFA
2621  * @param string string that should be evaluated
2622  *
2623  * @return 0 if string matches, non 0 otherwise
2624  */
2625 static int
2626 evaluate_nfa (struct GNUNET_REGEX_Automaton *a, const char *string)
2627 {
2628   const char *strp;
2629   char str[2];
2630   struct GNUNET_REGEX_State *s;
2631   struct GNUNET_REGEX_StateSet *sset;
2632   struct GNUNET_REGEX_StateSet *new_sset;
2633   unsigned int i;
2634   int result;
2635
2636   if (NFA != a->type)
2637   {
2638     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2639                 "Tried to evaluate NFA, but DFA automaton given");
2640     return -1;
2641   }
2642
2643   // If the string is empty but the starting state is accepting, we accept.
2644   if ((NULL == string || 0 == strlen (string)) && a->start->accepting)
2645     return 0;
2646
2647   result = 1;
2648   sset = nfa_closure_create (a, a->start, 0);
2649
2650   str[1] = '\0';
2651   for (strp = string; NULL != strp && *strp; strp++)
2652   {
2653     str[0] = *strp;
2654     new_sset = nfa_closure_set_create (a, sset, str);
2655     state_set_clear (sset);
2656     sset = nfa_closure_set_create (a, new_sset, 0);
2657     state_set_clear (new_sset);
2658   }
2659
2660   for (i = 0; i < sset->len; i++)
2661   {
2662     s = sset->states[i];
2663     if (NULL != s && s->accepting)
2664     {
2665       result = 0;
2666       break;
2667     }
2668   }
2669
2670   state_set_clear (sset);
2671   return result;
2672 }
2673
2674
2675 /**
2676  * Evaluates the given 'string' against the given compiled regex
2677  *
2678  * @param a automaton
2679  * @param string string to check
2680  *
2681  * @return 0 if string matches, non 0 otherwise
2682  */
2683 int
2684 GNUNET_REGEX_eval (struct GNUNET_REGEX_Automaton *a, const char *string)
2685 {
2686   int result;
2687
2688   switch (a->type)
2689   {
2690   case DFA:
2691     result = evaluate_dfa (a, string);
2692     break;
2693   case NFA:
2694     result = evaluate_nfa (a, string);
2695     break;
2696   default:
2697     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2698                 "Evaluating regex failed, automaton has no type!\n");
2699     result = GNUNET_SYSERR;
2700     break;
2701   }
2702
2703   return result;
2704 }
2705
2706
2707 /**
2708  * Get the canonical regex of the given automaton.
2709  * When constructing the automaton a proof is computed for each state,
2710  * consisting of the regular expression leading to this state. A complete
2711  * regex for the automaton can be computed by combining these proofs.
2712  * As of now this function is only useful for testing.
2713  *
2714  * @param a automaton for which the canonical regex should be returned.
2715  *
2716  * @return
2717  */
2718 const char *
2719 GNUNET_REGEX_get_canonical_regex (struct GNUNET_REGEX_Automaton *a)
2720 {
2721   if (NULL == a)
2722     return NULL;
2723
2724   return a->canonical_regex;
2725 }
2726
2727
2728 /**
2729  * Get the number of transitions that are contained in the given automaton.
2730  *
2731  * @param a automaton for which the number of transitions should be returned.
2732  *
2733  * @return number of transitions in the given automaton.
2734  */
2735 unsigned int
2736 GNUNET_REGEX_get_transition_count (struct GNUNET_REGEX_Automaton *a)
2737 {
2738   unsigned int t_count;
2739   struct GNUNET_REGEX_State *s;
2740
2741   if (NULL == a)
2742     return 0;
2743
2744   t_count = 0;
2745   for (s = a->states_head; NULL != s; s = s->next)
2746     t_count += s->transition_count;
2747
2748   return t_count;
2749 }
2750
2751
2752 /**
2753  * Get the first key for the given 'input_string'. This hashes the first x bits
2754  * of the 'input_string'.
2755  *
2756  * @param input_string string.
2757  * @param string_len length of the 'input_string'.
2758  * @param key pointer to where to write the hash code.
2759  *
2760  * @return number of bits of 'input_string' that have been consumed
2761  *         to construct the key
2762  */
2763 size_t
2764 GNUNET_REGEX_get_first_key (const char *input_string, size_t string_len,
2765                             struct GNUNET_HashCode * key)
2766 {
2767   unsigned int size;
2768
2769   size =
2770       string_len <
2771       GNUNET_REGEX_INITIAL_BITS ? string_len : GNUNET_REGEX_INITIAL_BITS;
2772
2773   if (NULL == input_string)
2774   {
2775     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Given input string was NULL!\n");
2776     return 0;
2777   }
2778
2779   GNUNET_CRYPTO_hash (input_string, size, key);
2780
2781   return size;
2782 }
2783
2784
2785 /**
2786  * Check if the given 'proof' matches the given 'key'.
2787  *
2788  * @param proof partial regex of a state.
2789  * @param key hash of a state.
2790  *
2791  * @return GNUNET_OK if the proof is valid for the given key.
2792  */
2793 int
2794 GNUNET_REGEX_check_proof (const char *proof, const struct GNUNET_HashCode *key)
2795 {
2796   struct GNUNET_HashCode key_check;
2797
2798   if (NULL == proof || NULL == key)
2799   {
2800     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Proof check failed, was NULL.\n");
2801     return GNUNET_NO;
2802   }
2803
2804   GNUNET_CRYPTO_hash (proof, strlen (proof), &key_check);
2805   return (0 ==
2806           GNUNET_CRYPTO_hash_cmp (key, &key_check)) ? GNUNET_OK : GNUNET_NO;
2807 }
2808
2809
2810 /**
2811  * Recursive function that calls the iterator for each synthetic start state.
2812  *
2813  * @param min_len minimum length of the path in the graph.
2814  * @param max_len maximum length of the path in the graph.
2815  * @param consumed_string string consumed by traversing the graph till this state.
2816  * @param state current state of the automaton.
2817  * @param iterator iterator function called for each edge.
2818  * @param iterator_cls closure for the iterator function.
2819  */
2820 static void
2821 iterate_initial_edge (const unsigned int min_len, const unsigned int max_len,
2822                       char *consumed_string, struct GNUNET_REGEX_State *state,
2823                       GNUNET_REGEX_KeyIterator iterator, void *iterator_cls)
2824 {
2825   unsigned int i;
2826   char *temp;
2827   struct GNUNET_REGEX_Transition *t;
2828   unsigned int num_edges = state->transition_count;
2829   struct GNUNET_REGEX_Edge edges[num_edges];
2830   struct GNUNET_REGEX_Edge edge[1];
2831   struct GNUNET_HashCode hash;
2832   struct GNUNET_HashCode hash_new;
2833
2834   unsigned int cur_len;
2835
2836   if (NULL != consumed_string)
2837     cur_len = strlen (consumed_string);
2838   else
2839     cur_len = 0;
2840
2841   if ((cur_len >= min_len || GNUNET_YES == state->accepting) && cur_len > 0 &&
2842       NULL != consumed_string)
2843   {
2844     if (cur_len <= max_len)
2845     {
2846       if (state->proof != NULL && 0 != strcmp (consumed_string, state->proof))
2847       {
2848         for (i = 0, t = state->transitions_head; NULL != t && i < num_edges;
2849              t = t->next, i++)
2850         {
2851           edges[i].label = t->label;
2852           edges[i].destination = t->to_state->hash;
2853         }
2854         GNUNET_CRYPTO_hash (consumed_string, strlen (consumed_string), &hash);
2855         iterator (iterator_cls, &hash, consumed_string, state->accepting,
2856                   num_edges, edges);
2857       }
2858
2859       if (GNUNET_YES == state->accepting && cur_len > 1 &&
2860           state->transition_count < 1 && cur_len < max_len)
2861       {
2862         // Special case for regex consisting of just a string that is shorter than
2863         // max_len
2864         edge[0].label = &consumed_string[cur_len - 1];
2865         edge[0].destination = state->hash;
2866         temp = GNUNET_strdup (consumed_string);
2867         temp[cur_len - 1] = '\0';
2868         GNUNET_CRYPTO_hash (temp, cur_len - 1, &hash_new);
2869         iterator (iterator_cls, &hash_new, temp, GNUNET_NO, 1, edge);
2870         GNUNET_free (temp);
2871       }
2872     }
2873     else if (max_len < cur_len)
2874     {
2875       // Case where the concatenated labels are longer than max_len, then split.
2876       edge[0].label = &consumed_string[max_len];
2877       edge[0].destination = state->hash;
2878       temp = GNUNET_strdup (consumed_string);
2879       temp[max_len] = '\0';
2880       GNUNET_CRYPTO_hash (temp, max_len, &hash);
2881       iterator (iterator_cls, &hash, temp, GNUNET_NO, 1, edge);
2882       GNUNET_free (temp);
2883     }
2884   }
2885
2886   if (cur_len < max_len)
2887   {
2888     for (t = state->transitions_head; NULL != t; t = t->next)
2889     {
2890       if (NULL != consumed_string)
2891         GNUNET_asprintf (&temp, "%s%s", consumed_string, t->label);
2892       else
2893         GNUNET_asprintf (&temp, "%s", t->label);
2894
2895       iterate_initial_edge (min_len, max_len, temp, t->to_state, iterator,
2896                             iterator_cls);
2897       GNUNET_free (temp);
2898     }
2899   }
2900 }
2901
2902
2903 /**
2904  * Iterate over all edges starting from start state of automaton 'a'. Calling
2905  * iterator for each edge.
2906  *
2907  * @param a automaton.
2908  * @param iterator iterator called for each edge.
2909  * @param iterator_cls closure.
2910  */
2911 void
2912 GNUNET_REGEX_iterate_all_edges (struct GNUNET_REGEX_Automaton *a,
2913                                 GNUNET_REGEX_KeyIterator iterator,
2914                                 void *iterator_cls)
2915 {
2916   struct GNUNET_REGEX_State *s;
2917
2918   for (s = a->states_head; NULL != s; s = s->next)
2919   {
2920     struct GNUNET_REGEX_Edge edges[s->transition_count];
2921     unsigned int num_edges;
2922
2923     num_edges = state_get_edges (s, edges);
2924
2925     if ((NULL != s->proof && 0 < strlen (s->proof)) || s->accepting)
2926       iterator (iterator_cls, &s->hash, s->proof, s->accepting, num_edges,
2927                 edges);
2928
2929     s->marked = GNUNET_NO;
2930   }
2931
2932   iterate_initial_edge (GNUNET_REGEX_INITIAL_BITS, GNUNET_REGEX_INITIAL_BITS,
2933                         NULL, a->start, iterator, iterator_cls);
2934 }
2935
2936
2937 /**
2938  * Create a string with binary IP notation for the given 'addr' in 'str'.
2939  *
2940  * @param af address family of the given 'addr'.
2941  * @param addr address that should be converted to a string.
2942  *             struct in_addr * for IPv4 and struct in6_addr * for IPv6.
2943  * @param str string that will contain binary notation of 'addr'. Expected
2944  *            to be at least 33 bytes long for IPv4 and 129 bytes long for IPv6.
2945  */
2946 static void
2947 iptobinstr (const int af, const void *addr, char *str)
2948 {
2949   int i;
2950
2951   switch (af)
2952   {
2953   case AF_INET:
2954   {
2955     uint32_t b = htonl (((struct in_addr *) addr)->s_addr);
2956
2957     str[32] = '\0';
2958     str += 31;
2959     for (i = 31; i >= 0; i--)
2960     {
2961       *str = (b & 1) + '0';
2962       str--;
2963       b >>= 1;
2964     }
2965     break;
2966   }
2967   case AF_INET6:
2968   {
2969     struct in6_addr b = *(const struct in6_addr *) addr;
2970
2971     str[128] = '\0';
2972     str += 127;
2973     for (i = 127; i >= 0; i--)
2974     {
2975       *str = (b.s6_addr[i / 8] & 1) + '0';
2976       str--;
2977       b.s6_addr[i / 8] >>= 1;
2978     }
2979     break;
2980   }
2981   }
2982 }
2983
2984
2985 /**
2986  * Get the ipv4 network prefix from the given 'netmask'.
2987  *
2988  * @param netmask netmask for which to get the prefix len.
2989  *
2990  * @return length of ipv4 prefix for 'netmask'.
2991  */
2992 static unsigned int
2993 ipv4netmasktoprefixlen (const char *netmask)
2994 {
2995   struct in_addr a;
2996   unsigned int len;
2997   uint32_t t;
2998
2999   if (1 != inet_pton (AF_INET, netmask, &a))
3000     return 0;
3001   len = 32;
3002   for (t = htonl (~a.s_addr); 0 != t; t >>= 1)
3003     len--;
3004   return len;
3005 }
3006
3007
3008 /**
3009  * Create a regex in 'rxstr' from the given 'ip' and 'netmask'.
3010  *
3011  * @param ip IPv4 representation.
3012  * @param netmask netmask for the ip.
3013  * @param rxstr generated regex, must be at least GNUNET_REGEX_IPV4_REGEXLEN
3014  *              bytes long.
3015  */
3016 void
3017 GNUNET_REGEX_ipv4toregex (const struct in_addr *ip, const char *netmask,
3018                           char *rxstr)
3019 {
3020   unsigned int pfxlen;
3021
3022   pfxlen = ipv4netmasktoprefixlen (netmask);
3023   iptobinstr (AF_INET, ip, rxstr);
3024   rxstr[pfxlen] = '\0';
3025   if (pfxlen < 32)
3026     strcat (rxstr, "(0|1)+");
3027 }
3028
3029
3030 /**
3031  * Create a regex in 'rxstr' from the given 'ipv6' and 'prefixlen'.
3032  *
3033  * @param ipv6 IPv6 representation.
3034  * @param prefixlen length of the ipv6 prefix.
3035  * @param rxstr generated regex, must be at least GNUNET_REGEX_IPV6_REGEXLEN
3036  *              bytes long.
3037  */
3038 void
3039 GNUNET_REGEX_ipv6toregex (const struct in6_addr *ipv6, unsigned int prefixlen,
3040                           char *rxstr)
3041 {
3042   iptobinstr (AF_INET6, ipv6, rxstr);
3043   rxstr[prefixlen] = '\0';
3044   if (prefixlen < 128)
3045     strcat (rxstr, "(0|1)+");
3046 }