diff options
author | reshilkin <[email protected]> | 2023-08-11 12:01:29 +0300 |
---|---|---|
committer | reshilkin <[email protected]> | 2023-08-11 13:00:03 +0300 |
commit | 5894c3ce50a49a9f9bc1c0316e2ef0708e3a7ef8 (patch) | |
tree | 624e56690fe689e569d05612fa0e92f2c5bdb75b /contrib/libs/flatbuffers/src/util.cpp | |
parent | 1eb895279c52b0d2505a31b79ad326b56d0b2681 (diff) |
Update contrib/libs/flatbuffers to 23.5.9
Diffstat (limited to 'contrib/libs/flatbuffers/src/util.cpp')
-rw-r--r-- | contrib/libs/flatbuffers/src/util.cpp | 243 |
1 files changed, 212 insertions, 31 deletions
diff --git a/contrib/libs/flatbuffers/src/util.cpp b/contrib/libs/flatbuffers/src/util.cpp index 3670a019395..38d8536c090 100644 --- a/contrib/libs/flatbuffers/src/util.cpp +++ b/contrib/libs/flatbuffers/src/util.cpp @@ -17,13 +17,14 @@ // clang-format off // Dont't remove `format off`, it prevent reordering of win-includes. +#include <cstring> #if defined(__MINGW32__) || defined(__MINGW64__) || defined(__CYGWIN__) || \ defined(__QNXNTO__) # define _POSIX_C_SOURCE 200809L # define _XOPEN_SOURCE 700L #endif -#ifdef _WIN32 +#if defined(_WIN32) || defined(__MINGW32__) || defined(__MINGW64__) || defined(__CYGWIN__) # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif @@ -34,28 +35,35 @@ # include <crtdbg.h> # endif # include <windows.h> // Must be included before <direct.h> -# include <direct.h> +# ifndef __CYGWIN__ +# include <direct.h> +# endif # include <winbase.h> # undef interface // This is also important because of reasons #endif // clang-format on -#include "flatbuffers/base.h" #include "flatbuffers/util.h" #include <sys/stat.h> + #include <clocale> #include <cstdlib> #include <fstream> +#include <functional> + +#include "flatbuffers/base.h" namespace flatbuffers { -bool FileExistsRaw(const char *name) { +namespace { + +static bool FileExistsRaw(const char *name) { std::ifstream ifs(name); return ifs.good(); } -bool LoadFileRaw(const char *name, bool binary, std::string *buf) { +static bool LoadFileRaw(const char *name, bool binary, std::string *buf) { if (DirExists(name)) return false; std::ifstream ifs(name, binary ? std::ifstream::binary : std::ifstream::in); if (!ifs.is_open()) return false; @@ -75,8 +83,131 @@ bool LoadFileRaw(const char *name, bool binary, std::string *buf) { return !ifs.bad(); } -static LoadFileFunction g_load_file_function = LoadFileRaw; -static FileExistsFunction g_file_exists_function = FileExistsRaw; +LoadFileFunction g_load_file_function = LoadFileRaw; +FileExistsFunction g_file_exists_function = FileExistsRaw; + +static std::string ToCamelCase(const std::string &input, bool is_upper) { + std::string s; + for (size_t i = 0; i < input.length(); i++) { + if (!i && input[i] == '_') { + s += input[i]; + // we ignore leading underscore but make following + // alphabet char upper. + if (i + 1 < input.length() && is_alpha(input[i + 1])) + s += CharToUpper(input[++i]); + } + else if (!i) + s += is_upper ? CharToUpper(input[i]) : CharToLower(input[i]); + else if (input[i] == '_' && i + 1 < input.length()) + s += CharToUpper(input[++i]); + else + s += input[i]; + } + return s; +} + +static std::string ToSnakeCase(const std::string &input, bool screaming) { + std::string s; + for (size_t i = 0; i < input.length(); i++) { + if (i == 0) { + s += screaming ? CharToUpper(input[i]) : CharToLower(input[i]); + } else if (input[i] == '_') { + s += '_'; + } else if (!islower(input[i])) { + // Prevent duplicate underscores for Upper_Snake_Case strings + // and UPPERCASE strings. + if (islower(input[i - 1]) || (isdigit(input[i-1]) && !isdigit(input[i]))) { s += '_'; } + s += screaming ? CharToUpper(input[i]) : CharToLower(input[i]); + } else { + s += screaming ? CharToUpper(input[i]) : input[i]; + } + } + return s; +} + +std::string ToAll(const std::string &input, + std::function<char(const char)> transform) { + std::string s; + for (size_t i = 0; i < input.length(); i++) { s += transform(input[i]); } + return s; +} + +std::string CamelToSnake(const std::string &input) { + std::string s; + for (size_t i = 0; i < input.length(); i++) { + if (i == 0) { + s += CharToLower(input[i]); + } else if (input[i] == '_') { + s += '_'; + } else if (!islower(input[i])) { + // Prevent duplicate underscores for Upper_Snake_Case strings + // and UPPERCASE strings. + if (islower(input[i - 1]) || (isdigit(input[i-1]) && !isdigit(input[i]))) { s += '_'; } + s += CharToLower(input[i]); + } else { + s += input[i]; + } + } + return s; +} + +std::string DasherToSnake(const std::string &input) { + std::string s; + for (size_t i = 0; i < input.length(); i++) { + if (input[i] == '-') { + s += "_"; + } else { + s += input[i]; + } + } + return s; +} + +std::string ToDasher(const std::string &input) { + std::string s; + char p = 0; + for (size_t i = 0; i < input.length(); i++) { + char const &c = input[i]; + if (c == '_') { + if (i > 0 && p != kPathSeparator && + // The following is a special case to ignore digits after a _. This is + // because ThisExample3 would be converted to this_example_3 in the + // CamelToSnake conversion, and then dasher would do this-example-3, + // but it expects this-example3. + !(i + 1 < input.length() && isdigit(input[i + 1]))) + s += "-"; + } else { + s += c; + } + p = c; + } + return s; +} + + +// Converts foo_bar_123baz_456 to foo_bar123_baz456 +std::string SnakeToSnake2(const std::string &s) { + if (s.length() <= 1) return s; + std::string result; + result.reserve(s.size()); + for (size_t i = 0; i < s.length() - 1; i++) { + if (s[i] == '_' && isdigit(s[i + 1])) { + continue; // Move the `_` until after the digits. + } + + result.push_back(s[i]); + + if (isdigit(s[i]) && isalpha(s[i + 1]) && islower(s[i + 1])) { + result.push_back('_'); + } + } + result.push_back(s.back()); + + return result; +} + +} // namespace + bool LoadFile(const char *name, bool binary, std::string *buf) { FLATBUFFERS_ASSERT(g_load_file_function); @@ -152,11 +283,20 @@ std::string StripFileName(const std::string &filepath) { return i != std::string::npos ? filepath.substr(0, i) : ""; } +std::string StripPrefix(const std::string &filepath, + const std::string &prefix_to_remove) { + if (!strncmp(filepath.c_str(), prefix_to_remove.c_str(), + prefix_to_remove.size())) { + return filepath.substr(prefix_to_remove.size()); + } + return filepath; +} + std::string ConCatPathFileName(const std::string &path, const std::string &filename) { std::string filepath = path; if (filepath.length()) { - char &filepath_last_character = string_back(filepath); + char &filepath_last_character = filepath.back(); if (filepath_last_character == kPathSeparatorWindows) { filepath_last_character = kPathSeparator; } else if (filepath_last_character != kPathSeparator) { @@ -176,6 +316,9 @@ std::string PosixPath(const char *path) { std::replace(p.begin(), p.end(), '\\', '/'); return p; } +std::string PosixPath(const std::string &path) { + return PosixPath(path.c_str()); +} void EnsureDirExists(const std::string &filepath) { auto parent = StripFileName(filepath); @@ -196,7 +339,7 @@ std::string AbsolutePath(const std::string &filepath) { #ifdef FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION return filepath; #else - #ifdef _WIN32 + #if defined(_WIN32) || defined(__MINGW32__) || defined(__MINGW64__) || defined(__CYGWIN__) char abs_path[MAX_PATH]; return GetFullPathNameA(filepath.c_str(), MAX_PATH, abs_path, nullptr) #else @@ -215,6 +358,36 @@ std::string AbsolutePath(const std::string &filepath) { // clang-format on } +std::string RelativeToRootPath(const std::string &project, + const std::string &filepath) { + std::string absolute_project = PosixPath(AbsolutePath(project)); + if (absolute_project.back() != '/') absolute_project += "/"; + std::string absolute_filepath = PosixPath(AbsolutePath(filepath)); + + // Find the first character where they disagree. + // The previous directory is the lowest common ancestor; + const char *a = absolute_project.c_str(); + const char *b = absolute_filepath.c_str(); + size_t common_prefix_len = 0; + while (*a != '\0' && *b != '\0' && *a == *b) { + if (*a == '/') common_prefix_len = a - absolute_project.c_str(); + a++; + b++; + } + // the number of ../ to prepend to b depends on the number of remaining + // directories in A. + const char *suffix = absolute_project.c_str() + common_prefix_len; + size_t num_up = 0; + while (*suffix != '\0') + if (*suffix++ == '/') num_up++; + num_up--; // last one is known to be '/'. + std::string result = "//"; + for (size_t i = 0; i < num_up; i++) result += "../"; + result += absolute_filepath.substr(common_prefix_len + 1); + + return result; +} + // Locale-independent code. #if defined(FLATBUFFERS_LOCALE_INDEPENDENT) && \ (FLATBUFFERS_LOCALE_INDEPENDENT > 0) @@ -238,8 +411,7 @@ ClassicLocale ClassicLocale::instance_; std::string RemoveStringQuotes(const std::string &s) { auto ch = *s.c_str(); - return ((s.size() >= 2) && (ch == '\"' || ch == '\'') && - (ch == string_back(s))) + return ((s.size() >= 2) && (ch == '\"' || ch == '\'') && (ch == s.back())) ? s.substr(1, s.length() - 2) : s; } @@ -261,27 +433,36 @@ bool ReadEnvironmentVariable(const char *var_name, std::string *_value) { return true; } -void SetupDefaultCRTReportMode() { - // clang-format off - - #ifdef _MSC_VER - // By default, send all reports to STDOUT to prevent CI hangs. - // Enable assert report box [Abort|Retry|Ignore] if a debugger is present. - const int dbg_mode = (_CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG) | - (IsDebuggerPresent() ? _CRTDBG_MODE_WNDW : 0); - (void)dbg_mode; // release mode fix - // CrtDebug reports to _CRT_WARN channel. - _CrtSetReportMode(_CRT_WARN, dbg_mode); - _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); - // The assert from <assert.h> reports to _CRT_ERROR channel - _CrtSetReportMode(_CRT_ERROR, dbg_mode); - _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT); - // Internal CRT assert channel? - _CrtSetReportMode(_CRT_ASSERT, dbg_mode); - _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); - #endif +std::string ConvertCase(const std::string &input, Case output_case, + Case input_case) { + if (output_case == Case::kKeep) return input; + // The output cases expect snake_case inputs, so if we don't have that input + // format, try to convert to snake_case. + switch (input_case) { + case Case::kLowerCamel: + case Case::kUpperCamel: + return ConvertCase(CamelToSnake(input), output_case); + case Case::kDasher: return ConvertCase(DasherToSnake(input), output_case); + case Case::kKeep: printf("WARNING: Converting from kKeep case.\n"); break; + default: + case Case::kSnake: + case Case::kScreamingSnake: + case Case::kAllLower: + case Case::kAllUpper: break; + } - // clang-format on + switch (output_case) { + case Case::kUpperCamel: return ToCamelCase(input, true); + case Case::kLowerCamel: return ToCamelCase(input, false); + case Case::kSnake: return input; + case Case::kScreamingSnake: return ToSnakeCase(input, true); + case Case::kAllUpper: return ToAll(input, CharToUpper); + case Case::kAllLower: return ToAll(input, CharToLower); + case Case::kDasher: return ToDasher(input); + case Case::kSnake2: return SnakeToSnake2(input); + default: + case Case::kUnknown: return input; + } } } // namespace flatbuffers |