Make foreach_free public and fix a few bugs.

This commit is contained in:
Danila Fedorin 2017-02-14 19:10:44 -08:00
parent 97933c4ce9
commit 140b727cc7
3 changed files with 38 additions and 15 deletions

View File

@ -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. * @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); 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 #endif

View File

@ -16,7 +16,11 @@ enum liblex_result_e {
/** /**
* Represents an invalid pattern. * Represents an invalid pattern.
*/ */
LIBLEX_INVALID LIBLEX_INVALID,
/**
* Represents an unrecognized token.
*/
LIBLEX_UNRECOGNIZED
}; };
typedef enum liblex_result_e liblex_result; typedef enum liblex_result_e liblex_result;

View File

@ -1,7 +1,6 @@
#include "eval.h" #include "eval.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <pattern.h>
#include "pattern.h" #include "pattern.h"
#include "pairmap.h" #include "pairmap.h"
@ -34,11 +33,6 @@ liblex_result eval_config_add(eval_config* config, char* ptrn, int pattern_id){
return result; 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){ int _eval_config_foreach_free(void *data, va_list args){
pattern* ptrn = data; pattern* ptrn = data;
int result = pattern_free(ptrn) == LIBLEX_SUCCESS ? 0 : EVAL_FOREACH_MALLOC; 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; tmp = eval->set_current;
eval->set_current = eval->set_next; eval->set_current = eval->set_next;
eval->set_next = tmp; eval->set_next = tmp;
eval->index++; if(eval->matched){
eval->index++;
}
ht_free(eval->set_next); ht_free(eval->set_next);
pairmap_init_ht(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; match* current_match = data;
int* max_match_id = va_arg(args, int*); int* max_match_id = va_arg(args, int*);
match* fill_match = va_arg(args, match*); 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; *max_match_id = current_match->pattern;
memcpy(fill_match, current_match, sizeof(*current_match)); 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_current = &evl.set_a;
evl.set_next = &evl.set_b; evl.set_next = &evl.set_b;
ll_foreach(&config->states, NULL, compare_always, _eval_foreach_add_node, evl.set_current); result = foreach_errors[ll_foreach(&config->states, NULL, compare_always, _eval_foreach_add_node, evl.set_current)];
do { if(result == LIBLEX_SUCCESS){
_eval_step(&evl); do {
} while(evl.matched && *(evl.string)); _eval_step(&evl);
} while(evl.matched && *(evl.string));
}
if(evl.matches.tail){ if(result == LIBLEX_SUCCESS && evl.matches.tail){
int largest_id = -1; int largest_id = -1;
ll_foreach(&evl.matches, NULL, compare_always, _eval_foreach_find_match, &largest_id, mtch); ll_foreach(&evl.matches, NULL, compare_always, _eval_foreach_find_match, &largest_id, mtch);
} else { } else {
@ -184,7 +182,7 @@ liblex_result eval_word(char* string, int index, eval_config* config, match* mtc
mtch->pattern = -1; 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); ll_free(&evl.matches);
ht_free(&evl.set_a); ht_free(&evl.set_a);
ht_free(&evl.set_b); 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){ if(new_match->pattern < 0){
done = 1; done = 1;
free(new_match); free(new_match);
if(string[index]){
result = LIBLEX_UNRECOGNIZED;
}
} else { } else {
result = ll_append(matches, new_match) == LIBDS_SUCCESS ? LIBLEX_SUCCESS : LIBLEX_MALLOC; 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); } 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; return result;
} }
int eval_foreach_match_free(void *data, va_list args){
free(data);
return 0;
}