aboutsummaryrefslogtreecommitdiff
path: root/src/regex/regex_graph.c
diff options
context:
space:
mode:
authorMaximilian Szengel <gnunet@maxsz.de>2012-07-05 14:29:32 +0000
committerMaximilian Szengel <gnunet@maxsz.de>2012-07-05 14:29:32 +0000
commit816d8f5199c6262d64a9230c23640dc0ce3d5be4 (patch)
tree5bcfb5217ad02ffd9402d2d8b716c2a2085a707b /src/regex/regex_graph.c
parent765c01ac57c598b3e4588c34ab633197c00e9a9a (diff)
downloadgnunet-816d8f5199c6262d64a9230c23640dc0ce3d5be4.tar.gz
gnunet-816d8f5199c6262d64a9230c23640dc0ce3d5be4.zip
regex: added verbose flag to graph api.
Diffstat (limited to 'src/regex/regex_graph.c')
-rw-r--r--src/regex/regex_graph.c82
1 files changed, 58 insertions, 24 deletions
diff --git a/src/regex/regex_graph.c b/src/regex/regex_graph.c
index eb4d61b4e..5adecab62 100644
--- a/src/regex/regex_graph.c
+++ b/src/regex/regex_graph.c
@@ -26,6 +26,25 @@
26#include "gnunet_regex_lib.h" 26#include "gnunet_regex_lib.h"
27#include "regex_internal.h" 27#include "regex_internal.h"
28 28
29/**
30 * Context for graph creation. Passed as the cls to
31 * GNUNET_REGEX_automaton_save_graph_step.
32 */
33struct GNUNET_REGEX_Graph_Context
34{
35 /**
36 * File pointer to the dot file used for output.
37 */
38 FILE *filep;
39
40 /**
41 * Verbose flag, if it's set to GNUNET_YES additional info will be printed in
42 * the graph.
43 */
44 int verbose;
45};
46
47
29/** 48/**
30 * Recursive function doing DFS with 'v' as a start, detecting all SCCs inside 49 * Recursive function doing DFS with 'v' as a start, detecting all SCCs inside
31 * the subgraph reachable from 'v'. Used with scc_tarjan function to detect all 50 * the subgraph reachable from 'v'. Used with scc_tarjan function to detect all
@@ -135,23 +154,27 @@ void
135GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count, 154GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count,
136 struct GNUNET_REGEX_State *s) 155 struct GNUNET_REGEX_State *s)
137{ 156{
138 FILE *p; 157 struct GNUNET_REGEX_Graph_Context *ctx = cls;
139 struct GNUNET_REGEX_Transition *ctran; 158 struct GNUNET_REGEX_Transition *ctran;
140 char *s_acc = NULL; 159 char *s_acc = NULL;
141 char *s_tran = NULL; 160 char *s_tran = NULL;
142 161 char *name;
143 p = cls; 162 char *to_name;
163
164 if (GNUNET_YES == ctx->verbose)
165 GNUNET_asprintf (&name, "%i (%s)", s->proof_id, s->name);
166 else
167 GNUNET_asprintf (&name, "%i", s->proof_id);
144 168
145 if (s->accepting) 169 if (s->accepting)
146 { 170 {
147 GNUNET_asprintf (&s_acc, 171 GNUNET_asprintf (&s_acc,
148 "\"%s(%i)\" [shape=doublecircle, color=\"0.%i 0.8 0.95\"];\n", 172 "\"%s\" [shape=doublecircle, color=\"0.%i 0.8 0.95\"];\n",
149 s->name, s->proof_id, s->scc_id); 173 name, s->scc_id);
150 } 174 }
151 else 175 else
152 { 176 {
153 GNUNET_asprintf (&s_acc, "\"%s(%i)\" [color=\"0.%i 0.8 0.95\"];\n", s->name, 177 GNUNET_asprintf (&s_acc, "\"%s\" [color=\"0.%i 0.8 0.95\"];\n", name, s->scc_id);
154 s->proof_id, s->scc_id);
155 } 178 }
156 179
157 if (NULL == s_acc) 180 if (NULL == s_acc)
@@ -159,7 +182,7 @@ GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count,
159 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not print state %s\n", s->name); 182 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not print state %s\n", s->name);
160 return; 183 return;
161 } 184 }
162 fwrite (s_acc, strlen (s_acc), 1, p); 185 fwrite (s_acc, strlen (s_acc), 1, ctx->filep);
163 GNUNET_free (s_acc); 186 GNUNET_free (s_acc);
164 s_acc = NULL; 187 s_acc = NULL;
165 188
@@ -173,21 +196,26 @@ GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count,
173 continue; 196 continue;
174 } 197 }
175 198
199 if (GNUNET_YES == ctx->verbose)
200 GNUNET_asprintf (&to_name, "%i (%s)", ctran->to_state->proof_id, ctran->to_state->name);
201 else
202 GNUNET_asprintf (&to_name, "%i", ctran->to_state->proof_id);
203
176 if (ctran->label == 0) 204 if (ctran->label == 0)
177 { 205 {
178 GNUNET_asprintf (&s_tran, 206 GNUNET_asprintf (&s_tran,
179 "\"%s(%i)\" -> \"%s(%i)\" [label = \"epsilon\", color=\"0.%i 0.8 0.95\"];\n", 207 "\"%s\" -> \"%s\" [label = \"epsilon\", color=\"0.%i 0.8 0.95\"];\n",
180 s->name, s->proof_id, ctran->to_state->name, 208 name, to_name, s->scc_id);
181 ctran->to_state->proof_id, s->scc_id);
182 } 209 }
183 else 210 else
184 { 211 {
185 GNUNET_asprintf (&s_tran, 212 GNUNET_asprintf (&s_tran,
186 "\"%s(%i)\" -> \"%s(%i)\" [label = \"%c\", color=\"0.%i 0.8 0.95\"];\n", 213 "\"%s\" -> \"%s\" [label = \"%c\", color=\"0.%i 0.8 0.95\"];\n",
187 s->name, s->proof_id, ctran->to_state->name, 214 name, to_name, ctran->label, s->scc_id);
188 ctran->to_state->proof_id, ctran->label, s->scc_id);
189 } 215 }
190 216
217 GNUNET_free (to_name);
218
191 if (NULL == s_tran) 219 if (NULL == s_tran)
192 { 220 {
193 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not print state %s\n", 221 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not print state %s\n",
@@ -195,10 +223,12 @@ GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count,
195 return; 223 return;
196 } 224 }
197 225
198 fwrite (s_tran, strlen (s_tran), 1, p); 226 fwrite (s_tran, strlen (s_tran), 1, ctx->filep);
199 GNUNET_free (s_tran); 227 GNUNET_free (s_tran);
200 s_tran = NULL; 228 s_tran = NULL;
201 } 229 }
230
231 GNUNET_free (name);
202} 232}
203 233
204 234
@@ -207,15 +237,19 @@ GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count,
207 * 237 *
208 * @param a the automaton to be saved 238 * @param a the automaton to be saved
209 * @param filename where to save the file 239 * @param filename where to save the file
240 * @param verbose if set to GNUNET_YES the generated graph will include extra
241 * information such as the NFA states that were used to generate
242 * the DFA state etc.
210 */ 243 */
211void 244void
212GNUNET_REGEX_automaton_save_graph (struct GNUNET_REGEX_Automaton *a, 245GNUNET_REGEX_automaton_save_graph (struct GNUNET_REGEX_Automaton *a,
213 const char *filename) 246 const char *filename,
247 int verbose)
214{ 248{
215 char *start; 249 char *start;
216 char *end; 250 char *end;
217 FILE *p; 251 struct GNUNET_REGEX_Graph_Context ctx;
218 252
219 if (NULL == a) 253 if (NULL == a)
220 { 254 {
221 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not print NFA, was NULL!"); 255 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not print NFA, was NULL!");
@@ -228,9 +262,9 @@ GNUNET_REGEX_automaton_save_graph (struct GNUNET_REGEX_Automaton *a,
228 return; 262 return;
229 } 263 }
230 264
231 p = fopen (filename, "w"); 265 ctx.filep = fopen (filename, "w");
232 266
233 if (NULL == p) 267 if (NULL == ctx.filep)
234 { 268 {
235 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not open file for writing: %s", 269 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not open file for writing: %s",
236 filename); 270 filename);
@@ -241,12 +275,12 @@ GNUNET_REGEX_automaton_save_graph (struct GNUNET_REGEX_Automaton *a,
241 scc_tarjan (a); 275 scc_tarjan (a);
242 276
243 start = "digraph G {\nrankdir=LR\n"; 277 start = "digraph G {\nrankdir=LR\n";
244 fwrite (start, strlen (start), 1, p); 278 fwrite (start, strlen (start), 1, ctx.filep);
245 279
246 GNUNET_REGEX_automaton_traverse (a, &GNUNET_REGEX_automaton_save_graph_step, 280 GNUNET_REGEX_automaton_traverse (a, &GNUNET_REGEX_automaton_save_graph_step,
247 p); 281 &ctx);
248 282
249 end = "\n}\n"; 283 end = "\n}\n";
250 fwrite (end, strlen (end), 1, p); 284 fwrite (end, strlen (end), 1, ctx.filep);
251 fclose (p); 285 fclose (ctx.filep);
252} 286}