diff options
Diffstat (limited to 'absl/flags/internal/type_erased.cc')
-rw-r--r-- | absl/flags/internal/type_erased.cc | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/absl/flags/internal/type_erased.cc b/absl/flags/internal/type_erased.cc new file mode 100644 index 000000000000..cc103983672b --- /dev/null +++ b/absl/flags/internal/type_erased.cc @@ -0,0 +1,121 @@ +// +// 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/type_erased.h" + +#include "absl/base/internal/raw_logging.h" +#include "absl/flags/config.h" +#include "absl/flags/usage_config.h" +#include "absl/strings/str_cat.h" + +namespace absl { +namespace flags_internal { + +bool GetCommandLineOption(absl::string_view name, std::string* value) { + if (name.empty()) return false; + assert(value); + + CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); + if (flag == nullptr || flag->IsRetired()) { + return false; + } + + absl::MutexLock l(InitFlagIfNecessary(flag)); + *value = flag->CurrentValue(); + return true; +} + +bool GetCommandLineFlagInfo(absl::string_view name, + CommandLineFlagInfo* OUTPUT) { + if (name.empty()) return false; + + CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); + if (flag == nullptr || flag->IsRetired()) { + return false; + } + + assert(OUTPUT); + FillCommandLineFlagInfo(flag, OUTPUT); + return true; +} + +CommandLineFlagInfo GetCommandLineFlagInfoOrDie(absl::string_view name) { + CommandLineFlagInfo info; + if (!GetCommandLineFlagInfo(name, &info)) { + ABSL_INTERNAL_LOG(FATAL, absl::StrCat("Flag '", name, "' does not exist")); + } + return info; +} + +// -------------------------------------------------------------------- + +bool SetCommandLineOption(absl::string_view name, absl::string_view value) { + return SetCommandLineOptionWithMode(name, value, + flags_internal::SET_FLAGS_VALUE); +} + +bool SetCommandLineOptionWithMode(absl::string_view name, + absl::string_view value, + FlagSettingMode set_mode) { + CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); + + if (!flag || flag->IsRetired()) return false; + + std::string error; + if (!flag->SetFromString(value, set_mode, kProgrammaticChange, &error)) { + // Errors here are all of the form: the provided name was a recognized + // flag, but the value was invalid (bad type, or validation failed). + flags_internal::ReportUsageError(error, false); + return false; + } + + return true; +} + +// -------------------------------------------------------------------- + +bool IsValidFlagValue(absl::string_view name, absl::string_view value) { + CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); + if (flag == nullptr) { + return false; + } + + if (flag->IsRetired()) { + return true; + } + + // No need to lock the flag since we are not mutating it. + void* obj = Clone(flag->op, flag->def); + std::string ignored_error; + const bool result = + flags_internal::Parse(flag->marshalling_op, value, obj, &ignored_error) && + Validate(flag, obj); + Delete(flag->op, obj); + return result; +} + +// -------------------------------------------------------------------- + +bool SpecifiedOnCommandLine(absl::string_view name) { + CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); + if (flag != nullptr && !flag->IsRetired()) { + absl::MutexLock l(InitFlagIfNecessary(flag)); + return flag->IsSpecifiedOnCommandLine(); + } + return false; +} + +} // namespace flags_internal +} // namespace absl |