diff options
Diffstat (limited to 'zen')
-rw-r--r-- | zen/FindFilePlus/FindFilePlus.vcxproj | 16 | ||||
-rw-r--r-- | zen/IFileOperation/FileOperation_Vista.vcxproj | 20 | ||||
-rw-r--r-- | zen/basic_math.h | 2 | ||||
-rw-r--r-- | zen/file_handling.cpp | 128 | ||||
-rw-r--r-- | zen/file_handling.h | 17 | ||||
-rw-r--r-- | zen/notify_removal.cpp | 7 | ||||
-rw-r--r-- | zen/optional.h | 19 | ||||
-rw-r--r-- | zen/privilege.cpp | 10 | ||||
-rw-r--r-- | zen/recycler.cpp | 10 | ||||
-rw-r--r-- | zen/scroll_window_under_cursor.cpp | 6 | ||||
-rw-r--r-- | zen/serialize.h | 2 | ||||
-rw-r--r-- | zen/string_tools.h | 2 | ||||
-rw-r--r-- | zen/symlink_target.h | 6 | ||||
-rw-r--r-- | zen/thread.h | 3 | ||||
-rw-r--r-- | zen/warn_static.h | 12 | ||||
-rw-r--r-- | zen/zstring.cpp | 4 |
16 files changed, 96 insertions, 168 deletions
diff --git a/zen/FindFilePlus/FindFilePlus.vcxproj b/zen/FindFilePlus/FindFilePlus.vcxproj index 73b7f70e..15ea6adf 100644 --- a/zen/FindFilePlus/FindFilePlus.vcxproj +++ b/zen/FindFilePlus/FindFilePlus.vcxproj @@ -28,23 +28,23 @@ <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -90,7 +90,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>_X86_;_DEBUG;_WINDOWS;_USRDLL;FIND_FILE_PLUS_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -101,6 +101,7 @@ <DisableSpecificWarnings>4100</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -125,7 +126,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>_AMD64_;_DEBUG;_WINDOWS;_USRDLL;FIND_FILE_PLUS_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -136,6 +137,7 @@ <DisableSpecificWarnings>4100</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -168,6 +170,7 @@ <DisableSpecificWarnings>4100</DisableSpecificWarnings> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -205,6 +208,7 @@ <DisableSpecificWarnings>4100</DisableSpecificWarnings> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> diff --git a/zen/IFileOperation/FileOperation_Vista.vcxproj b/zen/IFileOperation/FileOperation_Vista.vcxproj index e5165514..20f09a00 100644 --- a/zen/IFileOperation/FileOperation_Vista.vcxproj +++ b/zen/IFileOperation/FileOperation_Vista.vcxproj @@ -29,23 +29,23 @@ <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> <WholeProgramOptimization>true</WholeProgramOptimization> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>DynamicLibrary</ConfigurationType> <CharacterSet>Unicode</CharacterSet> - <PlatformToolset>Windows7.1SDK</PlatformToolset> + <PlatformToolset>v120_xp</PlatformToolset> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> @@ -87,7 +87,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>WXINTL_NO_GETTEXT_MACRO;ZEN_WIN;_DEBUG;_WINDOWS;_USRDLL;FILE_OP_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -99,6 +99,7 @@ <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -124,7 +125,7 @@ <ClCompile> <Optimization>Disabled</Optimization> <PreprocessorDefinitions>WXINTL_NO_GETTEXT_MACRO;ZEN_WIN;_DEBUG;_WINDOWS;_USRDLL;FILE_OP_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <MinimalRebuild>false</MinimalRebuild> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader> @@ -136,6 +137,7 @@ <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> <SmallerTypeCheck>true</SmallerTypeCheck> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> @@ -170,11 +172,12 @@ <DisableSpecificWarnings>4100;4996;4512</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> + <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> @@ -209,11 +212,12 @@ <DisableSpecificWarnings>4100;4996;4512</DisableSpecificWarnings> <AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories> <ForcedIncludeFiles>zen/warn_static.h</ForcedIncludeFiles> + <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <SuppressStartupBanner>true</SuppressStartupBanner> - <GenerateDebugInformation>false</GenerateDebugInformation> + <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> diff --git a/zen/basic_math.h b/zen/basic_math.h index 05d892ee..56cfd923 100644 --- a/zen/basic_math.h +++ b/zen/basic_math.h @@ -228,6 +228,8 @@ bool isNull(T value) inline int round(double d) { + assert(d - 0.5 >= std::numeric_limits<int>::min() && //if double is larger than what int can represent: + d + 0.5 <= std::numeric_limits<int>::max()); //=> undefined behavior! return static_cast<int>(d < 0 ? d - 0.5 : d + 0.5); } diff --git a/zen/file_handling.cpp b/zen/file_handling.cpp index 103a39f7..3f8d5bbd 100644 --- a/zen/file_handling.cpp +++ b/zen/file_handling.cpp @@ -45,74 +45,44 @@ using namespace zen; -warn_static("remove after test") -namespace -{ -void writeSysErrorIfNeeded(std::wstring* sysErrorMsg, const wchar_t* functionName, ErrorCode lastError) -{ - if (sysErrorMsg) - { - //skip uninteresting error codes: -#ifdef ZEN_WIN - if (lastError == ERROR_FILE_NOT_FOUND || - lastError == ERROR_PATH_NOT_FOUND) return; - //lastError == ERROR_BAD_NETPATH || //e.g. for a path like: \\192.168.1.1\test - //lastError == ERROR_NETNAME_DELETED; - -#elif defined ZEN_LINUX || defined ZEN_MAC - if (lastError == ENOENT) return; -#endif - *sysErrorMsg = formatSystemError(functionName, lastError); - } -} -} - - -bool zen::fileExists(const Zstring& filename, std::wstring* sysErrorMsg) +bool zen::fileExists(const Zstring& filename) { //symbolic links (broken or not) are also treated as existing files! #ifdef ZEN_WIN - const wchar_t functionName[] = L"GetFileAttributes"; const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(filename).c_str()); if (attr != INVALID_FILE_ATTRIBUTES) return (attr & FILE_ATTRIBUTE_DIRECTORY) == 0; //returns true for (file-)symlinks also #elif defined ZEN_LINUX || defined ZEN_MAC - const wchar_t functionName[] = L"lstat"; struct ::stat fileInfo = {}; - if (::lstat(filename.c_str(), &fileInfo) == 0) - return S_ISREG(fileInfo.st_mode) || S_ISLNK(fileInfo.st_mode); //in Linux a symbolic link is neither file nor directory + if (::stat(filename.c_str(), &fileInfo) == 0) //follow symlinks! + return S_ISREG(fileInfo.st_mode); #endif - writeSysErrorIfNeeded(sysErrorMsg, functionName, getLastError()); return false; } -bool zen::dirExists(const Zstring& dirname, std::wstring* sysErrorMsg) +bool zen::dirExists(const Zstring& dirname) { //symbolic links (broken or not) are also treated as existing directories! #ifdef ZEN_WIN - const wchar_t functionName[] = L"GetFileAttributes"; const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(dirname).c_str()); if (attr != INVALID_FILE_ATTRIBUTES) return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0; //returns true for (dir-)symlinks also #elif defined ZEN_LINUX || defined ZEN_MAC - const wchar_t functionName[] = L"lstat"; struct ::stat dirInfo = {}; - if (::lstat(dirname.c_str(), &dirInfo) == 0) - return S_ISDIR(dirInfo.st_mode) || S_ISLNK(dirInfo.st_mode); //in Linux a symbolic link is neither file nor directory + if (::stat(dirname.c_str(), &dirInfo) == 0) //follow symlinks! + return S_ISDIR(dirInfo.st_mode); #endif - writeSysErrorIfNeeded(sysErrorMsg, functionName, getLastError()); return false; } -bool zen::symlinkExists(const Zstring& linkname, std::wstring* sysErrorMsg) +bool zen::symlinkExists(const Zstring& linkname) { #ifdef ZEN_WIN - const wchar_t functionName[] = L"FindFirstFile"; WIN32_FIND_DATA linkInfo = {}; const HANDLE searchHandle = ::FindFirstFile(applyLongPathPrefix(linkname).c_str(), &linkInfo); if (searchHandle != INVALID_HANDLE_VALUE) @@ -122,20 +92,17 @@ bool zen::symlinkExists(const Zstring& linkname, std::wstring* sysErrorMsg) } #elif defined ZEN_LINUX || defined ZEN_MAC - const wchar_t functionName[] = L"lstat"; struct ::stat linkInfo = {}; if (::lstat(linkname.c_str(), &linkInfo) == 0) return S_ISLNK(linkInfo.st_mode); #endif - writeSysErrorIfNeeded(sysErrorMsg, functionName, getLastError()); return false; } -bool zen::somethingExists(const Zstring& objname, std::wstring* sysErrorMsg) +bool zen::somethingExists(const Zstring& objname) { #ifdef ZEN_WIN - const wchar_t functionName[] = L"GetFileAttributes"; const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(objname).c_str()); if (attr != INVALID_FILE_ATTRIBUTES) return true; @@ -143,35 +110,14 @@ bool zen::somethingExists(const Zstring& objname, std::wstring* sysErrorMsg) return true; #elif defined ZEN_LINUX || defined ZEN_MAC - const wchar_t functionName[] = L"lstat"; struct ::stat fileInfo = {}; if (::lstat(objname.c_str(), &fileInfo) == 0) return true; #endif - writeSysErrorIfNeeded(sysErrorMsg, functionName, getLastError()); return false; } -SymLinkType zen::getSymlinkType(const Zstring& linkname) //throw() -{ - assert(symlinkExists(linkname)); -#ifdef ZEN_WIN - const DWORD attr = ::GetFileAttributes(applyLongPathPrefix(linkname).c_str()); - if (attr == INVALID_FILE_ATTRIBUTES) - return SYMLINK_TYPE_UNKNOWN; - return (attr & FILE_ATTRIBUTE_DIRECTORY) ? SYMLINK_TYPE_DIR : SYMLINK_TYPE_FILE; - -#elif defined ZEN_LINUX || defined ZEN_MAC - //S_ISDIR and S_ISLNK are mutually exclusive on Linux => explicitly need to follow link - struct ::stat fileInfo = {}; - if (::stat(linkname.c_str(), &fileInfo) != 0) - return SYMLINK_TYPE_UNKNOWN; - return S_ISDIR(fileInfo.st_mode) ? SYMLINK_TYPE_DIR : SYMLINK_TYPE_FILE; -#endif -} - - namespace { #ifdef ZEN_WIN @@ -531,7 +477,7 @@ public: { renameFile_sub(unrelatedFileParked, unrelatedFile); //throw FileError, ErrorDifferentVolume } - catch (...) {} + catch (FileError&) {} } private: Zstring unrelatedFile; @@ -580,17 +526,10 @@ public: } virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) { - switch (getSymlinkType(fullName)) - { - case SYMLINK_TYPE_DIR: - dirs_.push_back(shortName); - break; - - case SYMLINK_TYPE_FILE: - case SYMLINK_TYPE_UNKNOWN: - files_.push_back(shortName); - break; - } + if (dirExists(fullName)) //dir symlink + dirs_.push_back(shortName); + else //file symlink, broken symlink + files_.push_back(shortName); return LINK_SKIP; } virtual TraverseCallback* onDir(const Zchar* shortName, const Zstring& fullName) @@ -918,7 +857,7 @@ void zen::setFileTime(const Zstring& filename, const Int64& modTime, ProcSymlink } } #ifndef NDEBUG //dst hack: verify data written - if (dst::isFatDrive(filename) && !dirExists(filename)) //throw() + if (dst::isFatDrive(filename) && fileExists(filename)) //throw() { FILETIME creationTimeDbg = {}; FILETIME lastWriteTimeDbg = {}; @@ -1282,13 +1221,13 @@ void zen::makeDirectory(const Zstring& directory, bool failIfExists) //throw Fil } catch (const FileError&) { - if (dirExists(directory)) //a file system race-condition! + /* + could there be situations where a directory/network path exists, + but creation fails with error different than "ErrorTargetExisting"?? + - creation of C:\ fails with ERROR_ACCESS_DENIED rather than ERROR_ALREADY_EXISTS + */ + if (somethingExists(directory)) //a file system race-condition! don't use dirExists() => harmonize with ErrorTargetExisting! { - /* - could there be situations where a directory/network path exists, - but creation fails with error different than "ErrorTargetExisting"?? - - creation of C:\ fails with ERROR_ACCESS_DENIED rather than ERROR_ALREADY_EXISTS - */ assert(false); if (failIfExists) throw; //do NOT convert to ErrorTargetExisting: if "failIfExists", not getting a ErrorTargetExisting *atomically* is unexpected! @@ -1313,7 +1252,7 @@ void zen::makeDirectoryPlain(const Zstring& directory, //throw FileError, ErrorT { dirTmp += FILE_NAME_SEPARATOR; //we do not support "C:" to represent a relative path! - const ErrorCode lastError = dirExists(dirTmp) ? ERROR_ALREADY_EXISTS : ERROR_PATH_NOT_FOUND; + const ErrorCode lastError = somethingExists(dirTmp) ? ERROR_ALREADY_EXISTS : ERROR_PATH_NOT_FOUND; //don't use dirExists() => harmonize with ErrorTargetExisting! const std::wstring errorMsg = replaceCpy(_("Cannot create directory %x."), L"%x", fmtFileName(dirTmp)); const std::wstring errorDescr = formatSystemError(L"CreateDirectory", lastError); @@ -1429,7 +1368,7 @@ void zen::makeDirectoryPlain(const Zstring& directory, //throw FileError, ErrorT } #endif - zen::ScopeGuard guardNewDir = zen::makeGuard([&] { try { removeDirectory(directory); } catch (...) {} }); //ensure cleanup: + zen::ScopeGuard guardNewDir = zen::makeGuard([&] { try { removeDirectory(directory); } catch (FileError&) {} }); //ensure cleanup: //enforce copying file permissions: it's advertized on GUI... if (copyFilePermissions) @@ -1475,12 +1414,12 @@ void zen::copySymlink(const Zstring& sourceLink, const Zstring& targetLink, bool { #ifdef ZEN_WIN if (isDirLink) - removeDirectory(targetLink); + removeDirectory(targetLink); //throw FileError else #endif - removeFile(targetLink); + removeFile(targetLink); //throw FileError } - catch (...) {} + catch (FileError&) {} }); //file times: essential for sync'ing a symlink: enforce this! (don't just try!) @@ -1676,7 +1615,7 @@ void copyFileWindowsSparse(const Zstring& sourceFile, throw FileError(errorMsg, errorDescr); } - ScopeGuard guardTarget = makeGuard([&] { try { removeFile(targetFile); } catch (...) {} }); //transactional behavior: guard just after opening target and before managing hFileOut + ScopeGuard guardTarget = makeGuard([&] { try { removeFile(targetFile); } catch (FileError&) {} }); //transactional behavior: guard just after opening target and before managing hFileOut ZEN_ON_SCOPE_EXIT(::CloseHandle(hFileTarget)); //---------------------------------------------------------------------- @@ -2018,7 +1957,7 @@ void copyFileWindowsDefault(const Zstring& sourceFile, try { activatePrivilege(SE_RESTORE_NAME); } catch (const FileError&) {} - zen::ScopeGuard guardTarget = zen::makeGuard([&] { try { removeFile(targetFile); } catch (...) {} }); + zen::ScopeGuard guardTarget = zen::makeGuard([&] { try { removeFile(targetFile); } catch (FileError&) {} }); //transactional behavior: guard just before starting copy, we don't trust ::CopyFileEx(), do we? ;) DWORD copyFlags = COPY_FILE_FAIL_IF_EXISTS; @@ -2091,7 +2030,7 @@ void copyFileWindowsDefault(const Zstring& sourceFile, //note: ERROR_INVALID_PARAMETER can also occur when copying to a SharePoint server or MS SkyDrive and the target filename is of a restricted type. } - catch (...) {} + catch (FileError&) {} throw FileError(errorMsg, errorDescr); } @@ -2165,7 +2104,7 @@ void copyFileLinuxMac(const Zstring& sourceFile, if (::fstat(fileIn.getDescriptor(), &sourceInfo) != 0) //read file attributes from source throw FileError(replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(sourceFile)), formatSystemError(L"fstat", getLastError())); - zen::ScopeGuard guardTarget = zen::makeGuard([&] { try { removeFile(targetFile); } catch (...) {} }); //transactional behavior: place guard before lifetime of FileOutput + zen::ScopeGuard guardTarget = zen::makeGuard([&] { try { removeFile(targetFile); } catch (FileError&) {} }); //transactional behavior: place guard before lifetime of FileOutput try { //create targetFile and open it for writing @@ -2269,7 +2208,6 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath if (transactionalCopy) { Zstring temporary = targetFile + zen::TEMP_FILE_ENDING; //use temporary file until a correct date has been set - zen::ScopeGuard guardTempFile = zen::makeGuard([&] { try { removeFile(temporary); } catch (...) {} }); //transactional behavior: ensure cleanup (e.g. network drop) -> ref to temporary[!] //raw file copy try @@ -2286,9 +2224,12 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath copyFileSelectOs(sourceFile, temporary, callback, sourceAttr); //throw FileError } + //transactional behavior: ensure cleanup; not needed before copyFileSelectOs() which is already transactional + zen::ScopeGuard guardTempFile = zen::makeGuard([&] { try { removeFile(temporary); } catch (FileError&) {} }); + //have target file deleted (after read access on source and target has been confirmed) => allow for almost transactional overwrite if (callback) - callback->deleteTargetFile(targetFile); + callback->deleteTargetFile(targetFile); //throw X //rename temporary file: //perf: this call is REALLY expensive on unbuffered volumes! ~40% performance decrease on FAT USB stick! @@ -2319,7 +2260,6 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath } else { - //have target file deleted if (callback) callback->deleteTargetFile(targetFile); copyFileSelectOs(sourceFile, targetFile, callback, sourceAttr); //throw FileError: ErrorTargetPathMissing, ErrorTargetExisting, ErrorFileLocked @@ -2335,7 +2275,7 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath //file permissions if (copyFilePermissions) { - zen::ScopeGuard guardTargetFile = zen::makeGuard([&] { try { removeFile(targetFile); } catch (...) {}}); + zen::ScopeGuard guardTargetFile = zen::makeGuard([&] { try { removeFile(targetFile); } catch (FileError&) {}}); copyObjectPermissions(sourceFile, targetFile, SYMLINK_FOLLOW); //throw FileError diff --git a/zen/file_handling.h b/zen/file_handling.h index 3cb8a68c..c437e7bc 100644 --- a/zen/file_handling.h +++ b/zen/file_handling.h @@ -18,19 +18,10 @@ struct CallbackRemoveDir; struct CallbackCopyFile; -bool fileExists (const Zstring& filename, std::wstring* sysErrorMsg = nullptr); //noexcept; check whether file *or* (file) symlink exists -bool dirExists (const Zstring& dirname , std::wstring* sysErrorMsg = nullptr); //noexcept; check whether directory *or* (dir) symlink exists -bool symlinkExists (const Zstring& linkname, std::wstring* sysErrorMsg = nullptr); //noexcept; check whether a symbolic link exists -bool somethingExists(const Zstring& objname , std::wstring* sysErrorMsg = nullptr); //noexcept; check whether any object with this name exists -//sysErrorMsg: optional in + optional out! written only for non-expected errors other than ERROR_FILE_NOT_FOUND/ENOENT, ect... - -enum SymLinkType -{ - SYMLINK_TYPE_DIR, //Windows: may be broken - SYMLINK_TYPE_FILE, //Windows: may be broken - SYMLINK_TYPE_UNKNOWN, //Windows: unable to determine type; Linux: broken Symlink -}; -SymLinkType getSymlinkType(const Zstring& linkname); //noexcept +bool fileExists (const Zstring& filename); //noexcept; check whether file or file-symlink exists +bool dirExists (const Zstring& dirname ); //noexcept; check whether directory or dir-symlink exists +bool symlinkExists (const Zstring& linkname); //noexcept; check whether a symbolic link exists +bool somethingExists(const Zstring& objname ); //noexcept; check whether any object with this name exists enum ProcSymlink { diff --git a/zen/notify_removal.cpp b/zen/notify_removal.cpp index 3815887a..4b00cadf 100644 --- a/zen/notify_removal.cpp +++ b/zen/notify_removal.cpp @@ -186,12 +186,7 @@ private: { PDEV_BROADCAST_HANDLE body = reinterpret_cast<PDEV_BROADCAST_HANDLE>(lParam); -#ifdef __MINGW32__ - const HDEVNOTIFY requestNotification = reinterpret_cast<HDEVNOTIFY>(body->dbch_hdevnotify); -#else - const HDEVNOTIFY requestNotification = body->dbch_hdevnotify; -#endif - if (requestNotification == hNotification) //is it for the notification we registered? + if (body->dbch_hdevnotify == hNotification) //is it for the notification we registered? switch (wParam) { case DBT_DEVICEQUERYREMOVE: diff --git a/zen/optional.h b/zen/optional.h index 6e54408a..15d27f4b 100644 --- a/zen/optional.h +++ b/zen/optional.h @@ -7,6 +7,8 @@ #ifndef OPTIONAL_H_2857428578342203589 #define OPTIONAL_H_2857428578342203589 +#include <cassert> + namespace zen { /* @@ -45,26 +47,19 @@ public: if (tmp.valid) value = tmp.value; valid = tmp.valid; - return *this; + return *this; } ////rvalue optimization: only basic exception safety: // Opt(Opt&& tmp) : value(std::move(tmp.value)), valid(tmp.valid) {} -#ifdef _MSC_VER -private: - struct ConversionToBool { int dummy; }; -public: - operator int ConversionToBool::* () const { return valid ? &ConversionToBool::dummy : nullptr; } -#else explicit operator bool() const { return valid; } //thank you C++11!!! -#endif - const T& operator*() const { return value; } - /**/ T& operator*() { return value; } + const T& operator*() const { assert(valid); return value; } + /**/ T& operator*() { assert(valid); return value; } - const T* operator->() const { return &value; } - /**/ T* operator->() { return &value; } + const T* operator->() const { assert(valid); return &value; } + /**/ T* operator->() { assert(valid); return &value; } void reset() { valid = false; } diff --git a/zen/privilege.cpp b/zen/privilege.cpp index 44318517..d4f956a8 100644 --- a/zen/privilege.cpp +++ b/zen/privilege.cpp @@ -104,13 +104,15 @@ private: ~Privileges() //clean up: deactivate all privileges that have been activated by this application { - for (auto it = activePrivileges.begin(); it != activePrivileges.end(); ++it) - if (it->second) + for (const auto& priv : activePrivileges) + if (priv.second) + { try { - setPrivilege(it->first.c_str(), false); //throw FileError + setPrivilege(priv.first.c_str(), false); //throw FileError } - catch (...) {} + catch (FileError&) {} + } } std::map<Zstring, bool> activePrivileges; //bool: enabled by this application diff --git a/zen/recycler.cpp b/zen/recycler.cpp index f1b8381a..20e1a4af 100644 --- a/zen/recycler.cpp +++ b/zen/recycler.cpp @@ -91,7 +91,7 @@ void zen::recycleOrDelete(const std::vector<Zstring>& filenames, CallbackRecycli const DllFun<FunType_getLastError> getLastError (getDllName(), funName_getLastError); if (!moveToRecycler || !getLastError) - throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin."), L"%x", fmtFileName(filenames[0])), + throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filenames[0])), replaceCpy(_("Cannot load file %x."), L"%x", fmtFileName(getDllName()))); std::vector<const wchar_t*> cNames; @@ -108,7 +108,7 @@ void zen::recycleOrDelete(const std::vector<Zstring>& filenames, CallbackRecycli if (filenames.size() > 1) filenameFmt += L", ..."; //give at least some hint that there are multiple files, and the error need not be related to the first one - throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin."), L"%x", filenameFmt), getLastError()); //already includes details about locking errors! + throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", filenameFmt), getLastError()); //already includes details about locking errors! } } else //regular recycle bin usage: available since XP @@ -133,7 +133,7 @@ void zen::recycleOrDelete(const std::vector<Zstring>& filenames, CallbackRecycli //"You should use fully-qualified path names with this function. Using it with relative path names is not thread safe." if (::SHFileOperation(&fileOp) != 0 || fileOp.fAnyOperationsAborted) { - throw FileError(replaceCpy(_("Unable to move %x to the Recycle Bin."), L"%x", fmtFileName(filenames[0]))); //probably not the correct file name for file list larger than 1! + throw FileError(replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filenames[0]))); //probably not the correct file name for file list larger than 1! } } } @@ -159,7 +159,7 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError if (!::g_file_trash(file, nullptr, &error)) { - const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the Recycle Bin."), L"%x", fmtFileName(filename)); + const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filename)); if (!error) throw FileError(errorMsg, L"Unknown error."); //user should never see this @@ -190,7 +190,7 @@ bool zen::recycleOrDelete(const Zstring& filename) //throw FileError auto throwFileError = [&](OSStatus oss) { - const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the Recycle Bin."), L"%x", fmtFileName(filename)); + const std::wstring errorMsg = replaceCpy(_("Unable to move %x to the recycle bin."), L"%x", fmtFileName(filename)); std::wstring errorDescr = L"OSStatus Code " + numberTo<std::wstring>(oss); if (const char* description = ::GetMacOSStatusCommentString(oss)) //found no documentation for proper use of GetMacOSStatusCommentString diff --git a/zen/scroll_window_under_cursor.cpp b/zen/scroll_window_under_cursor.cpp index f201bb04..ccc00bcf 100644 --- a/zen/scroll_window_under_cursor.cpp +++ b/zen/scroll_window_under_cursor.cpp @@ -13,15 +13,11 @@ #include <cassert> #include "win.h" //includes "windows.h" -#include "Windowsx.h" //WM_MOUSEWHEEL +#include <Windowsx.h> //WM_MOUSEWHEEL namespace { -#ifndef WM_MOUSEHWHEEL //MinGW is clueless... -#define WM_MOUSEHWHEEL 0x020E -#endif - LRESULT CALLBACK mouseInputHook(int nCode, WPARAM wParam, LPARAM lParam) { //"if nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function diff --git a/zen/serialize.h b/zen/serialize.h index 64c07213..14d0cdf7 100644 --- a/zen/serialize.h +++ b/zen/serialize.h @@ -95,7 +95,7 @@ struct BinStreamIn //throw UnexpectedEndOfStreamError } private: - const BinaryStream buffer; + BinaryStream buffer; size_t pos; }; diff --git a/zen/string_tools.h b/zen/string_tools.h index 4639e1dd..180056cb 100644 --- a/zen/string_tools.h +++ b/zen/string_tools.h @@ -389,7 +389,7 @@ template <class Num> inline int saferPrintf(char* buffer, size_t bufferSize, const char* format, const Num& number) //there is no such thing as a "safe" printf ;) { #if defined _MSC_VER || defined __MINGW32__ - return ::_snprintf(buffer, bufferSize, format, number); //by factor 10 faster than "std::snprintf" on Mingw and on par with std::sprintf()!!! + return ::_snprintf(buffer, bufferSize, format, number); //by factor 10 faster than "std::snprintf" on MinGW and on par with std::sprintf()!!! #else return std::snprintf(buffer, bufferSize, format, number); //C99 #endif diff --git a/zen/symlink_target.h b/zen/symlink_target.h index bfd9e038..e3e2ac4d 100644 --- a/zen/symlink_target.h +++ b/zen/symlink_target.h @@ -12,7 +12,7 @@ #ifdef ZEN_WIN #include "win.h" //includes "windows.h" -#include "WinIoCtl.h" +//#include <WinIoCtl.h> #include "privilege.h" #include "long_path_prefix.h" #include "dll.h" @@ -43,7 +43,8 @@ Zstring getSymlinkTargetRaw(const Zstring& linkPath); //throw FileError //################################ implementation ################################ -#ifdef _MSC_VER //I don't have Windows Driver Kit at hands right now, so unfortunately we need to redefine this structures and cross fingers... +#ifdef ZEN_WIN +//I don't have Windows Driver Kit at hands right now, so unfortunately we need to redefine this structure and cross fingers... typedef struct _REPARSE_DATA_BUFFER //from ntifs.h { ULONG ReparseTag; @@ -77,7 +78,6 @@ typedef struct _REPARSE_DATA_BUFFER //from ntifs.h #define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) #endif - namespace { //retrieve raw target data of symlink or junction diff --git a/zen/thread.h b/zen/thread.h index 76596513..1fa2c951 100644 --- a/zen/thread.h +++ b/zen/thread.h @@ -17,6 +17,9 @@ #pragma GCC diagnostic ignored "-Wstrict-aliasing" #pragma GCC diagnostic ignored "-Wredundant-decls" #pragma GCC diagnostic ignored "-Wshadow" +#ifndef __clang__ //clang defines __GNUC__, but doesn't support this warning +#pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#endif #endif #ifdef _MSC_VER #pragma warning(push) diff --git a/zen/warn_static.h b/zen/warn_static.h index 737a56fb..b9673ed6 100644 --- a/zen/warn_static.h +++ b/zen/warn_static.h @@ -15,19 +15,19 @@ Usage: */ #ifdef _MSC_VER -#define MAKE_STRING_SUB(NUM) #NUM -#define MAKE_STRING(NUM) MAKE_STRING_SUB(NUM) +#define STATIC_WARNING_MAKE_STRINGIZE_SUB(NUM) #NUM +#define STATIC_WARNING_MAKE_STRINGIZE(NUM) STATIC_WARNING_MAKE_STRINGIZE_SUB(NUM) #define warn_static(TXT) \ - __pragma(message (__FILE__ "(" MAKE_STRING(__LINE__) "): Warning: " ## TXT)) + __pragma(message (__FILE__ "(" STATIC_WARNING_MAKE_STRINGIZE(__LINE__) "): Warning: " ## TXT)) #elif defined __GNUC__ -#define ZEN_CONCAT_SUB(X, Y) X ## Y -#define ZEN_CONCAT(X, Y) ZEN_CONCAT_SUB(X, Y) +#define STATIC_WARNING_CONCAT_SUB(X, Y) X ## Y +#define STATIC_WARNING_CONCAT(X, Y) STATIC_WARNING_CONCAT_SUB(X, Y) #define warn_static(TXT) \ typedef int STATIC_WARNING_87903124 __attribute__ ((deprecated)); \ - enum { ZEN_CONCAT(warn_static_dummy_value, __LINE__) = sizeof(STATIC_WARNING_87903124) }; + enum { STATIC_WARNING_CONCAT(warn_static_dummy_value, __LINE__) = sizeof(STATIC_WARNING_87903124) }; #endif #endif //WARN_STATIC_HEADER_08724567834560832745 diff --git a/zen/zstring.cpp b/zen/zstring.cpp index 1cc037e8..6eb68f7b 100644 --- a/zen/zstring.cpp +++ b/zen/zstring.cpp @@ -127,10 +127,6 @@ time per call | function #ifdef ZEN_WIN namespace { -#ifdef __MINGW32__ //MinGW is clueless... -#define LOCALE_INVARIANT 0x007f -#endif - //warning: LOCALE_INVARIANT is NOT available with Windows 2000, so we have to make yet another distinction... const LCID ZSTRING_INVARIANT_LOCALE = zen::winXpOrLater() ? LOCALE_INVARIANT : |