diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-05-22 13:26:36 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-05-22 13:26:36 +0000 |
commit | bad29fd9a1cc3b1c7df7b992212568918c961b52 (patch) | |
tree | 692be9fda2a949f844690e360ce9d6d5f50f8916 /src/regex/regex_internal.c | |
parent | 7b636c9e74039f14b25e70d1050432d9782efef9 (diff) | |
download | gnunet-bad29fd9a1cc3b1c7df7b992212568918c961b52.tar.gz gnunet-bad29fd9a1cc3b1c7df7b992212568918c961b52.zip |
add logging and in particular checks to make sure no '.' wildcards are during initial transitions of the DFA
Diffstat (limited to 'src/regex/regex_internal.c')
-rw-r--r-- | src/regex/regex_internal.c | 224 |
1 files changed, 148 insertions, 76 deletions
diff --git a/src/regex/regex_internal.c b/src/regex/regex_internal.c index 56c6e74de..2dccd657f 100644 --- a/src/regex/regex_internal.c +++ b/src/regex/regex_internal.c | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | 32 | ||
33 | /** | 33 | /** |
34 | * Set this to GNUNET_YES to enable state naming. Used to debug NFA->DFA | 34 | * Set this to #GNUNET_YES to enable state naming. Used to debug NFA->DFA |
35 | * creation. Disabled by default for better performance. | 35 | * creation. Disabled by default for better performance. |
36 | */ | 36 | */ |
37 | #define REGEX_DEBUG_DFA GNUNET_NO | 37 | #define REGEX_DEBUG_DFA GNUNET_NO |
@@ -59,7 +59,7 @@ struct REGEX_INTERNAL_StateSet_MDLL | |||
59 | 59 | ||
60 | 60 | ||
61 | /** | 61 | /** |
62 | * Append state to the given StateSet ' | 62 | * Append state to the given StateSet. |
63 | * | 63 | * |
64 | * @param set set to be modified | 64 | * @param set set to be modified |
65 | * @param state state to be appended | 65 | * @param state state to be appended |
@@ -95,7 +95,7 @@ nullstrcmp (const char *str1, const char *str2) | |||
95 | 95 | ||
96 | 96 | ||
97 | /** | 97 | /** |
98 | * Adds a transition from one state to another on 'label'. Does not add | 98 | * Adds a transition from one state to another on @a label. Does not add |
99 | * duplicate states. | 99 | * duplicate states. |
100 | * | 100 | * |
101 | * @param ctx context | 101 | * @param ctx context |
@@ -105,7 +105,8 @@ nullstrcmp (const char *str1, const char *str2) | |||
105 | */ | 105 | */ |
106 | static void | 106 | static void |
107 | state_add_transition (struct REGEX_INTERNAL_Context *ctx, | 107 | state_add_transition (struct REGEX_INTERNAL_Context *ctx, |
108 | struct REGEX_INTERNAL_State *from_state, const char *label, | 108 | struct REGEX_INTERNAL_State *from_state, |
109 | const char *label, | ||
109 | struct REGEX_INTERNAL_State *to_state) | 110 | struct REGEX_INTERNAL_State *to_state) |
110 | { | 111 | { |
111 | struct REGEX_INTERNAL_Transition *t; | 112 | struct REGEX_INTERNAL_Transition *t; |
@@ -113,7 +114,8 @@ state_add_transition (struct REGEX_INTERNAL_Context *ctx, | |||
113 | 114 | ||
114 | if (NULL == from_state) | 115 | if (NULL == from_state) |
115 | { | 116 | { |
116 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not create Transition.\n"); | 117 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
118 | "Could not create Transition.\n"); | ||
117 | return; | 119 | return; |
118 | } | 120 | } |
119 | 121 | ||
@@ -196,16 +198,17 @@ state_compare (const void *a, const void *b) | |||
196 | 198 | ||
197 | 199 | ||
198 | /** | 200 | /** |
199 | * Get all edges leaving state 's'. | 201 | * Get all edges leaving state @a s. |
200 | * | 202 | * |
201 | * @param s state. | 203 | * @param s state. |
202 | * @param edges all edges leaving 's', expected to be allocated and have enough | 204 | * @param edges all edges leaving @a s, expected to be allocated and have enough |
203 | * space for s->transitions_count elements. | 205 | * space for `s->transitions_count` elements. |
204 | * | 206 | * |
205 | * @return number of edges. | 207 | * @return number of edges. |
206 | */ | 208 | */ |
207 | static unsigned int | 209 | static unsigned int |
208 | state_get_edges (struct REGEX_INTERNAL_State *s, struct REGEX_BLOCK_Edge *edges) | 210 | state_get_edges (struct REGEX_INTERNAL_State *s, |
211 | struct REGEX_BLOCK_Edge *edges) | ||
209 | { | 212 | { |
210 | struct REGEX_INTERNAL_Transition *t; | 213 | struct REGEX_INTERNAL_Transition *t; |
211 | unsigned int count; | 214 | unsigned int count; |
@@ -293,7 +296,7 @@ automaton_fragment_clear (struct REGEX_INTERNAL_Automaton *a) | |||
293 | 296 | ||
294 | 297 | ||
295 | /** | 298 | /** |
296 | * Frees the memory used by State 's' | 299 | * Frees the memory used by State @a s |
297 | * | 300 | * |
298 | * @param s state that should be destroyed | 301 | * @param s state that should be destroyed |
299 | */ | 302 | */ |
@@ -498,17 +501,17 @@ automaton_state_traverse (struct REGEX_INTERNAL_State *s, int *marks, | |||
498 | * @param start start state, pass a->start or NULL to traverse the whole automaton. | 501 | * @param start start state, pass a->start or NULL to traverse the whole automaton. |
499 | * @param check function that is checked before advancing on each transition | 502 | * @param check function that is checked before advancing on each transition |
500 | * in the DFS. | 503 | * in the DFS. |
501 | * @param check_cls closure for check. | 504 | * @param check_cls closure for @a check. |
502 | * @param action action to be performed on each state. | 505 | * @param action action to be performed on each state. |
503 | * @param action_cls closure for action | 506 | * @param action_cls closure for @a action |
504 | */ | 507 | */ |
505 | void | 508 | void |
506 | REGEX_INTERNAL_automaton_traverse (const struct REGEX_INTERNAL_Automaton *a, | 509 | REGEX_INTERNAL_automaton_traverse (const struct REGEX_INTERNAL_Automaton *a, |
507 | struct REGEX_INTERNAL_State *start, | 510 | struct REGEX_INTERNAL_State *start, |
508 | REGEX_INTERNAL_traverse_check check, | 511 | REGEX_INTERNAL_traverse_check check, |
509 | void *check_cls, | 512 | void *check_cls, |
510 | REGEX_INTERNAL_traverse_action action, | 513 | REGEX_INTERNAL_traverse_action action, |
511 | void *action_cls) | 514 | void *action_cls) |
512 | { | 515 | { |
513 | unsigned int count; | 516 | unsigned int count; |
514 | struct REGEX_INTERNAL_State *s; | 517 | struct REGEX_INTERNAL_State *s; |
@@ -532,8 +535,9 @@ REGEX_INTERNAL_automaton_traverse (const struct REGEX_INTERNAL_Automaton *a, | |||
532 | else | 535 | else |
533 | s = start; | 536 | s = start; |
534 | 537 | ||
535 | automaton_state_traverse (s, marks, &count, check, check_cls, action, | 538 | automaton_state_traverse (s, marks, &count, |
536 | action_cls); | 539 | check, check_cls, |
540 | action, action_cls); | ||
537 | } | 541 | } |
538 | 542 | ||
539 | 543 | ||
@@ -559,7 +563,7 @@ struct StringBuffer | |||
559 | size_t slen; | 563 | size_t slen; |
560 | 564 | ||
561 | /** | 565 | /** |
562 | * Number of bytes allocated for 'sbuf' | 566 | * Number of bytes allocated for @e sbuf |
563 | */ | 567 | */ |
564 | unsigned int blen; | 568 | unsigned int blen; |
565 | 569 | ||
@@ -570,7 +574,7 @@ struct StringBuffer | |||
570 | 574 | ||
571 | /** | 575 | /** |
572 | * If this entry is part of the last/current generation array, | 576 | * If this entry is part of the last/current generation array, |
573 | * this flag is GNUNET_YES if the last and current generation are | 577 | * this flag is #GNUNET_YES if the last and current generation are |
574 | * identical (and thus copying is unnecessary if the value didn't | 578 | * identical (and thus copying is unnecessary if the value didn't |
575 | * change). This is used in an optimization that improves | 579 | * change). This is used in an optimization that improves |
576 | * performance by about 1% --- if we use int16_t here. With just | 580 | * performance by about 1% --- if we use int16_t here. With just |
@@ -604,7 +608,7 @@ sb_nullstrcmp (const struct StringBuffer *s1, | |||
604 | return -1; | 608 | return -1; |
605 | return memcmp (s1->sbuf, s2->sbuf, s1->slen); | 609 | return memcmp (s1->sbuf, s2->sbuf, s1->slen); |
606 | } | 610 | } |
607 | 611 | ||
608 | 612 | ||
609 | /** | 613 | /** |
610 | * Compare two strings for equality. | 614 | * Compare two strings for equality. |
@@ -622,7 +626,7 @@ sb_strcmp (const struct StringBuffer *s1, | |||
622 | return -1; | 626 | return -1; |
623 | return memcmp (s1->sbuf, s2->sbuf, s1->slen); | 627 | return memcmp (s1->sbuf, s2->sbuf, s1->slen); |
624 | } | 628 | } |
625 | 629 | ||
626 | 630 | ||
627 | /** | 631 | /** |
628 | * Reallocate the buffer of 'ret' to fit 'nlen' characters; | 632 | * Reallocate the buffer of 'ret' to fit 'nlen' characters; |
@@ -669,7 +673,7 @@ sb_append (struct StringBuffer *ret, | |||
669 | sarg->slen); | 673 | sarg->slen); |
670 | ret->slen += sarg->slen; | 674 | ret->slen += sarg->slen; |
671 | } | 675 | } |
672 | 676 | ||
673 | 677 | ||
674 | /** | 678 | /** |
675 | * Append a C string. | 679 | * Append a C string. |
@@ -693,7 +697,7 @@ sb_append_cstr (struct StringBuffer *ret, | |||
693 | cstr_len); | 697 | cstr_len); |
694 | ret->slen += cstr_len; | 698 | ret->slen += cstr_len; |
695 | } | 699 | } |
696 | 700 | ||
697 | 701 | ||
698 | /** | 702 | /** |
699 | * Wrap a string buffer, that is, set ret to the format string | 703 | * Wrap a string buffer, that is, set ret to the format string |
@@ -854,7 +858,7 @@ sb_free (struct StringBuffer *sb) | |||
854 | static void | 858 | static void |
855 | sb_strdup (struct StringBuffer *out, | 859 | sb_strdup (struct StringBuffer *out, |
856 | const struct StringBuffer *in) | 860 | const struct StringBuffer *in) |
857 | 861 | ||
858 | { | 862 | { |
859 | out->null_flag = in->null_flag; | 863 | out->null_flag = in->null_flag; |
860 | if (GNUNET_YES == out->null_flag) | 864 | if (GNUNET_YES == out->null_flag) |
@@ -900,12 +904,12 @@ sb_strdup_cstr (struct StringBuffer *out, | |||
900 | 904 | ||
901 | 905 | ||
902 | /** | 906 | /** |
903 | * Check if the given string 'str' needs parentheses around it when | 907 | * Check if the given string @a str needs parentheses around it when |
904 | * using it to generate a regex. | 908 | * using it to generate a regex. |
905 | * | 909 | * |
906 | * @param str string | 910 | * @param str string |
907 | * | 911 | * |
908 | * @return GNUNET_YES if parentheses are needed, GNUNET_NO otherwise | 912 | * @return #GNUNET_YES if parentheses are needed, #GNUNET_NO otherwise |
909 | */ | 913 | */ |
910 | static int | 914 | static int |
911 | needs_parentheses (const struct StringBuffer *str) | 915 | needs_parentheses (const struct StringBuffer *str) |
@@ -949,9 +953,9 @@ needs_parentheses (const struct StringBuffer *str) | |||
949 | 953 | ||
950 | 954 | ||
951 | /** | 955 | /** |
952 | * Remove parentheses surrounding string 'str'. | 956 | * Remove parentheses surrounding string @a str. |
953 | * Example: "(a)" becomes "a", "(a|b)|(a|c)" stays the same. | 957 | * Example: "(a)" becomes "a", "(a|b)|(a|c)" stays the same. |
954 | * You need to GNUNET_free the returned string. | 958 | * You need to #GNUNET_free() the returned string. |
955 | * | 959 | * |
956 | * @param str string, modified to contain a | 960 | * @param str string, modified to contain a |
957 | * @return string without surrounding parentheses, string 'str' if no preceding | 961 | * @return string without surrounding parentheses, string 'str' if no preceding |
@@ -1799,8 +1803,10 @@ dfa_state_create (struct REGEX_INTERNAL_Context *ctx, | |||
1799 | for (i = 0; i < nfa_states->off; i++) | 1803 | for (i = 0; i < nfa_states->off; i++) |
1800 | { | 1804 | { |
1801 | cstate = nfa_states->states[i]; | 1805 | cstate = nfa_states->states[i]; |
1802 | GNUNET_snprintf (pos, pos - s->name + len, | 1806 | GNUNET_snprintf (pos, |
1803 | "%i,", cstate->id); | 1807 | pos - s->name + len, |
1808 | "%i,", | ||
1809 | cstate->id); | ||
1804 | pos += strlen (pos); | 1810 | pos += strlen (pos); |
1805 | 1811 | ||
1806 | /* Add a transition for each distinct label to NULL state */ | 1812 | /* Add a transition for each distinct label to NULL state */ |
@@ -1867,16 +1873,18 @@ dfa_move (struct REGEX_INTERNAL_State **s, const char *str) | |||
1867 | 1873 | ||
1868 | 1874 | ||
1869 | /** | 1875 | /** |
1870 | * Set the given state 'marked' to GNUNET_YES. Used by the | 1876 | * Set the given state 'marked' to #GNUNET_YES. Used by the |
1871 | * 'dfa_remove_unreachable_states' function to detect unreachable states in the | 1877 | * #dfa_remove_unreachable_states() function to detect unreachable states in the |
1872 | * automaton. | 1878 | * automaton. |
1873 | * | 1879 | * |
1874 | * @param cls closure, not used. | 1880 | * @param cls closure, not used. |
1875 | * @param count count, not used. | 1881 | * @param count count, not used. |
1876 | * @param s state where the marked attribute will be set to GNUNET_YES. | 1882 | * @param s state where the marked attribute will be set to #GNUNET_YES. |
1877 | */ | 1883 | */ |
1878 | static void | 1884 | static void |
1879 | mark_states (void *cls, const unsigned int count, struct REGEX_INTERNAL_State *s) | 1885 | mark_states (void *cls, |
1886 | const unsigned int count, | ||
1887 | struct REGEX_INTERNAL_State *s) | ||
1880 | { | 1888 | { |
1881 | s->marked = GNUNET_YES; | 1889 | s->marked = GNUNET_YES; |
1882 | } | 1890 | } |
@@ -1958,7 +1966,7 @@ dfa_remove_dead_states (struct REGEX_INTERNAL_Automaton *a) | |||
1958 | * | 1966 | * |
1959 | * @param ctx context | 1967 | * @param ctx context |
1960 | * @param a DFA automaton | 1968 | * @param a DFA automaton |
1961 | * @return GNUNET_OK on success | 1969 | * @return #GNUNET_OK on success |
1962 | */ | 1970 | */ |
1963 | static int | 1971 | static int |
1964 | dfa_merge_nondistinguishable_states (struct REGEX_INTERNAL_Context *ctx, | 1972 | dfa_merge_nondistinguishable_states (struct REGEX_INTERNAL_Context *ctx, |
@@ -3115,10 +3123,11 @@ REGEX_INTERNAL_automaton_destroy (struct REGEX_INTERNAL_Automaton *a) | |||
3115 | * @param a automaton, type must be DFA | 3123 | * @param a automaton, type must be DFA |
3116 | * @param string string that should be evaluated | 3124 | * @param string string that should be evaluated |
3117 | * | 3125 | * |
3118 | * @return 0 if string matches, non 0 otherwise | 3126 | * @return 0 if string matches, non-0 otherwise |
3119 | */ | 3127 | */ |
3120 | static int | 3128 | static int |
3121 | evaluate_dfa (struct REGEX_INTERNAL_Automaton *a, const char *string) | 3129 | evaluate_dfa (struct REGEX_INTERNAL_Automaton *a, |
3130 | const char *string) | ||
3122 | { | 3131 | { |
3123 | const char *strp; | 3132 | const char *strp; |
3124 | struct REGEX_INTERNAL_State *s; | 3133 | struct REGEX_INTERNAL_State *s; |
@@ -3157,11 +3166,11 @@ evaluate_dfa (struct REGEX_INTERNAL_Automaton *a, const char *string) | |||
3157 | * | 3166 | * |
3158 | * @param a automaton, type must be NFA | 3167 | * @param a automaton, type must be NFA |
3159 | * @param string string that should be evaluated | 3168 | * @param string string that should be evaluated |
3160 | * | 3169 | * @return 0 if string matches, non-0 otherwise |
3161 | * @return 0 if string matches, non 0 otherwise | ||
3162 | */ | 3170 | */ |
3163 | static int | 3171 | static int |
3164 | evaluate_nfa (struct REGEX_INTERNAL_Automaton *a, const char *string) | 3172 | evaluate_nfa (struct REGEX_INTERNAL_Automaton *a, |
3173 | const char *string) | ||
3165 | { | 3174 | { |
3166 | const char *strp; | 3175 | const char *strp; |
3167 | char str[2]; | 3176 | char str[2]; |
@@ -3215,15 +3224,15 @@ evaluate_nfa (struct REGEX_INTERNAL_Automaton *a, const char *string) | |||
3215 | 3224 | ||
3216 | 3225 | ||
3217 | /** | 3226 | /** |
3218 | * Evaluates the given 'string' against the given compiled regex | 3227 | * Evaluates the given @a string against the given compiled regex @a a |
3219 | * | 3228 | * |
3220 | * @param a automaton | 3229 | * @param a automaton |
3221 | * @param string string to check | 3230 | * @param string string to check |
3222 | * | 3231 | * @return 0 if string matches, non-0 otherwise |
3223 | * @return 0 if string matches, non 0 otherwise | ||
3224 | */ | 3232 | */ |
3225 | int | 3233 | int |
3226 | REGEX_INTERNAL_eval (struct REGEX_INTERNAL_Automaton *a, const char *string) | 3234 | REGEX_INTERNAL_eval (struct REGEX_INTERNAL_Automaton *a, |
3235 | const char *string) | ||
3227 | { | 3236 | { |
3228 | int result; | 3237 | int result; |
3229 | 3238 | ||
@@ -3292,19 +3301,19 @@ REGEX_INTERNAL_get_transition_count (struct REGEX_INTERNAL_Automaton *a) | |||
3292 | 3301 | ||
3293 | 3302 | ||
3294 | /** | 3303 | /** |
3295 | * Get the first key for the given 'input_string'. This hashes the first x bits | 3304 | * Get the first key for the given @a input_string. This hashes the first x bits |
3296 | * of the 'input_string'. | 3305 | * of the @a input_string. |
3297 | * | 3306 | * |
3298 | * @param input_string string. | 3307 | * @param input_string string. |
3299 | * @param string_len length of the 'input_string'. | 3308 | * @param string_len length of the @a input_string. |
3300 | * @param key pointer to where to write the hash code. | 3309 | * @param key pointer to where to write the hash code. |
3301 | * | 3310 | * @return number of bits of @a input_string that have been consumed |
3302 | * @return number of bits of 'input_string' that have been consumed | ||
3303 | * to construct the key | 3311 | * to construct the key |
3304 | */ | 3312 | */ |
3305 | size_t | 3313 | size_t |
3306 | REGEX_INTERNAL_get_first_key (const char *input_string, size_t string_len, | 3314 | REGEX_INTERNAL_get_first_key (const char *input_string, |
3307 | struct GNUNET_HashCode * key) | 3315 | size_t string_len, |
3316 | struct GNUNET_HashCode *key) | ||
3308 | { | 3317 | { |
3309 | size_t size; | 3318 | size_t size; |
3310 | 3319 | ||
@@ -3330,12 +3339,15 @@ REGEX_INTERNAL_get_first_key (const char *input_string, size_t string_len, | |||
3330 | * @param consumed_string string consumed by traversing the graph till this state. | 3339 | * @param consumed_string string consumed by traversing the graph till this state. |
3331 | * @param state current state of the automaton. | 3340 | * @param state current state of the automaton. |
3332 | * @param iterator iterator function called for each edge. | 3341 | * @param iterator iterator function called for each edge. |
3333 | * @param iterator_cls closure for the iterator function. | 3342 | * @param iterator_cls closure for the @a iterator function. |
3334 | */ | 3343 | */ |
3335 | static void | 3344 | static void |
3336 | iterate_initial_edge (const unsigned int min_len, const unsigned int max_len, | 3345 | iterate_initial_edge (unsigned int min_len, |
3337 | char *consumed_string, struct REGEX_INTERNAL_State *state, | 3346 | unsigned int max_len, |
3338 | REGEX_INTERNAL_KeyIterator iterator, void *iterator_cls) | 3347 | char *consumed_string, |
3348 | struct REGEX_INTERNAL_State *state, | ||
3349 | REGEX_INTERNAL_KeyIterator iterator, | ||
3350 | void *iterator_cls) | ||
3339 | { | 3351 | { |
3340 | char *temp; | 3352 | char *temp; |
3341 | struct REGEX_INTERNAL_Transition *t; | 3353 | struct REGEX_INTERNAL_Transition *t; |
@@ -3351,21 +3363,36 @@ iterate_initial_edge (const unsigned int min_len, const unsigned int max_len, | |||
3351 | else | 3363 | else |
3352 | cur_len = 0; | 3364 | cur_len = 0; |
3353 | 3365 | ||
3354 | if ((cur_len >= min_len || GNUNET_YES == state->accepting) && cur_len > 0 && | 3366 | if ( ( (cur_len >= min_len) || |
3355 | NULL != consumed_string) | 3367 | (GNUNET_YES == state->accepting) ) && |
3368 | (cur_len > 0) && | ||
3369 | (NULL != consumed_string) ) | ||
3356 | { | 3370 | { |
3357 | if (cur_len <= max_len) | 3371 | if (cur_len <= max_len) |
3358 | { | 3372 | { |
3359 | if (state->proof != NULL && 0 != strcmp (consumed_string, state->proof)) | 3373 | if ( (NULL != state->proof) && |
3374 | (0 != strcmp (consumed_string, | ||
3375 | state->proof)) ) | ||
3360 | { | 3376 | { |
3361 | (void) state_get_edges (state, edges); | 3377 | (void) state_get_edges (state, edges); |
3362 | GNUNET_CRYPTO_hash (consumed_string, strlen (consumed_string), &hash); | 3378 | GNUNET_CRYPTO_hash (consumed_string, |
3363 | iterator (iterator_cls, &hash, consumed_string, state->accepting, | 3379 | strlen (consumed_string), |
3380 | &hash); | ||
3381 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3382 | "Start state for string `%s' is %s\n", | ||
3383 | consumed_string, | ||
3384 | GNUNET_h2s (&hash)); | ||
3385 | iterator (iterator_cls, | ||
3386 | &hash, | ||
3387 | consumed_string, | ||
3388 | state->accepting, | ||
3364 | num_edges, edges); | 3389 | num_edges, edges); |
3365 | } | 3390 | } |
3366 | 3391 | ||
3367 | if (GNUNET_YES == state->accepting && cur_len > 1 && | 3392 | if ( (GNUNET_YES == state->accepting) && |
3368 | state->transition_count < 1 && cur_len < max_len) | 3393 | (cur_len > 1) && |
3394 | (state->transition_count < 1) && | ||
3395 | (cur_len < max_len) ) | ||
3369 | { | 3396 | { |
3370 | /* Special case for regex consisting of just a string that is shorter than | 3397 | /* Special case for regex consisting of just a string that is shorter than |
3371 | * max_len */ | 3398 | * max_len */ |
@@ -3373,8 +3400,18 @@ iterate_initial_edge (const unsigned int min_len, const unsigned int max_len, | |||
3373 | edge[0].destination = state->hash; | 3400 | edge[0].destination = state->hash; |
3374 | temp = GNUNET_strdup (consumed_string); | 3401 | temp = GNUNET_strdup (consumed_string); |
3375 | temp[cur_len - 1] = '\0'; | 3402 | temp[cur_len - 1] = '\0'; |
3376 | GNUNET_CRYPTO_hash (temp, cur_len - 1, &hash_new); | 3403 | GNUNET_CRYPTO_hash (temp, |
3377 | iterator (iterator_cls, &hash_new, temp, GNUNET_NO, 1, edge); | 3404 | cur_len - 1, |
3405 | &hash_new); | ||
3406 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3407 | "Start state for short string `%s' is %s\n", | ||
3408 | temp, | ||
3409 | GNUNET_h2s (&hash_new)); | ||
3410 | iterator (iterator_cls, | ||
3411 | &hash_new, | ||
3412 | temp, | ||
3413 | GNUNET_NO, 1, | ||
3414 | edge); | ||
3378 | GNUNET_free (temp); | 3415 | GNUNET_free (temp); |
3379 | } | 3416 | } |
3380 | } | 3417 | } |
@@ -3386,7 +3423,17 @@ iterate_initial_edge (const unsigned int min_len, const unsigned int max_len, | |||
3386 | temp = GNUNET_strdup (consumed_string); | 3423 | temp = GNUNET_strdup (consumed_string); |
3387 | temp[max_len] = '\0'; | 3424 | temp[max_len] = '\0'; |
3388 | GNUNET_CRYPTO_hash (temp, max_len, &hash); | 3425 | GNUNET_CRYPTO_hash (temp, max_len, &hash); |
3389 | iterator (iterator_cls, &hash, temp, GNUNET_NO, 1, edge); | 3426 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3427 | "Start state at split edge `%s'-`%s` is %s\n", | ||
3428 | temp, | ||
3429 | edge[0].label, | ||
3430 | GNUNET_h2s (&hash_new)); | ||
3431 | iterator (iterator_cls, | ||
3432 | &hash, | ||
3433 | temp, | ||
3434 | GNUNET_NO, | ||
3435 | 1, | ||
3436 | edge); | ||
3390 | GNUNET_free (temp); | 3437 | GNUNET_free (temp); |
3391 | } | 3438 | } |
3392 | } | 3439 | } |
@@ -3395,12 +3442,27 @@ iterate_initial_edge (const unsigned int min_len, const unsigned int max_len, | |||
3395 | { | 3442 | { |
3396 | for (t = state->transitions_head; NULL != t; t = t->next) | 3443 | for (t = state->transitions_head; NULL != t; t = t->next) |
3397 | { | 3444 | { |
3445 | if (NULL != strchr (t->label, | ||
3446 | (int) '.')) | ||
3447 | { | ||
3448 | /* Wildcards not allowed during starting states */ | ||
3449 | GNUNET_break (0); | ||
3450 | continue; | ||
3451 | } | ||
3398 | if (NULL != consumed_string) | 3452 | if (NULL != consumed_string) |
3399 | GNUNET_asprintf (&temp, "%s%s", consumed_string, t->label); | 3453 | GNUNET_asprintf (&temp, |
3454 | "%s%s", | ||
3455 | consumed_string, | ||
3456 | t->label); | ||
3400 | else | 3457 | else |
3401 | GNUNET_asprintf (&temp, "%s", t->label); | 3458 | GNUNET_asprintf (&temp, |
3402 | 3459 | "%s", | |
3403 | iterate_initial_edge (min_len, max_len, temp, t->to_state, iterator, | 3460 | t->label); |
3461 | iterate_initial_edge (min_len, | ||
3462 | max_len, | ||
3463 | temp, | ||
3464 | t->to_state, | ||
3465 | iterator, | ||
3404 | iterator_cls); | 3466 | iterator_cls); |
3405 | GNUNET_free (temp); | 3467 | GNUNET_free (temp); |
3406 | } | 3468 | } |
@@ -3423,6 +3485,14 @@ REGEX_INTERNAL_iterate_all_edges (struct REGEX_INTERNAL_Automaton *a, | |||
3423 | { | 3485 | { |
3424 | struct REGEX_INTERNAL_State *s; | 3486 | struct REGEX_INTERNAL_State *s; |
3425 | 3487 | ||
3488 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3489 | "Iterating over starting edges\n"); | ||
3490 | iterate_initial_edge (GNUNET_REGEX_INITIAL_BYTES, | ||
3491 | GNUNET_REGEX_INITIAL_BYTES, | ||
3492 | NULL, a->start, | ||
3493 | iterator, iterator_cls); | ||
3494 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3495 | "Iterating over DFA edges\n"); | ||
3426 | for (s = a->states_head; NULL != s; s = s->next) | 3496 | for (s = a->states_head; NULL != s; s = s->next) |
3427 | { | 3497 | { |
3428 | struct REGEX_BLOCK_Edge edges[s->transition_count]; | 3498 | struct REGEX_BLOCK_Edge edges[s->transition_count]; |
@@ -3431,18 +3501,20 @@ REGEX_INTERNAL_iterate_all_edges (struct REGEX_INTERNAL_Automaton *a, | |||
3431 | num_edges = state_get_edges (s, edges); | 3501 | num_edges = state_get_edges (s, edges); |
3432 | if ( ( (NULL != s->proof) && | 3502 | if ( ( (NULL != s->proof) && |
3433 | (0 < strlen (s->proof)) ) || s->accepting) | 3503 | (0 < strlen (s->proof)) ) || s->accepting) |
3504 | { | ||
3505 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
3506 | "Creating DFA edges at `%s' under key %s\n", | ||
3507 | s->proof, | ||
3508 | GNUNET_h2s (&s->hash)); | ||
3434 | iterator (iterator_cls, &s->hash, s->proof, | 3509 | iterator (iterator_cls, &s->hash, s->proof, |
3435 | s->accepting, | 3510 | s->accepting, |
3436 | num_edges, edges); | 3511 | num_edges, edges); |
3512 | } | ||
3437 | s->marked = GNUNET_NO; | 3513 | s->marked = GNUNET_NO; |
3438 | } | 3514 | } |
3439 | |||
3440 | iterate_initial_edge (GNUNET_REGEX_INITIAL_BYTES, | ||
3441 | GNUNET_REGEX_INITIAL_BYTES, | ||
3442 | NULL, a->start, | ||
3443 | iterator, iterator_cls); | ||
3444 | } | 3515 | } |
3445 | 3516 | ||
3517 | |||
3446 | /** | 3518 | /** |
3447 | * Struct to hold all the relevant state information in the HashMap. | 3519 | * Struct to hold all the relevant state information in the HashMap. |
3448 | * | 3520 | * |