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.
naka/src/comp.c

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