From: Maximilian Szengel Date: Fri, 6 Jul 2012 14:30:09 +0000 (+0000) Subject: regex: iterating over the initial states X-Git-Tag: initial-import-from-subversion-38251~12607 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=be0a1c9f96833554598b89a2feffe3f5a84dabc0;p=oweals%2Fgnunet.git regex: iterating over the initial states --- diff --git a/src/regex/regex.c b/src/regex/regex.c index 82949934d..77c90418c 100644 --- a/src/regex/regex.c +++ b/src/regex/regex.c @@ -32,7 +32,7 @@ /** * Constant for how many bits the initial string regex should have. */ -#define INITIAL_BITS 10 +#define INITIAL_BITS 8 /** @@ -2516,8 +2516,87 @@ int GNUNET_REGEX_check_proof (const char *proof, const struct GNUNET_HashCode *key) { struct GNUNET_HashCode key_check; + GNUNET_CRYPTO_hash (proof, strlen (proof), &key_check); - return (0 == GNUNET_CRYPTO_hash_cmp (key, &key_check)) ? GNUNET_OK : GNUNET_NO; + return (0 == + GNUNET_CRYPTO_hash_cmp (key, &key_check)) ? GNUNET_OK : GNUNET_NO; +} + +/** + * Recursive helper function for iterate_initial_edges. Will call iterator + * function for each initial state. + * + * @param max_len maximum length of the path in the graph. + * @param cur_len current length of the path already traversed. + * @param consumed_string string consumed by traversing the graph till this state. + * @param next_state next state in the graph that is reachable with 'label' transition. + * @param label label of the transition to the next state. + * @param iterator iterator function called for each edge. + * @param iterator_cls closure for the iterator function. + */ +static void +iterate_initial_edge (const unsigned int max_len, unsigned int cur_len, + char *consumed_string, + struct GNUNET_REGEX_State *next_state, const char label, + GNUNET_REGEX_KeyIterator iterator, void *iterator_cls) +{ + char *temp; + struct GNUNET_REGEX_Transition *t; + struct GNUNET_REGEX_Edge edge; + struct GNUNET_HashCode hash; + size_t constr_len; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "max_len: %u, cur_len: %u, consumed_string: %s\n", max_len, + cur_len, consumed_string); + + if (max_len == cur_len) + { + constr_len = strlen (consumed_string); + GNUNET_CRYPTO_hash (consumed_string, constr_len - 1, &hash); + GNUNET_asprintf (&temp, "%c", label); + edge.label = temp; + edge.destination = next_state->hash; + consumed_string[constr_len - 1] = '\0'; + iterator (iterator_cls, &hash, consumed_string, 0, 1, &edge); + GNUNET_free (temp); + + return; + } + else if (cur_len <= max_len) + { + cur_len++; + for (t = next_state->transitions_head; NULL != t; t = t->next) + { + if (NULL != consumed_string) + GNUNET_asprintf (&temp, "%s%c", consumed_string, t->label); + else + GNUNET_asprintf (&temp, "%c", t->label); + + iterate_initial_edge (max_len, cur_len, temp, t->to_state, t->label, + iterator, iterator_cls); + GNUNET_free (temp); + } + } +} + +/** + * Iterate over all initial edges that aren't actually part of the automaton. + * This is needed to find the initial states returned by + * GNUNET_REGEX_get_first_key. + * + * @param a the automaton for which the initial states should be computed. + * @param initial_len length of the initial state string. + * @param iterator iterator function called for each edge. + * @param iterator_cls closure for the iterator function. + */ +void +iterate_initial_edges (struct GNUNET_REGEX_Automaton *a, + const unsigned int initial_len, + GNUNET_REGEX_KeyIterator iterator, void *iterator_cls) +{ + iterate_initial_edge (initial_len + 1, 0, NULL, a->start, 0, iterator, + iterator_cls); } @@ -2569,5 +2648,6 @@ GNUNET_REGEX_iterate_all_edges (struct GNUNET_REGEX_Automaton *a, for (s = a->states_head; NULL != s; s = s->next) s->marked = GNUNET_NO; + iterate_initial_edges (a, INITIAL_BITS, iterator, iterator_cls); iterate_edge (a->start, iterator, iterator_cls); } diff --git a/src/regex/regex_graph.c b/src/regex/regex_graph.c index 5adecab62..b8eda8ec9 100644 --- a/src/regex/regex_graph.c +++ b/src/regex/regex_graph.c @@ -26,7 +26,7 @@ #include "gnunet_regex_lib.h" #include "regex_internal.h" -/** +/** * Context for graph creation. Passed as the cls to * GNUNET_REGEX_automaton_save_graph_step. */ @@ -77,7 +77,7 @@ scc_tarjan_strongconnect (unsigned int *scc_counter, if (NULL == w) continue; - + if (w->index < 0) { scc_tarjan_strongconnect (scc_counter, w, index, stack, stack_size); @@ -160,9 +160,10 @@ GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count, char *s_tran = NULL; char *name; char *to_name; - + if (GNUNET_YES == ctx->verbose) - GNUNET_asprintf (&name, "%i (%s)", s->proof_id, s->name); + GNUNET_asprintf (&name, "%i (%s) (%s) (%s)", s->proof_id, s->name, s->proof, + GNUNET_h2s (&s->hash)); else GNUNET_asprintf (&name, "%i", s->proof_id); @@ -174,7 +175,8 @@ GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count, } else { - GNUNET_asprintf (&s_acc, "\"%s\" [color=\"0.%i 0.8 0.95\"];\n", name, s->scc_id); + GNUNET_asprintf (&s_acc, "\"%s\" [color=\"0.%i 0.8 0.95\"];\n", name, + s->scc_id); } if (NULL == s_acc) @@ -197,10 +199,14 @@ GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count, } if (GNUNET_YES == ctx->verbose) - GNUNET_asprintf (&to_name, "%i (%s)", ctran->to_state->proof_id, ctran->to_state->name); + { + GNUNET_asprintf (&to_name, "%i (%s) (%s) (%s)", ctran->to_state->proof_id, + ctran->to_state->name, ctran->to_state->proof, + GNUNET_h2s (&ctran->to_state->hash)); + } else GNUNET_asprintf (&to_name, "%i", ctran->to_state->proof_id); - + if (ctran->label == 0) { GNUNET_asprintf (&s_tran, @@ -243,13 +249,12 @@ GNUNET_REGEX_automaton_save_graph_step (void *cls, unsigned int count, */ void GNUNET_REGEX_automaton_save_graph (struct GNUNET_REGEX_Automaton *a, - const char *filename, - int verbose) + const char *filename, int verbose) { char *start; char *end; struct GNUNET_REGEX_Graph_Context ctx; - + if (NULL == a) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not print NFA, was NULL!"); @@ -263,6 +268,7 @@ GNUNET_REGEX_automaton_save_graph (struct GNUNET_REGEX_Automaton *a, } ctx.filep = fopen (filename, "w"); + ctx.verbose = verbose; if (NULL == ctx.filep) {