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.
*/
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

View File

@ -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;

View File

@ -1,7 +1,6 @@
#include "eval.h"
#include <stdlib.h>
#include <string.h>
#include <pattern.h>
#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;
}