diff options
author | Maximilian Szengel <gnunet@maxsz.de> | 2012-09-24 19:11:42 +0000 |
---|---|---|
committer | Maximilian Szengel <gnunet@maxsz.de> | 2012-09-24 19:11:42 +0000 |
commit | 357582e58b08cdfce08b67412fd60305c3470809 (patch) | |
tree | 48f0ae9c9918dc0ebc45c73956b529b370c919f9 /src/regex/test_regex_iterate_api.c | |
parent | dbe7cda38fe4464992c8798306f1641162cdce41 (diff) | |
download | gnunet-357582e58b08cdfce08b67412fd60305c3470809.tar.gz gnunet-357582e58b08cdfce08b67412fd60305c3470809.zip |
regex: iteration improvements/fixes
Diffstat (limited to 'src/regex/test_regex_iterate_api.c')
-rw-r--r-- | src/regex/test_regex_iterate_api.c | 165 |
1 files changed, 130 insertions, 35 deletions
diff --git a/src/regex/test_regex_iterate_api.c b/src/regex/test_regex_iterate_api.c index b8f3cd266..84bb6e9fb 100644 --- a/src/regex/test_regex_iterate_api.c +++ b/src/regex/test_regex_iterate_api.c | |||
@@ -28,13 +28,25 @@ | |||
28 | #include "gnunet_regex_lib.h" | 28 | #include "gnunet_regex_lib.h" |
29 | #include "regex_internal.h" | 29 | #include "regex_internal.h" |
30 | 30 | ||
31 | #define GNUNET_REGEX_ITERATE_SAVE_DEBUG_GRAPH GNUNET_NO | ||
32 | |||
31 | static unsigned int transition_counter; | 33 | static unsigned int transition_counter; |
32 | 34 | ||
33 | struct IteratorContext | 35 | struct IteratorContext |
34 | { | 36 | { |
35 | int error; | 37 | int error; |
36 | int should_save_graph; | 38 | int should_save_graph; |
37 | FILE *graph_file; | 39 | FILE *graph_filep; |
40 | unsigned int string_count; | ||
41 | char *const *strings; | ||
42 | unsigned int match_count; | ||
43 | }; | ||
44 | |||
45 | struct RegexStringPair | ||
46 | { | ||
47 | char *regex; | ||
48 | unsigned int string_count; | ||
49 | char *strings[20]; | ||
38 | }; | 50 | }; |
39 | 51 | ||
40 | void | 52 | void |
@@ -44,21 +56,41 @@ key_iterator (void *cls, const struct GNUNET_HashCode *key, const char *proof, | |||
44 | { | 56 | { |
45 | unsigned int i; | 57 | unsigned int i; |
46 | struct IteratorContext *ctx = cls; | 58 | struct IteratorContext *ctx = cls; |
59 | char *out_str; | ||
60 | char *state_id = GNUNET_strdup (GNUNET_h2s (key)); | ||
47 | 61 | ||
48 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iterating... (accepting: %i)\n", | 62 | if (GNUNET_YES == ctx->should_save_graph) |
49 | accepting); | 63 | { |
64 | if (GNUNET_YES == accepting) | ||
65 | GNUNET_asprintf (&out_str, "\"%s\" [shape=doublecircle]\n", state_id); | ||
66 | else | ||
67 | GNUNET_asprintf (&out_str, "\"%s\" [shape=circle]\n", state_id); | ||
68 | fwrite (out_str, strlen (out_str), 1, ctx->graph_filep); | ||
69 | GNUNET_free (out_str); | ||
70 | |||
71 | for (i = 0; i < num_edges; i++) | ||
72 | { | ||
73 | transition_counter++; | ||
74 | GNUNET_asprintf (&out_str, "\"%s\" -> \"%s\" [label = \"%s (%s)\"]\n", | ||
75 | state_id, GNUNET_h2s (&edges[i].destination), | ||
76 | edges[i].label, proof); | ||
77 | fwrite (out_str, strlen (out_str), 1, ctx->graph_filep); | ||
50 | 78 | ||
51 | if (NULL != proof) | 79 | GNUNET_free (out_str); |
52 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Proof: %s\n", proof); | 80 | } |
81 | } | ||
82 | else | ||
83 | { | ||
84 | for (i = 0; i < num_edges; i++) | ||
85 | transition_counter++; | ||
86 | } | ||
53 | 87 | ||
54 | if (NULL != key) | 88 | GNUNET_free (state_id); |
55 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hash: %s\n", GNUNET_h2s (key)); | ||
56 | 89 | ||
57 | for (i = 0; i < num_edges; i++) | 90 | for (i = 0; i < ctx->string_count; i++) |
58 | { | 91 | { |
59 | transition_counter++; | 92 | if (0 == strcmp (proof, ctx->strings[i])) |
60 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Edge %i: Label: %s Destination: %s\n", | 93 | ctx->match_count++; |
61 | i, edges[i].label, GNUNET_h2s (&edges[i].destination)); | ||
62 | } | 94 | } |
63 | 95 | ||
64 | ctx->error += (GNUNET_OK == GNUNET_REGEX_check_proof (proof, key)) ? 0 : 1; | 96 | ctx->error += (GNUNET_OK == GNUNET_REGEX_check_proof (proof, key)) ? 0 : 1; |
@@ -80,49 +112,112 @@ main (int argc, char *argv[]) | |||
80 | unsigned int i; | 112 | unsigned int i; |
81 | unsigned int num_transitions; | 113 | unsigned int num_transitions; |
82 | struct IteratorContext ctx = { 0, 0, NULL }; | 114 | struct IteratorContext ctx = { 0, 0, NULL }; |
115 | char *filename = NULL; | ||
83 | 116 | ||
84 | error = 0; | 117 | error = 0; |
85 | 118 | ||
86 | const char *regex[17] = { | 119 | const struct RegexStringPair rxstr[10] = { |
87 | "ab(c|d)+c*(a(b|c)+d)+(bla)+", | 120 | {"ab(c|d)+c*(a(b|c)+d)+(bla)+", 2, {"abcdcdca", "abcabdbl"}}, |
88 | "(bla)*", | 121 | {"abcdefghijklmnop*qst", 1, {"abcdefgh"}}, |
89 | "b(lab)*la", | 122 | {"VPN-4-1(0|1)*", 2, {"VPN-4-10", "VPN-4-11"}}, |
90 | "(ab)*", | 123 | {"a+X*y+c|p|R|Z*K*y*R+w|Y*6+n+h*k*w+V*F|W*B*e*", 4, |
91 | "ab(c|d)+c*(a(b|c)+d)+(bla)(bla)*", | 124 | {"aaaaaaaa", "aaXXyyyc", "p", "Y"}}, |
92 | "z(abc|def)?xyz", | 125 | {"a*", 8, |
93 | "1*0(0|1)*", | 126 | {"a", "aa", "aaa", "aaaa", "aaaaa", "aaaaaa", "aaaaaaa", "aaaaaaaa"}}, |
94 | "a*b*", | 127 | {"xzxzxzxzxz", 1, {"xzxzxzxz"}}, |
95 | "a+X*y+c|p|R|Z*K*y*R+w|Y*6+n+h*k*w+V*F|W*B*e*", | 128 | {"xyz*", 2, {"xy", "xyz"}}, |
96 | "abcd:(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1):(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)", | 129 | {"ab", 1, {"a"}}, |
97 | "abc(1|0)*def", | 130 | {"abcd:(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1):(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)(0|1)", 2, {"abcd:000", "abcd:101"}}, |
98 | "ab|ac", | 131 | {"x*|(0|1|2)(a|b|c|d)", 2, {"xxxxxxxx", "0a"}} |
99 | "(ab)(ab)*", | ||
100 | "ab|cd|ef|gh", | ||
101 | "a|b|c|d|e|f|g", | ||
102 | "(ab)|(ac)", | ||
103 | "x*|(0|1|2)(a|b|c|d)" | ||
104 | }; | 132 | }; |
105 | 133 | ||
106 | for (i = 0; i < 17; i++) | 134 | const char *graph_start_str = "digraph G {\nrankdir=LR\n"; |
135 | const char *graph_end_str = "\n}\n"; | ||
136 | |||
137 | for (i = 0; i < 10; i++) | ||
107 | { | 138 | { |
139 | // Create graph | ||
140 | if (GNUNET_YES == GNUNET_REGEX_ITERATE_SAVE_DEBUG_GRAPH) | ||
141 | { | ||
142 | GNUNET_asprintf (&filename, "iteration_graph_%u.dot", i); | ||
143 | ctx.graph_filep = fopen (filename, "w"); | ||
144 | if (NULL == ctx.graph_filep) | ||
145 | { | ||
146 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
147 | "Could not open file %s for saving iteration graph.\n", | ||
148 | filename); | ||
149 | ctx.should_save_graph = GNUNET_NO; | ||
150 | } | ||
151 | else | ||
152 | { | ||
153 | ctx.should_save_graph = GNUNET_YES; | ||
154 | fwrite (graph_start_str, strlen (graph_start_str), 1, ctx.graph_filep); | ||
155 | } | ||
156 | GNUNET_free (filename); | ||
157 | } | ||
158 | else | ||
159 | { | ||
160 | ctx.should_save_graph = GNUNET_NO; | ||
161 | } | ||
162 | |||
163 | // Iterate over DFA edges | ||
108 | transition_counter = 0; | 164 | transition_counter = 0; |
109 | dfa = GNUNET_REGEX_construct_dfa (regex[i], strlen (regex[i])); | 165 | ctx.string_count = rxstr[i].string_count; |
166 | ctx.strings = rxstr[i].strings; | ||
167 | ctx.match_count = 0; | ||
168 | dfa = GNUNET_REGEX_construct_dfa (rxstr[i].regex, strlen (rxstr[i].regex)); | ||
110 | GNUNET_REGEX_iterate_all_edges (dfa, key_iterator, &ctx); | 169 | GNUNET_REGEX_iterate_all_edges (dfa, key_iterator, &ctx); |
111 | num_transitions = GNUNET_REGEX_get_transition_count (dfa); | 170 | num_transitions = GNUNET_REGEX_get_transition_count (dfa); |
112 | if (transition_counter != num_transitions) | 171 | |
172 | if (transition_counter < num_transitions) | ||
113 | { | 173 | { |
114 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 174 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
115 | "Automaton has %d transitions, iterated over %d transitions\n", | 175 | "Automaton has %d transitions, iterated over %d transitions\n", |
116 | num_transitions, transition_counter); | 176 | num_transitions, transition_counter); |
177 | error += 1; | ||
178 | break; | ||
179 | } | ||
180 | |||
181 | if (ctx.match_count < ctx.string_count) | ||
182 | { | ||
183 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
184 | "Missing initial states for regex %s\n", rxstr[i].regex); | ||
185 | error += (ctx.string_count - ctx.match_count); | ||
117 | } | 186 | } |
187 | else if (ctx.match_count > ctx.string_count) | ||
188 | { | ||
189 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
190 | "Doublicate initial transitions for regex %s\n", | ||
191 | rxstr[i].regex); | ||
192 | error += (ctx.string_count - ctx.match_count); | ||
193 | } | ||
194 | |||
118 | GNUNET_REGEX_automaton_destroy (dfa); | 195 | GNUNET_REGEX_automaton_destroy (dfa); |
196 | |||
197 | // Finish graph | ||
198 | if (GNUNET_YES == ctx.should_save_graph) | ||
199 | { | ||
200 | fwrite (graph_end_str, strlen (graph_end_str), 1, ctx.graph_filep); | ||
201 | fclose (ctx.graph_filep); | ||
202 | ctx.graph_filep = NULL; | ||
203 | ctx.should_save_graph = GNUNET_NO; | ||
204 | } | ||
119 | } | 205 | } |
120 | 206 | ||
121 | for (i = 0; i < 17; i++) | 207 | |
208 | for (i = 0; i < 10; i++) | ||
122 | { | 209 | { |
123 | dfa = GNUNET_REGEX_construct_dfa (regex[i], strlen (regex[i])); | 210 | dfa = GNUNET_REGEX_construct_dfa (rxstr[i].regex, strlen (rxstr[i].regex)); |
124 | GNUNET_REGEX_dfa_add_multi_strides (NULL, dfa, 2); | 211 | GNUNET_REGEX_dfa_add_multi_strides (NULL, dfa, 2); |
125 | GNUNET_REGEX_iterate_all_edges (dfa, key_iterator, &ctx); | 212 | GNUNET_REGEX_iterate_all_edges (dfa, key_iterator, &ctx); |
213 | |||
214 | if (ctx.match_count < ctx.string_count) | ||
215 | { | ||
216 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
217 | "Missing initial states for regex %s\n", rxstr[i].regex); | ||
218 | error += (ctx.string_count - ctx.match_count); | ||
219 | } | ||
220 | |||
126 | GNUNET_REGEX_automaton_destroy (dfa); | 221 | GNUNET_REGEX_automaton_destroy (dfa); |
127 | } | 222 | } |
128 | 223 | ||