diff options
author | Vincent Ambo <mail@tazj.in> | 2022-02-07T23·05+0300 |
---|---|---|
committer | clbot <clbot@tvl.fyi> | 2022-02-07T23·09+0000 |
commit | 5aa5d282eac56a21e74611c1cdbaa97bb5db2dca (patch) | |
tree | 8cc5dce8157a1470ff76719dd15d65f648a05522 /third_party/abseil_cpp/absl/flags/internal | |
parent | a25675804c4f429fab5ee5201fe25e89865dfd13 (diff) |
chore(3p/abseil_cpp): unvendor abseil_cpp r/3786
we weren't actually using these sources anymore, okay? Change-Id: If701571d9716de308d3512e1eb22c35db0877a66 Reviewed-on: https://cl.tvl.fyi/c/depot/+/5248 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi> Autosubmit: tazjin <tazjin@tvl.su>
Diffstat (limited to 'third_party/abseil_cpp/absl/flags/internal')
16 files changed, 0 insertions, 3119 deletions
diff --git a/third_party/abseil_cpp/absl/flags/internal/commandlineflag.cc b/third_party/abseil_cpp/absl/flags/internal/commandlineflag.cc deleted file mode 100644 index 4482955c4cb6..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/commandlineflag.cc +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright 2020 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/internal/commandlineflag.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -FlagStateInterface::~FlagStateInterface() {} - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/flags/internal/commandlineflag.h b/third_party/abseil_cpp/absl/flags/internal/commandlineflag.h deleted file mode 100644 index cb46fe2e979d..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/commandlineflag.h +++ /dev/null @@ -1,68 +0,0 @@ -// -// 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. - -#ifndef ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_ -#define ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_ - -#include "absl/base/config.h" -#include "absl/base/internal/fast_type_id.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -// An alias for flag fast type id. This value identifies the flag value type -// simialarly to typeid(T), without relying on RTTI being available. In most -// cases this id is enough to uniquely identify the flag's value type. In a few -// cases we'll have to resort to using actual RTTI implementation if it is -// available. -using FlagFastTypeId = absl::base_internal::FastTypeIdType; - -// Options that control SetCommandLineOptionWithMode. -enum FlagSettingMode { - // update the flag's value unconditionally (can call this multiple times). - SET_FLAGS_VALUE, - // update the flag's value, but *only if* it has not yet been updated - // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef". - SET_FLAG_IF_DEFAULT, - // set the flag's default value to this. If the flag has not been updated - // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef") - // change the flag's current value to the new default value as well. - SET_FLAGS_DEFAULT -}; - -// Options that control ParseFrom: Source of a value. -enum ValueSource { - // Flag is being set by value specified on a command line. - kCommandLine, - // Flag is being set by value specified in the code. - kProgrammaticChange, -}; - -// Handle to FlagState objects. Specific flag state objects will restore state -// of a flag produced this flag state from method CommandLineFlag::SaveState(). -class FlagStateInterface { - public: - virtual ~FlagStateInterface(); - - // Restores the flag originated this object to the saved state. - virtual void Restore() const = 0; -}; - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FLAGS_INTERNAL_COMMANDLINEFLAG_H_ diff --git a/third_party/abseil_cpp/absl/flags/internal/flag.cc b/third_party/abseil_cpp/absl/flags/internal/flag.cc deleted file mode 100644 index 1502e7f11d36..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/flag.cc +++ /dev/null @@ -1,568 +0,0 @@ -// -// 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/internal/flag.h" - -#include <assert.h> -#include <stddef.h> -#include <stdint.h> -#include <string.h> - -#include <array> -#include <atomic> -#include <memory> -#include <new> -#include <string> -#include <typeinfo> - -#include "absl/base/call_once.h" -#include "absl/base/casts.h" -#include "absl/base/config.h" -#include "absl/base/optimization.h" -#include "absl/flags/config.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/flags/usage_config.h" -#include "absl/memory/memory.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/string_view.h" -#include "absl/synchronization/mutex.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -// The help message indicating that the commandline flag has been -// 'stripped'. It will not show up when doing "-help" and its -// variants. The flag is stripped if ABSL_FLAGS_STRIP_HELP is set to 1 -// before including absl/flags/flag.h -const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001"; - -namespace { - -// Currently we only validate flag values for user-defined flag types. -bool ShouldValidateFlagValue(FlagFastTypeId flag_type_id) { -#define DONT_VALIDATE(T, _) \ - if (flag_type_id == base_internal::FastTypeId<T>()) return false; - ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(DONT_VALIDATE) -#undef DONT_VALIDATE - - return true; -} - -// RAII helper used to temporarily unlock and relock `absl::Mutex`. -// This is used when we need to ensure that locks are released while -// invoking user supplied callbacks and then reacquired, since callbacks may -// need to acquire these locks themselves. -class MutexRelock { - public: - explicit MutexRelock(absl::Mutex& mu) : mu_(mu) { mu_.Unlock(); } - ~MutexRelock() { mu_.Lock(); } - - MutexRelock(const MutexRelock&) = delete; - MutexRelock& operator=(const MutexRelock&) = delete; - - private: - absl::Mutex& mu_; -}; - -} // namespace - -/////////////////////////////////////////////////////////////////////////////// -// Persistent state of the flag data. - -class FlagImpl; - -class FlagState : public flags_internal::FlagStateInterface { - public: - template <typename V> - FlagState(FlagImpl& flag_impl, const V& v, bool modified, - bool on_command_line, int64_t counter) - : flag_impl_(flag_impl), - value_(v), - modified_(modified), - on_command_line_(on_command_line), - counter_(counter) {} - - ~FlagState() override { - if (flag_impl_.ValueStorageKind() != FlagValueStorageKind::kAlignedBuffer) - return; - flags_internal::Delete(flag_impl_.op_, value_.heap_allocated); - } - - private: - friend class FlagImpl; - - // Restores the flag to the saved state. - void Restore() const override { - if (!flag_impl_.RestoreState(*this)) return; - - ABSL_INTERNAL_LOG(INFO, - absl::StrCat("Restore saved value of ", flag_impl_.Name(), - " to: ", flag_impl_.CurrentValue())); - } - - // Flag and saved flag data. - FlagImpl& flag_impl_; - union SavedValue { - explicit SavedValue(void* v) : heap_allocated(v) {} - explicit SavedValue(int64_t v) : one_word(v) {} - explicit SavedValue(flags_internal::AlignedTwoWords v) : two_words(v) {} - - void* heap_allocated; - int64_t one_word; - flags_internal::AlignedTwoWords two_words; - } value_; - bool modified_; - bool on_command_line_; - int64_t counter_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Flag implementation, which does not depend on flag value type. - -DynValueDeleter::DynValueDeleter(FlagOpFn op_arg) : op(op_arg) {} - -void DynValueDeleter::operator()(void* ptr) const { - if (op == nullptr) return; - - Delete(op, ptr); -} - -void FlagImpl::Init() { - new (&data_guard_) absl::Mutex; - - auto def_kind = static_cast<FlagDefaultKind>(def_kind_); - - switch (ValueStorageKind()) { - case FlagValueStorageKind::kAlignedBuffer: - // For this storage kind the default_value_ always points to gen_func - // during initialization. - assert(def_kind == FlagDefaultKind::kGenFunc); - (*default_value_.gen_func)(AlignedBufferValue()); - break; - case FlagValueStorageKind::kOneWordAtomic: { - alignas(int64_t) std::array<char, sizeof(int64_t)> buf{}; - if (def_kind == FlagDefaultKind::kGenFunc) { - (*default_value_.gen_func)(buf.data()); - } else { - assert(def_kind != FlagDefaultKind::kDynamicValue); - std::memcpy(buf.data(), &default_value_, Sizeof(op_)); - } - OneWordValue().store(absl::bit_cast<int64_t>(buf), - std::memory_order_release); - break; - } - case FlagValueStorageKind::kTwoWordsAtomic: { - // For this storage kind the default_value_ always points to gen_func - // during initialization. - assert(def_kind == FlagDefaultKind::kGenFunc); - alignas(AlignedTwoWords) std::array<char, sizeof(AlignedTwoWords)> buf{}; - (*default_value_.gen_func)(buf.data()); - auto atomic_value = absl::bit_cast<AlignedTwoWords>(buf); - TwoWordsValue().store(atomic_value, std::memory_order_release); - break; - } - } -} - -absl::Mutex* FlagImpl::DataGuard() const { - absl::call_once(const_cast<FlagImpl*>(this)->init_control_, &FlagImpl::Init, - const_cast<FlagImpl*>(this)); - - // data_guard_ is initialized inside Init. - return reinterpret_cast<absl::Mutex*>(&data_guard_); -} - -void FlagImpl::AssertValidType(FlagFastTypeId rhs_type_id, - const std::type_info* (*gen_rtti)()) const { - FlagFastTypeId lhs_type_id = flags_internal::FastTypeId(op_); - - // `rhs_type_id` is the fast type id corresponding to the declaration - // visibile at the call site. `lhs_type_id` is the fast type id - // corresponding to the type specified in flag definition. They must match - // for this operation to be well-defined. - if (ABSL_PREDICT_TRUE(lhs_type_id == rhs_type_id)) return; - - const std::type_info* lhs_runtime_type_id = - flags_internal::RuntimeTypeId(op_); - const std::type_info* rhs_runtime_type_id = (*gen_rtti)(); - - if (lhs_runtime_type_id == rhs_runtime_type_id) return; - -#if defined(ABSL_FLAGS_INTERNAL_HAS_RTTI) - if (*lhs_runtime_type_id == *rhs_runtime_type_id) return; -#endif - - ABSL_INTERNAL_LOG( - FATAL, absl::StrCat("Flag '", Name(), - "' is defined as one type and declared as another")); -} - -std::unique_ptr<void, DynValueDeleter> FlagImpl::MakeInitValue() const { - void* res = nullptr; - switch (DefaultKind()) { - case FlagDefaultKind::kDynamicValue: - res = flags_internal::Clone(op_, default_value_.dynamic_value); - break; - case FlagDefaultKind::kGenFunc: - res = flags_internal::Alloc(op_); - (*default_value_.gen_func)(res); - break; - default: - res = flags_internal::Clone(op_, &default_value_); - break; - } - return {res, DynValueDeleter{op_}}; -} - -void FlagImpl::StoreValue(const void* src) { - switch (ValueStorageKind()) { - case FlagValueStorageKind::kAlignedBuffer: - Copy(op_, src, AlignedBufferValue()); - break; - case FlagValueStorageKind::kOneWordAtomic: { - int64_t one_word_val = 0; - std::memcpy(&one_word_val, src, Sizeof(op_)); - OneWordValue().store(one_word_val, std::memory_order_release); - break; - } - case FlagValueStorageKind::kTwoWordsAtomic: { - AlignedTwoWords two_words_val{0, 0}; - std::memcpy(&two_words_val, src, Sizeof(op_)); - TwoWordsValue().store(two_words_val, std::memory_order_release); - break; - } - } - - modified_ = true; - ++counter_; - InvokeCallback(); -} - -absl::string_view FlagImpl::Name() const { return name_; } - -std::string FlagImpl::Filename() const { - return flags_internal::GetUsageConfig().normalize_filename(filename_); -} - -std::string FlagImpl::Help() const { - return HelpSourceKind() == FlagHelpKind::kLiteral ? help_.literal - : help_.gen_func(); -} - -FlagFastTypeId FlagImpl::TypeId() const { - return flags_internal::FastTypeId(op_); -} - -bool FlagImpl::IsSpecifiedOnCommandLine() const { - absl::MutexLock l(DataGuard()); - return on_command_line_; -} - -std::string FlagImpl::DefaultValue() const { - absl::MutexLock l(DataGuard()); - - auto obj = MakeInitValue(); - return flags_internal::Unparse(op_, obj.get()); -} - -std::string FlagImpl::CurrentValue() const { - auto* guard = DataGuard(); // Make sure flag initialized - switch (ValueStorageKind()) { - case FlagValueStorageKind::kAlignedBuffer: { - absl::MutexLock l(guard); - return flags_internal::Unparse(op_, AlignedBufferValue()); - } - case FlagValueStorageKind::kOneWordAtomic: { - const auto one_word_val = - absl::bit_cast<std::array<char, sizeof(int64_t)>>( - OneWordValue().load(std::memory_order_acquire)); - return flags_internal::Unparse(op_, one_word_val.data()); - } - case FlagValueStorageKind::kTwoWordsAtomic: { - const auto two_words_val = - absl::bit_cast<std::array<char, sizeof(AlignedTwoWords)>>( - TwoWordsValue().load(std::memory_order_acquire)); - return flags_internal::Unparse(op_, two_words_val.data()); - } - } - - return ""; -} - -void FlagImpl::SetCallback(const FlagCallbackFunc mutation_callback) { - absl::MutexLock l(DataGuard()); - - if (callback_ == nullptr) { - callback_ = new FlagCallback; - } - callback_->func = mutation_callback; - - InvokeCallback(); -} - -void FlagImpl::InvokeCallback() const { - if (!callback_) return; - - // Make a copy of the C-style function pointer that we are about to invoke - // before we release the lock guarding it. - FlagCallbackFunc cb = callback_->func; - - // If the flag has a mutation callback this function invokes it. While the - // callback is being invoked the primary flag's mutex is unlocked and it is - // re-locked back after call to callback is completed. Callback invocation is - // guarded by flag's secondary mutex instead which prevents concurrent - // callback invocation. Note that it is possible for other thread to grab the - // primary lock and update flag's value at any time during the callback - // invocation. This is by design. Callback can get a value of the flag if - // necessary, but it might be different from the value initiated the callback - // and it also can be different by the time the callback invocation is - // completed. Requires that *primary_lock be held in exclusive mode; it may be - // released and reacquired by the implementation. - MutexRelock relock(*DataGuard()); - absl::MutexLock lock(&callback_->guard); - cb(); -} - -std::unique_ptr<FlagStateInterface> FlagImpl::SaveState() { - absl::MutexLock l(DataGuard()); - - bool modified = modified_; - bool on_command_line = on_command_line_; - switch (ValueStorageKind()) { - case FlagValueStorageKind::kAlignedBuffer: { - return absl::make_unique<FlagState>( - *this, flags_internal::Clone(op_, AlignedBufferValue()), modified, - on_command_line, counter_); - } - case FlagValueStorageKind::kOneWordAtomic: { - return absl::make_unique<FlagState>( - *this, OneWordValue().load(std::memory_order_acquire), modified, - on_command_line, counter_); - } - case FlagValueStorageKind::kTwoWordsAtomic: { - return absl::make_unique<FlagState>( - *this, TwoWordsValue().load(std::memory_order_acquire), modified, - on_command_line, counter_); - } - } - return nullptr; -} - -bool FlagImpl::RestoreState(const FlagState& flag_state) { - absl::MutexLock l(DataGuard()); - - if (flag_state.counter_ == counter_) { - return false; - } - - switch (ValueStorageKind()) { - case FlagValueStorageKind::kAlignedBuffer: - StoreValue(flag_state.value_.heap_allocated); - break; - case FlagValueStorageKind::kOneWordAtomic: - StoreValue(&flag_state.value_.one_word); - break; - case FlagValueStorageKind::kTwoWordsAtomic: - StoreValue(&flag_state.value_.two_words); - break; - } - - modified_ = flag_state.modified_; - on_command_line_ = flag_state.on_command_line_; - - return true; -} - -template <typename StorageT> -StorageT* FlagImpl::OffsetValue() const { - char* p = reinterpret_cast<char*>(const_cast<FlagImpl*>(this)); - // The offset is deduced via Flag value type specific op_. - size_t offset = flags_internal::ValueOffset(op_); - - return reinterpret_cast<StorageT*>(p + offset); -} - -void* FlagImpl::AlignedBufferValue() const { - assert(ValueStorageKind() == FlagValueStorageKind::kAlignedBuffer); - return OffsetValue<void>(); -} - -std::atomic<int64_t>& FlagImpl::OneWordValue() const { - assert(ValueStorageKind() == FlagValueStorageKind::kOneWordAtomic); - return OffsetValue<FlagOneWordValue>()->value; -} - -std::atomic<AlignedTwoWords>& FlagImpl::TwoWordsValue() const { - assert(ValueStorageKind() == FlagValueStorageKind::kTwoWordsAtomic); - return OffsetValue<FlagTwoWordsValue>()->value; -} - -// Attempts to parse supplied `value` string using parsing routine in the `flag` -// argument. If parsing successful, this function replaces the dst with newly -// parsed value. In case if any error is encountered in either step, the error -// message is stored in 'err' -std::unique_ptr<void, DynValueDeleter> FlagImpl::TryParse( - absl::string_view value, std::string& err) const { - std::unique_ptr<void, DynValueDeleter> tentative_value = MakeInitValue(); - - std::string parse_err; - if (!flags_internal::Parse(op_, value, tentative_value.get(), &parse_err)) { - absl::string_view err_sep = parse_err.empty() ? "" : "; "; - err = absl::StrCat("Illegal value '", value, "' specified for flag '", - Name(), "'", err_sep, parse_err); - return nullptr; - } - - return tentative_value; -} - -void FlagImpl::Read(void* dst) const { - auto* guard = DataGuard(); // Make sure flag initialized - switch (ValueStorageKind()) { - case FlagValueStorageKind::kAlignedBuffer: { - absl::MutexLock l(guard); - flags_internal::CopyConstruct(op_, AlignedBufferValue(), dst); - break; - } - case FlagValueStorageKind::kOneWordAtomic: { - const int64_t one_word_val = - OneWordValue().load(std::memory_order_acquire); - std::memcpy(dst, &one_word_val, Sizeof(op_)); - break; - } - case FlagValueStorageKind::kTwoWordsAtomic: { - const AlignedTwoWords two_words_val = - TwoWordsValue().load(std::memory_order_acquire); - std::memcpy(dst, &two_words_val, Sizeof(op_)); - break; - } - } -} - -void FlagImpl::Write(const void* src) { - absl::MutexLock l(DataGuard()); - - if (ShouldValidateFlagValue(flags_internal::FastTypeId(op_))) { - std::unique_ptr<void, DynValueDeleter> obj{flags_internal::Clone(op_, src), - DynValueDeleter{op_}}; - std::string ignored_error; - std::string src_as_str = flags_internal::Unparse(op_, src); - if (!flags_internal::Parse(op_, src_as_str, obj.get(), &ignored_error)) { - ABSL_INTERNAL_LOG(ERROR, absl::StrCat("Attempt to set flag '", Name(), - "' to invalid value ", src_as_str)); - } - } - - StoreValue(src); -} - -// Sets the value of the flag based on specified string `value`. If the flag -// was successfully set to new value, it returns true. Otherwise, sets `err` -// to indicate the error, leaves the flag unchanged, and returns false. There -// are three ways to set the flag's value: -// * Update the current flag value -// * Update the flag's default value -// * Update the current flag value if it was never set before -// The mode is selected based on 'set_mode' parameter. -bool FlagImpl::ParseFrom(absl::string_view value, FlagSettingMode set_mode, - ValueSource source, std::string& err) { - absl::MutexLock l(DataGuard()); - - switch (set_mode) { - case SET_FLAGS_VALUE: { - // set or modify the flag's value - auto tentative_value = TryParse(value, err); - if (!tentative_value) return false; - - StoreValue(tentative_value.get()); - - if (source == kCommandLine) { - on_command_line_ = true; - } - break; - } - case SET_FLAG_IF_DEFAULT: { - // set the flag's value, but only if it hasn't been set by someone else - if (modified_) { - // TODO(rogeeff): review and fix this semantic. Currently we do not fail - // in this case if flag is modified. This is misleading since the flag's - // value is not updated even though we return true. - // *err = absl::StrCat(Name(), " is already set to ", - // CurrentValue(), "\n"); - // return false; - return true; - } - auto tentative_value = TryParse(value, err); - if (!tentative_value) return false; - - StoreValue(tentative_value.get()); - break; - } - case SET_FLAGS_DEFAULT: { - auto tentative_value = TryParse(value, err); - if (!tentative_value) return false; - - if (DefaultKind() == FlagDefaultKind::kDynamicValue) { - void* old_value = default_value_.dynamic_value; - default_value_.dynamic_value = tentative_value.release(); - tentative_value.reset(old_value); - } else { - default_value_.dynamic_value = tentative_value.release(); - def_kind_ = static_cast<uint8_t>(FlagDefaultKind::kDynamicValue); - } - - if (!modified_) { - // Need to set both default value *and* current, in this case. - StoreValue(default_value_.dynamic_value); - modified_ = false; - } - break; - } - } - - return true; -} - -void FlagImpl::CheckDefaultValueParsingRoundtrip() const { - std::string v = DefaultValue(); - - absl::MutexLock lock(DataGuard()); - - auto dst = MakeInitValue(); - std::string error; - if (!flags_internal::Parse(op_, v, dst.get(), &error)) { - ABSL_INTERNAL_LOG( - FATAL, - absl::StrCat("Flag ", Name(), " (from ", Filename(), - "): string form of default value '", v, - "' could not be parsed; error=", error)); - } - - // We do not compare dst to def since parsing/unparsing may make - // small changes, e.g., precision loss for floating point types. -} - -bool FlagImpl::ValidateInputValue(absl::string_view value) const { - absl::MutexLock l(DataGuard()); - - auto obj = MakeInitValue(); - std::string ignored_error; - return flags_internal::Parse(op_, value, obj.get(), &ignored_error); -} - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/flags/internal/flag.h b/third_party/abseil_cpp/absl/flags/internal/flag.h deleted file mode 100644 index 370d8a02ef04..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/flag.h +++ /dev/null @@ -1,775 +0,0 @@ -// -// 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. - -#ifndef ABSL_FLAGS_INTERNAL_FLAG_H_ -#define ABSL_FLAGS_INTERNAL_FLAG_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <atomic> -#include <cstring> -#include <memory> -#include <new> -#include <string> -#include <type_traits> -#include <typeinfo> - -#include "absl/base/attributes.h" -#include "absl/base/call_once.h" -#include "absl/base/config.h" -#include "absl/base/optimization.h" -#include "absl/base/thread_annotations.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/config.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/flags/internal/registry.h" -#include "absl/flags/marshalling.h" -#include "absl/meta/type_traits.h" -#include "absl/strings/string_view.h" -#include "absl/synchronization/mutex.h" -#include "absl/utility/utility.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -/////////////////////////////////////////////////////////////////////////////// -// Forward declaration of absl::Flag<T> public API. -namespace flags_internal { -template <typename T> -class Flag; -} // namespace flags_internal - -#if defined(_MSC_VER) && !defined(__clang__) -template <typename T> -class Flag; -#else -template <typename T> -using Flag = flags_internal::Flag<T>; -#endif - -template <typename T> -ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag<T>& flag); - -template <typename T> -void SetFlag(absl::Flag<T>* flag, const T& v); - -template <typename T, typename V> -void SetFlag(absl::Flag<T>* flag, const V& v); - -template <typename U> -const CommandLineFlag& GetFlagReflectionHandle(const absl::Flag<U>& f); - -/////////////////////////////////////////////////////////////////////////////// -// Flag value type operations, eg., parsing, copying, etc. are provided -// by function specific to that type with a signature matching FlagOpFn. - -namespace flags_internal { - -enum class FlagOp { - kAlloc, - kDelete, - kCopy, - kCopyConstruct, - kSizeof, - kFastTypeId, - kRuntimeTypeId, - kParse, - kUnparse, - kValueOffset, -}; -using FlagOpFn = void* (*)(FlagOp, const void*, void*, void*); - -// Forward declaration for Flag value specific operations. -template <typename T> -void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3); - -// Allocate aligned memory for a flag value. -inline void* Alloc(FlagOpFn op) { - return op(FlagOp::kAlloc, nullptr, nullptr, nullptr); -} -// Deletes memory interpreting obj as flag value type pointer. -inline void Delete(FlagOpFn op, void* obj) { - op(FlagOp::kDelete, nullptr, obj, nullptr); -} -// Copies src to dst interpreting as flag value type pointers. -inline void Copy(FlagOpFn op, const void* src, void* dst) { - op(FlagOp::kCopy, src, dst, nullptr); -} -// Construct a copy of flag value in a location pointed by dst -// based on src - pointer to the flag's value. -inline void CopyConstruct(FlagOpFn op, const void* src, void* dst) { - op(FlagOp::kCopyConstruct, src, dst, nullptr); -} -// Makes a copy of flag value pointed by obj. -inline void* Clone(FlagOpFn op, const void* obj) { - void* res = flags_internal::Alloc(op); - flags_internal::CopyConstruct(op, obj, res); - return res; -} -// Returns true if parsing of input text is successfull. -inline bool Parse(FlagOpFn op, absl::string_view text, void* dst, - std::string* error) { - return op(FlagOp::kParse, &text, dst, error) != nullptr; -} -// Returns string representing supplied value. -inline std::string Unparse(FlagOpFn op, const void* val) { - std::string result; - op(FlagOp::kUnparse, val, &result, nullptr); - return result; -} -// Returns size of flag value type. -inline size_t Sizeof(FlagOpFn op) { - // This sequence of casts reverses the sequence from - // `flags_internal::FlagOps()` - return static_cast<size_t>(reinterpret_cast<intptr_t>( - op(FlagOp::kSizeof, nullptr, nullptr, nullptr))); -} -// Returns fast type id coresponding to the value type. -inline FlagFastTypeId FastTypeId(FlagOpFn op) { - return reinterpret_cast<FlagFastTypeId>( - op(FlagOp::kFastTypeId, nullptr, nullptr, nullptr)); -} -// Returns fast type id coresponding to the value type. -inline const std::type_info* RuntimeTypeId(FlagOpFn op) { - return reinterpret_cast<const std::type_info*>( - op(FlagOp::kRuntimeTypeId, nullptr, nullptr, nullptr)); -} -// Returns offset of the field value_ from the field impl_ inside of -// absl::Flag<T> data. Given FlagImpl pointer p you can get the -// location of the corresponding value as: -// reinterpret_cast<char*>(p) + ValueOffset(). -inline ptrdiff_t ValueOffset(FlagOpFn op) { - // This sequence of casts reverses the sequence from - // `flags_internal::FlagOps()` - return static_cast<ptrdiff_t>(reinterpret_cast<intptr_t>( - op(FlagOp::kValueOffset, nullptr, nullptr, nullptr))); -} - -// Returns an address of RTTI's typeid(T). -template <typename T> -inline const std::type_info* GenRuntimeTypeId() { -#if defined(ABSL_FLAGS_INTERNAL_HAS_RTTI) - return &typeid(T); -#else - return nullptr; -#endif -} - -/////////////////////////////////////////////////////////////////////////////// -// Flag help auxiliary structs. - -// This is help argument for absl::Flag encapsulating the string literal pointer -// or pointer to function generating it as well as enum descriminating two -// cases. -using HelpGenFunc = std::string (*)(); - -template <size_t N> -struct FixedCharArray { - char value[N]; - - template <size_t... I> - static constexpr FixedCharArray<N> FromLiteralString( - absl::string_view str, absl::index_sequence<I...>) { - return (void)str, FixedCharArray<N>({{str[I]..., '\0'}}); - } -}; - -template <typename Gen, size_t N = Gen::Value().size()> -constexpr FixedCharArray<N + 1> HelpStringAsArray(int) { - return FixedCharArray<N + 1>::FromLiteralString( - Gen::Value(), absl::make_index_sequence<N>{}); -} - -template <typename Gen> -constexpr std::false_type HelpStringAsArray(char) { - return std::false_type{}; -} - -union FlagHelpMsg { - constexpr explicit FlagHelpMsg(const char* help_msg) : literal(help_msg) {} - constexpr explicit FlagHelpMsg(HelpGenFunc help_gen) : gen_func(help_gen) {} - - const char* literal; - HelpGenFunc gen_func; -}; - -enum class FlagHelpKind : uint8_t { kLiteral = 0, kGenFunc = 1 }; - -struct FlagHelpArg { - FlagHelpMsg source; - FlagHelpKind kind; -}; - -extern const char kStrippedFlagHelp[]; - -// These two HelpArg overloads allows us to select at compile time one of two -// way to pass Help argument to absl::Flag. We'll be passing -// AbslFlagHelpGenFor##name as Gen and integer 0 as a single argument to prefer -// first overload if possible. If help message is evaluatable on constexpr -// context We'll be able to make FixedCharArray out of it and we'll choose first -// overload. In this case the help message expression is immediately evaluated -// and is used to construct the absl::Flag. No additionl code is generated by -// ABSL_FLAG Otherwise SFINAE kicks in and first overload is dropped from the -// consideration, in which case the second overload will be used. The second -// overload does not attempt to evaluate the help message expression -// immediately and instead delays the evaluation by returing the function -// pointer (&T::NonConst) genering the help message when necessary. This is -// evaluatable in constexpr context, but the cost is an extra function being -// generated in the ABSL_FLAG code. -template <typename Gen, size_t N> -constexpr FlagHelpArg HelpArg(const FixedCharArray<N>& value) { - return {FlagHelpMsg(value.value), FlagHelpKind::kLiteral}; -} - -template <typename Gen> -constexpr FlagHelpArg HelpArg(std::false_type) { - return {FlagHelpMsg(&Gen::NonConst), FlagHelpKind::kGenFunc}; -} - -/////////////////////////////////////////////////////////////////////////////// -// Flag default value auxiliary structs. - -// Signature for the function generating the initial flag value (usually -// based on default value supplied in flag's definition) -using FlagDfltGenFunc = void (*)(void*); - -union FlagDefaultSrc { - constexpr explicit FlagDefaultSrc(FlagDfltGenFunc gen_func_arg) - : gen_func(gen_func_arg) {} - -#define ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE(T, name) \ - T name##_value; \ - constexpr explicit FlagDefaultSrc(T value) : name##_value(value) {} // NOLINT - ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE) -#undef ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE - - void* dynamic_value; - FlagDfltGenFunc gen_func; -}; - -enum class FlagDefaultKind : uint8_t { - kDynamicValue = 0, - kGenFunc = 1, - kOneWord = 2 // for default values UP to one word in size -}; - -struct FlagDefaultArg { - FlagDefaultSrc source; - FlagDefaultKind kind; -}; - -// This struct and corresponding overload to InitDefaultValue are used to -// facilitate usage of {} as default value in ABSL_FLAG macro. -// TODO(rogeeff): Fix handling types with explicit constructors. -struct EmptyBraces {}; - -template <typename T> -constexpr T InitDefaultValue(T t) { - return t; -} - -template <typename T> -constexpr T InitDefaultValue(EmptyBraces) { - return T{}; -} - -template <typename ValueT, typename GenT, - typename std::enable_if<std::is_integral<ValueT>::value, int>::type = - (GenT{}, 0)> -constexpr FlagDefaultArg DefaultArg(int) { - return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kOneWord}; -} - -template <typename ValueT, typename GenT> -constexpr FlagDefaultArg DefaultArg(char) { - return {FlagDefaultSrc(&GenT::Gen), FlagDefaultKind::kGenFunc}; -} - -/////////////////////////////////////////////////////////////////////////////// -// Flag current value auxiliary structs. - -constexpr int64_t UninitializedFlagValue() { return 0xababababababababll; } - -template <typename T> -using FlagUseOneWordStorage = std::integral_constant< - bool, absl::type_traits_internal::is_trivially_copyable<T>::value && - (sizeof(T) <= 8)>; - -#if defined(ABSL_FLAGS_INTERNAL_ATOMIC_DOUBLE_WORD) -// Clang does not always produce cmpxchg16b instruction when alignment of a 16 -// bytes type is not 16. -struct alignas(16) AlignedTwoWords { - int64_t first; - int64_t second; - - bool IsInitialized() const { - return first != flags_internal::UninitializedFlagValue(); - } -}; - -template <typename T> -using FlagUseTwoWordsStorage = std::integral_constant< - bool, absl::type_traits_internal::is_trivially_copyable<T>::value && - (sizeof(T) > 8) && (sizeof(T) <= 16)>; -#else -// This is actually unused and only here to avoid ifdefs in other palces. -struct AlignedTwoWords { - constexpr AlignedTwoWords() noexcept : dummy() {} - constexpr AlignedTwoWords(int64_t, int64_t) noexcept : dummy() {} - char dummy; - - bool IsInitialized() const { - std::abort(); - return true; - } -}; - -// This trait should be type dependent, otherwise SFINAE below will fail -template <typename T> -using FlagUseTwoWordsStorage = - std::integral_constant<bool, sizeof(T) != sizeof(T)>; -#endif - -template <typename T> -using FlagUseBufferStorage = - std::integral_constant<bool, !FlagUseOneWordStorage<T>::value && - !FlagUseTwoWordsStorage<T>::value>; - -enum class FlagValueStorageKind : uint8_t { - kAlignedBuffer = 0, - kOneWordAtomic = 1, - kTwoWordsAtomic = 2 -}; - -template <typename T> -static constexpr FlagValueStorageKind StorageKind() { - return FlagUseBufferStorage<T>::value - ? FlagValueStorageKind::kAlignedBuffer - : FlagUseOneWordStorage<T>::value - ? FlagValueStorageKind::kOneWordAtomic - : FlagValueStorageKind::kTwoWordsAtomic; -} - -struct FlagOneWordValue { - constexpr FlagOneWordValue() : value(UninitializedFlagValue()) {} - - std::atomic<int64_t> value; -}; - -struct FlagTwoWordsValue { - constexpr FlagTwoWordsValue() - : value(AlignedTwoWords{UninitializedFlagValue(), 0}) {} - - std::atomic<AlignedTwoWords> value; -}; - -template <typename T, - FlagValueStorageKind Kind = flags_internal::StorageKind<T>()> -struct FlagValue; - -template <typename T> -struct FlagValue<T, FlagValueStorageKind::kAlignedBuffer> { - bool Get(T&) const { return false; } - - alignas(T) char value[sizeof(T)]; -}; - -template <typename T> -struct FlagValue<T, FlagValueStorageKind::kOneWordAtomic> : FlagOneWordValue { - bool Get(T& dst) const { - int64_t one_word_val = value.load(std::memory_order_acquire); - if (ABSL_PREDICT_FALSE(one_word_val == UninitializedFlagValue())) { - return false; - } - std::memcpy(&dst, static_cast<const void*>(&one_word_val), sizeof(T)); - return true; - } -}; - -template <typename T> -struct FlagValue<T, FlagValueStorageKind::kTwoWordsAtomic> : FlagTwoWordsValue { - bool Get(T& dst) const { - AlignedTwoWords two_words_val = value.load(std::memory_order_acquire); - if (ABSL_PREDICT_FALSE(!two_words_val.IsInitialized())) { - return false; - } - std::memcpy(&dst, static_cast<const void*>(&two_words_val), sizeof(T)); - return true; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// Flag callback auxiliary structs. - -// Signature for the mutation callback used by watched Flags -// The callback is noexcept. -// TODO(rogeeff): add noexcept after C++17 support is added. -using FlagCallbackFunc = void (*)(); - -struct FlagCallback { - FlagCallbackFunc func; - absl::Mutex guard; // Guard for concurrent callback invocations. -}; - -/////////////////////////////////////////////////////////////////////////////// -// Flag implementation, which does not depend on flag value type. -// The class encapsulates the Flag's data and access to it. - -struct DynValueDeleter { - explicit DynValueDeleter(FlagOpFn op_arg = nullptr); - void operator()(void* ptr) const; - - FlagOpFn op; -}; - -class FlagState; - -class FlagImpl final : public CommandLineFlag { - public: - constexpr FlagImpl(const char* name, const char* filename, FlagOpFn op, - FlagHelpArg help, FlagValueStorageKind value_kind, - FlagDefaultArg default_arg) - : name_(name), - filename_(filename), - op_(op), - help_(help.source), - help_source_kind_(static_cast<uint8_t>(help.kind)), - value_storage_kind_(static_cast<uint8_t>(value_kind)), - def_kind_(static_cast<uint8_t>(default_arg.kind)), - modified_(false), - on_command_line_(false), - counter_(0), - callback_(nullptr), - default_value_(default_arg.source), - data_guard_{} {} - - // Constant access methods - void Read(void* dst) const override ABSL_LOCKS_EXCLUDED(*DataGuard()); - - // Mutating access methods - void Write(const void* src) ABSL_LOCKS_EXCLUDED(*DataGuard()); - - // Interfaces to operate on callbacks. - void SetCallback(const FlagCallbackFunc mutation_callback) - ABSL_LOCKS_EXCLUDED(*DataGuard()); - void InvokeCallback() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); - - // Used in read/write operations to validate source/target has correct type. - // For example if flag is declared as absl::Flag<int> FLAGS_foo, a call to - // absl::GetFlag(FLAGS_foo) validates that the type of FLAGS_foo is indeed - // int. To do that we pass the "assumed" type id (which is deduced from type - // int) as an argument `type_id`, which is in turn is validated against the - // type id stored in flag object by flag definition statement. - void AssertValidType(FlagFastTypeId type_id, - const std::type_info* (*gen_rtti)()) const; - - private: - template <typename T> - friend class Flag; - friend class FlagState; - - // Ensures that `data_guard_` is initialized and returns it. - absl::Mutex* DataGuard() const - ABSL_LOCK_RETURNED(reinterpret_cast<absl::Mutex*>(data_guard_)); - // Returns heap allocated value of type T initialized with default value. - std::unique_ptr<void, DynValueDeleter> MakeInitValue() const - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); - // Flag initialization called via absl::call_once. - void Init(); - - // Offset value access methods. One per storage kind. These methods to not - // respect const correctness, so be very carefull using them. - - // This is a shared helper routine which encapsulates most of the magic. Since - // it is only used inside the three routines below, which are defined in - // flag.cc, we can define it in that file as well. - template <typename StorageT> - StorageT* OffsetValue() const; - // This is an accessor for a value stored in an aligned buffer storage. - // Returns a mutable pointer to the start of a buffer. - void* AlignedBufferValue() const; - // This is an accessor for a value stored as one word atomic. Returns a - // mutable reference to an atomic value. - std::atomic<int64_t>& OneWordValue() const; - // This is an accessor for a value stored as two words atomic. Returns a - // mutable reference to an atomic value. - std::atomic<AlignedTwoWords>& TwoWordsValue() const; - - // Attempts to parse supplied `value` string. If parsing is successful, - // returns new value. Otherwise returns nullptr. - std::unique_ptr<void, DynValueDeleter> TryParse(absl::string_view value, - std::string& err) const - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); - // Stores the flag value based on the pointer to the source. - void StoreValue(const void* src) ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); - - FlagHelpKind HelpSourceKind() const { - return static_cast<FlagHelpKind>(help_source_kind_); - } - FlagValueStorageKind ValueStorageKind() const { - return static_cast<FlagValueStorageKind>(value_storage_kind_); - } - FlagDefaultKind DefaultKind() const - ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()) { - return static_cast<FlagDefaultKind>(def_kind_); - } - - // CommandLineFlag interface implementation - absl::string_view Name() const override; - std::string Filename() const override; - std::string Help() const override; - FlagFastTypeId TypeId() const override; - bool IsSpecifiedOnCommandLine() const override - ABSL_LOCKS_EXCLUDED(*DataGuard()); - std::string DefaultValue() const override ABSL_LOCKS_EXCLUDED(*DataGuard()); - std::string CurrentValue() const override ABSL_LOCKS_EXCLUDED(*DataGuard()); - bool ValidateInputValue(absl::string_view value) const override - ABSL_LOCKS_EXCLUDED(*DataGuard()); - void CheckDefaultValueParsingRoundtrip() const override - ABSL_LOCKS_EXCLUDED(*DataGuard()); - - // Interfaces to save and restore flags to/from persistent state. - // Returns current flag state or nullptr if flag does not support - // saving and restoring a state. - std::unique_ptr<FlagStateInterface> SaveState() override - ABSL_LOCKS_EXCLUDED(*DataGuard()); - - // Restores the flag state to the supplied state object. If there is - // nothing to restore returns false. Otherwise returns true. - bool RestoreState(const FlagState& flag_state) - ABSL_LOCKS_EXCLUDED(*DataGuard()); - - bool ParseFrom(absl::string_view value, FlagSettingMode set_mode, - ValueSource source, std::string& error) override - ABSL_LOCKS_EXCLUDED(*DataGuard()); - - // Immutable flag's state. - - // Flags name passed to ABSL_FLAG as second arg. - const char* const name_; - // The file name where ABSL_FLAG resides. - const char* const filename_; - // Type-specific operations "vtable". - const FlagOpFn op_; - // Help message literal or function to generate it. - const FlagHelpMsg help_; - // Indicates if help message was supplied as literal or generator func. - const uint8_t help_source_kind_ : 1; - // Kind of storage this flag is using for the flag's value. - const uint8_t value_storage_kind_ : 2; - - uint8_t : 0; // The bytes containing the const bitfields must not be - // shared with bytes containing the mutable bitfields. - - // Mutable flag's state (guarded by `data_guard_`). - - // def_kind_ is not guard by DataGuard() since it is accessed in Init without - // locks. - uint8_t def_kind_ : 2; - // Has this flag's value been modified? - bool modified_ : 1 ABSL_GUARDED_BY(*DataGuard()); - // Has this flag been specified on command line. - bool on_command_line_ : 1 ABSL_GUARDED_BY(*DataGuard()); - - // Unique tag for absl::call_once call to initialize this flag. - absl::once_flag init_control_; - - // Mutation counter - int64_t counter_ ABSL_GUARDED_BY(*DataGuard()); - // Optional flag's callback and absl::Mutex to guard the invocations. - FlagCallback* callback_ ABSL_GUARDED_BY(*DataGuard()); - // Either a pointer to the function generating the default value based on the - // value specified in ABSL_FLAG or pointer to the dynamically set default - // value via SetCommandLineOptionWithMode. def_kind_ is used to distinguish - // these two cases. - FlagDefaultSrc default_value_; - - // This is reserved space for an absl::Mutex to guard flag data. It will be - // initialized in FlagImpl::Init via placement new. - // We can't use "absl::Mutex data_guard_", since this class is not literal. - // We do not want to use "absl::Mutex* data_guard_", since this would require - // heap allocation during initialization, which is both slows program startup - // and can fail. Using reserved space + placement new allows us to avoid both - // problems. - alignas(absl::Mutex) mutable char data_guard_[sizeof(absl::Mutex)]; -}; - -/////////////////////////////////////////////////////////////////////////////// -// The Flag object parameterized by the flag's value type. This class implements -// flag reflection handle interface. - -template <typename T> -class Flag { - public: - constexpr Flag(const char* name, const char* filename, FlagHelpArg help, - const FlagDefaultArg default_arg) - : impl_(name, filename, &FlagOps<T>, help, - flags_internal::StorageKind<T>(), default_arg), - value_() {} - - // CommandLineFlag interface - absl::string_view Name() const { return impl_.Name(); } - std::string Filename() const { return impl_.Filename(); } - std::string Help() const { return impl_.Help(); } - // Do not use. To be removed. - bool IsSpecifiedOnCommandLine() const { - return impl_.IsSpecifiedOnCommandLine(); - } - std::string DefaultValue() const { return impl_.DefaultValue(); } - std::string CurrentValue() const { return impl_.CurrentValue(); } - - private: - template <typename, bool> - friend class FlagRegistrar; - friend class FlagImplPeer; - - T Get() const { - // See implementation notes in CommandLineFlag::Get(). - union U { - T value; - U() {} - ~U() { value.~T(); } - }; - U u; - -#if !defined(NDEBUG) - impl_.AssertValidType(base_internal::FastTypeId<T>(), &GenRuntimeTypeId<T>); -#endif - - if (!value_.Get(u.value)) impl_.Read(&u.value); - return std::move(u.value); - } - void Set(const T& v) { - impl_.AssertValidType(base_internal::FastTypeId<T>(), &GenRuntimeTypeId<T>); - impl_.Write(&v); - } - - // Access to the reflection. - const CommandLineFlag& Reflect() const { return impl_; } - - // Flag's data - // The implementation depends on value_ field to be placed exactly after the - // impl_ field, so that impl_ can figure out the offset to the value and - // access it. - FlagImpl impl_; - FlagValue<T> value_; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Trampoline for friend access - -class FlagImplPeer { - public: - template <typename T, typename FlagType> - static T InvokeGet(const FlagType& flag) { - return flag.Get(); - } - template <typename FlagType, typename T> - static void InvokeSet(FlagType& flag, const T& v) { - flag.Set(v); - } - template <typename FlagType> - static const CommandLineFlag& InvokeReflect(const FlagType& f) { - return f.Reflect(); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// Implementation of Flag value specific operations routine. -template <typename T> -void* FlagOps(FlagOp op, const void* v1, void* v2, void* v3) { - switch (op) { - case FlagOp::kAlloc: { - std::allocator<T> alloc; - return std::allocator_traits<std::allocator<T>>::allocate(alloc, 1); - } - case FlagOp::kDelete: { - T* p = static_cast<T*>(v2); - p->~T(); - std::allocator<T> alloc; - std::allocator_traits<std::allocator<T>>::deallocate(alloc, p, 1); - return nullptr; - } - case FlagOp::kCopy: - *static_cast<T*>(v2) = *static_cast<const T*>(v1); - return nullptr; - case FlagOp::kCopyConstruct: - new (v2) T(*static_cast<const T*>(v1)); - return nullptr; - case FlagOp::kSizeof: - return reinterpret_cast<void*>(static_cast<uintptr_t>(sizeof(T))); - case FlagOp::kFastTypeId: - return const_cast<void*>(base_internal::FastTypeId<T>()); - case FlagOp::kRuntimeTypeId: - return const_cast<std::type_info*>(GenRuntimeTypeId<T>()); - case FlagOp::kParse: { - // Initialize the temporary instance of type T based on current value in - // destination (which is going to be flag's default value). - T temp(*static_cast<T*>(v2)); - if (!absl::ParseFlag<T>(*static_cast<const absl::string_view*>(v1), &temp, - static_cast<std::string*>(v3))) { - return nullptr; - } - *static_cast<T*>(v2) = std::move(temp); - return v2; - } - case FlagOp::kUnparse: - *static_cast<std::string*>(v2) = - absl::UnparseFlag<T>(*static_cast<const T*>(v1)); - return nullptr; - case FlagOp::kValueOffset: { - // Round sizeof(FlagImp) to a multiple of alignof(FlagValue<T>) to get the - // offset of the data. - ptrdiff_t round_to = alignof(FlagValue<T>); - ptrdiff_t offset = - (sizeof(FlagImpl) + round_to - 1) / round_to * round_to; - return reinterpret_cast<void*>(offset); - } - } - return nullptr; -} - -/////////////////////////////////////////////////////////////////////////////// -// This class facilitates Flag object registration and tail expression-based -// flag definition, for example: -// ABSL_FLAG(int, foo, 42, "Foo help").OnUpdate(NotifyFooWatcher); -struct FlagRegistrarEmpty {}; -template <typename T, bool do_register> -class FlagRegistrar { - public: - explicit FlagRegistrar(Flag<T>& flag) : flag_(flag) { - if (do_register) flags_internal::RegisterCommandLineFlag(flag_.impl_); - } - - FlagRegistrar OnUpdate(FlagCallbackFunc cb) && { - flag_.impl_.SetCallback(cb); - return *this; - } - - // Make the registrar "die" gracefully as an empty struct on a line where - // registration happens. Registrar objects are intended to live only as - // temporary. - operator FlagRegistrarEmpty() const { return {}; } // NOLINT - - private: - Flag<T>& flag_; // Flag being registered (not owned). -}; - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FLAGS_INTERNAL_FLAG_H_ diff --git a/third_party/abseil_cpp/absl/flags/internal/parse.h b/third_party/abseil_cpp/absl/flags/internal/parse.h deleted file mode 100644 index de706c898470..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/parse.h +++ /dev/null @@ -1,59 +0,0 @@ -// -// 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. - -#ifndef ABSL_FLAGS_INTERNAL_PARSE_H_ -#define ABSL_FLAGS_INTERNAL_PARSE_H_ - -#include <string> -#include <vector> - -#include "absl/base/config.h" -#include "absl/flags/declare.h" -#include "absl/strings/string_view.h" - -ABSL_DECLARE_FLAG(std::vector<std::string>, flagfile); -ABSL_DECLARE_FLAG(std::vector<std::string>, fromenv); -ABSL_DECLARE_FLAG(std::vector<std::string>, tryfromenv); -ABSL_DECLARE_FLAG(std::vector<std::string>, undefok); - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -enum class ArgvListAction { kRemoveParsedArgs, kKeepParsedArgs }; -enum class UsageFlagsAction { kHandleUsage, kIgnoreUsage }; -enum class OnUndefinedFlag { - kIgnoreUndefined, - kReportUndefined, - kAbortIfUndefined -}; - -std::vector<char*> ParseCommandLineImpl(int argc, char* argv[], - ArgvListAction arg_list_act, - UsageFlagsAction usage_flag_act, - OnUndefinedFlag on_undef_flag); - -// -------------------------------------------------------------------- -// Inspect original command line - -// Returns true if flag with specified name was either present on the original -// command line or specified in flag file present on the original command line. -bool WasPresentOnCommandLine(absl::string_view flag_name); - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FLAGS_INTERNAL_PARSE_H_ diff --git a/third_party/abseil_cpp/absl/flags/internal/path_util.h b/third_party/abseil_cpp/absl/flags/internal/path_util.h deleted file mode 100644 index a6594d3347e1..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/path_util.h +++ /dev/null @@ -1,62 +0,0 @@ -// -// 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. - -#ifndef ABSL_FLAGS_INTERNAL_PATH_UTIL_H_ -#define ABSL_FLAGS_INTERNAL_PATH_UTIL_H_ - -#include "absl/base/config.h" -#include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -// A portable interface that returns the basename of the filename passed as an -// argument. It is similar to basename(3) -// <https://linux.die.net/man/3/basename>. -// For example: -// flags_internal::Basename("a/b/prog/file.cc") -// returns "file.cc" -// flags_internal::Basename("file.cc") -// returns "file.cc" -inline absl::string_view Basename(absl::string_view filename) { - auto last_slash_pos = filename.find_last_of("/\\"); - - return last_slash_pos == absl::string_view::npos - ? filename - : filename.substr(last_slash_pos + 1); -} - -// A portable interface that returns the directory name of the filename -// passed as an argument, including the trailing slash. -// Returns the empty string if a slash is not found in the input file name. -// For example: -// flags_internal::Package("a/b/prog/file.cc") -// returns "a/b/prog/" -// flags_internal::Package("file.cc") -// returns "" -inline absl::string_view Package(absl::string_view filename) { - auto last_slash_pos = filename.find_last_of("/\\"); - - return last_slash_pos == absl::string_view::npos - ? absl::string_view() - : filename.substr(0, last_slash_pos + 1); -} - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FLAGS_INTERNAL_PATH_UTIL_H_ diff --git a/third_party/abseil_cpp/absl/flags/internal/path_util_test.cc b/third_party/abseil_cpp/absl/flags/internal/path_util_test.cc deleted file mode 100644 index 2091373c88ea..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/path_util_test.cc +++ /dev/null @@ -1,46 +0,0 @@ -// -// 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/internal/path_util.h" - -#include "gtest/gtest.h" - -namespace { - -namespace flags = absl::flags_internal; - -TEST(FlagsPathUtilTest, TestBasename) { - EXPECT_EQ(flags::Basename(""), ""); - EXPECT_EQ(flags::Basename("a.cc"), "a.cc"); - EXPECT_EQ(flags::Basename("dir/a.cc"), "a.cc"); - EXPECT_EQ(flags::Basename("dir1/dir2/a.cc"), "a.cc"); - EXPECT_EQ(flags::Basename("../dir1/dir2/a.cc"), "a.cc"); - EXPECT_EQ(flags::Basename("/dir1/dir2/a.cc"), "a.cc"); - EXPECT_EQ(flags::Basename("/dir1/dir2/../dir3/a.cc"), "a.cc"); -} - -// -------------------------------------------------------------------- - -TEST(FlagsPathUtilTest, TestPackage) { - EXPECT_EQ(flags::Package(""), ""); - EXPECT_EQ(flags::Package("a.cc"), ""); - EXPECT_EQ(flags::Package("dir/a.cc"), "dir/"); - EXPECT_EQ(flags::Package("dir1/dir2/a.cc"), "dir1/dir2/"); - EXPECT_EQ(flags::Package("../dir1/dir2/a.cc"), "../dir1/dir2/"); - EXPECT_EQ(flags::Package("/dir1/dir2/a.cc"), "/dir1/dir2/"); - EXPECT_EQ(flags::Package("/dir1/dir2/../dir3/a.cc"), "/dir1/dir2/../dir3/"); -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.cc b/third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.cc deleted file mode 100644 index a7eb58b6d45f..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.cc +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright 2020 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/internal/private_handle_accessor.h" - -#include <memory> -#include <string> - -#include "absl/base/config.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -FlagFastTypeId PrivateHandleAccessor::TypeId(const CommandLineFlag& flag) { - return flag.TypeId(); -} - -std::unique_ptr<FlagStateInterface> PrivateHandleAccessor::SaveState( - CommandLineFlag& flag) { - return flag.SaveState(); -} - -bool PrivateHandleAccessor::IsSpecifiedOnCommandLine( - const CommandLineFlag& flag) { - return flag.IsSpecifiedOnCommandLine(); -} - -bool PrivateHandleAccessor::ValidateInputValue(const CommandLineFlag& flag, - absl::string_view value) { - return flag.ValidateInputValue(value); -} - -void PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip( - const CommandLineFlag& flag) { - flag.CheckDefaultValueParsingRoundtrip(); -} - -bool PrivateHandleAccessor::ParseFrom(CommandLineFlag& flag, - absl::string_view value, - flags_internal::FlagSettingMode set_mode, - flags_internal::ValueSource source, - std::string& error) { - return flag.ParseFrom(value, set_mode, source, error); -} - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl - diff --git a/third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.h b/third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.h deleted file mode 100644 index c64435cd6199..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/private_handle_accessor.h +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright 2020 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. - -#ifndef ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_ -#define ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_ - -#include <memory> -#include <string> - -#include "absl/base/config.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/strings/string_view.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -// This class serves as a trampoline to access private methods of -// CommandLineFlag. This class is intended for use exclusively internally inside -// of the Abseil Flags implementation. -class PrivateHandleAccessor { - public: - // Access to CommandLineFlag::TypeId. - static FlagFastTypeId TypeId(const CommandLineFlag& flag); - - // Access to CommandLineFlag::SaveState. - static std::unique_ptr<FlagStateInterface> SaveState(CommandLineFlag& flag); - - // Access to CommandLineFlag::IsSpecifiedOnCommandLine. - static bool IsSpecifiedOnCommandLine(const CommandLineFlag& flag); - - // Access to CommandLineFlag::ValidateInputValue. - static bool ValidateInputValue(const CommandLineFlag& flag, - absl::string_view value); - - // Access to CommandLineFlag::CheckDefaultValueParsingRoundtrip. - static void CheckDefaultValueParsingRoundtrip(const CommandLineFlag& flag); - - static bool ParseFrom(CommandLineFlag& flag, absl::string_view value, - flags_internal::FlagSettingMode set_mode, - flags_internal::ValueSource source, std::string& error); -}; - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FLAGS_INTERNAL_PRIVATE_HANDLE_ACCESSOR_H_ diff --git a/third_party/abseil_cpp/absl/flags/internal/program_name.cc b/third_party/abseil_cpp/absl/flags/internal/program_name.cc deleted file mode 100644 index 51d698da8b31..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/program_name.cc +++ /dev/null @@ -1,60 +0,0 @@ -// -// 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/internal/program_name.h" - -#include <string> - -#include "absl/base/attributes.h" -#include "absl/base/config.h" -#include "absl/base/const_init.h" -#include "absl/base/thread_annotations.h" -#include "absl/flags/internal/path_util.h" -#include "absl/strings/string_view.h" -#include "absl/synchronization/mutex.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -ABSL_CONST_INIT static absl::Mutex program_name_guard(absl::kConstInit); -ABSL_CONST_INIT static std::string* program_name - ABSL_GUARDED_BY(program_name_guard) = nullptr; - -std::string ProgramInvocationName() { - absl::MutexLock l(&program_name_guard); - - return program_name ? *program_name : "UNKNOWN"; -} - -std::string ShortProgramInvocationName() { - absl::MutexLock l(&program_name_guard); - - return program_name ? std::string(flags_internal::Basename(*program_name)) - : "UNKNOWN"; -} - -void SetProgramInvocationName(absl::string_view prog_name_str) { - absl::MutexLock l(&program_name_guard); - - if (!program_name) - program_name = new std::string(prog_name_str); - else - program_name->assign(prog_name_str.data(), prog_name_str.size()); -} - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/flags/internal/program_name.h b/third_party/abseil_cpp/absl/flags/internal/program_name.h deleted file mode 100644 index b99b94fe18ab..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/program_name.h +++ /dev/null @@ -1,50 +0,0 @@ -// -// 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. - -#ifndef ABSL_FLAGS_INTERNAL_PROGRAM_NAME_H_ -#define ABSL_FLAGS_INTERNAL_PROGRAM_NAME_H_ - -#include <string> - -#include "absl/base/config.h" -#include "absl/strings/string_view.h" - -// -------------------------------------------------------------------- -// Program name - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -// Returns program invocation name or "UNKNOWN" if `SetProgramInvocationName()` -// is never called. At the moment this is always set to argv[0] as part of -// library initialization. -std::string ProgramInvocationName(); - -// Returns base name for program invocation name. For example, if -// ProgramInvocationName() == "a/b/mybinary" -// then -// ShortProgramInvocationName() == "mybinary" -std::string ShortProgramInvocationName(); - -// Sets program invocation name to a new value. Should only be called once -// during program initialization, before any threads are spawned. -void SetProgramInvocationName(absl::string_view prog_name_str); - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FLAGS_INTERNAL_PROGRAM_NAME_H_ diff --git a/third_party/abseil_cpp/absl/flags/internal/program_name_test.cc b/third_party/abseil_cpp/absl/flags/internal/program_name_test.cc deleted file mode 100644 index aff9f6315e4e..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/program_name_test.cc +++ /dev/null @@ -1,61 +0,0 @@ -// -// 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/internal/program_name.h" - -#include <string> - -#include "gtest/gtest.h" -#include "absl/strings/match.h" -#include "absl/strings/string_view.h" - -namespace { - -namespace flags = absl::flags_internal; - -TEST(FlagsPathUtilTest, TestProgamNameInterfaces) { - flags::SetProgramInvocationName("absl/flags/program_name_test"); - std::string program_name = flags::ProgramInvocationName(); - for (char& c : program_name) - if (c == '\\') c = '/'; - -#if !defined(__wasm__) && !defined(__asmjs__) - const std::string expect_name = "absl/flags/program_name_test"; - const std::string expect_basename = "program_name_test"; -#else - // For targets that generate javascript or webassembly the invocation name - // has the special value below. - const std::string expect_name = "this.program"; - const std::string expect_basename = "this.program"; -#endif - - EXPECT_TRUE(absl::EndsWith(program_name, expect_name)) << program_name; - EXPECT_EQ(flags::ShortProgramInvocationName(), expect_basename); - - flags::SetProgramInvocationName("a/my_test"); - - EXPECT_EQ(flags::ProgramInvocationName(), "a/my_test"); - EXPECT_EQ(flags::ShortProgramInvocationName(), "my_test"); - - absl::string_view not_null_terminated("absl/aaa/bbb"); - not_null_terminated = not_null_terminated.substr(1, 10); - - flags::SetProgramInvocationName(not_null_terminated); - - EXPECT_EQ(flags::ProgramInvocationName(), "bsl/aaa/bb"); - EXPECT_EQ(flags::ShortProgramInvocationName(), "bb"); -} - -} // namespace diff --git a/third_party/abseil_cpp/absl/flags/internal/registry.h b/third_party/abseil_cpp/absl/flags/internal/registry.h deleted file mode 100644 index a8d9eb9cb0bb..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/registry.h +++ /dev/null @@ -1,97 +0,0 @@ -// -// 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. - -#ifndef ABSL_FLAGS_INTERNAL_REGISTRY_H_ -#define ABSL_FLAGS_INTERNAL_REGISTRY_H_ - -#include <functional> - -#include "absl/base/config.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/internal/commandlineflag.h" -#include "absl/strings/string_view.h" - -// -------------------------------------------------------------------- -// Global flags registry API. - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -// Executes specified visitor for each non-retired flag in the registry. While -// callback are executed, the registry is locked and can't be changed. -void ForEachFlag(std::function<void(CommandLineFlag&)> visitor); - -//----------------------------------------------------------------------------- - -bool RegisterCommandLineFlag(CommandLineFlag&); - -void FinalizeRegistry(); - -//----------------------------------------------------------------------------- -// Retired registrations: -// -// Retired flag registrations are treated specially. A 'retired' flag is -// provided only for compatibility with automated invocations that still -// name it. A 'retired' flag: -// - is not bound to a C++ FLAGS_ reference. -// - has a type and a value, but that value is intentionally inaccessible. -// - does not appear in --help messages. -// - is fully supported by _all_ flag parsing routines. -// - consumes args normally, and complains about type mismatches in its -// argument. -// - emits a complaint but does not die (e.g. LOG(ERROR)) if it is -// accessed by name through the flags API for parsing or otherwise. -// -// The registrations for a flag happen in an unspecified order as the -// initializers for the namespace-scope objects of a program are run. -// Any number of weak registrations for a flag can weakly define the flag. -// One non-weak registration will upgrade the flag from weak to non-weak. -// Further weak registrations of a non-weak flag are ignored. -// -// This mechanism is designed to support moving dead flags into a -// 'graveyard' library. An example migration: -// -// 0: Remove references to this FLAGS_flagname in the C++ codebase. -// 1: Register as 'retired' in old_lib. -// 2: Make old_lib depend on graveyard. -// 3: Add a redundant 'retired' registration to graveyard. -// 4: Remove the old_lib 'retired' registration. -// 5: Eventually delete the graveyard registration entirely. -// - -// Retire flag with name "name" and type indicated by ops. -void Retire(const char* name, FlagFastTypeId type_id, char* buf); - -constexpr size_t kRetiredFlagObjSize = 3 * sizeof(void*); -constexpr size_t kRetiredFlagObjAlignment = alignof(void*); - -// Registered a retired flag with name 'flag_name' and type 'T'. -template <typename T> -class RetiredFlag { - public: - void Retire(const char* flag_name) { - flags_internal::Retire(flag_name, base_internal::FastTypeId<T>(), buf_); - } - - private: - alignas(kRetiredFlagObjAlignment) char buf_[kRetiredFlagObjSize]; -}; - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FLAGS_INTERNAL_REGISTRY_H_ diff --git a/third_party/abseil_cpp/absl/flags/internal/usage.cc b/third_party/abseil_cpp/absl/flags/internal/usage.cc deleted file mode 100644 index f29d7c9b48f0..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/usage.cc +++ /dev/null @@ -1,524 +0,0 @@ -// -// 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/internal/usage.h" - -#include <stdint.h> - -#include <functional> -#include <map> -#include <ostream> -#include <string> -#include <utility> -#include <vector> - -#include "absl/base/config.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/flag.h" -#include "absl/flags/internal/flag.h" -#include "absl/flags/internal/path_util.h" -#include "absl/flags/internal/private_handle_accessor.h" -#include "absl/flags/internal/program_name.h" -#include "absl/flags/internal/registry.h" -#include "absl/flags/usage_config.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_split.h" -#include "absl/strings/string_view.h" - -// Dummy global variables to prevent anyone else defining these. -bool FLAGS_help = false; -bool FLAGS_helpfull = false; -bool FLAGS_helpshort = false; -bool FLAGS_helppackage = false; -bool FLAGS_version = false; -bool FLAGS_only_check_args = false; -bool FLAGS_helpon = false; -bool FLAGS_helpmatch = false; - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { -namespace { - -using PerFlagFilter = std::function<bool(const absl::CommandLineFlag&)>; - -// Maximum length size in a human readable format. -constexpr size_t kHrfMaxLineLength = 80; - -// This class is used to emit an XML element with `tag` and `text`. -// It adds opening and closing tags and escapes special characters in the text. -// For example: -// std::cout << XMLElement("title", "Milk & Cookies"); -// prints "<title>Milk & Cookies</title>" -class XMLElement { - public: - XMLElement(absl::string_view tag, absl::string_view txt) - : tag_(tag), txt_(txt) {} - - friend std::ostream& operator<<(std::ostream& out, - const XMLElement& xml_elem) { - out << "<" << xml_elem.tag_ << ">"; - - for (auto c : xml_elem.txt_) { - switch (c) { - case '"': - out << """; - break; - case '\'': - out << "'"; - break; - case '&': - out << "&"; - break; - case '<': - out << "<"; - break; - case '>': - out << ">"; - break; - default: - out << c; - break; - } - } - - return out << "</" << xml_elem.tag_ << ">"; - } - - private: - absl::string_view tag_; - absl::string_view txt_; -}; - -// -------------------------------------------------------------------- -// Helper class to pretty-print info about a flag. - -class FlagHelpPrettyPrinter { - public: - // Pretty printer holds on to the std::ostream& reference to direct an output - // to that stream. - FlagHelpPrettyPrinter(size_t max_line_len, size_t min_line_len, - size_t wrapped_line_indent, std::ostream& out) - : out_(out), - max_line_len_(max_line_len), - min_line_len_(min_line_len), - wrapped_line_indent_(wrapped_line_indent), - line_len_(0), - first_line_(true) {} - - void Write(absl::string_view str, bool wrap_line = false) { - // Empty string - do nothing. - if (str.empty()) return; - - std::vector<absl::string_view> tokens; - if (wrap_line) { - for (auto line : absl::StrSplit(str, absl::ByAnyChar("\n\r"))) { - if (!tokens.empty()) { - // Keep line separators in the input string. - tokens.push_back("\n"); - } - for (auto token : - absl::StrSplit(line, absl::ByAnyChar(" \t"), absl::SkipEmpty())) { - tokens.push_back(token); - } - } - } else { - tokens.push_back(str); - } - - for (auto token : tokens) { - bool new_line = (line_len_ == 0); - - // Respect line separators in the input string. - if (token == "\n") { - EndLine(); - continue; - } - - // Write the token, ending the string first if necessary/possible. - if (!new_line && - (line_len_ + static_cast<int>(token.size()) >= max_line_len_)) { - EndLine(); - new_line = true; - } - - if (new_line) { - StartLine(); - } else { - out_ << ' '; - ++line_len_; - } - - out_ << token; - line_len_ += token.size(); - } - } - - void StartLine() { - if (first_line_) { - line_len_ = min_line_len_; - first_line_ = false; - } else { - line_len_ = min_line_len_ + wrapped_line_indent_; - } - out_ << std::string(line_len_, ' '); - } - void EndLine() { - out_ << '\n'; - line_len_ = 0; - } - - private: - std::ostream& out_; - const size_t max_line_len_; - const size_t min_line_len_; - const size_t wrapped_line_indent_; - size_t line_len_; - bool first_line_; -}; - -void FlagHelpHumanReadable(const CommandLineFlag& flag, std::ostream& out) { - FlagHelpPrettyPrinter printer(kHrfMaxLineLength, 4, 2, out); - - // Flag name. - printer.Write(absl::StrCat("--", flag.Name())); - - // Flag help. - printer.Write(absl::StrCat("(", flag.Help(), ");"), /*wrap_line=*/true); - - // The listed default value will be the actual default from the flag - // definition in the originating source file, unless the value has - // subsequently been modified using SetCommandLineOption() with mode - // SET_FLAGS_DEFAULT. - std::string dflt_val = flag.DefaultValue(); - std::string curr_val = flag.CurrentValue(); - bool is_modified = curr_val != dflt_val; - - if (flag.IsOfType<std::string>()) { - dflt_val = absl::StrCat("\"", dflt_val, "\""); - } - printer.Write(absl::StrCat("default: ", dflt_val, ";")); - - if (is_modified) { - if (flag.IsOfType<std::string>()) { - curr_val = absl::StrCat("\"", curr_val, "\""); - } - printer.Write(absl::StrCat("currently: ", curr_val, ";")); - } - - printer.EndLine(); -} - -// Shows help for every filename which matches any of the filters -// If filters are empty, shows help for every file. -// If a flag's help message has been stripped (e.g. by adding '#define -// STRIP_FLAG_HELP 1' then this flag will not be displayed by '--help' -// and its variants. -void FlagsHelpImpl(std::ostream& out, PerFlagFilter filter_cb, - HelpFormat format, absl::string_view program_usage_message) { - if (format == HelpFormat::kHumanReadable) { - out << flags_internal::ShortProgramInvocationName() << ": " - << program_usage_message << "\n\n"; - } else { - // XML schema is not a part of our public API for now. - out << "<?xml version=\"1.0\"?>\n" - << "<!-- This output should be used with care. We do not report type " - "names for flags with user defined types -->\n" - << "<!-- Prefer flag only_check_args for validating flag inputs -->\n" - // The document. - << "<AllFlags>\n" - // The program name and usage. - << XMLElement("program", flags_internal::ShortProgramInvocationName()) - << '\n' - << XMLElement("usage", program_usage_message) << '\n'; - } - - // Map of package name to - // map of file name to - // vector of flags in the file. - // This map is used to output matching flags grouped by package and file - // name. - std::map<std::string, - std::map<std::string, std::vector<const absl::CommandLineFlag*>>> - matching_flags; - - flags_internal::ForEachFlag([&](absl::CommandLineFlag& flag) { - // Ignore retired flags. - if (flag.IsRetired()) return; - - // If the flag has been stripped, pretend that it doesn't exist. - if (flag.Help() == flags_internal::kStrippedFlagHelp) return; - - // Make sure flag satisfies the filter - if (!filter_cb(flag)) return; - - std::string flag_filename = flag.Filename(); - - matching_flags[std::string(flags_internal::Package(flag_filename))] - [flag_filename] - .push_back(&flag); - }); - - absl::string_view package_separator; // controls blank lines between packages - absl::string_view file_separator; // controls blank lines between files - for (const auto& package : matching_flags) { - if (format == HelpFormat::kHumanReadable) { - out << package_separator; - package_separator = "\n\n"; - } - - file_separator = ""; - for (const auto& flags_in_file : package.second) { - if (format == HelpFormat::kHumanReadable) { - out << file_separator << " Flags from " << flags_in_file.first - << ":\n"; - file_separator = "\n"; - } - - for (const auto* flag : flags_in_file.second) { - flags_internal::FlagHelp(out, *flag, format); - } - } - } - - if (format == HelpFormat::kHumanReadable) { - FlagHelpPrettyPrinter printer(kHrfMaxLineLength, 0, 0, out); - - if (filter_cb && matching_flags.empty()) { - printer.Write("No flags matched.\n", true); - } - printer.EndLine(); - printer.Write( - "Try --helpfull to get a list of all flags or --help=substring " - "shows help for flags which include specified substring in either " - "in the name, or description or path.\n", - true); - } else { - // The end of the document. - out << "</AllFlags>\n"; - } -} - -void FlagsHelpImpl(std::ostream& out, - flags_internal::FlagKindFilter filename_filter_cb, - HelpFormat format, absl::string_view program_usage_message) { - FlagsHelpImpl( - out, - [&](const absl::CommandLineFlag& flag) { - return filename_filter_cb && filename_filter_cb(flag.Filename()); - }, - format, program_usage_message); -} - -} // namespace - -// -------------------------------------------------------------------- -// Produces the help message describing specific flag. -void FlagHelp(std::ostream& out, const CommandLineFlag& flag, - HelpFormat format) { - if (format == HelpFormat::kHumanReadable) - flags_internal::FlagHelpHumanReadable(flag, out); -} - -// -------------------------------------------------------------------- -// Produces the help messages for all flags matching the filename filter. -// If filter is empty produces help messages for all flags. -void FlagsHelp(std::ostream& out, absl::string_view filter, HelpFormat format, - absl::string_view program_usage_message) { - flags_internal::FlagKindFilter filter_cb = [&](absl::string_view filename) { - return filter.empty() || filename.find(filter) != absl::string_view::npos; - }; - flags_internal::FlagsHelpImpl(out, filter_cb, format, program_usage_message); -} - -// -------------------------------------------------------------------- -// Checks all the 'usage' command line flags to see if any have been set. -// If so, handles them appropriately. -int HandleUsageFlags(std::ostream& out, - absl::string_view program_usage_message) { - switch (GetFlagsHelpMode()) { - case HelpMode::kNone: - break; - case HelpMode::kImportant: - flags_internal::FlagsHelpImpl( - out, flags_internal::GetUsageConfig().contains_help_flags, - GetFlagsHelpFormat(), program_usage_message); - return 1; - - case HelpMode::kShort: - flags_internal::FlagsHelpImpl( - out, flags_internal::GetUsageConfig().contains_helpshort_flags, - GetFlagsHelpFormat(), program_usage_message); - return 1; - - case HelpMode::kFull: - flags_internal::FlagsHelp(out, "", GetFlagsHelpFormat(), - program_usage_message); - return 1; - - case HelpMode::kPackage: - flags_internal::FlagsHelpImpl( - out, flags_internal::GetUsageConfig().contains_helppackage_flags, - GetFlagsHelpFormat(), program_usage_message); - - return 1; - - case HelpMode::kMatch: { - std::string substr = GetFlagsHelpMatchSubstr(); - if (substr.empty()) { - // show all options - flags_internal::FlagsHelp(out, substr, GetFlagsHelpFormat(), - program_usage_message); - } else { - auto filter_cb = [&substr](const absl::CommandLineFlag& flag) { - if (absl::StrContains(flag.Name(), substr)) return true; - if (absl::StrContains(flag.Filename(), substr)) return true; - if (absl::StrContains(flag.Help(), substr)) return true; - - return false; - }; - flags_internal::FlagsHelpImpl( - out, filter_cb, HelpFormat::kHumanReadable, program_usage_message); - } - - return 1; - } - case HelpMode::kVersion: - if (flags_internal::GetUsageConfig().version_string) - out << flags_internal::GetUsageConfig().version_string(); - // Unlike help, we may be asking for version in a script, so return 0 - return 0; - - case HelpMode::kOnlyCheckArgs: - return 0; - } - - return -1; -} - -// -------------------------------------------------------------------- -// Globals representing usage reporting flags - -namespace { - -ABSL_CONST_INIT absl::Mutex help_attributes_guard(absl::kConstInit); -ABSL_CONST_INIT std::string* match_substr - ABSL_GUARDED_BY(help_attributes_guard) = nullptr; -ABSL_CONST_INIT HelpMode help_mode ABSL_GUARDED_BY(help_attributes_guard) = - HelpMode::kNone; -ABSL_CONST_INIT HelpFormat help_format ABSL_GUARDED_BY(help_attributes_guard) = - HelpFormat::kHumanReadable; - -} // namespace - -std::string GetFlagsHelpMatchSubstr() { - absl::MutexLock l(&help_attributes_guard); - if (match_substr == nullptr) return ""; - return *match_substr; -} - -void SetFlagsHelpMatchSubstr(absl::string_view substr) { - absl::MutexLock l(&help_attributes_guard); - if (match_substr == nullptr) match_substr = new std::string; - match_substr->assign(substr.data(), substr.size()); -} - -HelpMode GetFlagsHelpMode() { - absl::MutexLock l(&help_attributes_guard); - // Refer to dummy variales to prevent linker dropping them - if (FLAGS_help || FLAGS_helpfull || FLAGS_helpshort || FLAGS_helppackage || - FLAGS_version || FLAGS_only_check_args || FLAGS_helpon || - FLAGS_helpmatch) { - help_mode = HelpMode::kNone; - } - return help_mode; -} - -void SetFlagsHelpMode(HelpMode mode) { - absl::MutexLock l(&help_attributes_guard); - help_mode = mode; -} - -HelpFormat GetFlagsHelpFormat() { - absl::MutexLock l(&help_attributes_guard); - return help_format; -} - -void SetFlagsHelpFormat(HelpFormat format) { - absl::MutexLock l(&help_attributes_guard); - help_format = format; -} - -// Deduces usage flags from the input argument in a form --name=value or -// --name. argument is already split into name and value before we call this -// function. -bool DeduceUsageFlags(absl::string_view name, absl::string_view value) { - if (absl::ConsumePrefix(&name, "help")) { - if (name == "") { - if (value.empty()) { - SetFlagsHelpMode(HelpMode::kImportant); - } else { - SetFlagsHelpMode(HelpMode::kMatch); - SetFlagsHelpMatchSubstr(value); - } - return true; - } - - if (name == "match") { - SetFlagsHelpMode(HelpMode::kMatch); - SetFlagsHelpMatchSubstr(value); - return true; - } - - if (name == "on") { - SetFlagsHelpMode(HelpMode::kMatch); - SetFlagsHelpMatchSubstr(absl::StrCat("/", value, ".")); - return true; - } - - if (name == "full") { - SetFlagsHelpMode(HelpMode::kFull); - return true; - } - - if (name == "short") { - SetFlagsHelpMode(HelpMode::kShort); - return true; - } - - if (name == "package") { - SetFlagsHelpMode(HelpMode::kPackage); - return true; - } - - return false; - } - - if (name == "version") { - SetFlagsHelpMode(HelpMode::kVersion); - return true; - } - - if (name == "only_check_args") { - SetFlagsHelpMode(HelpMode::kOnlyCheckArgs); - return true; - } - - return false; -} - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/third_party/abseil_cpp/absl/flags/internal/usage.h b/third_party/abseil_cpp/absl/flags/internal/usage.h deleted file mode 100644 index c0bcac57628a..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/usage.h +++ /dev/null @@ -1,104 +0,0 @@ -// -// 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. - -#ifndef ABSL_FLAGS_INTERNAL_USAGE_H_ -#define ABSL_FLAGS_INTERNAL_USAGE_H_ - -#include <iosfwd> -#include <string> - -#include "absl/base/config.h" -#include "absl/flags/commandlineflag.h" -#include "absl/flags/declare.h" -#include "absl/strings/string_view.h" - -// -------------------------------------------------------------------- -// Usage reporting interfaces - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace flags_internal { - -// The format to report the help messages in. -enum class HelpFormat { - kHumanReadable, -}; - -// Streams the help message describing `flag` to `out`. -// The default value for `flag` is included in the output. -void FlagHelp(std::ostream& out, const CommandLineFlag& flag, - HelpFormat format = HelpFormat::kHumanReadable); - -// Produces the help messages for all flags matching the filter. A flag matches -// the filter if it is defined in a file with a filename which includes -// filter string as a substring. You can use '/' and '.' to restrict the -// matching to a specific file names. For example: -// FlagsHelp(out, "/path/to/file."); -// restricts help to only flags which resides in files named like: -// .../path/to/file.<ext> -// for any extension 'ext'. If the filter is empty this function produces help -// messages for all flags. -void FlagsHelp(std::ostream& out, absl::string_view filter, - HelpFormat format, absl::string_view program_usage_message); - -// -------------------------------------------------------------------- - -// If any of the 'usage' related command line flags (listed on the bottom of -// this file) has been set this routine produces corresponding help message in -// the specified output stream and returns: -// 0 - if "version" or "only_check_flags" flags were set and handled. -// 1 - if some other 'usage' related flag was set and handled. -// -1 - if no usage flags were set on a commmand line. -// Non negative return values are expected to be used as an exit code for a -// binary. -int HandleUsageFlags(std::ostream& out, - absl::string_view program_usage_message); - -// -------------------------------------------------------------------- -// Globals representing usage reporting flags - -enum class HelpMode { - kNone, - kImportant, - kShort, - kFull, - kPackage, - kMatch, - kVersion, - kOnlyCheckArgs -}; - -// Returns substring to filter help output (--help=substr argument) -std::string GetFlagsHelpMatchSubstr(); -// Returns the requested help mode. -HelpMode GetFlagsHelpMode(); -// Returns the requested help format. -HelpFormat GetFlagsHelpFormat(); - -// These are corresponding setters to the attributes above. -void SetFlagsHelpMatchSubstr(absl::string_view); -void SetFlagsHelpMode(HelpMode); -void SetFlagsHelpFormat(HelpFormat); - -// Deduces usage flags from the input argument in a form --name=value or -// --name. argument is already split into name and value before we call this -// function. -bool DeduceUsageFlags(absl::string_view name, absl::string_view value); - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_FLAGS_INTERNAL_USAGE_H_ diff --git a/third_party/abseil_cpp/absl/flags/internal/usage_test.cc b/third_party/abseil_cpp/absl/flags/internal/usage_test.cc deleted file mode 100644 index b5c2487da577..000000000000 --- a/third_party/abseil_cpp/absl/flags/internal/usage_test.cc +++ /dev/null @@ -1,493 +0,0 @@ -// -// 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/internal/usage.h" - -#include <stdint.h> - -#include <sstream> -#include <string> - -#include "gtest/gtest.h" -#include "absl/flags/flag.h" -#include "absl/flags/internal/parse.h" -#include "absl/flags/internal/path_util.h" -#include "absl/flags/internal/program_name.h" -#include "absl/flags/reflection.h" -#include "absl/flags/usage.h" -#include "absl/flags/usage_config.h" -#include "absl/strings/match.h" -#include "absl/strings/string_view.h" - -ABSL_FLAG(int, usage_reporting_test_flag_01, 101, - "usage_reporting_test_flag_01 help message"); -ABSL_FLAG(bool, usage_reporting_test_flag_02, false, - "usage_reporting_test_flag_02 help message"); -ABSL_FLAG(double, usage_reporting_test_flag_03, 1.03, - "usage_reporting_test_flag_03 help message"); -ABSL_FLAG(int64_t, usage_reporting_test_flag_04, 1000000000000004L, - "usage_reporting_test_flag_04 help message"); - -static const char kTestUsageMessage[] = "Custom usage message"; - -struct UDT { - UDT() = default; - UDT(const UDT&) = default; -}; -bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; } -std::string AbslUnparseFlag(const UDT&) { return "UDT{}"; } - -ABSL_FLAG(UDT, usage_reporting_test_flag_05, {}, - "usage_reporting_test_flag_05 help message"); - -ABSL_FLAG( - std::string, usage_reporting_test_flag_06, {}, - "usage_reporting_test_flag_06 help message.\n" - "\n" - "Some more help.\n" - "Even more long long long long long long long long long long long long " - "help message."); - -namespace { - -namespace flags = absl::flags_internal; - -static std::string NormalizeFileName(absl::string_view fname) { -#ifdef _WIN32 - std::string normalized(fname); - std::replace(normalized.begin(), normalized.end(), '\\', '/'); - fname = normalized; -#endif - - auto absl_pos = fname.rfind("absl/"); - if (absl_pos != absl::string_view::npos) { - fname = fname.substr(absl_pos); - } - return std::string(fname); -} - -class UsageReportingTest : public testing::Test { - protected: - UsageReportingTest() { - // Install default config for the use on this unit test. - // Binary may install a custom config before tests are run. - absl::FlagsUsageConfig default_config; - default_config.normalize_filename = &NormalizeFileName; - absl::SetFlagsUsageConfig(default_config); - } - ~UsageReportingTest() override { - flags::SetFlagsHelpMode(flags::HelpMode::kNone); - flags::SetFlagsHelpMatchSubstr(""); - flags::SetFlagsHelpFormat(flags::HelpFormat::kHumanReadable); - } - - private: - absl::FlagSaver flag_saver_; -}; - -// -------------------------------------------------------------------- - -using UsageReportingDeathTest = UsageReportingTest; - -TEST_F(UsageReportingDeathTest, TestSetProgramUsageMessage) { - EXPECT_EQ(absl::ProgramUsageMessage(), kTestUsageMessage); - -#ifndef _WIN32 - // TODO(rogeeff): figure out why this does not work on Windows. - EXPECT_DEATH_IF_SUPPORTED( - absl::SetProgramUsageMessage("custom usage message"), - ".*SetProgramUsageMessage\\(\\) called twice.*"); -#endif -} - -// -------------------------------------------------------------------- - -TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_01) { - const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_01"); - std::stringstream test_buf; - - flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); - EXPECT_EQ( - test_buf.str(), - R"( --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); - default: 101; -)"); -} - -TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_02) { - const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_02"); - std::stringstream test_buf; - - flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); - EXPECT_EQ( - test_buf.str(), - R"( --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); - default: false; -)"); -} - -TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_03) { - const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_03"); - std::stringstream test_buf; - - flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); - EXPECT_EQ( - test_buf.str(), - R"( --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); - default: 1.03; -)"); -} - -TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_04) { - const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_04"); - std::stringstream test_buf; - - flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); - EXPECT_EQ( - test_buf.str(), - R"( --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); - default: 1000000000000004; -)"); -} - -TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_05) { - const auto* flag = absl::FindCommandLineFlag("usage_reporting_test_flag_05"); - std::stringstream test_buf; - - flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); - EXPECT_EQ( - test_buf.str(), - R"( --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); - default: UDT{}; -)"); -} - -// -------------------------------------------------------------------- - -TEST_F(UsageReportingTest, TestFlagsHelpHRF) { - std::string usage_test_flags_out = - R"(usage_test: Custom usage message - - Flags from absl/flags/internal/usage_test.cc: - --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); - default: 101; - --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); - default: false; - --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); - default: 1.03; - --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); - default: 1000000000000004; - --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); - default: UDT{}; - --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. - - Some more help. - Even more long long long long long long long long long long long long help - message.); default: ""; - -Try --helpfull to get a list of all flags or --help=substring shows help for -flags which include specified substring in either in the name, or description or -path. -)"; - - std::stringstream test_buf_01; - flags::FlagsHelp(test_buf_01, "usage_test.cc", - flags::HelpFormat::kHumanReadable, kTestUsageMessage); - EXPECT_EQ(test_buf_01.str(), usage_test_flags_out); - - std::stringstream test_buf_02; - flags::FlagsHelp(test_buf_02, "flags/internal/usage_test.cc", - flags::HelpFormat::kHumanReadable, kTestUsageMessage); - EXPECT_EQ(test_buf_02.str(), usage_test_flags_out); - - std::stringstream test_buf_03; - flags::FlagsHelp(test_buf_03, "usage_test", flags::HelpFormat::kHumanReadable, - kTestUsageMessage); - EXPECT_EQ(test_buf_03.str(), usage_test_flags_out); - - std::stringstream test_buf_04; - flags::FlagsHelp(test_buf_04, "flags/invalid_file_name.cc", - flags::HelpFormat::kHumanReadable, kTestUsageMessage); - EXPECT_EQ(test_buf_04.str(), - R"(usage_test: Custom usage message - -No flags matched. - -Try --helpfull to get a list of all flags or --help=substring shows help for -flags which include specified substring in either in the name, or description or -path. -)"); - - std::stringstream test_buf_05; - flags::FlagsHelp(test_buf_05, "", flags::HelpFormat::kHumanReadable, - kTestUsageMessage); - std::string test_out = test_buf_05.str(); - absl::string_view test_out_str(test_out); - EXPECT_TRUE( - absl::StartsWith(test_out_str, "usage_test: Custom usage message")); - EXPECT_TRUE(absl::StrContains( - test_out_str, "Flags from absl/flags/internal/usage_test.cc:")); - EXPECT_TRUE( - absl::StrContains(test_out_str, "-usage_reporting_test_flag_01 ")); -} - -// -------------------------------------------------------------------- - -TEST_F(UsageReportingTest, TestNoUsageFlags) { - std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), -1); -} - -// -------------------------------------------------------------------- - -TEST_F(UsageReportingTest, TestUsageFlag_helpshort) { - flags::SetFlagsHelpMode(flags::HelpMode::kShort); - - std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1); - EXPECT_EQ(test_buf.str(), - R"(usage_test: Custom usage message - - Flags from absl/flags/internal/usage_test.cc: - --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); - default: 101; - --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); - default: false; - --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); - default: 1.03; - --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); - default: 1000000000000004; - --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); - default: UDT{}; - --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. - - Some more help. - Even more long long long long long long long long long long long long help - message.); default: ""; - -Try --helpfull to get a list of all flags or --help=substring shows help for -flags which include specified substring in either in the name, or description or -path. -)"); -} - -// -------------------------------------------------------------------- - -TEST_F(UsageReportingTest, TestUsageFlag_help_simple) { - flags::SetFlagsHelpMode(flags::HelpMode::kImportant); - - std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1); - EXPECT_EQ(test_buf.str(), - R"(usage_test: Custom usage message - - Flags from absl/flags/internal/usage_test.cc: - --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); - default: 101; - --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); - default: false; - --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); - default: 1.03; - --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); - default: 1000000000000004; - --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); - default: UDT{}; - --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. - - Some more help. - Even more long long long long long long long long long long long long help - message.); default: ""; - -Try --helpfull to get a list of all flags or --help=substring shows help for -flags which include specified substring in either in the name, or description or -path. -)"); -} - -// -------------------------------------------------------------------- - -TEST_F(UsageReportingTest, TestUsageFlag_help_one_flag) { - flags::SetFlagsHelpMode(flags::HelpMode::kMatch); - flags::SetFlagsHelpMatchSubstr("usage_reporting_test_flag_06"); - - std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1); - EXPECT_EQ(test_buf.str(), - R"(usage_test: Custom usage message - - Flags from absl/flags/internal/usage_test.cc: - --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. - - Some more help. - Even more long long long long long long long long long long long long help - message.); default: ""; - -Try --helpfull to get a list of all flags or --help=substring shows help for -flags which include specified substring in either in the name, or description or -path. -)"); -} - -// -------------------------------------------------------------------- - -TEST_F(UsageReportingTest, TestUsageFlag_help_multiple_flag) { - flags::SetFlagsHelpMode(flags::HelpMode::kMatch); - flags::SetFlagsHelpMatchSubstr("test_flag"); - - std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1); - EXPECT_EQ(test_buf.str(), - R"(usage_test: Custom usage message - - Flags from absl/flags/internal/usage_test.cc: - --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); - default: 101; - --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); - default: false; - --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); - default: 1.03; - --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); - default: 1000000000000004; - --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); - default: UDT{}; - --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. - - Some more help. - Even more long long long long long long long long long long long long help - message.); default: ""; - -Try --helpfull to get a list of all flags or --help=substring shows help for -flags which include specified substring in either in the name, or description or -path. -)"); -} - -// -------------------------------------------------------------------- - -TEST_F(UsageReportingTest, TestUsageFlag_helppackage) { - flags::SetFlagsHelpMode(flags::HelpMode::kPackage); - - std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1); - EXPECT_EQ(test_buf.str(), - R"(usage_test: Custom usage message - - Flags from absl/flags/internal/usage_test.cc: - --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); - default: 101; - --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); - default: false; - --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); - default: 1.03; - --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); - default: 1000000000000004; - --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); - default: UDT{}; - --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. - - Some more help. - Even more long long long long long long long long long long long long help - message.); default: ""; - -Try --helpfull to get a list of all flags or --help=substring shows help for -flags which include specified substring in either in the name, or description or -path. -)"); -} - -// -------------------------------------------------------------------- - -TEST_F(UsageReportingTest, TestUsageFlag_version) { - flags::SetFlagsHelpMode(flags::HelpMode::kVersion); - - std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 0); -#ifndef NDEBUG - EXPECT_EQ(test_buf.str(), "usage_test\nDebug build (NDEBUG not #defined)\n"); -#else - EXPECT_EQ(test_buf.str(), "usage_test\n"); -#endif -} - -// -------------------------------------------------------------------- - -TEST_F(UsageReportingTest, TestUsageFlag_only_check_args) { - flags::SetFlagsHelpMode(flags::HelpMode::kOnlyCheckArgs); - - std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 0); - EXPECT_EQ(test_buf.str(), ""); -} - -// -------------------------------------------------------------------- - -TEST_F(UsageReportingTest, TestUsageFlag_helpon) { - flags::SetFlagsHelpMode(flags::HelpMode::kMatch); - flags::SetFlagsHelpMatchSubstr("/bla-bla."); - - std::stringstream test_buf_01; - EXPECT_EQ(flags::HandleUsageFlags(test_buf_01, kTestUsageMessage), 1); - EXPECT_EQ(test_buf_01.str(), - R"(usage_test: Custom usage message - -No flags matched. - -Try --helpfull to get a list of all flags or --help=substring shows help for -flags which include specified substring in either in the name, or description or -path. -)"); - - flags::SetFlagsHelpMatchSubstr("/usage_test."); - - std::stringstream test_buf_02; - EXPECT_EQ(flags::HandleUsageFlags(test_buf_02, kTestUsageMessage), 1); - EXPECT_EQ(test_buf_02.str(), - R"(usage_test: Custom usage message - - Flags from absl/flags/internal/usage_test.cc: - --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); - default: 101; - --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); - default: false; - --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); - default: 1.03; - --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); - default: 1000000000000004; - --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); - default: UDT{}; - --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. - - Some more help. - Even more long long long long long long long long long long long long help - message.); default: ""; - -Try --helpfull to get a list of all flags or --help=substring shows help for -flags which include specified substring in either in the name, or description or -path. -)"); -} - -// -------------------------------------------------------------------- - -} // namespace - -int main(int argc, char* argv[]) { - (void)absl::GetFlag(FLAGS_undefok); // Force linking of parse.cc - flags::SetProgramInvocationName("usage_test"); - absl::SetProgramUsageMessage(kTestUsageMessage); - ::testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} |