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