From fdbdf5a7d853fe4c0d701a59f29446bd6eb991d5 Mon Sep 17 00:00:00 2001 From: Avril Date: Tue, 13 Jul 2021 13:36:20 +0100 Subject: [PATCH] display: Added format string generator function based on display flags. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 − 末吉 --- include/display.h | 11 ++++++++--- src/display.c | 31 +++++++++++++++++++++++++++---- src/main.c | 3 ++- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/include/display.h b/include/display.h index 5271e77..b99e8dd 100644 --- a/include/display.h +++ b/include/display.h @@ -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; diff --git a/src/display.c b/src/display.c index ee81724..879f03d 100644 --- a/src/display.c +++ b/src/display.c @@ -2,13 +2,36 @@ #include #include +#include #include #include #include +#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) diff --git a/src/main.c b/src/main.c index 726546c..4018324 100644 --- a/src/main.c +++ b/src/main.c @@ -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); } }