146 lines
4.3 KiB
C++
146 lines
4.3 KiB
C++
/*
|
|
* Mr. 4th Dimention - Allen Webster
|
|
*
|
|
* 17.06.2019
|
|
*
|
|
* Routines for operating on the String_Match and String_Match_List types.
|
|
*
|
|
*/
|
|
|
|
// TOP
|
|
|
|
internal void
|
|
string_match_list_push(Arena *arena, String_Match_List *list,
|
|
Buffer_ID buffer, i32 string_id, String_Match_Flag flags, Range_i64 range){
|
|
String_Match *match = push_array(arena, String_Match, 1);
|
|
sll_queue_push(list->first, list->last, match);
|
|
list->count += 1;
|
|
match->buffer = buffer;
|
|
match->string_id = string_id;
|
|
match->flags = flags;
|
|
match->range = range;
|
|
}
|
|
|
|
internal void
|
|
string_match_list_push(Arena *arena, String_Match_List *list,
|
|
Buffer_ID buffer, i32 string_id, String_Match_Flag flags, i64 start, i64 length){
|
|
string_match_list_push(arena, list, buffer, string_id, flags,
|
|
make_range_i64(start, start + length));
|
|
}
|
|
|
|
internal String_Match_List
|
|
string_match_list_join(String_Match_List *a, String_Match_List *b){
|
|
String_Match_List list = *a;
|
|
block_zero_struct(a);
|
|
if (list.last != 0){
|
|
list.last->next = b->first;
|
|
if (b->last != 0){
|
|
list.last = b->last;
|
|
}
|
|
}
|
|
else{
|
|
list.first = b->first;
|
|
list.last = b->last;
|
|
}
|
|
list.count += b->count;
|
|
block_zero_struct(b);
|
|
return(list);
|
|
}
|
|
|
|
internal void
|
|
string_match_list_filter_flags(String_Match_List *list, String_Match_Flag must_have_flags, String_Match_Flag must_not_have_flags){
|
|
String_Match_List new_list = {};
|
|
if ((must_have_flags & must_not_have_flags) == 0){
|
|
for (String_Match *node = list->first, *next = 0;
|
|
node != 0;
|
|
node = next){
|
|
next = node->next;
|
|
if ((node->flags & must_have_flags) == must_have_flags && (node->flags & must_not_have_flags) == 0){
|
|
sll_queue_push(new_list.first, new_list.last, node);
|
|
new_list.count += 1;
|
|
}
|
|
}
|
|
}
|
|
*list = new_list;
|
|
}
|
|
|
|
internal void
|
|
string_match_list_filter_remove_buffer(String_Match_List *list, Buffer_ID buffer){
|
|
String_Match_List new_list = {};
|
|
for (String_Match *node = list->first, *next = 0;
|
|
node != 0;
|
|
node = next){
|
|
next = node->next;
|
|
if (node->buffer != buffer){
|
|
sll_queue_push(new_list.first, new_list.last, node);
|
|
new_list.count += 1;
|
|
}
|
|
}
|
|
*list = new_list;
|
|
}
|
|
|
|
internal void
|
|
string_match_list_filter_remove_buffer_predicate(Application_Links *app, String_Match_List *list, Buffer_Predicate *predicate){
|
|
String_Match_List new_list = {};
|
|
for (String_Match *node = list->first, *next = 0;
|
|
node != 0;
|
|
node = next){
|
|
next = node->next;
|
|
if (!predicate(app, node->buffer)){
|
|
sll_queue_push(new_list.first, new_list.last, node);
|
|
new_list.count += 1;
|
|
}
|
|
}
|
|
*list = new_list;
|
|
}
|
|
|
|
internal String_Match_List
|
|
string_match_list_merge_nearest(String_Match_List *a, String_Match_List *b, Range_i64 range){
|
|
String_Match_List list = {};
|
|
String_Match *node_a = a->first;
|
|
String_Match *node_b = b->first;
|
|
for (String_Match *next_a = node_a, *next_b = node_b;
|
|
node_a != 0 && node_b != 0;
|
|
node_a = next_a, node_b = next_b){
|
|
i64 dist_a = range_distance(node_a->range, range);
|
|
i64 dist_b = range_distance(node_b->range, range);
|
|
if (dist_a <= dist_b){
|
|
next_a = next_a->next;
|
|
sll_queue_push(list.first, list.last, node_a);
|
|
list.count += 1;
|
|
}
|
|
else{
|
|
next_b = next_b->next;
|
|
sll_queue_push(list.first, list.last, node_b);
|
|
list.count += 1;
|
|
}
|
|
}
|
|
Assert(node_a == 0 || node_b == 0);
|
|
// TODO(allen): this is dumb O(n) work that could be O(1)
|
|
String_Match *node = 0;
|
|
if (node_a != 0){
|
|
node = node_a;
|
|
}
|
|
else if (node_b != 0){
|
|
node = node_b;
|
|
}
|
|
for (String_Match *next = 0;
|
|
node != 0;
|
|
node = next){
|
|
next = node->next;
|
|
sll_queue_push(list.first, list.last, node);
|
|
list.count += 1;
|
|
}
|
|
block_zero_struct(a);
|
|
block_zero_struct(b);
|
|
return(list);
|
|
}
|
|
|
|
internal String_Match_List
|
|
string_match_list_merge_front_to_back(String_Match_List *a, String_Match_List *b){
|
|
return(string_match_list_merge_nearest(a, b, make_range_i64(0)));
|
|
}
|
|
|
|
// BOTTOM
|
|
|