glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / regex / test_regex_proofs.c
1 /*
2      This file is part of GNUnet
3      Copyright (C) 2012 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your 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      Affero General Public License for more details.
14 */
15 /**
16  * @file regex/test_regex_proofs.c
17  * @brief test for regex.c
18  * @author Maximilian Szengel
19  */
20 #include "platform.h"
21 #include "regex_internal_lib.h"
22 #include "regex_test_lib.h"
23 #include "regex_internal.h"
24
25
26 /**
27  * Test if the given regex's canonical regex is the same as this canonical
28  * regex's canonical regex. Confused? Ok, then: 1. construct a dfa A from the
29  * given 'regex' 2. get the canonical regex of dfa A 3. construct a dfa B from
30  * this canonical regex 3. compare the canonical regex of dfa A with the
31  * canonical regex of dfa B.
32  *
33  * @param regex regular expression used for this test (see above).
34  *
35  * @return 0 on success, 1 on failure
36  */
37 static unsigned int
38 test_proof (const char *regex)
39 {
40   unsigned int error;
41   struct REGEX_INTERNAL_Automaton *dfa;
42   char *c_rx1;
43   const char *c_rx2;
44
45   dfa = REGEX_INTERNAL_construct_dfa (regex, strlen (regex), 1);
46   GNUNET_assert (NULL != dfa);
47   c_rx1 = GNUNET_strdup (REGEX_INTERNAL_get_canonical_regex (dfa));
48   REGEX_INTERNAL_automaton_destroy (dfa);
49   dfa = REGEX_INTERNAL_construct_dfa (c_rx1, strlen (c_rx1), 1);
50   GNUNET_assert (NULL != dfa);
51   c_rx2 = REGEX_INTERNAL_get_canonical_regex (dfa);
52
53   error = (0 == strcmp (c_rx1, c_rx2)) ? 0 : 1;
54
55   if (error > 0)
56   {
57     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
58                 "Comparing canonical regex of\n%s\nfailed:\n%s\nvs.\n%s\n",
59                 regex, c_rx1, c_rx2);
60   }
61
62   GNUNET_free (c_rx1);
63   REGEX_INTERNAL_automaton_destroy (dfa);
64
65   return error;
66 }
67
68
69 /**
70  * Use 'test_proof' function to randomly test the canonical regexes of 'count'
71  * random expressions of length 'rx_length'.
72  *
73  * @param count number of random regular expressions to test.
74  * @param rx_length length of the random regular expressions.
75  *
76  * @return 0 on succes, number of failures otherwise.
77  */
78 static unsigned int
79 test_proofs_random (unsigned int count, size_t rx_length)
80 {
81   unsigned int i;
82   char *rand_rx;
83   unsigned int failures;
84
85   failures = 0;
86
87   for (i = 0; i < count; i++)
88   {
89     rand_rx = REGEX_TEST_generate_random_regex (rx_length, NULL);
90     failures += test_proof (rand_rx);
91     GNUNET_free (rand_rx);
92   }
93
94   return failures;
95 }
96
97
98 /**
99  * Test a number of known examples of regexes for proper canonicalization.
100  *
101  * @return 0 on success, number of failures otherwise.
102  */
103 static unsigned int
104 test_proofs_static ()
105 {
106   unsigned int i;
107   unsigned int error;
108
109   const char *regex[8] = {
110     "a|aa*a",
111     "a+",
112     "a*",
113     "a*a*",
114     "(F*C|WfPf|y+F*C)",
115     "y*F*C|WfPf",
116     "((a|b)c|(a|b)(d|(a|b)e))",
117     "((a|b)(c|d)|(a|b)(a|b)e)"
118   };
119
120   const char *canon_rx1;
121   const char *canon_rx2;
122   struct REGEX_INTERNAL_Automaton *dfa1;
123   struct REGEX_INTERNAL_Automaton *dfa2;
124
125   error = 0;
126
127   for (i = 0; i < 8; i += 2)
128   {
129     dfa1 = REGEX_INTERNAL_construct_dfa (regex[i], strlen (regex[i]), 1);
130     dfa2 = REGEX_INTERNAL_construct_dfa (regex[i + 1], strlen (regex[i + 1]), 1);
131     GNUNET_assert (NULL != dfa1);
132     GNUNET_assert (NULL != dfa2);
133
134     canon_rx1 = REGEX_INTERNAL_get_canonical_regex (dfa1);
135     canon_rx2 = REGEX_INTERNAL_get_canonical_regex (dfa2);
136
137     error += (0 == strcmp (canon_rx1, canon_rx2)) ? 0 : 1;
138
139     if (error > 0)
140     {
141       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
142                   "Comparing canonical regex failed:\nrx1:\t%s\ncrx1:\t%s\nrx2:\t%s\ncrx2:\t%s\n",
143                   regex[i], canon_rx1, regex[i + 1], canon_rx2);
144     }
145
146     REGEX_INTERNAL_automaton_destroy (dfa1);
147     REGEX_INTERNAL_automaton_destroy (dfa2);
148   }
149
150   return error;
151 }
152
153
154 int
155 main (int argc, char *argv[])
156 {
157   GNUNET_log_setup ("test-regex", "WARNING", NULL);
158
159   int error;
160
161   error = 0;
162
163   error += test_proofs_static ();
164   error += test_proofs_random (100, 30);
165
166   return error;
167 }