From e3402aca65925a898e92a604264600657e41ea21 Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Wed, 13 Oct 2021 19:33:23 +0200 Subject: [PATCH] [ATL][ATL_APITEST] Add test for CPath +small fixes --- modules/rostests/apitests/atl/CMakeLists.txt | 4 +- modules/rostests/apitests/atl/CPath.cpp | 59 ++++ modules/rostests/apitests/atl/CPath.inl | 283 ++++++++++++++++++ .../rostests/apitests/atl/devenv/ATLTest.sln | 13 + .../apitests/atl/devenv/CPath.vcxproj | 189 ++++++++++++ modules/rostests/apitests/atl/testlist.c | 2 + sdk/lib/atl/atlpath.h | 66 ++-- 7 files changed, 587 insertions(+), 29 deletions(-) create mode 100644 modules/rostests/apitests/atl/CPath.cpp create mode 100644 modules/rostests/apitests/atl/CPath.inl create mode 100644 modules/rostests/apitests/atl/devenv/CPath.vcxproj diff --git a/modules/rostests/apitests/atl/CMakeLists.txt b/modules/rostests/apitests/atl/CMakeLists.txt index bc3184793de..a414eb2d636 100644 --- a/modules/rostests/apitests/atl/CMakeLists.txt +++ b/modules/rostests/apitests/atl/CMakeLists.txt @@ -13,6 +13,8 @@ list(APPEND SOURCE CComVariant.cpp CHeapPtrList.cpp CImage.cpp + CPath.cpp + CPath.inl CRegKey.cpp CSimpleArray.cpp CSimpleMap.cpp @@ -31,6 +33,6 @@ add_executable(atl_apitest target_link_libraries(atl_apitest wine uuid cpprt atl_classes) set_target_cpp_properties(atl_apitest WITH_EXCEPTIONS) set_module_type(atl_apitest win32cui) -add_importlibs(atl_apitest rpcrt4 ole32 oleaut32 msimg32 gdi32 advapi32 user32 msvcrt kernel32 ntdll) +add_importlibs(atl_apitest shlwapi rpcrt4 ole32 oleaut32 msimg32 gdi32 advapi32 user32 msvcrt kernel32 ntdll) add_pch(atl_apitest precomp.h "${PCH_SKIP_SOURCE}") add_rostests_file(TARGET atl_apitest) diff --git a/modules/rostests/apitests/atl/CPath.cpp b/modules/rostests/apitests/atl/CPath.cpp new file mode 100644 index 00000000000..6f8c9581911 --- /dev/null +++ b/modules/rostests/apitests/atl/CPath.cpp @@ -0,0 +1,59 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Test for CPath + * COPYRIGHT: Copyright 2021 Mark Jansen + */ + +#include +#include "resource.h" + +#ifdef HAVE_APITEST + #include +#else + #include "atltest.h" +#endif + +#undef ok +#undef _T + +#define TEST_NAMEX(name) void test_##name##W() +#define CPathX CPathW +#define CStringX CStringW +#define _X(x) L ## x +#define XCHAR WCHAR +#define dbgstrx(x) wine_dbgstr_w(x) +#define ok ok_("CPathW:\n" __FILE__, __LINE__) +#define GetModuleFileNameX GetModuleFileNameW +#include "CPath.inl" + +#undef CPathX +#undef CStringX +#undef TEST_NAMEX +#undef _X +#undef XCHAR +#undef dbgstrx +#undef ok +#undef GetModuleFileNameX + +#define TEST_NAMEX(name) void test_##name##A() +#define CPathX CPathA +#define CStringX CStringA +#define _X(x) x +#define XCHAR CHAR +#define dbgstrx(x) (const char*)x +#define ok ok_("CPathA:\n" __FILE__, __LINE__) +#define GetModuleFileNameX GetModuleFileNameA +#include "CPath.inl" + +START_TEST(CPath) +{ + test_initW(); + test_initA(); + + test_modifyW(); + test_modifyA(); + + test_is_somethingW(); + test_is_somethingA(); +} diff --git a/modules/rostests/apitests/atl/CPath.inl b/modules/rostests/apitests/atl/CPath.inl new file mode 100644 index 00000000000..e8b919bf7ee --- /dev/null +++ b/modules/rostests/apitests/atl/CPath.inl @@ -0,0 +1,283 @@ + +TEST_NAMEX(init) +{ + CPathX test1; + CPathX test2(_X("C:\\SomePath\\.\\That\\..\\is.txt.exe.bin")); + CPathX test3(test2); + + ok(CStringX("").Compare(test1) == 0, "Expected test1 to be '', was: '%s'\n", dbgstrx(test1)); + ok(CStringX("C:\\SomePath\\.\\That\\..\\is.txt.exe.bin").Compare(test2) == 0, "Expected test2 to be 'C:\\SomePath\\.\\That\\..\\is.txt.exe.bin', was: '%s'\n", dbgstrx(test2)); + ok(CStringX("C:\\SomePath\\.\\That\\..\\is.txt.exe.bin").Compare(test3) == 0, "Expected test3 to be 'C:\\SomePath\\.\\That\\..\\is.txt.exe.bin', was: '%s'\n", dbgstrx(test3)); + + test1 = _X("test"); + test2 = _X("test"); + ok(CStringX("test").Compare(test1) == 0, "Expected test1 to be 'test', was: '%s'\n", dbgstrx(test1)); + ok(CStringX("test").Compare(test2) == 0, "Expected test2 to be 'test', was: '%s'\n", dbgstrx(test1)); + + +#if 0 + // this does not compile: + test3 = test1 + _X("test"); + test3 = test1 + test2; + CPathX test4(test1 + test2); +#endif + // This one compiles, but does not behave as wanted! + CPathX test5(test1 + _X("test")); + ok(CStringX("testtest").Compare(test5) == 0, "Expected test5 to be 'testtest', was: '%s'\n", dbgstrx(test1)); +} + +TEST_NAMEX(modify) +{ + CPathX test(_X("C:\\Some Path\\.\\That\\..\\is.txt.exe.bin")); + CPathX canon; + CPathX empty; + + test.Canonicalize(); + ok(CStringX("C:\\Some Path\\is.txt.exe.bin").Compare(test) == 0, + "Expected test to be 'C:\\Some Path\\is.txt.exe.bin', was: '%s'\n", dbgstrx(test)); + + canon.Canonicalize(); + ok(CStringX("\\").Compare(canon) == 0, + "Expected canon to be '\\', was: '%s'\n", dbgstrx(canon)); + + ok(test.FileExists() == FALSE, "FileExists succeeded for '%s'\n", dbgstrx(test)); + + int ext = test.FindExtension(); + ok(ext == 23, "Expected ext to be 23, was: %i\n", ext); + ext = empty.FindExtension(); + ok(ext == -1, "Expected ext to be -1, was: %i\n", ext); + + int name = test.FindFileName(); + ok(name == 13, "Expected name to be 13, was: %i\n", name); + name = empty.FindFileName(); + ok(name == -1, "Expected name to be -1, was: %i\n", name); + + int drive = test.GetDriveNumber(); + ok(drive == 2, "Expected drive to be 2, was: %i\n", drive); + drive = empty.GetDriveNumber(); + ok(drive == -1, "Expected drive to be -1, was: %i\n", drive); + + int skiproot = test.SkipRoot(); + ok(skiproot == 3, "Expected skiproot to be 3, was: %i\n", skiproot); + +#if 0 + // Does not handle an empty string correctly + skiproot = empty.SkipRoot(); + ok(skiproot == -1, "Expected skiproot to be -1, was: %i\n", skiproot); +#endif + + + test.RemoveExtension(); + ok(CStringX("C:\\Some Path\\is.txt.exe").Compare(test) == 0, + "Expected test to be 'C:\\Some Path\\is.txt.exe', was: '%s'\n", dbgstrx(test)); + + empty.RemoveExtension(); + ok(CStringX("").Compare(empty) == 0, + "Expected empty to be '', was: '%s'\n", dbgstrx(empty)); + + CStringX extName = test.GetExtension(); + ok(CStringX(".exe").Compare(extName) == 0, + "Expected test.GetExtension() to be '.exe', was: '%s'\n", dbgstrx(extName)); + + extName = empty.GetExtension(); + ok(CStringX("").Compare(extName) == 0, + "Expected empty.GetExtension() to be '', was: '%s'\n", dbgstrx(extName)); + + test.QuoteSpaces(); + ok(CStringX("\"C:\\Some Path\\is.txt.exe\"").Compare(test) == 0, + "Expected test to be '\"C:\\Some Path\\is.txt.exe\"', was: '%s'\n", dbgstrx(test)); + + empty.QuoteSpaces(); + ok(CStringX("").Compare(empty) == 0, + "Expected empty to be '', was: '%s'\n", dbgstrx(empty)); + + ok(test.RemoveFileSpec(), "RemoveFileSpec failed\n"); + ok(CStringX("\"C:\\Some Path").Compare(test) == 0, + "Expected test to be '\"C:\\Some Path', was: '%s'\n", dbgstrx(test)); + + ok(empty.RemoveFileSpec() == FALSE, "RemoveFileSpec succeeded\n"); + ok(CStringX("").Compare(empty) == 0, + "Expected empty to be '', was: '%s'\n", dbgstrx(empty)); + + test.UnquoteSpaces(); + ok(CStringX("\"C:\\Some Path").Compare(test) == 0, + "Expected test to be '\"C:\\Some Path\\is.txt.exe\"', was: '%s'\n", dbgstrx(test)); + + empty.UnquoteSpaces(); + ok(CStringX("").Compare(empty) == 0, + "Expected empty to be '', was: '%s'\n", dbgstrx(empty)); + + test.m_strPath += _X('"'); + + test.UnquoteSpaces(); + ok(CStringX("C:\\Some Path").Compare(test) == 0, + "Expected test to be 'C:\\Some Path', was: '%s'\n", dbgstrx(test)); + + empty.UnquoteSpaces(); + ok(CStringX("").Compare(empty) == 0, + "Expected empty to be '', was: '%s'\n", dbgstrx(empty)); + + ok(test.AddExtension(_X(".dummy")), "AddExtension failed\n"); + ok(CStringX("C:\\Some Path.dummy").Compare(test) == 0, + "Expected test to be 'C:\\Some Path.dummy', was: '%s'\n", dbgstrx(test)); + + ok(empty.AddExtension(_X(".dummy")), "AddExtension failed\n"); + ok(CStringX(".dummy").Compare(empty) == 0, + "Expected empty to be '.dummy', was: '%s'\n", dbgstrx(empty)); + empty = _X(""); + + test.AddBackslash(); + ok(CStringX("C:\\Some Path.dummy\\").Compare(test) == 0, + "Expected test to be 'C:\\Some Path.dummy\\', was: '%s'\n", dbgstrx(test)); + + empty.AddBackslash(); + ok(CStringX("").Compare(empty) == 0, + "Expected empty to be '', was: '%s'\n", dbgstrx(empty)); + + test.AddBackslash(); + ok(CStringX("C:\\Some Path.dummy\\").Compare(test) == 0, + "Expected test to be 'C:\\Some Path.dummy\\', was: '%s'\n", dbgstrx(test)); + + empty.AddBackslash(); + ok(CStringX("").Compare(empty) == 0, + "Expected empty to be '', was: '%s'\n", dbgstrx(empty)); + + test.RemoveBlanks(); + ok(CStringX("C:\\Some Path.dummy\\").Compare(test) == 0, + "Expected test to be 'C:\\Some Path.dummy\\', was: '%s'\n", dbgstrx(test)); + + empty.RemoveBlanks(); + ok(CStringX("").Compare(empty) == 0, + "Expected empty to be '', was: '%s'\n", dbgstrx(empty)); + + test = _X(" C:\\Some Path.dummy\\ "); + empty = _X(" "); + + test.RemoveBlanks(); + ok(CStringX("C:\\Some Path.dummy\\").Compare(test) == 0, + "Expected test to be 'C:\\Some Path.dummy\\', was: '%s'\n", dbgstrx(test)); + + empty.RemoveBlanks(); + ok(CStringX("").Compare(empty) == 0, + "Expected empty to be '', was: '%s'\n", dbgstrx(empty)); + + test.RemoveBackslash(); + ok(CStringX("C:\\Some Path.dummy").Compare(test) == 0, + "Expected test to be 'C:\\Some Path.dummy', was: '%s'\n", dbgstrx(test)); + + empty.RemoveBackslash(); + ok(CStringX("").Compare(empty) == 0, + "Expected empty to be '', was: '%s'\n", dbgstrx(empty)); + + ok(test.RenameExtension(_X(".txt")), "RenameExtension failed\n"); + ok(CStringX("C:\\Some Path.txt").Compare(test) == 0, + "Expected test to be 'C:\\Some Path.txt', was: '%s'\n", dbgstrx(test)); + + ok(empty.RenameExtension(_X(".txt")), "RenameExtension failed\n"); + ok(CStringX(".txt").Compare(empty) == 0, + "Expected empty to be '.txt', was: '%s'\n", dbgstrx(empty)); + + empty = _X(""); + + test += _X("something"); + ok(CStringX("C:\\Some Path.txt\\something").Compare(test) == 0, + "Expected test to be 'C:\\Some Path.txt', was: '%s'\n", dbgstrx(test)); + + empty += _X("something"); + ok(CStringX("something").Compare(empty) == 0, + "Expected empty to be 'something', was: '%s'\n", dbgstrx(empty)); + + ok(test.Append(_X("stuff.txt")), "Append failed\n"); + ok(CStringX("C:\\Some Path.txt\\something\\stuff.txt").Compare(test) == 0, + "Expected test to be 'C:\\Some Path.txt\\something\\stuff.txt', was: '%s'\n", dbgstrx(test)); + + ok(empty.Append(_X("")), "Append failed\n"); + ok(CStringX("something").Compare(empty) == 0, + "Expected empty to be 'something', was: '%s'\n", dbgstrx(empty)); + + ok(test.MatchSpec(_X("stuff.txt")) == FALSE, "MatchSpec succeeded for 'stuff.txt'\n"); + ok(test.MatchSpec(_X("stuff.exe")) == FALSE, "MatchSpec succeeded for 'stuff.exe'\n"); + ok(test.MatchSpec(_X(".txt")) == FALSE, "MatchSpec succeeded for '.txt'\n"); + ok(test.MatchSpec(_X("txt")) == FALSE, "MatchSpec succeeded for 'txt'\n"); + ok(test.MatchSpec(_X("*.txt")), "MatchSpec failed for '*.txt'\n"); + ok(test.MatchSpec(_X("C:\\*.txt")), "MatchSpec failed for 'C:\\*.txt'\n"); + ok(test.MatchSpec(_X("D:\\*.txt")) == FALSE, "MatchSpec succeeded for 'D:\\*.txt'\n"); + + CStringX same("C:\\Some Path.txt\\something\\stuff.txt"); + + const CStringX& constref = test; + ok(same.Compare(constref) == 0, + "Expected constref to be '%s', was: '%s'\n", dbgstrx(same), dbgstrx(constref)); + + + CStringX& ref = test; + ok(same.Compare(ref) == 0, + "Expected ref to be '%s', was: '%s'\n", dbgstrx(same), dbgstrx(ref)); + + const XCHAR* rawptr = test; + ok(same.Compare(rawptr) == 0, + "Expected rawptr to be '%s', was: '%s'\n", dbgstrx(same), dbgstrx(rawptr)); + + test.BuildRoot(5); + ok(CStringX("F:\\").Compare(test) == 0, + "Expected test to be 'F:\\', was: '%s'\n", dbgstrx(test)); + +#if 0 + // Asserts 'iDrive <= 25' + test.BuildRoot(105); + ok(CStringX("f:").Compare(test) == 0, + "Expected test to be 'f:', was: '%s'\n", dbgstrx(test)); +#endif + + test.Combine(_X("C:"), _X("test")); + ok(CStringX("C:\\test").Compare(test) == 0, + "Expected test to be 'C:\\test', was: '%s'\n", dbgstrx(test)); + + test.Combine(_X("C:\\"), _X("\\test\\")); + ok(CStringX("C:\\test\\").Compare(test) == 0, + "Expected test to be 'C:\\test\\', was: '%s'\n", dbgstrx(test)); + + test.Combine(_X("C:\\"), _X("\\test\\\\")); + ok(CStringX("C:\\test\\\\").Compare(test) == 0, + "Expected test to be 'C:\\test\\\\', was: '%s'\n", dbgstrx(test)); +} + +TEST_NAMEX(is_something) +{ + XCHAR Buffer[MAX_PATH] = { 0 }; + GetModuleFileNameX(NULL, Buffer, MAX_PATH); + + CPathX test(Buffer); + + ok(test.IsDirectory() == FALSE, "IsDirectory succeeded for '%s'\n", dbgstrx(test)); + ok(test.IsFileSpec() == FALSE, "IsFileSpec succeeded for '%s'\n", dbgstrx(test)); + ok(test.IsRelative() == FALSE, "IsRelative succeeded for '%s'\n", dbgstrx(test)); + ok(test.IsRoot() == FALSE, "IsRoot succeeded for '%s'\n", dbgstrx(test)); + ok(test.FileExists(), "FileExists failed for '%s'\n", dbgstrx(test)); + + test.StripPath(); + ok(test.IsFileSpec(), "IsFileSpec failed for '%s'\n", dbgstrx(test)); + ok(test.IsRelative(), "IsRelative failed for '%s'\n", dbgstrx(test)); + ok(test.IsRoot() == FALSE, "IsRoot succeeded for '%s'\n", dbgstrx(test)); + + + ok(test.StripToRoot() == FALSE, "StripToRoot succeeded for '%s'\n", dbgstrx(test)); + ok(CStringX("").Compare(test) == 0, + "Expected test to be '', was: '%s'\n", dbgstrx(test)); + + test = Buffer; + + ok(test.StripToRoot(), "StripToRoot failed for '%s'\n", dbgstrx(test)); + ok(test.IsRoot(), "IsRoot failed for '%s'\n", dbgstrx(test)); + + { + CStringX help = test; + ok(help.GetLength() == 3, "IsRoot weird result for '%s'\n", dbgstrx(help)); + } + + test = Buffer; + + test.RemoveFileSpec(); + ok(test.IsDirectory(), "IsDirectory failed for '%s'\n", dbgstrx(test)); +} + diff --git a/modules/rostests/apitests/atl/devenv/ATLTest.sln b/modules/rostests/apitests/atl/devenv/ATLTest.sln index 9811121c7fd..2a923a69b57 100644 --- a/modules/rostests/apitests/atl/devenv/ATLTest.sln +++ b/modules/rostests/apitests/atl/devenv/ATLTest.sln @@ -27,6 +27,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CComHeapPtr", "CComHeapPtr. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SubclassWindow", "SubclassWindow.vcxproj", "{ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CPath", "CPath.vcxproj", "{7119D446-43C1-425A-91D0-CDFA49B8B59A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -131,8 +133,19 @@ Global {ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}.Release|x64.Build.0 = Release|x64 {ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}.Release|x86.ActiveCfg = Release|Win32 {ABACDAE7-3936-17E1-7525-96C4A7DA4CD2}.Release|x86.Build.0 = Release|Win32 + {7119D446-43C1-425A-91D0-CDFA49B8B59A}.Debug|x64.ActiveCfg = Debug|x64 + {7119D446-43C1-425A-91D0-CDFA49B8B59A}.Debug|x64.Build.0 = Debug|x64 + {7119D446-43C1-425A-91D0-CDFA49B8B59A}.Debug|x86.ActiveCfg = Debug|Win32 + {7119D446-43C1-425A-91D0-CDFA49B8B59A}.Debug|x86.Build.0 = Debug|Win32 + {7119D446-43C1-425A-91D0-CDFA49B8B59A}.Release|x64.ActiveCfg = Release|x64 + {7119D446-43C1-425A-91D0-CDFA49B8B59A}.Release|x64.Build.0 = Release|x64 + {7119D446-43C1-425A-91D0-CDFA49B8B59A}.Release|x86.ActiveCfg = Release|Win32 + {7119D446-43C1-425A-91D0-CDFA49B8B59A}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6603F212-2099-4D49-8667-FA9DC49C048C} + EndGlobalSection EndGlobal diff --git a/modules/rostests/apitests/atl/devenv/CPath.vcxproj b/modules/rostests/apitests/atl/devenv/CPath.vcxproj new file mode 100644 index 00000000000..b1a43ae24ce --- /dev/null +++ b/modules/rostests/apitests/atl/devenv/CPath.vcxproj @@ -0,0 +1,189 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {7119D446-43C1-425A-91D0-CDFA49B8B59A} + 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 + $(ProjectName)\$(Configuration)\ + + + true + true + $(ProjectName)\$(Platform)\$(Configuration)\ + + + true + false + $(ProjectName)\$(Configuration)\ + + + true + false + $(ProjectName)\$(Platform)\$(Configuration)\ + + + + 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 213ce2419c4..510b5f4d834 100644 --- a/modules/rostests/apitests/atl/testlist.c +++ b/modules/rostests/apitests/atl/testlist.c @@ -12,6 +12,7 @@ extern void func_CComQIPtr(void); extern void func_CComVariant(void); extern void func_CHeapPtrList(void); extern void func_CImage(void); +extern void func_CPath(void); extern void func_CRegKey(void); extern void func_CSimpleArray(void); extern void func_CSimpleMap(void); @@ -31,6 +32,7 @@ const struct test winetest_testlist[] = { "CComVariant", func_CComVariant }, { "CHeapPtrList", func_CHeapPtrList }, { "CImage", func_CImage }, + { "CPath", func_CPath }, { "CRegKey", func_CRegKey }, { "CSimpleArray", func_CSimpleArray }, { "CSimpleMap", func_CSimpleMap }, diff --git a/sdk/lib/atl/atlpath.h b/sdk/lib/atl/atlpath.h index 942b47f638f..6c5c03df68a 100644 --- a/sdk/lib/atl/atlpath.h +++ b/sdk/lib/atl/atlpath.h @@ -6,8 +6,6 @@ #ifndef __ATLPATH_H__ #define __ATLPATH_H__ -// WARNING: Untested code - #pragma once #include @@ -21,36 +19,36 @@ template class CPathT { // const - inline BOOL PathFileExistsX(LPCSTR pszPath) { return PathFileExistsA(pszPath); } - inline BOOL PathFileExistsX(LPCWSTR pszPath) { return PathFileExistsW(pszPath); } - inline LPCSTR PathFindExtensionX(LPCSTR pszPath) { return PathFindExtensionA(pszPath); } - inline LPCWSTR PathFindExtensionX(LPCWSTR pszPath) { return PathFindExtensionW(pszPath); } - inline LPCSTR PathFindFileNameX(LPCSTR pszPath) { return PathFindFileNameA(pszPath); } - inline LPCWSTR PathFindFileNameX(LPCWSTR pszPath) { return PathFindFileNameW(pszPath); } - inline int PathGetDriveNumberX(LPCSTR pszPath) { return PathGetDriveNumberA(pszPath); } - inline int PathGetDriveNumberX(LPCWSTR pszPath) { return PathGetDriveNumberW(pszPath); } - inline BOOL PathIsDirectoryX(LPCSTR pszPath) { return PathIsDirectoryA(pszPath); } - inline BOOL PathIsDirectoryX(LPCWSTR pszPath) { return PathIsDirectoryW(pszPath); } - inline BOOL PathIsFileSpecX(LPCSTR pszPath) { return PathIsFileSpecA(pszPath); } - inline BOOL PathIsFileSpecX(LPCWSTR pszPath) { return PathIsFileSpecW(pszPath); } + inline BOOL PathFileExistsX(LPCSTR pszPath) const { return PathFileExistsA(pszPath); } + inline BOOL PathFileExistsX(LPCWSTR pszPath) const { return PathFileExistsW(pszPath); } + inline LPCSTR PathFindExtensionX(LPCSTR pszPath) const { return PathFindExtensionA(pszPath); } + inline LPCWSTR PathFindExtensionX(LPCWSTR pszPath) const { return PathFindExtensionW(pszPath); } + inline LPCSTR PathFindFileNameX(LPCSTR pszPath) const { return PathFindFileNameA(pszPath); } + inline LPCWSTR PathFindFileNameX(LPCWSTR pszPath) const { return PathFindFileNameW(pszPath); } + inline int PathGetDriveNumberX(LPCSTR pszPath) const { return PathGetDriveNumberA(pszPath); } + inline int PathGetDriveNumberX(LPCWSTR pszPath) const { return PathGetDriveNumberW(pszPath); } + inline BOOL PathIsDirectoryX(LPCSTR pszPath) const { return PathIsDirectoryA(pszPath); } + inline BOOL PathIsDirectoryX(LPCWSTR pszPath) const { return PathIsDirectoryW(pszPath); } + inline BOOL PathIsFileSpecX(LPCSTR pszPath) const { return PathIsFileSpecA(pszPath); } + inline BOOL PathIsFileSpecX(LPCWSTR pszPath) const { return PathIsFileSpecW(pszPath); } inline BOOL PathIsPrefixX(LPCSTR pszPath, LPCSTR pszPrefix) { return PathIsPrefixA(pszPath, pszPrefix); } inline BOOL PathIsPrefixX(LPCWSTR pszPath, LPCWSTR pszPrefix) { return PathIsPrefixW(pszPath, pszPrefix); } - inline BOOL PathIsRelativeX(LPCSTR pszPath) { return PathIsRelativeA(pszPath); } - inline BOOL PathIsRelativeX(LPCWSTR pszPath) { return PathIsRelativeW(pszPath); } - inline BOOL PathIsRootX(LPCSTR pszPath) { return PathIsRootA(pszPath); } - inline BOOL PathIsRootX(LPCWSTR pszPath) { return PathIsRootW(pszPath); } - inline BOOL PathIsSameRootX(LPCSTR pszPath, LPCSTR pszOther) { return PathIsSameRootA(pszPath, pszOther); } - inline BOOL PathIsSameRootX(LPCWSTR pszPath, LPCWSTR pszOther) { return PathIsSameRootW(pszPath, pszOther); } + inline BOOL PathIsRelativeX(LPCSTR pszPath) const { return PathIsRelativeA(pszPath); } + inline BOOL PathIsRelativeX(LPCWSTR pszPath) const { return PathIsRelativeW(pszPath); } + inline BOOL PathIsRootX(LPCSTR pszPath) const { return PathIsRootA(pszPath); } + inline BOOL PathIsRootX(LPCWSTR pszPath) const { return PathIsRootW(pszPath); } + inline BOOL PathIsSameRootX(LPCSTR pszPath, LPCSTR pszOther) const { return PathIsSameRootA(pszPath, pszOther); } + inline BOOL PathIsSameRootX(LPCWSTR pszPath, LPCWSTR pszOther) const { return PathIsSameRootW(pszPath, pszOther); } inline BOOL PathIsUNCX(LPCSTR pszPath) { return PathIsUNCA(pszPath); } inline BOOL PathIsUNCX(LPCWSTR pszPath) { return PathIsUNCW(pszPath); } inline BOOL PathIsUNCServerX(LPCSTR pszPath) { return PathIsUNCServerA(pszPath); } inline BOOL PathIsUNCServerX(LPCWSTR pszPath) { return PathIsUNCServerW(pszPath); } inline BOOL PathIsUNCServerShareX(LPCSTR pszPath) { return PathIsUNCServerShareA(pszPath); } inline BOOL PathIsUNCServerShareX(LPCWSTR pszPath) { return PathIsUNCServerShareW(pszPath); } - inline BOOL PathMatchSpecX(LPCSTR pszPath, LPCSTR pszSpec) { return PathMatchSpecA(pszPath, pszSpec); } - inline BOOL PathMatchSpecX(LPCWSTR pszPath, LPCWSTR pszSpec) { return PathMatchSpecW(pszPath, pszSpec); } - inline LPCSTR PathSkipRootX(LPCSTR pszPath) { return PathSkipRootA(pszPath); } - inline LPCWSTR PathSkipRootX(LPCWSTR pszPath) { return PathSkipRootW(pszPath); } + inline BOOL PathMatchSpecX(LPCSTR pszPath, LPCSTR pszSpec) const { return PathMatchSpecA(pszPath, pszSpec); } + inline BOOL PathMatchSpecX(LPCWSTR pszPath, LPCWSTR pszSpec) const { return PathMatchSpecW(pszPath, pszSpec); } + inline LPCSTR PathSkipRootX(LPCSTR pszPath) const { return PathSkipRootA(pszPath); } + inline LPCWSTR PathSkipRootX(LPCWSTR pszPath) const { return PathSkipRootW(pszPath); } // non-const inline void PathAddBackslashX(LPSTR pszPath) { PathAddBackslashA(pszPath); } @@ -196,12 +194,22 @@ public: int FindExtension() const { - return PathFindExtensionX(m_strPath); + PCXSTR extension = PathFindExtensionX(m_strPath); + if (*extension == '\0') + return -1; + + PCXSTR str = m_strPath; + return (int)(extension - str); } int FindFileName() const { - return PathFindFileNameX(m_strPath); + PCXSTR filename = PathFindFileNameX(m_strPath); + if (*filename == '\0') + return -1; + + PCXSTR str = m_strPath; + return (int)(filename - str); } int GetDriveNumber() const @@ -333,7 +341,8 @@ public: int SkipRoot() const { - return PathSkipRootX(m_strPath); + PCXSTR str = m_strPath; + return (int)(PathSkipRootX(m_strPath) - str); } void StripPath() @@ -375,7 +384,8 @@ public: CPathT& operator+=(PCXSTR pszMore) { - m_strPath += pszMore; + Append(pszMore); + return *this; } };