183 lines
5.7 KiB
C
183 lines
5.7 KiB
C
#include "libregex.h"#include "libregex.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "ll.h"
|
|
|
|
libregex_result _regex_node_create_clear(regex_node** node){
|
|
libregex_result result = LIBREGEX_SUCCESS;
|
|
*node = malloc(sizeof(**node));
|
|
if(*node){
|
|
regex_node_clear(*node);
|
|
} else {
|
|
result = LIBREGEX_MALLOC;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
libregex_result _regex_node_create_value(regex_node** node, char value, regex_node* next){
|
|
libregex_result result = _regex_node_create_clear(node);
|
|
if(result == LIBREGEX_SUCCESS){
|
|
(*node)->type = REGEX_VALUE;
|
|
(*node)->data_u.value_s.value = value;
|
|
(*node)->data_u.value_s.next = next;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
libregex_result _regex_node_create_range(regex_node** node, char from, char to, regex_node* next){
|
|
libregex_result result = _regex_node_create_clear(node);
|
|
if(result == LIBREGEX_SUCCESS){
|
|
(*node)->type = REGEX_RANGE;
|
|
(*node)->data_u.range_s.from = from;
|
|
(*node)->data_u.range_s.to = to;
|
|
(*node)->data_u.range_s.next = next;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
libregex_result _regex_node_create_any(regex_node** node, regex_node* next){
|
|
libregex_result result = _regex_node_create_clear(node);
|
|
if(result == LIBREGEX_SUCCESS){
|
|
(*node)->type = REGEX_ANY;
|
|
(*node)->data_u.any_s.next = next;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
libregex_result _regex_node_create_connect(regex_node** node, regex_node* next){
|
|
libregex_result result = _regex_node_create_clear(node);
|
|
if(result == LIBREGEX_SUCCESS){
|
|
(*node)->type = REGEX_CONNECT;
|
|
(*node)->data_u.connect_s.next = next;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
libregex_result _regex_node_create_fork(regex_node** node, regex_node* left, regex_node* right){
|
|
libregex_result result = _regex_node_create_clear(node);
|
|
if(result == LIBREGEX_SUCCESS){
|
|
(*node)->type = REGEX_FORK;
|
|
(*node)->data_u.fork_s.left = left;
|
|
(*node)->data_u.fork_s.right = right;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
libregex_result _regex_node_create_group(regex_node** open, regex_node** close, int group_id){
|
|
libregex_result result = _regex_node_create_clear(open);
|
|
if(result == LIBREGEX_SUCCESS){
|
|
result = _regex_node_create_clear(close);
|
|
}
|
|
if(result == LIBREGEX_SUCCESS){
|
|
(*open)->type = (*close)->type = REGEX_GROUP;
|
|
(*open)->data_u.group_s.id = (*close)->data_u.group_s.id = group_id;
|
|
(*open)->data_u.group_s.other = (*close);
|
|
(*close)->data_u.group_s.other = (*open);
|
|
|
|
(*open)->data_u.group_s.open = 1;
|
|
} else {
|
|
free(*open);
|
|
free(*close);
|
|
*open = *close = NULL;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
libregex_result _regex_chain_create(regex_chain** new_chain, regex_node* head, regex_node* tail){
|
|
libregex_result result = LIBREGEX_MALLOC;
|
|
*new_chain = malloc(sizeof(**new_chain));
|
|
if(*new_chain){
|
|
result = LIBREGEX_SUCCESS;
|
|
(*new_chain)->head = head;
|
|
(*new_chain)->tail = tail;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
regex_node** _regex_node_get_next(regex_node* node){
|
|
regex_node** to_return = NULL;
|
|
if(node->type == REGEX_CONNECT){
|
|
to_return = &node->data_u.connect_s.next;
|
|
} else if(node->type == REGEX_VALUE){
|
|
to_return = &node->data_u.value_s.next;
|
|
} else if(node->type == REGEX_RANGE){
|
|
to_return = &node->data_u.range_s.next;
|
|
} else if(node->type == REGEX_ANY){
|
|
to_return = &node->data_u.any_s.next;
|
|
} else if(node->type == REGEX_GROUP) {
|
|
to_return = &node->data_u.group_s.next;
|
|
}
|
|
return to_return;
|
|
}
|
|
|
|
void _regex_node_append_node(regex_node* append_to, regex_node* to_append){
|
|
regex_node** next = _regex_node_get_next(append_to);
|
|
if(next){
|
|
*next = to_append;
|
|
}
|
|
}
|
|
|
|
void _regex_chain_append_node(regex_chain* append_to, regex_node* to_append){
|
|
if(append_to && to_append){
|
|
regex_node** to_set = append_to->head ? _regex_node_get_next(append_to->tail) : &append_to->head;
|
|
if(to_set) {
|
|
*to_set = append_to->tail = to_append;
|
|
}
|
|
}
|
|
}
|
|
|
|
void _regex_chain_prepend_node(regex_chain* prepend_to, regex_node* to_prepend){
|
|
if(prepend_to && to_prepend){
|
|
regex_node** next = _regex_node_get_next(to_prepend);
|
|
if(next){
|
|
*next = prepend_to->head;
|
|
prepend_to->head = to_prepend;
|
|
if(prepend_to->tail == NULL){
|
|
prepend_to->tail = to_prepend;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void _regex_chain_append_chain(regex_chain* append_to, regex_chain* to_append){
|
|
if(append_to && to_append){
|
|
_regex_chain_append_node(append_to, to_append->head);
|
|
if(to_append->tail) {
|
|
append_to->tail = to_append->tail;
|
|
}
|
|
}
|
|
}
|
|
|
|
libregex_result _regex_find_all(regex_node* node, ll* append_to, int tag_with){
|
|
libregex_result result = LIBREGEX_SUCCESS;
|
|
if(node && node->list_id != tag_with){
|
|
node->list_id = tag_with;
|
|
if(node->type == REGEX_VALUE){
|
|
result = _regex_find_all(node->data_u.value_s.next, append_to, tag_with);
|
|
} else if(node->type == REGEX_RANGE){
|
|
result = _regex_find_all(node->data_u.range_s.next, append_to, tag_with);
|
|
} else if(node->type == REGEX_ANY){
|
|
result = _regex_find_all(node->data_u.any_s.next, append_to, tag_with);
|
|
} else if(node->type == REGEX_GROUP){
|
|
result = _regex_find_all(node->data_u.group_s.next, append_to, tag_with);
|
|
} else if(node->type == REGEX_CONNECT){
|
|
result = _regex_find_all(node->data_u.connect_s.next, append_to, tag_with);
|
|
} else if(node->type == REGEX_FORK){
|
|
result = _regex_find_all(node->data_u.fork_s.left, append_to, tag_with);
|
|
if(result == LIBREGEX_SUCCESS){
|
|
result = _regex_find_all(node->data_u.fork_s.right, append_to, tag_with);
|
|
}
|
|
}
|
|
if(result == LIBREGEX_SUCCESS){
|
|
result = (ll_append(append_to, node) == LIBDS_SUCCESS) ? LIBREGEX_SUCCESS : LIBREGEX_MALLOC;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void regex_node_clear(regex_node* node){
|
|
node->type = REGEX_CLEAR;
|
|
node->list_id = -1;
|
|
memset(&node->data_u, 0, sizeof(node->data_u));
|
|
}
|