diff options
Diffstat (limited to 'absl/flags/internal')
-rw-r--r-- | absl/flags/internal/commandlineflag.cc | 62 | ||||
-rw-r--r-- | absl/flags/internal/commandlineflag.h | 26 | ||||
-rw-r--r-- | absl/flags/internal/flag.cc | 69 | ||||
-rw-r--r-- | absl/flags/internal/flag.h | 85 | ||||
-rw-r--r-- | absl/flags/internal/registry.cc | 8 |
5 files changed, 92 insertions, 158 deletions
diff --git a/absl/flags/internal/commandlineflag.cc b/absl/flags/internal/commandlineflag.cc deleted file mode 100644 index 09249274c3e7..000000000000 --- a/absl/flags/internal/commandlineflag.cc +++ /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. - -#include "absl/flags/internal/commandlineflag.h" - -#include "absl/flags/usage_config.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 - -// This is used by this file, and also in commandlineflags_reporting.cc -const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001"; - -absl::string_view CommandLineFlag::Typename() const { - // We do not store/report type in Abseil Flags, so that user do not rely on in - // at runtime - if (IsAbseilFlag() || IsRetired()) return ""; - -#define HANDLE_V1_BUILTIN_TYPE(t) \ - if (IsOfType<t>()) { \ - return #t; \ - } - - HANDLE_V1_BUILTIN_TYPE(bool); - HANDLE_V1_BUILTIN_TYPE(int32_t); - HANDLE_V1_BUILTIN_TYPE(int64_t); - HANDLE_V1_BUILTIN_TYPE(uint64_t); - HANDLE_V1_BUILTIN_TYPE(double); -#undef HANDLE_V1_BUILTIN_TYPE - - if (IsOfType<std::string>()) { - return "string"; - } - - return ""; -} - -std::string CommandLineFlag::Filename() const { - return flags_internal::GetUsageConfig().normalize_filename(filename_); -} - -} // namespace flags_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/absl/flags/internal/commandlineflag.h b/absl/flags/internal/commandlineflag.h index 49e13d1e726b..a0c18e80b6c7 100644 --- a/absl/flags/internal/commandlineflag.h +++ b/absl/flags/internal/commandlineflag.h @@ -61,8 +61,6 @@ enum ValueSource { kProgrammaticChange, }; -extern const char kStrippedFlagHelp[]; - // The per-type function template <typename T> void* FlagOps(FlagOp op, const void* v1, void* v2) { @@ -155,8 +153,7 @@ class FlagStateInterface { // Holds all information for a flag. class CommandLineFlag { public: - constexpr CommandLineFlag(const char* name, const char* filename) - : name_(name), filename_(filename) {} + constexpr CommandLineFlag() = default; // Virtual destructor virtual void Destroy() = 0; @@ -166,9 +163,6 @@ class CommandLineFlag { CommandLineFlag& operator=(const CommandLineFlag&) = delete; // Non-polymorphic access methods. - absl::string_view Name() const { return name_; } - absl::string_view Typename() const; - std::string Filename() const; // Return true iff flag has type T. template <typename T> @@ -190,8 +184,7 @@ class CommandLineFlag { // // 1. `U.value` has correct size and alignment for a value of type `T` // 2. The `U.value` constructor is not invoked since U's constructor does - // not - // do it explicitly. + // not do it explicitly. // 3. The `U.value` destructor is invoked since U's destructor does it // explicitly. This makes `U` a kind of RAII wrapper around non default // constructible value of T, which is destructed when we leave the @@ -213,9 +206,16 @@ class CommandLineFlag { // Polymorphic access methods - // Returns help message associated with this flag + // Returns name of this flag. + virtual absl::string_view Name() const = 0; + // Returns name of the file where this flag is defined. + virtual std::string Filename() const = 0; + // Returns name of the flag's value type for some built-in types or empty + // std::string. + virtual absl::string_view Typename() const = 0; + // Returns help message associated with this flag. virtual std::string Help() const = 0; - // Returns true iff this object corresponds to retired flag + // Returns true iff this object corresponds to retired flag. virtual bool IsRetired() const { return false; } // Returns true iff this is a handle to an Abseil Flag. virtual bool IsAbseilFlag() const { return true; } @@ -253,10 +253,6 @@ class CommandLineFlag { protected: ~CommandLineFlag() = default; - // Constant configuration for a particular flag. - const char* const name_; // Flags name passed to ABSL_FLAG as second arg. - const char* const filename_; // The file name where ABSL_FLAG resides. - private: // Copy-construct a new value of the flag's type in a memory referenced by // the dst based on the current flag's value. diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc index 599bd7a45561..bb9a98f34404 100644 --- a/absl/flags/internal/flag.cc +++ b/absl/flags/internal/flag.cc @@ -16,17 +16,25 @@ #include "absl/flags/internal/flag.h" #include "absl/base/optimization.h" +#include "absl/flags/usage_config.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(const CommandLineFlag& flag) { +bool ShouldValidateFlagValue(FlagOpFn flag_type_id) { #define DONT_VALIDATE(T) \ - if (flag.IsOfType<T>()) return false; + if (flag_type_id == &flags_internal::FlagOps<T>) return false; ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(DONT_VALIDATE) DONT_VALIDATE(std::string) DONT_VALIDATE(std::vector<std::string>) @@ -123,6 +131,12 @@ std::unique_ptr<void, DynValueDeleter> FlagImpl::MakeInitValue() const { return {res, DynValueDeleter{op_}}; } +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 help_source_kind_ == FlagHelpSrcKind::kLiteral ? help_.literal : help_.gen_func(); @@ -186,16 +200,15 @@ void FlagImpl::InvokeCallback() const { cb(); } -bool FlagImpl::RestoreState(const CommandLineFlag& flag, const void* value, - bool modified, bool on_command_line, - int64_t counter) { +bool FlagImpl::RestoreState(const void* value, bool modified, + bool on_command_line, int64_t counter) { { absl::MutexLock l(DataGuard()); if (counter_ == counter) return false; } - Write(flag, value, op_); + Write(value, op_); { absl::MutexLock l(DataGuard()); @@ -211,18 +224,15 @@ bool FlagImpl::RestoreState(const CommandLineFlag& flag, const void* value, // 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' -bool FlagImpl::TryParse(const CommandLineFlag& flag, void** dst, - absl::string_view value, std::string* err) const { +bool FlagImpl::TryParse(void** dst, absl::string_view value, + std::string* err) const { auto tentative_value = MakeInitValue(); std::string parse_err; if (!Parse(marshalling_op_, value, tentative_value.get(), &parse_err)) { - auto type_name = flag.Typename(); absl::string_view err_sep = parse_err.empty() ? "" : "; "; - absl::string_view typename_sep = type_name.empty() ? "" : " "; - *err = absl::StrCat("Illegal value '", value, "' specified for", - typename_sep, type_name, " flag '", flag.Name(), "'", - err_sep, parse_err); + *err = absl::StrCat("Illegal value '", value, "' specified for flag '", + Name(), "'", err_sep, parse_err); return false; } @@ -233,8 +243,7 @@ bool FlagImpl::TryParse(const CommandLineFlag& flag, void** dst, return true; } -void FlagImpl::Read(const CommandLineFlag& flag, void* dst, - const flags_internal::FlagOpFn dst_op) const { +void FlagImpl::Read(void* dst, const flags_internal::FlagOpFn dst_op) const { absl::ReaderMutexLock l(DataGuard()); // `dst_op` is the unmarshaling operation corresponding to the declaration @@ -243,7 +252,7 @@ void FlagImpl::Read(const CommandLineFlag& flag, void* dst, if (ABSL_PREDICT_FALSE(dst_op != op_)) { ABSL_INTERNAL_LOG( ERROR, - absl::StrCat("Flag '", flag.Name(), + absl::StrCat("Flag '", Name(), "' is defined as one type and declared as another")); } CopyConstruct(op_, cur_, dst); @@ -259,8 +268,7 @@ void FlagImpl::StoreAtomic() { } } -void FlagImpl::Write(const CommandLineFlag& flag, const void* src, - const flags_internal::FlagOpFn src_op) { +void FlagImpl::Write(const void* src, const flags_internal::FlagOpFn src_op) { absl::MutexLock l(DataGuard()); // `src_op` is the marshalling operation corresponding to the declaration @@ -269,18 +277,17 @@ void FlagImpl::Write(const CommandLineFlag& flag, const void* src, if (ABSL_PREDICT_FALSE(src_op != op_)) { ABSL_INTERNAL_LOG( ERROR, - absl::StrCat("Flag '", flag.Name(), + absl::StrCat("Flag '", Name(), "' is defined as one type and declared as another")); } - if (ShouldValidateFlagValue(flag)) { + if (ShouldValidateFlagValue(op_)) { void* obj = Clone(op_, src); std::string ignored_error; std::string src_as_str = Unparse(marshalling_op_, src); if (!Parse(marshalling_op_, src_as_str, obj, &ignored_error)) { - ABSL_INTERNAL_LOG(ERROR, - absl::StrCat("Attempt to set flag '", flag.Name(), - "' to invalid value ", src_as_str)); + ABSL_INTERNAL_LOG(ERROR, absl::StrCat("Attempt to set flag '", Name(), + "' to invalid value ", src_as_str)); } Delete(op_, obj); } @@ -301,15 +308,14 @@ void FlagImpl::Write(const CommandLineFlag& flag, const void* src, // * 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::SetFromString(const CommandLineFlag& flag, - absl::string_view value, FlagSettingMode set_mode, +bool FlagImpl::SetFromString(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 - if (!TryParse(flag, &cur_, value, err)) return false; + if (!TryParse(&cur_, value, err)) return false; modified_ = true; counter_++; StoreAtomic(); @@ -323,7 +329,7 @@ bool FlagImpl::SetFromString(const CommandLineFlag& flag, case SET_FLAG_IF_DEFAULT: { // set the flag's value, but only if it hasn't been set by someone else if (!modified_) { - if (!TryParse(flag, &cur_, value, err)) return false; + if (!TryParse(&cur_, value, err)) return false; modified_ = true; counter_++; StoreAtomic(); @@ -341,12 +347,12 @@ bool FlagImpl::SetFromString(const CommandLineFlag& flag, } case SET_FLAGS_DEFAULT: { if (def_kind_ == FlagDefaultSrcKind::kDynamicValue) { - if (!TryParse(flag, &default_src_.dynamic_value, value, err)) { + if (!TryParse(&default_src_.dynamic_value, value, err)) { return false; } } else { void* new_default_val = nullptr; - if (!TryParse(flag, &new_default_val, value, err)) { + if (!TryParse(&new_default_val, value, err)) { return false; } @@ -367,8 +373,7 @@ bool FlagImpl::SetFromString(const CommandLineFlag& flag, return true; } -void FlagImpl::CheckDefaultValueParsingRoundtrip( - const CommandLineFlag& flag) const { +void FlagImpl::CheckDefaultValueParsingRoundtrip() const { std::string v = DefaultValue(); absl::MutexLock lock(DataGuard()); @@ -378,7 +383,7 @@ void FlagImpl::CheckDefaultValueParsingRoundtrip( if (!flags_internal::Parse(marshalling_op_, v, dst.get(), &error)) { ABSL_INTERNAL_LOG( FATAL, - absl::StrCat("Flag ", flag.Name(), " (from ", flag.Filename(), + absl::StrCat("Flag ", Name(), " (from ", Filename(), "): std::string form of default value '", v, "' could not be parsed; error=", error)); } diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index 21a10c7f85f8..7d5271c40de6 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -82,6 +82,8 @@ struct HelpInitArg { FlagHelpSrcKind kind; }; +extern const char kStrippedFlagHelp[]; + // HelpConstexprWrap is used by struct AbslFlagHelpGenFor##name generated by // ABSL_FLAG macro. It is only used to silence the compiler in the case where // help message expression is not constexpr and does not have type const char*. @@ -148,11 +150,14 @@ struct DynValueDeleter { // The class encapsulates the Flag's data and safe access to it. class FlagImpl { public: - constexpr FlagImpl(const flags_internal::FlagOpFn op, + constexpr FlagImpl(const char* name, const char* filename, + const flags_internal::FlagOpFn op, const flags_internal::FlagMarshallingOpFn marshalling_op, - const flags_internal::FlagDfltGenFunc default_value_gen, - const HelpInitArg help) - : op_(op), + const HelpInitArg help, + const flags_internal::FlagDfltGenFunc default_value_gen) + : name_(name), + filename_(filename), + op_(op), marshalling_op_(marshalling_op), help_(help.source), help_source_kind_(help.kind), @@ -164,18 +169,18 @@ class FlagImpl { void Destroy(); // Constant access methods + absl::string_view Name() const; + std::string Filename() const; std::string Help() const; bool IsModified() const ABSL_LOCKS_EXCLUDED(*DataGuard()); bool IsSpecifiedOnCommandLine() const ABSL_LOCKS_EXCLUDED(*DataGuard()); std::string DefaultValue() const ABSL_LOCKS_EXCLUDED(*DataGuard()); std::string CurrentValue() const ABSL_LOCKS_EXCLUDED(*DataGuard()); - void Read(const CommandLineFlag& flag, void* dst, - const flags_internal::FlagOpFn dst_op) const + void Read(void* dst, const flags_internal::FlagOpFn dst_op) const ABSL_LOCKS_EXCLUDED(*DataGuard()); // Attempts to parse supplied `value` std::string. If parsing is successful, then // it replaces `dst` with the new value. - bool TryParse(const CommandLineFlag& flag, void** dst, - absl::string_view value, std::string* err) const + bool TryParse(void** dst, absl::string_view value, std::string* err) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); template <typename T> bool AtomicGet(T* v) const { @@ -189,12 +194,11 @@ class FlagImpl { } // Mutating access methods - void Write(const CommandLineFlag& flag, const void* src, - const flags_internal::FlagOpFn src_op) + void Write(const void* src, const flags_internal::FlagOpFn src_op) + ABSL_LOCKS_EXCLUDED(*DataGuard()); + bool SetFromString(absl::string_view value, FlagSettingMode set_mode, + ValueSource source, std::string* err) ABSL_LOCKS_EXCLUDED(*DataGuard()); - bool SetFromString(const CommandLineFlag& flag, absl::string_view value, - FlagSettingMode set_mode, ValueSource source, - std::string* err) ABSL_LOCKS_EXCLUDED(*DataGuard()); // If possible, updates copy of the Flag's value that is stored in an // atomic word. void StoreAtomic() ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); @@ -214,12 +218,11 @@ class FlagImpl { return absl::make_unique<flags_internal::FlagState<T>>( flag, std::move(cur_value), modified_, on_command_line_, counter_); } - bool RestoreState(const CommandLineFlag& flag, const void* value, - bool modified, bool on_command_line, int64_t counter) - ABSL_LOCKS_EXCLUDED(*DataGuard()); + bool RestoreState(const void* value, bool modified, bool on_command_line, + int64_t counter) ABSL_LOCKS_EXCLUDED(*DataGuard()); // Value validation interfaces. - void CheckDefaultValueParsingRoundtrip(const CommandLineFlag& flag) const + void CheckDefaultValueParsingRoundtrip() const ABSL_LOCKS_EXCLUDED(*DataGuard()); bool ValidateInputValue(absl::string_view value) const ABSL_LOCKS_EXCLUDED(*DataGuard()); @@ -235,7 +238,10 @@ class FlagImpl { ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); // Immutable Flag's data. - const FlagOpFn op_; // Type-specific handler. + // Constant configuration for a particular flag. + const char* const name_; // Flags name passed to ABSL_FLAG as second arg. + const char* const filename_; // The file name where ABSL_FLAG resides. + const FlagOpFn op_; // Type-specific handler. const FlagMarshallingOpFn marshalling_op_; // Marshalling ops handler. const FlagHelpSrc help_; // Help message literal or function to generate it. // Indicates if help message was supplied as literal or generator func. @@ -286,13 +292,12 @@ class FlagImpl { template <typename T> class Flag final : public flags_internal::CommandLineFlag { public: - constexpr Flag(const char* name, const flags_internal::HelpInitArg help, - const char* filename, + constexpr Flag(const char* name, const char* filename, const flags_internal::FlagMarshallingOpFn marshalling_op, - const flags_internal::FlagDfltGenFunc initial_value_gen) - : flags_internal::CommandLineFlag(name, filename), - impl_(&flags_internal::FlagOps<T>, marshalling_op, initial_value_gen, - help) {} + const flags_internal::HelpInitArg help, + const flags_internal::FlagDfltGenFunc default_value_gen) + : impl_(name, filename, &flags_internal::FlagOps<T>, marshalling_op, help, + default_value_gen) {} T Get() const { // See implementation notes in CommandLineFlag::Get(). @@ -303,19 +308,22 @@ class Flag final : public flags_internal::CommandLineFlag { }; U u; - impl_.Read(*this, &u.value, &flags_internal::FlagOps<T>); + impl_.Read(&u.value, &flags_internal::FlagOps<T>); return std::move(u.value); } bool AtomicGet(T* v) const { return impl_.AtomicGet(v); } - void Set(const T& v) { impl_.Write(*this, &v, &flags_internal::FlagOps<T>); } + void Set(const T& v) { impl_.Write(&v, &flags_internal::FlagOps<T>); } void SetCallback(const flags_internal::FlagCallback mutation_callback) { impl_.SetCallback(mutation_callback); } // CommandLineFlag interface + absl::string_view Name() const override { return impl_.Name(); } + std::string Filename() const override { return impl_.Filename(); } + absl::string_view Typename() const override { return ""; } std::string Help() const override { return impl_.Help(); } bool IsModified() const override { return impl_.IsModified(); } bool IsSpecifiedOnCommandLine() const override { @@ -338,20 +346,19 @@ class Flag final : public flags_internal::CommandLineFlag { // Restores the flag state to the supplied state object. If there is // nothing to restore returns false. Otherwise returns true. bool RestoreState(const flags_internal::FlagState<T>& flag_state) { - return impl_.RestoreState(*this, &flag_state.cur_value_, - flag_state.modified_, flag_state.on_command_line_, - flag_state.counter_); + return impl_.RestoreState(&flag_state.cur_value_, flag_state.modified_, + flag_state.on_command_line_, flag_state.counter_); } bool SetFromString(absl::string_view value, flags_internal::FlagSettingMode set_mode, flags_internal::ValueSource source, std::string* error) override { - return impl_.SetFromString(*this, value, set_mode, source, error); + return impl_.SetFromString(value, set_mode, source, error); } void CheckDefaultValueParsingRoundtrip() const override { - impl_.CheckDefaultValueParsingRoundtrip(*this); + impl_.CheckDefaultValueParsingRoundtrip(); } private: @@ -360,7 +367,7 @@ class Flag final : public flags_internal::CommandLineFlag { void Destroy() override { impl_.Destroy(); } void Read(void* dst) const override { - impl_.Read(*this, dst, &flags_internal::FlagOps<T>); + impl_.Read(dst, &flags_internal::FlagOps<T>); } flags_internal::FlagOpFn TypeId() const override { return &flags_internal::FlagOps<T>; @@ -416,20 +423,6 @@ T* MakeFromDefaultValue(EmptyBraces) { return new T; } -// MakeFromDefaultValueOrEmpty is basically the same as MakeFromDefaultValue. It -// also allows for empty macro parameter (hence no argument), which was somehow -// widely used for ABSL_RETIRED_FLAG(). - -template <typename T> -T* MakeFromDefaultValueOrEmpty(T t) { - return MakeFromDefaultValue(std::move(t)); -} - -template <typename T> -T* MakeFromDefaultValueOrEmpty() { - return MakeFromDefaultValue<T>(EmptyBraces()); -} - } // namespace flags_internal ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/flags/internal/registry.cc b/absl/flags/internal/registry.cc index 5eae933c3fa3..ae5afd42ee36 100644 --- a/absl/flags/internal/registry.cc +++ b/absl/flags/internal/registry.cc @@ -277,9 +277,7 @@ namespace { class RetiredFlagObj final : public flags_internal::CommandLineFlag { public: constexpr RetiredFlagObj(const char* name, FlagOpFn ops) - : flags_internal::CommandLineFlag(name, - /*filename=*/"RETIRED"), - op_(ops) {} + : name_(name), op_(ops) {} private: void Destroy() override { @@ -287,6 +285,9 @@ class RetiredFlagObj final : public flags_internal::CommandLineFlag { delete this; } + absl::string_view Name() const override { return name_; } + std::string Filename() const override { return "RETIRED"; } + absl::string_view Typename() const override { return ""; } flags_internal::FlagOpFn TypeId() const override { return op_; } std::string Help() const override { return ""; } bool IsRetired() const override { return true; } @@ -312,6 +313,7 @@ class RetiredFlagObj final : public flags_internal::CommandLineFlag { void Read(void*) const override {} // Data members + const char* const name_; const FlagOpFn op_; }; |