summaryrefslogtreecommitdiff
path: root/zen
diff options
context:
space:
mode:
authorB. Stack <bgstack15@gmail.com>2021-05-10 08:05:45 -0400
committerB. Stack <bgstack15@gmail.com>2021-05-10 08:05:45 -0400
commit0d0f8635218a2893fcd00385019089253474f634 (patch)
tree9261c60b81eb28e068f0f2f44fd8e60214462b2a /zen
parentMerge branch '11.9' into 'master' (diff)
downloadFreeFileSync-0d0f8635218a2893fcd00385019089253474f634.tar.gz
FreeFileSync-0d0f8635218a2893fcd00385019089253474f634.tar.bz2
FreeFileSync-0d0f8635218a2893fcd00385019089253474f634.zip
add upstream 11.10
Diffstat (limited to 'zen')
-rw-r--r--zen/globals.h10
-rw-r--r--zen/legacy_compiler.cpp22
-rw-r--r--zen/stl_tools.h22
-rw-r--r--zen/sys_info.cpp43
-rw-r--r--zen/sys_info.h2
-rw-r--r--zen/time.h112
6 files changed, 168 insertions, 43 deletions
diff --git a/zen/globals.h b/zen/globals.h
index 47da2ac4..6a50a497 100644
--- a/zen/globals.h
+++ b/zen/globals.h
@@ -211,10 +211,6 @@ void registerGlobalForDestruction(CleanUpEntry& entry)
}
//------------------------------------------------------------------------------------------
- #ifdef __cpp_lib_atomic_wait
- #error implement + rewiew improvements
- #endif
-
inline
bool PodSpinMutex::tryLock()
@@ -227,11 +223,7 @@ inline
void PodSpinMutex::lock()
{
while (!tryLock())
-#ifdef __cpp_lib_atomic_wait
flag_.wait(true, std::memory_order_relaxed);
-#else
- ;
-#endif
}
@@ -239,9 +231,7 @@ inline
void PodSpinMutex::unlock()
{
flag_.clear(std::memory_order_release);
-#ifdef __cpp_lib_atomic_wait
flag_.notify_one();
-#endif
}
diff --git a/zen/legacy_compiler.cpp b/zen/legacy_compiler.cpp
index 81efb4dd..6c5489d5 100644
--- a/zen/legacy_compiler.cpp
+++ b/zen/legacy_compiler.cpp
@@ -5,22 +5,24 @@
// *****************************************************************************
#include "legacy_compiler.h"
-#ifdef __cpp_lib_to_chars
- #error get rid of workarounds
-#endif
+#include <charconv>
+/* 1. including <charconv> in header file blows up VC++:
+ - string_tools.h: "An internal error has occurred in the compiler. (compiler file 'd:\agent\_work\1\s\src\vctools\Compiler\Utc\src\p2\p2symtab.c', line 2618)"
+ - PCH: "fatal error C1076: compiler limit: internal heap limit reached"
+ => include in separate compilation unit
+ 2. Disable "C/C++ -> Code Generation -> Smaller Type Check" (and PCH usage!), at least for this compilation unit: https://github.com/microsoft/STL/pull/171 */
double zen::fromChars(const char* first, const char* last)
{
- return std::strtod(std::string(first, last).c_str(), nullptr);
+ double num = 0;
+ [[maybe_unused]] const std::from_chars_result rv = std::from_chars(first, last, num);
+ return num;
}
const char* zen::toChars(char* first, char* last, double num)
{
- const size_t bufSize = last - first;
- const int charsWritten = std::snprintf(first, bufSize, "%g", num);
- //C99: returns number of chars written if successful, < 0 or >= bufferSize on failure
-
- return 0 <= charsWritten && charsWritten < static_cast<int>(bufSize) ?
- first + charsWritten : first;
+ const std::to_chars_result rv = std::to_chars(first, last, num);
+ return rv.ec == std::errc{} ? rv.ptr : first;
}
+
diff --git a/zen/stl_tools.h b/zen/stl_tools.h
index 53b95241..a1c5b7b1 100644
--- a/zen/stl_tools.h
+++ b/zen/stl_tools.h
@@ -36,6 +36,12 @@ void removeDuplicates(std::vector<T, Alloc>& v);
template <class T, class Alloc, class CompLess>
void removeDuplicates(std::vector<T, Alloc>& v, CompLess less);
+template <class T, class Alloc, class CompLess>
+void removeDuplicatesStable(std::vector<T, Alloc>& v, CompLess less);
+
+template <class T, class Alloc>
+void removeDuplicatesStable(std::vector<T, Alloc>& v);
+
//searching STL containers
template <class BidirectionalIterator, class T>
BidirectionalIterator findLast(BidirectionalIterator first, BidirectionalIterator last, const T& value);
@@ -132,6 +138,22 @@ void removeDuplicates(std::vector<T, Alloc>& v)
}
+template <class T, class Alloc, class CompLess> inline
+void removeDuplicatesStable(std::vector<T, Alloc>& v, CompLess less)
+{
+ std::set<T, CompLess> usedItems(less);
+ v.erase(std::remove_if(v.begin(), v.end(),
+ [&usedItems](const T& e) { return !usedItems.insert(e).second; }), v.end());
+}
+
+
+template <class T, class Alloc> inline
+void removeDuplicatesStable(std::vector<T, Alloc>& v)
+{
+ removeDuplicatesStable(v, std::less());
+}
+
+
template <class Iterator, class T, class CompLess> inline
Iterator binarySearch(Iterator first, Iterator last, const T& value, CompLess less)
{
diff --git a/zen/sys_info.cpp b/zen/sys_info.cpp
index 6eeab276..edb8dd9d 100644
--- a/zen/sys_info.cpp
+++ b/zen/sys_info.cpp
@@ -24,7 +24,7 @@
using namespace zen;
-Zstring zen::getUserName() //throw FileError
+Zstring zen::getLoginUser() //throw FileError
{
const uid_t userIdNo = ::getuid(); //never fails
@@ -66,7 +66,8 @@ Zstring zen::getUserName() //throw FileError
if (const char* userName = tryGetNonRootUser("SUDO_USER")) return userName;
if (const char* userName = tryGetNonRootUser("LOGNAME")) return userName;
- throw FileError(_("Cannot get process information."), L"Failed to determine non-root user name"); //should not happen?
+ //apparently the current user really IS root: https://freefilesync.org/forum/viewtopic.php?t=8405
+ return "root";
}
@@ -152,6 +153,19 @@ Zstring zen::getRealProcessPath() //throw FileError
}
+namespace
+{
+Zstring getUserDir() //throw FileError
+{
+ const Zstring loginUser = getLoginUser(); //throw FileError
+ if (loginUser == "root")
+ return "/root";
+ else
+ return "/home/" + loginUser;
+}
+}
+
+
Zstring zen::getUserDataPath() //throw FileError
{
if (::getuid() != 0) //nofail; root(0) => consider as request for elevation, NOT impersonation
@@ -159,7 +173,7 @@ Zstring zen::getUserDataPath() //throw FileError
xdgCfgPath && xdgCfgPath[0] != 0)
return xdgCfgPath;
- return "/home/" + getUserName() + "/.config"; //throw FileError
+ return getUserDir() + "/.config"; //throw FileError
}
@@ -167,18 +181,17 @@ Zstring zen::getUserDownloadsPath() //throw FileError
{
try
{
- const Zstring cmdLine = ::getuid() == 0 ? //nofail; root(0) => consider as request for elevation, NOT impersonation
- //sudo better be installed :>
- "sudo -u " + getUserName() + " xdg-user-dir DOWNLOAD" : //throw FileError
- "xdg-user-dir DOWNLOAD";
-
- const auto& [exitCode, output] = consoleExecute(cmdLine, std::nullopt /*timeoutMs*/); //throw SysError
- if (exitCode != 0) //fallback: probably correct 99.9% of the time anyway...
- return "/home/" + getUserName() + "/Downloads"; //throw FileError
-
- const Zstring& downloadsPath = trimCpy(output);
- ASSERT_SYSERROR(!downloadsPath.empty());
- return downloadsPath;
+ if (::getuid() != 0) //nofail; root(0) => consider as request for elevation, NOT impersonation
+ if (const auto& [exitCode, output] = consoleExecute("xdg-user-dir DOWNLOAD", std::nullopt /*timeoutMs*/); //throw SysError
+ exitCode == 0)
+ {
+ const Zstring& downloadsPath = trimCpy(output);
+ ASSERT_SYSERROR(!downloadsPath.empty());
+ return downloadsPath;
+ }
+
+ //fallback: probably correct 99.9% of the time anyway...
+ return getUserDir() + "/Downloads"; //throw FileError
}
catch (const SysError& e) { throw FileError(_("Cannot get process information."), e.toString()); }
}
diff --git a/zen/sys_info.h b/zen/sys_info.h
index 54dc1aca..0126ad2f 100644
--- a/zen/sys_info.h
+++ b/zen/sys_info.h
@@ -14,7 +14,7 @@ namespace zen
{
//COM needs to be initialized before calling any of these functions! CoInitializeEx/CoUninitialize
-Zstring getUserName(); //throw FileError
+Zstring getLoginUser(); //throw FileError
struct ComputerModel
{
diff --git a/zen/time.h b/zen/time.h
index e038eca3..b3b903b6 100644
--- a/zen/time.h
+++ b/zen/time.h
@@ -152,20 +152,116 @@ TimeComp getLocalTime(time_t utc)
constexpr auto fileTimeTimetOffset = 11'644'473'600;
-warn_static("remove after test")
#if 0
+warn_static("remove after test")
inline
TimeComp getUtcTime2(time_t utc)
{
- utc += year100UnixOffset; //first century not divisible by 400
+ //1. convert: seconds since year 1:
+ //...
+
+ //TODO: what if < 0?
+ long long remDays = utc / (24 * 3600);
+ long long remSecs = utc % (24 * 3600);
+
+ const int daysPer4Years = 4 * 365 /*usual days per year*/ + 1 /*including leap day*/;
+ const int daysPerYear = 365; //non-leap
+ const int daysPer100Years = 25 * daysPer4Years - 1;
+ const int daysPer400Years = 100 * daysPer4Years - 3 /*no leap days for centuries, except if divisible by 400 */;
+
+ const lldiv_t cycles400 = std::lldiv(remDays, daysPer400Years);
+ remDays = cycles400.rem;
+
+
+ int cycles100 = (remDays / daysPer100Years);
+ if (cycles100 == 4)
+ --cycles100;
+
+ remDays -= cycles100 * daysPer100Years;
+
+
+ int cycles4 = (remDays / daysPer4Years);
+ if (cycles4 == 25)
+ --cycles4;
+
+ remDays -= cycles4 * daysPer4Years;
+
+
+ int cycles1 = remDays / daysPerYear;
+ if (cycles1 == 4)
+ --cycles1;
- long long remSecs = year100UnixOffset % (24 * 3600);
- long long remDays = year100UnixOffset / (24 * 3600);
+ remDays -= cycles1 * daysPerYears;
+
+ const int year = 1 + cycles400.quot * 400 + cycles100 * 100; + cycles4 * 4 + cycles1;;
+
+
+
+
+
+ //first four years of century:
+ if (skipCenturyLeapDay)
+ {
+ if (remDays < 4 * daysPerYear)
+ {
+ year += remDays / daysPerYear;
+ remDays %= daysPerYear;
+ }
+ else
+ {
+ remDays -= 4 * daysPerYear;
+ year += 4;
+ => go to if block;
+ }
+ }
+ else
+ {
+ year += (remDays / daysPer4Years) * 4;
+ remDays %= daysPer4Years;
+
+ if (remDays < daysPerYear + 1 /*including leap day*/)
+ isLeapYear = true;
+ else
+ {
+ remDays -= daysPerYear + 1;
+ ++year;
+
+ year += remDays / daysPerYear;
+ remDays %= daysPerYear;
+ }
+ }
+
+
+
+
+
+
+
+
+ const int daysPer100Years = 25 * (4 * 365 /*usual days per year*/ + 1)/*leap days */;
+
+
+ const int daysPer100Years = 100 * 365 /*usual days per year*/ + 25 /*leap days */;
+ const int daysPer200Years = 200 * 365 /*usual days per year*/ + 50 /*leap days */ - 1 /*no leap days for centuries, except if divisible by 400 */;
+ const int daysPer300Years = 300 * 365 /*usual days per year*/ + 75 /*leap days */ - 2 /*no leap days for centuries, except if divisible by 400 */;
+
+ if (remDays >= daysPer300Years)
+ {
+ year += 300;
+ remDays -= daysPer300Years;
+ }
+ else if (remDays >= daysPer200Years)
+ {
+ year += 200;
+ remDays -= daysPer200Years;
+ }
+ else if (remDays >= daysPer100Years)
+ {
+ year += 100;
+ remDays -= daysPer100Years;
+ }
- constexpr int daysPer400Years = 400 * 365 /*usual days per year*/ + 100 /*leap days */ - 3 /*no leap days for centuries not divisible by 400 */;
- int year = 100 + (remDays / daysPer400Years) * 400;
- remDays %= 400;
constexpr int daysPer100Years = 100 * 365 /*usual days per year*/ + 25 /*leap days */ - 1 /*no leap days for centuries not divisible by 400 */;
@@ -188,6 +284,8 @@ TimeComp getUtcTime2(time_t utc)
}
+
+warn_static("get rid of fileTimeTimetOffset!")
#endif
bgstack15