133 lines
4.1 KiB
C++
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_
|