|
|
|
//
|
|
|
|
// Copyright 2019 The Abseil Authors.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
#include "absl/flags/parse.h"
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "gmock/gmock.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "absl/base/internal/raw_logging.h"
|
|
|
|
#include "absl/base/internal/scoped_set_env.h"
|
|
|
|
#include "absl/flags/declare.h"
|
|
|
|
#include "absl/flags/flag.h"
|
|
|
|
#include "absl/flags/internal/parse.h"
|
|
|
|
#include "absl/flags/internal/usage.h"
|
|
|
|
#include "absl/flags/reflection.h"
|
|
|
|
#include "absl/strings/str_cat.h"
|
|
|
|
#include "absl/strings/string_view.h"
|
|
|
|
#include "absl/strings/substitute.h"
|
|
|
|
#include "absl/types/span.h"
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
using absl::base_internal::ScopedSetEnv;
|
|
|
|
|
|
|
|
struct UDT {
|
|
|
|
UDT() = default;
|
|
|
|
UDT(const UDT&) = default;
|
Export of internal Abseil changes
--
b1fc72630aaa81c8395c3b22ba267d938fe29a2e by Derek Mauro <dmauro@google.com>:
Fix -Wdeprecated-copy warnings from Clang 13.
Example:
error: definition of implicit copy assignment operator for 'UDT' is deprecated because it has a user-declared copy constructor [-Werror,-Wdeprecated-copy]
PiperOrigin-RevId: 380058303
--
0422744812b1a2010d9eea5b17fbe89f3441b66b by Evan Brown <ezb@google.com>:
Change the "full table!" asserts in raw_hash_set to use `<= capacity` instead of `< capacity`.
If we add support for non-power-of-two-minus-one capacities, this is the correct thing to assert. For example, consider: Group::kWidth = 8, capacity_ = 8, ctrl_ = {kEmpty, 1, 2, 3, 4, 5, 6, 7, kSentinel, kEmpty, 1, 2, 3, 4, 5, 6}. In this case, if we do an unsuccessful lookup with H2 mapping to slot 1, then the first Group will contain {1, 2, 3, 4, 5, 6, 7, kSentinel} so we need to continue to the second Group (at which point seq.index() == 8 == capacity_) to find a kEmpty.
Note: this is a no-op change for now since we never have `capacity % Group::kWidth == 0`.
PiperOrigin-RevId: 380033480
--
40628c34d540356de65fabb16c1439c0ec7a0764 by Abseil Team <absl-team@google.com>:
Drop out-of-date documentation about `absl::FixedArray`'s allocator support
PiperOrigin-RevId: 379811653
--
e7ad047863ae55c9b7aec0753cfc527a4ea614bc by Evan Brown <ezb@google.com>:
Fix a bug in ConvertDeletedToEmptyAndFullToDeleted in which we were copying 1 more cloned control byte than actually exists.
When alignof(slot_type)>1, this wouldn't cause a problem because the extra byte is padding.
Also change loop bounds to not rely on the fact that capacity_+1 is a multiple of Group::kWidth.
PiperOrigin-RevId: 379311830
--
1a3ba500fb2c33205854eb9258cd6e0fb1061bca by Martijn Vels <mvels@google.com>:
Change Ring, EXTERNAL and FLAT tag values to be consecutive values
The purpose of this change is to have FLAT = EXTERNAL + 1. Especially in the ring and btree alternative code, there is a common check if a node is a 'plain' edge (EXTERNAL or FLAT), or 'something else'. This change can make that check a single branch, i.e., instead of 'tag == EXTERNAL || tag >= FLAT', we can simply check for 'tag >= EXTERNAL'. Likewise we have some cases where we check for RING, EXTERNAL or FLAT, so we align RING + 1 with EXTERNAL.
PiperOrigin-RevId: 379291576
--
0c78e65ca4d85244b106c3f8e24cf268e09e72a3 by Benjamin Barenblat <bbaren@google.com>:
Round a double multiplication before casting it to integer
The code
static_cast<int>(x * y)
(for double x and y) performs a double multiplication into a temporary
that, by standard, may have excess precision. The subsequent cast to int
discards the excess precision. However, the cast may examine the excess
precision during conversion, producing surprising results like
static_cast<int>(1.7 * 10) == 16
on certain systems. Correct this case by explicitly rounding 1.7 * 10
before casting it.
PiperOrigin-RevId: 378922064
GitOrigin-RevId: b1fc72630aaa81c8395c3b22ba267d938fe29a2e
Change-Id: Ica708a006921118673e78d5fd2d61fe0fb0894d1
4 years ago
|
|
|
UDT& operator=(const UDT&) = default;
|
|
|
|
UDT(int v) : value(v) {} // NOLINT
|
|
|
|
|
|
|
|
int value;
|
|
|
|
};
|
|
|
|
|
|
|
|
bool AbslParseFlag(absl::string_view in, UDT* udt, std::string* err) {
|
|
|
|
if (in == "A") {
|
|
|
|
udt->value = 1;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (in == "AAA") {
|
|
|
|
udt->value = 10;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
*err = "Use values A, AAA instead";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
std::string AbslUnparseFlag(const UDT& udt) {
|
|
|
|
return udt.value == 1 ? "A" : "AAA";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string GetTestTmpDirEnvVar(const char* const env_var_name) {
|
|
|
|
#ifdef _WIN32
|
|
|
|
char buf[MAX_PATH];
|
|
|
|
auto get_res = GetEnvironmentVariableA(env_var_name, buf, sizeof(buf));
|
|
|
|
if (get_res >= sizeof(buf) || get_res == 0) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::string(buf, get_res);
|
|
|
|
#else
|
|
|
|
const char* val = ::getenv(env_var_name);
|
|
|
|
if (val == nullptr) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
return val;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string& GetTestTempDir() {
|
|
|
|
static std::string* temp_dir_name = []() -> std::string* {
|
|
|
|
std::string* res = new std::string(GetTestTmpDirEnvVar("TEST_TMPDIR"));
|
|
|
|
|
|
|
|
if (res->empty()) {
|
|
|
|
*res = GetTestTmpDirEnvVar("TMPDIR");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (res->empty()) {
|
|
|
|
#ifdef _WIN32
|
|
|
|
char temp_path_buffer[MAX_PATH];
|
|
|
|
|
|
|
|
auto len = GetTempPathA(MAX_PATH, temp_path_buffer);
|
|
|
|
if (len < MAX_PATH && len != 0) {
|
|
|
|
std::string temp_dir_name = temp_path_buffer;
|
|
|
|
if (!absl::EndsWith(temp_dir_name, "\\")) {
|
|
|
|
temp_dir_name.push_back('\\');
|
|
|
|
}
|
|
|
|
absl::StrAppend(&temp_dir_name, "parse_test.", GetCurrentProcessId());
|
|
|
|
if (CreateDirectoryA(temp_dir_name.c_str(), nullptr)) {
|
|
|
|
*res = temp_dir_name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
char temp_dir_template[] = "/tmp/parse_test.XXXXXX";
|
|
|
|
if (auto* unique_name = ::mkdtemp(temp_dir_template)) {
|
|
|
|
*res = unique_name;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if (res->empty()) {
|
|
|
|
ABSL_INTERNAL_LOG(FATAL,
|
|
|
|
"Failed to make temporary directory for data files");
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
*res += "\\";
|
|
|
|
#else
|
|
|
|
*res += "/";
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}();
|
|
|
|
|
|
|
|
return *temp_dir_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct FlagfileData {
|
|
|
|
const absl::string_view file_name;
|
|
|
|
const absl::Span<const char* const> file_lines;
|
|
|
|
};
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
constexpr const char* const ff1_data[] = {
|
|
|
|
"# comment ",
|
|
|
|
" # comment ",
|
|
|
|
"",
|
|
|
|
" ",
|
|
|
|
"--int_flag=-1",
|
|
|
|
" --string_flag=q2w2 ",
|
|
|
|
" ## ",
|
|
|
|
" --double_flag=0.1",
|
|
|
|
"--bool_flag=Y "
|
|
|
|
};
|
|
|
|
|
|
|
|
constexpr const char* const ff2_data[] = {
|
|
|
|
"# Setting legacy flag",
|
|
|
|
"--legacy_int=1111",
|
|
|
|
"--legacy_bool",
|
|
|
|
"--nobool_flag",
|
|
|
|
"--legacy_str=aqsw",
|
|
|
|
"--int_flag=100",
|
|
|
|
" ## ============="
|
|
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
// Builds flagfile flag in the flagfile_flag buffer and returns it. This
|
|
|
|
// function also creates a temporary flagfile based on FlagfileData input.
|
|
|
|
// We create a flagfile in a temporary directory with the name specified in
|
|
|
|
// FlagfileData and populate it with lines specifed in FlagfileData. If $0 is
|
|
|
|
// referenced in any of the lines in FlagfileData they are replaced with
|
|
|
|
// temporary directory location. This way we can test inclusion of one flagfile
|
|
|
|
// from another flagfile.
|
|
|
|
const char* GetFlagfileFlag(const std::vector<FlagfileData>& ffd,
|
Export of internal Abseil changes
--
7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 313226473
--
1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>:
Migrate internal interface to use mutable references.
PiperOrigin-RevId: 312931131
--
96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>:
Remove random/internal/distributions.h
This file was something of an historical artifact. All of the related
code has either been removed or migraged, and so the only remaining type
belongs with uniform_helper.h, as it is used to infer the return type
of the absl::Uniform method in a few cases.
PiperOrigin-RevId: 312878173
--
6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>:
Release the StrFormat test case for Cords to open source.
PiperOrigin-RevId: 312707974
--
34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>:
Let Cord::Cord(string&&), Cord::operator=(string&&),
Cord::Append(string&&), and Cord::Prepend(string&&) steal string data
and embed it into the Cord as a single external chunk, instead of
copying it into flat chunks (at most 4083-byte each).
Stealing string data is faster, but it creates a long chunk, which leads
to a higher more memory usage if its subcords are created and outlive
the whole Cord.
These functions revert to copying the data if any of the following
conditions holds:
- string size is at most kMaxBytesToCopy (511), to avoid the overhead
of an external chunk for short strings;
- less than half of string capacity is used, to avoid pinning to much
unused memory.
PiperOrigin-RevId: 312683785
GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923
Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
5 years ago
|
|
|
std::string& flagfile_flag) {
|
|
|
|
flagfile_flag = "--flagfile=";
|
|
|
|
absl::string_view separator;
|
|
|
|
for (const auto& flagfile_data : ffd) {
|
|
|
|
std::string flagfile_name =
|
|
|
|
absl::StrCat(GetTestTempDir(), flagfile_data.file_name);
|
|
|
|
|
|
|
|
std::ofstream flagfile_out(flagfile_name);
|
|
|
|
for (auto line : flagfile_data.file_lines) {
|
|
|
|
flagfile_out << absl::Substitute(line, GetTestTempDir()) << "\n";
|
|
|
|
}
|
|
|
|
|
Export of internal Abseil changes
--
7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 313226473
--
1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>:
Migrate internal interface to use mutable references.
PiperOrigin-RevId: 312931131
--
96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>:
Remove random/internal/distributions.h
This file was something of an historical artifact. All of the related
code has either been removed or migraged, and so the only remaining type
belongs with uniform_helper.h, as it is used to infer the return type
of the absl::Uniform method in a few cases.
PiperOrigin-RevId: 312878173
--
6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>:
Release the StrFormat test case for Cords to open source.
PiperOrigin-RevId: 312707974
--
34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>:
Let Cord::Cord(string&&), Cord::operator=(string&&),
Cord::Append(string&&), and Cord::Prepend(string&&) steal string data
and embed it into the Cord as a single external chunk, instead of
copying it into flat chunks (at most 4083-byte each).
Stealing string data is faster, but it creates a long chunk, which leads
to a higher more memory usage if its subcords are created and outlive
the whole Cord.
These functions revert to copying the data if any of the following
conditions holds:
- string size is at most kMaxBytesToCopy (511), to avoid the overhead
of an external chunk for short strings;
- less than half of string capacity is used, to avoid pinning to much
unused memory.
PiperOrigin-RevId: 312683785
GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923
Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
5 years ago
|
|
|
absl::StrAppend(&flagfile_flag, separator, flagfile_name);
|
|
|
|
separator = ",";
|
|
|
|
}
|
|
|
|
|
Export of internal Abseil changes
--
7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 313226473
--
1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>:
Migrate internal interface to use mutable references.
PiperOrigin-RevId: 312931131
--
96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>:
Remove random/internal/distributions.h
This file was something of an historical artifact. All of the related
code has either been removed or migraged, and so the only remaining type
belongs with uniform_helper.h, as it is used to infer the return type
of the absl::Uniform method in a few cases.
PiperOrigin-RevId: 312878173
--
6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>:
Release the StrFormat test case for Cords to open source.
PiperOrigin-RevId: 312707974
--
34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>:
Let Cord::Cord(string&&), Cord::operator=(string&&),
Cord::Append(string&&), and Cord::Prepend(string&&) steal string data
and embed it into the Cord as a single external chunk, instead of
copying it into flat chunks (at most 4083-byte each).
Stealing string data is faster, but it creates a long chunk, which leads
to a higher more memory usage if its subcords are created and outlive
the whole Cord.
These functions revert to copying the data if any of the following
conditions holds:
- string size is at most kMaxBytesToCopy (511), to avoid the overhead
of an external chunk for short strings;
- less than half of string capacity is used, to avoid pinning to much
unused memory.
PiperOrigin-RevId: 312683785
GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923
Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
5 years ago
|
|
|
return flagfile_flag.c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
ABSL_FLAG(int, int_flag, 1, "");
|
|
|
|
ABSL_FLAG(double, double_flag, 1.1, "");
|
|
|
|
ABSL_FLAG(std::string, string_flag, "a", "");
|
|
|
|
ABSL_FLAG(bool, bool_flag, false, "");
|
|
|
|
ABSL_FLAG(UDT, udt_flag, -1, "");
|
|
|
|
ABSL_RETIRED_FLAG(int, legacy_int, 1, "");
|
|
|
|
ABSL_RETIRED_FLAG(bool, legacy_bool, false, "");
|
|
|
|
ABSL_RETIRED_FLAG(std::string, legacy_str, "l", "");
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
namespace flags = absl::flags_internal;
|
|
|
|
using testing::ElementsAreArray;
|
|
|
|
|
|
|
|
class ParseTest : public testing::Test {
|
|
|
|
public:
|
|
|
|
~ParseTest() override { flags::SetFlagsHelpMode(flags::HelpMode::kNone); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
absl::FlagSaver flag_saver_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
template <int N>
|
|
|
|
std::vector<char*> InvokeParse(const char* (&in_argv)[N]) {
|
|
|
|
return absl::ParseCommandLine(N, const_cast<char**>(in_argv));
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
template <int N>
|
|
|
|
void TestParse(const char* (&in_argv)[N], int int_flag_value,
|
|
|
|
double double_flag_val, absl::string_view string_flag_val,
|
|
|
|
bool bool_flag_val, int exp_position_args = 0) {
|
|
|
|
auto out_args = InvokeParse(in_argv);
|
|
|
|
|
|
|
|
EXPECT_EQ(out_args.size(), 1 + exp_position_args);
|
|
|
|
EXPECT_STREQ(out_args[0], "testbin");
|
|
|
|
|
|
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), int_flag_value);
|
|
|
|
EXPECT_NEAR(absl::GetFlag(FLAGS_double_flag), double_flag_val, 0.0001);
|
|
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), string_flag_val);
|
|
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_bool_flag), bool_flag_val);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestEmptyArgv) {
|
|
|
|
const char* in_argv[] = {"testbin"};
|
|
|
|
|
|
|
|
auto out_args = InvokeParse(in_argv);
|
|
|
|
|
|
|
|
EXPECT_EQ(out_args.size(), 1);
|
|
|
|
EXPECT_STREQ(out_args[0], "testbin");
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestValidIntArg) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--int_flag=10",
|
|
|
|
};
|
|
|
|
TestParse(in_args1, 10, 1.1, "a", false);
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
"-int_flag=020",
|
|
|
|
};
|
|
|
|
TestParse(in_args2, 20, 1.1, "a", false);
|
|
|
|
|
|
|
|
const char* in_args3[] = {
|
|
|
|
"testbin",
|
|
|
|
"--int_flag",
|
|
|
|
"-30",
|
|
|
|
};
|
|
|
|
TestParse(in_args3, -30, 1.1, "a", false);
|
|
|
|
|
|
|
|
const char* in_args4[] = {
|
|
|
|
"testbin",
|
|
|
|
"-int_flag",
|
|
|
|
"0x21",
|
|
|
|
};
|
|
|
|
TestParse(in_args4, 33, 1.1, "a", false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestValidDoubleArg) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--double_flag=2.3",
|
|
|
|
};
|
|
|
|
TestParse(in_args1, 1, 2.3, "a", false);
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
"--double_flag=0x1.2",
|
|
|
|
};
|
|
|
|
TestParse(in_args2, 1, 1.125, "a", false);
|
|
|
|
|
|
|
|
const char* in_args3[] = {
|
|
|
|
"testbin",
|
|
|
|
"--double_flag",
|
|
|
|
"99.7",
|
|
|
|
};
|
|
|
|
TestParse(in_args3, 1, 99.7, "a", false);
|
|
|
|
|
|
|
|
const char* in_args4[] = {
|
|
|
|
"testbin",
|
|
|
|
"--double_flag",
|
|
|
|
"0x20.1",
|
|
|
|
};
|
|
|
|
TestParse(in_args4, 1, 32.0625, "a", false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestValidStringArg) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--string_flag=aqswde",
|
|
|
|
};
|
|
|
|
TestParse(in_args1, 1, 1.1, "aqswde", false);
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
"-string_flag=a=b=c",
|
|
|
|
};
|
|
|
|
TestParse(in_args2, 1, 1.1, "a=b=c", false);
|
|
|
|
|
|
|
|
const char* in_args3[] = {
|
|
|
|
"testbin",
|
|
|
|
"--string_flag",
|
|
|
|
"zaxscd",
|
|
|
|
};
|
|
|
|
TestParse(in_args3, 1, 1.1, "zaxscd", false);
|
|
|
|
|
|
|
|
const char* in_args4[] = {
|
|
|
|
"testbin",
|
|
|
|
"-string_flag",
|
|
|
|
"--int_flag",
|
|
|
|
};
|
|
|
|
TestParse(in_args4, 1, 1.1, "--int_flag", false);
|
|
|
|
|
|
|
|
const char* in_args5[] = {
|
|
|
|
"testbin",
|
|
|
|
"--string_flag",
|
|
|
|
"--no_a_flag=11",
|
|
|
|
};
|
|
|
|
TestParse(in_args5, 1, 1.1, "--no_a_flag=11", false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestValidBoolArg) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--bool_flag",
|
|
|
|
};
|
|
|
|
TestParse(in_args1, 1, 1.1, "a", true);
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
"--nobool_flag",
|
|
|
|
};
|
|
|
|
TestParse(in_args2, 1, 1.1, "a", false);
|
|
|
|
|
|
|
|
const char* in_args3[] = {
|
|
|
|
"testbin",
|
|
|
|
"--bool_flag=true",
|
|
|
|
};
|
|
|
|
TestParse(in_args3, 1, 1.1, "a", true);
|
|
|
|
|
|
|
|
const char* in_args4[] = {
|
|
|
|
"testbin",
|
|
|
|
"-bool_flag=false",
|
|
|
|
};
|
|
|
|
TestParse(in_args4, 1, 1.1, "a", false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestValidUDTArg) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--udt_flag=A",
|
|
|
|
};
|
|
|
|
InvokeParse(in_args1);
|
|
|
|
|
|
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_udt_flag).value, 1);
|
|
|
|
|
|
|
|
const char* in_args2[] = {"testbin", "--udt_flag", "AAA"};
|
|
|
|
InvokeParse(in_args2);
|
|
|
|
|
|
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_udt_flag).value, 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestValidMultipleArg) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin", "--bool_flag", "--int_flag=2",
|
|
|
|
"--double_flag=0.1", "--string_flag=asd",
|
|
|
|
};
|
|
|
|
TestParse(in_args1, 2, 0.1, "asd", true);
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin", "--string_flag=", "--nobool_flag", "--int_flag",
|
|
|
|
"-011", "--double_flag", "-1e-2",
|
|
|
|
};
|
|
|
|
TestParse(in_args2, -11, -0.01, "", false);
|
|
|
|
|
|
|
|
const char* in_args3[] = {
|
|
|
|
"testbin", "--int_flag", "-0", "--string_flag", "\"\"",
|
|
|
|
"--bool_flag=true", "--double_flag=1e18",
|
|
|
|
};
|
|
|
|
TestParse(in_args3, 0, 1e18, "\"\"", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestPositionalArgs) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"p1",
|
|
|
|
"p2",
|
|
|
|
};
|
|
|
|
TestParse(in_args1, 1, 1.1, "a", false, 2);
|
|
|
|
|
|
|
|
auto out_args1 = InvokeParse(in_args1);
|
|
|
|
|
|
|
|
EXPECT_STREQ(out_args1[1], "p1");
|
|
|
|
EXPECT_STREQ(out_args1[2], "p2");
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
"--int_flag=2",
|
|
|
|
"p1",
|
|
|
|
};
|
|
|
|
TestParse(in_args2, 2, 1.1, "a", false, 1);
|
|
|
|
|
|
|
|
auto out_args2 = InvokeParse(in_args2);
|
|
|
|
|
|
|
|
EXPECT_STREQ(out_args2[1], "p1");
|
|
|
|
|
|
|
|
const char* in_args3[] = {"testbin", "p1", "--int_flag=3",
|
|
|
|
"p2", "--bool_flag", "true"};
|
|
|
|
TestParse(in_args3, 3, 1.1, "a", true, 3);
|
|
|
|
|
|
|
|
auto out_args3 = InvokeParse(in_args3);
|
|
|
|
|
|
|
|
EXPECT_STREQ(out_args3[1], "p1");
|
|
|
|
EXPECT_STREQ(out_args3[2], "p2");
|
|
|
|
EXPECT_STREQ(out_args3[3], "true");
|
|
|
|
|
|
|
|
const char* in_args4[] = {
|
|
|
|
"testbin",
|
|
|
|
"--",
|
|
|
|
"p1",
|
|
|
|
"p2",
|
|
|
|
};
|
|
|
|
TestParse(in_args4, 3, 1.1, "a", true, 2);
|
|
|
|
|
|
|
|
auto out_args4 = InvokeParse(in_args4);
|
|
|
|
|
|
|
|
EXPECT_STREQ(out_args4[1], "p1");
|
|
|
|
EXPECT_STREQ(out_args4[2], "p2");
|
|
|
|
|
|
|
|
const char* in_args5[] = {
|
|
|
|
"testbin", "p1", "--int_flag=4", "--", "--bool_flag", "false", "p2",
|
|
|
|
};
|
|
|
|
TestParse(in_args5, 4, 1.1, "a", true, 4);
|
|
|
|
|
|
|
|
auto out_args5 = InvokeParse(in_args5);
|
|
|
|
|
|
|
|
EXPECT_STREQ(out_args5[1], "p1");
|
|
|
|
EXPECT_STREQ(out_args5[2], "--bool_flag");
|
|
|
|
EXPECT_STREQ(out_args5[3], "false");
|
|
|
|
EXPECT_STREQ(out_args5[4], "p2");
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
using ParseDeathTest = ParseTest;
|
|
|
|
|
|
|
|
TEST_F(ParseDeathTest, TestUndefinedArg) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--undefined_flag",
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
|
|
|
|
"Unknown command line flag 'undefined_flag'");
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
"--noprefixed_flag",
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args2),
|
|
|
|
"Unknown command line flag 'noprefixed_flag'");
|
|
|
|
|
|
|
|
const char* in_args3[] = {
|
|
|
|
"testbin",
|
|
|
|
"--Int_flag=1",
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args3),
|
|
|
|
"Unknown command line flag 'Int_flag'");
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseDeathTest, TestInvalidBoolFlagFormat) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--bool_flag=",
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(
|
|
|
|
InvokeParse(in_args1),
|
|
|
|
"Missing the value after assignment for the boolean flag 'bool_flag'");
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
"--nobool_flag=true",
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args2),
|
|
|
|
"Negative form with assignment is not valid for the boolean "
|
|
|
|
"flag 'bool_flag'");
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseDeathTest, TestInvalidNonBoolFlagFormat) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--nostring_flag",
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
|
|
|
|
"Negative form is not valid for the flag 'string_flag'");
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
"--int_flag",
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args2),
|
|
|
|
"Missing the value for the flag 'int_flag'");
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseDeathTest, TestInvalidUDTFlagFormat) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--udt_flag=1",
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
|
|
|
|
"Illegal value '1' specified for flag 'udt_flag'; Use values A, "
|
|
|
|
"AAA instead");
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
"--udt_flag",
|
|
|
|
"AA",
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args2),
|
|
|
|
"Illegal value 'AA' specified for flag 'udt_flag'; Use values "
|
|
|
|
"A, AAA instead");
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestLegacyFlags) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--legacy_int=11",
|
|
|
|
};
|
|
|
|
TestParse(in_args1, 1, 1.1, "a", false);
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
"--legacy_bool",
|
|
|
|
};
|
|
|
|
TestParse(in_args2, 1, 1.1, "a", false);
|
|
|
|
|
|
|
|
const char* in_args3[] = {
|
|
|
|
"testbin", "--legacy_int", "22", "--int_flag=2",
|
|
|
|
"--legacy_bool", "true", "--legacy_str", "--string_flag=qwe",
|
|
|
|
};
|
|
|
|
TestParse(in_args3, 2, 1.1, "a", false, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestSimpleValidFlagfile) {
|
|
|
|
std::string flagfile_flag;
|
|
|
|
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
GetFlagfileFlag({{"parse_test.ff1", absl::MakeConstSpan(ff1_data)}},
|
Export of internal Abseil changes
--
7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 313226473
--
1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>:
Migrate internal interface to use mutable references.
PiperOrigin-RevId: 312931131
--
96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>:
Remove random/internal/distributions.h
This file was something of an historical artifact. All of the related
code has either been removed or migraged, and so the only remaining type
belongs with uniform_helper.h, as it is used to infer the return type
of the absl::Uniform method in a few cases.
PiperOrigin-RevId: 312878173
--
6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>:
Release the StrFormat test case for Cords to open source.
PiperOrigin-RevId: 312707974
--
34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>:
Let Cord::Cord(string&&), Cord::operator=(string&&),
Cord::Append(string&&), and Cord::Prepend(string&&) steal string data
and embed it into the Cord as a single external chunk, instead of
copying it into flat chunks (at most 4083-byte each).
Stealing string data is faster, but it creates a long chunk, which leads
to a higher more memory usage if its subcords are created and outlive
the whole Cord.
These functions revert to copying the data if any of the following
conditions holds:
- string size is at most kMaxBytesToCopy (511), to avoid the overhead
of an external chunk for short strings;
- less than half of string capacity is used, to avoid pinning to much
unused memory.
PiperOrigin-RevId: 312683785
GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923
Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
5 years ago
|
|
|
flagfile_flag),
|
|
|
|
};
|
|
|
|
TestParse(in_args1, -1, 0.1, "q2w2 ", true);
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
GetFlagfileFlag({{"parse_test.ff2", absl::MakeConstSpan(ff2_data)}},
|
Export of internal Abseil changes
--
7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 313226473
--
1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>:
Migrate internal interface to use mutable references.
PiperOrigin-RevId: 312931131
--
96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>:
Remove random/internal/distributions.h
This file was something of an historical artifact. All of the related
code has either been removed or migraged, and so the only remaining type
belongs with uniform_helper.h, as it is used to infer the return type
of the absl::Uniform method in a few cases.
PiperOrigin-RevId: 312878173
--
6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>:
Release the StrFormat test case for Cords to open source.
PiperOrigin-RevId: 312707974
--
34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>:
Let Cord::Cord(string&&), Cord::operator=(string&&),
Cord::Append(string&&), and Cord::Prepend(string&&) steal string data
and embed it into the Cord as a single external chunk, instead of
copying it into flat chunks (at most 4083-byte each).
Stealing string data is faster, but it creates a long chunk, which leads
to a higher more memory usage if its subcords are created and outlive
the whole Cord.
These functions revert to copying the data if any of the following
conditions holds:
- string size is at most kMaxBytesToCopy (511), to avoid the overhead
of an external chunk for short strings;
- less than half of string capacity is used, to avoid pinning to much
unused memory.
PiperOrigin-RevId: 312683785
GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923
Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
5 years ago
|
|
|
flagfile_flag),
|
|
|
|
};
|
|
|
|
TestParse(in_args2, 100, 0.1, "q2w2 ", false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestValidMultiFlagfile) {
|
|
|
|
std::string flagfile_flag;
|
|
|
|
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
GetFlagfileFlag({{"parse_test.ff2", absl::MakeConstSpan(ff2_data)},
|
|
|
|
{"parse_test.ff1", absl::MakeConstSpan(ff1_data)}},
|
Export of internal Abseil changes
--
7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 313226473
--
1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>:
Migrate internal interface to use mutable references.
PiperOrigin-RevId: 312931131
--
96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>:
Remove random/internal/distributions.h
This file was something of an historical artifact. All of the related
code has either been removed or migraged, and so the only remaining type
belongs with uniform_helper.h, as it is used to infer the return type
of the absl::Uniform method in a few cases.
PiperOrigin-RevId: 312878173
--
6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>:
Release the StrFormat test case for Cords to open source.
PiperOrigin-RevId: 312707974
--
34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>:
Let Cord::Cord(string&&), Cord::operator=(string&&),
Cord::Append(string&&), and Cord::Prepend(string&&) steal string data
and embed it into the Cord as a single external chunk, instead of
copying it into flat chunks (at most 4083-byte each).
Stealing string data is faster, but it creates a long chunk, which leads
to a higher more memory usage if its subcords are created and outlive
the whole Cord.
These functions revert to copying the data if any of the following
conditions holds:
- string size is at most kMaxBytesToCopy (511), to avoid the overhead
of an external chunk for short strings;
- less than half of string capacity is used, to avoid pinning to much
unused memory.
PiperOrigin-RevId: 312683785
GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923
Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
5 years ago
|
|
|
flagfile_flag),
|
|
|
|
};
|
|
|
|
TestParse(in_args1, -1, 0.1, "q2w2 ", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestFlagfileMixedWithRegularFlags) {
|
|
|
|
std::string flagfile_flag;
|
|
|
|
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin", "--int_flag=3",
|
|
|
|
GetFlagfileFlag({{"parse_test.ff1", absl::MakeConstSpan(ff1_data)}},
|
Export of internal Abseil changes
--
7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 313226473
--
1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>:
Migrate internal interface to use mutable references.
PiperOrigin-RevId: 312931131
--
96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>:
Remove random/internal/distributions.h
This file was something of an historical artifact. All of the related
code has either been removed or migraged, and so the only remaining type
belongs with uniform_helper.h, as it is used to infer the return type
of the absl::Uniform method in a few cases.
PiperOrigin-RevId: 312878173
--
6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>:
Release the StrFormat test case for Cords to open source.
PiperOrigin-RevId: 312707974
--
34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>:
Let Cord::Cord(string&&), Cord::operator=(string&&),
Cord::Append(string&&), and Cord::Prepend(string&&) steal string data
and embed it into the Cord as a single external chunk, instead of
copying it into flat chunks (at most 4083-byte each).
Stealing string data is faster, but it creates a long chunk, which leads
to a higher more memory usage if its subcords are created and outlive
the whole Cord.
These functions revert to copying the data if any of the following
conditions holds:
- string size is at most kMaxBytesToCopy (511), to avoid the overhead
of an external chunk for short strings;
- less than half of string capacity is used, to avoid pinning to much
unused memory.
PiperOrigin-RevId: 312683785
GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923
Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
5 years ago
|
|
|
flagfile_flag),
|
|
|
|
"-double_flag=0.2"};
|
|
|
|
TestParse(in_args1, -1, 0.2, "q2w2 ", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestFlagfileInFlagfile) {
|
|
|
|
std::string flagfile_flag;
|
|
|
|
|
|
|
|
constexpr const char* const ff3_data[] = {
|
|
|
|
"--flagfile=$0/parse_test.ff1",
|
|
|
|
"--flagfile=$0/parse_test.ff2",
|
|
|
|
};
|
|
|
|
|
|
|
|
GetFlagfileFlag({{"parse_test.ff2", absl::MakeConstSpan(ff2_data)},
|
|
|
|
{"parse_test.ff1", absl::MakeConstSpan(ff1_data)}},
|
|
|
|
flagfile_flag);
|
|
|
|
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
GetFlagfileFlag({{"parse_test.ff3", absl::MakeConstSpan(ff3_data)}},
|
Export of internal Abseil changes
--
7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 313226473
--
1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>:
Migrate internal interface to use mutable references.
PiperOrigin-RevId: 312931131
--
96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>:
Remove random/internal/distributions.h
This file was something of an historical artifact. All of the related
code has either been removed or migraged, and so the only remaining type
belongs with uniform_helper.h, as it is used to infer the return type
of the absl::Uniform method in a few cases.
PiperOrigin-RevId: 312878173
--
6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>:
Release the StrFormat test case for Cords to open source.
PiperOrigin-RevId: 312707974
--
34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>:
Let Cord::Cord(string&&), Cord::operator=(string&&),
Cord::Append(string&&), and Cord::Prepend(string&&) steal string data
and embed it into the Cord as a single external chunk, instead of
copying it into flat chunks (at most 4083-byte each).
Stealing string data is faster, but it creates a long chunk, which leads
to a higher more memory usage if its subcords are created and outlive
the whole Cord.
These functions revert to copying the data if any of the following
conditions holds:
- string size is at most kMaxBytesToCopy (511), to avoid the overhead
of an external chunk for short strings;
- less than half of string capacity is used, to avoid pinning to much
unused memory.
PiperOrigin-RevId: 312683785
GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923
Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
5 years ago
|
|
|
flagfile_flag),
|
|
|
|
};
|
|
|
|
TestParse(in_args1, 100, 0.1, "q2w2 ", false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseDeathTest, TestInvalidFlagfiles) {
|
|
|
|
std::string flagfile_flag;
|
|
|
|
|
|
|
|
constexpr const char* const ff4_data[] = {
|
|
|
|
"--unknown_flag=10"
|
|
|
|
};
|
|
|
|
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
GetFlagfileFlag({{"parse_test.ff4",
|
Export of internal Abseil changes
--
7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 313226473
--
1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>:
Migrate internal interface to use mutable references.
PiperOrigin-RevId: 312931131
--
96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>:
Remove random/internal/distributions.h
This file was something of an historical artifact. All of the related
code has either been removed or migraged, and so the only remaining type
belongs with uniform_helper.h, as it is used to infer the return type
of the absl::Uniform method in a few cases.
PiperOrigin-RevId: 312878173
--
6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>:
Release the StrFormat test case for Cords to open source.
PiperOrigin-RevId: 312707974
--
34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>:
Let Cord::Cord(string&&), Cord::operator=(string&&),
Cord::Append(string&&), and Cord::Prepend(string&&) steal string data
and embed it into the Cord as a single external chunk, instead of
copying it into flat chunks (at most 4083-byte each).
Stealing string data is faster, but it creates a long chunk, which leads
to a higher more memory usage if its subcords are created and outlive
the whole Cord.
These functions revert to copying the data if any of the following
conditions holds:
- string size is at most kMaxBytesToCopy (511), to avoid the overhead
of an external chunk for short strings;
- less than half of string capacity is used, to avoid pinning to much
unused memory.
PiperOrigin-RevId: 312683785
GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923
Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
5 years ago
|
|
|
absl::MakeConstSpan(ff4_data)}}, flagfile_flag),
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
|
|
|
|
"Unknown command line flag 'unknown_flag'");
|
|
|
|
|
|
|
|
constexpr const char* const ff5_data[] = {
|
|
|
|
"--int_flag 10",
|
|
|
|
};
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
GetFlagfileFlag({{"parse_test.ff5",
|
Export of internal Abseil changes
--
7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 313226473
--
1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>:
Migrate internal interface to use mutable references.
PiperOrigin-RevId: 312931131
--
96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>:
Remove random/internal/distributions.h
This file was something of an historical artifact. All of the related
code has either been removed or migraged, and so the only remaining type
belongs with uniform_helper.h, as it is used to infer the return type
of the absl::Uniform method in a few cases.
PiperOrigin-RevId: 312878173
--
6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>:
Release the StrFormat test case for Cords to open source.
PiperOrigin-RevId: 312707974
--
34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>:
Let Cord::Cord(string&&), Cord::operator=(string&&),
Cord::Append(string&&), and Cord::Prepend(string&&) steal string data
and embed it into the Cord as a single external chunk, instead of
copying it into flat chunks (at most 4083-byte each).
Stealing string data is faster, but it creates a long chunk, which leads
to a higher more memory usage if its subcords are created and outlive
the whole Cord.
These functions revert to copying the data if any of the following
conditions holds:
- string size is at most kMaxBytesToCopy (511), to avoid the overhead
of an external chunk for short strings;
- less than half of string capacity is used, to avoid pinning to much
unused memory.
PiperOrigin-RevId: 312683785
GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923
Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
5 years ago
|
|
|
absl::MakeConstSpan(ff5_data)}}, flagfile_flag),
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args2),
|
|
|
|
"Unknown command line flag 'int_flag 10'");
|
|
|
|
|
|
|
|
constexpr const char* const ff6_data[] = {
|
|
|
|
"--int_flag=10", "--", "arg1", "arg2", "arg3",
|
|
|
|
};
|
|
|
|
|
|
|
|
const char* in_args3[] = {
|
|
|
|
"testbin",
|
|
|
|
GetFlagfileFlag({{"parse_test.ff6", absl::MakeConstSpan(ff6_data)}},
|
Export of internal Abseil changes
--
7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 313226473
--
1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>:
Migrate internal interface to use mutable references.
PiperOrigin-RevId: 312931131
--
96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>:
Remove random/internal/distributions.h
This file was something of an historical artifact. All of the related
code has either been removed or migraged, and so the only remaining type
belongs with uniform_helper.h, as it is used to infer the return type
of the absl::Uniform method in a few cases.
PiperOrigin-RevId: 312878173
--
6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>:
Release the StrFormat test case for Cords to open source.
PiperOrigin-RevId: 312707974
--
34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>:
Let Cord::Cord(string&&), Cord::operator=(string&&),
Cord::Append(string&&), and Cord::Prepend(string&&) steal string data
and embed it into the Cord as a single external chunk, instead of
copying it into flat chunks (at most 4083-byte each).
Stealing string data is faster, but it creates a long chunk, which leads
to a higher more memory usage if its subcords are created and outlive
the whole Cord.
These functions revert to copying the data if any of the following
conditions holds:
- string size is at most kMaxBytesToCopy (511), to avoid the overhead
of an external chunk for short strings;
- less than half of string capacity is used, to avoid pinning to much
unused memory.
PiperOrigin-RevId: 312683785
GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923
Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
5 years ago
|
|
|
flagfile_flag),
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args3),
|
|
|
|
"Flagfile can't contain position arguments or --");
|
|
|
|
|
|
|
|
const char* in_args4[] = {
|
|
|
|
"testbin",
|
|
|
|
"--flagfile=invalid_flag_file",
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args4),
|
|
|
|
"Can't open flagfile invalid_flag_file");
|
|
|
|
|
|
|
|
constexpr const char* const ff7_data[] = {
|
|
|
|
"--int_flag=10",
|
|
|
|
"*bin*",
|
|
|
|
"--str_flag=aqsw",
|
|
|
|
};
|
|
|
|
|
|
|
|
const char* in_args5[] = {
|
|
|
|
"testbin",
|
|
|
|
GetFlagfileFlag({{"parse_test.ff7", absl::MakeConstSpan(ff7_data)}},
|
Export of internal Abseil changes
--
7d0468a6610ed85586d5c87fd65de8dac5118923 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 313226473
--
1131ef6d116f5ce7d46537a82f300ea06dcaaa53 by Gennadiy Rozental <rogeeff@google.com>:
Migrate internal interface to use mutable references.
PiperOrigin-RevId: 312931131
--
96225212a9f5fbd0b38c71fe65539164992c7c3b by Laramie Leavitt <lar@google.com>:
Remove random/internal/distributions.h
This file was something of an historical artifact. All of the related
code has either been removed or migraged, and so the only remaining type
belongs with uniform_helper.h, as it is used to infer the return type
of the absl::Uniform method in a few cases.
PiperOrigin-RevId: 312878173
--
6dcbd5be58ad425e08740ff64088373ee7fe4a72 by Mark Barolak <mbar@google.com>:
Release the StrFormat test case for Cords to open source.
PiperOrigin-RevId: 312707974
--
34484d18dfb63a0a7ad6e2aaeb570e33592968be by Abseil Team <absl-team@google.com>:
Let Cord::Cord(string&&), Cord::operator=(string&&),
Cord::Append(string&&), and Cord::Prepend(string&&) steal string data
and embed it into the Cord as a single external chunk, instead of
copying it into flat chunks (at most 4083-byte each).
Stealing string data is faster, but it creates a long chunk, which leads
to a higher more memory usage if its subcords are created and outlive
the whole Cord.
These functions revert to copying the data if any of the following
conditions holds:
- string size is at most kMaxBytesToCopy (511), to avoid the overhead
of an external chunk for short strings;
- less than half of string capacity is used, to avoid pinning to much
unused memory.
PiperOrigin-RevId: 312683785
GitOrigin-RevId: 7d0468a6610ed85586d5c87fd65de8dac5118923
Change-Id: If79b5a1dfe6d53a8ddddbc7da84338f11fc4cfa3
5 years ago
|
|
|
flagfile_flag),
|
|
|
|
};
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args5),
|
|
|
|
"Unexpected line in the flagfile .*: \\*bin\\*");
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestReadingRequiredFlagsFromEnv) {
|
|
|
|
const char* in_args1[] = {"testbin",
|
|
|
|
"--fromenv=int_flag,bool_flag,string_flag"};
|
|
|
|
|
|
|
|
ScopedSetEnv set_int_flag("FLAGS_int_flag", "33");
|
|
|
|
ScopedSetEnv set_bool_flag("FLAGS_bool_flag", "True");
|
|
|
|
ScopedSetEnv set_string_flag("FLAGS_string_flag", "AQ12");
|
|
|
|
|
|
|
|
TestParse(in_args1, 33, 1.1, "AQ12", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseDeathTest, TestReadingUnsetRequiredFlagsFromEnv) {
|
|
|
|
const char* in_args1[] = {"testbin", "--fromenv=int_flag"};
|
|
|
|
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
|
|
|
|
"FLAGS_int_flag not found in environment");
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseDeathTest, TestRecursiveFlagsFromEnv) {
|
|
|
|
const char* in_args1[] = {"testbin", "--fromenv=tryfromenv"};
|
|
|
|
|
|
|
|
ScopedSetEnv set_tryfromenv("FLAGS_tryfromenv", "int_flag");
|
|
|
|
|
|
|
|
EXPECT_DEATH_IF_SUPPORTED(InvokeParse(in_args1),
|
|
|
|
"Infinite recursion on flag tryfromenv");
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestReadingOptionalFlagsFromEnv) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin", "--tryfromenv=int_flag,bool_flag,string_flag,other_flag"};
|
|
|
|
|
|
|
|
ScopedSetEnv set_int_flag("FLAGS_int_flag", "17");
|
|
|
|
ScopedSetEnv set_bool_flag("FLAGS_bool_flag", "Y");
|
|
|
|
|
|
|
|
TestParse(in_args1, 17, 1.1, "a", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestReadingFlagsFromEnvMoxedWithRegularFlags) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--bool_flag=T",
|
|
|
|
"--tryfromenv=int_flag,bool_flag",
|
|
|
|
"--int_flag=-21",
|
|
|
|
};
|
|
|
|
|
|
|
|
ScopedSetEnv set_int_flag("FLAGS_int_flag", "-15");
|
|
|
|
ScopedSetEnv set_bool_flag("FLAGS_bool_flag", "F");
|
|
|
|
|
|
|
|
TestParse(in_args1, -21, 1.1, "a", false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestKeepParsedArgs) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin", "arg1", "--bool_flag",
|
|
|
|
"--int_flag=211", "arg2", "--double_flag=1.1",
|
|
|
|
"--string_flag", "asd", "--",
|
|
|
|
"arg3", "arg4",
|
|
|
|
};
|
|
|
|
|
|
|
|
auto out_args1 = InvokeParse(in_args1);
|
|
|
|
|
|
|
|
EXPECT_THAT(
|
|
|
|
out_args1,
|
|
|
|
ElementsAreArray({absl::string_view("testbin"), absl::string_view("arg1"),
|
|
|
|
absl::string_view("arg2"), absl::string_view("arg3"),
|
|
|
|
absl::string_view("arg4")}));
|
|
|
|
|
|
|
|
auto out_args2 = flags::ParseCommandLineImpl(
|
|
|
|
11, const_cast<char**>(in_args1), flags::ArgvListAction::kKeepParsedArgs,
|
|
|
|
flags::UsageFlagsAction::kHandleUsage,
|
|
|
|
flags::OnUndefinedFlag::kAbortIfUndefined);
|
|
|
|
|
|
|
|
EXPECT_THAT(
|
|
|
|
out_args2,
|
|
|
|
ElementsAreArray({absl::string_view("testbin"),
|
|
|
|
absl::string_view("--bool_flag"),
|
|
|
|
absl::string_view("--int_flag=211"),
|
|
|
|
absl::string_view("--double_flag=1.1"),
|
|
|
|
absl::string_view("--string_flag"),
|
|
|
|
absl::string_view("asd"), absl::string_view("--"),
|
|
|
|
absl::string_view("arg1"), absl::string_view("arg2"),
|
|
|
|
absl::string_view("arg3"), absl::string_view("arg4")}));
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, TestIgnoreUndefinedFlags) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"arg1",
|
|
|
|
"--undef_flag=aa",
|
|
|
|
"--int_flag=21",
|
|
|
|
};
|
|
|
|
|
|
|
|
auto out_args1 = flags::ParseCommandLineImpl(
|
|
|
|
4, const_cast<char**>(in_args1), flags::ArgvListAction::kRemoveParsedArgs,
|
|
|
|
flags::UsageFlagsAction::kHandleUsage,
|
|
|
|
flags::OnUndefinedFlag::kIgnoreUndefined);
|
|
|
|
|
|
|
|
EXPECT_THAT(out_args1, ElementsAreArray({absl::string_view("testbin"),
|
|
|
|
absl::string_view("arg1")}));
|
|
|
|
|
|
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 21);
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
"arg1",
|
|
|
|
"--undef_flag=aa",
|
|
|
|
"--string_flag=AA",
|
|
|
|
};
|
|
|
|
|
|
|
|
auto out_args2 = flags::ParseCommandLineImpl(
|
|
|
|
4, const_cast<char**>(in_args2), flags::ArgvListAction::kKeepParsedArgs,
|
|
|
|
flags::UsageFlagsAction::kHandleUsage,
|
|
|
|
flags::OnUndefinedFlag::kIgnoreUndefined);
|
|
|
|
|
|
|
|
EXPECT_THAT(
|
|
|
|
out_args2,
|
|
|
|
ElementsAreArray(
|
|
|
|
{absl::string_view("testbin"), absl::string_view("--undef_flag=aa"),
|
|
|
|
absl::string_view("--string_flag=AA"), absl::string_view("arg1")}));
|
|
|
|
|
|
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_string_flag), "AA");
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseDeathTest, TestSimpleHelpFlagHandling) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--help",
|
|
|
|
};
|
|
|
|
|
|
|
|
EXPECT_EXIT(InvokeParse(in_args1), testing::ExitedWithCode(1), "");
|
|
|
|
|
|
|
|
const char* in_args2[] = {
|
|
|
|
"testbin",
|
|
|
|
"--help",
|
|
|
|
"--int_flag=3",
|
|
|
|
};
|
|
|
|
|
|
|
|
auto out_args2 = flags::ParseCommandLineImpl(
|
|
|
|
3, const_cast<char**>(in_args2), flags::ArgvListAction::kRemoveParsedArgs,
|
|
|
|
flags::UsageFlagsAction::kIgnoreUsage,
|
|
|
|
flags::OnUndefinedFlag::kAbortIfUndefined);
|
|
|
|
|
|
|
|
EXPECT_EQ(flags::GetFlagsHelpMode(), flags::HelpMode::kImportant);
|
|
|
|
EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseDeathTest, TestSubstringHelpFlagHandling) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin",
|
|
|
|
"--help=abcd",
|
|
|
|
};
|
|
|
|
|
|
|
|
auto out_args1 = flags::ParseCommandLineImpl(
|
|
|
|
2, const_cast<char**>(in_args1), flags::ArgvListAction::kRemoveParsedArgs,
|
|
|
|
flags::UsageFlagsAction::kIgnoreUsage,
|
|
|
|
flags::OnUndefinedFlag::kAbortIfUndefined);
|
|
|
|
|
|
|
|
EXPECT_EQ(flags::GetFlagsHelpMode(), flags::HelpMode::kMatch);
|
|
|
|
EXPECT_EQ(flags::GetFlagsHelpMatchSubstr(), "abcd");
|
|
|
|
|
|
|
|
const char* in_args2[] = {"testbin", "--help", "some_positional_arg"};
|
|
|
|
|
|
|
|
auto out_args2 = flags::ParseCommandLineImpl(
|
|
|
|
3, const_cast<char**>(in_args2), flags::ArgvListAction::kRemoveParsedArgs,
|
|
|
|
flags::UsageFlagsAction::kIgnoreUsage,
|
|
|
|
flags::OnUndefinedFlag::kAbortIfUndefined);
|
|
|
|
|
|
|
|
EXPECT_EQ(flags::GetFlagsHelpMode(), flags::HelpMode::kImportant);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
TEST_F(ParseTest, WasPresentOnCommandLine) {
|
|
|
|
const char* in_args1[] = {
|
|
|
|
"testbin", "arg1", "--bool_flag",
|
|
|
|
"--int_flag=211", "arg2", "--double_flag=1.1",
|
|
|
|
"--string_flag", "asd", "--",
|
|
|
|
"--some_flag", "arg4",
|
|
|
|
};
|
|
|
|
|
|
|
|
InvokeParse(in_args1);
|
|
|
|
|
|
|
|
EXPECT_TRUE(flags::WasPresentOnCommandLine("bool_flag"));
|
|
|
|
EXPECT_TRUE(flags::WasPresentOnCommandLine("int_flag"));
|
|
|
|
EXPECT_TRUE(flags::WasPresentOnCommandLine("double_flag"));
|
|
|
|
EXPECT_TRUE(flags::WasPresentOnCommandLine("string_flag"));
|
|
|
|
EXPECT_FALSE(flags::WasPresentOnCommandLine("some_flag"));
|
|
|
|
EXPECT_FALSE(flags::WasPresentOnCommandLine("another_flag"));
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------
|
|
|
|
|
|
|
|
} // namespace
|