diff --git a/modules/rostests/apitests/atl/CAtlList.cpp b/modules/rostests/apitests/atl/CAtlList.cpp new file mode 100644 index 00000000000..eb8cb761620 --- /dev/null +++ b/modules/rostests/apitests/atl/CAtlList.cpp @@ -0,0 +1,81 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Test for CAtlList + * COPYRIGHT: Copyright 2016-2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + * Copyright 2019 Mark Jansen (mark.jansen@reactos.org) + */ + +#ifdef HAVE_APITEST + #include +#else + #include + #include + #include + int g_tests_executed = 0; + int g_tests_failed = 0; + void ok_func(const char *file, int line, bool value, const char *fmt, ...) + { + va_list va; + va_start(va, fmt); + if (!value) + { + printf("%s (%d): ", file, line); + vprintf(fmt, va); + g_tests_failed++; + } + g_tests_executed++; + va_end(va); + } + #undef ok + #define ok(value, ...) ok_func(__FILE__, __LINE__, value, __VA_ARGS__) + #define START_TEST(x) int main(void) +#endif + +#include +#include + + +START_TEST(CAtlList) +{ + CAtlList list1; + + ok(list1.GetCount() == 0, "Expected list1's size is zero, was %d\n", list1.GetCount()); + list1.AddTail(56); + ok(list1.GetCount() == 1, "Expected list1's size is 1, was %d\n", list1.GetCount()); + POSITION head = list1.AddHead(12); + ok(list1.GetCount() == 2, "Expected list1's size is 2, was %d\n", list1.GetCount()); + POSITION tail = list1.AddTail(90); + ok(list1.GetCount() == 3, "Expected list1's size is 3, was %d\n", list1.GetCount()); + + list1.InsertBefore(head, -123); + list1.InsertAfter(head, 34); // no longer head, but the POSITION should still be valid.. + + list1.InsertBefore(tail, 78); + list1.InsertAfter(tail, -44); + + int expected[] = {-123, 12, 34, 56, 78, 90, -44 }; + int expected_size = sizeof(expected) / sizeof(expected[0]); + int index = 0; + POSITION it = list1.GetHeadPosition(); + while (it != NULL) + { + ok(index < expected_size, "Too many items, expected %d, got %d!\n", expected_size, (index+1)); + int value = list1.GetNext(it); + if (index < expected_size) + { + ok(value == expected[index], "Wrong value, got %d, expected %d\n", value, expected[index]); + } + else + { + ok(0, "Extra value: %d\n", value); + } + index++; + } + ok(it == NULL, "it does still point to something!\n"); + +#ifndef HAVE_APITEST + printf("CAtlList: %i tests executed (0 marked as todo, %i failures), 0 skipped.\n", g_tests_executed, g_tests_failed); + return g_tests_failed; +#endif +} diff --git a/modules/rostests/apitests/atl/CMakeLists.txt b/modules/rostests/apitests/atl/CMakeLists.txt index 8055fffc456..7ff83d6691d 100644 --- a/modules/rostests/apitests/atl/CMakeLists.txt +++ b/modules/rostests/apitests/atl/CMakeLists.txt @@ -7,6 +7,7 @@ include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/atl) list(APPEND SOURCE atltypes.cpp CAtlFileMapping.cpp + CAtlList.cpp CComBSTR.cpp CComHeapPtr.cpp CComObject.cpp diff --git a/modules/rostests/apitests/atl/devenv/ATLTest.sln b/modules/rostests/apitests/atl/devenv/ATLTest.sln index 0244f719801..044cdd3c3ad 100644 --- a/modules/rostests/apitests/atl/devenv/ATLTest.sln +++ b/modules/rostests/apitests/atl/devenv/ATLTest.sln @@ -17,6 +17,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CComQIPtr", "CComQIPtr.vcxp EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CAtlFileMapping", "CAtlFile.vcxproj", "{3AE82A8E-D43D-41F6-8093-9C687283FAB6}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CAtlList", "CAtlList.vcxproj", "{00C3325D-0E3D-43F1-92C8-F7D5C32F70C6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -81,6 +83,14 @@ Global {3AE82A8E-D43D-41F6-8093-9C687283FAB6}.Release|x64.Build.0 = Release|x64 {3AE82A8E-D43D-41F6-8093-9C687283FAB6}.Release|x86.ActiveCfg = Release|Win32 {3AE82A8E-D43D-41F6-8093-9C687283FAB6}.Release|x86.Build.0 = Release|Win32 + {00C3325D-0E3D-43F1-92C8-F7D5C32F70C6}.Debug|x64.ActiveCfg = Debug|x64 + {00C3325D-0E3D-43F1-92C8-F7D5C32F70C6}.Debug|x64.Build.0 = Debug|x64 + {00C3325D-0E3D-43F1-92C8-F7D5C32F70C6}.Debug|x86.ActiveCfg = Debug|Win32 + {00C3325D-0E3D-43F1-92C8-F7D5C32F70C6}.Debug|x86.Build.0 = Debug|Win32 + {00C3325D-0E3D-43F1-92C8-F7D5C32F70C6}.Release|x64.ActiveCfg = Release|x64 + {00C3325D-0E3D-43F1-92C8-F7D5C32F70C6}.Release|x64.Build.0 = Release|x64 + {00C3325D-0E3D-43F1-92C8-F7D5C32F70C6}.Release|x86.ActiveCfg = Release|Win32 + {00C3325D-0E3D-43F1-92C8-F7D5C32F70C6}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/modules/rostests/apitests/atl/devenv/CAtlList.vcxproj b/modules/rostests/apitests/atl/devenv/CAtlList.vcxproj new file mode 100644 index 00000000000..7bcb1c8299b --- /dev/null +++ b/modules/rostests/apitests/atl/devenv/CAtlList.vcxproj @@ -0,0 +1,176 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {00C3325D-0E3D-43F1-92C8-F7D5C32F70C6} + 8.1 + AtlProj + + + + Application + true + v140_xp + Unicode + + + Application + false + v140_xp + Unicode + + + Application + true + v140_xp + Unicode + + + Application + false + v140_xp + Unicode + + + + + + + + + + + + + + + + + + + + + true + true + + + true + true + + + true + false + + + true + false + + + + NotUsing + Level3 + Disabled + WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) + true + + + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + _DEBUG;%(PreprocessorDefinitions) + + + Console + true + + + + + NotUsing + Level3 + Disabled + _WINDOWS;_DEBUG;%(PreprocessorDefinitions) + true + + + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + _DEBUG;%(PreprocessorDefinitions) + + + Console + true + + + + + NotUsing + Level3 + MaxSpeed + WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) + true + + + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + NDEBUG;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + NotUsing + Level3 + MaxSpeed + _WINDOWS;NDEBUG;%(PreprocessorDefinitions) + true + + + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + NDEBUG;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + MultiThreaded + MultiThreaded + MultiThreadedDebug + MultiThreadedDebug + NotUsing + NotUsing + NotUsing + NotUsing + + + + + + \ No newline at end of file diff --git a/modules/rostests/apitests/atl/testlist.c b/modules/rostests/apitests/atl/testlist.c index 0fa460898a5..73546673240 100644 --- a/modules/rostests/apitests/atl/testlist.c +++ b/modules/rostests/apitests/atl/testlist.c @@ -3,6 +3,7 @@ extern void func_atltypes(void); extern void func_CAtlFileMapping(void); +extern void func_CAtlList(void); extern void func_CComBSTR(void); extern void func_CComHeapPtr(void); extern void func_CComObject(void); @@ -18,6 +19,7 @@ const struct test winetest_testlist[] = { { "atltypes", func_atltypes }, { "CAtlFileMapping", func_CAtlFileMapping }, + { "CAtlList", func_CAtlList }, { "CComBSTR", func_CComBSTR }, { "CComHeapPtr", func_CComHeapPtr }, { "CComObject", func_CComObject }, diff --git a/sdk/lib/atl/atlcoll.h b/sdk/lib/atl/atlcoll.h index c8b0e7a0531..ae47ff7887f 100644 --- a/sdk/lib/atl/atlcoll.h +++ b/sdk/lib/atl/atlcoll.h @@ -198,6 +198,10 @@ public: E RemoveHead(); E RemoveTail(); + + POSITION InsertBefore(_In_ POSITION pos, INARGTYPE element); + POSITION InsertAfter(_In_ POSITION pos, INARGTYPE element); + void RemoveAll(); void RemoveAt(_In_ POSITION pos); @@ -389,6 +393,50 @@ E CAtlList::RemoveTail() return Element; } +template +POSITION CAtlList::InsertBefore(_In_ POSITION pos, _In_ INARGTYPE element) +{ + if (pos == NULL) + return AddHead(element); + + CNode* OldNode = (CNode*)pos; + CNode* Node = CreateNode(element, OldNode->m_Prev, OldNode); + + if (OldNode->m_Prev != NULL) + { + OldNode->m_Prev->m_Next = Node; + } + else + { + m_HeadNode = Node; + } + OldNode->m_Prev = Node; + + return (POSITION)Node; +} + +template +POSITION CAtlList::InsertAfter(_In_ POSITION pos, _In_ INARGTYPE element) +{ + if (pos == NULL) + return AddTail(element); + + CNode* OldNode = (CNode*)pos; + CNode* Node = CreateNode(element, OldNode, OldNode->m_Next); + + if (OldNode->m_Next != NULL) + { + OldNode->m_Next->m_Prev = Node; + } + else + { + m_TailNode = Node; + } + OldNode->m_Next = Node; + + return (POSITION)Node; +} + template void CAtlList::RemoveAll() {