From adbde8be4b6ee0a854177237391936faa8ca61c2 Mon Sep 17 00:00:00 2001 From: Maximilian Szengel Date: Thu, 26 Jul 2012 13:32:08 +0000 Subject: [PATCH] - Added coloring option to graph saving. - Fixed a bug causing NFAs not to print properly. --- src/include/gnunet_regex_lib.h | 39 ++++++++++++++---- src/regex/regex.c | 8 +++- src/regex/regex_graph.c | 74 +++++++++++++++++++++++++--------- 3 files changed, 92 insertions(+), 29 deletions(-) diff --git a/src/include/gnunet_regex_lib.h b/src/include/gnunet_regex_lib.h index 627bcaa22..53e7c13e0 100644 --- a/src/include/gnunet_regex_lib.h +++ b/src/include/gnunet_regex_lib.h @@ -95,18 +95,42 @@ GNUNET_REGEX_automaton_destroy (struct GNUNET_REGEX_Automaton *a); /** - * Save the given automaton as a GraphViz dot file + * Options for graph creation function + * GNUNET_REGEX_automaton_save_graph. + */ + +enum GNUNET_REGEX_GraphSavingOptions +{ + /** + * Default. Do nothing special. + */ + GNUNET_REGEX_GRAPH_DEFAULT = 0, + + /** + * The generated graph will include extra information such as the NFA states + * that were used to generate the DFA state. + */ + GNUNET_REGEX_GRAPH_VERBOSE = 1, + + /** + * Enable graph coloring. Will color each SCC in a different color. + */ + GNUNET_REGEX_GRAPH_COLORING = 2 +}; + + +/** + * Save the given automaton as a GraphViz dot file. * - * @param a the automaton to be saved - * @param filename where to save the file - * @param verbose if set to GNUNET_YES the generated graph will include extra - * information such as the NFA states that were used to generate - * the DFA state etc. + * @param a the automaton to be saved. + * @param filename where to save the file. + * @param options options for graph generation that include coloring or verbose + * mode */ void GNUNET_REGEX_automaton_save_graph (struct GNUNET_REGEX_Automaton *a, const char *filename, - int verbose); + enum GNUNET_REGEX_GraphSavingOptions options); /** @@ -192,4 +216,3 @@ GNUNET_REGEX_iterate_all_edges (struct GNUNET_REGEX_Automaton *a, /* end of gnunet_regex_lib.h */ #endif - diff --git a/src/regex/regex.c b/src/regex/regex.c index 2152167dc..c8b8ad3fa 100644 --- a/src/regex/regex.c +++ b/src/regex/regex.c @@ -766,7 +766,8 @@ number_states (void *cls, unsigned int count, struct GNUNET_REGEX_State *s) struct GNUNET_REGEX_State **states = cls; s->proof_id = count; - states[count] = s; + if (NULL != states) + states[count] = s; } @@ -1914,7 +1915,7 @@ nfa_add_question_op (struct GNUNET_REGEX_Context *ctx) struct GNUNET_REGEX_State *end; a = ctx->stack_tail; - + if (NULL == a) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -2174,6 +2175,9 @@ GNUNET_REGEX_construct_nfa (const char *regex, const size_t len) nfa->regex = GNUNET_strdup (regex); + /* create depth-first numbering of the states for pretty printing */ + GNUNET_REGEX_automaton_traverse (nfa, &number_states, NULL); + return nfa; error: diff --git a/src/regex/regex_graph.c b/src/regex/regex_graph.c index b8eda8ec9..9dfdb15a4 100644 --- a/src/regex/regex_graph.c +++ b/src/regex/regex_graph.c @@ -42,6 +42,11 @@ struct GNUNET_REGEX_Graph_Context * the graph. */ int verbose; + + /** + * Coloring flag, if set to GNUNET_YES SCCs will be colored. + */ + int coloring; }; @@ -169,15 +174,27 @@ GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count, if (s->accepting) { - GNUNET_asprintf (&s_acc, - "\"%s\" [shape=doublecircle, color=\"0.%i 0.8 0.95\"];\n", - name, s->scc_id); + if (GNUNET_YES == ctx->coloring) + { + GNUNET_asprintf (&s_acc, + "\"%s\" [shape=doublecircle, color=\"0.%i 0.8 0.95\"];\n", + name, s->scc_id); + } + else + { + GNUNET_asprintf (&s_acc, "\"%s\" [shape=doublecircle];\n", name, + s->scc_id); + } } - else + else if (GNUNET_YES == ctx->coloring) { - GNUNET_asprintf (&s_acc, "\"%s\" [color=\"0.%i 0.8 0.95\"];\n", name, + GNUNET_asprintf (&s_acc, "\"%s\" [shape=circle, color=\"0.%i 0.8 0.95\"];\n", name, s->scc_id); } + else + { + GNUNET_asprintf (&s_acc, "\"%s\" [shape=circle];\n", name, s->scc_id); + } if (NULL == s_acc) { @@ -209,15 +226,31 @@ GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count, if (ctran->label == 0) { - GNUNET_asprintf (&s_tran, - "\"%s\" -> \"%s\" [label = \"epsilon\", color=\"0.%i 0.8 0.95\"];\n", - name, to_name, s->scc_id); + if (GNUNET_YES == ctx->coloring) + { + GNUNET_asprintf (&s_tran, + "\"%s\" -> \"%s\" [label = \"ε\", color=\"0.%i 0.8 0.95\"];\n", + name, to_name, s->scc_id); + } + else + { + GNUNET_asprintf (&s_tran, "\"%s\" -> \"%s\" [label = \"ε\"];\n", + name, to_name, s->scc_id); + } } else { - GNUNET_asprintf (&s_tran, - "\"%s\" -> \"%s\" [label = \"%c\", color=\"0.%i 0.8 0.95\"];\n", - name, to_name, ctran->label, s->scc_id); + if (GNUNET_YES == ctx->coloring) + { + GNUNET_asprintf (&s_tran, + "\"%s\" -> \"%s\" [label = \"%c\", color=\"0.%i 0.8 0.95\"];\n", + name, to_name, ctran->label, s->scc_id); + } + else + { + GNUNET_asprintf (&s_tran, "\"%s\" -> \"%s\" [label = \"%c\"];\n", name, + to_name, ctran->label, s->scc_id); + } } GNUNET_free (to_name); @@ -239,17 +272,17 @@ GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count, /** - * Save the given automaton as a GraphViz dot file + * Save the given automaton as a GraphViz dot file. * - * @param a the automaton to be saved - * @param filename where to save the file - * @param verbose if set to GNUNET_YES the generated graph will include extra - * information such as the NFA states that were used to generate - * the DFA state etc. + * @param a the automaton to be saved. + * @param filename where to save the file. + * @param options options for graph generation that include coloring or verbose + * mode */ void GNUNET_REGEX_automaton_save_graph (struct GNUNET_REGEX_Automaton *a, - const char *filename, int verbose) + const char *filename, + enum GNUNET_REGEX_GraphSavingOptions options) { char *start; char *end; @@ -268,7 +301,10 @@ GNUNET_REGEX_automaton_save_graph (struct GNUNET_REGEX_Automaton *a, } ctx.filep = fopen (filename, "w"); - ctx.verbose = verbose; + ctx.verbose = + (0 == (options & GNUNET_REGEX_GRAPH_VERBOSE)) ? GNUNET_NO : GNUNET_YES; + ctx.coloring = + (0 == (options & GNUNET_REGEX_GRAPH_COLORING)) ? GNUNET_NO : GNUNET_YES; if (NULL == ctx.filep) { -- 2.25.1