diff --git a/include/eval.h b/include/eval.h index a5e987b..2a4d6b6 100644 --- a/include/eval.h +++ b/include/eval.h @@ -115,5 +115,14 @@ liblex_result eval_word(char* string, int index, eval_config* config, match* mat * @return LIBLEX_SUCCESS if all goes well, or LIBLEX_MALLOC if there was an allocation failure. */ liblex_result eval_all(char* string, int index, eval_config* config, ll* matches); +/** + * Function intended to be passed to "foreach" calls in libds. + * Since eval_all creates a lot of matches and puts them all in a linked list, + * this function takes care of freeing the matches. + * @param data the match being freed + * @param args unused + * @return always 0. + */ +int eval_foreach_match_free(void *data, va_list args); #endif diff --git a/include/liblex.h b/include/liblex.h index 63ee7ba..1e09e86 100644 --- a/include/liblex.h +++ b/include/liblex.h @@ -16,7 +16,11 @@ enum liblex_result_e { /** * Represents an invalid pattern. */ - LIBLEX_INVALID + LIBLEX_INVALID, + /** + * Represents an unrecognized token. + */ + LIBLEX_UNRECOGNIZED }; typedef enum liblex_result_e liblex_result; diff --git a/src/eval.c b/src/eval.c index 4685281..fa61eb3 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1,7 +1,6 @@ #include "eval.h" #include #include -#include #include "pattern.h" #include "pairmap.h" @@ -34,11 +33,6 @@ liblex_result eval_config_add(eval_config* config, char* ptrn, int pattern_id){ return result; } -int _eval_foreach_match_free(void *data, va_list args) { - free(data); - return 0; -} - int _eval_config_foreach_free(void *data, va_list args){ pattern* ptrn = data; int result = pattern_free(ptrn) == LIBLEX_SUCCESS ? 0 : EVAL_FOREACH_MALLOC; @@ -140,7 +134,9 @@ liblex_result _eval_step(eval *eval){ tmp = eval->set_current; eval->set_current = eval->set_next; eval->set_next = tmp; - eval->index++; + if(eval->matched){ + eval->index++; + } ht_free(eval->set_next); pairmap_init_ht(eval->set_next); @@ -151,7 +147,7 @@ int _eval_foreach_find_match(void *data, va_list args){ match* current_match = data; int* max_match_id = va_arg(args, int*); match* fill_match = va_arg(args, match*); - if(*max_match_id < current_match->pattern){ + if(*max_match_id < current_match->pattern || current_match->to > fill_match->to){ *max_match_id = current_match->pattern; memcpy(fill_match, current_match, sizeof(*current_match)); } @@ -170,12 +166,14 @@ liblex_result eval_word(char* string, int index, eval_config* config, match* mtc evl.set_current = &evl.set_a; evl.set_next = &evl.set_b; - ll_foreach(&config->states, NULL, compare_always, _eval_foreach_add_node, evl.set_current); - do { - _eval_step(&evl); - } while(evl.matched && *(evl.string)); + result = foreach_errors[ll_foreach(&config->states, NULL, compare_always, _eval_foreach_add_node, evl.set_current)]; + if(result == LIBLEX_SUCCESS){ + do { + _eval_step(&evl); + } while(evl.matched && *(evl.string)); + } - if(evl.matches.tail){ + if(result == LIBLEX_SUCCESS && evl.matches.tail){ int largest_id = -1; ll_foreach(&evl.matches, NULL, compare_always, _eval_foreach_find_match, &largest_id, mtch); } else { @@ -184,7 +182,7 @@ liblex_result eval_word(char* string, int index, eval_config* config, match* mtc mtch->pattern = -1; } - ll_foreach(&evl.matches, NULL, compare_always, _eval_foreach_match_free); + ll_foreach(&evl.matches, NULL, compare_always, eval_foreach_match_free); ll_free(&evl.matches); ht_free(&evl.set_a); ht_free(&evl.set_b); @@ -204,6 +202,9 @@ liblex_result eval_all(char* string, int index, eval_config* config, ll* matches if(new_match->pattern < 0){ done = 1; free(new_match); + if(string[index]){ + result = LIBLEX_UNRECOGNIZED; + } } else { result = ll_append(matches, new_match) == LIBDS_SUCCESS ? LIBLEX_SUCCESS : LIBLEX_MALLOC; } @@ -216,5 +217,14 @@ liblex_result eval_all(char* string, int index, eval_config* config, ll* matches } } while (result == LIBLEX_SUCCESS && done == 0); + if(result != LIBLEX_SUCCESS){ + ll_foreach(matches, NULL, compare_always, eval_foreach_match_free); + ll_clear(matches); + } + return result; } +int eval_foreach_match_free(void *data, va_list args){ + free(data); + return 0; +}