You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.3 KiB
90 lines
2.3 KiB
#define _GNU_SOURCE
|
|
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
|
|
#include <macros.h>
|
|
#include <ints.h>
|
|
#include <map.h>
|
|
|
|
#include <comp.h>
|
|
|
|
|
|
bool cmp_find(const map_t *pIN needle, const map_t *pIN haystack, usize *pOUT pos)
|
|
{
|
|
u8* start;
|
|
//TODO: Find sub-substring even if the full match fails
|
|
u8* substr = memmem(start = haystack->origin, haystack->len,
|
|
needle->origin, needle->len);
|
|
if(!substr) return false;
|
|
debug_assert(substr >= start);
|
|
*pos = (usize) (substr - start);
|
|
return true;
|
|
}
|
|
|
|
int cmp_find_many(const map_t *pIN needle, usize nhaystacks, usize sizes[pOUT nhaystacks], ...)
|
|
{
|
|
va_list v_haystacks;
|
|
va_start(v_haystacks, sizes);
|
|
|
|
const map_t* pINOUT haystack;
|
|
register int rval=-1;
|
|
for(usize i=0;i<nhaystacks;i++)
|
|
{
|
|
usize *pOUT size = sizes + i;
|
|
haystack = va_arg(v_haystacks, const map_t* pIN);
|
|
if(!haystack || !haystack->origin) FATAL("haystack %lu was null or its origin was null", i);
|
|
if(!cmp_find(needle, haystack, size)) {
|
|
rval = (int)i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
va_end(v_haystacks);
|
|
return rval;
|
|
}
|
|
|
|
comp_multires_t* comp_match_all(map_t *pIN needle, usize nh, map_t hs[pIN nh], bool abort_on_fail)
|
|
{
|
|
comp_multires_t* result = malloc(sizeof(comp_multires_t) + (sizeof(struct comp_single_result) * nh));
|
|
debug_assert(result);
|
|
|
|
result->all_matched = true;
|
|
result->idx_first_failure = -1;
|
|
result->num_results = nh;
|
|
|
|
|
|
usize i;
|
|
for(i =0;i<nh;i++)
|
|
{
|
|
usize start=0;
|
|
bool matched = cmp_find(needle, hs+i, &start);
|
|
struct comp_single_result res = {
|
|
.mapping = hs+i,
|
|
.matched = matched,
|
|
.slice_start = start,
|
|
};
|
|
TRACE("Result for %lu (%p): Matched: %s, slice start: %lu", i, hs+i, matched ? "yes" : "no", start);
|
|
result->aggr[i] = res;
|
|
if(!res.matched) {
|
|
WARN("Matching haystack %lu failed", i);
|
|
result->all_matched = false;
|
|
if(result->idx_first_failure < 0) {
|
|
INFO("First match failure is %lu", i);
|
|
result->idx_first_failure = (int)i;
|
|
}
|
|
if(abort_on_fail) {
|
|
result->num_results = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
INFO("Aggregate result for %lu / %lu haystack matches: Full passed: %s, first filaure: %d",
|
|
i, nh,
|
|
result->all_matched ? "yes" : "no",
|
|
result->idx_first_failure);
|
|
TRACE("Output result aggregate size: %lu (alloc: %p)", sizeof(comp_multires_t) + (sizeof(struct comp_single_result) * nh), result);
|
|
return result;
|
|
}
|