summaryrefslogtreecommitdiffstats
path: root/contrib/libs/flatbuffers/src/util.cpp
diff options
context:
space:
mode:
authorreshilkin <[email protected]>2023-08-11 12:01:29 +0300
committerreshilkin <[email protected]>2023-08-11 13:00:03 +0300
commit5894c3ce50a49a9f9bc1c0316e2ef0708e3a7ef8 (patch)
tree624e56690fe689e569d05612fa0e92f2c5bdb75b /contrib/libs/flatbuffers/src/util.cpp
parent1eb895279c52b0d2505a31b79ad326b56d0b2681 (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.cpp243
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