summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:20:07 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:20:07 +0200
commit88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170 (patch)
treec6c5babb49b90293380106b81ae5c446959ac70f /lib
parent5.3 (diff)
downloadFreeFileSync-88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170.tar.gz
FreeFileSync-88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170.tar.bz2
FreeFileSync-88a8b528e20013c0aa3cc6bcd9659b0b5ddd9170.zip
5.4
Diffstat (limited to 'lib')
-rw-r--r--lib/binary.cpp42
-rw-r--r--lib/db_file.cpp10
-rw-r--r--lib/dir_exist_async.h3
-rw-r--r--lib/dir_lock.cpp46
-rw-r--r--lib/help_provider.h5
-rw-r--r--lib/localization.cpp23
-rw-r--r--lib/parallel_scan.cpp80
-rw-r--r--lib/parallel_scan.h8
-rw-r--r--lib/parse_lng.h25
-rw-r--r--lib/perf_check.cpp7
-rw-r--r--lib/process_xml.cpp20
-rw-r--r--lib/process_xml.h14
-rw-r--r--lib/resolve_path.cpp10
-rw-r--r--lib/resources.cpp2
-rw-r--r--lib/return_codes.h22
-rw-r--r--lib/shadow.cpp2
-rw-r--r--lib/status_handler.h1
-rw-r--r--lib/xml_base.cpp3
18 files changed, 170 insertions, 153 deletions
diff --git a/lib/binary.cpp b/lib/binary.cpp
index c01bb4d2..4fc1d408 100644
--- a/lib/binary.cpp
+++ b/lib/binary.cpp
@@ -5,12 +5,15 @@
// **************************************************************************
#include "binary.h"
-#include <wx/stopwatch.h>
+#include <zen/tick_count.h>
#include <vector>
#include <zen/file_io.h>
#include <zen/int64.h>
#include <boost/thread/tss.hpp>
+using namespace zen;
+
+
inline
void setMinSize(std::vector<char>& buffer, size_t minSize)
{
@@ -61,6 +64,9 @@ private:
size_t bufSize;
};
+
+
+const std::int64_t TICKS_PER_SEC = ticksPerSec();
}
@@ -80,33 +86,39 @@ bool zen::filesHaveSameContent(const Zstring& filename1, const Zstring& filename
std::vector<char>& memory2 = *cpyBuf2;
BufferSize bufferSize;
- zen::UInt64 bytesCompared;
+ UInt64 bytesCompared;
- wxLongLong lastDelayViolation = wxGetLocalTimeMillis();
+ TickVal lastDelayViolation = getTicks();
do
{
setMinSize(memory1, bufferSize);
setMinSize(memory2, bufferSize);
- const wxLongLong startTime = wxGetLocalTimeMillis();
+ const TickVal startTime = getTicks();
const size_t length1 = file1.read(&memory1[0], bufferSize); //returns actual number of bytes read; throw FileError()
const size_t length2 = file2.read(&memory2[0], bufferSize); //
- const wxLongLong stopTime = wxGetLocalTimeMillis();
+ const TickVal stopTime = getTicks();
- //-------- dynamically set buffer size to keep callback interval between 200 - 500ms ---------------------
- const wxLongLong loopTime = stopTime - startTime;
- if (loopTime < 200 && stopTime - lastDelayViolation > 2000) //avoid "flipping back": e.g. DVD-Roms read 32MB at once, so first read may be > 300 ms, but second one will be 0ms!
- {
- lastDelayViolation = stopTime;
- bufferSize.inc(); //practically no costs!
- }
- else if (loopTime > 500)
+ //-------- dynamically set buffer size to keep callback interval between 100 - 500ms ---------------------
+ if (TICKS_PER_SEC > 0)
{
- lastDelayViolation = stopTime;
- bufferSize.dec(); //
+ const std::int64_t loopTime = (stopTime - startTime) * 1000 / TICKS_PER_SEC; //unit: [ms]
+ if (loopTime < 100)
+ {
+ if ((stopTime - lastDelayViolation) / TICKS_PER_SEC > 2) //avoid "flipping back": e.g. DVD-Roms read 32MB at once, so first read may be > 500 ms, but second one will be 0ms!
+ {
+ lastDelayViolation = stopTime;
+ bufferSize.inc();
+ }
+ }
+ else if (loopTime > 500)
+ {
+ lastDelayViolation = stopTime;
+ bufferSize.dec();
+ }
}
//------------------------------------------------------------------------------------------------
diff --git a/lib/db_file.cpp b/lib/db_file.cpp
index 1bc75d82..33c83a0e 100644
--- a/lib/db_file.cpp
+++ b/lib/db_file.cpp
@@ -15,7 +15,7 @@
#include <zen/file_io.h>
#include <zen/scope_guard.h>
#include <zen/guid.h>
-#include <zen/utf8.h>
+#include <zen/utf.h>
#ifdef FFS_WIN
#include <zen/win.h> //includes "windows.h"
@@ -128,7 +128,7 @@ StreamMapping loadStreams(const Zstring& filename) //throw FileError
}
catch (const std::bad_alloc& e)
{
- throw FileError(_("Out of memory!") + L" " + utf8CvrtTo<std::wstring>(e.what()));
+ throw FileError(_("Out of memory!") + L" " + utfCvrtTo<std::wstring>(e.what()));
}
}
@@ -148,7 +148,7 @@ public:
}
catch (const std::bad_alloc& e)
{
- throw FileError(_("Out of memory!") + L" " + utf8CvrtTo<std::wstring>(e.what()));
+ throw FileError(_("Out of memory!") + L" " + utfCvrtTo<std::wstring>(e.what()));
}
}
@@ -160,7 +160,7 @@ private:
Zstring readStringUtf8() const
{
- return utf8CvrtTo<Zstring>(readString<Zbase<char>>());
+ return utfCvrtTo<Zstring>(readString<Zbase<char>>());
}
FileId readFileId() const
@@ -280,7 +280,7 @@ private:
writePOD<bool>(false); //mark last entry
}
- void writeStringUtf8(const Zstring& str) { writeString(utf8CvrtTo<Zbase<char>>(str)); }
+ void writeStringUtf8(const Zstring& str) { writeString(utfCvrtTo<Zbase<char>>(str)); }
void writeFileId(const FileId& id)
{
diff --git a/lib/dir_exist_async.h b/lib/dir_exist_async.h
index 40ddffc7..2ab98e94 100644
--- a/lib/dir_exist_async.h
+++ b/lib/dir_exist_async.h
@@ -9,7 +9,6 @@
#include <zen/thread.h>
#include <zen/file_handling.h>
-//#include "status_handler.h"
#include "process_callback.h"
#include <zen/file_error.h>
#include "resolve_path.h"
@@ -21,7 +20,7 @@ bool dirExistsUpdating(const Zstring& dirname, bool allowUserInteraction, Proces
{
using namespace zen;
- procCallback.reportStatus(replaceCpy(_("Searching for directory %x..."), L"%x", fmtFileName(dirname), false));
+ procCallback.reportStatus(replaceCpy(_("Searching for folder %x..."), L"%x", fmtFileName(dirname), false));
auto ft = async([=]() -> bool
{
diff --git a/lib/dir_lock.cpp b/lib/dir_lock.cpp
index 402892c6..f41bbfa8 100644
--- a/lib/dir_lock.cpp
+++ b/lib/dir_lock.cpp
@@ -5,10 +5,9 @@
// **************************************************************************
#include "dir_lock.h"
#include <utility>
-#include <wx/utils.h>
-#include <wx/timer.h>
+//#include <wx/utils.h>
#include <wx/log.h>
-#include <wx/msgdlg.h>
+//#include <wx/msgdlg.h>
#include <memory>
#include <wx+/string_conv.h>
#include <zen/last_error.h>
@@ -16,6 +15,7 @@
#include <zen/scope_guard.h>
#include <zen/guid.h>
#include <zen/file_io.h>
+#include <zen/tick_count.h>
#include <zen/assert_static.h>
#include <wx+/serialize.h>
#include <zen/int64.h>
@@ -39,9 +39,9 @@ using namespace std::rel_ops;
namespace
{
-const size_t EMIT_LIFE_SIGN_INTERVAL = 5000; //show life sign; unit: [ms]
-const size_t POLL_LIFE_SIGN_INTERVAL = 4000; //poll for life sign; unit: [ms]
-const size_t DETECT_ABANDONED_INTERVAL = 30000; //assume abandoned lock; unit: [ms]
+const int EMIT_LIFE_SIGN_INTERVAL = 5; //show life sign; unit: [s]
+const int POLL_LIFE_SIGN_INTERVAL = 4; //poll for life sign; unit: [s]
+const int DETECT_ABANDONED_INTERVAL = 30; //assume abandoned lock; unit: [s]
const char LOCK_FORMAT_DESCR[] = "FreeFileSync";
const int LOCK_FORMAT_VER = 2; //lock file format version
@@ -60,7 +60,7 @@ public:
{
while (true)
{
- boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(EMIT_LIFE_SIGN_INTERVAL)); //interruption point!
+ boost::this_thread::sleep(boost::posix_time::seconds(EMIT_LIFE_SIGN_INTERVAL)); //interruption point!
//actual work
emitLifeSign(); //throw ()
@@ -68,7 +68,7 @@ public:
}
catch (const std::exception& e) //exceptions must be catched per thread
{
- wxSafeShowMessage(_("An exception occurred!") + L" (Dirlock)", utf8CvrtTo<wxString>(e.what())); //simple wxMessageBox won't do for threads
+ wxSafeShowMessage(_("An exception occurred!") + L" (Dirlock)", utfCvrtTo<wxString>(e.what())); //simple wxMessageBox won't do for threads
}
}
@@ -228,7 +228,7 @@ struct LockInformation //throw FileError
explicit LockInformation(FromCurrentProcess) :
lockId(zen::generateGUID()),
#ifdef FFS_WIN
- sessionId(utf8CvrtTo<std::string>(getLoginSid())), //throw FileError
+ sessionId(utfCvrtTo<std::string>(getLoginSid())), //throw FileError
processId(::GetCurrentProcessId()) //never fails
{
DWORD bufferSize = 0;
@@ -239,14 +239,14 @@ struct LockInformation //throw FileError
&buffer[0], //__out LPTSTR lpBuffer,
&bufferSize)) //__inout LPDWORD lpnSize
throw FileError(_("Cannot get process information.") + L"\n\n" + getLastErrorFormatted());
- computerName = "Windows." + utf8CvrtTo<std::string>(&buffer[0]);
+ computerName = "Windows." + utfCvrtTo<std::string>(&buffer[0]);
bufferSize = UNLEN + 1;
buffer.resize(bufferSize);
if (!::GetUserName(&buffer[0], //__out LPTSTR lpBuffer,
&bufferSize)) //__inout LPDWORD lpnSize
throw FileError(_("Cannot get process information.") + L"\n\n" + getLastErrorFormatted());
- userId = utf8CvrtTo<std::string>(&buffer[0]);
+ userId = utfCvrtTo<std::string>(&buffer[0]);
}
#elif defined FFS_LINUX
processId(::getpid()) //never fails
@@ -399,6 +399,9 @@ 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));
@@ -429,13 +432,16 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr
catch (FileError&) {} //logfile may be only partly written -> this is no error!
UInt64 fileSizeOld;
- wxMilliClock_t lastLifeSign = wxGetLocalTimeMillis();
+ TickVal lastLifeSign = getTicks();
while (true)
{
- wxMilliClock_t currentTime = wxGetLocalTimeMillis();
+ const TickVal currentTime = getTicks();
const UInt64 fileSizeNew = ::getLockFileSize(lockfilename); //throw FileError, ErrorNotExisting
+ if (TICKS_PER_SEC <= 0 || !lastLifeSign.isValid() || !currentTime.isValid())
+ throw FileError(L"System Timer failed!"); //no i18n: "should" never throw ;)
+
if (fileSizeNew != fileSizeOld) //received life sign from lock
{
fileSizeOld = fileSizeNew;
@@ -443,7 +449,7 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr
}
if (lockOwnderDead || //no need to wait any longer...
- currentTime - lastLifeSign > DETECT_ABANDONED_INTERVAL)
+ (currentTime - lastLifeSign) / TICKS_PER_SEC > DETECT_ABANDONED_INTERVAL)
{
DirLock dummy(deleteAbandonedLockName(lockfilename), callback); //throw FileError
@@ -461,19 +467,19 @@ void waitOnDirLock(const Zstring& lockfilename, DirLockCallback* callback) //thr
}
//wait some time...
- assert_static(POLL_LIFE_SIGN_INTERVAL % GUI_CALLBACK_INTERVAL == 0);
- for (size_t i = 0; i < POLL_LIFE_SIGN_INTERVAL / GUI_CALLBACK_INTERVAL; ++i)
+ assert_static(1000 * POLL_LIFE_SIGN_INTERVAL % GUI_CALLBACK_INTERVAL == 0);
+ for (size_t i = 0; i < 1000 * POLL_LIFE_SIGN_INTERVAL / GUI_CALLBACK_INTERVAL; ++i)
{
if (callback) callback->requestUiRefresh();
- wxMilliSleep(GUI_CALLBACK_INTERVAL);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(GUI_CALLBACK_INTERVAL));
if (callback)
{
//one signal missed: it's likely this is an abandoned lock => show countdown
- if (currentTime - lastLifeSign > EMIT_LIFE_SIGN_INTERVAL)
+ if ((currentTime - lastLifeSign) / TICKS_PER_SEC > EMIT_LIFE_SIGN_INTERVAL)
{
- long remainingSeconds = ((DETECT_ABANDONED_INTERVAL - (wxGetLocalTimeMillis() - lastLifeSign)) / 1000).ToLong();
- remainingSeconds = std::max(0L, remainingSeconds);
+ int remainingSeconds = DETECT_ABANDONED_INTERVAL - (getTicks() - lastLifeSign) / TICKS_PER_SEC;
+ remainingSeconds = std::max(0, remainingSeconds);
const std::wstring remSecMsg = replaceCpy(_P("1 sec", "%x sec", remainingSeconds), L"%x", numberTo<std::wstring>(remainingSeconds));
callback->reportInfo(infoMsg + L" " + remSecMsg);
diff --git a/lib/help_provider.h b/lib/help_provider.h
index 213c05e3..3b7443cb 100644
--- a/lib/help_provider.h
+++ b/lib/help_provider.h
@@ -9,10 +9,11 @@
#include <wx/help.h>
#include "ffs_paths.h"
+#include <zen/zstring.h>
namespace zen
{
-void displayHelpEntry(const wxString& section = wxEmptyString);
+void displayHelpEntry(const wxString& section = wxEmptyString); //use '/' as path separator!
@@ -52,7 +53,7 @@ void displayHelpEntry(const wxString& section)
if (section.empty())
getHelpCtrl().DisplayContents();
else
- getHelpCtrl().DisplaySection(section);
+ getHelpCtrl().DisplaySection(replaceCpy(section, L'/', utfCvrtTo<std::wstring>(FILE_NAME_SEPARATOR)));
}
}
diff --git a/lib/localization.cpp b/lib/localization.cpp
index f056aea0..5f9a4750 100644
--- a/lib/localization.cpp
+++ b/lib/localization.cpp
@@ -90,21 +90,21 @@ FFSLocale::FFSLocale(const wxString& filename, wxLanguage languageId) : langId_(
for (lngfile::TranslationMap::const_iterator i = transInput.begin(); i != transInput.end(); ++i)
{
- const std::wstring original = utf8CvrtTo<std::wstring>(i->first);
- const std::wstring translation = utf8CvrtTo<std::wstring>(i->second);
+ const std::wstring original = utfCvrtTo<std::wstring>(i->first);
+ const std::wstring translation = utfCvrtTo<std::wstring>(i->second);
assert(!translation.empty());
transMapping.insert(std::make_pair(original , translation));
}
for (lngfile::TranslationPluralMap::const_iterator i = transPluralInput.begin(); i != transPluralInput.end(); ++i)
{
- const std::wstring singular = utf8CvrtTo<std::wstring>(i->first.first);
- const std::wstring plural = utf8CvrtTo<std::wstring>(i->first.second);
+ const std::wstring singular = utfCvrtTo<std::wstring>(i->first.first);
+ const std::wstring plural = utfCvrtTo<std::wstring>(i->first.second);
const lngfile::PluralForms& plForms = i->second;
std::vector<std::wstring> plFormsWide;
for (lngfile::PluralForms::const_iterator j = plForms.begin(); j != plForms.end(); ++j)
- plFormsWide.push_back(utf8CvrtTo<std::wstring>(*j));
+ plFormsWide.push_back(utfCvrtTo<std::wstring>(*j));
assert(!plFormsWide.empty());
@@ -127,9 +127,9 @@ public:
lngFiles_.push_back(fullName);
}
- virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {}
+ virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) { return LINK_SKIP; }
virtual std::shared_ptr<TraverseCallback> onDir(const Zchar* shortName, const Zstring& fullName) { return nullptr; }
- virtual HandleError onError(const std::wstring& errorText) { return TRAV_ERROR_IGNORE; } //errors are not really critical in this context
+ virtual HandleError onError(const std::wstring& errorText) { return ON_ERROR_IGNORE; } //errors are not really critical in this context
private:
std::vector<Zstring>& lngFiles_;
@@ -177,7 +177,6 @@ ExistingTranslations::ExistingTranslations()
FindLngfiles traverseCallback(lngFiles);
traverseFolder(zen::getResourceDir() + Zstr("Languages"), //throw();
- false, //don't follow symlinks
traverseCallback);
for (auto i = lngFiles.begin(); i != lngFiles.end(); ++i)
@@ -193,14 +192,14 @@ ExistingTranslations::ExistingTranslations()
There is some buggy behavior in wxWidgets which maps "zh_TW" to simplified chinese.
Fortunately locales can be also entered as description. I changed to "Chinese (Traditional)" which works fine.
*/
- if (const wxLanguageInfo* locInfo = wxLocale::FindLanguageInfo(utf8CvrtTo<wxString>(lngHeader.localeName)))
+ if (const wxLanguageInfo* locInfo = wxLocale::FindLanguageInfo(utfCvrtTo<wxString>(lngHeader.localeName)))
{
ExistingTranslations::Entry newEntry;
newEntry.languageID = locInfo->Language;
- newEntry.languageName = utf8CvrtTo<wxString>(lngHeader.languageName);
+ newEntry.languageName = utfCvrtTo<wxString>(lngHeader.languageName);
newEntry.languageFile = toWx(*i);
- newEntry.translatorName = utf8CvrtTo<wxString>(lngHeader.translatorName);
- newEntry.languageFlag = utf8CvrtTo<wxString>(lngHeader.flagFile);
+ newEntry.translatorName = utfCvrtTo<wxString>(lngHeader.translatorName);
+ newEntry.languageFlag = utfCvrtTo<wxString>(lngHeader.flagFile);
locMapping.push_back(newEntry);
}
}
diff --git a/lib/parallel_scan.cpp b/lib/parallel_scan.cpp
index 9ab99920..435067b2 100644
--- a/lib/parallel_scan.cpp
+++ b/lib/parallel_scan.cpp
@@ -13,6 +13,7 @@
#include <wx+/string_conv.h>
#include <zen/thread.h> //includes <boost/thread.hpp>
#include <zen/scope_guard.h>
+#include <zen/fixed_list.h>
using namespace zen;
@@ -219,7 +220,7 @@ public:
void reportCurrentFile(const Zstring& filename, int threadID) //context of worker thread
{
- if (threadID != notifyingThreadID) return; //only one thread may report status
+ if (threadID != notifyingThreadID) return; //only one thread at a time may report status
boost::lock_guard<boost::mutex> dummy(lockCurrentStatus);
currentFile = filename;
@@ -329,7 +330,7 @@ public:
virtual std::shared_ptr<TraverseCallback>
onDir (const Zchar* shortName, const Zstring& fullName);
virtual void onFile (const Zchar* shortName, const Zstring& fullName, const FileInfo& details);
- virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details);
+ virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details);
virtual HandleError onError (const std::wstring& errorText);
private:
@@ -377,26 +378,38 @@ void DirCallback::onFile(const Zchar* shortName, const Zstring& fullName, const
}
-void DirCallback::onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details)
+DirCallback::HandleLink DirCallback::onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details)
{
boost::this_thread::interruption_point();
- if (cfg.handleSymlinks_ == SYMLINK_IGNORE)
- return;
+ switch (cfg.handleSymlinks_)
+ {
+ case SYMLINK_IGNORE:
+ return LINK_SKIP;
- //update status information no matter whether object is excluded or not!
- cfg.acb_.reportCurrentFile(fullName, cfg.threadID_);
+ case SYMLINK_USE_DIRECTLY:
+ {
+ //update status information no matter whether object is excluded or not!
+ cfg.acb_.reportCurrentFile(fullName, cfg.threadID_);
- //------------------------------------------------------------------------------------
- const Zstring& relName = relNameParentPf_ + shortName;
+ //------------------------------------------------------------------------------------
+ const Zstring& relName = relNameParentPf_ + shortName;
- //apply filter before processing (use relative name!)
- if (!cfg.filterInstance->passFileFilter(relName)) //always use file filter: Link type may not be "stable" on Linux!
- return;
+ //apply filter before processing (use relative name!)
+ if (cfg.filterInstance->passFileFilter(relName)) //always use file filter: Link type may not be "stable" on Linux!
+ {
+ output_.addSubLink(shortName, LinkDescriptor(details.lastWriteTimeRaw, details.targetPath, details.dirLink ? LinkDescriptor::TYPE_DIR : LinkDescriptor::TYPE_FILE));
+ cfg.acb_.incItemsScanned(); //add 1 element to the progress indicator
+ }
+ }
+ return LINK_SKIP;
- output_.addSubLink(shortName, LinkDescriptor(details.lastWriteTimeRaw, details.targetPath, details.dirLink ? LinkDescriptor::TYPE_DIR : LinkDescriptor::TYPE_FILE));
+ case SYMLINK_FOLLOW_LINK:
+ return LINK_FOLLOW;
+ }
- cfg.acb_.incItemsScanned(); //add 1 element to the progress indicator
+ assert(false);
+ return LINK_SKIP;
}
@@ -429,16 +442,16 @@ DirCallback::HandleError DirCallback::onError(const std::wstring& errorText)
{
switch (cfg.acb_.reportError(errorText))
{
- case FillBufferCallback::TRAV_ERROR_IGNORE:
+ case FillBufferCallback::ON_ERROR_IGNORE:
cfg.failedReads_.insert(relNameParentPf_);
- return TRAV_ERROR_IGNORE;
+ return ON_ERROR_IGNORE;
- case FillBufferCallback::TRAV_ERROR_RETRY:
- return TRAV_ERROR_RETRY;
+ case FillBufferCallback::ON_ERROR_RETRY:
+ return ON_ERROR_RETRY;
}
assert(false);
- return TRAV_ERROR_IGNORE;
+ return ON_ERROR_IGNORE;
}
@@ -498,20 +511,6 @@ public:
Zstring(),
dirVal.dirCont);
- bool followSymlinks = false;
- switch (item.first.handleSymlinks_)
- {
- case SYMLINK_IGNORE:
- followSymlinks = false; //=> symlinks will be reported via onSymlink() where they are excluded
- break;
- case SYMLINK_USE_DIRECTLY:
- followSymlinks = false;
- break;
- case SYMLINK_FOLLOW_LINK:
- followSymlinks = true;
- break;
- }
-
DstHackCallback* dstCallbackPtr = nullptr;
#ifdef FFS_WIN
DstHackCallbackImpl dstCallback(*acb_, threadID_);
@@ -519,7 +518,7 @@ public:
#endif
//get all files and folders from directoryPostfixed (and subdirectories)
- traverseFolder(directoryName, followSymlinks, traverser, dstCallbackPtr); //exceptions may be thrown!
+ traverseFolder(directoryName, traverser, dstCallbackPtr); //exceptions may be thrown!
});
}
@@ -540,8 +539,7 @@ void zen::fillBuffer(const std::set<DirectoryKey>& keysToRead, //in
std::vector<std::set<DirectoryKey>> buckets = separateByDistinctDisk(keysToRead); //one bucket per physical device
- std::vector<boost::thread> worker; //note: GCC doesn't allow to construct an array of empty threads since they would be initialized by const boost::thread&
- worker.reserve(buckets.size());
+ FixedList<boost::thread> worker; //note: we cannot use std::vector<boost::thread>: compiler error on GCC 4.7, probably a boost screw-up
zen::ScopeGuard guardWorker = zen::makeGuard([&]
{
@@ -554,7 +552,6 @@ void zen::fillBuffer(const std::set<DirectoryKey>& keysToRead, //in
//init worker threads
for (auto iter = buckets.begin(); iter != buckets.end(); ++iter)
{
- int threadID = iter - buckets.begin();
const std::set<DirectoryKey>& bucket = *iter;
std::vector<std::pair<DirectoryKey, DirectoryValue*>> workload;
@@ -566,16 +563,17 @@ void zen::fillBuffer(const std::set<DirectoryKey>& keysToRead, //in
workload.push_back(std::make_pair(key, &rv.first->second));
});
- worker.push_back(boost::thread(WorkerThread(threadID, acb, workload)));
+ const int threadId = iter - buckets.begin();
+ worker.emplace_back(WorkerThread(threadId, acb, workload));
}
//wait until done
- for (auto iter = worker.begin(); iter != worker.end(); ++iter)
+ int threadId = 0;
+ for (auto iter = worker.begin(); iter != worker.end(); ++iter, ++threadId)
{
boost::thread& wt = *iter;
- int threadID = iter - worker.begin();
- acb->setNotifyingThread(threadID); //process info messages of first (active) thread only
+ acb->setNotifyingThread(threadId); //process info messages of first (active) thread only
do
{
diff --git a/lib/parallel_scan.h b/lib/parallel_scan.h
index 836892ad..0ce0114d 100644
--- a/lib/parallel_scan.h
+++ b/lib/parallel_scan.h
@@ -56,11 +56,11 @@ public:
enum HandleError
{
- TRAV_ERROR_RETRY,
- TRAV_ERROR_IGNORE
+ ON_ERROR_RETRY,
+ ON_ERROR_IGNORE
};
- virtual HandleError reportError (const std::wstring& errorText) = 0; //may throw!
- virtual void reportStatus(const std::wstring& statusMsg, int itemTotal) = 0; //
+ virtual HandleError reportError (const std::wstring& errorText) = 0; //may throw!
+ virtual void reportStatus(const std::wstring& statusMsg, int itemsTotal) = 0; //
};
//attention: ensure directory filtering is applied later to exclude filtered directories which have been kept as parent folders
diff --git a/lib/parse_lng.h b/lib/parse_lng.h
index 07932c3a..6a0b9dc5 100644
--- a/lib/parse_lng.h
+++ b/lib/parse_lng.h
@@ -17,7 +17,8 @@
#include <stdexcept>
#include <string>
#include <vector>
-#include <zen/utf8.h>
+#include <zen/utf.h>
+#include <zen/string_tools.h>
namespace lngfile
{
@@ -311,24 +312,6 @@ private:
std::string::const_iterator pos;
};
-template <class C, class T>
-inline
-std::basic_string<C> numberToString(const T& number) //convert number to string the C++ way
-{
- std::basic_ostringstream<C> ss;
- ss << number;
- return ss.str();
-}
-
-template <class T, class C>
-inline
-T stringToNumber(const std::basic_string<C>& str) //convert string to number the C++ way
-{
- T number = 0;
- std::basic_istringstream<C>(str) >> number;
- return number;
-}
-
class LngParser
{
@@ -370,7 +353,7 @@ public:
consumeToken(Token::TK_FLAG_FILE_END);
consumeToken(Token::TK_PLURAL_COUNT_BEGIN);
- header.pluralCount = stringToNumber<int>(tk.text);
+ header.pluralCount = zen::stringTo<int>(tk.text);
consumeToken(Token::TK_TEXT);
consumeToken(Token::TK_PLURAL_COUNT_END);
@@ -521,7 +504,7 @@ void generateLng(const TranslationList& in, const TransHeader& header, std::stri
fileStream += KnownTokens::text(Token::TK_FLAG_FILE_END) + LB;
fileStream += TAB + KnownTokens::text(Token::TK_PLURAL_COUNT_BEGIN);
- fileStream += numberToString<char>(header.pluralCount);
+ fileStream += zen::numberTo<std::string>(header.pluralCount);
fileStream += KnownTokens::text(Token::TK_PLURAL_COUNT_END) + LB;
fileStream += TAB + KnownTokens::text(Token::TK_PLURAL_DEF_BEGIN);
diff --git a/lib/perf_check.cpp b/lib/perf_check.cpp
index 897be12c..ab0f7769 100644
--- a/lib/perf_check.cpp
+++ b/lib/perf_check.cpp
@@ -79,7 +79,7 @@ wxString PerfCheck::getRemainingTime(double dataRemaining) const
return zen::remainingTimeToShortString(remTimeSec);
}
}
- return wxT("-"); //fallback
+ return L"-"; //fallback
}
@@ -102,7 +102,7 @@ wxString PerfCheck::getBytesPerSecond() const
if (dataDelta > 0) //may be negative if user cancels copying
return zen::filesizeToShortString(zen::Int64(dataDelta * 1000 / timeDelta)) + _("/sec");
}
- return wxT("-"); //fallback
+ return L"-"; //fallback
}
@@ -120,7 +120,7 @@ wxString PerfCheck::getOverallBytesPerSecond() const //for all samples
if (dataDelta > 0) //may be negative if user cancels copying
return zen::filesizeToShortString(zen::Int64(dataDelta * 1000 / timeDelta)) + _("/sec");
}
- return wxT("-"); //fallback
+ return L"-"; //fallback
}
@@ -255,5 +255,4 @@ wxString Statistics::getRemainingTime(const int objectsCurrent, const double dat
return formatRemainingTime((objectsTotal - objectsCurrent) * z1_current + (dataTotal - dataCurrent) * z2_current);
}
-
*/
diff --git a/lib/process_xml.cpp b/lib/process_xml.cpp
index a3ed5bfc..677618b4 100644
--- a/lib/process_xml.cpp
+++ b/lib/process_xml.cpp
@@ -646,7 +646,7 @@ bool readText(const std::string& input, DirectionConfig::Variant& value)
template <> inline
-bool readValue(const XmlElement& input, ColumnAttributeRim& value)
+bool readStruc(const XmlElement& input, ColumnAttributeRim& value)
{
XmlIn in(input);
bool rv1 = in.attribute("Type", value.type_);
@@ -656,7 +656,7 @@ bool readValue(const XmlElement& input, ColumnAttributeRim& value)
}
template <> inline
-void writeValue(const ColumnAttributeRim& value, XmlElement& output)
+void writeStruc(const ColumnAttributeRim& value, XmlElement& output)
{
XmlOut out(output);
out.attribute("Type", value.type_);
@@ -666,7 +666,7 @@ void writeValue(const ColumnAttributeRim& value, XmlElement& output)
template <> inline
-bool readValue(const XmlElement& input, ColumnAttributeNavi& value)
+bool readStruc(const XmlElement& input, ColumnAttributeNavi& value)
{
XmlIn in(input);
bool rv1 = in.attribute("Type", value.type_);
@@ -676,7 +676,7 @@ bool readValue(const XmlElement& input, ColumnAttributeNavi& value)
}
template <> inline
-void writeValue(const ColumnAttributeNavi& value, XmlElement& output)
+void writeStruc(const ColumnAttributeNavi& value, XmlElement& output)
{
XmlOut out(output);
out.attribute("Type", value.type_);
@@ -812,7 +812,7 @@ void readConfig(const XmlIn& in, xmlAccess::XmlGuiConfig& config)
inGuiCfg["HideFiltered" ](config.hideFilteredElements);
inGuiCfg["HandleError" ](config.handleError);
- inGuiCfg["SyncPreviewActive"](config.syncPreviewEnabled);
+ inGuiCfg["SyncPreviewActive"](config.showSyncAction);
}
@@ -1081,7 +1081,7 @@ void writeConfig(const XmlGuiConfig& config, XmlOut& out)
outGuiCfg["HideFiltered" ](config.hideFilteredElements);
outGuiCfg["HandleError" ](config.handleError);
- outGuiCfg["SyncPreviewActive"](config.syncPreviewEnabled);
+ outGuiCfg["SyncPreviewActive"](config.showSyncAction);
}
void writeConfig(const XmlBatchConfig& config, XmlOut& out)
@@ -1220,9 +1220,9 @@ void xmlAccess::writeConfig(const XmlGlobalSettings& config)
}
-wxString xmlAccess::extractJobName(const wxString& configFilename)
+std::wstring xmlAccess::extractJobName(const Zstring& configFilename)
{
- const wxString shortName = afterLast(configFilename, utf8CvrtTo<wxString>(FILE_NAME_SEPARATOR)); //returns the whole string if separator not found
- const wxString jobName = beforeLast(shortName, L'.'); //returns empty string if seperator not found
- return jobName.IsEmpty() ? shortName : jobName;
+ const Zstring shortName = afterLast(configFilename, FILE_NAME_SEPARATOR); //returns the whole string if separator not found
+ const Zstring jobName = beforeLast(shortName, Zstr('.')); //returns empty string if seperator not found
+ return utfCvrtTo<std::wstring>(jobName.empty() ? shortName : jobName);
}
diff --git a/lib/process_xml.h b/lib/process_xml.h
index 767e4a40..43dedb51 100644
--- a/lib/process_xml.h
+++ b/lib/process_xml.h
@@ -39,8 +39,8 @@ enum OnGuiError
ON_GUIERROR_IGNORE
};
-typedef wxString Description;
-typedef wxString Commandline;
+typedef std::wstring Description;
+typedef std::wstring Commandline;
typedef std::vector<std::pair<Description, Commandline> > ExternalApps;
//---------------------------------------------------------------------
@@ -49,20 +49,20 @@ struct XmlGuiConfig
XmlGuiConfig() :
hideFilteredElements(false),
handleError(ON_GUIERROR_POPUP),
- syncPreviewEnabled(true) {} //initialize values
+ showSyncAction(true) {} //initialize values
zen::MainConfiguration mainCfg;
bool hideFilteredElements;
OnGuiError handleError; //reaction on error situation during synchronization
- bool syncPreviewEnabled;
+ bool showSyncAction;
bool operator==(const XmlGuiConfig& other) const
{
return mainCfg == other.mainCfg &&
hideFilteredElements == other.hideFilteredElements &&
handleError == other.handleError &&
- syncPreviewEnabled == other.syncPreviewEnabled;
+ showSyncAction == other.showSyncAction;
}
bool operator!=(const XmlGuiConfig& other) const { return !(*this == other); }
@@ -174,7 +174,7 @@ struct XmlGlobalSettings
externelApplications.push_back(std::make_pair(L"Open with default application", //mark for extraction: _("Open with default application")
L"\"%name\""));
#elif defined FFS_LINUX
- externelApplications.push_back(std::make_pair(L"Browse directory", //mark for extraction: _("Browse directory")
+ externelApplications.push_back(std::make_pair(L"Browse directory", //mark for extraction: _("Browse directory") Linux doesn't use the term "folder"
L"xdg-open \"%dir\""));
externelApplications.push_back(std::make_pair(L"Open with default application", //mark for extraction: _("Open with default application")
L"xdg-open \"%name\""));
@@ -250,7 +250,7 @@ MergeType getMergeType(const std::vector<Zstring>& filenames); //throw ()
void convertConfig(const std::vector<Zstring>& filenames, XmlGuiConfig& config); //throw xmlAccess::FfsXmlError
void convertConfig(const std::vector<Zstring>& filenames, XmlBatchConfig& config); //throw xmlAccess::FfsXmlError
-wxString extractJobName(const wxString& configFilename);
+std::wstring extractJobName(const Zstring& configFilename);
}
diff --git a/lib/resolve_path.cpp b/lib/resolve_path.cpp
index f5a342d2..bb0c1f3b 100644
--- a/lib/resolve_path.cpp
+++ b/lib/resolve_path.cpp
@@ -260,13 +260,13 @@ public:
TraverseMedia(DeviceList& devices) : devices_(devices) {}
virtual void onFile(const Zchar* shortName, const Zstring& fullName, const FileInfo& details) {}
- virtual void onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) {}
+ virtual HandleLink onSymlink(const Zchar* shortName, const Zstring& fullName, const SymlinkInfo& details) { return LINK_SKIP; }
virtual std::shared_ptr<TraverseCallback> onDir(const Zchar* shortName, const Zstring& fullName)
{
devices_.insert(std::make_pair(shortName, fullName));
return nullptr; //DON'T traverse into subdirs
}
- virtual HandleError onError(const std::wstring& errorText) { return TRAV_ERROR_IGNORE; }
+ virtual HandleError onError(const std::wstring& errorText) { return ON_ERROR_IGNORE; }
private:
DeviceList& devices_;
@@ -328,7 +328,7 @@ Zstring volumenNameToPath(const Zstring& volumeName) //return empty string on er
TraverseMedia::DeviceList deviceList;
TraverseMedia traverser(deviceList);
- traverseFolder("/media", false, traverser); //traverse one level
+ traverseFolder("/media", traverser); //traverse one level
TraverseMedia::DeviceList::const_iterator iter = deviceList.find(volumeName);
if (iter != deviceList.end())
@@ -511,7 +511,7 @@ Zstring zen::getFormattedDirectoryName(const Zstring& dirString) // throw()
//remove leading/trailing whitespace
trim(dirname, true, false);
- while (endsWith(dirname, " ")) //don't remove all whitespace from right, e.g. 0xa0 may be used as part of dir name
+ while (endsWith(dirname, Zstr(' '))) //don't remove all whitespace from right, e.g. 0xa0 may be used as part of dir name
dirname.resize(dirname.size() - 1);
if (dirname.empty()) //an empty string would later be resolved as "\"; this is not desired
@@ -613,7 +613,7 @@ void zen::loginNetworkShare(const Zstring& dirnameOrig, bool allowUserInteractio
trgRes.dwType = RESOURCETYPE_DISK;
trgRes.lpRemoteName = const_cast<LPWSTR>(networkShare.c_str()); //trgRes is "__in"
- //note: following function call may block heavily if network is not reachable!!!
+ //following function call may block heavily if network is not reachable!!!
DWORD rv2 = ::WNetAddConnection2(&trgRes, // __in LPNETRESOURCE lpNetResource,
nullptr, // __in LPCTSTR lpPassword,
nullptr, // __in LPCTSTR lpUsername,
diff --git a/lib/resources.cpp b/lib/resources.cpp
index 3ae24d1d..670f2cfd 100644
--- a/lib/resources.cpp
+++ b/lib/resources.cpp
@@ -53,7 +53,7 @@ GlobalResources::GlobalResources()
wxImage::AddHandler(new wxPNGHandler); //ownership passed
wxZipInputStream resourceFile(input, wxConvUTF8);
- //do NOT rely on wxConvLocal! May result in "Cannot convert from the charset 'Unknown encoding (-1)'!"
+ //do NOT rely on wxConvLocal! ON failure shows unhelpful popup "Cannot convert from the charset 'Unknown encoding (-1)'!"
while (true)
{
diff --git a/lib/return_codes.h b/lib/return_codes.h
new file mode 100644
index 00000000..c5f8fd15
--- /dev/null
+++ b/lib/return_codes.h
@@ -0,0 +1,22 @@
+// **************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
+// * Copyright (C) ZenJu (zhnmju123 AT gmx DOT de) - All Rights Reserved *
+// **************************************************************************
+
+#ifndef RETURN_CODES_H_INCLUDED
+#define RETURN_CODES_H_INCLUDED
+
+namespace zen
+{
+enum FfsReturnCode
+{
+ FFS_RC_SUCCESS = 0,
+ FFS_RC_FINISHED_WITH_ERRORS,
+ FFS_RC_ABORTED,
+ FFS_RC_EXCEPTION,
+};
+}
+
+
+#endif // RETURN_CODES_H_INCLUDED
diff --git a/lib/shadow.cpp b/lib/shadow.cpp
index f4d7f3af..ba4e1f5e 100644
--- a/lib/shadow.cpp
+++ b/lib/shadow.cpp
@@ -27,7 +27,7 @@ bool runningWOW64() //test if process is running under WOW64 (reference http://m
{
BOOL isWow64 = FALSE;
if (isWow64Process(::GetCurrentProcess(), &isWow64))
- return isWow64 == TRUE;
+ return isWow64 != FALSE;
}
return false;
diff --git a/lib/status_handler.h b/lib/status_handler.h
index 7b7cb3d7..ca7af298 100644
--- a/lib/status_handler.h
+++ b/lib/status_handler.h
@@ -8,6 +8,7 @@
#define STATUSHANDLER_H_INCLUDED
#include "../process_callback.h"
+#include <vector>
#include <string>
#include <zen/int64.h>
#include <zen/i18n.h>
diff --git a/lib/xml_base.cpp b/lib/xml_base.cpp
index 3f6cc0be..8f8ee74d 100644
--- a/lib/xml_base.cpp
+++ b/lib/xml_base.cpp
@@ -44,9 +44,6 @@ void xmlAccess::loadXmlDocument(const Zstring& filename, XmlDoc& doc) //throw Ff
}
catch (const FileError& error)
{
- if (!fileExists(filename))
- throw FfsXmlError(replaceCpy(_("Cannot find file %x."), L"%x", fmtFileName(filename)));
-
throw FfsXmlError(error.toString());
}
bgstack15