From e1ace703fbf4458d9e887ebf30050b1a0482a2d2 Mon Sep 17 00:00:00 2001 From: Gil Date: Wed, 11 Jul 2018 15:27:50 -0700 Subject: Fix Firestore source errors under VS2017 (#1515) * Project file updates from sync_project.rb * Fix misc compile errors under VS2017 * Fix util/hashing under VS2017 std::hash is not just a pass through in Microsoft's STL. * Disable unsafe code warnings in VS2017 ... where comparing against a reference implementation that has no easy safe equivalent. * Handle drive letters in paths on Windows --- .../firestore/immutable/sorted_map_iterator.h | 4 +- Firestore/core/src/firebase/firestore/util/bits.h | 14 +++---- .../core/src/firebase/firestore/util/hard_assert.h | 34 +++++++++------- .../core/src/firebase/firestore/util/hashing.h | 9 +++-- Firestore/core/src/firebase/firestore/util/path.cc | 47 +++++++++++++++++----- .../core/src/firebase/firestore/util/status.cc | 44 +++++++++++++------- 6 files changed, 103 insertions(+), 49 deletions(-) (limited to 'Firestore/core/src/firebase') diff --git a/Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h b/Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h index 960e3f6..20c11a7 100644 --- a/Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h +++ b/Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h @@ -119,7 +119,9 @@ class SortedMapIterator { pointer get() const { switch (tag_) { case Tag::Array: - return array_iter_; + // std::array::iterator is not guaranteed to be a bare pointer but will + // be a RandomAccessIterator which does have operator*(). + return &*array_iter_; case Tag::Tree: return tree_iter_.get(); } diff --git a/Firestore/core/src/firebase/firestore/util/bits.h b/Firestore/core/src/firebase/firestore/util/bits.h index 94a018f..591c306 100644 --- a/Firestore/core/src/firebase/firestore/util/bits.h +++ b/Firestore/core/src/firebase/firestore/util/bits.h @@ -24,13 +24,13 @@ #include -class Bits_Port32_Test; -class Bits_Port64_Test; - namespace firebase { namespace firestore { namespace util { +class Bits_Port32_Test; +class Bits_Port64_Test; + class Bits { public: /** Return floor(log2(n)) for positive integer n. Returns -1 iff n == 0. */ @@ -81,9 +81,9 @@ inline int Bits::Log2FloorNonZero64(uint64_t n) { return 63 ^ __builtin_clzll(n); } -#elif defined(COMPILER_MSVC) +#elif defined(_MSC_VER) -inline int Bits::Log2FloorNonZero(uint32 n) { +inline int Bits::Log2FloorNonZero(uint32_t n) { #ifdef _M_IX86 _asm { bsr ebx, n @@ -95,7 +95,7 @@ inline int Bits::Log2FloorNonZero(uint32 n) { #endif } -inline int Bits::Log2Floor(uint32 n) { +inline int Bits::Log2Floor(uint32_t n) { #ifdef _M_IX86 _asm { xor ebx, ebx @@ -120,7 +120,7 @@ inline int Bits::Log2FloorNonZero64(uint64_t n) { return Bits::Log2FloorNonZero64_Portable(n); } -#else // !__GNUC__ && !COMPILER_MSVC +#else // !__GNUC__ && !_MSC_VER inline int Bits::Log2Floor64(uint64_t n) { return Bits::Log2Floor64_Portable(n); diff --git a/Firestore/core/src/firebase/firestore/util/hard_assert.h b/Firestore/core/src/firebase/firestore/util/hard_assert.h index e60d71a..7b66f33 100644 --- a/Firestore/core/src/firebase/firestore/util/hard_assert.h +++ b/Firestore/core/src/firebase/firestore/util/hard_assert.h @@ -21,6 +21,12 @@ #include "Firestore/core/src/firebase/firestore/util/string_format.h" +#if defined(_MSC_VER) +#define FIRESTORE_FUNCTION_NAME __FUNCSIG__ +#else +#define FIRESTORE_FUNCTION_NAME __PRETTY_FUNCTION__ +#endif + /** * Fails the current function if the given condition is false. * @@ -30,14 +36,14 @@ * @param format (optional) A format string suitable for util::StringFormat. * @param ... format arguments to pass to util::StringFormat. */ -#define HARD_ASSERT(condition, ...) \ - do { \ - if (!(condition)) { \ - std::string _message = \ - firebase::firestore::util::StringFormat(__VA_ARGS__); \ - firebase::firestore::util::internal::Fail( \ - __FILE__, __PRETTY_FUNCTION__, __LINE__, _message, #condition); \ - } \ +#define HARD_ASSERT(condition, ...) \ + do { \ + if (!(condition)) { \ + std::string _message = \ + firebase::firestore::util::StringFormat(__VA_ARGS__); \ + firebase::firestore::util::internal::Fail( \ + __FILE__, FIRESTORE_FUNCTION_NAME, __LINE__, _message, #condition); \ + } \ } while (0) /** @@ -48,12 +54,12 @@ * @param format A format string suitable for util::StringFormat. * @param ... format arguments to pass to util::StringFormat. */ -#define HARD_FAIL(...) \ - do { \ - std::string _failure = \ - firebase::firestore::util::StringFormat(__VA_ARGS__); \ - firebase::firestore::util::internal::Fail(__FILE__, __PRETTY_FUNCTION__, \ - __LINE__, _failure); \ +#define HARD_FAIL(...) \ + do { \ + std::string _failure = \ + firebase::firestore::util::StringFormat(__VA_ARGS__); \ + firebase::firestore::util::internal::Fail( \ + __FILE__, FIRESTORE_FUNCTION_NAME, __LINE__, _failure); \ } while (0) /** diff --git a/Firestore/core/src/firebase/firestore/util/hashing.h b/Firestore/core/src/firebase/firestore/util/hashing.h index 21c0bd6..5219d64 100644 --- a/Firestore/core/src/firebase/firestore/util/hashing.h +++ b/Firestore/core/src/firebase/firestore/util/hashing.h @@ -82,7 +82,8 @@ struct has_std_hash { * `decltype(std::hash{}(std::declval()))`. */ template -using std_hash_type = typename std::enable_if{}, size_t>::type; +using std_hash_type = + typename std::enable_if::value, size_t>::type; /** * Combines a hash_value with whatever accumulated state there is so far. @@ -151,9 +152,11 @@ auto RankedInvokeHash(const Range& range, HashChoice<2>) size_t size = 0; for (auto&& element : range) { ++size; - result = Combine(result, InvokeHash(element)); + size_t piece = InvokeHash(element); + result = Combine(result, piece); } - result = Combine(result, size); + size_t size_hash = InvokeHash(size); + result = Combine(result, size_hash); return result; } diff --git a/Firestore/core/src/firebase/firestore/util/path.cc b/Firestore/core/src/firebase/firestore/util/path.cc index 940f12a..0da3b23 100644 --- a/Firestore/core/src/firebase/firestore/util/path.cc +++ b/Firestore/core/src/firebase/firestore/util/path.cc @@ -16,14 +16,45 @@ #include "Firestore/core/src/firebase/firestore/util/path.h" +#include "absl/strings/ascii.h" +#include "absl/strings/string_view.h" + namespace firebase { namespace firestore { namespace util { +namespace { + +static constexpr absl::string_view::size_type npos = absl::string_view::npos; + +/** Returns the given path with its leading drive letter removed. */ +inline absl::string_view StripDriveLetter(absl::string_view path) { +#if defined(_WIN32) + if (path.size() >= 2 && path[1] == ':' && absl::ascii_isalpha(path[0])) { + return path.substr(2); + } + return path; + +#else + return path; +#endif // defined(_WIN32) +} + +/** Returns true if the given character is a pathname separator. */ +inline bool IsSeparator(char c) { +#if defined(_WIN32) + return c == '/' || c == '\\'; +#else + return c == '/'; +#endif // defined(_WIN32) +} + +} // namespace + absl::string_view Path::Basename(absl::string_view pathname) { size_t slash = pathname.find_last_of('/'); - if (slash == absl::string_view::npos) { + if (slash == npos) { // No path separator found => the whole string. return pathname; } @@ -35,7 +66,7 @@ absl::string_view Path::Basename(absl::string_view pathname) { absl::string_view Path::Dirname(absl::string_view pathname) { size_t last_slash = pathname.find_last_of('/'); - if (last_slash == absl::string_view::npos) { + if (last_slash == npos) { // No path separator found => empty string. Conformance with POSIX would // have us return "." here. return pathname.substr(0, 0); @@ -43,7 +74,7 @@ absl::string_view Path::Dirname(absl::string_view pathname) { // Collapse runs of slashes. size_t nonslash = pathname.find_last_not_of('/', last_slash); - if (nonslash == absl::string_view::npos) { + if (nonslash == npos) { // All characters preceding the last path separator are slashes return pathname.substr(0, 1); } @@ -55,12 +86,8 @@ absl::string_view Path::Dirname(absl::string_view pathname) { } bool Path::IsAbsolute(absl::string_view path) { -#if defined(_WIN32) -#error "Handle drive letters" - -#else - return !path.empty() && path.front() == '/'; -#endif + path = StripDriveLetter(path); + return !path.empty() && IsSeparator(path.front()); } void Path::JoinAppend(std::string* base, absl::string_view path) { @@ -69,7 +96,7 @@ void Path::JoinAppend(std::string* base, absl::string_view path) { } else { size_t nonslash = base->find_last_not_of('/'); - if (nonslash != std::string::npos) { + if (nonslash != npos) { base->resize(nonslash + 1); base->push_back('/'); } diff --git a/Firestore/core/src/firebase/firestore/util/status.cc b/Firestore/core/src/firebase/firestore/util/status.cc index 3e8585a..beaa88a 100644 --- a/Firestore/core/src/firebase/firestore/util/status.cc +++ b/Firestore/core/src/firebase/firestore/util/status.cc @@ -100,18 +100,24 @@ static FirestoreErrorCode CodeForErrno(int errno_code) { #if defined(EISNAM) case EISNAM: // Is a named type file #endif - case ENOTBLK: // Block device required - case ENOTCONN: // The socket is not connected - case EPIPE: // Broken pipe +#if defined(ENOTBLK) + case ENOTBLK: // Block device required +#endif + case ENOTCONN: // The socket is not connected + case EPIPE: // Broken pipe +#if defined(ESHUTDOWN) case ESHUTDOWN: // Cannot send after transport endpoint shutdown - case ETXTBSY: // Text file busy +#endif + case ETXTBSY: // Text file busy #if defined(EUNATCH) case EUNATCH: // Protocol driver not attached #endif return FirestoreErrorCode::FailedPrecondition; - case ENOSPC: // No space left on device - case EDQUOT: // Disk quota exceeded + case ENOSPC: // No space left on device +#if defined(EDQUOT) + case EDQUOT: // Disk quota exceeded +#endif case EMFILE: // Too many open files case EMLINK: // Too many links case ENFILE: // Too many open files in system @@ -119,7 +125,9 @@ static FirestoreErrorCode CodeForErrno(int errno_code) { case ENODATA: // No message is available on the STREAM read queue case ENOMEM: // Not enough space case ENOSR: // No STREAM resources - case EUSERS: // Too many users +#if defined(EUSERS) + case EUSERS: // Too many users +#endif return FirestoreErrorCode::ResourceExhausted; #if defined(ECHRNG) @@ -133,13 +141,17 @@ static FirestoreErrorCode CodeForErrno(int errno_code) { #if defined(ENOPKG) case ENOPKG: // Package not installed #endif - case ENOSYS: // Function not implemented - case ENOTSUP: // Operation not supported - case EAFNOSUPPORT: // Address family not supported - case EPFNOSUPPORT: // Protocol family not supported + case ENOSYS: // Function not implemented + case ENOTSUP: // Operation not supported + case EAFNOSUPPORT: // Address family not supported +#if defined(EPFNOSUPPORT) + case EPFNOSUPPORT: // Protocol family not supported +#endif case EPROTONOSUPPORT: // Protocol not supported +#if defined(ESOCKTNOSUPPORT) case ESOCKTNOSUPPORT: // Socket type not supported - case EXDEV: // Improper link +#endif + case EXDEV: // Improper link return FirestoreErrorCode::Unimplemented; case EAGAIN: // Resource temporarily unavailable @@ -150,7 +162,9 @@ static FirestoreErrorCode CodeForErrno(int errno_code) { case ECONNABORTED: // Connection aborted case ECONNRESET: // Connection reset case EINTR: // Interrupted function call - case EHOSTDOWN: // Host is down +#if defined(EHOSTDOWN) + case EHOSTDOWN: // Host is down +#endif case EHOSTUNREACH: // Host is unreachable case ENETDOWN: // Network is down case ENETRESET: // Connection aborted by network @@ -163,7 +177,9 @@ static FirestoreErrorCode CodeForErrno(int errno_code) { return FirestoreErrorCode::Unavailable; case EDEADLK: // Resource deadlock avoided - case ESTALE: // Stale file handle +#if defined(ESTALE) + case ESTALE: // Stale file handle +#endif return FirestoreErrorCode::Aborted; case ECANCELED: // Operation cancelled -- cgit v1.2.3