corelib/tests/srd-preproc-location.hh

133 lines
4.1 KiB
C++

#ifndef TESTS_SRDPREPROCLOCATION_H_
#define TESTS_SRDPREPROCLOCATION_H_
#include <lw/lib/SRDPreproc.hh>
#include <lw/lib/SRDText.hh>
#include <lw/lib/SRDIO.hh>
#include <lw/lib/MemoryStreams.hh>
#include <cppunit/extensions/HelperMacros.h>
using namespace lw;
namespace {
inline T_SRDLocationChaining const* NextChain_(
T_SRDLocation const* from ) noexcept
{
return (from && from->isChained( ) ) ? &from->chaining( ) : nullptr;
}
uint32_t LocationDepth_(
const RPC_SRDLocation location ) noexcept
{
uint32_t depth( 0 );
auto lc( NextChain_( location ) );
while ( lc ) {
depth ++;
lc = NextChain_( RPC_SRDLocation( lc->location ) );
}
return depth;
}
uint32_t ErrorDepth_(
T_SRDErrors const& errors ,
const size_t index ) noexcept
{
auto const& error( errors[ index ] );
return LocationDepth_( &error.location( ) );
}
uint32_t TokenDepth_(
T_SRDList const& tokens ,
const size_t index ) noexcept
{
auto const& tok( tokens[ index ] );
assert( tok.hasLocation( ) );
return LocationDepth_( &tok.location( ) );
}
T_SRDLocationChaining const& GetChain_(
RPC_SRDLocation const& top ,
uint32_t depth ) noexcept
{
auto lc( NextChain_( top ) );
assert( lc );
while ( depth ) {
depth --;
lc = NextChain_( RPC_SRDLocation( lc->location ) );
assert( lc );
}
return *lc;
}
void PrintLoc_( RPC_SRDLocation location ) noexcept
{
printf( "at %s, l. %d c. %lu\n" , location->source( ).toOSString( ).data( ) ,
location->line( ) , location->character( ) );
if ( location->isChained( ) ) {
auto const& chain( location->chaining( ) );
printf( "\tChain type %d, depth %d, " ,
int( chain.circumstances ) , chain.depth );
PrintLoc_( RPC_SRDLocation( chain.location ) );
}
}
}
#define M_CKTOKDEPTH_( IDX , DEPTH ) \
CPPUNIT_ASSERT_EQUAL( uint32_t( DEPTH ) , TokenDepth_( output , IDX ) )
#define M_CKTOKLOC_( IDX , NAME , LINE , CHAR ) \
do { \
auto const& loc( output[ IDX ].location( ) ); \
CPPUNIT_ASSERT( T_String{ NAME } == loc.source( ) ); \
CPPUNIT_ASSERT_EQUAL( uint32_t( LINE ) , loc.line( ) ); \
CPPUNIT_ASSERT_EQUAL( size_t( CHAR ) , loc.character( ) ); \
} while ( 0 )
#define M_CKTOKFULL_( IDX , NAME , LINE , CHAR , DEPTH ) \
do { \
auto const& loc( output[ IDX ].location( ) ); \
CPPUNIT_ASSERT( T_String{ NAME } == loc.source( ) ); \
CPPUNIT_ASSERT_EQUAL( uint32_t( LINE ) , loc.line( ) ); \
CPPUNIT_ASSERT_EQUAL( size_t( CHAR ) , loc.character( ) ); \
M_CKTOKDEPTH_( IDX , DEPTH ); \
} while ( 0 )
#define M_CKTOKCHAIN_( IDX , DEPTH , HOW , NAME , LINE , CHAR , REC ) \
do { \
auto const& chain( GetChain_( &output[ IDX ].location( ) , DEPTH ) ); \
CPPUNIT_ASSERT( E_SRDLocationChaining::HOW == chain.circumstances ); \
CPPUNIT_ASSERT_EQUAL( uint32_t( REC ) , chain.depth ); \
CPPUNIT_ASSERT( T_String{ NAME } == chain.location->source( ) ); \
CPPUNIT_ASSERT_EQUAL( uint32_t( LINE ) , chain.location->line( ) ); \
CPPUNIT_ASSERT_EQUAL( size_t( CHAR ) , chain.location->character( ) ); \
} while ( 0 )
#define M_CKERRDEPTH_( IDX , DEPTH ) \
CPPUNIT_ASSERT_EQUAL( uint32_t( DEPTH ) , ErrorDepth_( errors , IDX ) )
#define M_CKERRFULL_( IDX , TEXT , DETAILS , NAME , LINE , CHAR , DEPTH ) \
do { \
CPPUNIT_ASSERT( T_String{ TEXT } == errors[ IDX ].error( ) ); \
CPPUNIT_ASSERT_EQUAL( bool( DETAILS ) , errors[ IDX ].isDetails( ) ); \
auto const& loc( errors[ IDX ].location( ) ); \
CPPUNIT_ASSERT( T_String{ NAME } == loc.source( ) ); \
CPPUNIT_ASSERT_EQUAL( uint32_t( LINE ) , loc.line( ) ); \
CPPUNIT_ASSERT_EQUAL( size_t( CHAR ) , loc.character( ) ); \
CPPUNIT_ASSERT_EQUAL( uint32_t( DEPTH ) , ErrorDepth_( errors , IDX ) ); \
} while ( 0 )
#define M_CKERRCHAIN_( IDX , DEPTH , HOW , NAME , LINE , CHAR , REC ) \
do { \
auto const& chain( GetChain_( &errors[ IDX ].location( ) , DEPTH ) ); \
CPPUNIT_ASSERT( E_SRDLocationChaining::HOW == chain.circumstances ); \
CPPUNIT_ASSERT_EQUAL( uint32_t( REC ) , chain.depth ); \
CPPUNIT_ASSERT( T_String{ NAME } == chain.location->source( ) ); \
CPPUNIT_ASSERT_EQUAL( uint32_t( LINE ) , chain.location->line( ) ); \
CPPUNIT_ASSERT_EQUAL( size_t( CHAR ) , chain.location->character( ) ); \
} while ( 0 )
#endif // TESTS_SRDPREPROCLOCATION_H_