summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/ShadowCopy/Shadow_Server2003.vcxproj8
-rw-r--r--lib/ShadowCopy/Shadow_Windows7.vcxproj8
-rw-r--r--lib/ShadowCopy/Shadow_XP.vcxproj8
-rw-r--r--lib/Thumbnail/Thumbnail.vcxproj8
-rw-r--r--lib/db_file.cpp10
-rw-r--r--lib/dir_exist_async.h2
-rw-r--r--lib/dir_lock.cpp39
-rw-r--r--lib/generate_logfile.h4
-rw-r--r--lib/icon_buffer.cpp4
-rw-r--r--lib/parallel_scan.cpp8
-rw-r--r--lib/parse_lng.h7
-rw-r--r--lib/perf_check.cpp76
-rw-r--r--lib/perf_check.h30
-rw-r--r--lib/process_xml.cpp45
-rw-r--r--lib/process_xml.h10
-rw-r--r--lib/resolve_path.cpp21
-rw-r--r--lib/shadow.cpp11
-rw-r--r--lib/status_handler.cpp11
-rw-r--r--lib/status_handler.h15
-rw-r--r--lib/versioning.cpp7
20 files changed, 162 insertions, 170 deletions
diff --git a/lib/ShadowCopy/Shadow_Server2003.vcxproj b/lib/ShadowCopy/Shadow_Server2003.vcxproj
index 520a4d6d..a9b8f740 100644
--- a/lib/ShadowCopy/Shadow_Server2003.vcxproj
+++ b/lib/ShadowCopy/Shadow_Server2003.vcxproj
@@ -87,7 +87,7 @@
</BuildLog>
<ClCompile>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -123,7 +123,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -157,7 +157,7 @@
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
@@ -195,7 +195,7 @@
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_2003;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
diff --git a/lib/ShadowCopy/Shadow_Windows7.vcxproj b/lib/ShadowCopy/Shadow_Windows7.vcxproj
index 1fe769d0..7c6f1f1d 100644
--- a/lib/ShadowCopy/Shadow_Windows7.vcxproj
+++ b/lib/ShadowCopy/Shadow_Windows7.vcxproj
@@ -87,7 +87,7 @@
</BuildLog>
<ClCompile>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -133,7 +133,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SmallerTypeCheck>true</SmallerTypeCheck>
</ClCompile>
<Link>
@@ -157,7 +157,7 @@
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
@@ -205,7 +205,7 @@
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>../..;C:\Program Files\C++\boost</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_WINDOWS7;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
diff --git a/lib/ShadowCopy/Shadow_XP.vcxproj b/lib/ShadowCopy/Shadow_XP.vcxproj
index 0d231f3d..0d54f2e4 100644
--- a/lib/ShadowCopy/Shadow_XP.vcxproj
+++ b/lib/ShadowCopy/Shadow_XP.vcxproj
@@ -86,7 +86,7 @@
</BuildLog>
<ClCompile>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -123,7 +123,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;_DEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -158,7 +158,7 @@
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
@@ -196,7 +196,7 @@
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>ZEN_WIN;WXINTL_NO_GETTEXT_MACRO;NDEBUG;_WINDOWS;_USRDLL;SHADOWDLL_EXPORTS;USE_SHADOW_XP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
diff --git a/lib/Thumbnail/Thumbnail.vcxproj b/lib/Thumbnail/Thumbnail.vcxproj
index 87fb152b..1ec016be 100644
--- a/lib/Thumbnail/Thumbnail.vcxproj
+++ b/lib/Thumbnail/Thumbnail.vcxproj
@@ -94,7 +94,7 @@
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
- <DisableSpecificWarnings>4100</DisableSpecificWarnings>
+ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
<SmallerTypeCheck>true</SmallerTypeCheck>
</ClCompile>
@@ -129,7 +129,7 @@
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- <DisableSpecificWarnings>4100</DisableSpecificWarnings>
+ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
<SmallerTypeCheck>true</SmallerTypeCheck>
</ClCompile>
@@ -161,7 +161,7 @@
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- <DisableSpecificWarnings>4100</DisableSpecificWarnings>
+ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
</ClCompile>
@@ -198,7 +198,7 @@
<WarningLevel>Level4</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
- <DisableSpecificWarnings>4100</DisableSpecificWarnings>
+ <DisableSpecificWarnings>4100;4996</DisableSpecificWarnings>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
</ClCompile>
diff --git a/lib/db_file.cpp b/lib/db_file.cpp
index 2f699e3a..ab7f9212 100644
--- a/lib/db_file.cpp
+++ b/lib/db_file.cpp
@@ -91,7 +91,7 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError, FileErrorD
{
try
{
- BinStreamIn streamIn = loadBinStream<BinaryStream>(filename); //throw FileError, ErrorNotExisting
+ BinStreamIn streamIn = loadBinStream<BinaryStream>(filename); //throw FileError
//read FreeFileSync file identifier
char formatDescr[sizeof(FILE_FORMAT_DESCR)] = {};
@@ -118,10 +118,12 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError, FileErrorD
}
return output;
}
- catch (ErrorNotExisting&)
+ catch (FileError&)
{
- throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + L" \n" +
- replaceCpy(_("Database file %x does not yet exist."), L"%x", fmtFileName(filename)));
+ if (!somethingExists(filename)) //a benign(?) race condition with FileError
+ throw FileErrorDatabaseNotExisting(_("Initial synchronization:") + L" \n" +
+ replaceCpy(_("Database file %x does not yet exist."), L"%x", fmtFileName(filename)));
+ throw;
}
catch (UnexpectedEndOfStreamError&)
{
diff --git a/lib/dir_exist_async.h b/lib/dir_exist_async.h
index dd77a36a..39ae6aff 100644
--- a/lib/dir_exist_async.h
+++ b/lib/dir_exist_async.h
@@ -47,7 +47,7 @@ std::set<Zstring, LessFilename> getExistingDirsUpdating(const std::set<Zstring,
const boost::system_time endTime = boost::get_system_time() + boost::posix_time::seconds(10); //10 sec should be enough even if Win32 waits much longer
auto itDirname = dirnames.begin();
- for (auto it = dirEx.begin(); it != dirEx.end(); ++it, ++itDirname)
+ for (auto it = dirEx.begin(); it != dirEx.end(); (void)++it, ++itDirname) //void: prevent ADL from dragging in boost's ,-overload: "MSVC warning C4913: user defined binary operator ',' exists but no overload could convert all operands"
{
procCallback.reportStatus(replaceCpy(_("Searching for folder %x..."), L"%x", fmtFileName(*itDirname), false)); //may throw!
diff --git a/lib/dir_lock.cpp b/lib/dir_lock.cpp
index 60d83a67..d7e3ba56 100644
--- a/lib/dir_lock.cpp
+++ b/lib/dir_lock.cpp
@@ -68,7 +68,7 @@ public:
}
catch (const std::exception& e) //exceptions must be catched per thread
{
- wxSafeShowMessage(_("An exception occurred"), utfCvrtTo<wxString>(e.what()) + L" (Dirlock)"); //simple wxMessageBox won't do for threads
+ wxSafeShowMessage(L"FreeFileSync - " + _("An exception occurred"), utfCvrtTo<wxString>(e.what()) + L" (Dirlock)"); //simple wxMessageBox won't do for threads
}
}
@@ -123,7 +123,7 @@ private:
namespace
{
-UInt64 getLockFileSize(const Zstring& filename) //throw FileError, ErrorNotExisting
+UInt64 getLockFileSize(const Zstring& filename) //throw FileError
{
#ifdef ZEN_WIN
WIN32_FIND_DATA fileInfo = {};
@@ -144,11 +144,7 @@ UInt64 getLockFileSize(const Zstring& filename) //throw FileError, ErrorNotExist
const ErrorCode lastError = getLastError();
const std::wstring errorMsg = replaceCpy(_("Cannot read file attributes of %x."), L"%x", fmtFileName(filename));
const std::wstring errorDescr = formatSystemError(functionName, lastError);
-
- if (errorCodeForNotExisting(lastError))
- throw ErrorNotExisting(errorMsg, errorDescr);
- else
- throw FileError(errorMsg, errorDescr);
+ throw FileError(errorMsg, errorDescr);
}
@@ -359,9 +355,9 @@ struct LockInformation //throw FileError
//wxGetFullHostName() is a performance killer for some users, so don't touch!
-LockInformation retrieveLockInfo(const Zstring& lockfilename) //throw FileError, ErrorNotExisting
+LockInformation retrieveLockInfo(const Zstring& lockfilename) //throw FileError
{
- BinStreamIn streamIn = loadBinStream<BinaryStream>(lockfilename); //throw FileError, ErrorNotExisting
+ BinStreamIn streamIn = loadBinStream<BinaryStream>(lockfilename); //throw FileError
try
{
return LockInformation(streamIn); //throw UnexpectedEndOfStreamError
@@ -374,9 +370,9 @@ LockInformation retrieveLockInfo(const Zstring& lockfilename) //throw FileError,
inline
-std::string retrieveLockId(const Zstring& lockfilename) //throw FileError, ErrorNotExisting
+std::string retrieveLockId(const Zstring& lockfilename) //throw FileError
{
- return retrieveLockInfo(lockfilename).lockId;
+ return retrieveLockInfo(lockfilename).lockId; //throw FileError
}
@@ -408,6 +404,7 @@ ProcessStatus getProcessStatus(const LockInformation& lockInfo) //throw FileErro
const std::int64_t TICKS_PER_SEC = ticksPerSec(); //= 0 on error
+
void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //throw FileError
{
const std::wstring infoMsg = replaceCpy(_("Waiting while directory is locked (%x)..."), L"%x", fmtFileName(lockfilename));
@@ -422,7 +419,7 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr
std::string originalLockId; //empty if it cannot be retrieved
try
{
- const LockInformation& lockInfo = retrieveLockInfo(lockfilename); //throw FileError, ErrorNotExisting
+ const LockInformation& lockInfo = retrieveLockInfo(lockfilename); //throw FileError
originalLockId = lockInfo.lockId;
switch (getProcessStatus(lockInfo)) //throw FileError
{
@@ -443,7 +440,7 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr
while (true)
{
const TickVal now = getTicks();
- const UInt64 fileSizeNew = ::getLockFileSize(lockfilename); //throw FileError, ErrorNotExisting
+ const UInt64 fileSizeNew = ::getLockFileSize(lockfilename); //throw FileError
if (TICKS_PER_SEC <= 0 || !lastLifeSign.isValid() || !now.isValid())
throw FileError(L"System Timer failed!"); //no i18n: "should" never throw ;)
@@ -462,10 +459,10 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr
//now that the lock is in place check existence again: meanwhile another process may have deleted and created a new lock!
if (!originalLockId.empty())
- if (retrieveLockId(lockfilename) != originalLockId) //throw FileError, ErrorNotExisting -> since originalLockId is filled, we are not expecting errors!
+ if (retrieveLockId(lockfilename) != originalLockId) //throw FileError -> since originalLockId is filled, we are not expecting errors!
return; //another process has placed a new lock, leave scope: the wait for the old lock is technically over...
- if (::getLockFileSize(lockfilename) != fileSizeOld) //throw FileError, ErrorNotExisting
+ if (::getLockFileSize(lockfilename) != fileSizeOld) //throw FileError
continue; //late life sign
removeFile(lockfilename); //throw FileError
@@ -494,9 +491,11 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr
}
}
}
- catch (const ErrorNotExisting&)
+ catch (FileError&)
{
- return; //what we are waiting for...
+ if (!somethingExists(lockfilename)) //a benign(?) race condition with FileError
+ return; //what we are waiting for...
+ throw;
}
}
@@ -582,7 +581,7 @@ public:
~SharedDirLock()
{
threadObj.interrupt(); //thread lifetime is subset of this instances's life
- threadObj.join(); //we assume precondition "threadObj.joinable()"!!!
+ threadObj.join(); //we assert precondition "threadObj.joinable()"!!!
::releaseLock(lockfilename_); //throw ()
}
@@ -618,7 +617,7 @@ public:
try //check based on lock GUID, deadlock prevention: "lockfilename" may be an alternative name for a lock already owned by this process
{
- const std::string lockId = retrieveLockId(lockfilename); //throw FileError, ErrorNotExisting
+ const std::string lockId = retrieveLockId(lockfilename); //throw FileError
if (const std::shared_ptr<SharedDirLock>& activeLock = getActiveLock(lockId)) //returns null-lock if not found
{
fileToGuid[lockfilename] = lockId; //found an alias for one of our active locks
@@ -629,7 +628,7 @@ public:
//lock not owned by us => create a new one
auto newLock = std::make_shared<SharedDirLock>(lockfilename, callback); //throw FileError
- const std::string& newLockGuid = retrieveLockId(lockfilename); //throw FileError, ErrorNotExisting
+ const std::string& newLockGuid = retrieveLockId(lockfilename); //throw FileError
//update registry
fileToGuid[lockfilename] = newLockGuid; //throw()
diff --git a/lib/generate_logfile.h b/lib/generate_logfile.h
index 31f7bd43..ff97b63a 100644
--- a/lib/generate_logfile.h
+++ b/lib/generate_logfile.h
@@ -147,9 +147,9 @@ void saveToLastSyncsLog(const SummaryInfo& summary, //throw FileError
Utf8String oldStream;
try
{
- oldStream = loadBinStream<Utf8String>(filename); //throw FileError, ErrorNotExisting
+ oldStream = loadBinStream<Utf8String>(filename); //throw FileError
}
- catch (const ErrorNotExisting&) {}
+ catch (FileError&) {}
if (!oldStream.empty())
{
diff --git a/lib/icon_buffer.cpp b/lib/icon_buffer.cpp
index cf916174..b0874d83 100644
--- a/lib/icon_buffer.cpp
+++ b/lib/icon_buffer.cpp
@@ -426,7 +426,7 @@ public:
{
assert(boost::this_thread::get_id() == mainThreadId );
{
- boost::unique_lock<boost::mutex> dummy(lockFiles);
+ boost::lock_guard<boost::mutex> dummy(lockFiles);
filesToLoad = newLoad;
}
conditionNewFiles.notify_all(); //instead of notify_one(); workaround bug: https://svn.boost.org/trac/boost/ticket/7796
@@ -437,7 +437,7 @@ public:
{
assert(boost::this_thread::get_id() == mainThreadId );
{
- boost::unique_lock<boost::mutex> dummy(lockFiles);
+ boost::lock_guard<boost::mutex> dummy(lockFiles);
filesToLoad.push_back(newEntry); //set as next item to retrieve
}
conditionNewFiles.notify_all();
diff --git a/lib/parallel_scan.cpp b/lib/parallel_scan.cpp
index df8ff095..2bac5690 100644
--- a/lib/parallel_scan.cpp
+++ b/lib/parallel_scan.cpp
@@ -180,7 +180,7 @@ public:
errorMsg.clear();
errorResponse.reset();
- dummy.unlock(); //optimization for condition_variable::notify_one()
+ dummy.unlock(); //optimization for condition_variable::notify_all()
conditionCanReportError.notify_all(); //instead of notify_one(); workaround bug: https://svn.boost.org/trac/boost/ticket/7796
return rv;
@@ -194,7 +194,7 @@ public:
FillBufferCallback::HandleError rv = callback.reportError(copyStringTo<std::wstring>(errorMsg)); //throw!
errorResponse = make_unique<FillBufferCallback::HandleError>(rv);
- dummy.unlock(); //optimization for condition_variable::notify_one()
+ dummy.unlock(); //optimization for condition_variable::notify_all()
conditionGotResponse.notify_all(); //instead of notify_one(); workaround bug: https://svn.boost.org/trac/boost/ticket/7796
}
}
@@ -236,7 +236,7 @@ public:
std::wstring statusText = copyStringTo<std::wstring>(textScanning);
const long activeCount = activeWorker;
if (activeCount >= 2)
- statusText += L" " + replaceCpy(_P("[1 Thread]", "[%x Threads]", activeCount), L"%x", numberTo<std::wstring>(activeCount));
+ statusText += L" [" + replaceCpy(_P("1 thread", "%x threads", activeCount), L"%x", numberTo<std::wstring>(activeCount)) + L"]";
statusText += L" " + fmtFileName(filename);
return statusText;
@@ -273,8 +273,8 @@ private:
boost::detail::atomic_count itemsScanned;
boost::detail::atomic_count activeWorker;
};
-//-------------------------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------------------------
struct TraverserShared
{
diff --git a/lib/parse_lng.h b/lib/parse_lng.h
index 8cd8e943..be47b66b 100644
--- a/lib/parse_lng.h
+++ b/lib/parse_lng.h
@@ -294,7 +294,7 @@ private:
static void normalize(std::string& text)
{
- zen::trim(text); //remmove whitespace from end
+ zen::trim(text); //remove whitespace from both ends
//Delimiter:
//----------
@@ -378,8 +378,11 @@ private:
if (token().type == Token::TK_PLURAL_BEGIN)
return parsePlural(pluralOut, pluralInfo);
+ if (token().type != Token::TK_TEXT)
+ throw ParsingError(L"Source text empty", scn.posRow(), scn.posCol());
std::string original = tk.text;
- consumeToken(Token::TK_TEXT);
+ nextToken();
+
consumeToken(Token::TK_SRC_END);
consumeToken(Token::TK_TRG_BEGIN);
diff --git a/lib/perf_check.cpp b/lib/perf_check.cpp
index 33361201..0f5506b3 100644
--- a/lib/perf_check.cpp
+++ b/lib/perf_check.cpp
@@ -16,10 +16,10 @@ using namespace zen;
PerfCheck::PerfCheck(unsigned int windowSizeRemainingTime,
- unsigned int windowSizeBytesPerSecond) :
+ unsigned int windowSizeSpeed) :
windowSizeRemTime(windowSizeRemainingTime),
- windowSizeBPS(windowSizeBytesPerSecond),
- windowMax(std::max(windowSizeRemainingTime, windowSizeBytesPerSecond)) {}
+ windowSizeSpeed_(windowSizeSpeed),
+ windowMax(std::max(windowSizeRemainingTime, windowSizeSpeed)) {}
PerfCheck::~PerfCheck()
@@ -43,9 +43,9 @@ PerfCheck::~PerfCheck()
}
-void PerfCheck::addSample(int objectsCurrent, double dataCurrent, long timeMs)
+void PerfCheck::addSample(int itemsCurrent, double dataCurrent, long timeMs)
{
- samples.insert(samples.end(), std::make_pair(timeMs, Record(objectsCurrent, dataCurrent))); //use fact that time is monotonously ascending
+ samples.insert(samples.end(), std::make_pair(timeMs, Record(itemsCurrent, dataCurrent))); //use fact that time is monotonously ascending
//remove all records earlier than "now - windowMax"
const long newBegin = timeMs - windowMax;
@@ -55,20 +55,32 @@ void PerfCheck::addSample(int objectsCurrent, double dataCurrent, long timeMs)
}
-std::wstring PerfCheck::getRemainingTime(double dataRemaining) const
+inline
+std::pair<const std::multimap<long, PerfCheck::Record>::value_type*, const std::multimap<long, PerfCheck::Record>::value_type*> PerfCheck::getBlockFromEnd(long windowSize) const
{
if (!samples.empty())
{
- const auto& recordBack = *samples.rbegin();
+ auto itBack = samples.rbegin();
//find start of records "window"
- auto itFront = samples.upper_bound(recordBack.first - windowSizeRemTime);
+ auto itFront = samples.upper_bound(itBack->first - windowSize);
if (itFront != samples.begin())
--itFront; //one point before window begin in order to handle "measurement holes"
+ return std::make_pair(&*itFront, &*itBack);
+ }
+ return std::make_pair(nullptr, nullptr);
+}
- const auto& recordFront = *itFront;
+
+zen::Opt<std::wstring> PerfCheck::getRemainingTime(double dataRemaining) const
+{
+ auto blk = getBlockFromEnd(windowSizeRemTime);
+ if (blk.first && blk.second)
+ {
+ const auto& itemFront = *blk.first;
+ const auto& itemBack = *blk.second;
//-----------------------------------------------------------------------------------------------
- const long timeDelta = recordBack.first - recordFront.first;
- const double dataDelta = recordBack.second.data_ - recordFront.second.data_;
+ const long timeDelta = itemBack.first - itemFront.first;
+ const double dataDelta = itemBack.second.data_ - itemFront.second.data_;
//objects model logical operations *NOT* disk accesses, so we better play safe and use "bytes" only!
//http://sourceforge.net/p/freefilesync/feature-requests/197/
@@ -76,29 +88,43 @@ std::wstring PerfCheck::getRemainingTime(double dataRemaining) const
if (!numeric::isNull(dataDelta)) //sign(dataRemaining) != sign(dataDelta) usually an error, so show it!
return remainingTimeToString(dataRemaining * timeDelta / (1000.0 * dataDelta));
}
- return L"-"; //fallback
+ return NoValue();
}
-std::wstring PerfCheck::getBytesPerSecond() const
+zen::Opt<std::wstring> PerfCheck::getBytesPerSecond() const
{
- if (!samples.empty())
+ auto blk = getBlockFromEnd(windowSizeSpeed_);
+ if (blk.first && blk.second)
{
- const auto& recordBack = *samples.rbegin();
- //find start of records "window"
- auto itFront = samples.upper_bound(recordBack.first - windowSizeBPS);
- if (itFront != samples.begin())
- --itFront; //one point before window begin in order to handle "measurement holes"
+ const auto& itemFront = *blk.first;
+ const auto& itemBack = *blk.second;
+ //-----------------------------------------------------------------------------------------------
+ const long timeDelta = itemBack.first - itemFront.first;
+ const double dataDelta = itemBack.second.data_ - itemFront.second.data_;
+
+ if (timeDelta != 0/* && dataDelta > 0*/)
+ return filesizeToShortString(zen::Int64(dataDelta * 1000.0 / timeDelta)) + _("/sec");
+ }
+ return NoValue();
+}
+
- const auto& recordFront = *itFront;
+zen::Opt<std::wstring> PerfCheck::getItemsPerSecond() const
+{
+ auto blk = getBlockFromEnd(windowSizeSpeed_);
+ if (blk.first && blk.second)
+ {
+ const auto& itemFront = *blk.first;
+ const auto& itemBack = *blk.second;
//-----------------------------------------------------------------------------------------------
- const long timeDelta = recordBack.first - recordFront.first;
- const double dataDelta = recordBack.second.data_ - recordFront.second.data_;
+ const long timeDelta = itemBack.first - itemFront.first;
+ const int itemsDelta = itemBack.second.itemCount_ - itemFront.second.itemCount_;
- if (timeDelta != 0 && dataDelta > 0)
- return filesizeToShortString(zen::Int64(dataDelta * 1000 / timeDelta)) + _("/sec");
+ if (timeDelta != 0)
+ return replaceCpy(_("%x items"), L"%x", formatThreeDigitPrecision(itemsDelta * 1000.0 / timeDelta)) + _("/sec");
}
- return L"-"; //fallback
+ return NoValue();
}
diff --git a/lib/perf_check.h b/lib/perf_check.h
index 3e04b778..9d82be57 100644
--- a/lib/perf_check.h
+++ b/lib/perf_check.h
@@ -9,31 +9,37 @@
#include <map>
#include <string>
+#include <zen/optional.h>
class PerfCheck
{
public:
- PerfCheck(unsigned int windowSizeRemainingTime, //unit: [ms]
- unsigned int windowSizeBytesPerSecond); //
+ PerfCheck(unsigned int windowSizeRemainingTime, //unit: [ms]
+ unsigned int windowSizeSpeed); //
~PerfCheck();
- void addSample(int objectsCurrent, double dataCurrent, long timeMs); //timeMs must be ascending!
+ void addSample(int itemsCurrent, double dataCurrent, long timeMs); //timeMs must be ascending!
- std::wstring getRemainingTime(double dataRemaining) const;
- std::wstring getBytesPerSecond() const; //for window
+ zen::Opt<std::wstring> getRemainingTime(double dataRemaining) const;
+ zen::Opt<std::wstring> getBytesPerSecond() const; //for window
+ zen::Opt<std::wstring> getItemsPerSecond() const; //for window
private:
- const long windowSizeRemTime; //unit: [ms]
- const long windowSizeBPS; //
- const long windowMax;
-
struct Record
{
- Record(int objCount, double data) : objCount_(objCount), data_(data) {}
- int objCount_;
+ Record(int itemCount, double data) : itemCount_(itemCount), data_(data) {}
+ int itemCount_;
double data_; //unit: [bytes]
};
- std::multimap<long, Record> samples; //time, unit: [ms]
+
+ std::pair<const std::multimap<long, Record>::value_type*,
+ const std::multimap<long, Record>::value_type*> getBlockFromEnd(long windowSize) const;
+
+ const long windowSizeRemTime; //unit: [ms]
+ const long windowSizeSpeed_; //
+ const long windowMax;
+
+ std::map<long, Record> samples; //time, unit: [ms]
};
#endif // STATISTICS_H_INCLUDED
diff --git a/lib/process_xml.cpp b/lib/process_xml.cpp
index 2422b2ef..49e4c711 100644
--- a/lib/process_xml.cpp
+++ b/lib/process_xml.cpp
@@ -99,6 +99,7 @@ void xmlAccess::OptionalDialogs::resetDialogs()
warningDirectoryLockFailed = true;
popupOnConfigChange = true;
confirmSyncStart = true;
+ confirmExternalCommandMassInvoke = true;
}
@@ -157,36 +158,6 @@ xmlAccess::XmlBatchConfig xmlAccess::convertGuiToBatchPreservingExistingBatch(co
}
-xmlAccess::MergeType xmlAccess::getMergeType(const std::vector<Zstring>& filenames) //throw()
-{
- bool guiCfgExists = false;
- bool batchCfgExists = false;
-
- for (auto it = filenames.begin(); it != filenames.end(); ++it)
- {
- switch (xmlAccess::getXmlType(*it)) //throw()
- {
- case XML_TYPE_GUI:
- guiCfgExists = true;
- break;
-
- case XML_TYPE_BATCH:
- batchCfgExists = true;
- break;
-
- case XML_TYPE_GLOBAL:
- case XML_TYPE_OTHER:
- return MERGE_OTHER;
- }
- }
-
- if (guiCfgExists)
- return batchCfgExists ? MERGE_GUI_BATCH : MERGE_GUI;
- else
- return batchCfgExists ? MERGE_BATCH : MERGE_OTHER;
-}
-
-
namespace
{
std::vector<Zstring> splitFilterByLines(const Zstring& filterPhrase)
@@ -243,13 +214,13 @@ void writeText(const SyncDirection& value, std::string& output)
{
switch (value)
{
- case SYNC_DIR_LEFT:
+ case SyncDirection::LEFT:
output = "left";
break;
- case SYNC_DIR_RIGHT:
+ case SyncDirection::RIGHT:
output = "right";
break;
- case SYNC_DIR_NONE:
+ case SyncDirection::NONE:
output = "none";
break;
}
@@ -261,11 +232,11 @@ bool readText(const std::string& input, SyncDirection& value)
std::string tmp = input;
zen::trim(tmp);
if (tmp == "left")
- value = SYNC_DIR_LEFT;
+ value = SyncDirection::LEFT;
else if (tmp == "right")
- value = SYNC_DIR_RIGHT;
+ value = SyncDirection::RIGHT;
else if (tmp == "none")
- value = SYNC_DIR_NONE;
+ value = SyncDirection::NONE;
else
return false;
return true;
@@ -1037,6 +1008,7 @@ void readConfig(const XmlIn& in, XmlGlobalSettings& config)
inOpt["WarnDirectoryLockFailed" ].attribute("Enabled", config.optDialogs.warningDirectoryLockFailed);
inOpt["ConfirmSaveConfig" ].attribute("Enabled", config.optDialogs.popupOnConfigChange);
inOpt["ConfirmStartSync" ].attribute("Enabled", config.optDialogs.confirmSyncStart);
+ inOpt["ConfirmExternalCommandMassInvoke"].attribute("Enabled", config.optDialogs.confirmExternalCommandMassInvoke);
//gui specific global settings (optional)
XmlIn inGui = in["Gui"];
@@ -1415,6 +1387,7 @@ void writeConfig(const XmlGlobalSettings& config, XmlOut& out)
outOpt["WarnDirectoryLockFailed" ].attribute("Enabled", config.optDialogs.warningDirectoryLockFailed);
outOpt["ConfirmSaveConfig" ].attribute("Enabled", config.optDialogs.popupOnConfigChange);
outOpt["ConfirmStartSync" ].attribute("Enabled", config.optDialogs.confirmSyncStart);
+ outOpt["ConfirmExternalCommandMassInvoke"].attribute("Enabled", config.optDialogs.confirmExternalCommandMassInvoke);
//gui specific global settings (optional)
XmlOut outGui = out["Gui"];
diff --git a/lib/process_xml.h b/lib/process_xml.h
index 95fa644d..b189e51f 100644
--- a/lib/process_xml.h
+++ b/lib/process_xml.h
@@ -103,6 +103,7 @@ struct OptionalDialogs
bool warningDirectoryLockFailed;
bool popupOnConfigChange;
bool confirmSyncStart;
+ bool confirmExternalCommandMassInvoke;
};
@@ -278,15 +279,6 @@ void writeConfig(const XmlBatchConfig& config, const Zstring& filename); //th
void writeConfig(const XmlGlobalSettings& config); //
//convert (multiple) *.ffs_gui, *.ffs_batch files or combinations of both into target config structure:
-enum MergeType
-{
- MERGE_GUI, //pure gui config files
- MERGE_BATCH, // " batch "
- MERGE_GUI_BATCH, //gui and batch files
- MERGE_OTHER
-};
-MergeType getMergeType(const std::vector<Zstring>& filenames); //noexcept
-
void readAnyConfig(const std::vector<Zstring>& filenames, XmlGuiConfig& config); //throw FfsXmlError
//config conversion utilities
diff --git a/lib/resolve_path.cpp b/lib/resolve_path.cpp
index 035e1d77..daa99d2a 100644
--- a/lib/resolve_path.cpp
+++ b/lib/resolve_path.cpp
@@ -620,20 +620,28 @@ void zen::loginNetworkShare(const Zstring& dirnameOrig, bool allowUserInteractio
nullptr, // __in LPCTSTR lpPassword,
nullptr, // __in LPCTSTR lpUsername,
0); //__in DWORD dwFlags
+ //53L ERROR_BAD_NETPATH The network path was not found.
+ //86L ERROR_INVALID_PASSWORD
+ //1219L ERROR_SESSION_CREDENTIAL_CONFLICT Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again.
+ //1326L ERROR_LOGON_FAILURE Logon failure: unknown user name or bad password.
+ //1236L ERROR_CONNECTION_ABORTED
if (somethingExists(trgRes.lpRemoteName)) //blocks!
return; //success: connection usable! -> don't care about "rv"
if (rv == ERROR_BAD_NETPATH || //Windows 7
- rv == ERROR_BAD_NET_NAME) //XP
+ rv == ERROR_BAD_NET_NAME|| //XP
+ rv == ERROR_CONNECTION_ABORTED) //failed to connect to a network that existed not too long ago; will later return ERROR_BAD_NETPATH
return; //no need to show a prompt for an unreachable network device
//2. if first attempt failed, we need to *force* prompt by using CONNECT_PROMPT
if (allowUserInteraction)
{
//avoid problem II.)
- DWORD rv2= WNetCancelConnection2(trgRes.lpRemoteName, //_In_ LPCTSTR lpName,
- 0, //_In_ DWORD dwFlags,
- true); //_In_ BOOL fForce
+ DWORD rv2= ::WNetCancelConnection2(trgRes.lpRemoteName, //_In_ LPCTSTR lpName,
+ 0, //_In_ DWORD dwFlags,
+ true); //_In_ BOOL fForce
+ //2250L ERROR_NOT_CONNECTED
+
//enforce login prompt
DWORD rv3 = ::WNetAddConnection2(&trgRes, // __in LPNETRESOURCE lpNetResource,
nullptr, // __in LPCTSTR lpPassword,
@@ -641,11 +649,6 @@ void zen::loginNetworkShare(const Zstring& dirnameOrig, bool allowUserInteractio
CONNECT_INTERACTIVE | CONNECT_PROMPT); //__in DWORD dwFlags
(void)rv2;
(void)rv3;
- //Sample error codes:
- //53L ERROR_BAD_NETPATH The network path was not found.
- //86L ERROR_INVALID_PASSWORD
- //1219L ERROR_SESSION_CREDENTIAL_CONFLICT Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again.
- //1326L ERROR_LOGON_FAILURE Logon failure: unknown user name or bad password.
}
};
diff --git a/lib/shadow.cpp b/lib/shadow.cpp
index 1161646e..71372270 100644
--- a/lib/shadow.cpp
+++ b/lib/shadow.cpp
@@ -111,14 +111,11 @@ Zstring ShadowCopy::makeShadowCopy(const Zstring& inputFile, const std::function
const Zstring volumeNamePf = appendSeparator(&volBuffer[0]); //msdn: if buffer is 1 char too short, GetVolumePathName() may skip last separator without error!
//input file is always absolute! directory formatting takes care of this! Therefore volume name can always be found.
- const size_t pos = filenameFinal.find(volumeNamePf); //filenameFinal needs NOT to begin with volumeNamePf: consider for example \\?\ prefix!
+ const size_t pos = filenameFinal.find(volumeNamePf); //filenameFinal needs NOT to begin with volumeNamePf: consider \\?\ prefix!
if (pos == Zstring::npos)
- {
- std::wstring msg = _("Volume name %x not part of file name %y.");
- replace(msg, L"%x", fmtFileName(volumeNamePf), false);
- replace(msg, L"%y", fmtFileName(filenameFinal), false);
- throw FileError(msg);
- }
+ throw FileError(replaceCpy(replaceCpy(_("Volume name %x is not part of file path %y."),
+ L"%x", fmtFileName(volumeNamePf)),
+ L"%y", fmtFileName(filenameFinal)));
//get or create instance of shadow volume
VolNameShadowMap::const_iterator it = shadowVol.find(volumeNamePf);
diff --git a/lib/status_handler.cpp b/lib/status_handler.cpp
index c24c6f50..5fb80161 100644
--- a/lib/status_handler.cpp
+++ b/lib/status_handler.cpp
@@ -5,21 +5,12 @@
// **************************************************************************
#include "status_handler.h"
-#include <wx/app.h>
+//#include <wx/app.h>
#include <zen/tick_count.h>
using namespace zen;
-void zen::updateUiNow()
-{
- //process UI events and prevent application from "not responding" -> NO performance issue!
- wxTheApp->Yield();
-
- // while (wxTheApp->Pending())
- // wxTheApp->Dispatch();
-}
-
namespace
{
const std::int64_t TICKS_UPDATE_INTERVAL = UI_UPDATE_INTERVAL* ticksPerSec() / 1000;
diff --git a/lib/status_handler.h b/lib/status_handler.h
index ed496824..c19935b1 100644
--- a/lib/status_handler.h
+++ b/lib/status_handler.h
@@ -16,13 +16,12 @@
namespace zen
{
bool updateUiIsAllowed(); //test if a specific amount of time is over
-void updateUiNow(); //do the updating
/*
Updating GUI is fast!
time per single call to ProcessCallback::forceUiRefresh()
- - Comparison 25 µs
- - Synchronization 0.6 ms (despite complex graph control!)
+ - Comparison 0.025 ms
+ - Synchronization 0.74 ms (despite complex graph control!)
*/
//gui may want to abort process
@@ -72,11 +71,13 @@ protected:
virtual void requestUiRefresh()
{
- if (updateUiIsAllowed()) //test if specific time span between ui updates is over
+ if (abortRequested) //triggered by requestAbortion()
+ {
+ forceUiRefresh();
+ abortThisProcess();
+ }
+ else if (updateUiIsAllowed()) //test if specific time span between ui updates is over
forceUiRefresh();
-
- if (abortRequested) //check *after* GUI update, to have up-to-date screen
- abortThisProcess(); //triggered by requestAbortion()
}
virtual void reportStatus(const std::wstring& text) { statusText_ = text; requestUiRefresh(); /*throw AbortThisProcess */ }
diff --git a/lib/versioning.cpp b/lib/versioning.cpp
index 1bf5a65e..a6458196 100644
--- a/lib/versioning.cpp
+++ b/lib/versioning.cpp
@@ -129,15 +129,14 @@ void moveObject(const Zstring& sourceFile, //throw FileError
{
assert(!dirExists(sourceFile) || symlinkExists(sourceFile)); //we process files and symlinks only
- auto removeTarget = [&]()
+ auto removeTarget = [&]
{
//remove target object
if (fileExists(targetFile)) //file or symlink
removeFile(targetFile); //throw FileError
else if (dirExists(targetFile)) //directory or symlink
- removeDirectory(targetFile); //throw FileError
- //we do not expect targetFile to be a directory in general => no callback required
- else assert(false);
+ removeDirectory(targetFile); //throw FileError; we do not expect targetFile to be a directory in general => no callback required
+ //else assert(false); -> may simply not exist if ErrorDifferentVolume!
};
//first try to move directly without copying
bgstack15