1304 lines
38 KiB
C++
1304 lines
38 KiB
C++
|
#include "srd-preproc-cmd-common.hh"
|
||
|
#include "srd-preproc-location.hh"
|
||
|
|
||
|
|
||
|
class SRDPreprocCmdCoreTest : public CppUnit::TestFixture
|
||
|
{
|
||
|
CPPUNIT_TEST_SUITE( SRDPreprocCmdCoreTest );
|
||
|
|
||
|
CPPUNIT_TEST( testRaw );
|
||
|
CPPUNIT_TEST( testRawEmpty );
|
||
|
CPPUNIT_TEST( testRawSkipComments );
|
||
|
CPPUNIT_TEST( testRawUnterminated );
|
||
|
|
||
|
CPPUNIT_TEST( testIfMissingArgs );
|
||
|
CPPUNIT_TEST( testIfExtraArgs );
|
||
|
CPPUNIT_TEST( testIfBadCondition );
|
||
|
CPPUNIT_TEST( testIfBadThenBlock );
|
||
|
CPPUNIT_TEST( testIfBadElseBlock );
|
||
|
CPPUNIT_TEST( testIfTrueThen );
|
||
|
CPPUNIT_TEST( testIfFalseThen );
|
||
|
CPPUNIT_TEST( testIfTrueThenElse );
|
||
|
CPPUNIT_TEST( testIfFalseThenElse );
|
||
|
CPPUNIT_TEST( testIfArgSubst );
|
||
|
CPPUNIT_TEST( testIfThenInnerList );
|
||
|
CPPUNIT_TEST( testIfElseInnerList );
|
||
|
|
||
|
CPPUNIT_TEST( testEvalEmpty );
|
||
|
CPPUNIT_TEST( testEval );
|
||
|
CPPUNIT_TEST( testEvalErrors );
|
||
|
CPPUNIT_TEST( testEvalSkipComments );
|
||
|
CPPUNIT_TEST( testEvalUnterminated );
|
||
|
CPPUNIT_TEST( testEvalInnerList );
|
||
|
CPPUNIT_TEST( testEvalCalls );
|
||
|
|
||
|
CPPUNIT_TEST( testScope );
|
||
|
CPPUNIT_TEST( testScopeValues );
|
||
|
CPPUNIT_TEST( testScopeInnerList );
|
||
|
|
||
|
CPPUNIT_TEST( testClearScopeInstruction );
|
||
|
CPPUNIT_TEST( testClearScopeBlock );
|
||
|
CPPUNIT_TEST( testClearScopeInnerList );
|
||
|
|
||
|
CPPUNIT_TEST( testTryEmpty );
|
||
|
CPPUNIT_TEST( testTryNoErrors );
|
||
|
CPPUNIT_TEST( testTryErrors );
|
||
|
CPPUNIT_TEST( testTryErrorsChained );
|
||
|
CPPUNIT_TEST( testTryUnterminated );
|
||
|
CPPUNIT_TEST( testTryTooManyErrors );
|
||
|
CPPUNIT_TEST( testTryInnerList );
|
||
|
|
||
|
CPPUNIT_TEST( testOutput );
|
||
|
CPPUNIT_TEST( testOutputErrors );
|
||
|
|
||
|
CPPUNIT_TEST( testErrorEmpty );
|
||
|
CPPUNIT_TEST( testErrorWord );
|
||
|
CPPUNIT_TEST( testErrorString );
|
||
|
CPPUNIT_TEST( testErrorVar );
|
||
|
CPPUNIT_TEST( testErrorInt );
|
||
|
CPPUNIT_TEST( testErrorLong );
|
||
|
CPPUNIT_TEST( testErrorReal );
|
||
|
CPPUNIT_TEST( testErrorList );
|
||
|
CPPUNIT_TEST( testErrorConcat );
|
||
|
|
||
|
CPPUNIT_TEST( testBreakMain );
|
||
|
CPPUNIT_TEST( testBreakMainList );
|
||
|
CPPUNIT_TEST( testBreakEvalInput );
|
||
|
CPPUNIT_TEST( testBreakEvalOutput );
|
||
|
CPPUNIT_TEST( testBreakFunction );
|
||
|
CPPUNIT_TEST( testBreakRecursiveFunction );
|
||
|
CPPUNIT_TEST( testBreakMacro );
|
||
|
CPPUNIT_TEST( testBreakArgs );
|
||
|
|
||
|
CPPUNIT_TEST( testRethrowNothing );
|
||
|
CPPUNIT_TEST( testRethrowList );
|
||
|
CPPUNIT_TEST( testRethrowEmptyList );
|
||
|
CPPUNIT_TEST( testRethrowUnwrapped );
|
||
|
CPPUNIT_TEST( testRethrowErrorWord );
|
||
|
CPPUNIT_TEST( testRethrowSourceWord );
|
||
|
CPPUNIT_TEST( testRethrowDetails );
|
||
|
CPPUNIT_TEST( testRethrowChained );
|
||
|
CPPUNIT_TEST( testRethrowChainedDepth );
|
||
|
|
||
|
CPPUNIT_TEST( testRethrowNoList );
|
||
|
CPPUNIT_TEST( testRethrowBadMessage );
|
||
|
CPPUNIT_TEST( testRethrowNoLocation );
|
||
|
CPPUNIT_TEST( testRethrowBadLocation );
|
||
|
CPPUNIT_TEST( testRethrowLocationBadSource );
|
||
|
CPPUNIT_TEST( testRethrowLocationBadLine );
|
||
|
CPPUNIT_TEST( testRethrowLocationNegativeLine );
|
||
|
CPPUNIT_TEST( testRethrowLocationLineTooHigh );
|
||
|
CPPUNIT_TEST( testRethrowLocationBadChar );
|
||
|
CPPUNIT_TEST( testRethrowLocationNegativeChar );
|
||
|
CPPUNIT_TEST( testRethrowChainedBad );
|
||
|
CPPUNIT_TEST( testRethrowChainedInvalid );
|
||
|
CPPUNIT_TEST( testRethrowChainedNoLocation );
|
||
|
CPPUNIT_TEST( testRethrowChainedBadLocation );
|
||
|
CPPUNIT_TEST( testRethrowChainedNegativeDepth );
|
||
|
CPPUNIT_TEST( testRethrowChainedDepthTooHigh );
|
||
|
CPPUNIT_TEST( testRethrowChainedDepthNoLocation );
|
||
|
CPPUNIT_TEST( testRethrowChainedDepthBadLocation );
|
||
|
|
||
|
CPPUNIT_TEST_SUITE_END( );
|
||
|
|
||
|
public:
|
||
|
void testRaw( );
|
||
|
void testRawEmpty( );
|
||
|
void testRawSkipComments( );
|
||
|
void testRawUnterminated( );
|
||
|
|
||
|
void testIfMissingArgs( );
|
||
|
void testIfExtraArgs( );
|
||
|
void testIfBadCondition( );
|
||
|
void testIfBadThenBlock( );
|
||
|
void testIfBadElseBlock( );
|
||
|
void testIfTrueThen( );
|
||
|
void testIfFalseThen( );
|
||
|
void testIfTrueThenElse( );
|
||
|
void testIfFalseThenElse( );
|
||
|
void testIfArgSubst( );
|
||
|
void testIfThenInnerList( );
|
||
|
void testIfElseInnerList( );
|
||
|
|
||
|
void testEvalEmpty( );
|
||
|
void testEval( );
|
||
|
void testEvalErrors( );
|
||
|
void testEvalSkipComments( );
|
||
|
void testEvalUnterminated( );
|
||
|
void testEvalInnerList( );
|
||
|
void testEvalCalls( );
|
||
|
|
||
|
void testScope( );
|
||
|
void testScopeValues( );
|
||
|
void testScopeInnerList( );
|
||
|
|
||
|
void testClearScopeInstruction( );
|
||
|
void testClearScopeBlock( );
|
||
|
void testClearScopeInnerList( );
|
||
|
|
||
|
void testTryEmpty( );
|
||
|
void testTryNoErrors( );
|
||
|
void testTryErrors( );
|
||
|
void testTryErrorsChained( );
|
||
|
void testTryUnterminated( );
|
||
|
void testTryTooManyErrors( );
|
||
|
void testTryInnerList( );
|
||
|
|
||
|
void testOutput( );
|
||
|
void testOutputErrors( );
|
||
|
|
||
|
void testErrorEmpty( );
|
||
|
void testErrorWord( );
|
||
|
void testErrorString( );
|
||
|
void testErrorVar( );
|
||
|
void testErrorInt( );
|
||
|
void testErrorLong( );
|
||
|
void testErrorReal( );
|
||
|
void testErrorList( );
|
||
|
void testErrorConcat( );
|
||
|
|
||
|
void testBreakMain( );
|
||
|
void testBreakMainList( );
|
||
|
void testBreakEvalInput( );
|
||
|
void testBreakEvalOutput( );
|
||
|
void testBreakFunction( );
|
||
|
void testBreakRecursiveFunction( );
|
||
|
void testBreakMacro( );
|
||
|
void testBreakArgs( );
|
||
|
|
||
|
void testRethrowNothing( );
|
||
|
void testRethrowList( );
|
||
|
void testRethrowEmptyList( );
|
||
|
void testRethrowUnwrapped( );
|
||
|
void testRethrowErrorWord( );
|
||
|
void testRethrowSourceWord( );
|
||
|
void testRethrowDetails( );
|
||
|
void testRethrowChained( );
|
||
|
void testRethrowChainedDepth( );
|
||
|
|
||
|
void testRethrowNoList( );
|
||
|
void testRethrowBadMessage( );
|
||
|
void testRethrowNoLocation( );
|
||
|
void testRethrowBadLocation( );
|
||
|
void testRethrowLocationBadSource( );
|
||
|
void testRethrowLocationBadLine( );
|
||
|
void testRethrowLocationNegativeLine( );
|
||
|
void testRethrowLocationLineTooHigh( );
|
||
|
void testRethrowLocationBadChar( );
|
||
|
void testRethrowLocationNegativeChar( );
|
||
|
void testRethrowChainedBad( );
|
||
|
void testRethrowChainedInvalid( );
|
||
|
void testRethrowChainedNoLocation( );
|
||
|
void testRethrowChainedBadLocation( );
|
||
|
void testRethrowChainedNegativeDepth( );
|
||
|
void testRethrowChainedDepthTooHigh( );
|
||
|
void testRethrowChainedDepthNoLocation( );
|
||
|
void testRethrowChainedDepthBadLocation( );
|
||
|
};
|
||
|
CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdCoreTest );
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRaw( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -raw ok $x ( -raw ) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "ok $x ( -raw )" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "test" , 1 , 8 , 0 );
|
||
|
M_CKTOKFULL_( 1 , "test" , 1 , 11 , 0 );
|
||
|
M_CKTOKFULL_( 2 , "test" , 1 , 14 , 0 );
|
||
|
M_CKTOKFULL_( 3 , "test" , 1 , 16 , 0 );
|
||
|
M_CKTOKFULL_( 4 , "test" , 1 , 21 , 0 );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRawEmpty( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -raw )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRawSkipComments( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -raw { a comment } x # another comment!\n)" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "x" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "test" , 1 , 22 , 0 );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRawUnterminated( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -raw\n(\n(" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 3u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "unterminated list" , false , "test" , 1 , 1 , 0 );
|
||
|
M_CKERRFULL_( 1 , "unterminated list" , false , "test" , 2 , 1 , 0 );
|
||
|
M_CKERRFULL_( 2 , "unterminated list" , false , "test" , 3 , 1 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "(())" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "test" , 2 , 1 , 0 );
|
||
|
M_CKTOKFULL_( 1 , "test" , 3 , 1 , 0 );
|
||
|
M_CKTOKFULL_( 2 , "*unexpected end of file*" , 0 , 2 , 0 );
|
||
|
M_CKTOKFULL_( 3 , "*unexpected end of file*" , 0 , 1 , 0 );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testIfMissingArgs( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -if )\n( -if 0 )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "not enough arguments" , false , "test" , 1 , 3 , 0 );
|
||
|
M_CKERRFULL_( 1 , "previous error cause" , true , "test" , 1 , 7 , 0 );
|
||
|
M_CKERRFULL_( 2 , "not enough arguments" , false , "test" , 2 , 3 , 0 );
|
||
|
M_CKERRFULL_( 3 , "previous error cause" , true , "test" , 2 , 9 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testIfExtraArgs( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -if 0 (a) (b) (blah()) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "too many arguments" , false , "test" , 1 , 3 , 0 );
|
||
|
M_CKERRFULL_( 1 , "previous error cause" , true , "test" , 1 , 17 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "b" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "test" , 1 , 14 , 0 );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testIfBadCondition( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -if nope () )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "numeric value expected" , false , "test" , 1 , 3 , 0 );
|
||
|
M_CKERRFULL_( 1 , "previous error cause" , true , "test" , 1 , 7 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testIfBadThenBlock( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -if 1 nope )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "list expected" , false , "test" , 1 , 3 , 0 );
|
||
|
M_CKERRFULL_( 1 , "previous error cause" , true , "test" , 1 , 9 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testIfBadElseBlock( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -if 1 (a) nope )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "list expected" , false , "test" , 1 , 3 , 0 );
|
||
|
M_CKERRFULL_( 1 , "previous error cause" , true , "test" , 1 , 13 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "a" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testIfTrueThen( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -if 1 (x) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "x" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "test" , 1 , 10 , 0 );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testIfFalseThen( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -if 0 (x) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testIfTrueThenElse( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -if 1 (x) (y) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "x" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "test" , 1 , 10 , 0 );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testIfFalseThenElse( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -if 0 (x) (y) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "y" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "test" , 1 , 14 , 0 );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testIfArgSubst( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set x 1 )\n"
|
||
|
"( -if $x (x) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "x" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "test" , 2 , 11 , 0 );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testIfThenInnerList( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set x (-raw ( () ) ) )\n"
|
||
|
"( -bless x )\n"
|
||
|
"( -if 1 (-not-a-command) )\n"
|
||
|
"( -if 1 ($x) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "-not-a-command (())" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "test" , 3 , 10 , 0 );
|
||
|
M_CKTOKFULL_( 1 , "$x" , 0 , 0 , 1 );
|
||
|
M_CKTOKCHAIN_( 1 , 0 , SUBSTITUTED , "test" , 4 , 10 , 0 );
|
||
|
M_CKTOKFULL_( 2 , "$x" , 0 , 1 , 1 );
|
||
|
M_CKTOKCHAIN_( 2 , 0 , SUBSTITUTED , "test" , 4 , 10 , 0 );
|
||
|
M_CKTOKFULL_( 3 , "$x" , 0 , 2 , 1 );
|
||
|
M_CKTOKCHAIN_( 3 , 0 , SUBSTITUTED , "test" , 4 , 10 , 0 );
|
||
|
M_CKTOKFULL_( 4 , "$x" , 0 , 3 , 1 );
|
||
|
M_CKTOKCHAIN_( 4 , 0 , SUBSTITUTED , "test" , 4 , 10 , 0 );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testIfElseInnerList( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set x (-raw ( () ) ) )\n"
|
||
|
"( -bless x )\n"
|
||
|
"( -if 0 () (-not-a-command) )\n"
|
||
|
"( -if 0 () ($x) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "-not-a-command (())" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "test" , 3 , 13 , 0 );
|
||
|
M_CKTOKFULL_( 1 , "$x" , 0 , 0 , 1 );
|
||
|
M_CKTOKCHAIN_( 1 , 0 , SUBSTITUTED , "test" , 4 , 13 , 0 );
|
||
|
M_CKTOKFULL_( 2 , "$x" , 0 , 1 , 1 );
|
||
|
M_CKTOKCHAIN_( 2 , 0 , SUBSTITUTED , "test" , 4 , 13 , 0 );
|
||
|
M_CKTOKFULL_( 3 , "$x" , 0 , 2 , 1 );
|
||
|
M_CKTOKCHAIN_( 3 , 0 , SUBSTITUTED , "test" , 4 , 13 , 0 );
|
||
|
M_CKTOKFULL_( 4 , "$x" , 0 , 3 , 1 );
|
||
|
M_CKTOKCHAIN_( 4 , 0 , SUBSTITUTED , "test" , 4 , 13 , 0 );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testEvalEmpty( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -eval )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testEval( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set (x y)\n"
|
||
|
"( -raw $y )\n"
|
||
|
"this-is-y\n"
|
||
|
")\n"
|
||
|
"eval ( -eval $x ) actual $x" ,
|
||
|
errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "eval this-is-y actual $y" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "test" , 5 , 1 , 0 );
|
||
|
M_CKTOKFULL_( 1 , "$y" , 0 , 0 , 2 );
|
||
|
M_CKTOKCHAIN_( 1 , 0 , SUBSTITUTED , "$x" , 0 , 0 , 0 );
|
||
|
M_CKTOKCHAIN_( 1 , 1 , EVALUATED , "test" , 5 , 8 , 0 );
|
||
|
M_CKTOKFULL_( 2 , "test" , 5 , 19 , 0 );
|
||
|
M_CKTOKFULL_( 3 , "$x" , 0 , 0 , 1 );
|
||
|
M_CKTOKCHAIN_( 3 , 0 , SUBSTITUTED , "test" , 5 , 26 , 0 );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testEvalErrors( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set x ( -raw $does-not-exist ) )\n"
|
||
|
"( -eval $x )" ,
|
||
|
errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "unknown variable" , false , "$x" , 0 , 0 , 1 );
|
||
|
M_CKERRCHAIN_( 0 , 0 , EVALUATED , "test" , 2 , 3 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testEvalSkipComments( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -eval (-from-source \"{ a comment } x # another comment!\")\n)" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "x" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "-from-source" , 1 , 15 , 1 );
|
||
|
M_CKTOKCHAIN_( 0 , 0 , GENERATED , "test" , 1 , 10 , 0 );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testEvalUnterminated( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -eval\n(\n(" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 3u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "unterminated list" , 1 , 1 );
|
||
|
M_CKERR_( 1 , "unterminated list" , 2 , 1 );
|
||
|
M_CKERR_( 2 , "unterminated list" , 3 , 1 );
|
||
|
CPPUNIT_ASSERT( check( "(())" , output ) );
|
||
|
M_CKTOKFULL_( 0 , "test" , 2 , 1 , 0 );
|
||
|
M_CKTOKFULL_( 1 , "test" , 3 , 1 , 0 );
|
||
|
M_CKTOKFULL_( 2 , "*unexpected end of file*" , 0 , 2 , 0 );
|
||
|
M_CKTOKFULL_( 3 , "*unexpected end of file*" , 0 , 1 , 0 );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testEvalInnerList( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set x (-raw ( () ) ) )\n"
|
||
|
"( -bless x )\n"
|
||
|
"( -eval -not-a-command )\n"
|
||
|
"( -eval $x )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "-not-a-command (())" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testEvalCalls( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set (x y) (-raw (() f1 (-raw $y) f2)) x)\n"
|
||
|
"(-bless x)\n"
|
||
|
"( -eval a $y b ($x) c ($x) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "a x b f1 x f2 c f1 x f2" , output ) );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testScope( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set-macro dump ( ( ) ( -raw ( ( -raw\n"
|
||
|
"( -is-set x )\n"
|
||
|
"( -is-blessed f )\n"
|
||
|
"( -is-set y )\n"
|
||
|
"( -is-macro m )\n"
|
||
|
"( -is-macro n )\n"
|
||
|
") ) ) ) )\n"
|
||
|
"( -set x 1 )\n"
|
||
|
"( -set f (()) )\n"
|
||
|
"( -set-macro m ( ( ) ) )\n"
|
||
|
"( -scope\n"
|
||
|
"( -unset x )\n"
|
||
|
"( -bless f )\n"
|
||
|
"( -set y 0 )\n"
|
||
|
"( -unset-macro m )\n"
|
||
|
"( -set-macro n ( ( ) ) )\n"
|
||
|
"(dump)\n"
|
||
|
")\n"
|
||
|
"(dump)\n"
|
||
|
"" ,
|
||
|
errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "( 0 1 1 0 1 ) ( 1 0 0 1 0 )" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testScopeValues( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set x 1 )\n"
|
||
|
"$x\n"
|
||
|
"( -scope\n"
|
||
|
"( -set x 2 )\n"
|
||
|
"$x\n"
|
||
|
")\n"
|
||
|
"$x\n" ,
|
||
|
errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "1 2 1" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testScopeInnerList( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set x (-raw ( () ) ) )\n"
|
||
|
"( -bless x )\n"
|
||
|
"( -scope -not-a-command )\n"
|
||
|
"( -scope $x )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "-not-a-command (())" , output ) );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testClearScopeInstruction( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set x )\n"
|
||
|
"( -set-macro y ( ( ) ) )\n"
|
||
|
"( -is-set x )\n"
|
||
|
"( -is-macro y )\n"
|
||
|
"( -clear-scope )\n"
|
||
|
"( -is-set x )\n"
|
||
|
"( -is-macro y )\n"
|
||
|
, errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "1 1 0 0" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testClearScopeBlock( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set x )\n"
|
||
|
"( -set-macro y ( ( ) ) )\n"
|
||
|
"( -is-set x )\n"
|
||
|
"( -is-macro y )\n"
|
||
|
"( -clear-scope\n"
|
||
|
"( -is-set x )\n"
|
||
|
"( -is-macro y )\n"
|
||
|
")\n"
|
||
|
"( -is-set x )\n"
|
||
|
"( -is-macro y )\n"
|
||
|
, errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "1 1 0 0 1 1" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testClearScopeInnerList( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -clear-scope -not-a-command )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "-not-a-command" , output ) );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testTryEmpty( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "(-try )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "() ()" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testTryNoErrors( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "(-try 1 2 3)" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "(1 2 3) ()" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testTryErrors( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -try $x 2 $y )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "( 2 ) ( "
|
||
|
"( \"unknown variable\" ( \"test\" 1 8 ) )"
|
||
|
"( \"unknown variable\" ( \"test\" 1 13 ) )"
|
||
|
")" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testTryErrorsChained( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-set (f1 f2) (-raw\n"
|
||
|
"(() f1 $x)\n"
|
||
|
"((a)\n"
|
||
|
"f2 $a\n"
|
||
|
"(-if (-gt $a 0) (\n"
|
||
|
"($f2 (-sub $a 1))\n"
|
||
|
")(\n"
|
||
|
"($f1)\n"
|
||
|
"))\n"
|
||
|
")\n"
|
||
|
"))\n"
|
||
|
"(-bless f1 f2)\n"
|
||
|
"( -try ($f1) ($f2 5))"
|
||
|
, errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check(
|
||
|
"( f1 f2 5 f2 4 f2 3 f2 2 f2 1 f2 0 f1 ) ( "
|
||
|
"( \"unknown variable\""
|
||
|
"( \"test\" 2 8 )"
|
||
|
"called ( \"test\" 13 9 )"
|
||
|
")"
|
||
|
"( \"unknown variable\""
|
||
|
"( \"test\" 2 8 )"
|
||
|
"called ( \"test\" 8 2 )"
|
||
|
"called 4 ( \"test\" 6 2 )"
|
||
|
"called ( \"test\" 13 15 )"
|
||
|
")"
|
||
|
")" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testTryUnterminated( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -try\n(\n(" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 3u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "unterminated list" , 1 , 1 );
|
||
|
M_CKERR_( 1 , "unterminated list" , 2 , 1 );
|
||
|
M_CKERR_( 2 , "unterminated list" , 3 , 1 );
|
||
|
CPPUNIT_ASSERT( check( "((()))()" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testTryTooManyErrors( )
|
||
|
{
|
||
|
T_StringBuilder sb;
|
||
|
sb << "(-set (output errors) (-try (\n";
|
||
|
for ( uint32_t i = 0 ; i < T_SRDErrors::MAX_ERRORS + 1 ; i ++ ) {
|
||
|
sb << "$missing\n";
|
||
|
}
|
||
|
sb << ") ) )\n"
|
||
|
<< "(-set last-error ( ((list)) (-raw\n"
|
||
|
<< "(-set (a b) $list)\n"
|
||
|
<< "(-if (-eq ($b) ()) ($a) (($last-error $b)))\n"
|
||
|
<< ")))\n"
|
||
|
<< "(-bless last-error)\n"
|
||
|
<< "$output (-length $errors) ($last-error (-unwrap $errors))\n"
|
||
|
<< '\0';
|
||
|
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( sb.data( ) , errors ) );
|
||
|
|
||
|
sb.clear( );
|
||
|
sb << "(()) 41 ( \"too many errors\" ( \"test\" " << ( T_SRDErrors::MAX_ERRORS + 1 ) << " 1 ) )" << '\0';
|
||
|
CPPUNIT_ASSERT( check( sb.data( ) , output ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testTryInnerList( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"( -set x (-raw ( () ) ) )\n"
|
||
|
"( -bless x )\n"
|
||
|
"( -try -not-a-command )\n"
|
||
|
"( -try $x )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "(-not-a-command) () ((())) ()" , output ) );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
class T_OutputErrorGen_ : public A_SRDReaderTarget
|
||
|
{
|
||
|
private:
|
||
|
A_SRDReaderTarget& next_;
|
||
|
|
||
|
public:
|
||
|
explicit T_OutputErrorGen_( A_SRDReaderTarget& next )
|
||
|
: A_SRDReaderTarget( ) , next_( next )
|
||
|
{}
|
||
|
|
||
|
void start( T_SRDErrors & errors ) override
|
||
|
{
|
||
|
next_.start( errors );
|
||
|
}
|
||
|
|
||
|
void push( T_SRDErrors & errors , T_SRDToken && token ) override
|
||
|
{
|
||
|
if ( token.type( ) == E_SRDTokenType::WORD && token.stringValue( ) == "fail" ) {
|
||
|
errors.add( "DO NOT WANT" , token );
|
||
|
}
|
||
|
next_.push( errors , std::move( token ) );
|
||
|
}
|
||
|
|
||
|
void end( T_SRDErrors & errors ) override
|
||
|
{
|
||
|
next_.end( errors );
|
||
|
}
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testOutput( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "(5 (-output (3 (-output (1 2)) 4)) 6)" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "(1 2) (3 4) (5 6)" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testOutputErrors( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDMemoryTarget mt( false );
|
||
|
mt.clearFlushToken( true );
|
||
|
T_OutputErrorGen_ eg( mt );
|
||
|
|
||
|
T_SRDPreprocessorConfig emptyConfig;
|
||
|
emptyConfig.addBuiltinCommands( );
|
||
|
T_SRDPreprocessor pp( emptyConfig , eg );
|
||
|
T_SRDLexer lexer( T_String( "test" ) , errors , pp );
|
||
|
pp.start( errors );
|
||
|
char const* ptr = "(-try (-output fail))";
|
||
|
while ( *ptr != 0 ) {
|
||
|
lexer.processCharacter( *ptr ++ );
|
||
|
}
|
||
|
lexer.processEnd( );
|
||
|
mt.end( errors );
|
||
|
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "fail () ( ( \"DO NOT WANT\" ( \"test\" 1 16 ) ) )" ,
|
||
|
mt.list( ) ) );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testErrorEmpty( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -error )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "user error" , 1 , 3 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testErrorWord( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -error fail )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "fail" , 1 , 3 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testErrorString( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -error \"out of cheese\" )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "out of cheese" , 1 , 3 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testErrorVar( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -error ( -raw $x ) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "$x" , 1 , 3 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testErrorInt( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -error 123 )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "123" , 1 , 3 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testErrorLong( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -error 5000000000 )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "5000000000" , 1 , 3 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testErrorReal( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -error 1.5 )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "1.5" , 1 , 3 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testErrorList( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -error ( a list ( 123 \"wut\" ) ) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "( a list ( 123 wut ) )" , 1 , 3 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testErrorConcat( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "( -error And this is the real thing \"(or is it?)\" )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "And this is the real thing (or is it?)" , 1 , 3 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testBreakMain( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "a (-break) b" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "a" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testBreakMainList( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "(a ((-break)) b)" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "(a())" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testBreakEvalInput( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "a (-eval (b (-break)) c) d" , errors ) );
|
||
|
for ( uint32_t i = 0 ; i < errors.size( ) ; i ++ ) {
|
||
|
M_PRINTERR_( i );
|
||
|
}
|
||
|
CPPUNIT_ASSERT( check( "a (b) d" , output ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testBreakEvalOutput( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "a (-eval b ((-raw ((-break)))) c) d" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "a b (())" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testBreakFunction( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-set f (-raw ( (a b) $a (-break) $b ) ))\n"
|
||
|
"(-bless f)\n"
|
||
|
"a ($f b c) d" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "a b d" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testBreakRecursiveFunction( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-set f (-raw ( (a b)\n"
|
||
|
"(\n"
|
||
|
"(-if (-lt $b $a ) (\n"
|
||
|
"(-break)\n"
|
||
|
"))\n"
|
||
|
"$a\n"
|
||
|
"($f (-add $a 1) $b)\n"
|
||
|
")\n"
|
||
|
")))\n"
|
||
|
"(-bless f)\n"
|
||
|
"a ($f 1 3) b" , errors ) );
|
||
|
for ( auto i = 0u ; i < errors.size( ) ; i ++ ) {
|
||
|
M_PRINTERR_( i );
|
||
|
}
|
||
|
CPPUNIT_ASSERT( check( "a (1(2(3()))) b" , output ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testBreakMacro( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-set-macro m (-raw ( (a b) ($a (-break) $b) ) ))\n"
|
||
|
"a (m b c) d" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "a (b) d" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testBreakArgs( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "(a (-break even) b)" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "too many arguments" , 1 , 5 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 1 , 12 );
|
||
|
CPPUNIT_ASSERT( check( "(a)" , output ) );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
#define M_CKRT_TEXT_( INDEX , TEXT ) \
|
||
|
CPPUNIT_ASSERT( errors[ INDEX ].error( ) == (TEXT) )
|
||
|
#define M_CKRT_SOURCE_( INDEX , EID , NAME , LINE , CHAR ) \
|
||
|
do { \
|
||
|
RPC_SRDLocation loc( &errors[ INDEX ].location( ) ); \
|
||
|
int i( EID ); \
|
||
|
while ( i > 0 ) { \
|
||
|
assert( loc->isChained( ) ); \
|
||
|
loc = RPC_SRDLocation( loc->chaining( ).location ); \
|
||
|
i --; \
|
||
|
} \
|
||
|
auto const& l( *loc ); \
|
||
|
CPPUNIT_ASSERT( l.source( ) == (NAME) ); \
|
||
|
CPPUNIT_ASSERT( l.line( ) == (LINE) ); \
|
||
|
CPPUNIT_ASSERT( l.character( ) == (CHAR) ); \
|
||
|
} while ( 0 )
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowNothing( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "(-rethrow)" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowList( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( ( \"error text\"\n"
|
||
|
"( \"source\" 2 3 )\n"
|
||
|
") ( \"second error\"\n"
|
||
|
"( \"source 2\" 4 5 )\n"
|
||
|
") ) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "error text" , false , "source" , 2 , 3 , 0 );
|
||
|
M_CKERRFULL_( 1 , "second error" , false , "source 2" , 4 , 5 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowEmptyList( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( ) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowUnwrapped( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error text\"\n"
|
||
|
"( \"source\" 2 3 )\n"
|
||
|
") ( \"second error\"\n"
|
||
|
"( \"source 2\" 4 5 )\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "error text" , false , "source" , 2 , 3 , 0 );
|
||
|
M_CKERRFULL_( 1 , "second error" , false , "source 2" , 4 , 5 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowErrorWord( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "(-rethrow ( error ( \"source\" 2 3 ) ) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "error" , false , "source" , 2 , 3 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowSourceWord( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( source 2 3 )\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "error" , false , "source" , 2 , 3 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowDetails( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"not an error\" details\n"
|
||
|
"( source 2 3 )\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "not an error" , true , "source" , 2 , 3 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowChained( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 1 1 )\n"
|
||
|
"called ( \"src\" 2 2 )\n"
|
||
|
"loaded ( \"src\" 3 3 )\n"
|
||
|
"included ( \"src\" 4 4 )\n"
|
||
|
"generated ( \"src\" 5 5 )\n"
|
||
|
"expanded ( \"src\" 6 6 )\n"
|
||
|
"evaluated ( \"src\" 7 7 )\n"
|
||
|
"substituted ( \"src\" 8 8 )\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "error" , false , "src" , 1 , 1 , 7 );
|
||
|
M_CKERRCHAIN_( 0 , 0 , CALLED , "src" , 2 , 2 , 0 );
|
||
|
M_CKERRCHAIN_( 0 , 1 , LOADED , "src" , 3 , 3 , 0 );
|
||
|
M_CKERRCHAIN_( 0 , 2 , INCLUDED , "src" , 4 , 4 , 0 );
|
||
|
M_CKERRCHAIN_( 0 , 3 , GENERATED , "src" , 5 , 5 , 0 );
|
||
|
M_CKERRCHAIN_( 0 , 4 , EXPANDED , "src" , 6 , 6 , 0 );
|
||
|
M_CKERRCHAIN_( 0 , 5 , EVALUATED , "src" , 7 , 7 , 0 );
|
||
|
M_CKERRCHAIN_( 0 , 6 , SUBSTITUTED , "src" , 8 , 8 , 0 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowChainedDepth( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 1 1 )\n"
|
||
|
"called 5 ( \"src\" 2 2 )\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) );
|
||
|
M_CKERRFULL_( 0 , "error" , false , "src" , 1 , 1 , 1 );
|
||
|
M_CKERRCHAIN_( 0 , 0 , CALLED , "src" , 2 , 2 , 5 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowNoList( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "(-rethrow nope)" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "start of list expected" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 1 , 11 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowBadMessage( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "(-rethrow ( 12 ) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "error message expected" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 1 , 13 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowNoLocation( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "(-rethrow ( error ) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "'details' or start of list expected" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 1 , 19 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowBadLocation( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "(-rethrow ( \"error\" nope ) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "'details' or start of list expected" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 1 , 21 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowLocationBadSource( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process( "(-rethrow ( \"error\" ( 12 1 2 ) ) )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "source name expected" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 1 , 23 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowLocationBadLine( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" nope 3 )\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "line number expected" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 2 , 9 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowLocationNegativeLine( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" -1 3 )\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "invalid line number" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 2 , 9 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowLocationLineTooHigh( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 5000000000 3 )\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "invalid line number" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 2 , 9 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowLocationBadChar( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 2 nope )\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "character/byte number expected" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 2 , 11 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowLocationNegativeChar( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 2 -3 )\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "invalid character/byte number" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 2 , 11 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowChainedBad( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 2 3 )\n"
|
||
|
"12\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "chaining type or end of list expected" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 3 , 1 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowChainedInvalid( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 2 3 )\n"
|
||
|
"blah\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "invalid chaining type" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 3 , 1 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowChainedNoLocation( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 2 3 )\n"
|
||
|
"loaded\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "depth or start of list expected" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 4 , 1 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowChainedBadLocation( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 2 3 )\n"
|
||
|
"loaded nope\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "depth or start of list expected" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 3 , 8 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowChainedNegativeDepth( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 2 3 )\n"
|
||
|
"loaded -1\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "invalid recursion depth" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 3 , 8 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowChainedDepthTooHigh( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 2 3 )\n"
|
||
|
"loaded 5000000000\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "invalid recursion depth" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 3 , 8 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowChainedDepthNoLocation( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 2 3 )\n"
|
||
|
"loaded 5\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "start of list expected" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 4 , 1 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|
||
|
|
||
|
void SRDPreprocCmdCoreTest::testRethrowChainedDepthBadLocation( )
|
||
|
{
|
||
|
T_SRDErrors errors;
|
||
|
T_SRDList output( process(
|
||
|
"(-rethrow ( \"error\"\n"
|
||
|
"( \"src\" 2 3 )\n"
|
||
|
"loaded 5 nope\n"
|
||
|
") )" , errors ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
|
||
|
M_CKERR_( 0 , "start of list expected" , 1 , 2 );
|
||
|
M_CKERR_( 1 , "previous error cause" , 3 , 10 );
|
||
|
CPPUNIT_ASSERT( check( "" , output ) );
|
||
|
}
|