display: Added format string generator function based on display flags.

TODO: Format string generator function uses a lot of ugly and unsafe hacks, rewrite it to do better bounds checking and more safe and efficient string concatenation.

Fortune for naka's current commit: Future blessing − 末吉
master
Avril 3 years ago
parent 1189d7fee8
commit fdbdf5a7d8
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -16,15 +16,20 @@ typedef enum display_kind {
#define X(n) AS(1lu << (n), usize)
typedef enum display_flags {
// Show the number (index) of they haystack matched
DISPF_SHOW_NUMBER = X(0),
DISPF_SHOW_LENGTH = X(1),
DISPF_SHOW_SLICE = X(2),
// Show the slice
DISPF_SHOW_SLICE = X(1),
// Show the length of the slice
DISPF_SHOW_LENGTH = X(2),
// Show failed matches
DISPF_SHOW_FAILURES = X(3),
} dispflags_t;
#define DISPLAY_FLAGS_DEFAULT (DISPF_SHOW_SLICE | DISPF_SHOW_NUMBER | DISPF_SHOW_FAILURES)
#undef X
typedef struct {
typedef struct {
bool matched;
slice_t cslice;
const void* base;
usize index;

@ -2,13 +2,36 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <macros.h>
#include <comp.h>
#include <display.h>
#define FLAGSET(f, flag) (( (f) & (flag) ) == (flag))
#define DFLAGSET(f, flagname) FLAGSET(f, DISPF_SHOW_ ## flagname)
//TODO: This probably won't work. Write wrappers for strncpy(), strncat() that return number of bytes written isntead of useless pointer that we already have.
static usize _display_get_fmt(dispflags_t flags, bool matched, usize _len, char str[pOUT _len])
{
register usize len = _len;
static const char* fmts[] = { "match: ", "%lu: ", SLICE_FORMAT, " (len %lu)", "failure: ", (const char*)NULL };
#define ADDSTR(s) do { debug_assert((s)); strncat(str, (s), len); w = strlen((s)); w = w > len ? len : w; ifU(len<=w) { str[len-1] = 0; return w; } len -= w; str += w; fw+=w; } while(0)
usize fw;
usize w = strlen(strncpy(str, matched ? fmts[0]
: DFLAGSET(flags, FAILURES) ? fmts[4]
: "", len)); if(len<=w || w == 0) { str[len-1] = 0; return 0; } len -= w; str += w; fw = w;
if(DFLAGSET(flags, NUMBER)) ADDSTR(fmts[1]);
if(DFLAGSET(flags, SLICE)) ADDSTR(fmts[2]);
if(DFLAGSET(flags, LENGTH)) ADDSTR(fmts[3]);
ADDSTR("\n");
TRACE("Output string written: %lu, (rlen %lu)", fw, len);
return fw;
}
static void _display_normal(FILE* output, dispin_t*pIN input, dispflags_t flags)
{
bool matched = input->matched;
slice_t cslice = input->cslice;
const void* base = input->base;
usize i = input->index;
@ -25,16 +48,16 @@ static void _display_normal(FILE* output, dispin_t*pIN input, dispflags_t flags)
#endif
INFO("Mapped region slice for %lu, pre-transform (at %p): " SLICE_FORMAT ", len: %lu", i+1, base, SLICE_FORMAT_ARGS(&cslice), cslice.len);
//TODO: Honour `flags`
IGNORE(flags);
fprintf(output, "match: %lu: %lu -> %lu\n", i+1, pos.start, pos.end);
//Honour `flags`
char fmt[200]; //TODO: Find the realistic max for this.
fmt[_display_get_fmt(flags, matched, 100, fmt)] = 0;
fprintf(output, fmt, i+1, pos.start, pos.end, pos.end-pos.start);
}
void display_result(FILE* output, dispin_t input, dispkind_t how, dispflags_t flags)
{
flags = flags ?: DISPLAY_FLAGS_DEFAULT;
output = output ?: stdout;
debug_assert(input);
TRACE("Outputting as %d to %p with flags 0x%08lx", (int)how, output, (usize)flags);
switch(how)

@ -178,11 +178,12 @@ inv_args:
{
slice_t cslice;
const void* base = current->mapping->origin;
bool matched = current->matched;
if(!comp_slice_of(&needle, current++, &cslice)) {
printf("fail: %lu\n", i+1);
} else {
TRACE("Displaying result %lu (" SLICE_FORMAT ") (base %p)", i, SLICE_FORMAT_ARGS(&cslice), base);
display_result(stdout, (dispin_t){ .base = base, .cslice = cslice, .index = i}, DISPK_NORMAL, 0);
display_result(stdout, (dispin_t){ .base = base, .cslice = cslice, .index = i, .matched = matched }, DISPK_NORMAL, 0);
}
}

Loading…
Cancel
Save