Precommit (#1)

* first commit

* cleanup
This commit is contained in:
tompzf
2025-11-04 13:28:06 +01:00
committed by GitHub
parent dba45dc636
commit 6ed4b1534e
898 changed files with 256340 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
# Define project
project (UnitTest_IDLCompiler VERSION 1.0 LANGUAGES CXX)
# Find the IDL compiler
# REMARKS The compiler can only be found after it has build. Having both the compiler and the unittest project build, causes an
# error during the scanning phase of CMake.
#find_program(SDVIDL NAMES "sdv_idl_compiler" PATHS "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/../../bin/" NO_CACHE)
set (SDVIDL "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/../../bin/sdv_idl_compiler")
message("Use IDL compiler: ${SDVIDL}")
# Compile the IDL
add_custom_command(
OUTPUT ${PROJECT_SOURCE_DIR}/generated/linked.h
DEPENDS sdv_idl_compiler
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/linked.idl
COMMENT "Build linked.idl"
COMMAND ${SDVIDL} "${PROJECT_SOURCE_DIR}/linked.idl" "-I${PROJECT_SOURCE_DIR}/../../../export" "-O${PROJECT_SOURCE_DIR}/generated"
VERBATIM
)
add_custom_command(
OUTPUT ${PROJECT_SOURCE_DIR}/generated/test.h
DEPENDS sdv_idl_compiler
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/test.idl
COMMENT "Build test.idl"
COMMAND ${SDVIDL} "${PROJECT_SOURCE_DIR}/test.idl" "-I${PROJECT_SOURCE_DIR}/../../../export" "-O${PROJECT_SOURCE_DIR}/generated"
VERBATIM
)
add_custom_command(
OUTPUT ${PROJECT_SOURCE_DIR}/generated/array.h
DEPENDS sdv_idl_compiler
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/array.idl
COMMENT "Build array.idl"
COMMAND ${SDVIDL} "${PROJECT_SOURCE_DIR}/array.idl" "-I${PROJECT_SOURCE_DIR}/../../../export" "-O${PROJECT_SOURCE_DIR}/generated"
VERBATIM
)
add_custom_command(
OUTPUT ${PROJECT_SOURCE_DIR}/generated/union.h
DEPENDS sdv_idl_compiler
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/union.idl
COMMENT "Build union.idl"
COMMAND ${SDVIDL} "${PROJECT_SOURCE_DIR}/union.idl" "-I${PROJECT_SOURCE_DIR}/../../../export" "-O${PROJECT_SOURCE_DIR}/generated"
VERBATIM
)
add_custom_command(
OUTPUT ${PROJECT_SOURCE_DIR}/generated/interfaces.h
DEPENDS sdv_idl_compiler
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/interfaces.idl
COMMENT "Build interfaces.idl"
COMMAND ${SDVIDL} "${PROJECT_SOURCE_DIR}/interfaces.idl" "-I${PROJECT_SOURCE_DIR}/../../../export" "-O${PROJECT_SOURCE_DIR}/generated"
VERBATIM
)
add_custom_command(
OUTPUT ${PROJECT_SOURCE_DIR}/generated/test_ifc_id1.h
DEPENDS sdv_idl_compiler
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/test_ifc_id1.idl
COMMENT "Build test_ifc_id1.idl"
COMMAND ${SDVIDL} "${PROJECT_SOURCE_DIR}/test_ifc_id1.idl" "-I${PROJECT_SOURCE_DIR}/../../../export" "-O${PROJECT_SOURCE_DIR}/generated" --no_ps
VERBATIM
)
add_custom_command(
OUTPUT ${PROJECT_SOURCE_DIR}/generated/test_ifc_id2.h
DEPENDS sdv_idl_compiler
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/test_ifc_id2.idl
COMMENT "Build test_ifc_id2.idl"
COMMAND ${SDVIDL} "${PROJECT_SOURCE_DIR}/test_ifc_id2.idl" "-I${PROJECT_SOURCE_DIR}/../../../export" "-O${PROJECT_SOURCE_DIR}/generated" --no_ps
VERBATIM
)
set_source_files_properties(generator_interface_id_test.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test.h)
set_source_files_properties(generator_ps_test.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/test.h)
set_source_files_properties(generator_ps_interface_test.cpp OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/generated/interfaces.h)
# Get xxHash from github
include(FetchContent)
FetchContent_Declare(
xxhash
GIT_REPOSITORY https://github.com/Cyan4973/xxHash.git
GIT_TAG v0.8.1
)
FetchContent_MakeAvailable(xxhash)
# Add include directories
include_directories(../../../export ${xxhash_SOURCE_DIR})
# Compile the source code
add_executable(UnitTest_IDLCompiler
"generated/linked.h"
"generated/test.h"
"generated/array.h"
"generated/test_ifc_id1.h"
"generated/test_ifc_id2.h"
"generated/union.h"
"main.cpp"
"lexer_test.cpp"
"parser_test.cpp"
"preproc_test.cpp"
"source_test.cpp"
"code_to_text_test.cpp"
"parser_module_test.cpp"
"constvariant_test.cpp"
"parser_const_assignment_test.cpp"
"parser_var_assignment_test.cpp"
"parser_interface_test.cpp"
"parser_struct_test.cpp"
"parser_typedef_test.cpp"
"parser_exception_test.cpp"
"parser_union_test.cpp"
"parser_enum_test.cpp"
"commandline_test.cpp"
"parser_meta_test.cpp"
"parser_meta_test.cpp"
"generator_interface_id_test.cpp"
"generator_ps_test.cpp"
"generator_test.cpp"
"generator_test.h"
"generator_ps_interface_test.cpp"
"compiler_test.cpp"
"idl_interface_id_compatibility.cpp"
"parser_ext_test.cpp"
)
target_link_libraries(UnitTest_IDLCompiler ${CMAKE_DL_LIBS} GTest::GTest)
# Add the IDL Compiler unittest
add_test(NAME UnitTest_IDLCompiler COMMAND UnitTest_IDLCompiler)
# Execute the test
add_custom_command(TARGET UnitTest_IDLCompiler POST_BUILD
COMMAND ${CMAKE_COMMAND} -E env TEST_EXECUTION_MODE=CMake "$<TARGET_FILE:UnitTest_IDLCompiler>" "--gtest_output=xml:${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/UnitTest_IDLCompiler.xml"
VERBATIM
)
# The unit-test project depends on a proper compilation of the compiler before
add_dependencies(UnitTest_IDLCompiler dependency_sdv_components)

View File

@@ -0,0 +1,54 @@
const int32 iGlobalLength = 32;
const char szGlobalArray1[] = "12345678901234567890123456789801";
const char szGlobalArray2[32] = "1234567890123456789012345678901";
const char szGlobalArray3[iGlobalLength] = "1234567890123456789012345678901";
//const char rgszGlobalArray4[4][] = { "1234567", "1234567", "1234567", "1234567" };
const char rgszGlobalArray5[4][8] = { "1234567", "1234567", "1234567", "1234567" };
const char rgszGlobalArray6[4][iGlobalLength/4] = { "1234567", "1234567", "1234567", "1234567" };
struct SFixedArrayLength
{
const int32 iStaticLength = 32;
char szArray1[32];
char szArray2[iGlobalLength];
char szArray3[iStaticLength];
char szArray5[4][iGlobalLength / 4];
char szArray6[4][iStaticLength / 4];
char szArray8[iGlobalLength / 4][4];
char szArray9[iStaticLength / 4][4];
};
struct SArrayTest
{
// Member variable
uint32 rguiValSingle[10];
uint32 rguiValMulti[4][3][2];
// Const variable
const uint32 rgConstValSingle[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
const uint32 rgConstValMulti[4][3][2] = {{{011, 012}, {021, 022}, {031, 032}},
{{111, 112}, {121, 122}, {131, 132}},
{{211, 212}, {221, 222}, {231, 232}},
{{311, 312}, {321, 322}, {331, 332}}};
const uint32 rgConstValUnboundSingle[] = {10, 20, 30, 40};
//const uint32 rgConstValUnboundMulti[2][] = {{10, 20, 30, 40}, {50, 60, 70, 80}};
// Typedef
typedef uint32 TArray;
typedef uint32 TArraySingle[10];
typedef uint32 TArrayMulti[3][2];
typedef uint32 TArrayUnbound[];
TArray tArrayVar = 10;
TArray tArrayVarArry[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
TArraySingle tArraySingleVar = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
TArraySingle tArraySingleVarArray[2] = {{10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, {10, 20, 30, 40, 50, 60, 70, 80, 90, 100}};
TArrayMulti tArrayMultiVar[4] = {{{011, 012}, {021, 022}, {031, 032}},
{{111, 112}, {121, 122}, {131, 132}},
{{211, 212}, {221, 222}, {231, 232}},
{{311, 312}, {321, 322}, {331, 332}}};
//TArrayUnbound tArrayUnboundVar = {10, 20, 30}; // TODO --> Error... only with const
//TArrayUnbound tARrayUnboundVar2[2] = {{20, 30, 40}, {120, 130, 140}}; // TODO --> Error... only with const
//TArrayUnbound tARrayUnboundVar3[2] = {{30, 40}, {120, 130, 140}}; // TODO --> Error... only with const and invalid size
};

View File

@@ -0,0 +1,444 @@
#include "includes.h"
#include "lexer_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/support.h"
using CText2CTextTranslator = CLexerTest;
TEST_F(CText2CTextTranslator, InterpretCTextAscii)
{
std::string ssResult;
uint32_t uiByteCnt = 0;
// Standard text
EXPECT_NO_THROW(InterpretCText("Hello", nullptr, ssResult, uiByteCnt, false, true));
EXPECT_EQ(ssResult, "Hello");
EXPECT_EQ(uiByteCnt, 5u);
// Text with escape sequence
EXPECT_NO_THROW(InterpretCText("Hello\\nYou there", nullptr, ssResult, uiByteCnt, false, true));
EXPECT_EQ(ssResult, "Hello\nYou there");
EXPECT_EQ(uiByteCnt, 16u);
}
TEST_F(CText2CTextTranslator, InterpretCTextUTF8)
{
std::string ssResult;
uint32_t uiByteCnt = 0;
// Standard text
EXPECT_NO_THROW(InterpretCText("Hello", nullptr, ssResult, uiByteCnt, false));
EXPECT_EQ(ssResult, "Hello");
EXPECT_EQ(uiByteCnt, 5u);
// Text with escape sequence
EXPECT_NO_THROW(InterpretCText("Hello\\nYou there", nullptr, ssResult, uiByteCnt, false));
EXPECT_EQ(ssResult, "Hello\nYou there");
EXPECT_EQ(uiByteCnt, 16u);
}
TEST_F(CText2CTextTranslator, InterpretCTextUTF16)
{
std::u16string ssResult;
uint32_t uiByteCnt = 0;
// Standard text
EXPECT_NO_THROW(InterpretCText("Hello", nullptr, ssResult, uiByteCnt, false));
EXPECT_EQ(ssResult, u"Hello");
EXPECT_EQ(uiByteCnt, 5u);
// Text with escape sequence
EXPECT_NO_THROW(InterpretCText("Hello\\nYou there", nullptr, ssResult, uiByteCnt, false));
EXPECT_EQ(ssResult, u"Hello\nYou there");
EXPECT_EQ(uiByteCnt, 16u);
}
TEST_F(CText2CTextTranslator, InterpretCTextUTF32)
{
std::u32string ssResult;
uint32_t uiByteCnt = 0;
// Standard text
EXPECT_NO_THROW(InterpretCText("Hello", nullptr, ssResult, uiByteCnt, false));
EXPECT_EQ(ssResult, U"Hello");
EXPECT_EQ(uiByteCnt, 5u);
// Text with escape sequence
EXPECT_NO_THROW(InterpretCText("Hello\\nYou there", nullptr, ssResult, uiByteCnt, false));
EXPECT_EQ(ssResult, U"Hello\nYou there");
EXPECT_EQ(uiByteCnt, 16u);
}
TEST_F(CText2CTextTranslator, InterpretCTextWide)
{
std::wstring ssResult;
uint32_t uiByteCnt = 0;
// Standard text
EXPECT_NO_THROW(InterpretCText("Hello", nullptr, ssResult, uiByteCnt, false));
EXPECT_EQ(ssResult, L"Hello");
EXPECT_EQ(uiByteCnt, 5u);
// Text with escape sequence
EXPECT_NO_THROW(InterpretCText("Hello\\nYou there", nullptr, ssResult, uiByteCnt, false));
EXPECT_EQ(ssResult, L"Hello\nYou there");
EXPECT_EQ(uiByteCnt, 16u);
}
TEST_F(CText2CTextTranslator, InterpretCTextCodePos)
{
std::string ssResult;
uint32_t uiByteCnt = 0;
// Standard text
EXPECT_NO_THROW(InterpretCText(CCodePos("Hello"), nullptr, ssResult, uiByteCnt, false, true));
EXPECT_EQ(ssResult, "Hello");
EXPECT_EQ(uiByteCnt, 5u);
// Text with escape sequence
EXPECT_NO_THROW(InterpretCText(CCodePos("Hello\\nYou there"), nullptr, ssResult, uiByteCnt, false, true));
EXPECT_EQ(ssResult, "Hello\nYou there");
EXPECT_EQ(uiByteCnt, 16u);
}
TEST_F(CText2CTextTranslator, InterpretCTextWithDelimiter)
{
std::string ssResult;
uint32_t uiByteCnt = 0;
// Standard text
const char szCodeText1[] = "const char* sz = \"This is a text\";";
EXPECT_NO_THROW(InterpretCText(szCodeText1 + 18, "\"", ssResult, uiByteCnt, false, true));
EXPECT_EQ(ssResult, "This is a text");
EXPECT_EQ(uiByteCnt, 14u);
// Escape character text
const char szCodeText2[] = "const char* sz = \"This is a\\ntext\";";
EXPECT_NO_THROW(InterpretCText(szCodeText2 + 18, "\"", ssResult, uiByteCnt, false, true));
EXPECT_EQ(ssResult, "This is a\ntext");
EXPECT_EQ(uiByteCnt, 15u);
// Standard char
const char szCodeChar1[] = "const char c = \'T\';";
EXPECT_NO_THROW(InterpretCText(szCodeChar1 + 16, "\'", ssResult, uiByteCnt, false, true));
EXPECT_EQ(ssResult, "T");
EXPECT_EQ(uiByteCnt, 1u);
// Escaped char
const char szCodeChar2[] = "const char c = \'\\a\';";
EXPECT_NO_THROW(InterpretCText(szCodeChar2 + 16, "\'", ssResult, uiByteCnt, false, true));
EXPECT_EQ(ssResult, "\a");
EXPECT_EQ(uiByteCnt, 2u);
// Raw text
const char szCodeRaw1[] = R"code(abc(this is a delimiter check)abc)code";
EXPECT_NO_THROW(InterpretCText(szCodeRaw1 + 4, ")abc", ssResult, uiByteCnt, true, true));
EXPECT_EQ(ssResult, "this is a delimiter check");
EXPECT_EQ(uiByteCnt, 25u);
// Raw text with newline
const char szCodeRaw2[] = R"code(abc(this is a delimiter\check)abc)code";
EXPECT_NO_THROW(InterpretCText(szCodeRaw2 + 4, ")abc", ssResult, uiByteCnt, true, true));
EXPECT_EQ(ssResult, "this is a delimiter\\check");
EXPECT_EQ(uiByteCnt, 25u);
}
TEST_F(CText2CTextTranslator, InterpretEscapedCText)
{
std::string ssResult;
uint32_t uiByteCnt = 0;
// Default escaped
const char szEscapedCode1[] = "\\\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v\\265\\40\\xB5\\xb5";
EXPECT_NO_THROW(InterpretCText(szEscapedCode1, nullptr, ssResult, uiByteCnt, false, true));
EXPECT_EQ(ssResult, "\'\"?\\\a\b\f\n\r\t\v\265 \265\265");
EXPECT_EQ(uiByteCnt, 37u);
// Invalid escapes
const char szInvalidEscape1[] = "\\p";
EXPECT_THROW(InterpretCText(szInvalidEscape1, nullptr, ssResult, uiByteCnt, false, true), CCompileException);
const char szInvalidEscape2[] = "\\400";
EXPECT_THROW(InterpretCText(szInvalidEscape2, nullptr, ssResult, uiByteCnt, false, true), CCompileException);
const char szInvalidEscape3[] = "\\xx";
EXPECT_THROW(InterpretCText(szInvalidEscape3, nullptr, ssResult, uiByteCnt, false, true), CCompileException);
}
TEST_F(CText2CTextTranslator, InterpretEscapedCTextUnicodeASCII)
{
std::string ssResult;
uint32_t uiByteCnt = 0;
// Default escaped
const char szEscapedCode1[] = "\\u0040\\u00ff\\U00000040\\U000000FF";
EXPECT_NO_THROW(InterpretCText(szEscapedCode1, nullptr, ssResult, uiByteCnt, false, true));
EXPECT_EQ(ssResult, "@\xff@\xff");
EXPECT_EQ(uiByteCnt, 32u);
// Invalid escaped
const char szInvalidEscaped1[] = "\\u0140"; // ASCII doesn't support this character
EXPECT_THROW(InterpretCText(szInvalidEscaped1, nullptr, ssResult, uiByteCnt, false, true), CCompileException);
const char szInvalidEscaped2[] = "\\u040xyz"; // Invalid code
EXPECT_THROW(InterpretCText(szInvalidEscaped2, nullptr, ssResult, uiByteCnt, false, true), CCompileException);
const char szInvalidEscaped3[] = "\\U0000000"; // Invalid code
EXPECT_THROW(InterpretCText(szInvalidEscaped3, nullptr, ssResult, uiByteCnt, false, true), CCompileException);
const char szInvalidEscaped4[] = "\\uD800"; // Reserved code
EXPECT_THROW(InterpretCText(szInvalidEscaped4, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped5[] = "\\udfff"; // Reserved code
EXPECT_THROW(InterpretCText(szInvalidEscaped5, nullptr, ssResult, uiByteCnt, false), CCompileException);
}
TEST_F(CText2CTextTranslator, InterpretEscapedCTextUnicodeUTF8)
{
std::string ssResult;
uint32_t uiByteCnt = 0;
// Default escaped
const char szEscapedCode1[] = "\\u0040\\u00ff\\U00000040\\U000000FF\\u0024\\u00a3\\u0939\\u20AC\\ud55c\\U00010348";
EXPECT_NO_THROW(InterpretCText(szEscapedCode1, nullptr, ssResult, uiByteCnt, false));
EXPECT_EQ(ssResult, u8"@\u00ff@\u00ff\u0024\u00a3\u0939\u20AC\ud55c\U00010348");
// ATTENTION: The following line will run okay with MSVC, but causes an error with GNU-C. This is because GNU-C is translating
// the string u8"\xff" wronly in "\xFF", whereas it should translate to "\xC3\xBF".
// EXPECT_EQ(ssResult, u8"@\xff@\xff\u0024\u00a3\u0939\u20AC\ud55c\U00010348");
EXPECT_EQ(uiByteCnt, 72u);
// Invalid escaped
const char szInvalidEscaped1[] = "\\u040xyz"; // Invalid code
EXPECT_THROW(InterpretCText(szInvalidEscaped1, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped2[] = "\\U0000000"; // Invalid code
EXPECT_THROW(InterpretCText(szInvalidEscaped2, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped3[] = "\\uD800"; // Reserved code
EXPECT_THROW(InterpretCText(szInvalidEscaped3, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped4[] = "\\udfff"; // Reserved code
EXPECT_THROW(InterpretCText(szInvalidEscaped4, nullptr, ssResult, uiByteCnt, false), CCompileException);
}
TEST_F(CText2CTextTranslator, InterpretEscapedCTextUnicodeUTF16)
{
std::u16string ssResult;
uint32_t uiByteCnt = 0;
// Default escaped
const char szEscapedCode1[] = "\\u0040\\u00ff\\U00000040\\U000000FF\\u0024\\u00a3\\u0939\\u20AC\\ud55c\\U00010348";
EXPECT_NO_THROW(InterpretCText(szEscapedCode1, nullptr, ssResult, uiByteCnt, false));
EXPECT_EQ(ssResult, u"@\xff@\xff\u0024\u00a3\u0939\u20AC\ud55c\U00010348");
EXPECT_EQ(uiByteCnt, 72u);
// Invalid escaped
const char szInvalidEscaped1[] = "\\u040xyz"; // Invalid code
EXPECT_THROW(InterpretCText(szInvalidEscaped1, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped2[] = "\\U0000000"; // Invalid code
EXPECT_THROW(InterpretCText(szInvalidEscaped2, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped3[] = "\\uD800"; // Reserved code
EXPECT_THROW(InterpretCText(szInvalidEscaped3, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped4[] = "\\udfff"; // Reserved code
EXPECT_THROW(InterpretCText(szInvalidEscaped4, nullptr, ssResult, uiByteCnt, false), CCompileException);
}
TEST_F(CText2CTextTranslator, InterpretEscapedCTextUnicodeUTF32)
{
std::u32string ssResult;
uint32_t uiByteCnt = 0;
// Default escaped
const char szEscapedCode1[] = "\\u0040\\u00ff\\U00000040\\U000000FF\\u0024\\u00a3\\u0939\\u20AC\\ud55c\\U00010348";
EXPECT_NO_THROW(InterpretCText(szEscapedCode1, nullptr, ssResult, uiByteCnt, false));
EXPECT_EQ(ssResult, U"@\xff@\xff\u0024\u00a3\u0939\u20AC\ud55c\U00010348");
EXPECT_EQ(uiByteCnt, 72u);
// Invalid escaped
const char szInvalidEscaped1[] = "\\u040xyz"; // Invalid code
EXPECT_THROW(InterpretCText(szInvalidEscaped1, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped2[] = "\\U0000000"; // Invalid code
EXPECT_THROW(InterpretCText(szInvalidEscaped2, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped3[] = "\\uD800"; // Reserved code
EXPECT_THROW(InterpretCText(szInvalidEscaped3, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped4[] = "\\udfff"; // Reserved code
EXPECT_THROW(InterpretCText(szInvalidEscaped4, nullptr, ssResult, uiByteCnt, false), CCompileException);
}
TEST_F(CText2CTextTranslator, InterpretEscapedCTextUnicodeWide)
{
std::wstring ssResult;
uint32_t uiByteCnt = 0;
// Default escaped
const char szEscapedCode1[] = "\\u0040\\u00ff\\U00000040\\U000000FF\\u0024\\u00a3\\u0939\\u20AC\\ud55c\\U00010348";
EXPECT_NO_THROW(InterpretCText(szEscapedCode1, nullptr, ssResult, uiByteCnt, false));
EXPECT_EQ(ssResult, L"@\xff@\xff\u0024\u00a3\u0939\u20AC\ud55c\U00010348");
EXPECT_EQ(uiByteCnt, 72u);
// Invalid escaped
const char szInvalidEscaped1[] = "\\u040xyz"; // Invalid code
EXPECT_THROW(InterpretCText(szInvalidEscaped1, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped2[] = "\\U0000000"; // Invalid code
EXPECT_THROW(InterpretCText(szInvalidEscaped2, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped3[] = "\\uD800"; // Reserved code
EXPECT_THROW(InterpretCText(szInvalidEscaped3, nullptr, ssResult, uiByteCnt, false), CCompileException);
const char szInvalidEscaped4[] = "\\udfff"; // Reserved code
EXPECT_THROW(InterpretCText(szInvalidEscaped4, nullptr, ssResult, uiByteCnt, false), CCompileException);
}
TEST_F(CText2CTextTranslator, GenerateCTextASCIIString)
{
std::string ssResult;
// Standard text
EXPECT_EQ(GenerateCText("Hello", 0xFFFFFFFF, true), "Hello");
// Text with escape sequence
EXPECT_EQ(GenerateCText("Hello\nYou there", 0xFFFFFFFF, true), "Hello\\nYou there");
// Limited text with escape sequence
EXPECT_EQ(GenerateCText("Hello\nYou there", 9, true), "Hello\\nYou");
}
TEST_F(CText2CTextTranslator, GenerateCTextUTF8String)
{
std::string ssResult;
// Standard text
EXPECT_EQ(GenerateCText(u8"Hello"), "Hello");
// Text with escape sequence
EXPECT_EQ(GenerateCText(u8"Hello\nYou there"), "Hello\\nYou there");
// Limited text with escape sequence
EXPECT_EQ(GenerateCText(u8"Hello\nYou there", 9), "Hello\\nYou");
}
TEST_F(CText2CTextTranslator, GenerateCTextUTF16String)
{
std::string ssResult;
// Standard text
EXPECT_EQ(GenerateCText(u"Hello"), "Hello");
// Text with escape sequence
EXPECT_EQ(GenerateCText(u"Hello\nYou there"), "Hello\\nYou there");
// Limited text with escape sequence
EXPECT_EQ(GenerateCText(u"Hello\nYou there", 9), "Hello\\nYou");
}
TEST_F(CText2CTextTranslator, GenerateCTextUTF32String)
{
std::string ssResult;
// Standard text
EXPECT_EQ(GenerateCText(U"Hello"), "Hello");
// Text with escape sequence
EXPECT_EQ(GenerateCText(U"Hello\nYou there"), "Hello\\nYou there");
// Limited text with escape sequence
EXPECT_EQ(GenerateCText(U"Hello\nYou there", 9), "Hello\\nYou");
}
TEST_F(CText2CTextTranslator, GenerateCTextWideString)
{
std::string ssResult;
// Standard text
EXPECT_EQ(GenerateCText(L"Hello"), "Hello");
// Text with escape sequence
EXPECT_EQ(GenerateCText(L"Hello\nYou there"), "Hello\\nYou there");
// Limited text with escape sequence
EXPECT_EQ(GenerateCText(L"Hello\nYou there", 9), "Hello\\nYou");
}
TEST_F(CText2CTextTranslator, GenerateCTextASCIIChar)
{
std::string ssResult;
// Standard text
EXPECT_EQ(GenerateCText('H', true), "H");
// Text with escape sequence
EXPECT_EQ(GenerateCText('\n', true), "\\n");
}
TEST_F(CText2CTextTranslator, GenerateCTextUTF8Char)
{
std::string ssResult;
// Standard text
EXPECT_EQ(GenerateCText(u8'H'), "H");
// Text with escape sequence
EXPECT_EQ(GenerateCText(u8'\n'), "\\n");
}
TEST_F(CText2CTextTranslator, GenerateCTextUTF16Char)
{
std::string ssResult;
// Standard text
EXPECT_EQ(GenerateCText(u'H'), "H");
// Text with escape sequence
EXPECT_EQ(GenerateCText(u'\n'), "\\n");
}
TEST_F(CText2CTextTranslator, GenerateCTextUTF32Char)
{
std::string ssResult;
// Standard text
EXPECT_EQ(GenerateCText(U'H'), "H");
// Text with escape sequence
EXPECT_EQ(GenerateCText(U'\n'), "\\n");
}
TEST_F(CText2CTextTranslator, GenerateCTextWideChar)
{
std::string ssResult;
// Standard text
EXPECT_EQ(GenerateCText(L'H'), "H");
// Text with escape sequence
EXPECT_EQ(GenerateCText(L'\n'), "\\n");
}
TEST_F(CText2CTextTranslator, GenerateEscapedCTextFromString)
{
// Default escaped
EXPECT_EQ(GenerateCText("\'\"?\\\a\b\f\n\r\t\v\265 \xB5\xb5", 0xFFFFFFFF, true),
"\\\'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\\265 \\265\\265");
}
TEST_F(CText2CTextTranslator, GenerateUnicodeEscapedCTextFromUTF8String)
{
// Default escaped
EXPECT_EQ(GenerateCText(u8"@\u00ff@\u00ff\u0024\u00a3\u0939\u20AC\ud55c\U00010348"),
"@\\u00ff@\\u00ff$\\u00a3\\u0939\\u20ac\\ud55c\\U00010348");
// ATTENTION: The following line will run okay with MSVC, but causes an error with GNU-C. This is because GNU-C is translating
// the string u8"\xff" wronly in "\xFF" and combines it with u8"\u0024" to "\U003c0fe4".
// EXPECT_EQ(GenerateCText(u8"@\xff@\xff\u0024\u00a3\u0939\u20AC\ud55c\U00010348"),
// "@\\u00ff@\\u00ff$\\u00a3\\u0939\\u20ac\\ud55c\\U00010348");
}
TEST_F(CText2CTextTranslator, GenerateUnicodeEscapedCTextFromUTF16String)
{
// Default escaped
EXPECT_EQ(GenerateCText(u"@\xff@\xff\u0024\u00a3\u0939\u20AC\ud55c\U00010348"),
"@\\u00ff@\\u00ff$\\u00a3\\u0939\\u20ac\\ud55c\\U00010348");
}
TEST_F(CText2CTextTranslator, GenerateUnicodeEscapedCTextFromUTF32String)
{
// Default escaped
EXPECT_EQ(GenerateCText(U"@\xff@\xff\u0024\u00a3\u0939\u20AC\ud55c\U00010348"),
"@\\u00ff@\\u00ff$\\u00a3\\u0939\\u20ac\\ud55c\\U00010348");
}
TEST_F(CText2CTextTranslator, GenerateUnicodeEscapedCTextFromWideString)
{
// Default escaped
EXPECT_EQ(GenerateCText(L"@\xff@\xff\u0024\u00a3\u0939\u20AC\ud55c\U00010348"),
"@\\u00ff@\\u00ff$\\u00a3\\u0939\\u20ac\\ud55c\\U00010348");
}

View File

@@ -0,0 +1,224 @@
#include "includes.h"
#include "lexer_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/core_idl_backup.h"
#include "../../../global/cmdlnparser/cmdlnparser.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/environment.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/logger.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/exception.h"
using CCommandLineTest = CLexerTest;
TEST_F(CCommandLineTest, UnknownOption)
{
// Note: 1st argument is the executable file path.
CIdlCompilerEnvironment env;
std::vector<std::string> vecCLOption1 = { "idl_compiler_test", "-xyz"};
EXPECT_THROW(env = CIdlCompilerEnvironment(vecCLOption1), CCompileException);
#ifdef _WIN32
std::vector<std::string> vecCLOption2 = { "idl_compiler_test", "/xyz"};
EXPECT_THROW(env = CIdlCompilerEnvironment(vecCLOption2), CCompileException);
#endif
std::vector<std::string> vecCLOption3 = { "idl_compiler_test", "--xyz"};
EXPECT_THROW(env = CIdlCompilerEnvironment(vecCLOption3), CCompileException);
std::vector<std::string> vecCLOption4 = { "idl_compiler_test", "--help", "-xyz"};
EXPECT_THROW(env = CIdlCompilerEnvironment(vecCLOption4), CCompileException);
#ifdef _WIN32
std::vector<std::string> vecCLOption5 = { "idl_compiler_test", "--help", "/xyz"};
EXPECT_THROW(env = CIdlCompilerEnvironment(vecCLOption5), CCompileException);
#endif
}
TEST_F(CCommandLineTest, CommandLineHelp)
{
// Note: 1st argument is the executable file path.
CIdlCompilerEnvironment env;
std::vector<std::string> vecCLHelp1 = { "idl_compiler_test", "--help" };
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecCLHelp1)).Help());
#ifdef _WIN32
std::vector<std::string> vecCLHelp2 = { "idl_compiler_test", "/?" };
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecCLHelp2)).Help());
#endif
std::vector<std::string> vecCLHelp3 = { "idl_compiler_test", "-?" };
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecCLHelp3)).Help());
std::vector<std::string> vecCLHelp4 = { "idl_compiler_test", "--version", "--help" };
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecCLHelp4)).Help());
}
TEST_F(CCommandLineTest, CommandLineVersion)
{
// Note: 1st argument is the executable file path.
CIdlCompilerEnvironment env;
std::vector<std::string> vecCLVersion1 = { "idl_compiler_test", "--version"};
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecCLVersion1)).Version());
std::vector<std::string> vecCLVersion2 = { "idl_compiler_test", "--help", "--version"};
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecCLVersion2)).Version());
}
TEST_F(CCommandLineTest, CommandLineIncludeDirs)
{
// Note: 1st argument is the executable file path.
CIdlCompilerEnvironment env;
std::vector<std::string> vecCLIncludeDirs1 = { "idl_compiler_test", "-IHello", "-I../Hoho"};
std::vector<std::filesystem::path> vecIncludeDirs1 =
CIdlCompilerEnvironment(vecCLIncludeDirs1).GetIncludeDirs();
ASSERT_EQ(vecIncludeDirs1.size(), 2);
EXPECT_EQ(vecIncludeDirs1[0], "Hello");
EXPECT_EQ(vecIncludeDirs1[1], "../Hoho");
#ifdef _WIN32
std::vector<std::string> vecCLIncludeDirs2 = { "idl_compiler_test", "/IHello", "/I..\\Hoho"};
std::vector<std::filesystem::path> vecIncludeDirs2 =
CIdlCompilerEnvironment(vecCLIncludeDirs2).GetIncludeDirs();
ASSERT_EQ(vecIncludeDirs2.size(), 2);
EXPECT_EQ(vecIncludeDirs2[0], "Hello");
EXPECT_EQ(vecIncludeDirs2[1], "..\\Hoho");
#endif
}
TEST_F(CCommandLineTest, CommandLineOutputDir)
{
// Note: 1st argument is the executable file path.
CIdlCompilerEnvironment env;
std::vector<std::string> vecCLOutputDir1 = { "idl_compiler_test", "-OHello" };
std::filesystem::path pathOutputDir1 = CIdlCompilerEnvironment(vecCLOutputDir1).GetOutputDir();
EXPECT_EQ(pathOutputDir1, "Hello");
#ifdef _WIN32
std::vector<std::string> vecCLOutputDir2 = { "idl_compiler_test", "/OHello" };
std::filesystem::path pathOutputDir2 = CIdlCompilerEnvironment(vecCLOutputDir2).GetOutputDir();
EXPECT_EQ(pathOutputDir2, "Hello");
#endif
std::vector<std::string> vecCLOutputDir3 = { "idl_compiler_test", "-OHello", "-OHello2" };
EXPECT_THROW((env = CIdlCompilerEnvironment(vecCLOutputDir3)).GetOutputDir(), CCompileException);
}
TEST_F(CCommandLineTest, CommandLineDefines)
{
// Note: 1st argument is the executable file path.
CIdlCompilerEnvironment env;
std::vector<std::string> vecCLDefine1 = { "idl_compiler_test", "-DTEST"};
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecCLDefine1)).Defined("TEST"));
#ifdef _WIN32
std::vector<std::string> vecCLDefine2 = { "idl_compiler_test", "/DTEST"};
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecCLDefine2)).Defined("TEST"));
#endif
std::vector<std::string> vecCLDefine3 = { "idl_compiler_test", "-DTEST", "-DTEST"};
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecCLDefine3)).Defined("TEST"));
std::vector<std::string> vecCLDefine4 = { "idl_compiler_test", "-DTEST=2"};
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecCLDefine4)).Defined("TEST"));
std::vector<std::string> vecCLDefine5 = { "idl_compiler_test", "-DTEST(a,b,c)=a+b+c"};
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecCLDefine5)).Defined("TEST"));
std::vector<std::string> vecCLDefine6 = { "idl_compiler_test", "-DTEST", "-DTEST=2"};
EXPECT_THROW(env = CIdlCompilerEnvironment(vecCLDefine6), CCompileException);
}
TEST_F(CCommandLineTest, CommandLineResolveConst)
{
// Note: 1st argument is the executable file path.
CIdlCompilerEnvironment env;
std::vector<std::string> vecResolveConst = { "idl_compiler_test", "--resolve_const"};
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecResolveConst)).ResolveConst());
}
TEST_F(CCommandLineTest, CommandLineNoPS)
{
// Note: 1st argument is the executable file path.
CIdlCompilerEnvironment env;
std::vector<std::string> vecNoPS = { "idl_compiler_test", "--no_ps" };
EXPECT_TRUE((env = CIdlCompilerEnvironment(vecNoPS)).NoProxyStub());
}
TEST_F(CCommandLineTest, CommandLineProxyStubLibName)
{
// Note: 1st argument is the executable file path.
CIdlCompilerEnvironment env;
std::vector<std::string> vecProxyStub = { "idl_compiler_test" };
auto ssLibName = CIdlCompilerEnvironment(vecProxyStub).GetProxStubCMakeTarget();
EXPECT_EQ(ssLibName, "proxystub");
vecProxyStub.push_back("--ps_lib_nameExampleString");
ssLibName = CIdlCompilerEnvironment(vecProxyStub).GetProxStubCMakeTarget();
EXPECT_EQ(ssLibName, "ExampleString");
}
TEST_F(CCommandLineTest, CommandLineExtensions)
{
// Note: 1st argument is the executable file path.
CIdlCompilerEnvironment env;
EXPECT_TRUE(env.InterfaceTypeExtension());
std::vector<std::string> vec = { "idl_compiler_test", "--interface_type-" };
EXPECT_FALSE((env = CIdlCompilerEnvironment(vec)).InterfaceTypeExtension());
vec[1] = "--interface_type+";
EXPECT_TRUE((env = CIdlCompilerEnvironment(vec)).InterfaceTypeExtension());
EXPECT_TRUE(env.ExceptionTypeExtension());
vec[1] = "--exception_type-";
EXPECT_FALSE((env = CIdlCompilerEnvironment(vec)).ExceptionTypeExtension());
vec[1] = "--exception_type+";
EXPECT_TRUE((env = CIdlCompilerEnvironment(vec)).ExceptionTypeExtension());
EXPECT_TRUE(env.PointerTypeExtension());
vec[1] = "--pointer_type-";
EXPECT_FALSE((env = CIdlCompilerEnvironment(vec)).PointerTypeExtension());
vec[1] = "--pointer_type+";
EXPECT_TRUE((env = CIdlCompilerEnvironment(vec)).PointerTypeExtension());
EXPECT_TRUE(env.UnicodeExtension());
vec[1] = "--unicode_char-";
EXPECT_FALSE((env = CIdlCompilerEnvironment(vec)).UnicodeExtension());
vec[1] = "--unicode_char+";
EXPECT_TRUE((env = CIdlCompilerEnvironment(vec)).UnicodeExtension());
EXPECT_TRUE(env.CaseSensitiveTypeExtension());
vec[1] = "--case_sensitive-";
EXPECT_FALSE((env = CIdlCompilerEnvironment(vec)).CaseSensitiveTypeExtension());
vec[1] = "--case_sensitive+";
EXPECT_TRUE((env = CIdlCompilerEnvironment(vec)).CaseSensitiveTypeExtension());
EXPECT_TRUE(env.ContextDependentNamesExtension());
vec[1] = "--context_names-";
EXPECT_FALSE((env = CIdlCompilerEnvironment(vec)).ContextDependentNamesExtension());
vec[1] = "--context_names+";
EXPECT_TRUE((env = CIdlCompilerEnvironment(vec)).ContextDependentNamesExtension());
EXPECT_TRUE(env.MultiDimArrayExtension());
vec[1] = "--multi_dimensional_array-";
EXPECT_FALSE((env = CIdlCompilerEnvironment(vec)).MultiDimArrayExtension());
vec[1] = "--multi_dimensional_array+";
EXPECT_TRUE((env = CIdlCompilerEnvironment(vec)).MultiDimArrayExtension());
}
TEST_F(CCommandLineTest, CommandLineStrict)
{
// Note: 1st argument is the executable file path.
CIdlCompilerEnvironment env;
#ifdef _WIN32
std::vector<std::string> vec = { "idl_compiler_test", "--strict" };
#else
std::vector<std::string> vec = { "idl_compiler_test", "--strict" };
#endif
EXPECT_TRUE(env.InterfaceTypeExtension());
EXPECT_TRUE(env.ExceptionTypeExtension());
EXPECT_TRUE(env.UnicodeExtension());
EXPECT_TRUE(env.CaseSensitiveTypeExtension());
EXPECT_TRUE(env.ContextDependentNamesExtension());
EXPECT_TRUE(env.MultiDimArrayExtension());
env = CIdlCompilerEnvironment(vec);
EXPECT_FALSE(env.InterfaceTypeExtension());
EXPECT_FALSE(env.ExceptionTypeExtension());
EXPECT_FALSE(env.UnicodeExtension());
EXPECT_FALSE(env.CaseSensitiveTypeExtension());
EXPECT_FALSE(env.ContextDependentNamesExtension());
EXPECT_FALSE(env.MultiDimArrayExtension());
}
TEST_F(CCommandLineTest, CommandLineDefaultArg)
{
// Note: 1st argument is the executable file path.
std::vector<std::string> vec = { "idl_compiler_test", "test1.idl", "test2.idl"};
CIdlCompilerEnvironment env(vec);
std::filesystem::path pathFile = env.GetNextFile();
EXPECT_EQ(pathFile, "test1.idl");
pathFile = env.GetNextFile();
EXPECT_EQ(pathFile, "test2.idl");
pathFile = env.GetNextFile();
EXPECT_TRUE(pathFile.empty());
}

View File

@@ -0,0 +1,555 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
#include "../../../sdv_executables/sdv_idl_compiler/generator/context.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/generator/ps_class_generator_base.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/generator/definition_generator.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/generator/proxy_generator.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/generator/stub_generator.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/generator/serdes_generator.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/generator/cmake_generator.cpp"
/**
* @brief IDL file management class.
*/
class CIdlFile
{
public:
/**
* @brief Constructor
* @param[in] rssIdlCode Reference to the string containing the code to store in the IDL file.
*/
CIdlFile(const std::string& rssIdlCode) : m_pathIdl(std::filesystem::current_path() / "test.idl")
{
// Start clean
CleanUp();
// Create a stream and write the code.
std::ofstream fstreamIdlFile(m_pathIdl.c_str());
fstreamIdlFile << rssIdlCode;
fstreamIdlFile.close();
}
/**
* @brief Destructor
*/
~CIdlFile()
{
CleanUp();
}
/**
* @brief Get the full path to the IDL file.
* @return The path.
*/
std::filesystem::path PathIdl() const { return m_pathIdl; }
/**
* @brief Get the header file content (if one was created).
* @return The string containing the header file content.
*/
std::string Header() const
{
std::filesystem::path pathHdr = m_pathIdl;
pathHdr.replace_extension(".h");
std::ifstream fstream(pathHdr.c_str());
std::stringstream sstreamContent;
sstreamContent << fstream.rdbuf();
return sstreamContent.str();
}
private:
/**
* @brief Clean up before and after the compilation.
*/
void CleanUp()
{
try
{
if (std::filesystem::exists(m_pathIdl))
std::filesystem::remove(m_pathIdl);
} catch (const std::filesystem::filesystem_error&)
{}
std::filesystem::path pathHdr = m_pathIdl;
pathHdr.replace_extension(".h");
try
{
if (std::filesystem::exists(pathHdr))
std::filesystem::remove(pathHdr);
} catch (const std::filesystem::filesystem_error&)
{}
std::filesystem::path pathPSDir = m_pathIdl;
pathPSDir.remove_filename();
pathPSDir /= "ps";
if (std::filesystem::exists(pathPSDir))
{
try
{
std::filesystem::remove_all(pathPSDir);
} catch (const std::filesystem::filesystem_error&)
{}
}
std::filesystem::path pathSerDesDir = m_pathIdl;
pathSerDesDir.remove_filename();
pathSerDesDir /= "serdes";
if (std::filesystem::exists(pathSerDesDir))
{
try
{
std::filesystem::remove_all(pathSerDesDir);
} catch (const std::filesystem::filesystem_error&)
{}
}
}
std::filesystem::path m_pathIdl; ///< Path to the IDL file
};
/**
* @brief Class managing a test compilation.
*/
class CTestCompile : public CIdlFile
{
public:
/**
* @brief Constructor triggering a test compilation using the provided code.
* @param[in] rssIdlCode Reference to the IDL code to compile.
*/
CTestCompile(const std::string& rssIdlCode) : CIdlFile(rssIdlCode)
{
CIdlCompilerEnvironment environment;
try
{
// Parse file
CParser parser(PathIdl(), environment);
parser.Parse();
// Generate definition
CDefinitionGenerator defgen(&parser);
defgen.Generate();
// Proxy code
CProxyGenerator proxygen(&parser);
proxygen.Generate();
// Stub code
CStubGenerator stubgen(&parser);
stubgen.Generate();
// Serdes code
CSerdesGenerator serdesgen(&parser);
serdesgen.Generate();
// CMake code generation
CIdlCompilerCMakeGenerator cmakegen(&parser);
cmakegen.Generate("proxystub");
}
catch (const CCompileException& rexcept)
{
std::stringstream sstreamError;
if (!rexcept.GetPath().empty())
std::cout << rexcept.GetPath() << "(line=" << rexcept.GetLineNo() << ", col=" << rexcept.GetColNo() <<
") error: " << rexcept.GetReason() << std::endl;
else
std::cout << "error: " << rexcept.GetReason() << std::endl;
return;
}
// Compilation was successful
m_bResult = true;
}
/**
* @brief Return the result.
*/
operator bool() const
{
return m_bResult;
}
private:
bool m_bResult = false; ///< The result value of the test.
};
using CCompilerTest = CParserTest;
TEST_F(CCompilerTest, EmptyFile)
{
// Tests bug fix: #380794
EXPECT_TRUE(CTestCompile(""));
EXPECT_TRUE(CTestCompile("/// @file Empty file without any definitions"));
}
TEST_F(CCompilerTest, SkipCodePreCompiled)
{
// Partially skip code
EXPECT_TRUE(CTestCompile(R"code(/// @file Skip code by using a conditional pre-compile statement
struct S1
{};
#if 0
module mod
{};
#endif
struct S2
{};)code"));
// Tests bug fix: #380794
// Completely skip code
EXPECT_TRUE(CTestCompile(R"code(/// @file Skip complete file by using a conditional pre-compile statement
#if 0
module mod
{};
#endif)code"));
}
TEST_F(CCompilerTest, SkipCodeCommenting)
{
// Partially skip code
EXPECT_TRUE(CTestCompile(R"code(/// @file Skip code by using a commented out code
struct S1
{};
//module mod
//{};
struct S2
{};)code"));
// Tests bug fix: #380794
// Completely skip code
EXPECT_TRUE(CTestCompile(R"code(/// @file Skip code by using a commented out code
//struct S1
//{};
//module mod
//{};
//struct S2
//{};)code"));
// Tests bug fix: #380790
// Skip large chunk
std::stringstream sstream;
sstream << R"code(/// @file Skip code by using a commented out code
struct S1
{};
)code";
for (size_t n = 0; n < 20000; n++)
{
sstream << R"code(// struct STest {
// this is a test with lots of comments
// which should be skipped and not be processed
// and should not lead to any unexpected behaviour
// like crashes or giant comment blocks for the definition
// following...
// };
)code";
}
sstream << R"code(
struct S2
{};)code";
EXPECT_TRUE(CTestCompile(sstream.str()));
}
TEST_F(CCompilerTest, GeneratedCodeWithTypedefOfArray)
{
const char szIdl[] = R"code(struct LidarPointField {};
const int32 maxLidarPoints = 32;
typedef LidarPointField LidarPointsField_t;
typedef LidarPointField LidarPointsAry[maxLidarPoints];
struct LidarPoints
{
uint32 pointNumber;
LidarPointsField_t point;
LidarPointsAry lidarPointsList;
};)code";
const char szHdr[] = R"code(struct LidarPointField{};
static const int32_t maxLidarPoints = 32;
typedef LidarPointField LidarPointsField_t;
typedef LidarPointField LidarPointsAry[maxLidarPoints];
struct LidarPoints
{
uint32_t pointNumber;
LidarPointsField_t point;
LidarPointsAry lidarPointsList;
};)code";
// Tests bug fix: #385982
CTestCompile test(szIdl);
EXPECT_TRUE(test);
EXPECT_CPPEQ(test.Header(), szHdr);
}
TEST_F(CCompilerTest, ExplicitSpecifyModule)
{
const char szIdl[] = R"code(module MyAPI
{
struct VehSpd {};
module interfaces
{
struct VehSpd
{
MyAPI::VehSpd notifyStatus;
};
};
};)code";
const char szHdr[] = R"code(namespace MyAPI
{
struct VehSpd
{};
namespace interfaces
{
struct VehSpd
{
MyAPI::VehSpd notifyStatus;
};
}
}
)code";
// Tests bug fix: #384857
CTestCompile test(szIdl);
EXPECT_TRUE(test);
EXPECT_CPPEQ(test.Header(), szHdr);
}
// NOTE 11.04.2025: The C++ comparison function is not working correctly.
TEST_F(CCompilerTest, DISABLED_ForwardDeclUnion)
{
const char szIdlTypeBased[] = R"code(union UTest;
/**
* @brief Standard union based on a integer.
*/
union UTest switch (uint32)
{
case 10: boolean bVal; ///< Bool value
case 20: uint64 uiVal; ///< 64-bit int value
case 30: float fVal; ///< Float value
default: string ssVal; ///< String value
};)code";
const char szHdrTypeBased[] = R"code(struct UTest;
struct UTest;
/**
* @brief Standard union based on a integer.
*/
struct UTest
{
/** Constructor */
UTest()
{
construct_switch_value();
}
/** Destructor */
~UTest()
{
destruct_switch_value();
}
private:
/** Constructor helper function for switch_value */
void construct_switch_value(uint32_t val = uint32_t{})
{
switch_value = val;
switch (val)
{
case 10:
new (&bVal) bool;
break;
case 20:
new (&uiVal) uint64_t;
break;
case 30:
new (&fVal) float;
break;
default:
new (&ssVal) sdv::string;
break;
}
}
/** Destructor helper function for switch_value */
void destruct_switch_value()
{
switch (switch_value)
{
case 10:
break;
case 20:
break;
case 30:
break;
default:
ssVal.~string_base();
break;
}
}
public:
/** Set the switch type for the union UTest */
void switch_to(uint32_t val)
{
// Anything to do?
if (switch_value == val) return;
// Assign the new value...
switch_value = val;
// Destruct and construct switch_value...
destruct_switch_value();
construct_switch_value(val);
}
/** Get the switch value */
uint32_t get_switch() const
{
return switch_value;
}
private:
uint32_t switch_value; ///< Union switch variable.
public:
union /*switch(switch_value)*/
{
// case 10:
/// Bool value
bool bVal;
// case 20:
/// 64-bit int value
uint64_t uiVal;
// case 30:
/// Float value
float fVal;
// default
/// String value
sdv::string ssVal;
};
};
)code";
// Tests bug fix: #380792
CTestCompile testTypeBased(szIdlTypeBased);
EXPECT_TRUE(testTypeBased);
EXPECT_CPPEQ(testTypeBased.Header(), szHdrTypeBased);
const char szIdlVarBased[] = R"code(struct S {
// Forward declaration
union UTest;
int32 iVal;
/**
* @brief Standard union based on a integer value.
*/
union UTest switch (iVal)
{
case 10: boolean bVal; ///< Bool value
case 20: uint64 uiVal; ///< 64-bit int value
case 30: float fVal; ///< Float value
default: char cVal; ///< Character value
};
};)code";
const char szHdrVarBased[] = R"code(struct S {
union UTest;
int32_t iVal;
union UTest
{
UTest() {}
~UTest() {}
bool bVal;
uint64_t uiVal;
float fVal;
char cVal;
};
};
)code";
// Tests bug fix: #380792
CTestCompile testVarBased(szIdlVarBased);
EXPECT_TRUE(testVarBased);
EXPECT_CPPEQ(testVarBased.Header(), szHdrVarBased);
}
// NOTE 11.04.2025: The C++ comparison function is not working correctly.
TEST_F(CCompilerTest, DISABLED_UnionWithComplexMembers)
{
const char szIdlTypeBased[] = R"code(/**
* @brief Standard union based on a integer.
*/
union UTest switch (uint32)
{
case 10: boolean bVal; ///< Bool value
case 20: uint64 uiVal; ///< 64-bit int value
case 30: float fVal; ///< Float value
default: string ssVal; ///< String value
};)code";
const char szHdrTypeBased[] = R"code(struct UTest
{
UTest(uint32_t val = 10)
{
switch_value = val;
switch (val)
{
case 10: new (&bVal) bool; break;
case 20: new (&uiVal) uint64_t; break;
case 30: new (&fVal) float; break;
default: new (&ssVal) sdv::string; break;
}
}
~UTest()
{
switch (switch_value)
{
case 10: break;
case 20: break;
case 30: break;
default: ssVal.~string_base(); break;
}
}
void switch_to(uint32_t val)
{
if (val == switch_value) return;
this->~UTest();
new (this) UTest(val);
}
uint32_t switch_value;
union
{
bool bVal;
uint64_t uiVal;
float fVal;
sdv::string ssVal;
};
};
)code";
// Tests bug fix: #380792
CTestCompile testTypeBased(szIdlTypeBased);
EXPECT_TRUE(testTypeBased);
EXPECT_CPPEQ(testTypeBased.Header(), szHdrTypeBased);
}

View File

@@ -0,0 +1,701 @@
#include "includes.h"
#include "lexer_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/constvariant.cpp"
using CConstVariantTest = CLexerTest;
TEST_F(CConstVariantTest, DefaultConstruction)
{
CConstVariant var;
EXPECT_EQ(var.Get<int>(), 0);
}
TEST_F(CConstVariantTest, LiteralDirectValueConstruction)
{
EXPECT_EQ(CConstVariant(5).Get<int>(), 5);
EXPECT_EQ(CConstVariant(10u).Get<unsigned int>(), 10u);
EXPECT_EQ(CConstVariant(20l).Get<int32_t>(), static_cast<int32_t>(20l));
EXPECT_EQ(CConstVariant(static_cast<uint32_t>(30ul)).Get<uint32_t>(), 30ul);
EXPECT_EQ(CConstVariant(40ll).Get<int64_t>(), 40ll);
EXPECT_EQ(CConstVariant(50ull).Get<uint64_t>(), 50ull);
EXPECT_EQ(CConstVariant('A').Get<char>(), 'A');
EXPECT_EQ(CConstVariant(L'B').Get<wchar_t>(), L'B');
EXPECT_EQ(CConstVariant(u8'C').Get<char>(), u8'C');
EXPECT_EQ(CConstVariant(u'D').Get<char16_t>(), u'D');
EXPECT_EQ(CConstVariant(U'E').Get<char32_t>(), U'E');
EXPECT_EQ(CConstVariant(true).Get<bool>(), true);
EXPECT_EQ(CConstVariant(static_cast<std::string>("string")).Get<std::string>(), "string");
EXPECT_EQ(CConstVariant(static_cast<std::string>(u8"string")).Get<std::string>(), u8"string");
EXPECT_EQ(CConstVariant(static_cast<std::u16string>(u"string")).Get<std::u16string>(), u"string");
EXPECT_EQ(CConstVariant(static_cast<std::u32string>(U"string")).Get<std::u32string>(), U"string");
EXPECT_EQ(CConstVariant(static_cast<std::wstring>(L"string")).Get<std::wstring>(), L"string");
}
TEST_F(CConstVariantTest, LiteralIndirectValueConstruction)
{
bool b = true; EXPECT_EQ(CConstVariant(b).Get<bool>(), true);
int8_t i8 = 10; EXPECT_EQ(CConstVariant(i8).Get<int8_t>(), 10);
int16_t i16 = 20; EXPECT_EQ(CConstVariant(i16).Get<int16_t>(), 20);
int32_t i32 = 30; EXPECT_EQ(CConstVariant(i32).Get<int32_t>(), 30);
int64_t i64 = 40; EXPECT_EQ(CConstVariant(i64).Get<int64_t>(), 40);
uint8_t ui8 = 50; EXPECT_EQ(CConstVariant(ui8).Get<uint8_t>(), 50);
uint16_t ui16 = 60; EXPECT_EQ(CConstVariant(ui16).Get<uint16_t>(), 60u);
uint32_t ui32 = 70; EXPECT_EQ(CConstVariant(ui32).Get<uint32_t>(), 70u);
uint64_t ui64 = 80; EXPECT_EQ(CConstVariant(ui64).Get<uint64_t>(), 80ull);
float f = 90.0; EXPECT_EQ(CConstVariant(f).Get<float>(), 90.0);
double d = 100.0; EXPECT_EQ(CConstVariant(d).Get<double>(), 100.0);
long double ld = 110.0; EXPECT_EQ(CConstVariant(ld).Get<long double>(), 110.0);
std::string ss = "string"; EXPECT_EQ(CConstVariant(ss).Get<std::string>(), "string");
std::string ssUtf8 = u8"string"; EXPECT_EQ(CConstVariant(ssUtf8).Get<std::string>(), u8"string");
std::u16string ssUtf16 = u"string"; EXPECT_EQ(CConstVariant(ssUtf16).Get<std::u16string>(), u"string");
std::u32string ssUtf32 = U"string"; EXPECT_EQ(CConstVariant(ssUtf32).Get<std::u32string>(), U"string");
std::wstring ssWide = L"string"; EXPECT_EQ(CConstVariant(ssWide).Get<std::wstring>(), L"string");
}
TEST_F(CConstVariantTest, LiteralDirectValueAssignment)
{
CConstVariant var;
var = 5; EXPECT_EQ(var.Get<int>(), 5);
var = 10u; EXPECT_EQ(var.Get<unsigned int>(), 10u);
var = 20l; EXPECT_EQ(var.Get<int32_t>(), 20l);
var = static_cast<uint32_t>(30ul); EXPECT_EQ(var.Get<uint32_t>(), 30ul);
var = 40ll; EXPECT_EQ(var.Get<int64_t>(), 40ll);
var = 50ull; EXPECT_EQ(var.Get<uint64_t>(), 50ull);
var = 'A'; EXPECT_EQ(var.Get<char>(), 'A');
var = L'B'; EXPECT_EQ(var.Get<wchar_t>(), L'B');
var = u8'C'; EXPECT_EQ(var.Get<char>(), u8'C');
var = u'D'; EXPECT_EQ(var.Get<char16_t>(), u'D');
var = U'E'; EXPECT_EQ(var.Get<char32_t>(), U'E');
var = true; EXPECT_EQ(var.Get<bool>(), true);
var = static_cast<std::string>("string"); EXPECT_EQ(var.Get<std::string>(), "string");
var = static_cast<std::string>(u8"string"); EXPECT_EQ(var.Get<std::string>(), u8"string");
var = static_cast<std::u16string>(u"string"); EXPECT_EQ(var.Get<std::u16string>(), u"string");
var = static_cast<std::u32string>(U"string"); EXPECT_EQ(var.Get<std::u32string>(), U"string");
var = static_cast<std::wstring>(L"string"); EXPECT_EQ(var.Get<std::wstring>(), L"string");
}
TEST_F(CConstVariantTest, LiteralIndirectValueAssignment)
{
CConstVariant var;
bool b = true; var = b; EXPECT_EQ(var.Get<bool>(), true);
int8_t i8 = 10; var = i8; EXPECT_EQ(var.Get<int8_t>(), 10);
int16_t i16 = 20; var = i16; EXPECT_EQ(var.Get<int16_t>(), 20);
int32_t i32 = 30; var = i32; EXPECT_EQ(var.Get<int32_t>(), 30);
int64_t i64 = 40; var = i64; EXPECT_EQ(var.Get<int64_t>(), 40);
uint8_t ui8 = 50; var = ui8; EXPECT_EQ(var.Get<uint8_t>(), 50);
uint16_t ui16 = 60; var = ui16; EXPECT_EQ(var.Get<uint16_t>(), 60);
uint32_t ui32 = 70; var = ui32; EXPECT_EQ(var.Get<uint32_t>(), 70u);
uint64_t ui64 = 80; var = ui64; EXPECT_EQ(var.Get<uint64_t>(), 80ull);
float f = 90.0; var = f; EXPECT_EQ(var.Get<float>(), 90.0);
double d = 100.0; var = d; EXPECT_EQ(var.Get<double>(), 100.0);
long double ld = 110.0; var = ld; EXPECT_EQ(var.Get<long double>(), 110.0);
std::string ss = "string"; var = ss; EXPECT_EQ(var.Get<std::string>(), "string");
std::string ssUtf8 = u8"string"; var = ssUtf8; EXPECT_EQ(var.Get<std::string>(), u8"string");
std::u16string ssUtf16 = u"string"; var = ssUtf16; EXPECT_EQ(var.Get<std::u16string>(), u"string");
std::u32string ssUtf32 = U"string"; var = ssUtf32; EXPECT_EQ(var.Get<std::u32string>(), U"string");
std::wstring ssWide = L"string"; var = ssWide; EXPECT_EQ(var.Get<std::wstring>(), L"string");
}
TEST_F(CConstVariantTest, TypePromotion)
{
CConstVariant var;
bool b = true;
var = b;
EXPECT_EQ(var.Get<int8_t>(), 1);
EXPECT_EQ(var.Get<uint8_t>(), 1);
EXPECT_EQ(var.Get<int16_t>(), 1);
EXPECT_EQ(var.Get<uint16_t>(), 1u);
EXPECT_EQ(var.Get<int32_t>(), 1);
EXPECT_EQ(var.Get<uint32_t>(), 1u);
EXPECT_EQ(var.Get<int64_t>(), 1);
EXPECT_EQ(var.Get<uint64_t>(), 1ull);
EXPECT_EQ(var.Get<float>(), 1.0f);
EXPECT_EQ(var.Get<double>(), 1.0);
EXPECT_EQ(var.Get<long double>(), 1.0l);
int8_t i8 = -10;
var = i8;
EXPECT_EQ(var.Get<uint8_t>(), 0xf6);
EXPECT_EQ(var.Get<int16_t>(), -10);
EXPECT_EQ(var.Get<uint16_t>(), 0xfff6);
EXPECT_EQ(var.Get<int32_t>(), -10);
EXPECT_EQ(var.Get<uint32_t>(), 0xfffffff6ul);
EXPECT_EQ(var.Get<int64_t>(), -10);
EXPECT_EQ(var.Get<uint64_t>(), 0xfffffffffffffff6ull);
EXPECT_EQ(var.Get<float>(), -10.0f);
EXPECT_EQ(var.Get<double>(), -10.0);
EXPECT_EQ(var.Get<long double>(), -10.0l);
uint8_t ui8 = 50;
var = ui8;
EXPECT_EQ(var.Get<int16_t>(), 50);
EXPECT_EQ(var.Get<uint16_t>(), 50u);
EXPECT_EQ(var.Get<int32_t>(), 50);
EXPECT_EQ(var.Get<uint32_t>(), 50u);
EXPECT_EQ(var.Get<int64_t>(), 50);
EXPECT_EQ(var.Get<uint64_t>(), 50ull);
EXPECT_EQ(var.Get<float>(), 50.0f);
EXPECT_EQ(var.Get<double>(), 50.0);
EXPECT_EQ(var.Get<long double>(), 50.0l);
int16_t i16 = -20;
var = i16;
EXPECT_EQ(var.Get<uint16_t>(), 0xffec);
EXPECT_EQ(var.Get<int32_t>(), -20);
EXPECT_EQ(var.Get<uint32_t>(), 0xffffffecul);
EXPECT_EQ(var.Get<int64_t>(), -20);
EXPECT_EQ(var.Get<uint64_t>(), 0xffffffffffffffecull);
EXPECT_EQ(var.Get<float>(), -20.0f);
EXPECT_EQ(var.Get<double>(), -20.0);
EXPECT_EQ(var.Get<long double>(), -20.0l);
uint16_t ui16 = 60;
var = ui16;
EXPECT_EQ(var.Get<int32_t>(), 60);
EXPECT_EQ(var.Get<uint32_t>(), 60u);
EXPECT_EQ(var.Get<int64_t>(), 60);
EXPECT_EQ(var.Get<uint64_t>(), 60ull);
EXPECT_EQ(var.Get<float>(), 60.0f);
EXPECT_EQ(var.Get<double>(), 60.0);
EXPECT_EQ(var.Get<long double>(), 60.0l);
int32_t i32 = -30;
var = i32;
EXPECT_EQ(var.Get<uint32_t>(), 0xffffffe2ul);
EXPECT_EQ(var.Get<int64_t>(), -30);
EXPECT_EQ(var.Get<uint64_t>(), 0xffffffffffffffe2ull);
EXPECT_EQ(var.Get<float>(), -30.0f);
EXPECT_EQ(var.Get<double>(), -30.0);
EXPECT_EQ(var.Get<long double>(), -30.0l);
uint32_t ui32 = 70;
var = ui32;
EXPECT_EQ(var.Get<int64_t>(), 70);
EXPECT_EQ(var.Get<uint64_t>(), 70ull);
EXPECT_EQ(var.Get<float>(), 70.0f);
EXPECT_EQ(var.Get<double>(), 70.0);
EXPECT_EQ(var.Get<long double>(), 70.0l);
int64_t i64 = -40;
var = i64;
EXPECT_EQ(var.Get<uint64_t>(), 0xffffffffffffffd8ull);
EXPECT_EQ(var.Get<float>(), -40.0f);
EXPECT_EQ(var.Get<double>(), -40.0);
EXPECT_EQ(var.Get<long double>(), -40.0l);
uint64_t ui64 = 80;
var = ui64;
EXPECT_EQ(var.Get<float>(), 80.0f);
EXPECT_EQ(var.Get<double>(), 80.0);
EXPECT_EQ(var.Get<long double>(), 80.0l);
float f = -90.0;
var = f;
EXPECT_EQ(var.Get<double>(), -90.0);
EXPECT_EQ(var.Get<long double>(), -90.0l);
double d = -100.0;
var = d;
EXPECT_EQ(var.Get<long double>(), -100.0l);
}
TEST_F(CConstVariantTest, TypeDemotion)
{
CConstVariant var;
int8_t i8 = 1;
var = i8;
EXPECT_EQ(var.Get<bool>(), true);
var = std::numeric_limits<int8_t>::min();
EXPECT_EQ(var.Get<bool>(), true);
var = std::numeric_limits<int8_t>::max();
EXPECT_EQ(var.Get<bool>(), true);
uint8_t ui8 = 50;
var = ui8;
EXPECT_EQ(var.Get<int8_t>(), 50);
EXPECT_EQ(var.Get<bool>(), true);
var = std::numeric_limits<uint8_t>::max();
EXPECT_THROW(var.Get<int8_t>(), CCompileException);
int16_t i16 = -20;
var = i16;
EXPECT_EQ(var.Get<uint8_t>(), 0xec);
EXPECT_EQ(var.Get<int8_t>(), -20);
var = std::numeric_limits<int16_t>::min();
EXPECT_THROW(var.Get<uint8_t>(), CCompileException);
var = std::numeric_limits<int16_t>::max();
EXPECT_THROW(var.Get<uint8_t>(), CCompileException);
uint16_t ui16 = 60;
var = ui16;
EXPECT_EQ(var.Get<int16_t>(), 60);
EXPECT_EQ(var.Get<int8_t>(), 60);
var = std::numeric_limits<uint16_t>::max();
EXPECT_THROW(var.Get<int16_t>(), CCompileException);
int32_t i32 = -30;
var = i32;
EXPECT_EQ(var.Get<uint16_t>(), 0xffe2);
EXPECT_EQ(var.Get<int16_t>(), -30);
var = std::numeric_limits<int32_t>::min();
EXPECT_THROW(var.Get<uint16_t>(), CCompileException);
var = std::numeric_limits<int32_t>::max();
EXPECT_THROW(var.Get<uint16_t>(), CCompileException);
uint32_t ui32 = 70;
var = ui32;
EXPECT_EQ(var.Get<int32_t>(), 70);
EXPECT_EQ(var.Get<int16_t>(), 70);
var = std::numeric_limits<uint32_t>::max();
EXPECT_THROW(var.Get<int32_t>(), CCompileException);
int64_t i64 = -40;
var = i64;
EXPECT_EQ(var.Get<uint32_t>(), 0xffffffd8);
EXPECT_EQ(var.Get<int32_t>(), -40);
var = std::numeric_limits<int64_t>::min();
EXPECT_THROW(var.Get<uint32_t>(), CCompileException);
var = std::numeric_limits<int64_t>::max();
EXPECT_THROW(var.Get<uint32_t>(), CCompileException);
uint64_t ui64 = 80;
var = ui64;
EXPECT_EQ(var.Get<int64_t>(), 80);
EXPECT_EQ(var.Get<int32_t>(), 80);
var = std::numeric_limits<uint64_t>::max();
EXPECT_THROW(var.Get<int64_t>(), CCompileException);
float f = 90.0;
var = f;
EXPECT_THROW(var.Get<int64_t>(), CCompileException);
EXPECT_THROW(var.Get<uint64_t>(), CCompileException);
double d = 100.0;
var = d;
EXPECT_EQ(var.Get<float>(), 100.0f);
var = std::numeric_limits<double>::max();
EXPECT_THROW(var.Get<float>(), CCompileException);
var = std::numeric_limits<double>::min();
EXPECT_THROW(var.Get<float>(), CCompileException);
var = std::numeric_limits<double>::lowest();
EXPECT_THROW(var.Get<float>(), CCompileException);
if (std::numeric_limits<double>::max() < std::numeric_limits<long double>::max())
{
long double ld = 110.0;
var = ld;
EXPECT_EQ(var.Get<double>(), 110.0);
var = std::numeric_limits<long double>::max();
EXPECT_THROW(var.Get<double>(), CCompileException);
var = std::numeric_limits<long double>::min();
EXPECT_THROW(var.Get<double>(), CCompileException);
var = std::numeric_limits<long double>::lowest();
EXPECT_THROW(var.Get<double>(), CCompileException);
}
}
TEST_F(CConstVariantTest, InvalidConversion)
{
EXPECT_THROW(CConstVariant(90).Get<std::string>(), CCompileException);
EXPECT_THROW(CConstVariant(90.0f).Get<uint32_t>(), CCompileException);
EXPECT_THROW(CConstVariant(100.0).Get<char>(), CCompileException);
EXPECT_THROW(CConstVariant(110.0l).Get<std::wstring>(), CCompileException);
EXPECT_THROW(CConstVariant("string").Get<std::u16string>(), CCompileException);
EXPECT_THROW(CConstVariant(u8"string").Get<std::wstring>(), CCompileException);
EXPECT_THROW(CConstVariant(u"string").Get<std::u32string>(), CCompileException);
EXPECT_THROW(CConstVariant(U"string").Get<std::string>(), CCompileException);
EXPECT_THROW(CConstVariant(L"string").Get<std::u16string>(), CCompileException);
}
TEST_F(CConstVariantTest, ArithmicOperatorLogicalNot)
{
CConstVariant var1(true);
CConstVariant var2 = !var1;
EXPECT_EQ(var2.Get<uint32_t>(), 0u);
var1 = 100.0;
EXPECT_THROW(var2 = !var1, CCompileException);
var1 = 100;
var2 = !var1;
EXPECT_EQ(var2.Get<double>(), 0);
}
TEST_F(CConstVariantTest, ArithmicOperatorBitwiseNot)
{
CConstVariant var1(static_cast<uint16_t>(0b1011100010ull));
CConstVariant var2 = ~var1;
EXPECT_EQ(var2.Get<uint16_t>(), 0b1111110100011101ull);
var1 = 100.0;
EXPECT_THROW(var2 = ~var1, CCompileException);
var1 = false;
EXPECT_THROW(var2 = ~var1, CCompileException);
var1 = static_cast<uint8_t>(0x0f);
var2 = ~var1;
EXPECT_EQ(var2.Get<uint16_t>(), 0xfff0);
}
TEST_F(CConstVariantTest, ArithmicOperatorConfirmation)
{
CConstVariant var1(true);
CConstVariant var2 = +var1;
EXPECT_EQ(var2.Get<uint32_t>(), 1u);
var1 = 100.0;
var2 = +var1;
EXPECT_EQ(var2.Get<float>(), 100.0f);
var1 = 100;
var2 = +var1;
EXPECT_EQ(var2.Get<int8_t>(), 100);
}
TEST_F(CConstVariantTest, ArithmicOperatorNegetion)
{
CConstVariant var1(static_cast<uint8_t>('A'));
CConstVariant var2 = -var1;
EXPECT_EQ(var2.Get<int32_t>(), -65);
var1 = true;
EXPECT_THROW(var2 = -var1, CCompileException);
var1 = 100.0;
var2 = -var1;
EXPECT_EQ(var2.Get<float>(), -100.0f);
var1 = 100;
var2 = -var1;
EXPECT_EQ(var2.Get<int8_t>(), -100);
}
TEST_F(CConstVariantTest, ArithmicOperatorMultiplication)
{
CConstVariant var1(90);
CConstVariant var2(45);
CConstVariant var3 = var1 * var2;
EXPECT_EQ(var3.Get<uint32_t>(), 4050u);
var1 = 100.0;
var2 = 45.0;
var3 = var1 * var2;
EXPECT_EQ(var3.Get<double>(), 4500);
var1 = 100.0;
var2 = 'A';
var3 = var1 * var2;
EXPECT_EQ(var3.Get<double>(), 6500);
}
TEST_F(CConstVariantTest, ArithmicOperatorDivision)
{
CConstVariant var1(90);
CConstVariant var2(45);
CConstVariant var3 = var1 / var2;
EXPECT_EQ(var3.Get<double>(), 2);
var1 = 100.0;
var2 = 45.0;
var3 = var1 / var2;
EXPECT_EQ(var3.Get<double>(), 100.0/45.0);
var1 = 130;
var2 = 'A';
var3 = var1 / var2;
EXPECT_EQ(var3.Get<uint32_t>(), 2u);
EXPECT_THROW(var3 / 0, CCompileException);
}
TEST_F(CConstVariantTest, ArithmicOperatorAddition)
{
CConstVariant var1(90);
CConstVariant var2(45);
CConstVariant var3 = var1 + var2;
EXPECT_EQ(var3.Get<uint32_t>(), 135u);
var1 = 100.0;
var2 = 45.0;
var3 = var1 + var2;
EXPECT_EQ(var3.Get<double>(), 145);
var1 = 100.0;
var2 = 'A';
var3 = var1 + var2;
EXPECT_EQ(var3.Get<double>(), 165);
}
TEST_F(CConstVariantTest, ArithmicOperatorSubtraction)
{
CConstVariant var1(90);
CConstVariant var2(45);
CConstVariant var3 = var1 - var2;
EXPECT_EQ(var3.Get<uint32_t>(), 45u);
var1 = 100.0;
var2 = 45.0;
var3 = var1 - var2;
EXPECT_EQ(var3.Get<double>(), 55);
var1 = 0.0;
var2 = 'A';
var3 = var1 - var2;
EXPECT_EQ(var3.Get<double>(), -65);
}
TEST_F(CConstVariantTest, ArithmicOperatorRemainder)
{
CConstVariant var1(90);
CConstVariant var2(40);
CConstVariant var3 = var1 % var2;
EXPECT_EQ(var3.Get<double>(), 10);
var1 = 100.0;
var2 = 45.0;
EXPECT_THROW(var1 % var2, CCompileException);
var1 = 130;
var2 = 'A';
var3 = var1 % var2;
EXPECT_EQ(var3.Get<uint32_t>(), 0u);
EXPECT_THROW(var3 % 0, CCompileException);
}
TEST_F(CConstVariantTest, ArithmicOperatorShiftLeft)
{
CConstVariant var1(90);
CConstVariant var2(3);
CConstVariant var3 = var1 << var2;
EXPECT_EQ(var3.Get<uint32_t>(), 720u);
var1 = 100.0;
var2 = 2.0;
EXPECT_THROW(var1 << var2, CCompileException);
var1 = static_cast<int8_t>('A');
var2 = static_cast<uint8_t>(2);
var3 = var1 << var2;
EXPECT_EQ(var3.Get<uint32_t>(), 260u);
}
TEST_F(CConstVariantTest, ArithmicOperatorShiftRight)
{
CConstVariant var1(90);
CConstVariant var2(3);
CConstVariant var3 = var1 >> var2;
EXPECT_EQ(var3.Get<uint32_t>(), 11u);
var1 = 100.0;
var2 = 2.0;
EXPECT_THROW(var1 >> var2, CCompileException);
var1 = 'A';
var2 = static_cast<uint8_t>(2);
var3 = var1 >> var2;
EXPECT_EQ(var3.Get<uint32_t>(), 16u);
}
TEST_F(CConstVariantTest, ArithmicOperatorBitwiseAnd)
{
CConstVariant var1(0b10101010);
CConstVariant var2(0b11110000);
CConstVariant var3 = var1 & var2;
EXPECT_EQ(var3.Get<uint32_t>(), 0b10100000u);
var1 = 100.0;
var2 = 2.0;
EXPECT_THROW(var1 & var2, CCompileException);
var1 = 'A';
var2 = static_cast<uint8_t>(1);
var3 = var1 & var2;
EXPECT_EQ(var3.Get<uint32_t>(), 1u);
}
TEST_F(CConstVariantTest, ArithmicOperatorBitwiseXor)
{
CConstVariant var1(0b10101010);
CConstVariant var2(0b11110000);
CConstVariant var3 = var1 ^ var2;
EXPECT_EQ(var3.Get<uint32_t>(), 0b1011010u);
var1 = 100.0;
var2 = 2.0;
EXPECT_THROW(var1 ^ var2, CCompileException);
var1 = 'A';
var2 = static_cast<uint8_t>(1);
var3 = var1 ^ var2;
EXPECT_EQ(var3.Get<uint32_t>(), 64u);
}
TEST_F(CConstVariantTest, ArithmicOperatorBitwiseOr)
{
CConstVariant var1(0b10101010);
CConstVariant var2(0b11110000);
CConstVariant var3 = var1 | var2;
EXPECT_EQ(var3.Get<uint32_t>(), 0b11111010u);
var1 = 100.0;
var2 = 2.0;
EXPECT_THROW(var1 | var2, CCompileException);
var1 = 'A';
var2 = static_cast<uint8_t>(2);
var3 = var1 | var2;
EXPECT_EQ(var3.Get<uint32_t>(), 67u);
}
TEST_F(CConstVariantTest, ArithmicOperatorLogicalAnd)
{
CConstVariant var1(90);
CConstVariant var2(45);
CConstVariant var3 = var1 && var2;
EXPECT_EQ(var3.Get<uint32_t>(), 1u);
var1 = 100.0;
var2 = 45.0;
var3 = 100.0;
CConstVariant var4 = 45.0;
CConstVariant var5 = var1 == var3 && var2 == var4;
EXPECT_EQ(var3.Get<bool>(), true);
var1 = 65ull;
var2 = 'A';
var3 = true;
var4 = var1 == var2 && var3;
EXPECT_EQ(var4.Get<bool>(), true);
}
TEST_F(CConstVariantTest, ArithmicOperatorLogicalOr)
{
CConstVariant var1(90);
CConstVariant var2(false);
CConstVariant var3 = var1 || var2;
EXPECT_EQ(var3.Get<uint32_t>(), 1u);
var1 = 100.0;
var2 = 45.0;
var3 = 190.0;
CConstVariant var4 = 45.0;
CConstVariant var5 = var1 == var3 || var2 == var4;
EXPECT_EQ(var3.Get<bool>(), true);
var1 = 65ull;
var2 = 'A';
var3 = false;
var4 = var1 == var2 || var3;
EXPECT_EQ(var4.Get<bool>(), true);
}
TEST_F(CConstVariantTest, ArithmicOperatorCompareSmaller)
{
CConstVariant var1(45);
CConstVariant var2(90);
CConstVariant var3 = var1 < var2;
EXPECT_EQ(var3.Get<uint32_t>(), 1u);
var1 = 100.0;
var2 = 45.0;
var3 = var2 < var1;
EXPECT_EQ(var3.Get<bool>(), true);
var1 = 65ull;
var2 = 'A';
var3 = var1 < var2;
EXPECT_EQ(var3.Get<bool>(), false);
}
TEST_F(CConstVariantTest, ArithmicOperatorCompareSmallerOrEqual)
{
CConstVariant var1(45);
CConstVariant var2(90);
CConstVariant var3 = var1 <= var2;
EXPECT_EQ(var3.Get<uint32_t>(), 1u);
var1 = 100.0;
var2 = 45.0;
var3 = var2 <= var1;
EXPECT_EQ(var3.Get<bool>(), true);
var1 = 65ull;
var2 = 'A';
var3 = var1 <= var2;
EXPECT_EQ(var3.Get<bool>(), true);
}
TEST_F(CConstVariantTest, ArithmicOperatorCompareGreater)
{
CConstVariant var1(90);
CConstVariant var2(45);
CConstVariant var3 = var1 > var2;
EXPECT_EQ(var3.Get<uint32_t>(), 1u);
var1 = 45.0;
var2 = 100.0;
var3 = var2 > var1;
EXPECT_EQ(var3.Get<bool>(), true);
var1 = 65ull;
var2 = 'A';
var3 = var1 > var2;
EXPECT_EQ(var3.Get<bool>(), false);
}
TEST_F(CConstVariantTest, ArithmicOperatorCompareGreaterOrEqual)
{
CConstVariant var1(90);
CConstVariant var2(45);
CConstVariant var3 = var1 >= var2;
EXPECT_EQ(var3.Get<uint32_t>(), 1u);
var1 = 45.0;
var2 = 100.0;
var3 = var2 >= var1;
EXPECT_EQ(var3.Get<bool>(), true);
var1 = 65ull;
var2 = 'A';
var3 = var1 >= var2;
EXPECT_EQ(var3.Get<bool>(), true);
}
TEST_F(CConstVariantTest, ArithmicOperatorCompareEqual)
{
CConstVariant var1(90);
CConstVariant var2(45);
CConstVariant var3 = var1 == var2;
EXPECT_EQ(var3.Get<uint32_t>(), 0u);
var1 = 45.0;
var2 = 100.0;
var3 = var2 == var1;
EXPECT_EQ(var3.Get<bool>(), false);
var1 = 65ull;
var2 = 'A';
var3 = var1 == var2;
EXPECT_EQ(var3.Get<bool>(), true);
}
TEST_F(CConstVariantTest, ArithmicOperatorCompareNotEqual)
{
CConstVariant var1(90);
CConstVariant var2(45);
CConstVariant var3 = var1 != var2;
EXPECT_EQ(var3.Get<uint32_t>(), 1u);
var1 = 45.0;
var2 = 100.0;
var3 = var2 != var1;
EXPECT_EQ(var3.Get<bool>(), true);
var1 = 65ull;
var2 = 'A';
var3 = var1 != var2;
EXPECT_EQ(var3.Get<bool>(), false);
}

View File

@@ -0,0 +1,214 @@
#include "includes.h"
#include <interfaces/core.h>
#include "parser_test.h"
#include <fstream>
using CGeneratorInterfaceIdTest = CParserTest;
namespace id1
{
namespace sdv
{
using interface_id = ::sdv::interface_id;
}
#include "generated/test_ifc_id1.h"
}
namespace id2
{
namespace sdv
{
using interface_id = ::sdv::interface_id;
}
#include "generated/test_ifc_id2.h"
}
TEST_F(CGeneratorInterfaceIdTest, EmptyIdentical)
{
EXPECT_EQ(sdv::GetInterfaceId<id1::IEmptyIdentical>(), sdv::GetInterfaceId<id2::IEmptyIdentical>());
}
TEST_F(CGeneratorInterfaceIdTest, Identical)
{
EXPECT_EQ(sdv::GetInterfaceId<id1::IIdentical>(), sdv::GetInterfaceId<id2::IIdentical>());
}
TEST_F(CGeneratorInterfaceIdTest, EmptyDifferent)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IEmptyDifferent1>(), sdv::GetInterfaceId<id2::IEmptyDifferent2>());
}
TEST_F(CGeneratorInterfaceIdTest, Different)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferent1>(), sdv::GetInterfaceId<id2::IDifferent2>());
}
TEST_F(CGeneratorInterfaceIdTest, DiffentModule)
{
EXPECT_NE(sdv::GetInterfaceId<id1::mod1::IDiffentModule>(), sdv::GetInterfaceId<id2::mod2::IDiffentModule>());
}
TEST_F(CGeneratorInterfaceIdTest, DiffentParentModule)
{
EXPECT_NE(sdv::GetInterfaceId<id1::mod_parent1::mod::IEmptyIdentical>(), sdv::GetInterfaceId<id2::mod_parent2::mod::IEmptyIdentical>());
}
TEST_F(CGeneratorInterfaceIdTest, DiffentMemberFunc)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDiffentMemberFunc>(), sdv::GetInterfaceId<id2::IDiffentMemberFunc>());
}
TEST_F(CGeneratorInterfaceIdTest, DiffentMemberFuncOrder)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDiffentMemberFuncOrder>(), sdv::GetInterfaceId<id2::IDiffentMemberFuncOrder>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncVisibility)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncVisibility>(), sdv::GetInterfaceId<id2::IDifferentFuncVisibility>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentAddFunc)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentAddFunc>(), sdv::GetInterfaceId<id2::IDifferentAddFunc>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentAddFuncParam)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentAddFuncParam>(), sdv::GetInterfaceId<id2::IDifferentAddFuncParam>());
}
TEST_F(CGeneratorInterfaceIdTest, ComplexParamChange)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IComplexParamChange>(), sdv::GetInterfaceId<id2::IComplexParamChange>());
}
TEST_F(CGeneratorInterfaceIdTest, ComplexReturnValChange)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IComplexReturnValChange>(), sdv::GetInterfaceId<id2::IComplexReturnValChange>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncParamOrder)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncParamOrder>(), sdv::GetInterfaceId<id2::IDifferentFuncParamOrder>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncRetVal)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncRetVal>(), sdv::GetInterfaceId<id2::IDifferentFuncRetVal>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncParamName)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncParamName>(), sdv::GetInterfaceId<id2::IDifferentFuncParamName>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncParamType)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncParamType>(), sdv::GetInterfaceId<id2::IDifferentFuncParamType>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncParamDirection)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncParamDirection>(), sdv::GetInterfaceId<id2::IDifferentFuncParamDirection>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncAddException)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncAddException>(), sdv::GetInterfaceId<id2::IDifferentFuncAddException>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncChangeException)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncChangeException>(), sdv::GetInterfaceId<id2::IDifferentFuncChangeException>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncAdditionalException)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncAdditionalException>(), sdv::GetInterfaceId<id2::IDifferentFuncAdditionalException>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncExceptionOrder)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncExceptionOrder>(), sdv::GetInterfaceId<id2::IDifferentFuncExceptionOrder>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncExceptionName)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncExceptionName>(), sdv::GetInterfaceId<id2::IDifferentFuncExceptionName>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncExceptionType)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncExceptionType>(), sdv::GetInterfaceId<id2::IDifferentFuncExceptionType>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentAttrName)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentAttrName>(), sdv::GetInterfaceId<id2::IDifferentAttrName>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentAttrType)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentAttrType>(), sdv::GetInterfaceId<id2::IDifferentAttrType>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentAddAttr)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentAddAttr>(), sdv::GetInterfaceId<id2::IDifferentAddAttr>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentAttrVisibility)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentAttrVisibility>(), sdv::GetInterfaceId<id2::IDifferentAttrVisibility>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentAttrAddException)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentAttrAddException>(), sdv::GetInterfaceId<id2::IDifferentAttrAddException>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentAttrChangeException)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentAttrChangeException>(), sdv::GetInterfaceId<id2::IDifferentAttrChangeException>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentAttrAdditionalException)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentAttrAdditionalException>(), sdv::GetInterfaceId<id2::IDifferentAttrAdditionalException>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentAttrExceptionDirection)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentAttrExceptionDirection>(), sdv::GetInterfaceId<id2::IDifferentAttrExceptionDirection>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentFuncExceptionDirection2)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentFuncExceptionDirection2>(), sdv::GetInterfaceId<id2::IDifferentFuncExceptionDirection2>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentAttrExceptionName)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentAttrExceptionName>(), sdv::GetInterfaceId<id2::IDifferentAttrExceptionName>());
}
TEST_F(CGeneratorInterfaceIdTest, DifferentAttrExceptionType)
{
EXPECT_NE(sdv::GetInterfaceId<id1::IDifferentAttrExceptionType>(), sdv::GetInterfaceId<id2::IDifferentAttrExceptionType>());
}
TEST_F(CGeneratorInterfaceIdTest, IdenticalAddConstDecl)
{
EXPECT_EQ(sdv::GetInterfaceId<id1::IIdenticalAddConstDecl>(), sdv::GetInterfaceId<id2::IIdenticalAddConstDecl>());
}
TEST_F(CGeneratorInterfaceIdTest, IdenticalAddComments)
{
EXPECT_EQ(sdv::GetInterfaceId<id1::IIdenticalAddComments>(), sdv::GetInterfaceId<id2::IIdenticalAddComments>());
}
TEST_F(CGeneratorInterfaceIdTest, IdenticalAddChildDef)
{
EXPECT_EQ(sdv::GetInterfaceId<id1::IIdenticalAddChildDef>(), sdv::GetInterfaceId<id2::IIdenticalAddChildDef>());
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,180 @@
#include "includes.h"
#include "generator_test.h"
#include <support/local_service_access.h>
/**
* @brief Align on 64 bit.
* @tparam T The type to alignb the data for
* @param[in] tVal The value to align
* @return The aligned value
*/
template <typename T>
inline constexpr T Align(T tVal)
{
return tVal % 8 ? tVal + 8 - tVal % 8 : tVal;
}
MockRepoService* MockRepoService::m_pRepo = nullptr;
void CGeneratorTest::SetUpTestCase()
{
ASSERT_TRUE(true);
}
void CGeneratorTest::TearDownTestCase()
{}
void CGeneratorTest::SetUp()
{}
void CGeneratorTest::TearDown()
{}
void CGeneratorTest::RegisterStubObject(sdv::interface_t ifc, sdv::IInterfaceAccess* pStub)
{
// Check for valid interface
if (!ifc) return;
// Get the link interface of the stub object
if (!pStub) return;
sdv::ps::IStubLink* pStubLink = pStub->GetInterface<sdv::ps::IStubLink>();
if (!pStubLink) return;
// Register the stub object
m_repo.m_ciService.RegisterStubObject(ifc, pStub);
// Link the interface
pStubLink->Link(ifc);
}
void CGeneratorTest::RegisterProxyObject(sdv::interface_t ifc, sdv::IInterfaceAccess* pStub, sdv::IInterfaceAccess* pProxy)
{
// Check for valid interface
if (!ifc) return;
if (!pStub) return;
// Get the marshall interface of the stub object
sdv::ps::IMarshall* pMarshall = pStub->GetInterface<sdv::ps::IMarshall>();
if (!pMarshall) return;
// Get the link interface of the proxy object
if (!pProxy) return;
sdv::ps::IMarshallLink* pMarshallLink = pProxy->GetInterface<sdv::ps::IMarshallLink>();
if (!pMarshallLink) return;
// Register the proxy
m_repo.m_ciService.RegisterProxyObject(ifc, pProxy);
// Link the proxy to the stub
pMarshallLink->Link(pMarshall);
}
void MockCommunicationService::RegisterProxyObject(sdv::interface_t ifc, sdv::IInterfaceAccess* pProxy)
{
// Find the stub object
auto itStub = m_mapStubObjects.find(ifc);
if (itStub == m_mapStubObjects.end()) return;
m_mapProxyObjects.try_emplace(itStub->second, std::make_pair(ifc.id(), pProxy));
}
void MockCommunicationService::RegisterStubObject(sdv::interface_t ifc, sdv::IInterfaceAccess* pStub)
{
sdv::ps::TMarshallID tStubID{};
tStubID.uiIdent = static_cast<uint32_t>(m_vecStubbjects.size());
tStubID.uiControl = rand();
m_vecStubbjects.push_back(pStub);
m_mapStubObjects.try_emplace(ifc, tStubID);
}
sdv::pointer<uint8_t> CGeneratorTest::Allocate(uint32_t uiLength)
{
return sdv::internal::make_ptr<uint8_t>(this, uiLength);
}
sdv::interface_t MockCommunicationService::GetProxy(/*in*/ const sdv::ps::TMarshallID& tStubID, /*in*/ sdv::interface_id id)
{
auto itProxy = m_mapProxyObjects.find(tStubID);
if (itProxy == m_mapProxyObjects.end()) return nullptr;
if (itProxy->second.first != id) return nullptr;
sdv::ps::IProxyControl* pControl = itProxy->second.second->GetInterface<sdv::ps::IProxyControl>();
if (!pControl) throw sdv::XInvalidState();
return pControl->GetTargetInterface();
}
sdv::ps::TMarshallID MockCommunicationService::GetStub(/*in*/ sdv::interface_t ifc)
{
auto itStub = m_mapStubObjects.find(ifc);
if (itStub == m_mapStubObjects.end()) return {};
return itStub->second;
}
//sdv::interface_t MockCommunicationService::CreateInterfaceProxy(/*in*/ sdv::interface_id idInterfaceID, /*in*/ const sdv::com::SRemoteObjectID& sRemoteObject)
//{
// if (sRemoteObject.uiClusterID != (uint64_t)this) return nullptr;
// if (sRemoteObject.uiProcessID != (uint64_t)this) return nullptr;
//
// // Get the proxy object
// SStubInterface* pStubInterface = reinterpret_cast<SStubInterface*>(sRemoteObject.uiStubID);
// if (!pStubInterface) return nullptr;
// auto itProxy = m_mapProxyObjects.find(std::make_pair(idInterfaceID, pStubInterface->pStub));
// if (itProxy == m_mapProxyObjects.end()) return nullptr;
//
// // Assign the marshall interface
// sdv::ps::IMarshallLink* pLink = itProxy->second->GetInterface<sdv::ps::IMarshallLink>();
// if (!pLink) return nullptr;
// pLink->Link(pMarshall);
//
// // Return the proxy object interface
// sdv::ps::IProxyControl* pGetIfc = itProxy->second->GetInterface<sdv::ps::IProxyControl>();
// return pGetIfc->GetTargetInterface();
//}
//
//
//sdv::com::SRemoteObjectID MockCommunicationService::CreateInterfaceStub(/*in*/ sdv::interface_t pInterface)
//{
// // Get the stub object
// auto itStub = m_mapStubObjects.find(pInterface);
// if (itStub == m_mapStubObjects.end()) return sdv::com::SRemoteObjectID{0,0,0};
//
// // Assign the interface to the stub object
// sdv::ps::IStubLink* pStubLink = itStub->second->GetInterface<sdv::ps::IStubLink>();
// if (!pStubLink) return sdv::com::SRemoteObjectID{ 0,0,0 };
// pStubLink->Link(pInterface);
//
// // Store the information
// std::shared_ptr<SStubInterface> ptrStubInterface = std::make_shared<SStubInterface>(pInterface.id(), pInterface, itStub->second);
// m_mapStubInterfaces.insert(std::make_pair((uint64_t) ptrStubInterface.get(), ptrStubInterface));
// uint64_t stubID= (uint64_t)ptrStubInterface.get();
// sdv::com::SParticipantID participant = GetParticipantInfo();
// sdv::com::SRemoteObjectID ret;
// ret.uiClusterID = participant.uiClusterID;
// ret.uiProcessID = participant.uiProcessID;
// ret.uiStubID = stubID;
// return ret;
//}
//
//sdv::com::SParticipantID MockCommunicationService::GetParticipantInfo()
//{
// sdv::com::SParticipantID sPartId{};
// sPartId.uiProcessID = (uint64_t)this;
// sPartId.uiClusterID = (uint64_t)this;
// return sPartId;
//}
void* CGeneratorTest::Alloc(size_t nSize)
{
return malloc(nSize);
}
void* CGeneratorTest::Realloc(void* pData, size_t nSize)
{
return realloc(pData, nSize);
}
void CGeneratorTest::Free(void* pData)
{
free(pData);
}

View File

@@ -0,0 +1,189 @@
#ifndef GENERATOR_TEST_H
#define GENERATOR_TEST_H
#include "includes.h"
#include <queue>
#include <thread>
#include <interfaces/core.h>
#include <interfaces/core_ps.h>
#include <support/local_service_access.h>
#include <support/mem_access.h>
#include <support/interface_ptr.h>
#include <interfaces/com.h>
#include <interfaces/repository.h>
#include <support/pssup.h>
class MockCommunicationService :
public sdv::IInterfaceAccess,
public sdv::ps::IMarshallAccess
{
public:
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::IInterfaceAccess)
SDV_INTERFACE_ENTRY(sdv::ps::IMarshallAccess)
END_SDV_INTERFACE_MAP()
/**
* @brief Register proxy object.
*/
void RegisterProxyObject(sdv::interface_t ifc, sdv::IInterfaceAccess* pProxy);
/**
* @brief Register stub object.
*/
void RegisterStubObject(sdv::interface_t ifc, sdv::IInterfaceAccess* pStub);
/**
* @brief Get a proxy for the interface connection to the stub. Overload of sdv::ps::IMarshallAcess::GetProxy.
* @param[in] tStubID Reference to the ID of the stub to connect to.
* @param[in] id The interface ID to get the proxy for.
* @return Returns the interface to the proxy object.
*/
virtual sdv::interface_t GetProxy(/*in*/ const sdv::ps::TMarshallID& tStubID, /*in*/ sdv::interface_id id) override;
/**
* @brief Get a stub for the interface with the supplied ID. Overload of sdv::ps::IMarshallAcess::GetStub.
* @param[in] ifc The interface to get the stub for..
* @return Returns the Stub ID that is assigned to the interface. Or an empty ID when no stub could be found.
*/
virtual sdv::ps::TMarshallID GetStub(/*in*/ sdv::interface_t ifc) override;
private:
/// Vector with stub objects. The position in the vector determines the stub ID.
std::vector<sdv::IInterfaceAccess*> m_vecStubbjects;
/// Map with stub objects for a specific interface
std::map<sdv::interface_t, sdv::ps::TMarshallID> m_mapStubObjects;
/// Map with proxy objects for a specific stub ID.
std::map<sdv::ps::TMarshallID, std::pair<sdv::interface_id, sdv::IInterfaceAccess*>> m_mapProxyObjects;
};
class MockRepoService: public sdv::IInterfaceAccess, public sdv::core::IObjectAccess
{
public:
MockRepoService()
{
m_pRepo = this;
}
~MockRepoService()
{
m_pRepo = nullptr;
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::IInterfaceAccess)
SDV_INTERFACE_ENTRY(sdv::core::IObjectAccess)
END_SDV_INTERFACE_MAP()
virtual IInterfaceAccess* GetObject(/*in*/ const sdv::u8string& ssObjectName) override
{
if(ssObjectName == "CommunicationControl")
{
return &m_ciService;
}
return nullptr;
}
virtual IInterfaceAccess* GetObjectByID(/*in*/ sdv::core::TObjectID /*rObjectID*/) override
{
return nullptr;
}
MockCommunicationService m_ciService;
static MockRepoService* m_pRepo; ///< Global repository access
};
inline sdv::TInterfaceAccessPtr sdv::core::GetObject(const std::string& ssObjectName)
{
return MockRepoService::m_pRepo ? MockRepoService::m_pRepo->GetObject(ssObjectName) : nullptr;
}
/**
* @brief Test class for code genertion tests.
*/
class CGeneratorTest :
public testing::Test, public sdv::core::IMemoryAlloc, public sdv::IInterfaceAccess, public sdv::internal::IInternalMemAlloc
{
public:
/**
* @brief Constructor
*/
CGeneratorTest() = default;
/**
* @brief Set up the test suite.
*/
static void SetUpTestCase();
/**
* @brief Tear down the test suite.
*/
static void TearDownTestCase();
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::IInterfaceAccess)
SDV_INTERFACE_ENTRY(sdv::core::IMemoryAlloc)
END_SDV_INTERFACE_MAP()
/**
* @brief Test setup.
*/
void SetUp() override;
/**
* @brief Test teardown.
*/
void TearDown() override;
/**
* @brief Register stub object and link the object to the stub.
* @param[in] ifc Target interface to marshall.
* @param[in] pStub Pointer to the stub object.
*/
void RegisterStubObject(sdv::interface_t ifc, sdv::IInterfaceAccess* pStub);
/**
* @brief Register proxy object and link the previously registered stub to the proxy.
* @attention Will only work if the stub was registered before the proxy.
* @param[in] ifc Target interface to marshall.
* @param[in] pStub Pointer to the stub object.
* @param[in] pProxy Pointer to the proxy object.
*/
void RegisterProxyObject(sdv::interface_t ifc, sdv::IInterfaceAccess* pStub, sdv::IInterfaceAccess* pProxy);
/**
* @brief Allocate a memory block of the provided length. Overload of sdv::core::IMemoryAlloc::Allocate.
* @param[in] uiLength The length of the memory block to allocate.
* @return The allocated memory or NULL when memory allocation was not possible.
*/
virtual sdv::pointer<uint8_t> Allocate(uint32_t uiLength) override;
private:
/**
* @brief Allocate memory. Overload of sdv::internal::IInternalMemAlloc::Alloc.
* @param[in] nSize The size of the memory to allocate (in bytes).
* @return Pointer to the memory allocation or NULL when memory allocation failed.
*/
virtual void* Alloc(size_t nSize) override;
/**
* @brief Reallocate memory. Overload of sdv::internal::IInternalMemAlloc::Realloc.
* @param[in] pData Pointer to a previous allocation or NULL when no previous allocation was available.
* @param[in] nSize The size of the memory to allocate (in bytes).
* @return Pointer to the memory allocation or NULL when memory allocation failed.
*/
virtual void* Realloc(void* pData, size_t nSize) override;
/**
* @brief Free a memory allocation. Overload of sdv::internal::IInternalMemAlloc::Free.
* @param[in] pData Pointer to a previous allocation.
*/
virtual void Free(void* pData) override;
MockRepoService m_repo;
};
#endif // !defined(GENERATOR_TEST_H)

View File

@@ -0,0 +1,102 @@
#include "includes.h"
#include "parser_test.h"
#include <fstream>
#include <interfaces/core_idl.h>
using CIdlInterfaceIdCompatibilityTest = CParserTest;
// Backup namespace to differentiate between generated and defined in backup file.
namespace bck
{
using u8string = ::sdv::u8string;
template <class T, size_t nFixedSize = 0>
using sequence = ::sdv::sequence<T, nFixedSize>;
template <typename T /*= uint8_t*/>
using pointer = ::sdv::pointer<T>;
namespace internal
{
using IInternalMemAlloc = ::sdv::internal::IInternalMemAlloc;
template <typename T>
inline bck::pointer<T> make_ptr(internal::IInternalMemAlloc* /*pAllocator*/, size_t /*nSize*/)
{
return {};
}
}
}
// Reload the backup file, but change the namespace to "bck".
#define sdv bck
#undef IDL_PARSER_INTERFACE_H
#undef SDV_INTERFACE_H
#undef SDV_EXCEPT_H
#include "../../../sdv_executables/sdv_idl_compiler/core_idl_backup.h"
#undef sdv
/**
* @brief Use inline non-constexpr function to get the ID.
* @details The standard GetInterfaceId and GetExceptionId functions are constexpr and cause to return the same ID for the sdv and
* the bck object, thus not detecting any changes. This is due to the use of "constexpr", implementing the return value of the
* function at compile time. By using an inline function, the access of the ID occurs at runtime allowing to differentiate between
* the bck and sdv IDs.
* @tparam TObj The object to retrieve the ID for.
* @return The ID of the object.
*/
template <typename TObj>
inline uint64_t GetId()
{
return TObj::_id;
}
TEST_F(CIdlInterfaceIdCompatibilityTest, InterfaceAccess)
{
EXPECT_EQ(GetId<sdv::IInterfaceAccess>(), GetId<bck::IInterfaceAccess>());
}
TEST_F(CIdlInterfaceIdCompatibilityTest, SdvExceptions)
{
EXPECT_EQ(GetId<sdv::XNoInterface>(), GetId<bck::XNoInterface>());
EXPECT_EQ(GetId<sdv::XIndexOutOfRange>(), GetId<bck::XIndexOutOfRange>());
EXPECT_EQ(GetId<sdv::XInvalidIterator>(), GetId<bck::XInvalidIterator>());
EXPECT_EQ(GetId<sdv::XNullPointer>(), GetId<bck::XNullPointer>());
EXPECT_EQ(GetId<sdv::XInvalidRefCount>(), GetId<bck::XInvalidRefCount>());
EXPECT_EQ(GetId<sdv::XBufferTooSmall>(), GetId<bck::XBufferTooSmall>());
EXPECT_EQ(GetId<sdv::XHashNotMatching>(), GetId<bck::XHashNotMatching>());
EXPECT_EQ(GetId<sdv::XOffsetPastBufferSize>(), GetId<bck::XOffsetPastBufferSize>());
EXPECT_EQ(GetId<sdv::XUnhandledException>(), GetId<bck::XUnhandledException>());
}
TEST_F(CIdlInterfaceIdCompatibilityTest, CoreExceptions)
{
EXPECT_EQ(GetId<sdv::core::XNoMemMgr>(), GetId<bck::core::XNoMemMgr>());
EXPECT_EQ(GetId<sdv::core::XAllocFailed>(), GetId<bck::core::XAllocFailed>());
}
TEST_F(CIdlInterfaceIdCompatibilityTest, CompilerInterfaces)
{
EXPECT_EQ(GetId<sdv::idl::ICompilerOption>(), GetId<bck::idl::ICompilerOption>());
EXPECT_EQ(GetId<sdv::idl::ICompilerInfo>(), GetId<bck::idl::ICompilerInfo>());
}
TEST_F(CIdlInterfaceIdCompatibilityTest, CompilerExceptions)
{
EXPECT_EQ(GetId<sdv::idl::XCompileError>(), GetId<bck::idl::XCompileError>());
}
TEST_F(CIdlInterfaceIdCompatibilityTest, EntityInterfaces)
{
EXPECT_EQ(GetId<sdv::idl::IEntityInfo>(), GetId<bck::idl::IEntityInfo>());
EXPECT_EQ(GetId<sdv::idl::IEntityIterator>(), GetId<bck::idl::IEntityIterator>());
EXPECT_EQ(GetId<sdv::idl::IEntityContext>(), GetId<bck::idl::IEntityContext>());
EXPECT_EQ(GetId<sdv::idl::IMetaEntity>(), GetId<bck::idl::IMetaEntity>());
EXPECT_EQ(GetId<sdv::idl::IEntityComments>(), GetId<bck::idl::IEntityComments>());
EXPECT_EQ(GetId<sdv::idl::IForwardDeclarationEntity>(), GetId<bck::idl::IForwardDeclarationEntity>());
EXPECT_EQ(GetId<sdv::idl::IDeclarationType>(), GetId<bck::idl::IDeclarationType>());
EXPECT_EQ(GetId<sdv::idl::IDeclarationEntity>(), GetId<bck::idl::IDeclarationEntity>());
EXPECT_EQ(GetId<sdv::idl::IInterfaceEntity>(), GetId<bck::idl::IInterfaceEntity>());
EXPECT_EQ(GetId<sdv::idl::IOperationEntity>(), GetId<bck::idl::IOperationEntity>());
EXPECT_EQ(GetId<sdv::idl::IAttributeEntity>(), GetId<bck::idl::IAttributeEntity>());
EXPECT_EQ(GetId<sdv::idl::IParameterEntity>(), GetId<bck::idl::IParameterEntity>());
EXPECT_EQ(GetId<sdv::idl::IEnumEntity>(), GetId<bck::idl::IEnumEntity>());
EXPECT_EQ(GetId<sdv::idl::IUnionEntity>(), GetId<bck::idl::IUnionEntity>());
EXPECT_EQ(GetId<sdv::idl::ICaseEntity>(), GetId<bck::idl::ICaseEntity>());
}

View File

@@ -0,0 +1,39 @@
#ifndef INCLUDES_H
#define INCLUDES_H
#include "../../include/gtest_custom.h"
/**
* @brief This project implements its own GetObject function.
*/
#define SDV_CUSTOM_GETOBJECT
#include "../../../sdv_executables/sdv_idl_compiler/logger.h"
/**
* @brief For testing purposes, enable the verbosity mode.
*/
inline void EnableVerbosityMode()
{
g_log_control.SetVerbosityMode(EVerbosityMode::report_all);
}
/**
* @brief For testing purposes, disable the verbosity mode.
*/
inline void DisableVerbosityMode()
{
g_log_control.SetVerbosityMode(EVerbosityMode::report_errors);
}
/**
* @brief For testing purposes, enable the verbosity mode within local scope.
*/
class CVerbosityMode
{
public:
CVerbosityMode() {EnableVerbosityMode();}
~CVerbosityMode() {DisableVerbosityMode();}
};
#endif // !defined INCLUDES_H

View File

@@ -0,0 +1,685 @@
#include <interfaces/core.idl>
enum EHello
{
hi,
huhu,
hello,
hallo,
servus,
gruessgott
};
struct SSub
{
int32 i;
};
module Indirect
{
struct SIndirectSub
{
int32 i;
};
};
/**
* @brief Multiply the value with itself.
*/
interface IMultiplyValue
{
/**
* @brief Multiply the value with itself.
* @param[in] n The value.
* @return The result.
*/
native Multiply(in native n);
};
/**
* @brief Add the value with itself.
*/
interface IAddValue
{
/**
* @brief Add the value with itself.
* @param[in] n The value.
* @return The result.
*/
native Add(in native n);
};
typedef boolean TBoolean;
typedef short TShort;
typedef unsigned short TUShort;
typedef long TLong;
typedef unsigned long TULong;
typedef long long TLongLong;
typedef unsigned long long TULongLong;
typedef int8 TInt8;
typedef uint8 TUInt8;
typedef int16 TInt16;
typedef uint16 TUInt16;
typedef int32 TInt32;
typedef uint32 TUInt32;
typedef int64 TInt64;
typedef uint64 TUInt64;
typedef char TChar;
typedef char16 TChar16;
typedef char32 TChar32;
typedef wchar TWChar;
typedef float TFloat;
typedef double TDouble;
typedef long double TLongDouble;
typedef native TNative;
typedef EHello TEHello;
typedef interface_id TInterfaceId;
typedef string TString;
typedef u8string TU8String;
typedef u16string TU16String;
typedef u32string TU32String;
typedef wstring TWString;
typedef string<10> TFString;
typedef u8string<10> TFU8String;
typedef u16string<10> TFU16String;
typedef u32string<10> TFU32String;
typedef wstring<10> TFWString;
typedef pointer<uint8> TU8Pointer;
typedef pointer<string> TSPointer;
typedef pointer<uint8, 20> TU8FixPointer;
typedef pointer<string, 5> TSFixPointer;
typedef sequence<uint8> TU8Sequence;
typedef sequence<string> TSSequence;
typedef sequence<uint8, 20> TU8FixSequence;
typedef sequence<string, 5> TSFixSequence;
typedef interface_t TInterface;
// Typedef of interfaces current not possible. BUG #399464
//typedef IMultiplyValue TMultiplyValue;
typedef SSub TSSub;
typedef Indirect::SIndirectSub TSIndirectSub;
//typedef struct { int32 i; } TStruct; // Anonymous definitions are not allowed at root level
/**
* @brief Mega struct with all possible data types.
*/
struct SMegaStruct
{
boolean bVal;
short sVal;
unsigned short usVal;
long lVal;
unsigned long ulVal;
long long llVal;
unsigned long long ullVal;
int8 i8Val;
uint8 ui8Val;
int16 i16Val;
uint16 ui16Val;
int32 i32Val;
uint32 ui32Val;
int64 i64Val;
uint64 ui64Val;
char cVal;
char16 c16Val;
char32 c32Val;
wchar wcVal;
float fVal;
double dVal;
long double ldVal;
native nVal;
EHello eHelloVal;
interface_id idVal;
string ssVal;
u8string ss8Val;
u16string ss16Val;
u32string ss32Val;
wstring wssVal;
string<10> ssFixVal;
u8string<10> ss8FixVal;
u16string<10> ss16FixVal;
u32string<10> ss32FixVal;
wstring<10> wssFixVal;
pointer<uint8> ptr8Val;
pointer<string> ptrssVal;
pointer<uint8, 20> ptr8FixVal;
pointer<string, 5> ptrssFixVal;
sequence<uint8> seq8Val;
sequence<string> seqssVal;
sequence<uint8, 20> seq8FixVal;
sequence<string, 5> seqssFixVal;
interface_t ifcVal;
IMultiplyValue pMultiplyValue;
SSub sSubVal;
Indirect::SIndirectSub sIndVal;
// Unnamed structs are not supported by IDL (since C++ doesn't support them either)
//struct { int32 i; } sUnnamedVal;
// Anonymous structs are not supported (since C++ doesn't support them either)
//struct { int32 iAnonymous1; int32 iAnonymous2; };
// Anonymous union declarations and unnamed union definitions are supported if not at global scope. But only if they have
// variable based switch statements or a declaration.
union switch(int32) { case 0: int32 iCaseA0; default: int32 iCaseA1; } uUnnamedValA;
//union switch(int32) { case 0: int32 iCaseB0; default: int32 iCaseB1; };
int32 iSwitchValCD;
union switch(iSwitchValCD) { case 0: int32 iCaseC0; default: int32 iCaseC1; } uUnnamedValC;
union switch(iSwitchValCD) { case 0: int32 iCaseD0; default: int32 iCaseD1; };
boolean rgbVal[2];
short rgsVal[2];
unsigned short rgusVal[2];
long rglVal[2];
unsigned long rgulVal[2];
long long rgllVal[2];
unsigned long long rgullVal[2];
int8 rgi8Val[2];
uint8 rgui8Val[2];
int16 rgi16Val[2];
uint16 rgui16Val[2];
int32 rgi32Val[2];
uint32 rgui32Val[2];
int64 rgi64Val[2];
uint64 rgui64Val[2];
char rgcVal[2];
char16 rgc16Val[2];
char32 rgc32Val[2];
wchar rgwcVal[2];
float rgfVal[2];
double rgdVal[2];
long double rgldVal[2];
native rgnVal[2];
EHello rgeHelloVal[2];
interface_id rgidVal[2];
string rgssVal[2];
u8string rgss8Val[2];
u16string rgss16Val[2];
u32string rgss32Val[2];
wstring rgwssVal[2];
string<10> rgssFixVal[2];
u8string<10> rgss8FixVal[2];
u16string<10> rgss16FixVal[2];
u32string<10> rgss32FixVal[2];
wstring<10> rgwssFixVal[2];
pointer<uint8> rgptr8Val[2];
pointer<string> rgptrssVal[2];
pointer<uint8, 20> rgptr8FixVal[2];
pointer<string, 5> rgptrssFixVal[2];
sequence<uint8> rgseq8Val[2];
sequence<string> rgseqssVal[2];
sequence<uint8, 20> rgseq8FixVal[2];
sequence<string, 5> rgseqssFixVal[2];
// Incompatible serdes generation: BUG #398509
//interface_t rgifcVal[2];
SSub rgsSubVal[2];
// Incompatible serdes generation: BUG #398509
//Indirect::SIndirectSub rgsIndVal[2];
// Unnamed struct with array is not yet supported due to incorret serdes code generation: BUG #398246
//struct { int32 i; } rgsUnnamedVal[2];
// Unnamed unions (inline definition) are not supported yet: PBI #398209
//union switch(int32) { case 0: int32 i; default: int32 j; } rguUnnamedVal[2];
// Anonymous structs and unions (unnamed and no declaration) are not supported yet: PBI #397894
//struct { int32 iAnonymous1; int32 iAnonymous2; }[2];
//union switch(int32) { case 0: int32 iAnonymous1; default: int32 iAnonymous2; }[2];
TBoolean tbVal;
TShort tsVal;
TUShort tusVal;
TLong tlVal;
TULong tulVal;
TLongLong tllVal;
TULongLong tullVal;
TInt8 ti8Val;
TUInt8 tui8Val;
TInt16 ti16Val;
TUInt16 tui16Val;
TInt32 ti32Val;
TUInt32 tui32Val;
TInt64 ti64Val;
TUInt64 tui64Val;
TChar tcVal;
TChar16 tc16Val;
TChar32 tc32Val;
TWChar twcVal;
TFloat tfVal;
TDouble tdVal;
TLongDouble tldVal;
TNative tnVal;
TEHello teHelloVal;
TInterfaceId tidVal;
TString tssVal;
TU8String tss8Val;
TU16String tss16Val;
TU32String tss32Val;
TWString twssVal;
TFString tssFixVal;
TFU8String tss8FixVal;
TFU16String tss16FixVal;
TFU32String tss32FixVal;
TFWString twssFixVal;
// Using typedefs of template based types produced an error: BUG #398266
//TU8Pointer tptr8Val;
//TSPointer tptrssVal;
//TU8FixPointer tptr8FixVal;
//TSFixPointer tptrssFixVal;
//TU8Sequence tseq8Val;
//TSSequence tseqssVal;
//TU8FixSequence tseq8FixVal;
//TSFixSequence tseqssFixVal;
TInterface tifcVal;
// Typedef of interfaces current not possible. BUG #399464
//TMultiplyValue ptMultiplyValue;
TSSub tsSubVal;
TSIndirectSub tsIndVal;
// Incompatible serdes generation: BUG #398509
//TStruct tsUnnamedVal;
// Anonymous structs and unions (unnamed and no declaration) are not allowed at root level.
// Unnamed unions (inline definition) are not supported yet: PBI #398209
//union switch(int32) { case 0: int32 i; default: int32 j; } uUnnamedVal;
// Anonymous structs and unions (unnamed and no declaration) are not allowed at root levelsupported yet: PBI #397894
//struct { int32 iAnonymous1; int32 iAnonymous2; };
//union switch(int32) { case 0: int32 iAnonymous1; default: int32 iAnonymous2; };
};
/**
* @brief Mega union with type based switch with all possible data types.
*/
union UMegaTypeBasedUnion switch (uint32)
{
case 1: boolean bVal;
case 2: short sVal;
case 3: unsigned short usVal;
case 4: long lVal;
case 5: unsigned long ulVal;
case 6: long long llVal;
case 7: unsigned long long ullVal;
case 8: int8 i8Val;
case 9: uint8 ui8Val;
case 10: int16 i16Val;
case 11: uint16 ui16Val;
case 12: int32 i32Val;
case 13: uint32 ui32Val;
case 14: int64 i64Val;
case 15: uint64 ui64Val;
case 16: char cVal;
case 17: char16 c16Val;
case 18: char32 c32Val;
case 19: wchar wcVal;
case 20: float fVal;
case 21: double dVal;
case 22: long double ldVal;
case 23: native nVal;
case 24: EHello eHelloVal;
case 25: interface_id idVal;
case 26: string ssVal;
case 27: u8string ss8Val;
case 28: u16string ss16Val;
case 29: u32string ss32Val;
case 30: wstring wssVal;
case 31: string<10> ssFixVal;
case 32: u8string<10> ss8FixVal;
case 33: u16string<10> ss16FixVal;
case 34: u32string<10> ss32FixVal;
case 35: wstring<10> wssFixVal;
case 36: pointer<uint8> ptr8Val;
case 37: pointer<string> ptrssVal;
case 38: pointer<uint8, 20> ptr8FixVal;
case 39: pointer<string, 5> ptrssFixVal;
case 40: sequence<uint8> seq8Val;
case 41: sequence<string> seqssVal;
case 42: sequence<uint8, 20> seq8FixVal;
case 43: sequence<string, 5> seqssFixVal;
case 44: interface_t ifcVal;
case 45: IMultiplyValue pMultiplyValue;
case 46: SSub sSubVal;
// Incompatible serdes generation: BUG #398509
//case 47: Indirect::SIndirectSub sIndVal;
// Unnamed struct inside unions are not supported yet: PBI #398230
//case 48: struct { int32 i; } sUnnamedVal;
// Unnamed unions are not supported yet: PBI #398209
//case 49: union switch(int32) { case 0: int32 i; default: int32 j; } uUnnamedVal;
// Anonymous structs and unions (unnamed and no declaration) are not supported yet: PBI #397894
//case 50: struct { int32 iAnonymous1; int32 iAnonymous2; };
//case 51: union switch(int32) { case 0: int32 iAnonymous1; default: int32 iAnonymous2; };
// Array based members are incorrectly supported: BUG #398246
//case 101: boolean rgbVal[2];
//case 102: short rgsVal[2];
//case 103: unsigned short rgusVal[2];
//case 104: long rglVal[2];
//case 105: unsigned long rgulVal[2];
//case 106: long long rgllVal[2];
//case 107: unsigned long long rgullVal[2];
//case 108: int8 rgi8Val[2];
//case 109: uint8 rgui8Val[2];
//case 110: int16 rgi16Val[2];
//case 111: uint16 rgui16Val[2];
//case 112: int32 rgi32Val[2];
//case 113: uint32 rgui32Val[2];
//case 114: int64 rgi64Val[2];
//case 115: uint64 rgui64Val[2];
//case 116: char rgcVal[2];
//case 117: char16 rgc16Val[2];
//case 118: char32 rgc32Val[2];
//case 119: wchar rgwcVal[2];
//case 120: float rgfVal[2];
//case 121: double rgdVal[2];
////case 122: long double rgldVal[2];
//case 123: native rgnVal[2];
//case 124: EHello rgeHelloVal[2];
//case 125: interface_id rgidVal[2];
//case 126: string rgssVal[2];
//case 127: u8string rgss8Val[2];
//case 128: u16string rgss16Val[2];
//case 129: u32string rgss32Val[2];
//case 130: wstring rgwssVal[2];
//case 131: string<10> rgssFixVal[2];
//case 132: u8string<10> rgss8FixVal[2];
//case 133: u16string<10> rgss16FixVal[2];
//case 134: u32string<10> rgss32FixVal[2];
//case 135: wstring<10> rgwssFixVal[2];
//case 136: pointer<uint8, 20> rgptr8Val[2];
//case 137: pointer<string, 5> rgptrssVal[2];
//case 138: sequence<uint8, 20> rgseq8Val[2];
//case 139: sequence<string, 5> rgseqssVal[2];
//case 140: interface_t rgifcVal[2];
//case 141: SSub rgsSubVal[2];
//case 142: Indirect::SIndirectSub rgsIndVal[2];
//// Unnamed struct inside unions are not supported yet: PBI #398230
////case 143: struct { int32 i; int32 j; } sUnnamedVal[2];
//// Unnamed unions are not supported yet: PBI #398209
////case 144: union switch(int32) { case 0: int32 i; default: int32 j; } uUnnamedVal[2];
//// Anonymous structs and unions (unnamed and no declaration) are not supported yet: PBI #397894
////case 145: struct { int32 iAnonymous1; int32 iAnonymous2; }[2];
////case 146: union switch(int32) { case 0: int32 iAnonymous1; default: int32 iAnonymous2; }[2];
case 201: TBoolean tbVal;
case 202: TShort tsVal;
case 203: TUShort tusVal;
case 204: TLong tlVal;
case 205: TULong tulVal;
case 206: TLongLong tllVal;
case 207: TULongLong tullVal;
case 208: TInt8 ti8Val;
case 209: TUInt8 tui8Val;
case 210: TInt16 ti16Val;
case 211: TUInt16 tui16Val;
case 212: TInt32 ti32Val;
case 213: TUInt32 tui32Val;
case 214: TInt64 ti64Val;
case 215: TUInt64 tui64Val;
case 216: TChar tcVal;
case 217: TChar16 tc16Val;
case 218: TChar32 tc32Val;
case 219: TWChar twcVal;
case 220: TFloat tfVal;
case 221: TDouble tdVal;
case 222: TLongDouble tldVal;
case 223: TNative tnVal;
case 224: TEHello teHelloVal;
case 225: TInterfaceId tidVal;
case 226: TString tssVal;
case 227: TU8String tss8Val;
case 228: TU16String tss16Val;
case 229: TU32String tss32Val;
case 230: TWString twssVal;
case 231: TFString tssFixVal;
case 232: TFU8String tss8FixVal;
case 233: TFU16String tss16FixVal;
case 234: TFU32String tss32FixVal;
case 235: TFWString twssFixVal;
// Using typedefs of template based types produced an error: BUG #398266
//case 236: TU8Pointer tptr8Val;
//case 237: TSPointer tptrssVal;
//case 238: TU8FixPointer tptr8FixVal;
//case 239: TSFixPointer tptrssFixVal;
//case 240: TU8Sequence tseq8Val;
//case 241: TSSequence tseqssVal;
//case 242: TU8FixSequence tseq8FixVal;
//case 243: TSFixSequence tseqssFixVal;
case 244: TInterface tifcVal;
// Typedef of interfaces current not possible. BUG #399464
//case 245: TMultiplyValue ptMultiplyValue;
case 246: TSSub tsSubVal;
case 247: TSIndirectSub tsIndVal;
// Incompatible serdes generation: BUG #398509
//case 248: struct { int32 i; } tsUnnamedVal;
// Unnamed unions are not supported yet: PBI #398209
//case 249: union switch(int32) { case 0: int32 i; default: int32 j; } tuUnnamedVal;
// Anonymous structs and unions (unnamed and no declaration) are not supported yet: PBI #397894
//case 250: struct { int32 iAnonymous1; int32 iAnonymous2; };
//case 251: union switch(int32) { case 0: int32 iAnonymous1; default: int32 iAnonymous2; };
};
/**
* @brief Mega union with var based switch with all possible data types.
*/
struct SMegaVarBasedUnion
{
uint32 uiSwitchType;
union UUnion switch (uiSwitchType)
{
case 1: boolean bVal;
case 2: short sVal;
case 3: unsigned short usVal;
case 4: long lVal;
case 5: unsigned long ulVal;
case 6: long long llVal;
case 7: unsigned long long ullVal;
case 8: int8 i8Val;
case 9: uint8 ui8Val;
case 10: int16 i16Val;
case 11: uint16 ui16Val;
case 12: int32 i32Val;
case 13: uint32 ui32Val;
case 14: int64 i64Val;
case 15: uint64 ui64Val;
case 16: char cVal;
case 17: char16 c16Val;
case 18: char32 c32Val;
case 19: wchar wcVal;
case 20: float fVal;
case 21: double dVal;
case 22: long double ldVal;
case 23: native nVal;
case 24: EHello eHelloVal;
case 25: interface_id idVal;
case 26: string ssVal;
case 27: u8string ss8Val;
case 28: u16string ss16Val;
case 29: u32string ss32Val;
case 30: wstring wssVal;
case 31: string<10> ssFixVal;
case 32: u8string<10> ss8FixVal;
case 33: u16string<10> ss16FixVal;
case 34: u32string<10> ss32FixVal;
case 35: wstring<10> wssFixVal;
case 36: pointer<uint8> ptr8Val;
case 37: pointer<string> ptrssVal;
case 38: pointer<uint8, 20> ptr8FixVal;
case 39: pointer<string, 5> ptrssFixVal;
case 40: sequence<uint8> seq8Val;
case 41: sequence<string> seqssVal;
case 42: sequence<uint8, 20> seq8FixVal;
case 43: sequence<string, 5> seqssFixVal;
case 44: interface_t ifcVal;
case 45: IMultiplyValue pMultiplyValue;
case 46: SSub sSubVal;
// Incompatible serdes generation: BUG #398509
//case 47: Indirect::SIndirectSub sIndVal;
// Unnamed struct inside unions are not supported yet: PBI #398230
//case 48: struct { int32 i; } sUnnamedVal;
// Unnamed unions are not supported yet: PBI #398209
//case 49: union switch(int32) { case 0: int32 i; default: int32 j; } uUnnamedVal;
// Anonymous structs and unions (unnamed and no declaration) are not supported yet: PBI #397894
//case 50: struct { int32 iAnonymous1; int32 iAnonymous2; };
//case 51: union switch(int32) { case 0: int32 iAnonymous1; default: int32 iAnonymous2; };
// Array based members are incorrectly supported: BUG #398246
//case 101: boolean rgbVal[2];
//case 102: short rgsVal[2];
//case 103: unsigned short rgusVal[2];
//case 104: long rglVal[2];
//case 105: unsigned long rgulVal[2];
//case 106: long long rgllVal[2];
//case 107: unsigned long long rgullVal[2];
//case 108: int8 rgi8Val[2];
//case 109: uint8 rgui8Val[2];
//case 110: int16 rgi16Val[2];
//case 111: uint16 rgui16Val[2];
//case 112: int32 rgi32Val[2];
//case 113: uint32 rgui32Val[2];
//case 114: int64 rgi64Val[2];
//case 115: uint64 rgui64Val[2];
//case 116: char rgcVal[2];
//case 117: char16 rgc16Val[2];
//case 118: char32 rgc32Val[2];
//case 119: wchar rgwcVal[2];
//case 120: float rgfVal[2];
//case 121: double rgdVal[2];
////case 122: long double rgldVal[2];
//case 123: native rgnVal[2];
//case 124: EHello rgeHelloVal[2];
//case 125: interface_id rgidVal[2];
//case 126: string rgssVal[2];
//case 127: u8string rgss8Val[2];
//case 128: u16string rgss16Val[2];
//case 129: u32string rgss32Val[2];
//case 130: wstring rgwssVal[2];
//case 131: string<10> rgssFixVal[2];
//case 132: u8string<10> rgss8FixVal[2];
//case 133: u16string<10> rgss16FixVal[2];
//case 134: u32string<10> rgss32FixVal[2];
//case 135: wstring<10> rgwssFixVal[2];
//case 136: pointer<uint8, 20> rgptr8Val[2];
//case 137: pointer<string, 5> rgptrssVal[2];
//case 138: sequence<uint8, 20> rgseq8Val[2];
//case 139: sequence<string, 5> rgseqssVal[2];
//case 140: interface_t rgifcVal[2];
//case 141: SSub rgsSubVal[2];
//case 142: Indirect::SIndirectSub rgsIndVal[2];
//// Unnamed struct inside unions are not supported yet: PBI #398230
////case 143: struct { int32 i; int32 j; } sUnnamedVal[2];
//// Unnamed unions are not supported yet: PBI #398209
////case 144: union switch(int32) { case 0: int32 i; default: int32 j; } uUnnamedVal[2];
//// Anonymous structs and unions (unnamed and no declaration) are not supported yet: PBI #397894
////case 145: struct { int32 iAnonymous1; int32 iAnonymous2; }[2];
////case 146: union switch(int32) { case 0: int32 iAnonymous1; default: int32 iAnonymous2; }[2];
case 201: TBoolean tbVal;
case 202: TShort tsVal;
case 203: TUShort tusVal;
case 204: TLong tlVal;
case 205: TULong tulVal;
case 206: TLongLong tllVal;
case 207: TULongLong tullVal;
case 208: TInt8 ti8Val;
case 209: TUInt8 tui8Val;
case 210: TInt16 ti16Val;
case 211: TUInt16 tui16Val;
case 212: TInt32 ti32Val;
case 213: TUInt32 tui32Val;
case 214: TInt64 ti64Val;
case 215: TUInt64 tui64Val;
case 216: TChar tcVal;
case 217: TChar16 tc16Val;
case 218: TChar32 tc32Val;
case 219: TWChar twcVal;
case 220: TFloat tfVal;
case 221: TDouble tdVal;
case 222: TLongDouble tldVal;
case 223: TNative tnVal;
case 224: TEHello teHelloVal;
case 225: TInterfaceId tidVal;
case 226: TString tssVal;
case 227: TU8String tss8Val;
case 228: TU16String tss16Val;
case 229: TU32String tss32Val;
case 230: TWString twssVal;
case 231: TFString tssFixVal;
case 232: TFU8String tss8FixVal;
case 233: TFU16String tss16FixVal;
case 234: TFU32String tss32FixVal;
case 235: TFWString twssFixVal;
// Using typedefs of template based types produced an error: BUG #398266
//case 236: TU8Pointer tptr8Val;
//case 237: TSPointer tptrssVal;
//case 238: TU8FixPointer tptr8FixVal;
//case 239: TSFixPointer tptrssFixVal;
//case 240: TU8Sequence tseq8Val;
//case 241: TSSequence tseqssVal;
//case 242: TU8FixSequence tseq8FixVal;
//case 243: TSFixSequence tseqssFixVal;
case 244: TInterface tifcVal;
// Typedef of interfaces current not possible. BUG #399464
//case 245: TMultiplyValue ptMultiplyValue;
case 246: TSSub tsSubVal;
case 247: TSIndirectSub tsIndVal;
// Incompatible serdes generation: BUG #398509
//case 248: struct { int32 i; } tsUnnamedVal;
// Unnamed unions are not supported yet: PBI #398209
//case 249: union switch(int32) { case 0: int32 i; default: int32 j; } tuUnnamedVal;
// Anonymous structs and unions (unnamed and no declaration) are not supported yet: PBI #397894
//case 250: struct { int32 iAnonymous1; int32 iAnonymous2; };
//case 251: union switch(int32) { case 0: int32 iAnonymous1; default: int32 iAnonymous2; };
} uVal;
};
/**
* @brief Mega struct and union test.
*/
interface IMegaTest
{
/**
* @brief Update the mega struct. This will test marshalling and unmarshalling of the mega struct.
* @param[in, out] rsStruct Reference to the struct to update.
*/
void ProcessMegaStruct(inout SMegaStruct rsStruct);
/**
* @brief Update the mega type based union. This will test marshalling and unmarshalling of the mega union.
* @param[in, out] ruUnion Reference to the union to update.
*/
void ProcessMegaTypeBasedUnion(inout UMegaTypeBasedUnion ruUnion);
/**
* @brief Update the mega var based union. This will test marshalling and unmarshalling of the mega union.
* @param[in, out] ruUnion Reference to the union to update.
*/
void ProcessMegaVarBasedUnion(inout SMegaVarBasedUnion ruUnion);
};
/**
* @brief Use this interface to return a friendly text.
*/
interface ISayHello
{
/**
* @brief Say hello!
* @return The greeting text.
*/
string Hello();
};
/**
* @brief Get the hello interface.
*/
interface IRequestHello
{
/**
* @brief Request the hello interface.
* @return pHello The hello interface.
*/
ISayHello Request();
};
/**
* @brief Register the hello interface as a callback.
*/
interface IRegisterHelloCallback
{
/**
* @brief Register the callback with the hello interface.
* @param[in] pHello The hello interface.
*/
void Register(in ISayHello pHello);
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
#ifndef LEXER_TEST_H
#define LEXER_TEST_H
/**
* \brief Test class for instantiation tests.
*/
class CLexerTest : public testing::Test
{
public:
/**
* \brief Constructor
*/
CLexerTest() = default;
/**
* \brief Set up the test suite.
*/
static void SetUpTestCase();
/**
* \brief Tear down the test suite.
*/
static void TearDownTestCase();
/**
* \brief Test setup.
*/
void SetUp() override;
/**
* \brief Test teardown.
*/
void TearDown() override;
};
#endif // !defined LEXER_TEST_H

View File

@@ -0,0 +1,5 @@
exception InsufficientFunds
{
int32 i;
};

View File

@@ -0,0 +1,18 @@
#include "includes.h"
#include "../../../global/process_watchdog.h"
#include "generated/test.h"
/**
* @brief Main function
*/
#if defined(_WIN32) && defined(_UNICODE)
extern "C" int wmain(int argc, wchar_t* argv[])
#else
extern "C" int main(int argc, char* argv[])
#endif
{
CProcessWatchdog watchdog;
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,782 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/declaration_entity.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/constvariant.inl"
#include "../../../sdv_executables/sdv_idl_compiler/entities/entity_value.h"
using CParserConstAssignmentTest = CParserTest;
TEST_F(CParserConstAssignmentTest, ConstAssignment)
{
EXPECT_TRUE(CParser("const long hello = 10 * 10;").Parse().Root()->Find("hello"));
}
TEST_F(CParserConstAssignmentTest, NestedConstAssignment)
{
EXPECT_TRUE(CParser("module Test { const long hello = 10; };").Parse().Root()->Find("Test::hello"));
}
TEST_F(CParserConstAssignmentTest, ConstMissingType)
{
EXPECT_THROW(CParser("const hello = 10 * 10;").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstMissingSemiColon)
{
EXPECT_THROW(CParser("const long hello = 10 * 10").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstMissingAssignmentOperator)
{
EXPECT_THROW(CParser("const long hello;").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstArray)
{
EXPECT_EQ(CParser("const long rglHello[2] = {1, 2};").Parse().Root()->Find<CVariableEntity>("rglHello")->ValueRef()->Get<CArrayValueNode>()->GetSize(), 2);
EXPECT_EQ(CParser("const long rglHello[] = {1, 2};").Parse().Root()->Find<CVariableEntity>("rglHello")->ValueRef()->Get<CArrayValueNode>()->GetSize(), 2);
EXPECT_EQ(CParser("const long rglHello[] = {1, 2}; const long rglHello2[rglHello[1]] = {rglHello[0], rglHello[1]};").
Parse().Root()->Find<CVariableEntity>("rglHello2")->ValueRef()->Get<CArrayValueNode>()->GetSize(), 2);
EXPECT_THROW(CParser("const long rglHello[2] = {1, 2, 3};").Parse(), CCompileException);
EXPECT_THROW(CParser("const long rglHello[2] = {1};").Parse(), CCompileException);
EXPECT_THROW(CParser("const long rglHello[2] = {1, 2;").Parse(), CCompileException);
EXPECT_THROW(CParser("const long rglHello[2] = 1, 2};").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, MultipleConstAssignments)
{
EXPECT_TRUE(CParser("const int8 iHello = 10, iHello2 = 20;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = 10, iHello2 = 20;").Parse().Root()->Find("iHello2"));
EXPECT_EQ(CParser("const long rglHello[] = {1, 2}, rglHello2[rglHello[1]] = {rglHello[0], rglHello[1]};").
Parse().Root()->Find<CVariableEntity>("rglHello2")->ValueRef()->Get<CArrayValueNode>()->GetSize(), 2);
EXPECT_THROW(CParser("const int8 iHello = 10, const int iHello2 = 20;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int8 iHello = 10, int iHello2 = 20;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int8 iHello = 10, iHello2;").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentInt8)
{
EXPECT_TRUE(CParser("const int8 iHello = 10;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = 10l;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = 10ll;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = 'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = L'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = u'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = U'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = '\\0\\0\\0A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = true;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = false;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = TRUE;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = FALSE;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = nullptr;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = NULL;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = -128;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 iHello = +127;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int8 rgiHello[2] = {+127, -127};").Parse().Root()->Find("rgiHello"));
EXPECT_THROW(CParser("const int8 iHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int8 iHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int8 iHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int8 iHello = 10.0d;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int8 iHello = 128;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int8 iHello = L'\\u20ac';").Parse(), CCompileException);
EXPECT_THROW(CParser("const int8 uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentInt16)
{
EXPECT_TRUE(CParser("const int16 iHello = 10;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = 10l;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = 10ll;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = 'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = L'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = u'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = U'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = '\\0\\0BA';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = true;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = false;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = TRUE;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = FALSE;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = nullptr;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = NULL;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = -32768;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 iHello = +32767;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int16 rgiHello[2] = {+32767, -32767};").Parse().Root()->Find("rgiHello"));
EXPECT_THROW(CParser("const int16 iHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int16 iHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int16 iHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int16 iHello = 10.0d;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int16 iHello = 32768;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int16 iHello = u'\\U00010437';").Parse(), CCompileException);
EXPECT_THROW(CParser("const int16 uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentInt32)
{
EXPECT_TRUE(CParser("const int32 iHello = 10;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = 10l;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = 10ll;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = 'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = L'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = u'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = U'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = 'DCBA';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = true;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = false;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = TRUE;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = FALSE;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = nullptr;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = NULL;").Parse().Root()->Find("iHello"));
// NOTE: The value -2147483648 would still fit in an integer. The C++-parsing, however, sees the minus operator not as part
// of the number and therefore does a calculation of "unary minus" on number "2147483648", which doesn't fit in the 32-bits
// any more.
EXPECT_TRUE(CParser("const int32 iHello = -2147483647;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = -2147483648ll;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 iHello = +2147483647;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int32 rgiHello[2] = {+2147483647, -2147483647};").Parse().Root()->Find("rgiHello"));
EXPECT_THROW(CParser("const int32 iHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int32 iHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int32 iHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int32 iHello = 10.0d;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int32 iHello = 2147483648;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int32 uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentInt64)
{
EXPECT_TRUE(CParser("const int64 iHello = 10;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = 10l;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = 10ll;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = 'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = L'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = u'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = U'A';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = 'DCBA';").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = true;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = false;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = TRUE;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = FALSE;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = nullptr;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = NULL;").Parse().Root()->Find("iHello"));
// NOTE: The value -9223372036854775808 would still fit in an integer. The C++-parsing, however, sees the minus operator not
// as part of the number and therefore does a calculation of "unary minus" on number "9223372036854775808", which doesn't fit
// in the 64-bits any more.
EXPECT_THROW(CParser("const int64 iHello = -9223372036854775808ll;").Parse(), CCompileException);
EXPECT_TRUE(CParser("const int64 iHello = -9223372036854775807ll - 1;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 iHello = +9223372036854775807ll;").Parse().Root()->Find("iHello"));
EXPECT_TRUE(CParser("const int64 rgiHello[2] = {+9223372036854775807ll, -9223372036854775807ll};").Parse().Root()->Find("rgiHello"));
EXPECT_THROW(CParser("const int64 iHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int64 iHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int64 iHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int64 iHello = 10.0d;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int64 iHello = 9223372036854775808ll;").Parse(), CCompileException);
EXPECT_THROW(CParser("const int64 uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentUInt8)
{
EXPECT_TRUE(CParser("const uint8 uiHello = 10;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = 10l;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = 10ll;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = 'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = L'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = u'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = U'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = '\\0\\0\\0A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = true;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = false;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = TRUE;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = FALSE;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = nullptr;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = NULL;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = +0;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = -0;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 uiHello = +255;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint8 rguiHello[2] = {0, +255};").Parse().Root()->Find("rguiHello"));
EXPECT_THROW(CParser("const uint8 uiHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint8 uiHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint8 uiHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint8 uiHello = 10.0d;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint8 uiHello = 256;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint8 uiHello = L'\\u20ac';").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint8 uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentUInt16)
{
EXPECT_TRUE(CParser("const uint16 uiHello = 10;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = 10l;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = 10ll;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = 'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = L'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = u'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = U'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = '\\0\\0BA';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = true;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = false;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = TRUE;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = FALSE;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = nullptr;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = NULL;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = +0;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = -0;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 uiHello = +65535;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint16 rguiHello[2] = {0, +65535};").Parse().Root()->Find("rguiHello"));
EXPECT_THROW(CParser("const uint16 uiHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint16 uiHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint16 uiHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint16 uiHello = 10.0d;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint16 uiHello = 65536;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint16 uiHello = u'\\U00010437';").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint16 uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentUInt32)
{
EXPECT_TRUE(CParser("const uint32 uiHello = 10;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = 10l;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = 10ll;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = 'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = L'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = u'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = U'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = 'DCBA';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = true;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = false;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = TRUE;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = FALSE;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = nullptr;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = NULL;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = +0;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = -0;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 uiHello = +4294967295;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint32 rguiHello[2] = {0, +4294967295};").Parse().Root()->Find("rguiHello"));
EXPECT_THROW(CParser("const uint32 uiHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint32 uiHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint32 uiHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint32 uiHello = 10.0d;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint32 uiHello = 4294967296;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint32 uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentUInt64)
{
EXPECT_TRUE(CParser("const uint64 uiHello = 10;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = 10l;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = 10ll;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = 'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = L'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = u'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = U'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = 'DCBA';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = true;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = false;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = TRUE;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = FALSE;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = nullptr;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = NULL;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = +0;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = -0;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 uiHello = +18446744073709551615ull;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const uint64 rguiHello[2] = {0, +18446744073709551615ull};").Parse().Root()->Find("rguiHello"));
EXPECT_THROW(CParser("const uint64 uiHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint64 uiHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint64 uiHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint64 uiHello = 10.0d;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint64 uiHello = 18446744073709551616ull;").Parse(), CCompileException);
EXPECT_THROW(CParser("const uint64 uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmenChar)
{
EXPECT_TRUE(CParser("const char cHello = 10;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = 10l;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = 10ll;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = 'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = L'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = u'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = U'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = '\\0\\0\\0A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = true;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = false;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = TRUE;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = FALSE;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = nullptr;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = NULL;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = -128;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char cHello = +127;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char rgcHello[2] = {-127, +127};").Parse().Root()->Find("rgcHello"));
EXPECT_THROW(CParser("const char cHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char cHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char cHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char cHello = 10.0d;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char cHello = 128;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char cHello = L'\\u20ac';").Parse(), CCompileException);
EXPECT_THROW(CParser("const char uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentChar16)
{
EXPECT_TRUE(CParser("const char16 cHello = 10;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = 10l;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = 10ll;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = 'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = L'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = u'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = U'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = '\\0\\0BA';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = true;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = false;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = TRUE;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = FALSE;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = nullptr;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = NULL;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = +0;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = -0;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 cHello = +65535;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char16 rgcHello[2] = {0, +65535};").Parse().Root()->Find("rgcHello"));
EXPECT_THROW(CParser("const char16 cHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char16 cHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char16 cHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char16 cHello = 10.0d;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char16 cHello = 65536;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char16 cHello = u'\\U00010437';").Parse(), CCompileException);
EXPECT_THROW(CParser("const char16 uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentChar32)
{
EXPECT_TRUE(CParser("const char32 cHello = 10;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = 10l;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = 10ll;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = 'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = L'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = u'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = U'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = 'DCBA';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = true;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = false;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = TRUE;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = FALSE;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = nullptr;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = NULL;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = +0;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 cHello = -0;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const char32 rgcHello[2] = {0, +4294967295};").Parse().Root()->Find("rgcHello"));
EXPECT_THROW(CParser("const char32 cHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char32 cHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char32 cHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char32 cHello = 10.0d;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char32 cHello = 4294967296;").Parse(), CCompileException);
EXPECT_THROW(CParser("const char32 uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentWChar)
{
EXPECT_TRUE(CParser("const wchar cHello = 10;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = 10l;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = 10ll;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = 'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = L'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = u'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = U'A';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = '\\0\\0BA';").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = true;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = false;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = TRUE;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = FALSE;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = nullptr;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = NULL;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = +0;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = -0;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar cHello = +65535;").Parse().Root()->Find("cHello"));
EXPECT_TRUE(CParser("const wchar rgcHello[2] = {0, +65535};").Parse().Root()->Find("rgcHello"));
EXPECT_THROW(CParser("const wchar cHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const wchar cHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const wchar cHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const wchar cHello = 10.0d;").Parse(), CCompileException);
#ifdef _MSC_VER
EXPECT_THROW(CParser("const wchar cHello = 65536;").Parse(), CCompileException);
EXPECT_THROW(CParser("const wchar cHello = u'\\U00010437';").Parse(), CCompileException);
#else
EXPECT_THROW(CParser("const wchar cHello = 4294967296;").Parse(), CCompileException);
#endif
EXPECT_THROW(CParser("const wchar uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentOctet)
{
EXPECT_TRUE(CParser("const octet uiHello = 10;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = 10l;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = 10ll;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = 'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = L'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = u'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = U'A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = '\\0\\0\\0A';").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = true;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = false;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = TRUE;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = FALSE;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = nullptr;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = NULL;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = +0;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = -0;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet uiHello = +255;").Parse().Root()->Find("uiHello"));
EXPECT_TRUE(CParser("const octet rguiHello[2] = {0, +255};").Parse().Root()->Find("rguiHello"));
EXPECT_THROW(CParser("const octet uiHello = 10.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const octet uiHello = 10.0f;").Parse(), CCompileException);
EXPECT_THROW(CParser("const octet uiHello = 10.0l;").Parse(), CCompileException);
EXPECT_THROW(CParser("const octet uiHello = 10.0d;").Parse(), CCompileException);
EXPECT_THROW(CParser("const octet uiHello = 256;").Parse(), CCompileException);
EXPECT_THROW(CParser("const octet uiHello = L'\\u20ac';").Parse(), CCompileException);
EXPECT_THROW(CParser("const octet uiHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentFloat)
{
EXPECT_TRUE(CParser("const float fHello = 111.11;").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = -2.22;").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = 0X1.BC70A3D70A3D7P+6;").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = .18973e+39;").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = 10ull;").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = 'A';").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = L'A';").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = u'A';").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = U'A';").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = '\\0\\0\\0A';").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = true;").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = false;").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = TRUE;").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = FALSE;").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = nullptr;").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = NULL;").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser((std::string("const float fHello = ") + std::to_string(std::numeric_limits<float>::min()) + ";").c_str()).Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser((std::string("const float fHello = ") + std::to_string(std::numeric_limits<float>::max()) + ";").c_str()).Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser((std::string("const float fHello = ") + std::to_string(std::numeric_limits<float>::lowest()) + ";").c_str()).Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float fHello = 10.0d;").Parse().Root()->Find("fHello"));
EXPECT_TRUE(CParser("const float rgfHello[2] = {10.0d, 20.0d};").Parse().Root()->Find("rgfHello"));
EXPECT_THROW(CParser("const float fHello = 3.40283e+38;").Parse(), CCompileException);
EXPECT_THROW(CParser("const float fHello = -3.40283e+38;").Parse(), CCompileException);
EXPECT_THROW(CParser("const float fHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentDouble)
{
EXPECT_TRUE(CParser("const double ldHello = 111.11;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = -2.22;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = 0X1.BC70A3D70A3D7P+6;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = .18973e+39;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = 10ull;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = 'A';").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = L'A';").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = u'A';").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = U'A';").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = '\\0\\0\\0A';").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = true;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = false;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = TRUE;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = FALSE;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = nullptr;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double ldHello = NULL;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser((std::string("const double dHello = ") + std::to_string(std::numeric_limits<double>::min()) + ";").c_str()).Parse().Root()->Find("dHello"));
EXPECT_TRUE(CParser((std::string("const double dHello = ") + std::to_string(std::numeric_limits<double>::max()) + ";").c_str()).Parse().Root()->Find("dHello"));
EXPECT_TRUE(CParser((std::string("const double dHello = ") + std::to_string(std::numeric_limits<double>::lowest()) + ";").c_str()).Parse().Root()->Find("dHello"));
EXPECT_TRUE(CParser("const double ldHello = 10.0d;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const double rgldHello[2] = {10.0d, 20.0d};").Parse().Root()->Find("rgldHello"));
EXPECT_THROW(CParser("const double ldHello = 1.7977e+308;").Parse(), CCompileException);
EXPECT_THROW(CParser("const double ldHello = -1.7977e+308;").Parse(), CCompileException);
EXPECT_THROW(CParser("const double ldHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentLongDouble)
{
EXPECT_TRUE(CParser("const long double ldHello = 111.11;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = -2.22;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = 0X1.BC70A3D70A3D7P+6;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = .18973e+39;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = 10ull;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = 'A';").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = L'A';").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = u'A';").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = U'A';").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = '\\0\\0\\0A';").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = true;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = false;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = TRUE;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = FALSE;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = nullptr;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = NULL;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser((std::string("const long double ldHello = ") + std::to_string(std::numeric_limits<long double>::min()) + ";").c_str()).Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser((std::string("const long double ldHello = ") + std::to_string(std::numeric_limits<long double>::max()) + ";").c_str()).Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser((std::string("const long double ldHello = ") + std::to_string(std::numeric_limits<long double>::lowest()) + ";").c_str()).Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double ldHello = 10.0d;").Parse().Root()->Find("ldHello"));
EXPECT_TRUE(CParser("const long double rgldHello[2] = {10.0d, 20.0d};").Parse().Root()->Find("rgldHello"));
EXPECT_THROW(CParser("const long double ldHello = 1.18974e+4932;").Parse(), CCompileException);
EXPECT_THROW(CParser("const long double ldHello = -1.18974e+4932;").Parse(), CCompileException);
EXPECT_THROW(CParser("const long double ldHello = u8\"\\u20ac\";").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentFixed)
{
EXPECT_TRUE(CParser("const fixed fixHello = 111.11d;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = -2.22D;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = 0X1.BC70A3D70A3D7P+6;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = 10ull;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = 'A';").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = L'A';").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = u'A';").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = U'A';").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = '\\0\\0\\0A';").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = true;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = false;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = TRUE;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = FALSE;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = nullptr;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = NULL;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = -2147483647;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = 2147483648;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = 0.0000000004656612873077392578125d;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed fixHello = 10.0d;").Parse().Root()->Find("fixHello"));
EXPECT_TRUE(CParser("const fixed rgfixHello[2] = {10.0d, 20.0d};").Parse().Root()->Find("rgfixHello"));
EXPECT_THROW(CParser("const fixed fHello = 0.2147484000e+10;").Parse(), CCompileException);
EXPECT_THROW(CParser("const fixed fHello = -0.2147484000e+10;").Parse(), CCompileException);
EXPECT_THROW(CParser("const fixed fHello = u8\"\\u20ac\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const fixed fixHello = .18973e+39;").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentBoolean)
{
EXPECT_TRUE(CParser("const boolean bHello = true;").Parse().Root()->Find("bHello"));
EXPECT_TRUE(CParser("const boolean bHello = false;").Parse().Root()->Find("bHello"));
EXPECT_TRUE(CParser("const boolean bHello = TRUE;").Parse().Root()->Find("bHello"));
EXPECT_TRUE(CParser("const boolean bHello = FALSE;").Parse().Root()->Find("bHello"));
EXPECT_TRUE(CParser("const boolean bHello = 1;").Parse().Root()->Find("bHello"));
EXPECT_TRUE(CParser("const boolean bHello = 0;").Parse().Root()->Find("bHello"));
EXPECT_TRUE(CParser("const boolean bHello = '\\1';").Parse().Root()->Find("bHello"));
EXPECT_TRUE(CParser("const boolean bHello = '\\0\\0\\0\\1';").Parse().Root()->Find("bHello"));
EXPECT_TRUE(CParser("const boolean bHello = -1;").Parse().Root()->Find("bHello"));
EXPECT_TRUE(CParser("const boolean bHello = 2;").Parse().Root()->Find("bHello"));
EXPECT_TRUE(CParser("const boolean bHello = 1.0;").Parse().Root()->Find("bHello"));
EXPECT_TRUE(CParser("const boolean rgbHello[2] = {1.0, 2.0};").Parse().Root()->Find("rgbHello"));
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentString)
{
EXPECT_TRUE(CParser("const string ssHello = \"hello\";").Parse().Root()->Find("ssHello"));
EXPECT_TRUE(CParser("const string ssHello = \"hello\" \"hello2\";").Parse().Root()->Find("ssHello"));
EXPECT_TRUE(CParser("const string rgssHello[2] = {\"hello\", \"hello2\" \"hello3\"};").Parse().Root()->Find("rgssHello"));
EXPECT_THROW(CParser("const string ssHello = u8\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const string ssHello = u\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const string ssHello = U\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const string ssHello = L\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const string ssHello = \"hello\" u8\"hello2\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const string ssHello = true;").Parse(), CCompileException);
EXPECT_THROW(CParser("const string ssHello = 1;").Parse(), CCompileException);
EXPECT_THROW(CParser("const string ssHello = 1.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const string ssHello = 'A';").Parse(), CCompileException);
EXPECT_THROW(CParser("const string ssHello = nullptr;").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentUtf8String)
{
EXPECT_TRUE(CParser("const u8string ssHello = u8\"hello\";").Parse().Root()->Find("ssHello"));
EXPECT_TRUE(CParser("const u8string ssHello = u8\"hello\" u8\"hello2\";").Parse().Root()->Find("ssHello"));
EXPECT_TRUE(CParser("const u8string rgssHello[2] = {u8\"hello\", u8\"hello2\" u8\"hello3\"};").Parse().Root()->Find("rgssHello"));
EXPECT_THROW(CParser("const u8string ssHello = \"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u8string ssHello = u\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u8string ssHello = U\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u8string ssHello = L\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u8string ssHello = u8\"hello\" \"hello2\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u8string ssHello = true;").Parse(), CCompileException);
EXPECT_THROW(CParser("const u8string ssHello = 1;").Parse(), CCompileException);
EXPECT_THROW(CParser("const u8string ssHello = 1.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const u8string ssHello = 'A';").Parse(), CCompileException);
EXPECT_THROW(CParser("const u8string ssHello = nullptr;").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentUtf16String)
{
EXPECT_TRUE(CParser("const u16string ssHello = u\"hello\";").Parse().Root()->Find("ssHello"));
EXPECT_TRUE(CParser("const u16string ssHello = u\"hello\" u\"hello2\";").Parse().Root()->Find("ssHello"));
EXPECT_TRUE(CParser("const u16string rgssHello[2] = {u\"hello\", u\"hello2\" u\"hello3\"};").Parse().Root()->Find("rgssHello"));
EXPECT_THROW(CParser("const u16string ssHello = \"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u16string ssHello = u8\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u16string ssHello = U\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u16string ssHello = L\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u16string ssHello = u\"hello\" \"hello2\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u16string ssHello = true;").Parse(), CCompileException);
EXPECT_THROW(CParser("const u16string ssHello = 1;").Parse(), CCompileException);
EXPECT_THROW(CParser("const u16string ssHello = 1.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const u16string ssHello = 'A';").Parse(), CCompileException);
EXPECT_THROW(CParser("const u16string ssHello = nullptr;").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentUtf32String)
{
EXPECT_TRUE(CParser("const u32string ssHello = U\"hello\";").Parse().Root()->Find("ssHello"));
EXPECT_TRUE(CParser("const u32string ssHello = U\"hello\" U\"hello2\";").Parse().Root()->Find("ssHello"));
EXPECT_TRUE(CParser("const u32string rgssHello[2] = {U\"hello\", U\"hello2\" U\"hello3\"};").Parse().Root()->Find("rgssHello"));
EXPECT_THROW(CParser("const u32string ssHello = \"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u32string ssHello = u8\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u32string ssHello = u\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u32string ssHello = L\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u32string ssHello = U\"hello\" \"hello2\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const u32string ssHello = true;").Parse(), CCompileException);
EXPECT_THROW(CParser("const u32string ssHello = 1;").Parse(), CCompileException);
EXPECT_THROW(CParser("const u32string ssHello = 1.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const u32string ssHello = 'A';").Parse(), CCompileException);
EXPECT_THROW(CParser("const u32string ssHello = nullptr;").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentWideString)
{
EXPECT_TRUE(CParser("const wstring ssHello = L\"hello\";").Parse().Root()->Find("ssHello"));
EXPECT_TRUE(CParser("const wstring ssHello = L\"hello\" L\"hello2\";").Parse().Root()->Find("ssHello"));
EXPECT_TRUE(CParser("const wstring rgssHello[2] = {L\"hello\", L\"hello2\" L\"hello3\"};").Parse().Root()->Find("rgssHello"));
EXPECT_THROW(CParser("const wstring ssHello = \"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const wstring ssHello = u8\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const wstring ssHello = u\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const wstring ssHello = U\"hello\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const wstring ssHello = L\"hello\" \"hello2\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const wstring ssHello = true;").Parse(), CCompileException);
EXPECT_THROW(CParser("const wstring ssHello = 1;").Parse(), CCompileException);
EXPECT_THROW(CParser("const wstring ssHello = 1.0;").Parse(), CCompileException);
EXPECT_THROW(CParser("const wstring ssHello = 'A';").Parse(), CCompileException);
EXPECT_THROW(CParser("const wstring ssHello = nullptr;").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentNumericIdentifiers)
{
EXPECT_TRUE(CParser("const int32 iHello1 = 100;\nconst int32 iHello2 = iHello1;").Parse().Root()->Find("iHello2"));
EXPECT_TRUE(CParser("const int32 iHello1 = 100;\nconst int32 iHello2 = iHello1; const int64 rgiHello3[] = {iHello1, iHello2};").Parse().Root()->Find("rgiHello3"));
EXPECT_TRUE(CParser("module TEST {const int32 iHello1 = 100;};\nconst int32 iHello2 = TEST::iHello1;").Parse().Root()->Find("iHello2"));
EXPECT_TRUE(CParser("module TEST {const int32 iHello1 = 100;};\nconst int32 iHello2 = ::TEST::iHello1;").Parse().Root()->Find("iHello2"));
EXPECT_TRUE(CParser("module TEST {const int32 iHello1 = 100;};\nmodule TEST2{const int32 iHello2 = TEST::iHello1;};").Parse().Root()->Find("TEST2::iHello2"));
EXPECT_TRUE(CParser("module TEST {const int32 iHello1 = 100;};\nmodule TEST2{const int32 iHello2 = ::TEST::iHello1;};").Parse().Root()->Find("TEST2::iHello2"));
EXPECT_TRUE(CParser("module TEST {const int32 iHello1 = 100; const int32 iHello2 = TEST::iHello1;};").Parse().Root()->Find("TEST::iHello2"));
EXPECT_TRUE(CParser("module TEST {const int32 iHello1 = 100; const int32 iHello2 = iHello1;};").Parse().Root()->Find("TEST::iHello2"));
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentStringIdentifiers)
{
EXPECT_TRUE(CParser("const wstring ssHello1 = L\"hello\";\nconst wstring ssHello2 = ssHello1;").Parse().Root()->Find("ssHello2"));
EXPECT_TRUE(CParser("const wstring ssHello1 = L\"hello\";\nconst wstring ssHello2 = ssHello1; const wstring ssHello3[] = {ssHello1, ssHello2};").Parse().Root()->Find("ssHello2"));
EXPECT_TRUE(CParser("module TEST {const wstring ssHello1 = L\"hello\";};\nconst wstring ssHello2 = TEST::ssHello1;").Parse().Root()->Find("ssHello2"));
EXPECT_TRUE(CParser("module TEST {const wstring ssHello1 = L\"hello\";};\nconst wstring ssHello2 = ::TEST::ssHello1;").Parse().Root()->Find("ssHello2"));
EXPECT_TRUE(CParser("module TEST {const wstring ssHello1 = L\"hello\";};\nmodule TEST2{const wstring ssHello2 = TEST::ssHello1;};").Parse().Root()->Find("TEST2::ssHello2"));
EXPECT_TRUE(CParser("module TEST {const wstring ssHello1 = L\"hello\";};\nmodule TEST2{const wstring ssHello2 = ::TEST::ssHello1;};").Parse().Root()->Find("TEST2::ssHello2"));
EXPECT_TRUE(CParser("module TEST {const wstring ssHello1 = L\"hello\"; const wstring ssHello2 = TEST::ssHello1;};").Parse().Root()->Find("TEST::ssHello2"));
EXPECT_TRUE(CParser("module TEST {const wstring ssHello1 = L\"hello\"; const wstring ssHello2 = ssHello1;};").Parse().Root()->Find("TEST::ssHello2"));
EXPECT_THROW(CParser("const wstring ssHello1 = L\"hello\";\nconst wstring ssHello2 = ssHello1 \"this doesn't work\";").Parse(), CCompileException);
EXPECT_THROW(CParser("const wstring ssHello1 = L\"hello\";\nconst wstring ssHello2 = \"this doesn't work\" ssHello1;").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ComplexConstAssignment)
{
EXPECT_TRUE(CParser("struct S {int32 i;}; const S s1 = {10};").Parse().Root()->Find("s1"));
EXPECT_TRUE(CParser("struct S {int32 i;}; const struct S s1 = {10};").Parse().Root()->Find("s1"));
EXPECT_THROW(CParser("interface I {}; const I i1;").Parse(), CCompileException);
EXPECT_THROW(CParser("exception Ex {}; const Ex ex1;").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentOperatorsIntegral)
{
// Parenthesis while calculating
CParser parserParenthesis(R"code(
const int32 a = 10;
const int32 b = 5;
const int32 c = b*b;
const int64 e = 10;
const int16 f = a * (c + e);
)code");
EXPECT_NO_THROW(parserParenthesis.Parse());
const CVariableEntity* pParenthesisEntityResult = parserParenthesis.Root()->Find<CVariableEntity>("f");
ASSERT_NE(pParenthesisEntityResult, nullptr);
EXPECT_EQ(pParenthesisEntityResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 350);
// Operators + - / * %
CParser parserArithmetic(R"code(
const int64 f = 10 + 11 * 35 % 10 -2;
)code");
EXPECT_NO_THROW(parserArithmetic.Parse());
const CVariableEntity* pArithmeticResult = parserArithmetic.Root()->Find<CVariableEntity>("f");
ASSERT_NE(pArithmeticResult, nullptr);
EXPECT_EQ(pArithmeticResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 13);
// Operators << >> & | ~
CParser parserBitManipulation(R"code(
const uint8 f = 2 << 2 | 7 >> 1 & (~ 120 & 7);
)code");
EXPECT_NO_THROW(parserBitManipulation.Parse());
const CVariableEntity* pBitManipulationResult = parserBitManipulation.Root()->Find<CVariableEntity>("f");
ASSERT_NE(pBitManipulationResult, nullptr);
EXPECT_EQ(pBitManipulationResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int64_t>(), 11);
// Operators && || < > <= >= == !=
CParser parserCondition(R"code(
const boolean a = (20 || 10 && 1) < 2;
const boolean b = 50 + 7 >= 57;
const boolean c = 50 + 8 > 57;
const boolean d = 50 + 7 <= 57;
const boolean e = 10 != 0;
const int32 f = a + b + c + d + e;
)code");
EXPECT_NO_THROW(parserCondition.Parse());
const CVariableEntity* pConditionResult = parserCondition.Root()->Find<CVariableEntity>("f");
ASSERT_NE(pConditionResult, nullptr);
EXPECT_EQ(pConditionResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<uint8_t>(), 5);
// Div by zero /
EXPECT_THROW(CParser("const long i = 0; const unsigned long j = 10/i;").Parse(), CCompileException);
// Div by zero %
EXPECT_THROW(CParser("const long i = 0; const unsigned long j = 10%i;").Parse(), CCompileException);
}
TEST_F(CParserConstAssignmentTest, ConstAssignmentOperatorsFloatingPoint)
{
// Parenthesis while calculating
CParser parserParenthesis(R"code(
const double a = 10;
const double b = 5;
const double c = b*b;
const double e = 10;
const double f = a * (c + e);
)code");
EXPECT_NO_THROW(parserParenthesis.Parse());
const CVariableEntity* pParenthesisEntityResult = parserParenthesis.Root()->Find<CVariableEntity>("f");
ASSERT_NE(pParenthesisEntityResult, nullptr);
EXPECT_EQ(pParenthesisEntityResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<float>(), 350);
// Operators + - / * %
CParser parserArithmetic(R"code(
const float f = 10 + 11 * 35 % 10 -2;
)code");
EXPECT_NO_THROW(parserArithmetic.Parse());
const CVariableEntity* pArithmeticResult = parserArithmetic.Root()->Find<CVariableEntity>("f");
ASSERT_NE(pArithmeticResult, nullptr);
EXPECT_EQ(pArithmeticResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<long double>(), 13);
// Operators && || < > <= >= == !=
CParser parserCondition(R"code(
const boolean a = (20.0 || 10.0 && 1.0) < 2.0;
const boolean b = 50.0 + 7.0 >= 57.0;
const boolean c = 50.0 + 8.0 > 57.0;
const boolean d = 50.0 + 7.0 <= 57.0;
const boolean e = 10.0 != 0.0;
const int32 f = a + b + c + d + e;
)code");
EXPECT_NO_THROW(parserCondition.Parse());
const CVariableEntity* pConditionResult = parserCondition.Root()->Find<CVariableEntity>("f");
ASSERT_NE(pConditionResult, nullptr);
EXPECT_EQ(pConditionResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<uint8_t>(), 5);
// Div by zero /
EXPECT_THROW(CParser("const float i = 0; const long double j = 10/i;").Parse(), CCompileException);
// Div by zero %
EXPECT_THROW(CParser("const double i = 0; const float j = 10%i;").Parse(), CCompileException);
}

View File

@@ -0,0 +1,261 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/enum_entity.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/entities/entity_value.h"
using CParserEnumTest = CParserTest;
TEST_F(CParserEnumTest, ForwardDeclaration)
{
// enum <enum_identifier>; --> forward declaration
EXPECT_TRUE(CParser("enum E1; enum E1 {};").Parse().Root()->Find("E1"));
EXPECT_TRUE(CParser("enum E1 {}; enum E1;").Parse().Root()->Find("E1"));
EXPECT_TRUE(CParser("enum E1; enum E1; enum E1; enum E1;").Parse().Root()->Find("E1"));
EXPECT_TRUE(CParser("enum E1 {}; enum E1; enum E1; ").Parse().Root()->Find("E1"));
EXPECT_THROW(CParser("enum E1 {}; enum E1; enum E1 {}; ").Parse(), CCompileException);
}
TEST_F(CParserEnumTest, Definition)
{
// enum <enum_identifier> {...}; --> enum definition
EXPECT_TRUE(CParser("enum E2 {};").Parse().Root()->Find("E2"));
EXPECT_THROW(CParser("enum E2 {} e2;").Parse(), CCompileException);
}
TEST_F(CParserEnumTest, AnonymousDefinition)
{
// enum <enum_identifier> {...}; --> enum definition
EXPECT_TRUE(CParser("struct S { enum {} e2; };").Parse().Root()->Find("S::e2"));
// Anonymous definitions at root level are not allowed.
EXPECT_THROW(CParser("typedef enum {} TE2;").Parse(), CCompileException);
}
TEST_F(CParserEnumTest, SpecificEntryValueAssignment)
{
EXPECT_TRUE(CParser("enum E2 { test = 10 };").Parse().Root()->Find("E2"));
EXPECT_TRUE(CParser("enum E2 { test = 10 };").Parse().Root()->Find("E2::test"));
EXPECT_TRUE(CParser("enum E2 { test = 10, };").Parse().Root()->Find("E2"));
EXPECT_TRUE(CParser("enum E2 { test = 10, };").Parse().Root()->Find("E2::test"));
EXPECT_THROW(CParser("enum E2 { test1 = 10, test1 = 20};").Parse(), CCompileException);
EXPECT_THROW(CParser("enum E2 { test1 = 10, test1 = 10};").Parse(), CCompileException);
EXPECT_EQ(CParser("enum E2 { test1 = 10, test2 = 20 };").Parse().Root()->Find("E2::test1")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 10);
EXPECT_EQ(CParser("enum E2 { test1 = 10, test2 = 20 };").Parse().Root()->Find("E2::test2")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 20);
EXPECT_EQ(CParser("enum E2 { test1 = 0xa, test2 = 0xf};").Parse().Root()->Find("E2::test1")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 10);
EXPECT_EQ(CParser("enum E2 { test1 = 0xa, test2 = 0xf};").Parse().Root()->Find("E2::test2")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 15);
EXPECT_EQ(CParser("enum E2 { test1 = 20, test2 = 10 };").Parse().Root()->Find("E2::test1")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 20);
EXPECT_EQ(CParser("enum E2 { test1 = 20, test2 = 10 };").Parse().Root()->Find("E2::test2")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 10);
EXPECT_THROW(CParser("enum E2 { test1 = 10, test2 = 10 };").Parse(), CCompileException);
EXPECT_EQ(CParser("enum E2 { test1 = 10, test2 = 2, test3 = 5, test4 = 1, };").Parse().Root()->Find("E2::test1")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 10);
EXPECT_EQ(CParser("enum E2 { test1 = 10, test2 = 2, test3 = 5, test4 = 1, };").Parse().Root()->Find("E2::test2")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_EQ(CParser("enum E2 { test1 = 10, test2 = 2, test3 = 5, test4 = 1, };").Parse().Root()->Find("E2::test3")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 5);
EXPECT_EQ(CParser("enum E2 { test1 = 10, test2 = 2, test3 = 5, test4 = 1, };").Parse().Root()->Find("E2::test4")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 1);
}
TEST_F(CParserEnumTest, AutomaticEntryValueAssignment)
{
EXPECT_TRUE(CParser("enum E2 { test };").Parse().Root()->Find("E2"));
EXPECT_TRUE(CParser("enum E2 { test };").Parse().Root()->Find("E2::test"));
EXPECT_TRUE(CParser("enum E2 { test, };").Parse().Root()->Find("E2"));
EXPECT_TRUE(CParser("enum E2 { test, };").Parse().Root()->Find("E2::test"));
EXPECT_THROW(CParser("enum E2 { test1, test1};").Parse(), CCompileException);
EXPECT_EQ(CParser("enum E2 { test1, test2 };").Parse().Root()->Find("E2::test1")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 0);
EXPECT_EQ(CParser("enum E2 { test1, test2 };").Parse().Root()->Find("E2::test2")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 1);
EXPECT_EQ(CParser("enum E2 { test1 = 0xa, test2};").Parse().Root()->Find("E2::test1")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 10);
EXPECT_EQ(CParser("enum E2 { test1 = 0xa, test2};").Parse().Root()->Find("E2::test2")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 11);
EXPECT_EQ(CParser("enum E2 { test1, test2 = 10 };").Parse().Root()->Find("E2::test1")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 0);
EXPECT_EQ(CParser("enum E2 { test1, test2 = 10 };").Parse().Root()->Find("E2::test2")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 10);
EXPECT_THROW(CParser("enum E2 { test1 = 9, test2, test3 = 10 };").Parse(), CCompileException);
EXPECT_EQ(CParser("enum E2 { test1 = 10, test2 = 8, test3, test4, };").Parse().Root()->Find("E2::test1")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 10);
EXPECT_EQ(CParser("enum E2 { test1 = 10, test2 = 8, test3, test4, };").Parse().Root()->Find("E2::test2")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 8);
EXPECT_EQ(CParser("enum E2 { test1 = 10, test2 = 8, test3, test4, };").Parse().Root()->Find("E2::test3")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 9);
EXPECT_EQ(CParser("enum E2 { test1 = 10, test2 = 8, test3, test4, };").Parse().Root()->Find("E2::test4")->Get<CEnumEntry>()->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 11);
}
TEST_F(CParserEnumTest, ValueAssignment)
{
EXPECT_EQ(CParser("struct S {enum E { test = 1 } eVar = E::test;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 1);
EXPECT_EQ(CParser("struct S {enum E { test = 1, test2 } rgVar[2] = {E::test, E::test2};};").Parse().Root()->FindValue("S.rgVar[1]")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_THROW(CParser("struct S {enum E { test = 1 } eVar = 1;};").Parse(), CCompileException);
EXPECT_EQ(CParser("struct S {enum E { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_EQ(CParser("enum E { test1 = 1, test2 = 2 }; struct S {E eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_EQ(CParser("enum E { test1 = 1, test2 = 2 }; struct S {enum E eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_EQ(CParser("typedef enum tagE { test1 = 1, test2 = 2 } E; struct S {E eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_EQ(CParser("typedef enum tagE { test1 = 1, test2 = 2 } E; struct S {E eVar = E::test2, eVar2 = eVar;};").Parse().Root()->FindValue("S.eVar2")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
}
TEST_F(CParserEnumTest, ValueAssignmentInt8)
{
EXPECT_EQ(CParser("struct S {enum E : int8 { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_EQ(CParser("struct S {enum E : int8 { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), -2);
EXPECT_THROW(CParser("struct S {enum E : int8 { test1 = -130, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : int8 { test1 = 1, test2 = 130 } eVar = E::test2;};").Parse(), CCompileException);
}
TEST_F(CParserEnumTest, ValueAssignmentInt16)
{
EXPECT_EQ(CParser("struct S {enum E : int16 { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_EQ(CParser("struct S {enum E : int16 { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), -2);
EXPECT_THROW(CParser("struct S {enum E : int16 { test1 = -32769, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : int16 { test1 = 1, test2 = 32768 } eVar = E::test2;};").Parse(), CCompileException);
}
TEST_F(CParserEnumTest, ValueAssignmentInt32)
{
EXPECT_EQ(CParser("struct S {enum E : int32 { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_EQ(CParser("struct S {enum E : int32 { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), -2);
EXPECT_THROW(CParser("struct S {enum E : int32 { test1 = -2147483649, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : int32 { test1 = 1, test2 = 2147483648 } eVar = E::test2;};").Parse(), CCompileException);
}
TEST_F(CParserEnumTest, ValueAssignmentInt64)
{
EXPECT_EQ(CParser("struct S {enum E : int64 { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int64_t>(), 2);
EXPECT_EQ(CParser("struct S {enum E : int64 { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int64_t>(), -2);
EXPECT_EQ(CParser("struct S {enum E : int64 { test1 = -2147483649, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int64_t>(), -2);
EXPECT_EQ(CParser("struct S {enum E : int64 { test1 = 1, test2 = 2147483648 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int64_t>(), 2147483648);
}
TEST_F(CParserEnumTest, ValueAssignmentUInt8)
{
EXPECT_EQ(CParser("struct S {enum E : uint8 { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2u);
EXPECT_EQ(CParser("struct S {enum E : uint8 { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 0xfeu);
EXPECT_THROW(CParser("struct S {enum E : uint8 { test1 = -130, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_EQ(CParser("struct S {enum E : uint8 { test1 = 1, test2 = 130 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 130u);
}
TEST_F(CParserEnumTest, ValueAssignmentUInt16)
{
EXPECT_EQ(CParser("struct S {enum E : uint16 { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2u);
EXPECT_EQ(CParser("struct S {enum E : uint16 { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 0xfffeu);
EXPECT_THROW(CParser("struct S {enum E : uint16 { test1 = -32769, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_EQ(CParser("struct S {enum E : uint16 { test1 = 1, test2 = 32768 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 32768u);
}
TEST_F(CParserEnumTest, ValueAssignmentUInt32)
{
EXPECT_EQ(CParser("struct S {enum E : uint32 { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2u);
EXPECT_EQ(CParser("struct S {enum E : uint32 { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 0xfffffffeu);
EXPECT_THROW(CParser("struct S {enum E : uint32 { test1 = -2147483649, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_EQ(CParser("struct S {enum E : uint32 { test1 = 1, test2 = 2147483648 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2147483648u);
}
TEST_F(CParserEnumTest, ValueAssignmentUInt64)
{
EXPECT_EQ(CParser("struct S {enum E : uint64 { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint64_t>(), 2ull);
EXPECT_EQ(CParser("struct S {enum E : uint64 { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint64_t>(), 0xFFFFFFFFFFFFFFFEull);
EXPECT_EQ(CParser("struct S {enum E : uint64 { test1 = -2147483649, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint64_t>(), 0xFFFFFFFFFFFFFFFEull);
EXPECT_EQ(CParser("struct S {enum E : uint64 { test1 = 1, test2 = 2147483648 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint64_t>(), 2147483648ull);
}
TEST_F(CParserEnumTest, ValueAssignmentChar)
{
EXPECT_EQ(CParser("struct S {enum E : char { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_EQ(CParser("struct S {enum E : char { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), -2);
EXPECT_THROW(CParser("struct S {enum E : char { test1 = -130, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : char { test1 = 1, test2 = 130 } eVar = E::test2;};").Parse(), CCompileException);
}
TEST_F(CParserEnumTest, ValueAssignmentShort)
{
EXPECT_EQ(CParser("struct S {enum E : short { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_EQ(CParser("struct S {enum E : short { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), -2);
EXPECT_THROW(CParser("struct S {enum E : short { test1 = -32769, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : short { test1 = 1, test2 = 32768 } eVar = E::test2;};").Parse(), CCompileException);
}
TEST_F(CParserEnumTest, ValueAssignmentLong)
{
EXPECT_EQ(CParser("struct S {enum E : long { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_EQ(CParser("struct S {enum E : long { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), -2);
EXPECT_THROW(CParser("struct S {enum E : long { test1 = -2147483649, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : long { test1 = 1, test2 = 2147483648 } eVar = E::test2;};").Parse(), CCompileException);
}
TEST_F(CParserEnumTest, ValueAssignmentLongLong)
{
EXPECT_EQ(CParser("struct S {enum E : long long { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), 2);
EXPECT_EQ(CParser("struct S {enum E : long long { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), -2);
EXPECT_EQ(CParser("struct S {enum E : long long { test1 = -2147483649, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int32_t>(), -2);
EXPECT_EQ(CParser("struct S {enum E : long long { test1 = 1, test2 = 2147483648 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<int64_t>(), 2147483648);
}
TEST_F(CParserEnumTest, ValueAssignmentOctet)
{
EXPECT_EQ(CParser("struct S {enum E : octet { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2u);
EXPECT_EQ(CParser("struct S {enum E : octet { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 0xfeu);
EXPECT_THROW(CParser("struct S {enum E : octet { test1 = -130, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_EQ(CParser("struct S {enum E : octet { test1 = 1, test2 = 130 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 130u);
}
TEST_F(CParserEnumTest, ValueAssignmentUnsignedShort)
{
EXPECT_EQ(CParser("struct S {enum E : unsigned short { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2u);
EXPECT_EQ(CParser("struct S {enum E : unsigned short { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 0xfffeu);
EXPECT_THROW(CParser("struct S {enum E : unsigned short { test1 = -32769, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_EQ(CParser("struct S {enum E : unsigned short { test1 = 1, test2 = 32768 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 32768u);
}
TEST_F(CParserEnumTest, ValueAssignmentUnsignedLong)
{
EXPECT_EQ(CParser("struct S {enum E : unsigned long { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2u);
EXPECT_EQ(CParser("struct S {enum E : unsigned long { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 0xfffffffeu);
EXPECT_THROW(CParser("struct S {enum E : unsigned long { test1 = -2147483649, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_EQ(CParser("struct S {enum E : unsigned long { test1 = 1, test2 = 2147483648 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2147483648u);
}
TEST_F(CParserEnumTest, ValueAssignmentUnsignedLongLong)
{
EXPECT_EQ(CParser("struct S {enum E : unsigned long long { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint64_t>(), 2ull);
EXPECT_EQ(CParser("struct S {enum E : unsigned long long { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint64_t>(), 0xFFFFFFFFFFFFFFFEull);
EXPECT_EQ(CParser("struct S {enum E : unsigned long long { test1 = -2147483649, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint64_t>(), 0xFFFFFFFFFFFFFFFEull);
EXPECT_EQ(CParser("struct S {enum E : unsigned long long { test1 = 1, test2 = 2147483648 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint64_t>(), 2147483648ull);
}
TEST_F(CParserEnumTest, ValueAssignmentChar16)
{
EXPECT_EQ(CParser("struct S {enum E : char16 { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2u);
EXPECT_EQ(CParser("struct S {enum E : char16 { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 0xfffeu);
EXPECT_THROW(CParser("struct S {enum E : char16 { test1 = -32769, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_EQ(CParser("struct S {enum E : char16 { test1 = 1, test2 = 32768 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 32768u);
}
TEST_F(CParserEnumTest, ValueAssignmentChar32)
{
EXPECT_EQ(CParser("struct S {enum E : char32 { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2u);
EXPECT_EQ(CParser("struct S {enum E : char32 { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 0xfffffffeu);
EXPECT_THROW(CParser("struct S {enum E : char32 { test1 = -2147483649, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_EQ(CParser("struct S {enum E : char32 { test1 = 1, test2 = 2147483648 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2147483648u);
}
TEST_F(CParserEnumTest, ValueAssignmentWChar)
{
if constexpr (sizeof(wchar_t) == 2)
{
EXPECT_EQ(CParser("struct S {enum E : wchar { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2u);
EXPECT_EQ(CParser("struct S {enum E : wchar { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 0xfffeu);
EXPECT_THROW(CParser("struct S {enum E : wchar { test1 = -32769, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_EQ(CParser("struct S {enum E : wchar { test1 = 1, test2 = 32768 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 32768u);
}
else
{
EXPECT_EQ(CParser("struct S {enum E : wchar { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2u);
EXPECT_EQ(CParser("struct S {enum E : wchar { test1 = -1, test2 = -2 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 0xfffffffeu);
EXPECT_THROW(CParser("struct S {enum E : wchar { test1 = -2147483649, test2 = -2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_EQ(CParser("struct S {enum E : wchar { test1 = 1, test2 = 2147483648 } eVar = E::test2;};").Parse().Root()->FindValue("S.eVar")->Get<CEnumValueNode>()->Variant().Get<uint32_t>(), 2147483648u);
}
}
TEST_F(CParserEnumTest, ValueAssignmentInvalidType)
{
EXPECT_THROW(CParser("struct S {enum E : float { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : double { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : long double { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : fixed { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : string { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : u8string { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : u16string { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : u32string { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {enum E : wstring { test1 = 1, test2 = 2 } eVar = E::test2;};").Parse(), CCompileException);
}

View File

@@ -0,0 +1,151 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/exception_entity.cpp"
using CParserExceptionTest = CParserTest;
TEST_F(CParserExceptionTest, ForwardDeclaration)
{
// exception <exception_identifier>; --> forward declaration
EXPECT_TRUE(CParser("exception X1; exception X1 {};").Parse().Root()->Find("X1"));
EXPECT_TRUE(CParser("exception X1 {}; exception X1;").Parse().Root()->Find("X1"));
EXPECT_TRUE(CParser("exception X1; exception X1; exception X1; exception X1;").Parse().Root()->Find("X1"));
EXPECT_TRUE(CParser("exception X1 {}; exception X1; exception X1; ").Parse().Root()->Find("X1"));
EXPECT_THROW(CParser("exception X1 {}; exception X1; exception X1 {}; ").Parse(), CCompileException);
EXPECT_THROW(CParser("exception X1; struct X1 {};").Parse(), CCompileException);
}
TEST_F(CParserExceptionTest, Definition)
{
// exception <interface_identifier> {...}; --> exception definition
EXPECT_TRUE(CParser("exception X2 {};").Parse().Root()->Find("X2"));
EXPECT_TRUE(CParser("exception X2 { int32 i; };").Parse().Root()->Find("X2"));
EXPECT_TRUE(CParser("exception X2 { int32 i; };").Parse().Root()->Find("X2::i"));
}
TEST_F(CParserExceptionTest, DefinitionWithInheritance)
{
// exception <exception_identifier> : <base_exception,...> {...}; --> exception definition with inheritance
EXPECT_TRUE(CParser("exception X3base {int32 i = 1;}; exception X3 : X3base {int32 j = 1;};").Parse().Root()->Find("X3::i"));
EXPECT_THROW(CParser("exception X3base {int32 i = 1;}; struct S3 : X3base {int32 j = 1;};").Parse(), CCompileException);
}
TEST_F(CParserExceptionTest, VariableDeclaration)
{
// <struct_identifier> <decl_identifier>; --> exception variable declaration
EXPECT_TRUE(CParser("exception X{struct S4 {int32 i;}; S4 s4Value;};").Parse().Root()->Find("X::s4Value"));
// exception <struct_identifier> <decl_identifier>; --> exception variable declaration
EXPECT_TRUE(CParser("exception X{struct S6 {int32 i;}; struct S6 s6Value;};").Parse().Root()->Find("X::s6Value"));
}
TEST_F(CParserExceptionTest, VarDeclarationAndAssignment)
{
// <struct_identifier> <decl_identifier> = {...}; --> exception variable declaration and assignment
EXPECT_TRUE(CParser("exception X{struct S5 {int32 i;}; S5 s5Value = {10};};").Parse().Root()->Find("X::s5Value"));
EXPECT_TRUE(CParser("exception X{struct S5b {int32 i = 11;}; S5b s5bValue = {10};};").Parse().Root()->Find("X::s5bValue"));
// exception <struct_identifier> <decl_identifier> = {...}; --> exception variable declaration and assignment
EXPECT_TRUE(CParser("exception X{struct S7 {int32 i;}; struct S7 s7Value = {10};};").Parse().Root()->Find("X::s7Value"));
}
TEST_F(CParserExceptionTest, DefinitionAndVariableDeclaration)
{
// exception <struct_identifier> {...} <decl_identifier>; --> exception definition and variable declaration
EXPECT_TRUE(CParser("exception X{struct S8 {int32 i;} s8Value;};").Parse().Root()->Find("X::s8Value"));
}
TEST_F(CParserExceptionTest, DefinitionWithInheritanceAndVariableDeclaration)
{
// exception <struct_identifier> : <base_struct,...> {...} <decl_identifier>; --> exception definition with inheritance and variable declaration
EXPECT_TRUE(CParser("exception X{struct S9base {int32 i;}; struct S9 : S9base {int32 j;} s9Value;};").Parse().Root()->Find("X::s9Value"));
}
TEST_F(CParserExceptionTest, DefinitionAndVariableDeclarationAndAssignment)
{
// exception <struct_identifier> {...} <decl_identifier> = {...}; --> exception definition, variable declaration and assignment
EXPECT_TRUE(CParser("exception X{struct S10 {int32 i;} s10Value = {10};};").Parse().Root()->Find("X::s10Value"));
}
TEST_F(CParserExceptionTest, DefinitionWithInheritanceAndVariableDeclarationAndAssignment)
{
// exception <struct_identifier> : <base_struct,...> {...} <decl_identifier> = {...}; --> exception definition with inheritance, variable declaration and assignment
EXPECT_TRUE(CParser("exception X{struct S11base {int32 i;}; struct S11 : S11base {int32 j;} s11Value = {{10}, 10};};").Parse().Root()->Find("X::s11Value"));
EXPECT_TRUE(CParser("exception X{struct S11base {int32 i;}; struct S11 : S11base {} s11Value = {{10}};};").Parse().Root()->Find("X::s11Value"));
}
TEST_F(CParserExceptionTest, UnnamedDefinitionAndVariableDeclaration)
{
// exception {...} <decl_identifier>; --> unnamed exception definition and variable declaration
// NOTE 11.04.2025: Not allowed due to incompatibility in C++ standard
EXPECT_THROW(CParser("exception X{struct {int32 i;} s12Value;};").Parse(), CCompileException);
}
TEST_F(CParserExceptionTest, UnnamedDefinitionWithInheritanceAndVariableDeclaration)
{
// exception : <base_struct,...> {...} <decl_identifier>; --> unnamed exception definition with inheritance and variable declaration
// NOTE 11.04.2025: Not allowed due to incompatibility in C++ standard
EXPECT_THROW(CParser("exception X{struct S13base {int32 i;}; struct : S13base {int32 j;} s13Value;};").Parse(), CCompileException);
}
TEST_F(CParserExceptionTest, UnnamedDefinitionAndVariableDeclarationAndAssignment)
{
// exception {...} <decl_identifier> = {...}; --> unnamed exception definition, variable declaration and assignment
// NOTE 11.04.2025: Not allowed due to incompatibility in C++ standard
EXPECT_THROW(CParser("exception X{struct {int32 i;} s14Value = {10};};").Parse(), CCompileException);
}
TEST_F(CParserExceptionTest, UnnamedDefinitionWithInheritanceAndVariableDeclarationAndAssignment)
{
// exception : <base_struct,...> {...} <decl_identifier> = {...}; --> unnamed exception definition with inheritance, variable declaration and assignment
// NOTE 11.04.2025: Not allowed due to incompatibility in C++ standard
EXPECT_THROW(CParser("exception X{struct S15base {int32 i;}; struct : S15base {int32 j;} s15Value = {{10}, 10};};").Parse(), CCompileException);
}
TEST_F(CParserExceptionTest, ComplexCombinationWithStructTypedefMultiDimmensionalArrayDeclarations)
{
const char szCode[] = R"code(
exception X
{
const int32 a = 2;
typedef int32 intarray[a];
typedef intarray initintarray[3][1];
initintarray rgarray[4] = {{{{1,2}}, {{3,4}}, {{5,6}}},
{{{7,8}},{{9,10}}, {{a,b}}},
{{{13,14}}, {{15,16}}, {{17,18}}},
{{{19,20}},{{21,22}}, {{23,24}}} };
const int32 b = 4;
};
)code";
CParser parser(szCode);
EXPECT_NO_THROW(parser.Parse());
CEntityPtr ptrVar = parser.Root()->Find("X::rgarray");
ASSERT_TRUE(ptrVar);
CDeclarationEntity* pVar = ptrVar->Get<CDeclarationEntity>();
ASSERT_NE(pVar, nullptr);
CValueNodePtr ptrVal = ptrVar->ValueRef();
ASSERT_TRUE(ptrVal);
CArrayValueNode* pInitIntArrayVal = ptrVal->Get<CArrayValueNode>();
ASSERT_NE(pInitIntArrayVal, nullptr);
EXPECT_EQ(pInitIntArrayVal->GetSize(), 4);
CValueNodePtr ptrIntArrayVal = (*pInitIntArrayVal)[3];
ASSERT_TRUE(ptrIntArrayVal);
CArrayValueNode* pIntArrayVal = ptrIntArrayVal->Get<CArrayValueNode>();
ASSERT_NE(pIntArrayVal, nullptr);
EXPECT_EQ(pIntArrayVal->GetSize(), 3);
CValueNodePtr ptrIntArrayVal_2 = (*pIntArrayVal)[2];
ASSERT_TRUE(ptrIntArrayVal_2);
CArrayValueNode* pIntArrayVal_2 = ptrIntArrayVal_2->Get<CArrayValueNode>();
ASSERT_NE(pIntArrayVal_2, nullptr);
EXPECT_EQ(pIntArrayVal_2->GetSize(), 1);
CValueNodePtr ptrIntArrayVal_3 = (*pIntArrayVal_2)[0];
ASSERT_TRUE(ptrIntArrayVal_3);
CArrayValueNode* pIntArrayVal_3 = ptrIntArrayVal_3->Get<CArrayValueNode>();
ASSERT_NE(pIntArrayVal_3, nullptr);
EXPECT_EQ(pIntArrayVal_3->GetSize(), 2);
CValueNodePtr ptrIntVal = (*pIntArrayVal_3)[1];
ASSERT_TRUE(ptrIntVal);
CSimpleTypeValueNode* pIntVal = ptrIntVal->Get<CSimpleTypeValueNode>();
ASSERT_NE(pIntVal, nullptr);
EXPECT_EQ(pIntVal->Variant().Get<int32_t>(), 24);
}

View File

@@ -0,0 +1,187 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/definition_entity.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/struct_entity.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/variable_entity.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/declaration_entity.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/entity_value.h"
using CParserExtensionTest = CParserTest;
TEST_F(CParserExtensionTest, InterfaceType)
{
// Check the use of the interface_t and the interface_id types.
EXPECT_TRUE(CParser("interface I{void func(in interface_t ifc);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("struct S{interface_t ifc;};").Parse().Root()->Find("S::ifc"));
EXPECT_TRUE(CParser("interface I{void func(in interface_id id);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("struct S{interface_id id;};").Parse().Root()->Find("S::id"));
EXPECT_TRUE(CParser("interface I{}; struct S{I ifc = null;};").Parse().Root()->Find("S::ifc"));
EXPECT_THROW(CParser("struct interface_t{};").Parse(), CCompileException); // not available as def name
EXPECT_THROW(CParser("struct interface_id{};").Parse(), CCompileException); // not available as def name
EXPECT_THROW(CParser("struct null{};").Parse(), CCompileException); // not available as def name
// Disable the interface type extension
CIdlCompilerEnvironment env;
std::vector<std::string> vec = { "idl_compiler_test", "--interface_type-" };
env = CIdlCompilerEnvironment(vec);
EXPECT_FALSE(env.InterfaceTypeExtension());
EXPECT_THROW(CParser("interface I{void func(in interface_t ifc);};", env).Parse(), CCompileException);
EXPECT_THROW(CParser("struct S{interface_t ifc;};", env).Parse(), CCompileException);
EXPECT_THROW(CParser("interface I{void func(in interface_id id);};", env).Parse(), CCompileException);
EXPECT_THROW(CParser("struct S{interface_id id;};", env).Parse(), CCompileException);
EXPECT_THROW(CParser("interface I{}; struct S{I ifc = null;};", env).Parse(), CCompileException);
EXPECT_TRUE(CParser("struct interface_t{};", env).Parse().Root()->Find("interface_t")); // available as def name
EXPECT_TRUE(CParser("struct interface_id{};", env).Parse().Root()->Find("interface_id")); // available as def name
EXPECT_TRUE(CParser("struct null{};", env).Parse().Root()->Find("null")); // available as def name
}
TEST_F(CParserExtensionTest, ExceptionId)
{
// Check the use of the exception_id type.
EXPECT_TRUE(CParser("struct S{ exception_id id; };").Parse().Root()->Find("S::id"));
EXPECT_THROW(CParser("struct exception_id{};").Parse(), CCompileException); // not available as def name
// Disable the interface type extension
CIdlCompilerEnvironment env;
std::vector<std::string> vec = { "idl_compiler_test", "--exception_type-" };
env = CIdlCompilerEnvironment(vec);
EXPECT_FALSE(env.ExceptionTypeExtension());
EXPECT_THROW(CParser("struct S{ exception_id id; };", env).Parse(), CCompileException);
EXPECT_TRUE(CParser("struct exception_id{};", env).Parse().Root()->Find("exception_id")); // available as def name
}
TEST_F(CParserExtensionTest, PointerType)
{
// Check the use of the pointer type.
EXPECT_TRUE(CParser("struct S{ pointer<uint8> ptr; };").Parse().Root()->Find("S::ptr"));
EXPECT_THROW(CParser("struct pointer{};").Parse(), CCompileException); // not available as def name
// Disable the interface type extension
CIdlCompilerEnvironment env;
std::vector<std::string> vec = { "idl_compiler_test", "--pointer_type-" };
env = CIdlCompilerEnvironment(vec);
EXPECT_FALSE(env.PointerTypeExtension());
EXPECT_THROW(CParser("struct S{ pointer<uint8> ptr; };", env).Parse(), CCompileException);
EXPECT_TRUE(CParser("struct pointer{};", env).Parse().Root()->Find("pointer")); // available as def name
}
TEST_F(CParserExtensionTest, UnicodeCharType)
{
// Check the use of the pointer type.
EXPECT_TRUE(CParser("struct S{ char16 c16; };").Parse().Root()->Find("S::c16"));
EXPECT_TRUE(CParser("struct S{ char32 c32; };").Parse().Root()->Find("S::c32"));
EXPECT_THROW(CParser("struct char16{};").Parse(), CCompileException); // not available as def name
EXPECT_THROW(CParser("struct char32{};").Parse(), CCompileException); // not available as def name
// Disable the interface type extension
CIdlCompilerEnvironment env;
std::vector<std::string> vec = { "idl_compiler_test", "--unicode_char-" };
env = CIdlCompilerEnvironment(vec);
EXPECT_FALSE(env.UnicodeExtension());
EXPECT_THROW(CParser("struct S{ char16 c16; };", env).Parse(), CCompileException);
EXPECT_THROW(CParser("struct S{ char32 c32; };", env).Parse(), CCompileException);
EXPECT_TRUE(CParser("struct char16{};", env).Parse().Root()->Find("char16")); // available as def name
EXPECT_TRUE(CParser("struct char32{};", env).Parse().Root()->Find("char32")); // available as def name
}
TEST_F(CParserExtensionTest, UnicodeStringType)
{
// Check the use of the pointer type.
EXPECT_TRUE(CParser("struct S{ u8string ss8; };").Parse().Root()->Find("S::ss8"));
EXPECT_TRUE(CParser("struct S{ u16string ss16; };").Parse().Root()->Find("S::ss16"));
EXPECT_TRUE(CParser("struct S{ u32string ss32; };").Parse().Root()->Find("S::ss32"));
EXPECT_THROW(CParser("struct u8string{};").Parse(), CCompileException); // not available as def name
EXPECT_THROW(CParser("struct u16string{};").Parse(), CCompileException); // not available as def name
EXPECT_THROW(CParser("struct u32string{};").Parse(), CCompileException); // not available as def name
// Disable the interface type extension
CIdlCompilerEnvironment env;
std::vector<std::string> vec = { "idl_compiler_test", "--unicode_char-" };
env = CIdlCompilerEnvironment(vec);
EXPECT_FALSE(env.UnicodeExtension());
EXPECT_THROW(CParser("struct S{ u8string ss8; };", env).Parse(), CCompileException);
EXPECT_THROW(CParser("struct S{ u16string ss16; };", env).Parse(), CCompileException);
EXPECT_THROW(CParser("struct S{ u32string ss32; };", env).Parse(), CCompileException);
EXPECT_TRUE(CParser("struct u8string{};", env).Parse().Root()->Find("u8string")); // available as def name
EXPECT_TRUE(CParser("struct u16string{};", env).Parse().Root()->Find("u16string")); // available as def name
EXPECT_TRUE(CParser("struct u32string{};", env).Parse().Root()->Find("u32string")); // available as def name
}
TEST_F(CParserExtensionTest, CaseSensitivity)
{
// Disable case sensitivity
CIdlCompilerEnvironment env;
std::vector<std::string> vec = { "idl_compiler_test", "--case_sensitive-" };
env = CIdlCompilerEnvironment(vec);
EXPECT_FALSE(env.CaseSensitiveTypeExtension());
// Use identical keyword only differencing in case
EXPECT_TRUE(CParser("struct Struct{};").Parse().Root()->Find("Struct"));
EXPECT_THROW(CParser("struct Struct{};", env).Parse(), CCompileException);
// Use identical identifiers only differencing in case
EXPECT_THROW(CParser("struct S{ int32 i; int32 i;};").Parse(), CCompileException); // Case sensitive; two vars
EXPECT_THROW(CParser("struct S{ int32 i; int32 i;};", env).Parse(), CCompileException); // Case insensitive; two vars
EXPECT_NO_THROW(CParser("struct S { int32 i; int32 I; };").Parse()); // Case sensitive; two vars differ in case
EXPECT_THROW(CParser("struct S { int32 i; int32 I; };", env).Parse(), CCompileException); // Case insensitive; two vars differ in case
EXPECT_NO_THROW(CParser("struct S{}; struct S2{ S s; };").Parse()); // Case sensitive; def and decl differ in scope and case
EXPECT_NO_THROW(CParser("struct S{}; struct S2{ S s; };", env).Parse()); // Case insensitive; def and decl differ in scope and case
}
TEST_F(CParserExtensionTest, ContextDependentNames)
{
// Disable context dependent names
std::vector<std::string> vecNoContextDeptNamesCaseSensitive = { "idl_compiler_test", "--context_names-" };
std::vector<std::string> vecNoContextDeptNamesCaseInsensitive = { "idl_compiler_test", "--context_names-", "--case_sensitive-" };
CIdlCompilerEnvironment envNoContextDeptNamesCaseSensitive(vecNoContextDeptNamesCaseSensitive);
CIdlCompilerEnvironment envNoContextDeptNamesCaseInsensitive(vecNoContextDeptNamesCaseInsensitive);
EXPECT_FALSE(envNoContextDeptNamesCaseSensitive.ContextDependentNamesExtension());
EXPECT_FALSE(envNoContextDeptNamesCaseInsensitive.ContextDependentNamesExtension());
EXPECT_FALSE(envNoContextDeptNamesCaseInsensitive.CaseSensitiveTypeExtension());
// Use identical identifiers only differencing in case
EXPECT_NO_THROW(CParser("struct S2{ struct S{}; S s;};").Parse()); // Case sensitive; reuse allowed
EXPECT_NO_THROW(CParser("struct S2{ struct S{}; S s;};", envNoContextDeptNamesCaseSensitive).Parse()); // Case sensitive; reuse allowed
EXPECT_THROW(CParser("struct S2{ struct S{}; S s;};", envNoContextDeptNamesCaseInsensitive).Parse(), CCompileException); // Names differ in case only; no reuse allowed
EXPECT_NO_THROW(CParser("struct S2{ struct S{}; S S;};").Parse()); // Context differs; reuse allowed
EXPECT_THROW(CParser("struct S2{ struct S{}; S S;};", envNoContextDeptNamesCaseSensitive).Parse(), CCompileException); // Identical names; no reuse allowed
EXPECT_THROW(CParser("struct S2{ struct S{}; S S;};", envNoContextDeptNamesCaseInsensitive).Parse(), CCompileException); // Identical names; no reuse allowed
EXPECT_NO_THROW(CParser("struct S2{ int16 s; struct S{};};").Parse()); // Case sensitive; reuse allowed
EXPECT_NO_THROW(CParser("struct S2{ int16 s; struct S{};};", envNoContextDeptNamesCaseSensitive).Parse()); // Case sensitive; reuse allowed
EXPECT_THROW(CParser("struct S2{ int16 s; struct S{};};", envNoContextDeptNamesCaseInsensitive).Parse(), CCompileException); // Names differ in case only; no reuse allowed
EXPECT_THROW(CParser("struct S2{ struct S{}; typedef int16 S;};").Parse(), CCompileException); // Identical names with no context change; no reuse allowed
EXPECT_THROW(CParser("struct S2{ struct S{}; typedef int16 S;};", envNoContextDeptNamesCaseSensitive).Parse(), CCompileException); // Identical names; no reuse allowed
EXPECT_THROW(CParser("struct S2{ struct S{}; typedef int16 S;};", envNoContextDeptNamesCaseInsensitive).Parse(), CCompileException); // Identical names; no reuse allowed
EXPECT_NO_THROW(CParser("struct S{ int16 attribute;};").Parse()); // Context differs; reuse allowed
EXPECT_THROW(CParser("struct S{ int16 attribute;};", envNoContextDeptNamesCaseSensitive).Parse(), CCompileException); // Keyword is reserved; no reuse allowed
EXPECT_THROW(CParser("struct S{ int16 attribute;};", envNoContextDeptNamesCaseInsensitive).Parse(), CCompileException); // Keyword is reserved; no reuse allowed
EXPECT_NO_THROW(CParser("struct S{ int16 Attribute;};").Parse()); // Context differs; reuse allowed
EXPECT_NO_THROW(CParser("struct S{ int16 Attribute;};", envNoContextDeptNamesCaseSensitive).Parse()); // Case sensitive; reuse allowed
EXPECT_THROW(CParser("struct S{ int16 Attribute;};", envNoContextDeptNamesCaseInsensitive).Parse(), CCompileException); // Keyword name differs in case only; no reuse allowed
EXPECT_THROW(CParser("struct S{ struct attribute{};};").Parse(), CCompileException); // Keyword is reserved; reuse allowed
EXPECT_THROW(CParser("struct S{ struct attribute{};};", envNoContextDeptNamesCaseSensitive).Parse(), CCompileException); // Keyword is reserved; no reuse allowed
EXPECT_THROW(CParser("struct S{ struct attribute{};};", envNoContextDeptNamesCaseInsensitive).Parse(), CCompileException); // Keyword is reserved; no reuse allowed
EXPECT_NO_THROW(CParser("struct S{ struct Attribute{};};").Parse()); // Case sensitive; reuse allowed
EXPECT_NO_THROW(CParser("struct S{ struct Attribute{};};", envNoContextDeptNamesCaseSensitive).Parse()); // Case sensitive; reuse allowed
EXPECT_THROW(CParser("struct S{ struct Attribute{};};", envNoContextDeptNamesCaseInsensitive).Parse(), CCompileException); // Keyword name differs in case only; no reuse allowed
}
TEST_F(CParserExtensionTest, MultiDimArray)
{
// Disable multi dimensional arrays
CIdlCompilerEnvironment env;
std::vector<std::string> vec = { "idl_compiler_test", "--multi_dimensional_array-" };
env = CIdlCompilerEnvironment(vec);
EXPECT_FALSE(env.MultiDimArrayExtension());
// Declare arrays
EXPECT_NO_THROW(CParser("const int16 rguiArr[1] = { 10 };").Parse());
EXPECT_NO_THROW(CParser("const int16 rguiArr[1] = { 10 };", env).Parse());
EXPECT_NO_THROW(CParser("struct S { int16 rguiArr[1]; };").Parse());
EXPECT_NO_THROW(CParser("struct S { int16 rguiArr[1]; };", env).Parse());
EXPECT_NO_THROW(CParser("const int16 rguiArr[1][1] = { { 10 } };").Parse());
EXPECT_THROW(CParser("const int16 rguiArr[1][1] = { { 10 } };", env).Parse(), CCompileException);
EXPECT_NO_THROW(CParser("struct S { int16 rguiArr[1][1]; };").Parse());
EXPECT_THROW(CParser("struct S { int16 rguiArr[1][1]; };", env).Parse(), CCompileException);
}

View File

@@ -0,0 +1,306 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/interface_entity.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/entities/attribute_entity.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/entities/operation_entity.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/entities/parameter_entity.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/entities/exception_entity.h"
using CParserInterfaceTest = CParserTest;
TEST_F(CParserInterfaceTest, ForwardDeclaration)
{
// interface <interface_identifier>; --> forward declaration
EXPECT_TRUE(CParser("interface I1; interface I1 {};").Parse().Root()->Find("I1"));
EXPECT_TRUE(CParser("interface I1 {}; interface I1;").Parse().Root()->Find("I1"));
EXPECT_TRUE(CParser("interface I1; interface I1; interface I1; interface I1;").Parse().Root()->Find("I1"));
EXPECT_TRUE(CParser("interface I1 {}; interface I1; interface I1; ").Parse().Root()->Find("I1"));
EXPECT_THROW(CParser("interface I1 {}; interface I1; interface I1 {}; ").Parse(), CCompileException);
}
TEST_F(CParserInterfaceTest, Definition)
{
// interface <interface_identifier> {...}; --> interface definition
EXPECT_TRUE(CParser("interface I2 {};").Parse().Root()->Find("I2"));
EXPECT_TRUE(CParser("interface I2 { const int32 i = 1; };").Parse().Root()->Find("I2"));
EXPECT_TRUE(CParser("interface I2 { const int32 i = 1; };").Parse().Root()->Find("I2::i"));
}
TEST_F(CParserInterfaceTest, DefinitionWithInheritance)
{
// interface <interface_identifier> : <base_interface,...> {...}; --> interface definition with inheritance
EXPECT_TRUE(CParser("interface I3base {const int32 i = 1;}; interface I3 : I3base {const int32 j = 1;};").Parse().Root()->Find("I3"));
EXPECT_TRUE(CParser("interface I3base_1 {const int32 i = 1;}; interface I3base_2 {const int32 i = 2;}; interface I3_12 : I3base_1, I3base_2 {const int32 j = 1;};").Parse().Root()->Find("I3_12"));
EXPECT_TRUE(CParser("interface I3base_1 {}; interface I3base_2 : I3base_1 {}; interface I3_12 : I3base_2 {};").Parse().Root()->Find("I3_12"));
EXPECT_TRUE(CParser("interface I3base_1 {}; interface I3base_2 : I3base_1 {}; interface I3_12 : I3base_1, I3base_2 {};").Parse().Root()->Find("I3_12"));
// I3base is not defined
EXPECT_THROW(CParser("interface I3 : I3base {};").Parse(), CCompileException);
EXPECT_THROW(CParser("interface I3base; interface I3 : I3base {};").Parse(), CCompileException);
// Invalid base interface
EXPECT_THROW(CParser("const uint32_t I1 = 10; interface I2 : I1 {};").Parse(), CCompileException);
}
TEST_F(CParserInterfaceTest, DuplicateNameThroughInheritance)
{
EXPECT_THROW(CParser("interface I1 {const char c = 'C';}; interface I2 : I1 {const int32 c = 10;};").Parse(), CCompileException);
EXPECT_THROW(CParser("interface I1; interface I1 {const char c = 'C';}; interface I2 : I1 {const int32 c = 10;};").Parse(), CCompileException);
EXPECT_THROW(CParser("interface I1 {const char c = 'C';}; interface I2 : I1 {}; interface I3 : I2 {const int32 c = 10;};").Parse(), CCompileException);
}
TEST_F(CParserInterfaceTest, SimpleTypeAttributeDefinition)
{
EXPECT_TRUE(CParser("interface I{attribute int8 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute int16 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute int32 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute int64 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute uint8 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute uint16 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute uint32 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute uint64 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute octet attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute short attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute long attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute long long attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute unsigned short attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute unsigned long attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute unsigned long long attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute char attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute wchar attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute char16 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute char32 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute float attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute double attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute long double attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute fixed attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute string attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute u8string attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute u16string attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute u32string attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{attribute wstring attr;};").Parse().Root()->Find("I::attr"));
EXPECT_THROW(CParser("interface I{attribute void attr;};").Parse(), CCompileException);
}
TEST_F(CParserInterfaceTest, ComplexTypeAttributeDefinition)
{
EXPECT_TRUE(CParser("struct S{}; interface I{attribute S attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("struct S{}; interface I{attribute struct S attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("typedef struct tagS {} S; interface I{attribute S attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("typedef int32 TI; interface I{attribute TI attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("typedef int32 TI[10]; interface I{attribute TI attr;};").Parse().Root()->Find("I::attr"));
EXPECT_THROW(CParser("typedef int32 TI[]; interface I{attribute TI attr;};").Parse(), CCompileException);
}
TEST_F(CParserInterfaceTest, AttributeWithExceptionDefinition)
{
EXPECT_TRUE(CParser("exception S1{}; interface I{attribute int32 attr raises(S1);};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("exception S1{}; exception S2{}; interface I{attribute int32 attr getraises(S1) setraises(S2);};").Parse().Root()->Find("I::attr"));
EXPECT_NO_THROW(CParser("exception S1{}; exception S2{}; interface I{attribute int32 attr raises(S1) setraises(S2);};").Parse());
EXPECT_NO_THROW(CParser("exception S1{}; exception S2{}; interface I{attribute int32 attr raises(S1) getraises(S2);};").Parse());
EXPECT_NO_THROW(CParser("exception S1{}; exception S2{}; interface I{attribute int32 attr setraises(S1) raises(S2);};").Parse());
EXPECT_NO_THROW(CParser("exception S1{}; exception S2{}; interface I{attribute int32 attr getraises(S1) raises(S2);};").Parse());
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{attribute int32 attr setraises(S1) setraises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{attribute int32 attr getraises(S1) getraises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{attribute int32 attr raises(S1) raises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("interface I{attribute int32 attr raises(S1);};").Parse(), CCompileException);
}
TEST_F(CParserInterfaceTest, SimpleTypeReadOnlyAttributeDefinition)
{
EXPECT_TRUE(CParser("interface I{readonly attribute int8 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute int16 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute int32 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute int64 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute uint8 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute uint16 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute uint32 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute uint64 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute octet attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute short attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute long attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute long long attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute unsigned short attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute unsigned long attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute unsigned long long attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute char attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute wchar attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute char16 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute char32 attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute float attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute double attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute long double attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute fixed attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute string attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute u8string attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute u16string attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute u32string attr;};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("interface I{readonly attribute wstring attr;};").Parse().Root()->Find("I::attr"));
EXPECT_THROW(CParser("interface I{readonly attribute void attr;};").Parse(), CCompileException);
}
TEST_F(CParserInterfaceTest, ReadOnlyAttributeWithExceptionDefinition)
{
EXPECT_TRUE(CParser("exception S1{}; interface I{readonly attribute int32 attr raises(S1);};").Parse().Root()->Find("I::attr"));
EXPECT_TRUE(CParser("exception S1{}; exception S2{}; interface I{readonly attribute int32 attr getraises(S1);};").Parse().Root()->Find("I::attr"));
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{readonly attribute int32 attr setraises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{readonly attribute int32 attr getraises(S1) setraises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{readonly attribute int32 attr raises(S1) setraises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{readonly attribute int32 attr raises(S1) getraises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{readonly attribute int32 attr setraises(S1) raises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{readonly attribute int32 attr getraises(S1) raises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{readonly attribute int32 attr setraises(S1) setraises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{readonly attribute int32 attr getraises(S1) getraises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{readonly attribute int32 attr raises(S1) raises(S2);};").Parse(), CCompileException);
}
TEST_F(CParserInterfaceTest, MultipleAttributeDefinition)
{
EXPECT_TRUE(CParser("interface I{attribute int32 attr1, attr2, attr3;};").Parse().Root()->Find("I::attr3"));
EXPECT_TRUE(CParser("exception S1{}; exception S2{}; exception S3; interface I{attribute int32 attr1 raises(S1), attr2 getraises(S1) setraises(S2), attr3;};").Parse().Root()->Find("I::attr3"));
}
TEST_F(CParserInterfaceTest, SimpleTypeOperationDefinition)
{
EXPECT_TRUE(CParser("interface I{void func(in int8 var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in int16 var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in int32 var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in int64 var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in uint8 var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in uint16 var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in uint32 var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in uint64 var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in octet var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in short var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in long var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in long long var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in unsigned short var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in unsigned long var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in unsigned long long var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in char var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in wchar var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in char16 var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in char32 var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in float var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in double var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in long double var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in fixed var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in string var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in u8string var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in u16string var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in u32string var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func(in wstring var);};").Parse().Root()->Find("I::func"));
EXPECT_THROW(CParser("interface I{void func(in void);};").Parse(), CCompileException);
}
TEST_F(CParserInterfaceTest, ReturnSimpleTypeOperationDefinition)
{
EXPECT_TRUE(CParser("interface I{int8 func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{int16 func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{int32 func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{int64 func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{uint8 func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{uint16 func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{uint32 func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{uint64 func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{octet func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{short func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{long func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{long long func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{unsigned short func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{unsigned long func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{unsigned long long func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{char func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{wchar func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{char16 func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{char32 func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{float func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{double func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{long double func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{fixed func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{string func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{u8string func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{u16string func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{u32string func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{wstring func();};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func();};").Parse().Root()->Find("I::func"));
}
TEST_F(CParserInterfaceTest, ReturnSimpleTypeConstOperationDefinition)
{
EXPECT_TRUE(CParser("interface I{int16 func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{int32 func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{int64 func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{uint8 func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{uint16 func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{uint32 func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{uint64 func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{octet func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{short func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{long func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{long long func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{unsigned short func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{unsigned long func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{int8 func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{unsigned long long func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{char func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{wchar func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{char16 func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{char32 func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{float func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{double func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{long double func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{fixed func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{string func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{u8string func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{u16string func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{u32string func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{wstring func() const;};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface I{void func() const;};").Parse().Root()->Find("I::func"));
}
TEST_F(CParserInterfaceTest, SimpleTypeOperationMegaDefinition)
{
EXPECT_TRUE(CParser("interface I{void func(in int8 var1, in int16 var2, in int32 var3, in int64 var4, in uint8 var5,"
" in uint16 var6, in uint32 var7, in uint64 var8, in octet var9, in short var10, in long var11, in long long var12,"
" in unsigned short var13, in unsigned long var14, in unsigned long long var15, in char var16, in wchar var17,"
" in char16 var18, in char32 var19, in float var20, in double var21, in long double var22, in fixed var23,"
" in string var24, in u8string var25, in u16string var26, in u32string var27, in wstring var28);};").Parse().
Root()->Find("I::func"));
}
TEST_F(CParserInterfaceTest, ComplexTypeOperationDefinition)
{
EXPECT_TRUE(CParser("struct S{}; interface I{void func(in S var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("struct S{}; interface I{void func(in struct S var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("typedef struct tagS {} S; interface I{void func(in S var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("typedef int32 TI; interface I{void func(in TI var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("typedef int32 TI[10]; interface I{void func(in TI var);};").Parse().Root()->Find("I::func"));
EXPECT_THROW(CParser("typedef int32 TI[]; interface I{void func(in TI var);};").Parse(), CCompileException);
EXPECT_TRUE(CParser("interface IRet{}; interface I{void func(in IRet var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface IRet{}; interface I{void func(out IRet var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface IRet{}; interface I{void func(inout IRet var);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("interface IRet{}; interface I{IRet func();};").Parse().Root()->Find("I::func"));
}
TEST_F(CParserInterfaceTest, OperationWithExceptionDefinition)
{
EXPECT_TRUE(CParser("exception S1{}; interface I{void func(in int32 var) raises(S1);};").Parse().Root()->Find("I::func"));
EXPECT_TRUE(CParser("exception S1{}; interface I{void func(in int32 var) const raises(S1);};").Parse().Root()->Find("I::func"));
EXPECT_THROW(CParser("exception S1{}; interface I{void func(in int32 var) getraises(S1);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; interface I{void func(in int32 var) const getraises(S1);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; interface I{void func(in int32 var) raises(S1) const;};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; interface I{void func(in int32 var) getraises(S1) const;};").Parse(), CCompileException);
EXPECT_NO_THROW(CParser("exception S1{}; interface I{void func(in int32 var) raises(S1);};").Parse());
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{void func(in int32 var) setraises(S1) getraises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{void func(in int32 var) raises(S1) getraises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{void func(in int32 var) getraises(S1) raises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{void func(in int32 var) getraises(S1) getraises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("exception S1{}; exception S2{}; interface I{void func(in int32 var) raises(S1) raises(S2);};").Parse(), CCompileException);
EXPECT_THROW(CParser("interface I{void func(in int32 var) raises(S1);};").Parse(), CCompileException);
}
TEST_F(CParserInterfaceTest, LocalInterface)
{
EXPECT_THROW(CParser("interface I{uint8[] Test(in int8 p);};").Parse(), CCompileException);
}

View File

@@ -0,0 +1,301 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/meta_entity.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
#include <fstream>
using CParserMetaTest = CParserTest;
TEST_F(CParserMetaTest, CheckIncludeLocal)
{
// Create a dummy file
std::ofstream fstreamTest("include_test.idl", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamTest.is_open());
fstreamTest << "const int32 i = 10;";
fstreamTest.close();
// Parse the statement
CParser parser("#include \"include_test.idl\"");
parser.Parse();
const CEntityList& rlstMeta = parser.Root()->Get<CRootEntity>()->GetMeta();
ASSERT_EQ(rlstMeta.size(), 1);
// Check for the include meta (first entry)
ASSERT_TRUE(rlstMeta.front() != nullptr);
CEntityPtr ptrMeta = rlstMeta.front();
EXPECT_EQ(ptrMeta->GetType(), sdv::idl::EEntityType::type_meta);
const CMetaEntity* pMeta = ptrMeta->Get<CMetaEntity>();
ASSERT_TRUE(pMeta != nullptr);
EXPECT_EQ(pMeta->GetMetaType(), sdv::idl::IMetaEntity::EType::include_local);
EXPECT_EQ(pMeta->GetContent(), "\"include_test.idl\"");
fstreamTest.close();
try
{
std::filesystem::remove("include_test.idl");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST_F(CParserMetaTest, CheckIncludeLocalAbsolute)
{
// Create a dummy file
std::filesystem::path pathCurrent = std::filesystem::current_path();
std::ofstream fstreamTest("include_test.idl", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamTest.is_open());
fstreamTest << "const int32 i = 10;";
fstreamTest.close();
// Parse the statement
std::string ssCode = "#include \"";
ssCode += (pathCurrent / "include_test.idl").generic_u8string();
ssCode += "\"";
CParser parser(ssCode.c_str());
parser.Parse();
const CEntityList& rlstMeta = parser.Root()->Get<CRootEntity>()->GetMeta();
ASSERT_EQ(rlstMeta.size(), 1);
// Check for the include meta (first entry)
ASSERT_TRUE(rlstMeta.front() != nullptr);
CEntityPtr ptrMeta = rlstMeta.front();
EXPECT_EQ(ptrMeta->GetType(), sdv::idl::EEntityType::type_meta);
const CMetaEntity* pMeta = ptrMeta->Get<CMetaEntity>();
ASSERT_TRUE(pMeta != nullptr);
EXPECT_EQ(pMeta->GetMetaType(), sdv::idl::IMetaEntity::EType::include_local);
EXPECT_EQ(pMeta->GetContent(), std::string("\"") + (pathCurrent / "include_test.idl").generic_u8string() + "\"");
fstreamTest.close();
try
{
std::filesystem::remove("include_test.idl");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST_F(CParserMetaTest, CheckIncludeGlobal)
{
// Create a dummy file
std::filesystem::create_directory("dummy1");
std::filesystem::path path = "dummy1/include_test.idl";
std::ofstream fstreamTest(path.generic_u8string().c_str(), std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamTest.is_open());
fstreamTest << "const int32 i = 20;";
fstreamTest.close();
// Make include dirs (1st argument is the executable file path).
std::vector<std::string> vecArgs = {"idl_compiler_test.exe", "-Idummy1"};
CIdlCompilerEnvironment environment(vecArgs);
// Parse the statement
CParser parser("#include <include_test.idl>", environment);
parser.Parse();
const CEntityList& rlstMeta = parser.Root()->Get<CRootEntity>()->GetMeta();
ASSERT_EQ(rlstMeta.size(), 1);
// Check for the include meta (first entry)
ASSERT_TRUE(rlstMeta.front() != nullptr);
CEntityPtr ptrMeta = rlstMeta.front();
EXPECT_EQ(ptrMeta->GetType(), sdv::idl::EEntityType::type_meta);
const CMetaEntity* pMeta = ptrMeta->Get<CMetaEntity>();
ASSERT_TRUE(pMeta != nullptr);
EXPECT_EQ(pMeta->GetMetaType(), sdv::idl::IMetaEntity::EType::include_global);
EXPECT_EQ(pMeta->GetContent(), "<include_test.idl>");
fstreamTest.close();
try
{
std::filesystem::remove(path);
std::filesystem::remove_all("dummy1");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST_F(CParserMetaTest, CheckDefine)
{
// Parse the statement
CParser parser("#define def1\n#define def2 10");
parser.Parse();
const CEntityList& rlstMeta = parser.Root()->Get<CRootEntity>()->GetMeta();
ASSERT_EQ(rlstMeta.size(), 2);
// Check for the 1st define meta
ASSERT_TRUE(rlstMeta.front() != nullptr);
CEntityPtr ptrMeta = rlstMeta.front();
EXPECT_EQ(ptrMeta->GetType(), sdv::idl::EEntityType::type_meta);
const CMetaEntity* pMeta = ptrMeta->Get<CMetaEntity>();
ASSERT_TRUE(pMeta != nullptr);
EXPECT_EQ(pMeta->GetMetaType(), sdv::idl::IMetaEntity::EType::define);
EXPECT_EQ(pMeta->GetContent(), "def1");
// Check for the 2nd define meta
ASSERT_TRUE(rlstMeta.back() != nullptr);
ptrMeta = rlstMeta.back();
EXPECT_EQ(ptrMeta->GetType(), sdv::idl::EEntityType::type_meta);
pMeta = ptrMeta->Get<CMetaEntity>();
ASSERT_TRUE(pMeta != nullptr);
EXPECT_EQ(pMeta->GetMetaType(), sdv::idl::IMetaEntity::EType::define);
EXPECT_EQ(pMeta->GetContent(), "def2 10");
}
TEST_F(CParserMetaTest, CheckUndef)
{
// Parse the statement
CParser parser("#define def1 10\n#undef def1");
parser.Parse();
const CEntityList& rlstMeta = parser.Root()->Get<CRootEntity>()->GetMeta();
ASSERT_EQ(rlstMeta.size(), 2);
// Check for the define meta (first entry)
ASSERT_TRUE(rlstMeta.front() != nullptr);
CEntityPtr ptrMeta = rlstMeta.front();
EXPECT_EQ(ptrMeta->GetType(), sdv::idl::EEntityType::type_meta);
const CMetaEntity* pMeta = ptrMeta->Get<CMetaEntity>();
ASSERT_TRUE(pMeta != nullptr);
EXPECT_EQ(pMeta->GetMetaType(), sdv::idl::IMetaEntity::EType::define);
EXPECT_EQ(pMeta->GetContent(), "def1 10");
// Check for the undef meta (second entry)
ASSERT_TRUE(rlstMeta.back() != nullptr);
ptrMeta = rlstMeta.back();
EXPECT_EQ(ptrMeta->GetType(), sdv::idl::EEntityType::type_meta);
pMeta = ptrMeta->Get<CMetaEntity>();
ASSERT_TRUE(pMeta != nullptr);
EXPECT_EQ(pMeta->GetMetaType(), sdv::idl::IMetaEntity::EType::undef);
EXPECT_EQ(pMeta->GetContent(), "def1");
}
TEST_F(CParserMetaTest, CheckIncludeLocalDefineCombi)
{
// Create a dummy file
std::ofstream fstreamTest("include_test.idl", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamTest.is_open());
fstreamTest << "#define HELLO";
fstreamTest.close();
// Parse the statement
CParser parser("#include \"include_test.idl\"");
parser.Parse();
const CEntityList& rlstMeta = parser.Root()->Get<CRootEntity>()->GetMeta();
ASSERT_EQ(rlstMeta.size(), 2);
// Check for the include meta (first entry)
ASSERT_TRUE(rlstMeta.front() != nullptr);
CEntityPtr ptrMeta = rlstMeta.front();
EXPECT_EQ(ptrMeta->GetType(), sdv::idl::EEntityType::type_meta);
const CMetaEntity* pMeta = ptrMeta->Get<CMetaEntity>();
ASSERT_TRUE(pMeta != nullptr);
EXPECT_EQ(pMeta->GetMetaType(), sdv::idl::IMetaEntity::EType::include_local);
EXPECT_EQ(pMeta->GetContent(), "\"include_test.idl\"");
// Check for the define meta (second entry)
ASSERT_TRUE(rlstMeta.back() != nullptr);
ptrMeta = rlstMeta.back();
EXPECT_EQ(ptrMeta->GetType(), sdv::idl::EEntityType::type_meta);
pMeta = ptrMeta->Get<CMetaEntity>();
ASSERT_TRUE(pMeta != nullptr);
EXPECT_EQ(pMeta->GetMetaType(), sdv::idl::IMetaEntity::EType::define);
EXPECT_EQ(pMeta->GetContent(), "HELLO");
fstreamTest.close();
try
{
std::filesystem::remove("include_test.idl");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST_F(CParserMetaTest, CheckVerbatim)
{
// Parse the statement
CParser parser(
"#verbatim const int32 i = 10\n"
"#verbatim const int32 j = 10\n"
"#verbatim const int32 k = 10\\\n"
"const int32 l = 10\n"
"// Definition of M\n"
"#verbatim #define M\n"
"#verbatim #include <string>");
parser.Parse();
const CEntityList& rlstMeta = parser.Root()->Get<CRootEntity>()->GetMeta();
ASSERT_EQ(rlstMeta.size(), 5);
size_t nIndex = 0;
for (const CEntityPtr& rptrMeta : rlstMeta)
{
EXPECT_EQ(rptrMeta->GetType(), sdv::idl::EEntityType::type_meta);
const CMetaEntity* pMeta = rptrMeta->Get<CMetaEntity>();
ASSERT_TRUE(pMeta != nullptr);
EXPECT_EQ(pMeta->GetMetaType(), sdv::idl::IMetaEntity::EType::verbatim);
switch (nIndex)
{
case 0:
EXPECT_EQ(pMeta->GetContent(), "const int32 i = 10");
break;
case 1:
EXPECT_EQ(pMeta->GetContent(), "const int32 j = 10");
break;
case 2:
EXPECT_EQ(pMeta->GetContent(), "const int32 k = 10\\\nconst int32 l = 10");
break;
case 3:
{
EXPECT_EQ(pMeta->GetContent(), "#define M");
uint32_t uiFlags = 0;
EXPECT_EQ(pMeta->GetComments(uiFlags), "Definition of M");
break;
}
case 4:
EXPECT_EQ(pMeta->GetContent(), "#include <string>");
break;
}
nIndex++;
}
}
TEST_F(CParserMetaTest, CheckVerbatimBlock)
{
// Parse the statement
CParser parser(
"#verbatim_begin\n"
"const int32 i = 10\n"
"const int32 j = 10\n"
"const int32 k = 10\\\n"
"const int32 l = 10\n"
"// Definition of M\n"
"#define M\n"
"#include <string>\n"
"#verbatim_end\n"
"#define N\n");
parser.Parse();
const CEntityList& rlstMeta = parser.Root()->Get<CRootEntity>()->GetMeta();
ASSERT_EQ(rlstMeta.size(), 2);
size_t nIndex = 0;
for (const CEntityPtr& rptrMeta : rlstMeta)
{
EXPECT_EQ(rptrMeta->GetType(), sdv::idl::EEntityType::type_meta);
const CMetaEntity* pMeta = rptrMeta->Get<CMetaEntity>();
ASSERT_TRUE(pMeta != nullptr);
switch (nIndex)
{
case 0:
EXPECT_EQ(pMeta->GetMetaType(), sdv::idl::IMetaEntity::EType::verbatim);
EXPECT_EQ(pMeta->GetContent(),
"const int32 i = 10\n"
"const int32 j = 10\n"
"const int32 k = 10\\\n"
"const int32 l = 10\n"
"// Definition of M\n"
"#define M\n"
"#include <string>\n" );
break;
case 1:
EXPECT_EQ(pMeta->GetMetaType(), sdv::idl::IMetaEntity::EType::define);
EXPECT_EQ(pMeta->GetContent(), "N");
break;
}
nIndex++;
}
}

View File

@@ -0,0 +1,41 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/module_entity.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
using CParserModuleTest = CParserTest;
TEST_F(CParserModuleTest, ParsingNonExistentModule)
{
EXPECT_FALSE(CParser("").Parse().Root()->Find("Test"));
EXPECT_THROW(CParser("{};").Parse(), CCompileException);
EXPECT_THROW(CParser("};").Parse(), CCompileException);
EXPECT_THROW(CParser("}").Parse(), CCompileException);
EXPECT_NO_THROW(CParser(";").Parse());
}
TEST_F(CParserModuleTest, ParsingModule)
{
EXPECT_TRUE(CParser("module Test {};").Parse().Root()->Find("Test"));
}
TEST_F(CParserModuleTest, ParsingRootModule)
{
EXPECT_TRUE(CParser("module Test {};").Parse().Root()->Find("::Test"));
}
TEST_F(CParserModuleTest, ParsingNestedModules)
{
EXPECT_TRUE(CParser("module Test { module Test2 {}; };").Parse().Root()->Find("Test::Test2"));
}
TEST_F(CParserModuleTest, ParsingJoinModules)
{
EXPECT_NO_THROW(CParser("module Test { module Test2 {}; };\nmodule Test { module Test3 {}; };").Parse().Root()->Find("Test::Test3"));
}
TEST_F(CParserModuleTest, ParsingJoinNestedModules)
{
EXPECT_NO_THROW(CParser("module Test { module Test2 {}; };\nmodule Test { module Test2 { module Test2b {}; }; };").Parse().Root()->Find("Test::Test2::Test2b"));
}

View File

@@ -0,0 +1,281 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/definition_entity.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/entities/struct_entity.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/entities/variable_entity.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/declaration_entity.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/entity_value.h"
using CParserStructTest = CParserTest;
TEST_F(CParserStructTest, ForwardDeclaration)
{
// struct <struct_identifier>; --> forward declaration
EXPECT_TRUE(CParser("struct S1; struct S1 {};").Parse().Root()->Find("S1"));
EXPECT_TRUE(CParser("struct S1 {}; struct S1;").Parse().Root()->Find("S1"));
EXPECT_TRUE(CParser("struct S1; struct S1; struct S1; struct S1;").Parse().Root()->Find("S1"));
EXPECT_TRUE(CParser("struct S1 {}; struct S1; struct S1; ").Parse().Root()->Find("S1"));
EXPECT_THROW(CParser("struct S1 {}; struct S1; struct S1 {}; ").Parse(), CCompileException);
}
TEST_F(CParserStructTest, Definition)
{
// struct <struct_identifier> {...}; --> struct definition
EXPECT_TRUE(CParser("struct S2 {};").Parse().Root()->Find("S2"));
EXPECT_TRUE(CParser("struct S2 { int32 i; };").Parse().Root()->Find("S2"));
EXPECT_TRUE(CParser("struct S2 { int32 i; };").Parse().Root()->Find("S2::i"));
}
TEST_F(CParserStructTest, DefinitionWithInheritance)
{
// struct <struct_identifier> : <base_struct,...> {...}; --> struct definition with inheritance
EXPECT_TRUE(CParser("struct S3base {int32 i;}; struct S3 : S3base {int32 j;};").Parse().Root()->Find("S3"));
EXPECT_TRUE(CParser("struct S3base_1 {int32 i;}; struct S3base_2 {int32 i;}; struct S3_12 : S3base_1, S3base_2 {int32 j;};").Parse().Root()->Find("S3_12"));
EXPECT_TRUE(CParser("struct S3base_1 {}; struct S3base_2 : S3base_1 {}; struct S3_12 : S3base_2 {};").Parse().Root()->Find("S3_12"));
EXPECT_TRUE(CParser("struct S3base_1 {}; struct S3base_2 : S3base_1 {}; struct S3_12 : S3base_1, S3base_2 {};").Parse().Root()->Find("S3_12"));
// S3base is not defined
EXPECT_THROW(CParser("struct S3 : S3base {};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S3base; struct S3 : S3base {};").Parse(), CCompileException);
// Invalid base struct
EXPECT_THROW(CParser("const uint32_t S1 = 10; struct S2 : S1 {};").Parse(), CCompileException);
}
TEST_F(CParserStructTest, DuplicateNameThroughInheritance)
{
EXPECT_THROW(CParser("struct S1 {const char c = 'C';}; struct S2 : S1 {const int32 c = 10;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S1; struct S1 {const char c = 'C';}; struct S2 : S1 {const int32 c = 10;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S1 {const char c = 'C';}; struct S2 : S1 {}; struct S3 : S2 {const int32 c = 10;};").Parse(), CCompileException);
}
TEST_F(CParserStructTest, DeclarationsAndTypedefs)
{
const char szCode[] = R"code(
struct S
{
struct S1
{
int32 a;
int32 b;
int32 c;
};
typedef S1 TS1;
struct S2 : TS1
{
int32 d;
int32 e;
int32 f;
};
typedef S2 TS2;
struct S3
{
TS1 ts1Value;
TS2 ts2Value;
};
typedef S3 TS3;
TS3 ts3Value;
typedef TS3 TS4;
TS4 ts4Value;
};
)code";
CParser parser(szCode);
parser.Parse();
EXPECT_TRUE(parser.Root()->Find("S::S1"));
EXPECT_TRUE(parser.Root()->Find("S::S1::a"));
EXPECT_TRUE(parser.Root()->Find("S::S1::b"));
EXPECT_TRUE(parser.Root()->Find("S::S1::c"));
EXPECT_TRUE(parser.Root()->Find("S::TS1"));
EXPECT_TRUE(parser.Root()->Find("S::TS1::a"));
EXPECT_TRUE(parser.Root()->Find("S::TS1::b"));
EXPECT_TRUE(parser.Root()->Find("S::TS1::c"));
EXPECT_TRUE(parser.Root()->Find("S::S2"));
EXPECT_TRUE(parser.Root()->Find("S::S2::a"));
EXPECT_TRUE(parser.Root()->Find("S::S2::b"));
EXPECT_TRUE(parser.Root()->Find("S::S2::c"));
EXPECT_TRUE(parser.Root()->Find("S::S2::d"));
EXPECT_TRUE(parser.Root()->Find("S::S2::e"));
EXPECT_TRUE(parser.Root()->Find("S::S2::f"));
EXPECT_TRUE(parser.Root()->Find("S::TS2"));
EXPECT_TRUE(parser.Root()->Find("S::TS2::a"));
EXPECT_TRUE(parser.Root()->Find("S::TS2::b"));
EXPECT_TRUE(parser.Root()->Find("S::TS2::c"));
EXPECT_TRUE(parser.Root()->Find("S::TS2::d"));
EXPECT_TRUE(parser.Root()->Find("S::TS2::e"));
EXPECT_TRUE(parser.Root()->Find("S::TS2::f"));
EXPECT_TRUE(parser.Root()->Find("S::S3"));
EXPECT_TRUE(parser.Root()->Find("S::TS3"));
EXPECT_TRUE(parser.Root()->Find("S::ts3Value.ts1Value"));
EXPECT_TRUE(parser.Root()->Find("S::ts3Value.ts2Value"));
EXPECT_TRUE(parser.Root()->Find("S::ts3Value.ts1Value.a"));
EXPECT_TRUE(parser.Root()->Find("S::ts3Value.ts1Value.b"));
EXPECT_TRUE(parser.Root()->Find("S::ts3Value.ts1Value.c"));
EXPECT_TRUE(parser.Root()->Find("S::ts3Value.ts2Value.a"));
EXPECT_TRUE(parser.Root()->Find("S::ts3Value.ts2Value.b"));
EXPECT_TRUE(parser.Root()->Find("S::ts3Value.ts2Value.c"));
EXPECT_TRUE(parser.Root()->Find("S::ts3Value.ts2Value.d"));
EXPECT_TRUE(parser.Root()->Find("S::ts3Value.ts2Value.e"));
EXPECT_TRUE(parser.Root()->Find("S::ts3Value.ts2Value.f"));
EXPECT_TRUE(parser.Root()->Find("S::TS4"));
EXPECT_TRUE(parser.Root()->Find("S::ts4Value.ts1Value"));
EXPECT_TRUE(parser.Root()->Find("S::ts4Value.ts2Value"));
EXPECT_TRUE(parser.Root()->Find("S::ts4Value.ts1Value.a"));
EXPECT_TRUE(parser.Root()->Find("S::ts4Value.ts1Value.b"));
EXPECT_TRUE(parser.Root()->Find("S::ts4Value.ts1Value.c"));
EXPECT_TRUE(parser.Root()->Find("S::ts4Value.ts2Value.a"));
EXPECT_TRUE(parser.Root()->Find("S::ts4Value.ts2Value.b"));
EXPECT_TRUE(parser.Root()->Find("S::ts4Value.ts2Value.c"));
EXPECT_TRUE(parser.Root()->Find("S::ts4Value.ts2Value.d"));
EXPECT_TRUE(parser.Root()->Find("S::ts4Value.ts2Value.e"));
EXPECT_TRUE(parser.Root()->Find("S::ts4Value.ts2Value.f"));
}
TEST_F(CParserStructTest, VariableDeclaration)
{
// <struct_identifier> <decl_identifier>; --> struct variable declaration
EXPECT_TRUE(CParser("struct S{struct S4 {int32 i;}; S4 s4Value;};").Parse().Root()->Find("S::s4Value"));
EXPECT_TRUE(CParser("struct S{struct S4 {int32 i;}; S4 s4Value;};").Parse().Root()->Find("S::s4Value.i"));
EXPECT_TRUE(CParser("struct S{struct S4 {int32 i;}; typedef S4 S5; S5 s5Value;};").Parse().Root()->Find("S::s5Value.i"));
EXPECT_TRUE(CParser("struct S{struct S4 {struct S5{int32 i;} s5Value;}; typedef S4 S6; S6 s6Value;};").Parse().Root()->Find("S::s6Value.s5Value.i"));
EXPECT_TRUE(CParser("struct S{struct S4 {struct S5{int32 i;} s5Value;}; typedef S4 S6; S6 s6Value;}; const S sValue = {{{10}}};").Parse().Root()->Find("sValue.s6Value.s5Value.i"));
// struct <struct_identifier> <decl_identifier>; --> struct variable declaration
EXPECT_TRUE(CParser("struct S{struct S6 {int32 i;}; struct S6 s6Value;};").Parse().Root()->Find("S::s6Value"));
}
TEST_F(CParserStructTest, VarDeclarationAndAssignment)
{
// <struct_identifier> <decl_identifier> = {...}; --> struct variable declaration and assignment
EXPECT_TRUE(CParser("struct S{struct S5 {int32 i;}; S5 s5Value = {10};};").Parse().Root()->Find("S::s5Value"));
EXPECT_TRUE(CParser("struct S{struct S5b {int32 i = 11;}; S5b s5bValue = {10};};").Parse().Root()->Find("S::s5bValue"));
// struct <struct_identifier> <decl_identifier> = {...}; --> struct variable declaration and assignment
EXPECT_TRUE(CParser("struct S{struct S7 {int32 i;}; struct S7 s7Value = {10};};").Parse().Root()->Find("S::s7Value"));
}
TEST_F(CParserStructTest, VarDeclarationAndAssignmentOfStructDecl)
{
EXPECT_EQ(CParser("struct S1{int32 i;}; struct S2{ S1 sValue1 = {10}; S1 sValue2 = sValue1; };").Parse().Root()->FindValueVariant("S2::sValue2.i").Get<int32_t>(), 10);
EXPECT_EQ(CParser("struct S1{int32 i[2];}; struct S2{ S1 sValue1 = {{10, 20}}; S1 sValue2 = sValue1; };").Parse().Root()->FindValueVariant("S2::sValue2.i[1]").Get<int32_t>(), 20);
EXPECT_EQ(CParser("struct S1{int32 i[2][2];}; struct S2{ S1 sValue1 = {{{10, 20}, {30, 40}}}; S1 sValue2 = sValue1; };").Parse().Root()->FindValueVariant("S2::sValue2.i[1][1]").Get<int32_t>(), 40);
EXPECT_EQ(CParser("struct S1{typedef int32 ti[2]; ti i[2];}; struct S2{ S1 sValue1 = {{{10, 20}, {30, 40}}}; S1 sValue2 = sValue1; };").Parse().Root()->FindValueVariant("S2::sValue2.i[1][1]").Get<int32_t>(), 40);
EXPECT_EQ(CParser("typedef struct tagS1 {int32 i;} S1; struct S2{ S1 sValue1 = {10}; S1 sValue2 = sValue1; };").Parse().Root()->FindValueVariant("S2::sValue2.i").Get<int32_t>(), 10);
EXPECT_EQ(CParser("typedef struct tagS1 {int32 i;} S1; struct S2{ S1 sValue1[2] = {{10}, {20}}; S1 sValue2 = sValue1[1]; };").Parse().Root()->FindValueVariant("S2::sValue2.i").Get<int32_t>(), 20);
EXPECT_EQ(CParser("typedef struct tagS1 {int32 i;} S1; const int32 index = 2; struct S2{ S1 sValue1[index] = {{10}, {20}}; S1 sValue2 = sValue1[1]; };").Parse().Root()->FindValueVariant("S2::sValue2.i").Get<int32_t>(), 20);
EXPECT_EQ(CParser("typedef struct tagS1 {int32 i;} S1; struct S2{ S1 sValue1[2] = {{10}, {20}};}; struct S3{S1 sValue2 = S2.sValue1[1]; };").Parse().Root()->FindValueVariant("S3::sValue2.i").Get<int32_t>(), 20);
}
TEST_F(CParserStructTest, DefinitionAndVariableDeclaration)
{
// struct <struct_identifier> {...} <decl_identifier>; --> struct definition and variable declaration
EXPECT_TRUE(CParser("struct S{struct S8 {int32 i;} s8Value;};").Parse().Root()->Find("S::s8Value"));
}
TEST_F(CParserStructTest, DefinitionWithInheritanceAndVariableDeclaration)
{
// struct <struct_identifier> : <base_struct,...> {...} <decl_identifier>; --> struct definition with inheritance and variable declaration
EXPECT_TRUE(CParser("struct S{struct S9base {int32 i;}; struct S9 : S9base {int32 j;} s9Value;};").Parse().Root()->Find("S::s9Value"));
}
TEST_F(CParserStructTest, DefinitionAndVariableDeclarationAndAssignment)
{
// struct <struct_identifier> {...} <decl_identifier> = {...}; --> struct definition, variable declaration and assignment
EXPECT_TRUE(CParser("struct S{struct S10 {int32 i;} s10Value = {10};};").Parse().Root()->Find("S::s10Value"));
}
TEST_F(CParserStructTest, DefinitionWithInheritanceAndVariableDeclarationAndAssignment)
{
// struct <struct_identifier> : <base_struct,...> {...} <decl_identifier> = {...}; --> struct definition with inheritance, variable declaration and assignment
EXPECT_TRUE(CParser("struct S{struct S11base {int32 i;}; struct S11 : S11base {int32 j;} s11Value = {{10}, 10};};").Parse().Root()->Find("S::s11Value"));
EXPECT_TRUE(CParser("struct S{struct S11base {int32 i;}; struct S11 : S11base {} s11Value = {{10}};};").Parse().Root()->Find("S::s11Value"));
}
TEST_F(CParserStructTest, UnnamedDefinitionAndVariableDeclaration)
{
// struct {...} <decl_identifier>; --> unnamed struct definition and variable declaration
// NOTE 11.04.2025: Not allowed due to incompatibility in C++ standard
EXPECT_THROW(CParser("struct S{struct {int32 i;} s12Value;};").Parse(), CCompileException);
}
TEST_F(CParserStructTest, UnnamedDefinitionWithInheritanceAndVariableDeclaration)
{
// struct : <base_struct,...> {...} <decl_identifier>; --> unnamed struct definition with inheritance and variable declaration
// NOTE 11.04.2025: Not allowed due to incompatibility in C++ standard
EXPECT_THROW(CParser("struct S{struct S13base {int32 i;}; struct : S13base {int32 j;} s13Value;};").Parse(), CCompileException);
}
TEST_F(CParserStructTest, UnnamedDefinitionAndVariableDeclarationAndAssignment)
{
// struct {...} <decl_identifier> = {...}; --> unnamed struct definition, variable declaration and assignment
// NOTE 11.04.2025: Not allowed due to incompatibility in C++ standard
EXPECT_THROW(CParser("struct S{struct {int32 i;} s14Value = {10};};").Parse(), CCompileException);
}
TEST_F(CParserStructTest, UnnamedDefinitionWithInheritanceAndVariableDeclarationAndAssignment)
{
// struct : <base_struct,...> {...} <decl_identifier> = {...}; --> unnamed struct definition with inheritance, variable declaration and assignment
// NOTE 11.04.2025: Not allowed due to incompatibility in C++ standard
EXPECT_THROW(CParser("struct S{struct S15base {int32 i;}; struct : S15base {int32 j;} s15Value = {{10}, 10};};").Parse(), CCompileException);
}
TEST_F(CParserStructTest, ComplexCombinationWithStructTypedefMultiDimmensionalArrayDeclarations)
{
const char szCode[] = R"code(
struct S
{
const int32 a = 2;
typedef int32 intarray[a];
typedef intarray initintarray[3][1];
initintarray rgarray[4] = {{{{1,2}}, {{3,4}}, {{5,6}}},
{{{7,8}},{{9,10}}, {{a,b}}},
{{{13,14}}, {{15,16}}, {{17,18}}},
{{{19,20}},{{21,22}}, {{23,24}}} };
const int32 b = 4;
};
)code";
CParser parser(szCode);
EXPECT_NO_THROW(parser.Parse());
CEntityPtr ptrVar = parser.Root()->Find("S::rgarray");
ASSERT_TRUE(ptrVar);
CDeclarationEntity* pVar = ptrVar->Get<CDeclarationEntity>();
ASSERT_NE(pVar, nullptr);
CValueNodePtr ptrVal = ptrVar->ValueRef();
ASSERT_TRUE(ptrVal);
CArrayValueNode* pInitIntArrayVal = ptrVal->Get<CArrayValueNode>();
ASSERT_NE(pInitIntArrayVal, nullptr);
EXPECT_EQ(pInitIntArrayVal->GetSize(), 4);
CValueNodePtr ptrIntArrayVal = (*pInitIntArrayVal)[3];
ASSERT_TRUE(ptrIntArrayVal);
CArrayValueNode* pIntArrayVal = ptrIntArrayVal->Get<CArrayValueNode>();
ASSERT_NE(pIntArrayVal, nullptr);
EXPECT_EQ(pIntArrayVal->GetSize(), 3);
CValueNodePtr ptrIntArrayVal_2 = (*pIntArrayVal)[2];
ASSERT_TRUE(ptrIntArrayVal_2);
CArrayValueNode* pIntArrayVal_2 = ptrIntArrayVal_2->Get<CArrayValueNode>();
ASSERT_NE(pIntArrayVal_2, nullptr);
EXPECT_EQ(pIntArrayVal_2->GetSize(), 1);
CValueNodePtr ptrIntArrayVal_3 = (*pIntArrayVal_2)[0];
ASSERT_TRUE(ptrIntArrayVal_3);
CArrayValueNode* pIntArrayVal_3 = ptrIntArrayVal_3->Get<CArrayValueNode>();
ASSERT_NE(pIntArrayVal_3, nullptr);
EXPECT_EQ(pIntArrayVal_3->GetSize(), 2);
CValueNodePtr ptrIntVal = (*pIntArrayVal_3)[1];
ASSERT_TRUE(ptrIntVal);
CSimpleTypeValueNode* pIntVal = ptrIntVal->Get<CSimpleTypeValueNode>();
ASSERT_NE(pIntVal, nullptr);
EXPECT_EQ(pIntVal->Variant().Get<int32_t>(), 24);
}
TEST_F(CParserStructTest, StringAssignmentInStruct)
{
// Tests bug fix: #380904
const char szCode[] = R"code(
struct SStringTest
{
string ssVal = "hello";
u8string ss8Val = u8"hello";
};
)code";
CParser parser(szCode);
EXPECT_NO_THROW(parser.Parse());
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
#ifndef PARSER_TEST_H
#define PARSER_TEST_H
/**
* \brief Test class for instantiation tests.
*/
class CParserTest : public testing::Test
{
public:
/**
* \brief Constructor
*/
CParserTest() = default;
/**
* \brief Set up the test suite.
*/
static void SetUpTestCase();
/**
* \brief Tear down the test suite.
*/
static void TearDownTestCase();
/**
* \brief Test setup.
*/
void SetUp() override;
/**
* \brief Test teardown.
*/
void TearDown() override;
};
#endif // define PARSER_TEST_H

View File

@@ -0,0 +1,276 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/typedef_entity.cpp"
using CParserTypedefTest = CParserTest;
TEST_F(CParserTypedefTest, ParsingTypeDefinition)
{
EXPECT_TRUE(CParser("typedef int8 hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint8 hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef octet hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int16 hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint16 hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef short hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned short hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int32 hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint32 hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned long hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int64 hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint64 hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long long hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned long long hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef float hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef double hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long double hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef wchar hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char16 hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char32 hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef string hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u8string hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u16string hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u32string hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef fixed hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef boolean hello;").Parse().Root()->Find("hello"));
}
TEST_F(CParserTypedefTest, ParsingIndirectTypeDefinition)
{
EXPECT_TRUE(CParser("typedef int8 hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint8 hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef octet hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int16 hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint16 hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef short hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned short hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int32 hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint32 hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned long hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int64 hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint64 hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long long hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned long long hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef float hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef double hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long double hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef wchar hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char16 hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char32 hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef string hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u8string hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u16string hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u32string hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef fixed hi; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef boolean hi; typedef hi hello;").Parse().Root()->Find("hello"));
}
TEST_F(CParserTypedefTest, ParsingTypeDefinitionArrayDirect)
{
EXPECT_TRUE(CParser("typedef int8 hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint8 hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef octet hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int16 hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint16 hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef short hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned short hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int32 hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint32 hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned long hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int64 hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint64 hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long long hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned long long hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef float hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef double hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long double hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef wchar hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char16 hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char32 hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef string hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u8string hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u16string hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u32string hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef fixed hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef boolean hello[2];").Parse().Root()->Find("hello"));
}
TEST_F(CParserTypedefTest, ParsingTypeDefinitionArrayUnbound)
{
EXPECT_TRUE(CParser("typedef int8 hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef uint8 hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef char hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef octet hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef int16 hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef uint16 hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef short hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef unsigned short hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef int32 hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef uint32 hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef long hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef unsigned long hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef int64 hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef uint64 hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef long long hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef unsigned long long hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef float hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef double hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef long double hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef wchar hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef char16 hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef char32 hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef string hi[]; const hi hello = {\"1\", \"2\"};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef u8string hi[]; const hi hello = {u8\"1\", u8\"2\"};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef u16string hi[]; const hi hello = {u\"1\", u\"2\"};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef u32string hi[]; const hi hello = {U\"1\", U\"2\"};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef wstring hi[]; const hi hello = {L\"1\", L\"2\"};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef fixed hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_TRUE(CParser("typedef boolean hi[]; const hi hello = {1, 2};").Parse().Root()->Find("hi"));
EXPECT_THROW(CParser("typedef boolean hi[]; hi hello = {1, 2};").Parse(), CCompileException);
EXPECT_THROW(CParser("typedef boolean hi[]; typedef hi hi; ho hello = {1, 2};").Parse(), CCompileException);
}
TEST_F(CParserTypedefTest, ParsingTypeDefinitionArrayIndirect)
{
EXPECT_TRUE(CParser("const int32 size = 2; typedef int8 hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef uint8 hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef char hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef octet hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef int16 hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef uint16 hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef short hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef unsigned short hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef int32 hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef uint32 hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef long hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef unsigned long hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef int64 hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef uint64 hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef long long hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef unsigned long long hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef float hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef double hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef long double hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef wchar hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef char16 hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef char32 hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef string hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef u8string hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef u16string hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef u32string hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef fixed hello[2 * size];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("const int32 size = 2; typedef boolean hello[2 * size];").Parse().Root()->Find("hello"));
}
TEST_F(CParserTypedefTest, ParsingIndirectArrayTypeDefinition)
{
EXPECT_TRUE(CParser("typedef int8 hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint8 hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef octet hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int16 hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint16 hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef short hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned short hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int32 hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint32 hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned long hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int64 hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint64 hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long long hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned long long hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef float hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef double hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long double hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef wchar hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char16 hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char32 hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef string hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u8string hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u16string hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u32string hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef fixed hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef boolean hi[2]; typedef hi hello;").Parse().Root()->Find("hello"));
}
TEST_F(CParserTypedefTest, ParsingIndirectTypeArrayDefinition)
{
EXPECT_TRUE(CParser("typedef int8 hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint8 hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef octet hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int16 hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint16 hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef short hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned short hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int32 hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint32 hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned long hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int64 hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint64 hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long long hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned long long hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef float hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef double hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long double hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef wchar hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char16 hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char32 hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef string hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u8string hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u16string hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u32string hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef fixed hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef boolean hi; typedef hi hello[2];").Parse().Root()->Find("hello"));
}
TEST_F(CParserTypedefTest, ParsingIndirectArrayTypeArrayDefinition)
{
EXPECT_TRUE(CParser("typedef int8 hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint8 hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef octet hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int16 hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint16 hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef short hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned short hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int32 hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint32 hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned long hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef int64 hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef uint64 hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long long hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef unsigned long long hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef float hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef double hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef long double hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef wchar hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char16 hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef char32 hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef string hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u8string hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u16string hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef u32string hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef fixed hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
EXPECT_TRUE(CParser("typedef boolean hi[2]; typedef hi hello[2];").Parse().Root()->Find("hello"));
}
TEST_F(CParserTypedefTest, ParsingAnonymousStructDefinition)
{
// Anonymous struct definitions are not allowed in IDL
EXPECT_THROW(CParser("typedef struct { const long hello = 10; } S1_t;").Parse(), CCompileException);
EXPECT_THROW(CParser("typedef struct { const long hello = 10; } S1_t[10];").Parse().Root(), CCompileException);
// Named struct definitions are allowed in IDL
EXPECT_TRUE(CParser("typedef struct S1 { const long hello = 10; } S1_t;").Parse().Root()->Find("S1_t"));
EXPECT_TRUE(CParser("typedef struct S1 { const long hello = 10; } S1_t[10];").Parse().Root()->Find("S1_t"));
}

View File

@@ -0,0 +1,364 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/union_entity.cpp"
using CParserUnionTest = CParserTest;
TEST_F(CParserUnionTest, ForwardDeclaration)
{
// type based union: union <union_identifier>; --> forward declaration
EXPECT_TRUE(CParser("union U1; union U1 switch (int32) {};").Parse().Root()->Find("U1"));
EXPECT_TRUE(CParser("union U1 switch (int32) {}; union U1;").Parse().Root()->Find("U1"));
EXPECT_TRUE(CParser("union U1; union U1; union U1; union U1;").Parse().Root()->Find("U1"));
EXPECT_TRUE(CParser("union U1 switch (int32) {}; union U1; union U1; ").Parse().Root()->Find("U1"));
EXPECT_THROW(CParser("union U1 switch (int32) {}; union U1; union U1 switch (int32) {}; ").Parse(), CCompileException);
// variable based union: struct {union <union_identifier>; --> forward declaration}
EXPECT_TRUE(CParser("struct S { uint32 uiVal; union U1 switch (uiVal) {};};").Parse().Root()->Find("S::U1"));
EXPECT_TRUE(CParser("struct S { union U1; uint32 uiVal; union U1 switch (uiVal) {};};").Parse().Root()->Find("S::U1"));
}
TEST_F(CParserUnionTest, Definition)
{
// union <union_identifier> switch(<case_identifier>){...}; --> union definition
EXPECT_TRUE(CParser("union U2 switch (int32) {};").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(boolean) { case true: int32 i; case false: int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(boolean) { case true: int32 i; case false: int64 j; };").Parse().Root()->Find("U2::i"));
EXPECT_TRUE(CParser("union U2 switch(int32) { case 1: int32 i; case 2: int64 j; default: float f; };").Parse().Root()->Find("U2::f"));
EXPECT_TRUE(CParser("union U2 switch(int32) { default: float f; case 1: int32 i; case 2: int64 j; };").Parse().Root()->Find("U2::f"));
EXPECT_THROW(CParser("union U2 switch(int32) { default: float f; case 1: int32 i; case 2: int64 j; default: double d; };").Parse(), CCompileException);
EXPECT_THROW(CParser("union U2 switch(int32) { default: float f; case 1: int32 i; case 2: int64 j; default: double d; };").Parse(), CCompileException);
}
TEST_F(CParserUnionTest, VariableDeclaration)
{
// <union_identifier> <decl_identifier>; --> union variable declaration
EXPECT_TRUE(CParser("struct S{union U4 switch(int32){case 10: int32 i;}; U4 u4Value;};").Parse().Root()->Find("S::u4Value"));
// union <union_identifier> <decl_identifier>; --> union variable declaration
EXPECT_TRUE(CParser("struct S{union U6 switch(int32){case 10: int32 i;}; union U6 u6Value;};").Parse().Root()->Find("S::u6Value"));
}
TEST_F(CParserUnionTest, IntegralSwitchType)
{
// Use any type of integral value in case
EXPECT_TRUE(CParser("union U2 switch(boolean) { case true: int32 i; case false: int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(int8) { case 10: int32 i; case -10: int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(int16) { case 10: int32 i; case -10: int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(int32) { case 10: int32 i; case -10: int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(int64) { case 10: int32 i; case -10: int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(uint8) { case 10: int32 i; case 20: int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(uint16) { case 10: int32 i; case 20: int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(uint32) { case 10: int32 i; case 20: int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(uint64) { case 10: int32 i; case 20: int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(char) { case 'a': int32 i; case 'b': int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(char16) { case u'a': int32 i; case u'b': int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(char32) { case U'a': int32 i; case U'A': int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("union U2 switch(wchar) { case L'a': int32 i; case L'b': int64 j; };").Parse().Root()->Find("U2"));
// Use other type of value in case
EXPECT_THROW(CParser("union U2 switch(float) { case 0.0: int32 i; case 1.1: int64 j; };").Parse(), CCompileException);
}
TEST_F(CParserUnionTest, IntegralTypeMixing)
{
// Use const values in case
EXPECT_TRUE(CParser("const int32 iVal1 = 10, iVal2 = 20; union U2 switch(int32) { case iVal1: int32 i; case iVal2: int64 j; };").Parse().Root()->Find("U2"));
// Use calculated const value in case
EXPECT_TRUE(CParser("const int32 iVal1 = 10 + 10, iVal2 = 30; union U2 switch(int32) { case iVal1: int32 i; case iVal2: int64 j; };").Parse().Root()->Find("U2"));
// Use calculated value in case
EXPECT_TRUE(CParser("const int32 iVal1 = 10; union U2 switch(int32) { case iVal1: int32 i; case iVal1 + 1: int64 j; };").Parse().Root()->Find("U2"));
// Use declaration of const values following the switch case
EXPECT_TRUE(CParser("union U2 switch(int32) { case iVal1: int32 i; case iVal2: int64 j; }; const int32 iVal1 = 10, iVal2 = 20;").Parse().Root()->Find("U2"));
// Use typedef value in case
EXPECT_TRUE(CParser("typedef int32 TCaseInt; const TCaseInt iVal1 = 10, iVal2 = 20; union U2 switch(TCaseInt) { case iVal1: int32 i; case iVal2: int64 j; };").Parse().Root()->Find("U2"));
EXPECT_TRUE(CParser("typedef int32 TCaseInt; const int32 iVal1 = 10, iVal2 = 20; union U2 switch(TCaseInt) { case iVal1: int32 i; case iVal2: int64 j; };").Parse().Root()->Find("U2"));
// Use mixed const values in case
EXPECT_TRUE(CParser("const int8 iVal1 = 10; const int64 iVal2 = 20; union U2 switch(int32) { case iVal1: int32 i; case iVal2: int64 j; };").Parse().Root()->Find("U2"));
}
TEST_F(CParserUnionTest, EnumSwitchtype)
{
// Use enum values in case
EXPECT_TRUE(CParser("enum EValues {ten, twenty}; union U2 switch(EValues) { case ten: int32 i; case twenty: int64 j; };").Parse().Root()->Find("U2"));
// Use definition of enum following the switch case
EXPECT_THROW(CParser("union U2 switch(EValues) { case ten: int32 i; case twenty: int64 j; }; enum EValues {ten, twenty};").Parse(), CCompileException);
EXPECT_TRUE(CParser("enum EValues; union U2 switch(EValues) { case ten: int32 i; case twenty: int64 j; }; enum EValues {ten, twenty};").Parse().Root()->Find("U2"));
}
TEST_F(CParserUnionTest, DuplicateCaseLabel)
{
// Use values in case
EXPECT_THROW(CParser("union U2 switch(int32) { case 10: int32 i; case 10: int64 j; };").Parse(), CCompileException);
// Use const values in case
EXPECT_THROW(CParser("const int32 iVal1 = 10, iVal2 = 10; union U2 switch(int32) { case iVal1: int32 i; case iVal2: int64 j; };").Parse(), CCompileException);
// Use enum values in case
EXPECT_THROW(CParser("enum EValues {ten, twenty}; union U2 switch(EValues) { case ten: int32 i; case ten: int64 j; };").Parse(), CCompileException);
// Duplicate default
EXPECT_THROW(CParser("union U2 switch(int32) { default: double d; case 10: int32 i; case 20: int64 j; default: float f; };").Parse(), CCompileException);
}
TEST_F(CParserUnionTest, DuplicateVariables)
{
EXPECT_THROW(CParser("union U2 switch(int32) { case 10: int32 i; case 20: int64 j; case 30: int32 i; };").Parse(), CCompileException);
EXPECT_THROW(CParser("union U2 switch(int32) { case 10: int32 i; case 20: int64 j; case 30: int64 i; };").Parse(), CCompileException);
EXPECT_THROW(CParser("union U2 switch(int32) { case 10: int32 i; case 20: int64 j; default: int32 i; };").Parse(), CCompileException);
EXPECT_THROW(CParser("union U2 switch(int32) { case 10: int32 i; case 20: int64 j; default: int64 i; };").Parse(), CCompileException);
}
TEST_F(CParserUnionTest, MemberSwitchLabelType)
{
// Use const value in switch label
EXPECT_THROW(CParser("const int32 iVal = 10; union U2 switch(iVal) { case 10: int32 i; case 20: int64 j; };").Parse(), CCompileException);
// Use value in switch label
EXPECT_TRUE(CParser("struct S {int32 iVal = 10; union U2 switch(iVal) { case 10: int32 i; case 20: int64 j; } u2Var;};").Parse().Root()->Find("S::u2Var"));
// Use succeeding declared value in switch label
EXPECT_TRUE(CParser("struct S {union U2 switch(iVal) { case 10: int32 i; case 20: int64 j; }u2Var; int32 iVal = 10;};").Parse().Root()->Find("S::u2Var"));
// Use enum values in switch label
EXPECT_TRUE(CParser("struct S {enum EValues {ten, twenty}; union U2 switch(EValues) { case ten: int32 i; case twenty: int64 j; } u2Var;};").Parse().Root()->Find("S::u2Var"));
}
TEST_F(CParserUnionTest, UnnamedUnionDefinition)
{
// Declaration of unnamed union at global scope is not allowed.
// Use type in switch label
EXPECT_THROW(CParser(R"code(
union switch(int32)
{
case 10:
int32 i;
case 20:
int64 j;
} u1;
};)code").Parse(), CCompileException);
// Declaration of unnamed union within struct.
// Use type in switch label
EXPECT_TRUE(CParser(R"code(
struct S
{
union switch(int32)
{
case 10:
int32 i;
case 20:
int64 j;
} u2;
};)code").Parse().Root()->Find("S::u2"));
// Use value in switch label
EXPECT_TRUE(CParser(R"code(
struct S
{
int32 iVal = 10;
union switch(iVal)
{
case 10:
int32 i;
case 20:
int64 j;
} u2;
};)code").Parse().Root()->Find("S::u2"));
}
TEST_F(CParserUnionTest, AnonymousUnionDeclaration)
{
// Declaration of unnamed union within struct.
// Use type in switch label
CParser parser1(R"code(
struct S
{
union switch(int32)
{
case 10:
int32 i;
case 20:
int64 j;
};
};)code");
EXPECT_NO_THROW(parser1.Parse());
EXPECT_TRUE(parser1.Root()->Find("S::i"));
EXPECT_TRUE(parser1.Root()->Find("S::j"));
// Use value in switch label
CParser parser2(R"code(
struct S
{
int32 iVal = 10;
union switch(iVal)
{
case 10:
int32 i;
case 20:
int64 j;
};
};)code");
EXPECT_NO_THROW(parser2.Parse());
EXPECT_TRUE(parser2.Root()->Find("S::iVal"));
EXPECT_TRUE(parser2.Root()->Find("S::i"));
EXPECT_TRUE(parser2.Root()->Find("S::j"));
}
// Disable this struct until support for anonymous declarations are implemented: PBI #397894
TEST_F(CParserUnionTest, DISABLED_AnonymousDeclaration)
{
// Use type in switch label on root level
EXPECT_THROW(CParser("union switch(int32) { case 10: int32 i; case 20: int64 j; };").Parse(), CCompileException);
// Use type in switch label
EXPECT_TRUE(CParser("struct S {union switch(int32) { case 10: int32 i; case 20: int64 j; };};").Parse().Root()->Find("S::i"));
// Use type in switch label
char szCodeTypeLabel[] = R"code(
struct S
{
union switch (int32)
{
case 10:
union switch (int32)
{
case 1: int32 a;
case 2: int32 b;
case 3: int32 c;
};
case 20:
struct
{
int32 d;
int32 e;
int32 f;
};
case 30:
int32 g;
};
};
)code";
CParser parserTypeLabel(szCodeTypeLabel);
parserTypeLabel.Parse();
EXPECT_TRUE(parserTypeLabel.Root()->Find("S"));
EXPECT_TRUE(parserTypeLabel.Root()->Find("S::a"));
EXPECT_TRUE(parserTypeLabel.Root()->Find("S::b"));
EXPECT_TRUE(parserTypeLabel.Root()->Find("S::c"));
EXPECT_TRUE(parserTypeLabel.Root()->Find("S::d"));
EXPECT_TRUE(parserTypeLabel.Root()->Find("S::e"));
EXPECT_TRUE(parserTypeLabel.Root()->Find("S::f"));
EXPECT_TRUE(parserTypeLabel.Root()->Find("S::g"));
// Use value in switch label
EXPECT_TRUE(CParser("struct S {int32 iVal = 10; union switch(iVal) { case 10: int32 i; case 20: int64 j; };};").Parse().Root()->Find("S::i"));
EXPECT_TRUE(CParser("struct S {union switch(iVal) { case 10: int32 i; case 20: int64 j; }; int32 iVal = 10;};").Parse().Root()->Find("S::i"));
EXPECT_THROW(CParser("const int32 iVal = 10; struct S {union switch(iVal) { case 10: int32 i; case 20: int64 j; };};").Parse(), CCompileException);
// Use value in switch label
char szCodeVarLabel[] = R"code(
struct S
{
int32 iVal = 10;
int32 iVal2 = 1;
union switch (iVal)
{
case 10:
union switch (iVal2)
{
case 1: int32 a;
case 2: int32 b;
case 3: int32 c;
};
case 20:
struct
{
int32 d;
int32 e;
int32 f;
};
case 30:
int32 g;
};
};
struct S2
{
S sValue;
};
)code";
CParser parserVarLabel(szCodeVarLabel);
parserVarLabel.Parse();
EXPECT_TRUE(parserVarLabel.Root()->Find("S"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S::iVal"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S::iVal2"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S::a"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S::b"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S::c"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S::d"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S::e"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S::f"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S::g"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S2::sValue"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S2::sValue.iVal"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S2::sValue.iVal2"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S2::sValue.a"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S2::sValue.b"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S2::sValue.c"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S2::sValue.d"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S2::sValue.e"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S2::sValue.f"));
EXPECT_TRUE(parserVarLabel.Root()->Find("S2::sValue.g"));
}
/*
Test:
- Union with nested anonymous/named/assigned struct/union in case - not allowed following C++ rules
- Struct with anonymous union with/without switch variable - allowed
- Struct with multiple anonymous unions with/without switch variable - allowed
- Struct with anonymous struct with declaration - allowed
- Struct with anonymous union with/without switch variable with declaration - allowed
- Struct with two union definition, second using the declaration of the first definition in case statement - allowed
*/
///**
// * @brief Union with complex type as a variable.
// */
union UComplex1
{
~UComplex1() {}
int32_t i; ///< Simple type
struct SComplex
{
sdv::u8string ss1; ///< String var
int8_t i8; ///< int var
} sComplex; ///< Complex type
sdv::u8string ss2; ///< String type
};
// ///**
// // * @brief Union with complex type as a variable.
// // */
// union UComplex2
// {
// ~UComplex2() {}
// int32_t i; ///< Simple type
// struct
// {
// sdv::u8string ss1; ///< String var
// int8_t i8; ///< int var
// }; ///< Complex type
// sdv::u8string ss2; ///< String type
// };

View File

@@ -0,0 +1,795 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/declaration_entity.h"
#include "../../../sdv_executables/sdv_idl_compiler/entities/variable_entity.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/constvariant.inl"
#include "../../../sdv_executables/sdv_idl_compiler/entities/entity_value.h"
using CParserVarAssignmentTest = CParserTest;
TEST_F(CParserVarAssignmentTest, ParsingVarAssignment)
{
EXPECT_TRUE(CParser("struct S {long hello = 10 * 10;};").Parse().Root()->Find("S::hello"));
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentOutOfScope)
{
EXPECT_THROW(CParser("long hello = 10 * 10;").Parse(), CCompileException);
EXPECT_THROW(CParser("module m {long hello = 10 * 10;};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingConstMissingSemiColon)
{
EXPECT_THROW(CParser("struct S {long hello = 10 * 10};};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingConstNoAssignmentOperator)
{
EXPECT_TRUE(CParser("struct S {long hello;};").Parse().Root()->Find("S::hello"));
}
TEST_F(CParserVarAssignmentTest, ParsingVarArray)
{
EXPECT_EQ(CParser("struct S {long rglHello[2] = {1, 2};};").Parse().Root()->Find<CVariableEntity>("S::rglHello")->ValueRef()->Get<CArrayValueNode>()->GetSize(), 2);
EXPECT_THROW(CParser("struct S {long rglHello[] = {1, 2};};").Parse(), CCompileException);
EXPECT_EQ(CParser("struct S {const long rglHello[2] = {1, 2}; long rglHello2[rglHello[1]] = {rglHello[0], rglHello[1]};};").
Parse().Root()->Find<CVariableEntity>("S::rglHello2")->ValueRef()->Get<CArrayValueNode>()->GetSize(), 2);
EXPECT_THROW(CParser("struct S {long rglHello[2] = {1, 2, 3};};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {long rglHello[2] = {1};};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {long rglHello[2] = {1, 2;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {long rglHello[2] = 1, 2};};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingMultipleVarAssignments)
{
EXPECT_TRUE(CParser("struct S {int8 iHello = 10, iHello2 = 20;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = 10, iHello2 = 20;};").Parse().Root()->Find("S::iHello2"));
EXPECT_EQ(CParser("struct S {const long rglHello[2] = {1, 2}, rglHello2[rglHello[1]] = {rglHello[0], rglHello[1]};};").
Parse().Root()->Find<CVariableEntity>("S::rglHello2")->ValueRef()->Get<CArrayValueNode>()->GetSize(), 2);
EXPECT_THROW(CParser("struct S {int8 iHello = 10, int iHello2 = 20;};").Parse(), CCompileException);
EXPECT_TRUE(CParser("struct S {int8 iHello = 10, iHello2;};").Parse().Root()->Find("S::iHello2"));
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentInt8)
{
EXPECT_TRUE(CParser("struct S {int8 iHello = 10;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = 10l;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = 10ll;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = 'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = L'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = u'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = U'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = '\\0\\0\\0A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = true;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = false;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = TRUE;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = FALSE;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = nullptr;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = NULL;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = -128;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 iHello = +127;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int8 rgiHello[2] = {+127, -127};};").Parse().Root()->Find("S::rgiHello"));
EXPECT_THROW(CParser("struct S {int8 iHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int8 iHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int8 iHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int8 iHello = 10.0d;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int8 iHello = 128;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int8 iHello = L'\\u20ac';};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int8 uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentInt16)
{
EXPECT_TRUE(CParser("struct S {int16 iHello = 10;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = 10l;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = 10ll;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = 'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = L'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = u'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = U'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = '\\0\\0BA';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = true;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = false;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = TRUE;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = FALSE;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = nullptr;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = NULL;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = -32768;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 iHello = +32767;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int16 rgiHello[2] = {+32767, -32767};};").Parse().Root()->Find("S::rgiHello"));
EXPECT_THROW(CParser("struct S {int16 iHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int16 iHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int16 iHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int16 iHello = 10.0d;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int16 iHello = 32768;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int16 iHello = u'\\U00010437';};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int16 uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentInt32)
{
EXPECT_TRUE(CParser("struct S {int32 iHello = 10;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = 10l;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = 10ll;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = 'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = L'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = u'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = U'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = 'DCBA';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = true;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = false;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = TRUE;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = FALSE;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = nullptr;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = NULL;};").Parse().Root()->Find("S::iHello"));
// NOTE: The value -2147483648 would still fit in an integer. The C++-parsing, however, sees the minus operator not as part
// of the number and therefore does a calculation of "unary minus" on number "2147483648", which doesn't fit in the 32-bits
// any more.
EXPECT_TRUE(CParser("struct S {int32 iHello = -2147483647;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = -2147483648ll;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 iHello = +2147483647;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int32 rgiHello[2] = {+2147483647, -2147483647};};").Parse().Root()->Find("S::rgiHello"));
EXPECT_THROW(CParser("struct S {int32 iHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int32 iHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int32 iHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int32 iHello = 10.0d;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int32 iHello = 2147483648;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int32 uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentInt64)
{
EXPECT_TRUE(CParser("struct S {int64 iHello = 10;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = 10l;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = 10ll;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = 'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = L'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = u'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = U'A';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = 'DCBA';};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = true;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = false;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = TRUE;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = FALSE;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = nullptr;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = NULL;};").Parse().Root()->Find("S::iHello"));
// NOTE: The value -9223372036854775808 would still fit in an integer. The C++-parsing, however, sees the minus operator not
// as part of the number and therefore does a calculation of "unary minus" on number "9223372036854775808", which doesn't fit
// in the 64-bits any more.
EXPECT_THROW(CParser("struct S {int64 iHello = -9223372036854775808ll;};").Parse(), CCompileException);
EXPECT_TRUE(CParser("struct S {int64 iHello = -9223372036854775807ll - 1;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 iHello = +9223372036854775807ll;};").Parse().Root()->Find("S::iHello"));
EXPECT_TRUE(CParser("struct S {int64 rgiHello[2] = {+9223372036854775807ll, -9223372036854775807ll};};").Parse().Root()->Find("S::rgiHello"));
EXPECT_THROW(CParser("struct S {int64 iHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int64 iHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int64 iHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int64 iHello = 10.0d;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int64 iHello = 9223372036854775808ll;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {int64 uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentUInt8)
{
EXPECT_TRUE(CParser("struct S {uint8 uiHello = 10;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = 10l;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = 10ll;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = 'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = L'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = u'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = U'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = '\\0\\0\\0A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = true;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = false;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = TRUE;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = FALSE;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = nullptr;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = NULL;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = +0;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = -0;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 uiHello = +255;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint8 rguiHello[2] = {0, +255};};").Parse().Root()->Find("S::rguiHello"));
EXPECT_THROW(CParser("struct S {uint8 uiHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint8 uiHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint8 uiHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint8 uiHello = 10.0d;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint8 uiHello = 256;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint8 uiHello = L'\\u20ac';};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint8 uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentUInt16)
{
EXPECT_TRUE(CParser("struct S {uint16 uiHello = 10;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = 10l;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = 10ll;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = 'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = L'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = u'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = U'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = '\\0\\0BA';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = true;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = false;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = TRUE;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = FALSE;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = nullptr;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = NULL;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = +0;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = -0;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 uiHello = +65535;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint16 rguiHello[2] = {0, +65535};};").Parse().Root()->Find("S::rguiHello"));
EXPECT_THROW(CParser("struct S {uint16 uiHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint16 uiHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint16 uiHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint16 uiHello = 10.0d;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint16 uiHello = 65536;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint16 uiHello = u'\\U00010437';};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint16 uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentUInt32)
{
EXPECT_TRUE(CParser("struct S {uint32 uiHello = 10;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = 10l;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = 10ll;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = 'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = L'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = u'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = U'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = 'DCBA';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = true;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = false;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = TRUE;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = FALSE;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = nullptr;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = NULL;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = +0;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = -0;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 uiHello = +4294967295;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint32 rguiHello[2] = {0, +4294967295};};").Parse().Root()->Find("S::rguiHello"));
EXPECT_THROW(CParser("struct S {uint32 uiHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint32 uiHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint32 uiHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint32 uiHello = 10.0d;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint32 uiHello = 4294967296;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint32 uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentUInt64)
{
EXPECT_TRUE(CParser("struct S {uint64 uiHello = 10;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = 10l;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = 10ll;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = 'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = L'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = u'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = U'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = 'DCBA';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = true;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = false;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = TRUE;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = FALSE;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = nullptr;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = NULL;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = +0;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = -0;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 uiHello = +18446744073709551615ull;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {uint64 rguiHello[2] = {0, +18446744073709551615ull};};").Parse().Root()->Find("S::rguiHello"));
EXPECT_THROW(CParser("struct S {uint64 uiHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint64 uiHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint64 uiHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint64 uiHello = 10.0d;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint64 uiHello = 18446744073709551616ull;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {uint64 uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingConstAssignmenChar)
{
EXPECT_TRUE(CParser("struct S {char cHello = 10;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = 10l;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = 10ll;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = 'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = L'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = u'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = U'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = '\\0\\0\\0A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = true;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = false;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = TRUE;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = FALSE;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = nullptr;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = NULL;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = -128;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char cHello = +127;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char rgcHello[2] = {-127, +127};};").Parse().Root()->Find("S::rgcHello"));
EXPECT_THROW(CParser("struct S {char cHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char cHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char cHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char cHello = 10.0d;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char cHello = 128;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char cHello = L'\\u20ac';};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentChar16)
{
EXPECT_TRUE(CParser("struct S {char16 cHello = 10;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = 10l;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = 10ll;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = 'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = L'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = u'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = U'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = '\\0\\0BA';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = true;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = false;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = TRUE;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = FALSE;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = nullptr;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = NULL;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = +0;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = -0;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 cHello = +65535;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char16 rgcHello[2] = {0, +65535};};").Parse().Root()->Find("S::rgcHello"));
EXPECT_THROW(CParser("struct S {char16 cHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char16 cHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char16 cHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char16 cHello = 10.0d;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char16 cHello = 65536;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char16 cHello = u'\\U00010437';};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char16 uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentChar32)
{
EXPECT_TRUE(CParser("struct S {char32 cHello = 10;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = 10l;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = 10ll;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = 'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = L'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = u'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = U'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = 'DCBA';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = true;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = false;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = TRUE;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = FALSE;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = nullptr;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = NULL;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = +0;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 cHello = -0;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {char32 rgcHello[2] = {0, +4294967295};};").Parse().Root()->Find("S::rgcHello"));
EXPECT_THROW(CParser("struct S {char32 cHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char32 cHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char32 cHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char32 cHello = 10.0d;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char32 cHello = 4294967296;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {char32 uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentWChar)
{
EXPECT_TRUE(CParser("struct S {wchar cHello = 10;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = 10l;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = 10ll;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = 'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = L'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = u'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = U'A';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = '\\0\\0BA';};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = true;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = false;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = TRUE;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = FALSE;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = nullptr;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = NULL;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = +0;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = -0;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar cHello = +65535;};").Parse().Root()->Find("S::cHello"));
EXPECT_TRUE(CParser("struct S {wchar rgcHello[2] = {0, +65535};};").Parse().Root()->Find("S::rgcHello"));
EXPECT_THROW(CParser("struct S {wchar cHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wchar cHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wchar cHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wchar cHello = 10.0d;};").Parse(), CCompileException);
#ifdef _MSC_VER
EXPECT_THROW(CParser("struct S {wchar cHello = 65536;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wchar cHello = u'\\U00010437';};").Parse(), CCompileException);
#else
EXPECT_THROW(CParser("struct S {wchar cHello = 4294967296;};").Parse(), CCompileException);
#endif
EXPECT_THROW(CParser("struct S {wchar uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentOctet)
{
EXPECT_TRUE(CParser("struct S {octet uiHello = 10;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = 10l;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = 10ll;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = 'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = L'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = u'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = U'A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = '\\0\\0\\0A';};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = true;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = false;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = TRUE;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = FALSE;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = nullptr;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = NULL;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = +0;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = -0;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet uiHello = +255;};").Parse().Root()->Find("S::uiHello"));
EXPECT_TRUE(CParser("struct S {octet rguiHello[2] = {0, +255};};").Parse().Root()->Find("S::rguiHello"));
EXPECT_THROW(CParser("struct S {octet uiHello = 10.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {octet uiHello = 10.0f;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {octet uiHello = 10.0l;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {octet uiHello = 10.0d;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {octet uiHello = 256;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {octet uiHello = L'\\u20ac';};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {octet uiHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentFloat)
{
EXPECT_TRUE(CParser("struct S {float fHello = 111.11;};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = -2.22;};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = 0X1.BC70A3D70A3D7P+6;};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = .18973e+39;};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = 10ull;};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = 'A';};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = L'A';};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = u'A';};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = U'A';};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = '\\0\\0\\0A';};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = true;};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = false;};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = TRUE;};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = FALSE;};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = nullptr;};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = NULL;};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser((std::string("struct S {float fHello = ") + std::to_string(std::numeric_limits<float>::min()) + ";};").c_str()).Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser((std::string("struct S {float fHello = ") + std::to_string(std::numeric_limits<float>::max()) + ";};").c_str()).Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser((std::string("struct S {float fHello = ") + std::to_string(std::numeric_limits<float>::lowest()) + ";};").c_str()).Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float fHello = 10.0d;};").Parse().Root()->Find("S::fHello"));
EXPECT_TRUE(CParser("struct S {float rgfHello[2] = {10.0d, 20.0d};};").Parse().Root()->Find("S::rgfHello"));
EXPECT_THROW(CParser("struct S {float fHello = 3.40283e+38;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {float fHello = -3.40283e+38;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {float fHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentDouble)
{
EXPECT_TRUE(CParser("struct S {double ldHello = 111.11;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = -2.22;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = 0X1.BC70A3D70A3D7P+6;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = .18973e+39;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = 10ull;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = 'A';};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = L'A';};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = u'A';};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = U'A';};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = '\\0\\0\\0A';};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = true;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = false;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = TRUE;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = FALSE;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = nullptr;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = NULL;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser((std::string("struct S {double dHello = ") + std::to_string(std::numeric_limits<double>::min()) + ";};").c_str()).Parse().Root()->Find("S::dHello"));
EXPECT_TRUE(CParser((std::string("struct S {double dHello = ") + std::to_string(std::numeric_limits<double>::max()) + ";};").c_str()).Parse().Root()->Find("S::dHello"));
EXPECT_TRUE(CParser((std::string("struct S {double dHello = ") + std::to_string(std::numeric_limits<double>::lowest()) + ";};").c_str()).Parse().Root()->Find("S::dHello"));
EXPECT_TRUE(CParser("struct S {double ldHello = 10.0d;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {double rgldHello[2] = {10.0d, 20.0d};};").Parse().Root()->Find("S::rgldHello"));
EXPECT_THROW(CParser("struct S {double ldHello = 1.7977e+308;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {double ldHello = -1.7977e+308;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {double ldHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentLongDouble)
{
EXPECT_TRUE(CParser("struct S {long double ldHello = 111.11;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = -2.22;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = 0X1.BC70A3D70A3D7P+6;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = .18973e+39;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = 10ull;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = 'A';};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = L'A';};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = u'A';};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = U'A';};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = '\\0\\0\\0A';};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = true;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = false;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = TRUE;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = FALSE;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = nullptr;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = NULL;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser((std::string("struct S {long double ldHello = ") + std::to_string(std::numeric_limits<long double>::min()) + ";};").c_str()).Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser((std::string("struct S {long double ldHello = ") + std::to_string(std::numeric_limits<long double>::max()) + ";};").c_str()).Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser((std::string("struct S {long double ldHello = ") + std::to_string(std::numeric_limits<long double>::lowest()) + ";};").c_str()).Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double ldHello = 10.0d;};").Parse().Root()->Find("S::ldHello"));
EXPECT_TRUE(CParser("struct S {long double rgldHello[2] = {10.0d, 20.0d};};").Parse().Root()->Find("S::rgldHello"));
EXPECT_THROW(CParser("struct S {long double ldHello = 1.18974e+4932;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {long double ldHello = -1.18974e+4932;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {long double ldHello = u8\"\\u20ac\";};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentFixed)
{
EXPECT_TRUE(CParser("struct S {fixed fixHello = 111.11d;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = -2.22D;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = 0X1.BC70A3D70A3D7P+6;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = 10ull;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = 'A';};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = L'A';};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = u'A';};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = U'A';};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = '\\0\\0\\0A';};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = true;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = false;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = TRUE;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = FALSE;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = nullptr;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = NULL;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = -2147483647;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = 2147483648;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = 0.0000000004656612873077392578125d;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed fixHello = 10.0d;};").Parse().Root()->Find("S::fixHello"));
EXPECT_TRUE(CParser("struct S {fixed rgfixHello[2] = {10.0d, 20.0d};};").Parse().Root()->Find("S::rgfixHello"));
EXPECT_THROW(CParser("struct S {fixed fHello = 0.2147484000e+10;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {fixed fHello = -0.2147484000e+10;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {fixed fHello = u8\"\\u20ac\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {fixed fixHello = .18973e+39;};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentBoolean)
{
EXPECT_TRUE(CParser("struct S {boolean bHello = true;};").Parse().Root()->Find("S::bHello"));
EXPECT_TRUE(CParser("struct S {boolean bHello = false;};").Parse().Root()->Find("S::bHello"));
EXPECT_TRUE(CParser("struct S {boolean bHello = TRUE;};").Parse().Root()->Find("S::bHello"));
EXPECT_TRUE(CParser("struct S {boolean bHello = FALSE;};").Parse().Root()->Find("S::bHello"));
EXPECT_TRUE(CParser("struct S {boolean bHello = 1;};").Parse().Root()->Find("S::bHello"));
EXPECT_TRUE(CParser("struct S {boolean bHello = 0;};").Parse().Root()->Find("S::bHello"));
EXPECT_TRUE(CParser("struct S {boolean bHello = '\\1';};").Parse().Root()->Find("S::bHello"));
EXPECT_TRUE(CParser("struct S {boolean bHello = '\\0\\0\\0\\1';};").Parse().Root()->Find("S::bHello"));
EXPECT_TRUE(CParser("struct S {boolean bHello = -1;};").Parse().Root()->Find("S::bHello"));
EXPECT_TRUE(CParser("struct S {boolean bHello = 2;};").Parse().Root()->Find("S::bHello"));
EXPECT_TRUE(CParser("struct S {boolean bHello = 1.0;};").Parse().Root()->Find("S::bHello"));
EXPECT_TRUE(CParser("struct S {boolean rgbHello[2] = {1.0, 2.0};};").Parse().Root()->Find("S::rgbHello"));
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentString)
{
EXPECT_TRUE(CParser("struct S {string ssHello = \"hello\";};").Parse().Root()->Find("S::ssHello"));
EXPECT_TRUE(CParser("struct S {string ssHello = \"hello\" \"hello2\";};").Parse().Root()->Find("S::ssHello"));
EXPECT_TRUE(CParser("struct S {string rgssHello[2] = {\"hello\", \"hello2\" \"hello3\"};};").Parse().Root()->Find("S::rgssHello"));
EXPECT_THROW(CParser("struct S {string ssHello = u8\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {string ssHello = u\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {string ssHello = U\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {string ssHello = L\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {string ssHello = \"hello\" u8\"hello2\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {string ssHello = true;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {string ssHello = 1;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {string ssHello = 1.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {string ssHello = 'A';};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {string ssHello = nullptr;};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentUtf8String)
{
EXPECT_TRUE(CParser("struct S {u8string ssHello = u8\"hello\";};").Parse().Root()->Find("S::ssHello"));
EXPECT_TRUE(CParser("struct S {u8string ssHello = u8\"hello\" u8\"hello2\";};").Parse().Root()->Find("S::ssHello"));
EXPECT_TRUE(CParser("struct S {u8string rgssHello[2] = {u8\"hello\", u8\"hello2\" u8\"hello3\"};};").Parse().Root()->Find("S::rgssHello"));
EXPECT_THROW(CParser("struct S {u8string ssHello = \"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u8string ssHello = u\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u8string ssHello = U\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u8string ssHello = L\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u8string ssHello = u8\"hello\" \"hello2\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u8string ssHello = true;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u8string ssHello = 1;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u8string ssHello = 1.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u8string ssHello = 'A';};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u8string ssHello = nullptr;};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentUtf16String)
{
EXPECT_TRUE(CParser("struct S {u16string ssHello = u\"hello\";};").Parse().Root()->Find("S::ssHello"));
EXPECT_TRUE(CParser("struct S {u16string ssHello = u\"hello\" u\"hello2\";};").Parse().Root()->Find("S::ssHello"));
EXPECT_TRUE(CParser("struct S {u16string rgssHello[2] = {u\"hello\", u\"hello2\" u\"hello3\"};};").Parse().Root()->Find("S::rgssHello"));
EXPECT_THROW(CParser("struct S {u16string ssHello = \"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u16string ssHello = u8\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u16string ssHello = U\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u16string ssHello = L\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u16string ssHello = u\"hello\" \"hello2\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u16string ssHello = true;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u16string ssHello = 1;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u16string ssHello = 1.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u16string ssHello = 'A';};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u16string ssHello = nullptr;};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentUtf32String)
{
EXPECT_TRUE(CParser("struct S {u32string ssHello = U\"hello\";};").Parse().Root()->Find("S::ssHello"));
EXPECT_TRUE(CParser("struct S {u32string ssHello = U\"hello\" U\"hello2\";};").Parse().Root()->Find("S::ssHello"));
EXPECT_TRUE(CParser("struct S {u32string rgssHello[2] = {U\"hello\", U\"hello2\" U\"hello3\"};};").Parse().Root()->Find("S::rgssHello"));
EXPECT_THROW(CParser("struct S {u32string ssHello = \"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u32string ssHello = u8\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u32string ssHello = u\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u32string ssHello = L\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u32string ssHello = U\"hello\" \"hello2\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u32string ssHello = true;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u32string ssHello = 1;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u32string ssHello = 1.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u32string ssHello = 'A';};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {u32string ssHello = nullptr;};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentWideString)
{
EXPECT_TRUE(CParser("struct S {wstring ssHello = L\"hello\";};").Parse().Root()->Find("S::ssHello"));
EXPECT_TRUE(CParser("struct S {wstring ssHello = L\"hello\" L\"hello2\";};").Parse().Root()->Find("S::ssHello"));
EXPECT_TRUE(CParser("struct S {wstring rgssHello[2] = {L\"hello\", L\"hello2\" L\"hello3\"};};").Parse().Root()->Find("S::rgssHello"));
EXPECT_THROW(CParser("struct S {wstring ssHello = \"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wstring ssHello = u8\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wstring ssHello = u\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wstring ssHello = U\"hello\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wstring ssHello = L\"hello\" \"hello2\";};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wstring ssHello = true;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wstring ssHello = 1;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wstring ssHello = 1.0;};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wstring ssHello = 'A';};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {wstring ssHello = nullptr;};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentNumericIdentifiers)
{
EXPECT_TRUE(CParser("struct S {const int32 iHello1 = 100;\nint32 iHello2 = iHello1;};").Parse().Root()->Find("S::iHello2"));
EXPECT_TRUE(CParser("struct S {const int32 iHello1 = 100;\nconst int32 iHello2 = iHello1; int64 rgiHello3[2] = {iHello1, iHello2};};").Parse().Root()->Find("S::rgiHello3"));
EXPECT_TRUE(CParser("module TEST {const int32 iHello1 = 100;};\nstruct S {int32 iHello2 = TEST::iHello1;};").Parse().Root()->Find("S::iHello2"));
EXPECT_TRUE(CParser("module TEST {const int32 iHello1 = 100;};\nstruct S {int32 iHello2 = ::TEST::iHello1;};").Parse().Root()->Find("S::iHello2"));
EXPECT_TRUE(CParser("module TEST {const int32 iHello1 = 100;};\nmodule TEST2{struct S {int32 iHello2 = TEST::iHello1;};};").Parse().Root()->Find("TEST2::S::iHello2"));
EXPECT_TRUE(CParser("module TEST {const int32 iHello1 = 100;};\nmodule TEST2{struct S {int32 iHello2 = ::TEST::iHello1;};};").Parse().Root()->Find("TEST2::S::iHello2"));
EXPECT_TRUE(CParser("module TEST {const int32 iHello1 = 100; struct S {int32 iHello2 = TEST::iHello1;};};").Parse().Root()->Find("TEST::S::iHello2"));
EXPECT_TRUE(CParser("module TEST {const int32 iHello1 = 100; struct S {int32 iHello2 = iHello1;};};").Parse().Root()->Find("TEST::S::iHello2"));
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentStringIdentifiers)
{
EXPECT_TRUE(CParser("struct S {const wstring ssHello1 = L\"hello\";\nwstring ssHello2 = ssHello1;};").Parse().Root()->Find("S::ssHello2"));
EXPECT_TRUE(CParser("struct S {const wstring ssHello1 = L\"hello\";\nconst wstring ssHello2 = ssHello1; wstring rgssHello3[2] = {ssHello1, ssHello2};};").Parse().Root()->Find("S::rgssHello3"));
EXPECT_TRUE(CParser("module TEST {const wstring ssHello1 = L\"hello\";};\nstruct S {wstring ssHello2 = TEST::ssHello1;};").Parse().Root()->Find("S::ssHello2"));
EXPECT_TRUE(CParser("module TEST {const wstring ssHello1 = L\"hello\";};\nstruct S {wstring ssHello2 = ::TEST::ssHello1;};").Parse().Root()->Find("S::ssHello2"));
EXPECT_TRUE(CParser("module TEST {const wstring ssHello1 = L\"hello\";};\nmodule TEST2{struct S {wstring ssHello2 = TEST::ssHello1;};};").Parse().Root()->Find("TEST2::S::ssHello2"));
EXPECT_TRUE(CParser("module TEST {const wstring ssHello1 = L\"hello\";};\nmodule TEST2{struct S {wstring ssHello2 = ::TEST::ssHello1;};};").Parse().Root()->Find("TEST2::S::ssHello2"));
EXPECT_TRUE(CParser("module TEST {const wstring ssHello1 = L\"hello\"; struct S { wstring ssHello2 = TEST::ssHello1;};};").Parse().Root()->Find("TEST::S::ssHello2"));
EXPECT_TRUE(CParser("module TEST {const wstring ssHello1 = L\"hello\"; struct S { wstring ssHello2 = ssHello1;};};").Parse().Root()->Find("TEST::S::ssHello2"));
EXPECT_THROW(CParser("struct S {const wstring ssHello1 = L\"hello\";\nwstring ssHello2 = ssHello1 \"this doesn't work\";};};").Parse(), CCompileException);
EXPECT_THROW(CParser("struct S {const wstring ssHello1 = L\"hello\";\nwstring ssHello2 = \"this doesn't work\" ssHello1;};};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentOperatorsIntegral)
{
// Parenthesis while calculating
CParser parserParenthesis(R"code(struct S {
int32 a = 10;
int32 b = 5;
int32 c = b*b;
int64 e = 10;
int16 f = a * (c + e);
};)code");
EXPECT_NO_THROW(parserParenthesis.Parse());
const CVariableEntity* pParenthesisEntityResult = parserParenthesis.Root()->Find<CVariableEntity>("S::f");
ASSERT_NE(pParenthesisEntityResult, nullptr);
// Since 'f' is dynamic (based on variables), the result is 0.
EXPECT_EQ(pParenthesisEntityResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 0);
// Operators + - / * %
CParser parserArithmetic(R"code(
struct S {int64 f = 10 + 11 * 35 % 10 -2;};
)code");
EXPECT_NO_THROW(parserArithmetic.Parse());
const CVariableEntity* pArithmeticResult = parserArithmetic.Root()->Find<CVariableEntity>("S::f");
ASSERT_NE(pArithmeticResult, nullptr);
EXPECT_EQ(pArithmeticResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int32_t>(), 13);
// Operators << >> & | ~
CParser parserBitManipulation(R"code(
struct S {uint8 f = 2 << 2 | 7 >> 1 & (~ 120 & 7); };
)code");
EXPECT_NO_THROW(parserBitManipulation.Parse());
const CVariableEntity* pBitManipulationResult = parserBitManipulation.Root()->Find<CVariableEntity>("S::f");
ASSERT_NE(pBitManipulationResult, nullptr);
EXPECT_EQ(pBitManipulationResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<int64_t>(), 11);
// Operators && || < > <= >= == !=
CParser parserCondition(R"code(struct S {
boolean a = (20 || 10 && 1) < 2;
boolean b = 50 + 7 >= 57;
boolean c = 50 + 8 > 57;
boolean d = 50 + 7 <= 57;
boolean e = 10 != 0;
int32 f = a + b + c + d + e;
};)code");
EXPECT_NO_THROW(parserCondition.Parse());
const CVariableEntity* pConditionResult = parserCondition.Root()->Find<CVariableEntity>("S::f");
ASSERT_NE(pConditionResult, nullptr);
// Since 'f' is dynamic (based on variables), the result is 0.
EXPECT_EQ(pConditionResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<uint8_t>(), 0);
// Div by zero /
EXPECT_THROW(CParser("struct S {long i = 0; struct S {unsigned long j = 10/i;};").Parse(), CCompileException);
// Div by zero %
EXPECT_THROW(CParser("struct S {long i = 0; struct S {unsigned long j = 10%i;};").Parse(), CCompileException);
}
TEST_F(CParserVarAssignmentTest, ParsingVarAssignmentOperatorsFloatingPoint)
{
// Parenthesis while calculating
CParser parserParenthesis(R"code(struct S {
double a = 10;
double b = 5;
double c = b*b;
double e = 10;
double f = a * (c + e);
};)code");
EXPECT_NO_THROW(parserParenthesis.Parse());
const CVariableEntity* pParenthesisEntityResult = parserParenthesis.Root()->Find<CVariableEntity>("S::f");
ASSERT_NE(pParenthesisEntityResult, nullptr);
// Since 'f' is dynamic (based on variables), the result is 0.0.
EXPECT_EQ(pParenthesisEntityResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<float>(), 0.0);
// Operators + - / * %
CParser parserArithmetic(R"code(
struct S {float f = 10 + 11 * 35 % 10 -2; };
)code");
EXPECT_NO_THROW(parserArithmetic.Parse());
const CVariableEntity* pArithmeticResult = parserArithmetic.Root()->Find<CVariableEntity>("S::f");
ASSERT_NE(pArithmeticResult, nullptr);
EXPECT_EQ(pArithmeticResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<long double>(), 13);
// Operators && || < > <= >= == !=
CParser parserCondition(R"code(struct S {
boolean a = (20.0 || 10.0 && 1.0) < 2.0;
boolean b = 50.0 + 7.0 >= 57.0;
boolean c = 50.0 + 8.0 > 57.0;
boolean d = 50.0 + 7.0 <= 57.0;
boolean e = 10.0 != 0.0;
int32 f = a + b + c + d + e;
};)code");
EXPECT_NO_THROW(parserCondition.Parse());
const CVariableEntity* pConditionResult = parserCondition.Root()->Find<CVariableEntity>("S::f");
ASSERT_NE(pConditionResult, nullptr);
// Since 'f' is dynamic (based on variables), the result is 0.
EXPECT_EQ(pConditionResult->ValueRef()->Get<CSimpleTypeValueNode>()->Variant().Get<uint8_t>(), 0.0);
// Div by zero /
EXPECT_THROW(CParser("struct S {float i = 0; struct S {long double j = 10/i;};").Parse(), CCompileException);
// Div by zero %
EXPECT_THROW(CParser("struct S {double i = 0; struct S {float j = 10%i;};").Parse(), CCompileException);
}
// Scoped names... relative to a parent....
// Missing type - okay
// Invalid type
// Scoped name
// Available
// Unavailable
// Wrong type
// Missing assignment operator - okay
// Expression
// With every possible type
// Missing expression - okay
// Expression type automatic conversion
// Expression type does not match
// Uses identifier within same module
// Uses identifier in parent/sub module
// Missing ';' - okay
// Additional data types
// Correct expression

View File

@@ -0,0 +1,777 @@
#include "includes.h"
#include "parser_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/preproc.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/macro.cpp"
#include "../../../sdv_executables/sdv_idl_compiler/parser.h"
#include "../../../sdv_executables/sdv_idl_compiler/exception.h"
#include <fstream>
using CPreprocTest = CParserTest;
TEST_F(CPreprocTest, PreprocessorUnknownDirective)
{
// Unknown preproc error
EXPECT_THROW(CParser(nullptr).LexicalCheck(), CCompileException);
EXPECT_THROW(CParser("#abc").LexicalCheck(), CCompileException);
}
TEST_F(CPreprocTest, PreprocessorWhitespace)
{
// Parse preprocessor with additional whitespace before
// Single preprocessing directive
EXPECT_TRUE(CParser(" #define TEST").LexicalCheck().GetEnvironment().Defined("TEST"));
EXPECT_TRUE(CParser(" # define TEST").LexicalCheck().GetEnvironment().Defined("TEST"));
EXPECT_TRUE(CParser("\t#\tdefine TEST").LexicalCheck().GetEnvironment().Defined("TEST"));
EXPECT_TRUE(CParser(" \n#define TEST").LexicalCheck().GetEnvironment().Defined("TEST"));
// Multiple preprocessing directives
EXPECT_TRUE(CParser(R"code(
# if defined HELLO
# define NO_TEST
# else
# define TEST
# endif)code").LexicalCheck().GetEnvironment().Defined("TEST"));
// Tests bug fix: #381248
// Verbatim block test
EXPECT_NO_THROW(CParser(R"code(#verbatim_begin
// ...
#verbatim_end)code").Parse());
EXPECT_NO_THROW(CParser(R"code( # verbatim_begin
// ...
# not valid text...
# verbatim_end)code").Parse());
}
TEST_F(CPreprocTest, PreprocessorMacroDefined)
{
// Parse preprocessor
EXPECT_TRUE(CParser("#define TEST").LexicalCheck().GetEnvironment().Defined("TEST"));
EXPECT_TRUE(CParser("#define TEST()").LexicalCheck().GetEnvironment().Defined("TEST"));
EXPECT_TRUE(CParser("#define TEST(a)").LexicalCheck().GetEnvironment().Defined("TEST"));
EXPECT_TRUE(CParser("#define TEST(a, b,c)").LexicalCheck().GetEnvironment().Defined("TEST"));
EXPECT_TRUE(CParser("#define TEST value").LexicalCheck().GetEnvironment().Defined("TEST"));
EXPECT_TRUE(CParser("#define TEST(a) value a").LexicalCheck().GetEnvironment().Defined("TEST"));
EXPECT_TRUE(CParser("#define TEST(a, b,c) value a*b*c").LexicalCheck().GetEnvironment().Defined("TEST"));
}
TEST_F(CPreprocTest, PreprocessorDefineRedefine)
{
// Redefinition
EXPECT_NO_THROW(CParser("#define TEST(a, b,c) value a*b*c\n#define TEST(a, b,c) value a*b*c").LexicalCheck());
EXPECT_THROW(CParser("#define TEST(a, b,c) value a*b*c\n#define TEST").LexicalCheck(), CCompileException);
}
TEST_F(CPreprocTest, PreprocessorDefineAndSingleExpand)
{
// Parse preprocessor
CParser parser(
"#define TEST\n"
"#define ABBA 2\n"
"#define ABBABA 3\n"
"#define AB(c) AB##c\n"
"#define BA(c) AB ## c\n"
"#define TEXT(c) # c"
);
parser.LexicalCheck();
// Code will be prepended with an empty tring
CCodePos codeTest("");
EXPECT_TRUE(parser.GetEnvironment().TestAndExpand("TEST", codeTest));
EXPECT_TRUE(static_cast<std::string>(codeTest.GetLocation()).empty());
// Code will be prepended with the value "2"
CCodePos codeAbba("");
EXPECT_TRUE(parser.GetEnvironment().TestAndExpand("ABBA", codeAbba));
EXPECT_EQ(static_cast<std::string>(codeAbba.GetLocation()), "2");
// Code will be prepended with "ABBA" and expanded to "2"
CCodePos codeAbba2("(BA)");
EXPECT_TRUE(parser.GetEnvironment().TestAndExpand("AB", codeAbba2));
EXPECT_EQ(static_cast<std::string>(codeAbba2.GetLocation()), "2");
// Code will be prepended with "ABBA" and expanded to "2"
CCodePos codeAbba3("(BA)");
EXPECT_TRUE(parser.GetEnvironment().TestAndExpand("BA", codeAbba3));
EXPECT_EQ(static_cast<std::string>(codeAbba3.GetLocation()), "2");
// Code will be prepende with "\"hello\""
CCodePos codeText("(hello)");
EXPECT_TRUE(parser.GetEnvironment().TestAndExpand("TEXT", codeText));
EXPECT_EQ(static_cast<std::string>(codeText.GetLocation()), "\"hello\"");
// Code will be prepended with "ABBA"
CCodePos codeAbba4("(B)A");
EXPECT_TRUE(parser.GetEnvironment().TestAndExpand("AB", codeAbba4));
CToken tokenAbba4 = codeAbba4.GetLocation();
++codeAbba4; // Skip prepended 'A'
++codeAbba4; // Skip prepended 'B'
++codeAbba4; // Skip prepended 'C'
++codeAbba4; // Skip 'A'
codeAbba4.UpdateLocation(tokenAbba4);
EXPECT_EQ(static_cast<std::string>(tokenAbba4), "ABBA");
}
TEST_F(CPreprocTest, PreprocessorDefineAndExpand)
{
// Parse preprocessor
CParser parser(
"#define TEST\n"
"#define ABBA 2\n"
"#define ABBABA 3\n"
"#define AB(c) AB##c\n"
"#define BA(c) AB ## c\n"
"#define DE AB(BA) ## BA\n"
"#define EF ABBA ## BA\n"
"#define CIRCULAR CIRCULAR\n"
"#define MULTI(a, b) a ## b\n"
"#define MULTI_SPACE(a, b) a \\\n \\\r\n\t b\n"
"#define MULTI_COMMENT1(a, b) a // ## b\n"
"#define MULTI_COMMENT2(a, b) a /* ## */ b\n"
"#define TEXT(c) # c\n"
"#define Fx abc\n"
"#define Bx def\n"
"#define FB(arg) #arg\n"
"#define FB1(arg) FB(arg)\n"
"#define DOx(x) x\n"
"#define CIRCULAR2 DOx(CIRCULAR2)\n"
"#define CIRCULAR3 CIRCULAR"
);
parser.LexicalCheck();
// Simple parsing function
auto fnGetLastProcessedToken = [&](CCodePos& rCode) -> CToken
{
CToken token;
while (!rCode.HasEOF())
{
// If the current position is not part of the macro expansion, reset the set of macros used in a expansion.
bool bInMacroExpansion = rCode.CurrentPositionInMacroExpansion();
// Get a token
token = parser.GetLexer().GetToken(rCode, nullptr);
// Check whether the token is an identifier, if so, check for any macro
if (token.GetType() == ETokenType::token_identifier)
{
if (parser.GetEnvironment().TestAndExpand(static_cast<std::string>(token).c_str(), rCode, bInMacroExpansion))
continue; // macro was replaced, get a token again.
}
}
return token;
};
// Multiple arguments.
CCodePos codeMulti("FB1(MULTI(abc, def))");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeMulti)), "\"abcdef\"");
// Comments are ignored in expansion.
CCodePos codeComment1("FB1(MULTI_COMMENT1(abc, def))");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeComment1)), "\"abc\"");
CCodePos codeComment2("FB1(MULTI_COMMENT2(abc, def))");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeComment2)), "\"abc def\"");
CCodePos codeComment3("FB1(MULTI(abc /*the first*/, /*the second*/def))");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeComment3)), "\"abcdef\"");
// Macro is formed using another macro and expanded itself to "2".
CCodePos codeAbba5("AB(B)A");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeAbba5)), "2");
// Strings from arguments - argument expansion only when not stringificating.
// Version 1 stringificates the argument without expansion
// Version 2 expands the argument first and then stringificates
CCodePos codeFB0("FB(Fx Bx)");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeFB0)), "\"Fx Bx\"");
CCodePos codeFB1("FB1(Fx Bx)");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeFB1)), "\"abc def\"");
// Reduce large spaces to one space
// Version 1 has space in the arguments, which will be reduced to one space
// Version 2 has space in the definition, which will be reduced to one space
CCodePos codeSpace1("FB1(Fx \t\\\n \t\t\\\r\n \tBx)");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeSpace1)), "\"abc def\"");
CCodePos codeSpace2("FB1(MULTI_SPACE(abc, def))");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeSpace2)), "\"abc def\"");
// Expand results before added to the code
// Version 1 expands ABBA into 2 and then adds A
// VERSION 2 glues ABBA to BA and expands ABABA into 3
CCodePos codeRes1("FB1(DE)");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeRes1)), "\"2BA\"");
CCodePos codeRes2("FB1(EF)");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeRes2)), "\"3\"");
// Circular referencing
// Version 1 calls itself
// Version 2 calls another macro calling itsel
// Version 3 has multiple circular macros in one parameter
CCodePos codeCircular1("FB1(CIRCULAR)");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeCircular1)), "\"CIRCULAR\"");
CCodePos codeCircular2("FB1(CIRCULAR2)");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeCircular2)), "\"CIRCULAR2\"");
CCodePos codeCircular3("FB1(CIRCULAR3 CIRCULAR CIRCULAR3)");
EXPECT_EQ(static_cast<std::string>(fnGetLastProcessedToken(codeCircular3)), "\"CIRCULAR CIRCULAR CIRCULAR\"");
}
TEST_F(CPreprocTest, PreprocessorUndef)
{
// Parse preprocessor
CParser parser(
"#define TEST\n"
"#define ABBA 2\n"
"#define ABBABA 3\n"
"#define AB(c) AB##c\n"
"#define BA(c) AB ## c\n"
"#undef TEST\n"
"#undef ABRACADABRA\n"
"#undef ABBABA with dummy text... is ignored\n"
"#undef BA // with comments"
);
parser.LexicalCheck();
EXPECT_FALSE(parser.GetEnvironment().Defined("TEST"));
EXPECT_TRUE(parser.GetEnvironment().Defined("ABBA"));
EXPECT_FALSE(parser.GetEnvironment().Defined("ABBABA"));
EXPECT_TRUE(parser.GetEnvironment().Defined("AB"));
EXPECT_FALSE(parser.GetEnvironment().Defined("BA"));
}
TEST_F(CPreprocTest, PreprocessorIncludeLocal)
{
// Create a dummy files
std::ofstream fstreamNormal("dummy_source_test_preprocessor_include.tmp", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamNormal.is_open());
fstreamNormal << "#define HELLO2";
fstreamNormal.close();
std::ofstream fstreamCircular("dummy_source_test_preprocessor_include_circular.tmp", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamCircular.is_open());
fstreamCircular << "#include \"dummy_source_test_preprocessor_include_circular.tmp\"";
fstreamCircular.close();
std::filesystem::create_directory("dummy1");
std::filesystem::path pathDummy1File = "dummy1/dummy1_subdir_source_test_preprocessor_include.tmp";
std::ofstream fstreamDummy1Subdir(pathDummy1File.string(), std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamDummy1Subdir.is_open());
fstreamDummy1Subdir << "#define DUMMY1";
fstreamDummy1Subdir.close();
std::filesystem::create_directory("dummy2");
std::filesystem::path pathDummy2File = "dummy2/dummy2_subdir_source_test_preprocessor_include.tmp";
std::ofstream fstreamDummy2Subdir(pathDummy2File.string(), std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamDummy2Subdir.is_open());
fstreamDummy2Subdir << "#include \"../dummy3/dummy3_subdir_source_test_preprocessor_include.tmp\"";
fstreamDummy2Subdir.close();
std::filesystem::create_directory("dummy3");
std::filesystem::path pathDummy3File = "dummy3/dummy3_subdir_source_test_preprocessor_include.tmp";
std::ofstream fstreamDummy3Subdir(pathDummy3File.string(), std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamDummy3Subdir.is_open());
fstreamDummy3Subdir << "#define DUMMY3\n#include \"dummy4_subdir_source_test_preprocessor_include.tmp\"";
fstreamDummy3Subdir.close();
std::filesystem::path pathDummy4File = "dummy3/dummy4_subdir_source_test_preprocessor_include.tmp";
std::ofstream fstreamDummy4Subdir(pathDummy4File.string(), std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamDummy4Subdir.is_open());
fstreamDummy4Subdir << "#define DUMMY4";
fstreamDummy4Subdir.close();
// Make include dirs (1st argument is the executable file path).
std::vector<std::string> rvecArgs = {"idl_compiler_test", "-Idummy1", "-Idummy2"};
CIdlCompilerEnvironment environment(rvecArgs);
// Check non-existing
EXPECT_THROW(CParser("#include \"non_existing_file.tmp\"", environment).LexicalCheck(), CCompileException);
// Check local
EXPECT_TRUE(CParser("#include \"dummy_source_test_preprocessor_include.tmp\"", environment).LexicalCheck().
GetEnvironment().Defined("HELLO2"));
// Check local with relative path
EXPECT_TRUE(CParser("#include \"dummy1/dummy1_subdir_source_test_preprocessor_include.tmp\"").LexicalCheck().
GetEnvironment().Defined("DUMMY1"));
// Check circular (re-inclusion is prevented)
EXPECT_NO_THROW(CParser("#include \"dummy_source_test_preprocessor_include_circular.tmp\"", environment).LexicalCheck());
// Check through include path
EXPECT_TRUE(CParser("#include \"dummy1_subdir_source_test_preprocessor_include.tmp\"", environment).LexicalCheck().
GetEnvironment().Defined("DUMMY1"));
// Check local includes from an included file not in the search path
EXPECT_TRUE(CParser("#include \"dummy2_subdir_source_test_preprocessor_include.tmp\"", environment).LexicalCheck().
GetEnvironment().Defined("DUMMY4"));
try
{
std::filesystem::remove("dummy_source_test_preprocessor_include.tmp");
std::filesystem::remove("dummy_source_test_preprocessor_include_circular.tmp");
std::filesystem::remove_all("dummy1");
std::filesystem::remove_all("dummy2");
std::filesystem::remove_all("dummy3");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST_F(CPreprocTest, PreprocessorIncludeLocalAbsolute)
{
// Create a dummy files
std::filesystem::path pathCurrent = std::filesystem::current_path();
std::ofstream fstreamNormal("dummy_source_test_preprocessor_include.tmp", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamNormal.is_open());
fstreamNormal << "#include \"" << (pathCurrent / "dummy" / "dummy_subdir_source_test_preprocessor_include.tmp").generic_u8string() << "\"";
fstreamNormal.close();
std::filesystem::create_directory("dummy");
std::filesystem::path pathDummy1File = "dummy/dummy_subdir_source_test_preprocessor_include.tmp";
std::ofstream fstreamDummySubdir(pathDummy1File.string(), std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamDummySubdir.is_open());
fstreamDummySubdir << "#define HELLO";
fstreamDummySubdir.close();
// Check access through path (should not be possible)
EXPECT_THROW(CParser("#include \"dummy_subdir_source_test_preprocessor_include.tmp\"").LexicalCheck(), CCompileException);
// Check relative path
EXPECT_TRUE(CParser("#include \"dummy/dummy_subdir_source_test_preprocessor_include.tmp\"").LexicalCheck().
GetEnvironment().Defined("HELLO"));
// Check direct absolute path
std::string ssCode = "#include \"";
ssCode += (pathCurrent / "dummy" / "dummy_subdir_source_test_preprocessor_include.tmp").generic_u8string();
ssCode += "\"";
EXPECT_TRUE(CParser(ssCode.c_str()).LexicalCheck().
GetEnvironment().Defined("HELLO"));
// Check indirect absolute path
EXPECT_TRUE(CParser("#include \"dummy_source_test_preprocessor_include.tmp\"").LexicalCheck().
GetEnvironment().Defined("HELLO"));
try
{
std::filesystem::remove("dummy_source_test_preprocessor_include.tmp");
std::filesystem::remove_all("dummy");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST_F(CPreprocTest, PreprocessorIncludeGlobal)
{
// Create a dummy files
std::ofstream fstreamNormal("dummy_source_test_preprocessor_include.tmp", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamNormal.is_open());
fstreamNormal << "#define HELLO2";
fstreamNormal.close();
std::ofstream fstreamCircular("dummy_source_test_preprocessor_include_circular.tmp", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamCircular.is_open());
fstreamCircular << "#include \"dummy_source_test_preprocessor_include_circular.tmp\"";
fstreamCircular.close();
std::filesystem::create_directory("dummy1");
std::filesystem::path pathDummy1File = "dummy1/dummy1_subdir_source_test_preprocessor_include.tmp";
std::ofstream fstreamDummy1Subdir(pathDummy1File.string(), std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamDummy1Subdir.is_open());
fstreamDummy1Subdir << "#define DUMMY1";
fstreamDummy1Subdir.close();
std::filesystem::create_directory("dummy2");
std::filesystem::path pathDummy2File = "dummy2/dummy2_subdir_source_test_preprocessor_include.tmp";
std::ofstream fstreamDummy2Subdir(pathDummy2File.string(), std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamDummy2Subdir.is_open());
fstreamDummy2Subdir << "#include \"../dummy3/dummy3_subdir_source_test_preprocessor_include.tmp\"";
fstreamDummy2Subdir.close();
std::filesystem::create_directory("dummy3");
std::filesystem::path pathDummy3File = "dummy3/dummy3_subdir_source_test_preprocessor_include.tmp";
std::ofstream fstreamDummy3Subdir(pathDummy3File.string(), std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamDummy3Subdir.is_open());
fstreamDummy3Subdir << "#define DUMMY3\n#include \"dummy4_subdir_source_test_preprocessor_include.tmp\"";
fstreamDummy3Subdir.close();
std::filesystem::path pathDummy4File = "dummy3/dummy4_subdir_source_test_preprocessor_include.tmp";
std::ofstream fstreamDummy4Subdir(pathDummy4File.string(), std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstreamDummy4Subdir.is_open());
fstreamDummy4Subdir << "#define DUMMY4";
fstreamDummy4Subdir.close();
// Make include dirs (1st argument is the executable file path).
std::vector<std::string> rvecArgs = {"idl_compiler_test.exe", "-Idummy1", "-Idummy2"};
CIdlCompilerEnvironment environment(rvecArgs);
// Check non-existing
EXPECT_THROW(CParser("#include <non_existing_file.tmp>", environment).LexicalCheck(), CCompileException);
// Check local
EXPECT_THROW(CParser("#include <dummy_source_test_preprocessor_include.tmp>", environment).LexicalCheck(), CCompileException);
// Check local with relative path
EXPECT_THROW(CParser("#include <dummy1/dummy1_subdir_source_test_preprocessor_include.tmp>").LexicalCheck(), CCompileException);
// Check through include path
EXPECT_TRUE(CParser("#include <dummy1_subdir_source_test_preprocessor_include.tmp>", environment).LexicalCheck().
GetEnvironment().Defined("DUMMY1"));
// Check local includes from an included file not in the search path
EXPECT_TRUE(CParser("#include <dummy2_subdir_source_test_preprocessor_include.tmp>", environment).LexicalCheck().
GetEnvironment().Defined("DUMMY4"));
try
{
std::filesystem::remove("dummy_source_test_preprocessor_include.tmp");
std::filesystem::remove("dummy_source_test_preprocessor_include_circular.tmp");
std::filesystem::remove_all("dummy1");
std::filesystem::remove_all("dummy2");
std::filesystem::remove_all("dummy3");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST_F(CPreprocTest, PreprocessorIf)
{
// Direct if with integer
EXPECT_TRUE(CParser(
"#if 1\n"
"#define CORRECT\n"
"#else\n"
"#define INCORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
// Direct if with boolean
EXPECT_TRUE(CParser(
"#if true\n"
"#define CORRECT\n"
"#else\n"
"#define INCORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
// Direct if with character
EXPECT_TRUE(CParser(
"#if 'a'\n"
"#define CORRECT\n"
"#else\n"
"#define INCORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
// Direct if with macro
EXPECT_TRUE(CParser(
"#define a 10\n"
"#if a\n"
"#define CORRECT\n"
"#else\n"
"#define INCORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
// Direct if with zerod macro
EXPECT_TRUE(CParser(
"#define a 0\n"
"#if a\n"
"#define INCORRECT\n"
"#else\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
// Direct if with defined macro without value
EXPECT_THROW(CParser(
"#define a\n"
"#if a\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck(), CCompileException);
// Direct if with non-existent macro (equals to 0)
EXPECT_TRUE(CParser(
"#if a\n"
"#define INCORRECT\n"
"#else\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
// Incomplete if statement
EXPECT_THROW(CParser(
"#if\n"
"#define CORRECT\n"
"#else\n"
"#define INCORRECT\n"
"#endif"
).LexicalCheck(), CCompileException);
// Correct if section using macros
EXPECT_TRUE(CParser(
"#define a 10\n"
"#define b(c, d) c*d\n"
"#define e 10\n"
"#if a + b(5, 5) + e == 45\n"
"#define CORRECT\n"
"#else\n"
"#define INCORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
// Incorrect if section using macros
EXPECT_FALSE(CParser(
"#define a 10\n"
"#define b(c, d) c*d\n"
"#define e 10\n"
"#if a + b(5, 5) + e == 45\n"
"#define CORRECT\n"
"#else\n"
"#define INCORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("INCORRECT"));
// Parenthesis while calculating
EXPECT_TRUE(CParser(
"#define a 10\n"
"#define b(c, d) c*d\n"
"#define e 10\n"
"#if a * (b(5, 5) + e) == 350\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
// Operators + - / * %
EXPECT_TRUE(CParser(
"#if 10 + 11 * 35 % 10 - 2 == 13\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
// Operators << >> & | ~
// NOTE: '!=' comes before '&'
EXPECT_TRUE(CParser(
"#if (2 << 2 | 7 >> 1 & (~ 120 & 7)) != 11\n"
"#define INCORRECT\n"
"#else\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
// Operators && || < > <= >= == !=
EXPECT_TRUE(CParser(
"#if (20 || 10 && 1) < 2\n"
"#define CORRECT1 1\n"
"#endif\n"
"#if 50 + 7 >= 57\n"
"#define CORRECT2 1\n"
"#endif\n"
"#if 50 + 8 > 57\n"
"#define CORRECT3 1\n"
"#endif\n"
"#if 50 + 7 <= 57\n"
"#define CORRECT4 1\n"
"#endif\n"
"#if 10 != TEST\n"
"#define CORRECT5 1\n"
"#endif\n"
"#if CORRECT1 + CORRECT2 + CORRECT3 + CORRECT4 + CORRECT5 == 5\n"
"#define CORRECT\n"
"#endif\n"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
// Div by zero /
EXPECT_THROW(CParser(
"#if 10 / TEST\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck(), CCompileException);
// Div by zero %
EXPECT_THROW(CParser(
"#if 10 % TEST\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck(), CCompileException);
// Incomplete
EXPECT_THROW(CParser(
"#define TEST\n"
"#if 10 % TEST\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck(), CCompileException);
// Exclude code
EXPECT_NO_THROW(CParser(
"#if 0\n"
"bla bla\n"
"#endif"
).LexicalCheck());
// Exclude code incomplete
EXPECT_THROW(CParser(
"#if 0\n"
"bla bla\n"
).LexicalCheck(), CCompileException);
}
TEST_F(CPreprocTest, PreprocessorDefinedOperator)
{
// defined(macro)
EXPECT_TRUE(CParser(
"#if !defined(TEST)\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
EXPECT_TRUE(CParser(
"#define TEST\n"
"#if defined(TEST)\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
EXPECT_THROW(CParser(
"#if defined()\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck(), CCompileException);
// defined macro
EXPECT_TRUE(CParser(
"#if !defined TEST\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
EXPECT_TRUE(CParser(
"#define TEST\n"
"#if defined TEST\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck().GetEnvironment().Defined("CORRECT"));
EXPECT_THROW(CParser(
"#if defined\n"
"#define CORRECT\n"
"#endif"
).LexicalCheck(), CCompileException);
}
TEST_F(CPreprocTest, PreprocessorElif)
{
// Parse preprocessor
CParser parser(
"#define TEST\n"
"#define AB(c) AB##c\n"
"#ifdef TOAST\n"
"#define XY\n"
"#elif defined(TEST)\n"
"#define VW\n"
"#endif"
);
parser.LexicalCheck();
EXPECT_TRUE(parser.GetEnvironment().Defined("TEST"));
EXPECT_FALSE(parser.GetEnvironment().Defined("XY"));
EXPECT_TRUE(parser.GetEnvironment().Defined("VW"));
}
TEST_F(CPreprocTest, PreprocessorIfDef)
{
// Parse preprocessor
CParser parser(
"#define TEST\n"
"#define AB(c) AB##c\n"
"#ifdef TEST\n"
"#define XY\n"
"#ifdef AB\n"
"#define VW\n"
"#endif\n"
"#endif\n"
"#ifdef TEST2\n"
"#define MN\n"
"#endif"
);
parser.LexicalCheck();
EXPECT_TRUE(parser.GetEnvironment().Defined("TEST"));
EXPECT_TRUE(parser.GetEnvironment().Defined("AB"));
EXPECT_TRUE(parser.GetEnvironment().Defined("XY"));
EXPECT_TRUE(parser.GetEnvironment().Defined("VW"));
EXPECT_FALSE(parser.GetEnvironment().Defined("MD"));
}
TEST_F(CPreprocTest, PreprocessorIfnDef)
{
// Parse preprocessor
CParser parser(
"#define TEST\n"
"#define AB(c) AB##c\n"
"#ifndef TEST\n"
"#define XY\n"
"#ifndef AB\n"
"#define VW\n"
"#endif\n"
"#endif\n"
"#ifndef TEST2\n"
"#define MN\n"
"#endif"
);
parser.LexicalCheck();
EXPECT_TRUE(parser.GetEnvironment().Defined("TEST"));
EXPECT_TRUE(parser.GetEnvironment().Defined("AB"));
EXPECT_FALSE(parser.GetEnvironment().Defined("XY"));
EXPECT_FALSE(parser.GetEnvironment().Defined("VW"));
EXPECT_TRUE(parser.GetEnvironment().Defined("MN"));
}
TEST_F(CPreprocTest, PreprocessorElse)
{
// Parse preprocessor
CParser parser(
"#define TEST\n"
"#ifdef TEST\n"
"#define XY\n"
"#else\n"
"#define VW\n"
"#endif\n"
"#ifdef TEST2\n"
"#define ZA\n"
"#else\n"
"#define TR\n"
"#endif"
);
parser.LexicalCheck();
EXPECT_TRUE(parser.GetEnvironment().Defined("TEST"));
EXPECT_TRUE(parser.GetEnvironment().Defined("XY"));
EXPECT_FALSE(parser.GetEnvironment().Defined("VW"));
EXPECT_FALSE(parser.GetEnvironment().Defined("ZA"));
EXPECT_TRUE(parser.GetEnvironment().Defined("TR"));
}
TEST_F(CPreprocTest, ProcessVerbatim)
{
// Parse preprocessor
CParser parser(
"#verbatim const int i = 10\n"
"#verbatim const int j = 10\\n"
"#verbatim const int k = 10\n"
"#verbatim #define L\n"
"#verbatim #include <string>"
);
EXPECT_NO_THROW(parser.LexicalCheck());
}
TEST_F(CPreprocTest, ProcessVerbatimBlock)
{
// Parse preprocessor
CParser parser(
"#verbatim_begin ignored text\n"
"const int j = 10\\n"
"const int k = 10\n"
"#define L\n"
"#include <string>\n"
"#verbatim_end ignored text"
);
EXPECT_NO_THROW(parser.LexicalCheck());
CParser parser2(
"#verbatim_end ignored text"
);
EXPECT_THROW(parser2.LexicalCheck(), CCompileException);
CParser parser3(
"#verbatim_begin ignored text\n"
"const int j = 10\\n"
"const int k = 10\n"
"#define L\n"
"#include <string>\n"
);
EXPECT_THROW(parser3.LexicalCheck(), CCompileException);
}

View File

@@ -0,0 +1,174 @@
#include "includes.h"
#include "lexer_test.h"
#include "../../../sdv_executables/sdv_idl_compiler/source.cpp"
using CSourceTest = CLexerTest;
TEST_F(CSourceTest, SourceCodeDirect)
{
// Open a sourcefile without code
EXPECT_THROW(CSource(nullptr), CCompileException);
EXPECT_NO_THROW(CSource(""));
}
TEST_F(CSourceTest, SourceFileOpenNonExisting)
{
// Open non existing files
EXPECT_THROW(CSource(std::filesystem::path("DummyFile")), CCompileException);
}
TEST_F(CSourceTest, SourceFileReadAnsi)
{
// Create a dummy file
std::ofstream fstream("dummy_source_test_ansi.tmp", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstream.is_open());
fstream << "Hello, this is a text!";
fstream.close();
CSource source(std::filesystem::path("dummy_source_test_ansi.tmp"));
EXPECT_EQ(source.GetCodeRef(), "Hello, this is a text!");
try
{
std::filesystem::remove("dummy_source_test_ansi.tmp");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST_F(CSourceTest, SourceFileReadUTF8)
{
// Create a dummy file
std::ofstream fstream("dummy_source_test_utf8.tmp", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstream.is_open());
fstream.put(static_cast<char>(0xEF));
fstream.put(static_cast<char>(0xBB));
fstream.put(static_cast<char>(0xBF));
fstream << "Hello, this is a text!";
fstream.close();
CSource source(std::filesystem::path("dummy_source_test_utf8.tmp"));
EXPECT_EQ(source.GetCodeRef(), "Hello, this is a text!");
try
{
std::filesystem::remove("dummy_source_test_utf8.tmp");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST_F(CSourceTest, SourceFileReadUTF16LE)
{
// Create a dummy file
std::ofstream fstream("dummy_source_test_utf16le.tmp", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstream.is_open());
fstream.put(static_cast<char>(0xFF));
fstream.put(static_cast<char>(0xFE));
char16_t szText[] = u"Hello, this is a text!";
for (char16_t c16 : szText)
{
if (!c16) break;
char* rgc = reinterpret_cast<char*>(&c16);
fstream.put(rgc[0]);
fstream.put(rgc[1]);
}
fstream.close();
CSource source(std::filesystem::path("dummy_source_test_utf16le.tmp"));
EXPECT_EQ(source.GetCodeRef(), "Hello, this is a text!");
try
{
std::filesystem::remove("dummy_source_test_utf16le.tmp");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST_F(CSourceTest, SourceFileReadUTF16BE)
{
// Create a dummy file
std::ofstream fstream("dummy_source_test_utf16be.tmp", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstream.is_open());
fstream.put(static_cast<char>(0xFE));
fstream.put(static_cast<char>(0xFF));
char16_t szText[] = u"Hello, this is a text!";
for (char16_t c16 : szText)
{
if (!c16) break;
char* rgc = reinterpret_cast<char*>(&c16);
fstream.put(rgc[1]);
fstream.put(rgc[0]);
}
fstream.close();
CSource source(std::filesystem::path("dummy_source_test_utf16be.tmp"));
EXPECT_EQ(source.GetCodeRef(), "Hello, this is a text!");
try
{
std::filesystem::remove("dummy_source_test_utf16be.tmp");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST_F(CSourceTest, SourceFileReadUTF32LE)
{
// Create a dummy file
std::ofstream fstream("dummy_source_test_utf32le.tmp", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstream.is_open());
fstream.put(static_cast<char>(0xFF));
fstream.put(static_cast<char>(0xFE));
fstream.put(0x00);
fstream.put(0x00);
char32_t szText[] = U"Hello, this is a text!";
for (char32_t c32 : szText)
{
if (!c32) break;
char* rgc = reinterpret_cast<char*>(&c32);
fstream.put(rgc[0]);
fstream.put(rgc[1]);
fstream.put(rgc[2]);
fstream.put(rgc[3]);
}
fstream.close();
CSource source(std::filesystem::path("dummy_source_test_utf32le.tmp"));
EXPECT_EQ(source.GetCodeRef(), "Hello, this is a text!");
try
{
std::filesystem::remove("dummy_source_test_utf32le.tmp");
} catch (const std::filesystem::filesystem_error&)
{}
}
TEST_F(CSourceTest, SourceFileReadUTF32BE)
{
// Create a dummy file
std::ofstream fstream("dummy_source_test_utf32be.tmp", std::ios_base::out | std::ios_base::trunc);
ASSERT_TRUE(fstream.is_open());
fstream.put(0x00);
fstream.put(0x00);
fstream.put(static_cast<char>(0xFE));
fstream.put(static_cast<char>(0xFF));
char32_t szText[] = U"Hello, this is a text!";
for (char32_t c32 : szText)
{
if (!c32) break;
char* rgc = reinterpret_cast<char*>(&c32);
fstream.put(rgc[3]);
fstream.put(rgc[2]);
fstream.put(rgc[1]);
fstream.put(rgc[0]);
}
fstream.close();
CSource source(std::filesystem::path("dummy_source_test_utf32be.tmp"));
EXPECT_EQ(source.GetCodeRef(), "Hello, this is a text!");
try
{
std::filesystem::remove("dummy_source_test_utf32be.tmp");
} catch (const std::filesystem::filesystem_error&)
{}
}

View File

@@ -0,0 +1,370 @@
#include <interfaces/core.idl>
#include "linked.idl"
// Test: split nested module definitions
// Nested module definitions
module Test1
{
/**
* @brief Javadoc like comments
*/
module Test2
{
struct SModuleTest1
{};
};
};
// Extending module definitions
module Test1
{
module Test2
{
struct SModuleTest2
{};
};
};
// Test: forward declaration of struct
struct SForward1;
/*!
* @brief Implementation of forward declared structure
*/
struct SForward1
{};
/**
* @brief Second level base interface.
*/
interface I2ndLevelBase : sdv::IInterfaceAccess
{
void Test2nd_1();
void Test2nd_2();
};
/**
* @brief Base interface
*/
interface IBase : I2ndLevelBase
{
void TestBase_1();
void TestBase_2();
};
/**
* @brief Inheritance test interface.
*/
interface IInheritanceTest : IBase
{
void Test1();
void Test2();
};
/**
* @brief Complex structure
*/
struct SComplex
{
uint8 uiVal8 = 0x08;
uint16 uiVal16 = 0x0106;
uint32 uiVal32 = 0x00030002;
uint64 uiVal64 = 0x0000000600000004;
float fVal = 1234.1234f;
double dVal = 5678.5678;
// GCC issue with generated initialization in the constructor for the "long double" type: BUG #3982727
//long double ldVal = 12345678.12345678l;
boolean bVal = true;
uint32 rguiVal32[5] = { 0x10, 0x20, 0x30, 0x40, 0x50 };
char16 rgcVal[6] = u"Hello";
string ssEmptyVal;
string ssVal;
u8string ss8Val;
u16string ss16Val;
u32string ss32Val;
wstring sswVal;
string<15> ssFixedVal;
u8string<15> ss8FixedVal;
u16string<15> ss16FixedVal;
u32string<15> ss32FixedVal;
wstring<15> sswFixedVal;
struct SRGB
{
string ssRed;
string ssGreen;
string ssBlue;
};
sequence<SRGB> seqEmptyVal;
sequence<SRGB> seqRgbVal;
sequence<SRGB, 20> seqFixedRgbVal;
pointer<SRGB> ptrEmptyVal;
pointer<SRGB> ptrRgbVal;
pointer<SRGB, 200> ptrFixedRgbVal;
any anyString;
any anyFloat;
any anyInteger;
};
/**
* @brief Exception defined
*/
exception XExceptionTest
{
SComplex sComplex; ///< Complex data in the exception
};
/**
* @brief Interface to test the marshalling of variables.
*/
interface IVarTest
{
/**
* @{
* @brief Test signed fixed integral.
*/
void SetFixedInt(in int8 i8Val, in int16 i16Val, in int32 i32Val, in int64 i64Val);
void GetFixedInt(out int8 i8Val, out int16 i16Val, out int32 i32Val, out int64 i64Val) const;
/**
* @}
*/
/**
* @{
* @brief Test unsigned fixed integral.
*/
void SetFixedUInt(in boolean bVal, in native nVal, in uint8 ui8Val, in uint16 ui16Val, in uint32 ui32Val, in uint64 ui64Val);
void GetFixedUInt(out boolean bVal, out native nVal, out uint8 ui8Val, out uint16 ui16Val, out uint32 ui32Val, out uint64 ui64Val) const;
/**
* @}
*/
/**
* @{
* @brief Test character integral.
*/
void SetFixedChar(in char cVal, in wchar cwVal, in char16 c16Val, in char32 c32Val);
void GetFixedChar(out char cVal, out wchar cwVal, out char16 c16Val, out char32 c32Val) const;
/**
* @}
*/
/**
* @{
* @brief Test floating point.
*/
// GCC issue with generated initialization in the consructor for the "long double" type: BUG #3982727
void SetFloatingPoint(in float fVal, in double dVal/*, in long double ldVal*/);
void GetFloatingPoint(out float fVal, out double dVal/*, out long double ldVal*/) const;
/**
* @}
*/
/**
* @{
* @brief Test fixed point.
*/
void SetFixedPoint(in fixed<10, 3> fixVal10, in fixed<8, 2> fixVal8, in fixed<5, 0> fixVal5);
void GetFixedPoint(out fixed<10, 3> fixVal10, out fixed<8, 2> fixVal8, out fixed<5, 0> fixVal5) const;
/**
* @}
*/
/**
* @{
* @brief Test string.
*/
void SetString(in string ssText, in u8string ss8Text, in u16string ss16Text, in u32string ss32Text, in wstring sswText);
void GetString(out string ssText, out u8string ss8Text, out u16string ss16Text, out u32string ss32Text, out wstring sswText) const;
/**
* @}
*/
/**
* @{
* @brief Test fixed size string.
*/
void SetFixedString(in string<10> ssText, in u8string<10> ss8Text, in u16string<10> ss16Text, in u32string<10> ss32Text, in wstring<10> sswText);
void GetFixedString(out string<15> ssText, out u8string<15> ss8Text, out u16string<15> ss16Text, out u32string<15> ss32Text, out wstring<15> sswText) const;
/**
* @}
*/
/**
* @{
* @brief Test sequence.
*/
void SetSequence(in sequence<uint32> seqUInts, in sequence<string> seqTexts, in sequence<sequence<uint32>> seqSequences);
void GetSequence(out sequence<uint32> seqUInts, out sequence<string> seqTexts, out sequence<sequence<uint32>> seqSequences);
/**
* @}
*/
/**
* @{
* @brief Test fixed size sequence.
*/
void SetFixedSequence(in sequence<uint32, 10> seqUInts, in sequence<string, 10> seqTexts, in sequence<sequence<uint32, 10>, 2> seqSequences);
void GetFixedSequence(out sequence<uint32, 7> seqUInts, out sequence<string, 15> seqTexts, out sequence<sequence<uint32, 5>, 3> seqSequences);
/**
* @}
*/
/**
* @{
* @brief Test map.
*/
void SetMap(in map<uint32, uint32> mapUInts, in map<string, string> mapTexts, in map<string, sequence<uint32>> mapSequences);
void GetMap(out map<uint32, uint32> mapUInts, out map<string, string> mapTexts, out map<string, sequence<uint32>> mapSequences);
/**
* @}
*/
/**
* @{
* @brief Test fixed size map.
*/
void SetFixedMap(in map<uint32, uint32, 10> mapUInts, in map<string, string, 10> mapTexts, in map<string, sequence<uint32, 10>, 2> mapSequences);
void GetFixedMap(out map<uint32, uint32, 7> mapUInts, out map<string, string, 15> mapTexts, out map<string, sequence<uint32, 5>, 3> mapSequences);
/**
* @}
*/
/**
* @{
* @brief Test pointer.
*/
void SetPointer(in pointer<uint32> ptrUInts, in pointer<string> ptrTexts, in pointer<sequence<uint32>> ptrSequences);
void GetPointer(out pointer<uint32> ptrUInts, out pointer<string> ptrTexts, out pointer<sequence<uint32>> ptrSequences);
/**
* @}
*/
/**
* @{
* @brief Test fixed size pointer.
*/
void SetFixedPointer(in pointer<uint32, 10> ptrUInts, in pointer<string, 10> ptrTexts, in pointer<sequence<uint32, 10>, 2> ptrSequences);
void GetFixedPointer(out pointer<uint32, 7> ptrUInts, out pointer<string, 15> ptrTexts, out pointer<sequence<uint32, 5>, 3> ptrSequences);
/**
* @}
*/
/**
* @{
* @brief Test any data type.
*/
void SetAny(in any anyMyValue);
void GetAny(out any anyMyValue);
/**
* @}
*/
/**
* @{
* @brief Test complex data type.
*/
void SetComplex(in SComplex rsComplex);
SComplex GetComplex() const;
void UpdateComplex(inout SComplex rsComplex);
/**
* @}
*/
/**
* @{
* @brief Test attributes
*/
attribute boolean bVal;
attribute native nVal;
attribute int8 i8Val;
attribute int16 i16Val;
attribute int32 i32Val;
attribute int64 i64Val;
attribute uint8 ui8Val;
attribute uint16 ui16Val;
attribute uint32 ui32Val;
attribute uint64 ui64Val;
attribute char cVal;
attribute wchar cwVal;
attribute char16 c16Val;
attribute char32 c32Val;
attribute float fVal;
attribute double dVal;
// GCC issue with generated initialization in the consructor for the "long double" type: BUG #3982727
//attribute long double ldVal;
attribute fixed<10, 3> fixVal10;
attribute fixed<8, 2> fixVal8;
attribute fixed<5, 0> fixVal5;
attribute string ssText;
attribute u8string ss8Text;
attribute u16string ss16Text;
attribute u32string ss32Text;
attribute wstring sswText;
attribute string<10> ssFixedText;
attribute u8string<10> ss8FixedText;
attribute u16string<10> ss16FixedText;
attribute u32string<10> ss32FixedText;
attribute wstring<10> sswFixedText;
attribute sequence<uint32> seqUInts;
attribute sequence<string> seqTexts;
attribute sequence<sequence<uint32>> seqSequences;
attribute sequence<uint32, 10> seqFixedUInts;
attribute sequence<string, 10> seqFixedTexts;
attribute sequence<sequence<uint32, 10>, 2> seqFixedSequences;
attribute map<uint32, uint32> mapUInts;
attribute map<string, string> mapTexts;
attribute map<string, sequence<uint32>> mapSequences;
attribute map<uint32, uint32, 10> mapFixedUInts;
attribute map<string, string, 10> mapFixedTexts;
attribute map<string, sequence<uint32, 10>, 2> mapFixedSequences;
attribute pointer<uint32> ptrUInts;
attribute pointer<string> ptrTexts;
attribute pointer<sequence<uint32>> ptrSequences;
attribute pointer<uint32, 10> ptrFixedUInts;
attribute pointer<string, 10> ptrFixedTexts;
attribute pointer<sequence<uint32, 10>, 2> ptrFixedSequences;
attribute any anyMyValue;
/**
* @}
*/
/**
* Trigger complex exception.
*/
void TriggerComplexException() raises(XExceptionTest);
/**
* Trigger system exception.
*/
void TriggerSystemException();
/**
* Trigger unhandled exception.
*/
void TriggerUnhandledException();
/**
* Trigger crash exception.
*/
void TriggerCrashException();
};
module BankDemo
{
typedef float TCashAmount; // Type for representing cash
typedef string TAccountId; // Type for representing account ids
//...
interface IAccount : sdv::IInterfaceAccess
{
readonly attribute TAccountId fAccountId; //!< The account ID
attribute TCashAmount fBalance; //!< The balance
void
Withdraw(in TCashAmount fAmount)
raises(InsufficientFunds);
void
Deposit(in TCashAmount fAmount);
};
};

View File

@@ -0,0 +1,343 @@
#include <interfaces/core_types.idl>
/**
* @brief Empty identical
*/
interface IEmptyIdentical
{};
/**
* @brief Identical
*/
interface IIdentical
{
void Test();
};
/**
* @brief Empty different name
*/
interface IEmptyDifferent1
{};
/**
* @brief Different name
*/
interface IDifferent1
{};
/**
* @brief Different module
*/
module mod1
{
interface IDiffentModule
{};
};
/**
* @brief Different module's module
*/
module mod_parent1
{
module mod
{
interface IEmptyIdentical
{};
};
};
/**
* @brief Function name change
*/
interface IDiffentMemberFunc
{
void Test1();
};
/**
* @brief Function order
*/
interface IDiffentMemberFuncOrder
{
void Test1();
void Test2();
};
/**
* @brief Function read/write change.
*/
interface IDifferentFuncVisibility
{
void Test();
};
/**
* @brief Additional function
*/
interface IDifferentAddFunc
{
void Test();
};
/**
* @brief Additional function parameter
*/
interface IDifferentAddFuncParam
{
void Test(in int32 iParam1);
};
/**
* @brief Interface to test a change of the function when used as variable or return value.
*/
interface IParamTestInterface
{
void Test(in int32 iVal);
};
/**
* @brief Complex param type change.
*/
interface IComplexParamChange
{
void Test(in IParamTestInterface ifc);
};
/**
* @brief Complex return type change.
*/
interface IComplexReturnValChange
{
IParamTestInterface Test();
};
/**
* @brief Function parameter order change
*/
interface IDifferentFuncParamOrder
{
void Test(in int32 iParam1, in int32 iParam2);
};
/**
* @brief Function return value change
*/
interface IDifferentFuncRetVal
{
int32 Test();
};
/**
* @brief Function parameter name change
*/
interface IDifferentFuncParamName
{
void Test(in int32 iParam1);
};
/**
* @brief Function parameter type change
*/
interface IDifferentFuncParamType
{
void Test(in int32 iParam);
};
/**
* @brief Changed directional parameter
*/
interface IDifferentFuncParamDirection
{
void Test(inout int32 iParam);
};
/**
* Exception definition to test the affect of an exception on the interface ID.
*/
exception SExcept
{};
/**
* @brief Add exception to function
*/
interface IDifferentFuncAddException
{
void Test();
};
/**
* Exception definition to test the affect of an additional exception on the interface ID.
*/
exception SAdditionalExcept
{};
/**
* @brief Change exception in function
*/
interface IDifferentFuncChangeException
{
void Test() raises(SExcept);
};
/**
* @brief Additional exception in function
*/
interface IDifferentFuncAdditionalException
{
void Test() raises(SExcept);
};
/**
* @brief Identical exception order in function
*/
interface IDifferentFuncExceptionOrder
{
void Test() raises(SExcept, SAdditionalExcept);
};
/**
* @brief Exception to test the affect on the interface ID with a member name change.
*/
exception SExceptVarName
{
int32 iVar1;
};
/**
* @brief Change function exception name
*/
interface IDifferentFuncExceptionName
{
void Test() raises(SExceptVarName);
};
/**
* @brief Exception to test the affect on the interface ID with a member type change.
*/
exception SExceptVarType
{
int32 iVar;
};
/**
* @brief Change function exception type
*/
interface IDifferentFuncExceptionType
{
void Test() raises(SExceptVarType);
};
/**
* @brief Attribute name change
*/
interface IDifferentAttrName
{
attribute int32 iVar1;
};
/**
* @brief Attribute type change
*/
interface IDifferentAttrType
{
attribute int32 iVar;
};
/**
* @brief Additional attribute
*/
interface IDifferentAddAttr
{
attribute int32 iVar;
};
/**
* @brief Readonly/writable attribute
*/
interface IDifferentAttrVisibility
{
attribute int32 iVar;
};
/**
* @brief Add exception to attribute
*/
interface IDifferentAttrAddException
{
attribute int32 iVar;
};
/**
* @brief Change exception in attribute
*/
interface IDifferentAttrChangeException
{
attribute int32 iVar raises(SExcept);
};
/**
* @brief Additional exception in attribute
*/
interface IDifferentAttrAdditionalException
{
attribute int32 iVar raises(SExcept);
};
/**
* @brief Change attribnute exception direction
*/
interface IDifferentAttrExceptionDirection
{
attribute int32 iVar getraises(SExcept);
};
/**
* @brief Change exception direction of two exception
*/
interface IDifferentFuncExceptionDirection2
{
attribute int32 iVar getraises(SExcept) setraises(SAdditionalExcept);
};
/**
* @brief Change attribute exception name
*/
interface IDifferentAttrExceptionName
{
attribute int32 iVar raises(SExceptVarName);
};
/**
* @brief Change function exception type
*/
interface IDifferentAttrExceptionType
{
attribute int32 iVar raises(SExceptVarType);
};
/**
* @brief Identical, but different const vars
*/
interface IIdenticalAddConstDecl
{
const int32 iVar1 = 10;
};
/**
* @brief Identical, but different comments
*/
interface IIdenticalAddComments
{
// First comment
void Test1();
};
/**
* @brief Identical, but additional child definitions
*/
interface IIdenticalAddChildDef
{
struct SStruct1
{};
};

View File

@@ -0,0 +1,347 @@
#include <interfaces/core_types.idl>
/**
* @brief Empty identical
*/
interface IEmptyIdentical
{};
/**
* @brief Identical
*/
interface IIdentical
{
void Test();
};
/**
* @brief Empty different name
*/
interface IEmptyDifferent2
{};
/**
* @brief Different name
*/
interface IDifferent2
{};
/**
* @brief Different module
*/
module mod2
{
interface IDiffentModule
{};
};
/**
* @brief Different module's module
*/
module mod_parent2
{
module mod
{
interface IEmptyIdentical
{};
};
};
/**
* @brief Function name change
*/
interface IDiffentMemberFunc
{
void Test2();
};
/**
* @brief Function order
*/
interface IDiffentMemberFuncOrder
{
void Test2();
void Test1();
};
/**
* @brief Function read/write change.
*/
interface IDifferentFuncVisibility
{
void Test() const;
};
/**
* @brief Additional function
*/
interface IDifferentAddFunc
{
void Test();
void Test2();
};
/**
* @brief Additional function parameter
*/
interface IDifferentAddFuncParam
{
void Test(in int32 iParam1, in int32 iParam2);
};
/**
* @brief Interface to test a change of the function when used as variable or return value.
*/
interface IParamTestInterface
{
void Test(in int16 iVal);
};
/**
* @brief Complex param type change.
*/
interface IComplexParamChange
{
void Test(in IParamTestInterface ifc);
};
/**
* @brief Complex return type change.
*/
interface IComplexReturnValChange
{
IParamTestInterface Test();
};
/**
* @brief Function parameter order change
*/
interface IDifferentFuncParamOrder
{
void Test(in int32 iParam2, in int32 iParam1);
};
/**
* @brief Function return value change
*/
interface IDifferentFuncRetVal
{
int16 Test();
};
/**
* @brief Function parameter name change
*/
interface IDifferentFuncParamName
{
void Test(in int32 iParam2);
};
/**
* @brief Function parameter type change
*/
interface IDifferentFuncParamType
{
void Test(in int16 iParam);
};
/**
* @brief Changed directional parameter
*/
interface IDifferentFuncParamDirection
{
void Test(out int32 iParam);
};
/**
* Exception definition to test the affect of an exception on the interface ID.
*/
exception SExcept
{};
/**
* @brief Add exception to function
*/
interface IDifferentFuncAddException
{
void Test() raises(SExcept);
};
/**
* Exception definition to test the affect of an additional exception on the interface ID.
*/
exception SAdditionalExcept
{};
/**
* @brief Change exception in function
*/
interface IDifferentFuncChangeException
{
void Test() raises(SAdditionalExcept);
};
/**
* @brief Additional exception in function
*/
interface IDifferentFuncAdditionalException
{
void Test() raises(SExcept, SAdditionalExcept);
};
/**
* @brief Identical exception order in function
*/
interface IDifferentFuncExceptionOrder
{
void Test() raises(SAdditionalExcept, SExcept);
};
/**
* @brief Exception to test the affect on the interface ID with a member name change.
*/
exception SExceptVarName
{
int32 iVar2;
};
/**
* @brief Change function exception name
*/
interface IDifferentFuncExceptionName
{
void Test() raises(SExceptVarName);
};
/**
* @brief Exception to test the affect on the interface ID with a member type change.
*/
exception SExceptVarType
{
int16 iVar;
};
/**
* @brief Change function exception type
*/
interface IDifferentFuncExceptionType
{
void Test() raises(SExceptVarType);
};
/**
* @brief Attribute name change
*/
interface IDifferentAttrName
{
attribute int32 iVar2;
};
/**
* @brief Attribute type change
*/
interface IDifferentAttrType
{
attribute int16 iVar;
};
/**
* @brief Additional attribute
*/
interface IDifferentAddAttr
{
attribute int32 iVar;
attribute int32 iVar2;
};
/**
* @brief Readonly/writable attribute
*/
interface IDifferentAttrVisibility
{
readonly attribute int32 iVar;
};
/**
* @brief Add exception to attribute
*/
interface IDifferentAttrAddException
{
attribute int32 iVar raises(SExcept);
};
/**
* @brief Change exception in attribute
*/
interface IDifferentAttrChangeException
{
attribute int32 iVar raises(SAdditionalExcept);
};
/**
* @brief Additional exception in attribute
*/
interface IDifferentAttrAdditionalException
{
attribute int32 iVar raises(SExcept, SAdditionalExcept);
};
/**
* @brief Change attribnute exception direction
*/
interface IDifferentAttrExceptionDirection
{
attribute int32 iVar setraises(SExcept);
};
/**
* @brief Change exception direction of two exception
*/
interface IDifferentFuncExceptionDirection2
{
attribute int32 iVar getraises(SAdditionalExcept) setraises(SExcept);
};
/**
* @brief Change attribute exception name
*/
interface IDifferentAttrExceptionName
{
attribute int32 iVar raises(SExceptVarName);
};
/**
* @brief Change function exception type
*/
interface IDifferentAttrExceptionType
{
attribute int32 iVar raises(SExceptVarType);
};
/**
* @brief Identical, but different const vars
*/
interface IIdenticalAddConstDecl
{
const int32 iVar1 = 10;
const int32 iVar2 = 20;
};
/**
* @brief Identical, but different comments
*/
interface IIdenticalAddComments
{
// Second comment
void Test1();
};
/**
* @brief Identical, but additional child definitions
*/
interface IIdenticalAddChildDef
{
struct SStruct2
{};
};

View File

@@ -0,0 +1,428 @@
// Several issues exist with the code generation of the unions:
// - Forward declaration of unions with value based switch --> forward declarated type is union and impl. type is struct
// - Unions with complex members --> constructor and destructor are deleted
// Forward declaration
union UStandard;
/**
* @brief Standard union based on a integer.
*/
union UStandard switch (uint32)
{
case 10: boolean bVal; ///< Bool value
case 20: uint64 uiVal; ///< 64-bit int value
case 30: string ssVal; ///< String value
default: float fVal; ///< Float value
};
/**
* \@brief Typedef of a standard union.
*/
typedef UStandard UTypedefStandard;
/**
* @brief Enum variable for switch case
*/
enum ESwitch : long
{
ten, ///< Value 10
twenty, ///< Value 20
thirty ///< Value 30
};
/**
* @brief Standard union based on an enum.
*/
union UStandardEnum switch (ESwitch)
{
case ten: boolean bVal; ///< Bool value
case twenty: uint64 uiVal; ///< 64-bit int value
case thirty: string ssVal; ///< String value
default: float fVal; ///< Float value
};
/**
* @brief Standard union in struct.
*/
struct SStandardUnion
{
UStandard uStandardVar; ///< Standard union declaration.
UStandardEnum uStandardEnumVar; ///< Standard union declaration based on enum.
UTypedefStandard uTypedefStandardVar; ///< Typedef standard union declaration.
/**
* @brief Contained based union.
*/
union UContained switch (uint32)
{
case 10: boolean bVal; ///< Bool value
case 20: uint64 uiVal; ///< 64-bit int value
case 30: string ssVal; ///< String value
default: float fVal; ///< Float value
};
UContained uContainedVar; ///< Contained union declaration.
/**
* @brief Contained based union.
*/
union UContainedEnum switch (ESwitch)
{
case ten: boolean bVal; ///< Bool value
case twenty: uint64 uiVal; ///< 64-bit int value
case thirty: string ssVal; ///< String value
default: float fVal; ///< Float value
};
UContainedEnum uContainedEnumVar; ///< Contained union declaration based on enum.
};
/**
* @brief Variable based union in struct.
*/
struct SVariableUnion
{
uint32 uiSwitch; ///< Switch value
/**
* @brief Contained union based on variable.
*/
union UContained switch (uiSwitch)
{
case 10: boolean bVal; ///< Bool value
case 20: uint64 uiVal; ///< 64-bit int value
case 30: string ssVal; ///< String value
default: float fVal; ///< Float value
};
UContained uContainedVar; ///< Contained union declaration.
};
/**
* @brief Multiple variable based unions in struct.
*/
struct SMultiVariableUnion
{
uint32 uiSwitch1; ///< Switch1 value
uint32 uiSwitch2; ///< Switch2 value
/**
* @brief Contained union based on variable #1.
*/
union UContained1 switch (uiSwitch1)
{
case 10: boolean bVal1; ///< Bool value
case 20: uint64 uiVal1; ///< 64-bit int value
case 30: string ssVal1; ///< String value
default: float fVal1; ///< Float value
};
/**
* @brief Contained union based on variable #2.
*/
union UContained2 switch (uiSwitch2)
{
case 10: boolean bVal2; ///< Bool value
case 20: uint64 uiVal2; ///< 64-bit int value
case 30: string ssVal2; ///< String value
default: float fVal2; ///< Float value
};
UContained1 uContainedVar1; ///< Contained union #1 declaration.
UContained2 uContainedVar2; ///< Contained union #2 declaration.
};
/**
* @brief Multiple variable based unions with simple data types in struct.
*/
struct SSimpleMultiVariableUnion
{
uint32 uiSwitch1; ///< Switch1 value
uint32 uiSwitch2; ///< Switch2 value
/**
* @brief Contained union based on variable #1.
*/
union UContained1 switch (uiSwitch1)
{
case 10: boolean bVal1; ///< Bool value
case 20: uint64 ui64Val1; ///< 64-bit int value
case 30: uint32 ui32Val1; ///< 32-bit int value
default: float fVal1; ///< Float value
};
/**
* @brief Contained union based on variable #2.
*/
union UContained2 switch (uiSwitch2)
{
case 10: boolean bVal2; ///< Bool value
case 20: uint64 ui64Val2; ///< 64-bit int value
case 30: uint32 ui32Val2; ///< 32-bit int value
default: float fVal2; ///< Float value
};
UContained1 uContainedVar1; ///< Contained union #1 declaration.
UContained2 uContainedVar2; ///< Contained union #2 declaration.
};
// This union will only work after anonymous struct/union support has been implemented: PBI #397894
/**
* @brief Use transparent unions with switches from the struct holding the unions.
*/
struct SSimpleAnonymousUnion
{
int32 iVal = 10; ///< Variable for the switch of the first union.
union switch (iVal) ///< Anonymous union
{
case 10:
int32 a; ///< Var a
case 20:
int32 b; ///< Var b
case 30:
int32 c; ///< Var c
};
};
/**
* @brief Use transparent unions with switches from the struct holding the unions.
*/
struct SSimpleMultipleAnonymousUnion
{
int32 iVal1 = 10; ///< Variable for the switch of the first union.
union switch (iVal1) ///< Anonymous union
{
case 10:
int32 a; ///< Var a
case 20:
int32 b; ///< Var b
case 30:
int32 c; ///< Var c
};
int32 iVal2 = 10; ///< Variable for the switch of the first union.
union switch (iVal2) ///< Anonymous union
{
case 10:
int32 d; ///< Var a
case 20:
int32 e; ///< Var b
case 30:
int32 f; ///< Var c
};
};
/**
* @brief Union with complex type as a variable.
*/
struct SComplexVarUnion
{
/// Complex type
struct SComplex
{
u8string ss1; ///< First string
u8string ss2; ///< Second string
};
int32 iVal = 10; ///< Variable for the switch of the first union.
union switch (iVal) ///< Anonymous union
{
case 10:
int32 i; ///< Simple type
case 20:
SComplex s; ///< Complex type
case 30:
u8string ss; ///< String type
};
};
struct STrippleIndirect
{
struct SDoubleIndirect
{
struct SIndirect
{
struct SSwitchValStruct
{
double dOtherVal;
int32 iVal = 5; ///< Variable for the switch of a separate union.
string ssOtherVal;
} sSwitchValStruct;
};
SIndirect sIndirect;
union UIndirect switch (sIndirect.sSwitchValStruct.iVal)
{
case 5:
int i;
case 6:
double d;
default:
string ss;
} uIndirect;
};
};
/**
* @brief Union with complex type as a variable and switch case that is in a variable of a variable array within a structure
* declaration of a base class two levels higher defined after the union definition.
*/
struct SComplexIndirectVarUnion
{
/// Complex type
struct SComplex
{
u8string ss1; ///< First string
u8string ss2; ///< Second string
};
struct SIndirect
{
int32 rgiVal[3] = { 10, 20, 30 }; ///< Variable for the switch of parallel laying unions.
};
SIndirect sIndirect;
STrippleIndirect::SDoubleIndirect sDoubleIndirect;
STrippleIndirect::SDoubleIndirect::SIndirect sOneHalfIndirect;
// Child structure
struct SChild
{
const int32 iArrayLen = 4; ///< Array length
/// Transparent union
union /*UUnnamed*/ switch (SComplexIndirectVarUnion::sIndirect.rgiVal[0])
{
case 10:
int32 i; ///< Simple type
case 20:
SComplex s; ///< Complex type
case 30:
u8string ss; ///< String type
} /*Anonymous*/;
/// Unnamed, but declared union
union /*UUnnamed2*/ switch (sIndirect.rgiVal[1])
{
case 10:
int32 i; ///< Simple type
case 20:
SComplex s; ///< Complex type
case 30:
u8string ss; ///< String type
} uUnnamed;
/// Named and declared union
union UNamed switch (/*Comment in switch case*/ sIndirect.rgiVal[2])
{
case 10:
int32 i; ///< Simple type
case 20:
SComplex s; ///< Complex type
case 30:
u8string ss; ///< String type
} uNamed;
UNamed uNamedArray[2][iArrayLen]; ///< Named array
union UDoubleIndirect switch (sDoubleIndirect.sIndirect.sSwitchValStruct.iVal /*Comment in switch case*/)
{
case 1:
int32 i; ///< Simple type
case 5:
SComplex s; ///< Complex type
case 10:
u8string ss; ///< String type
} uDoubleIndirect;
union UOneHalfIndirect switch (sOneHalfIndirect.sSwitchValStruct.iVal /*Comment in switch case*/)
{
case 1:
int32 i; ///< Simple type
case 5:
SComplex s; ///< Complex type
case 10:
u8string ss; ///< String type
} uOneHalfIndirect;
};
SChild sChild1; ///< Child declaration
SChild sChildArray[5][SChild::iArrayLen]; ///< Child array declaration
};
union UEmptyCase switch (int32)
{
case 10:
int32 i;
case 20:
uint32 ui;
case 30:
// nothing
case 40:
string ss;
default:
// nothing
};
#if 0
// NOTE: The following union is not allowed, since it uses an anonymous structure in a case switch. Anonymous structures are
// allowed in C, but not in C++ - therefore they are not supported by the compiler.
/**
* @brief Use transparent unions with switches from the struct holding the unions.
*/
struct STransparentUnion
{
int32 iVal = 10; ///< Variable for the switch of the first union.
union switch (iVal) ///< Anonymous union
{
case 10:
// NOTE: A variable based switched union cannot be used here, since it lacks the posibility for accessing the variable.
// NOTE: Only one nested anonymous type based union can be used; otherwise there would be multiple switch_value-variables.
union switch (int32) ///< Anonymous union
{
case 1: int32 a; ///< Var a
case 2: int32 b; ///< Var b
case 3: int32 c; ///< Var c
};
case 20:
struct ///< Anonymous struct
{
int32 d; ///< Var d
int32 e; ///< Var e
int32 f; ///< Var f
};
case 30:
int32 g; ///< Var g
};
};
#endif
/**
* @brief Union test interface to enforce proxy/stub creation.
*/
interface IUnionTest
{
/// Test a standard union with type based integral switch.
void TestStandardUnion(in UStandard uStandardVar);
/// Test a standard union with type based enum switch.
void TestStandardEnumUnion(in UStandardEnum uStandardEnumVar);
/// Test a contained standard union with type based switch.
void TestStandardContainedUnion(in SStandardUnion::UContained uStandardContainedVar);
/// Test a structure containing unions
void TestStandardUnionStruct(in SStandardUnion sStandardStructVar);
/// Test a structure with a union with variable based switch.
void TestVariableUnion(in SVariableUnion sVariableStructVar);
/// Test a structure with multiple unions with variable based switch.
void TestMultiVariableUnion(in SMultiVariableUnion sVariableStructVar);
/// Test a structure with multiple unions with variable based switch and simple data types.
void TestSimpleMultiVariableUnion(in SSimpleMultiVariableUnion sVariableStructVar);
/// Test a structure with an anonymous union with variable based switch and simple data types.
void TestSimpleAnonymousUnion(in SSimpleAnonymousUnion sVariableStructVar);
};