//! Displaying match data
# 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 ;
# undef ADDSTR
}
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 ;
# ifdef _DEBUG_MANCALC_OFFSETS
struct {
usize start , end ;
} pos = {
. start = AS ( cslice . ptr - base , usize ) ,
} ;
pos . end = pos . start + cslice . len ;
# else
let pos = slice_sted ( ( slice_t [ ] ) { SLICE ( AS ( cslice . ptr - base , usize ) , cslice . len ) } ) ;
# endif
INFO ( " Mapped region slice for %lu, pre-transform (at %p): " SLICE_FORMAT " , len: %lu " , i + 1 , base , SLICE_FORMAT_ARGS ( & cslice ) , cslice . len ) ;
//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 ;
TRACE ( " Outputting as %d to %p with flags 0x%08lx " , ( int ) how , output , ( usize ) flags ) ;
switch ( how )
{
case DISPK_NORMAL :
_display_normal ( output , & input , flags ) ;
break ;
case DISPK_CSV :
case DISPK_BINARY :
case DISPK_INI :
TODO ( " display kind %d is unimplemented " , ( int ) how ) ;
default : COLD_EXPR ( FATAL ( " unknown display kind: %d " , ( int ) how ) ) ;
}
}