1 | // |
2 | // Copyright 2019 The Abseil Authors. |
3 | // |
4 | // Licensed under the Apache License, Version 2.0 (the "License"); |
5 | // you may not use this file except in compliance with the License. |
6 | // You may obtain a copy of the License at |
7 | // |
8 | // https://www.apache.org/licenses/LICENSE-2.0 |
9 | // |
10 | // Unless required by applicable law or agreed to in writing, software |
11 | // distributed under the License is distributed on an "AS IS" BASIS, |
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | // See the License for the specific language governing permissions and |
14 | // limitations under the License. |
15 | |
16 | #include "absl/flags/internal/type_erased.h" |
17 | |
18 | #include "absl/base/internal/raw_logging.h" |
19 | #include "absl/flags/config.h" |
20 | #include "absl/flags/usage_config.h" |
21 | #include "absl/strings/str_cat.h" |
22 | |
23 | namespace absl { |
24 | namespace flags_internal { |
25 | |
26 | bool GetCommandLineOption(absl::string_view name, std::string* value) { |
27 | if (name.empty()) return false; |
28 | assert(value); |
29 | |
30 | CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); |
31 | if (flag == nullptr || flag->IsRetired()) { |
32 | return false; |
33 | } |
34 | |
35 | absl::MutexLock l(InitFlagIfNecessary(flag)); |
36 | *value = flag->CurrentValue(); |
37 | return true; |
38 | } |
39 | |
40 | bool GetCommandLineFlagInfo(absl::string_view name, |
41 | CommandLineFlagInfo* OUTPUT) { |
42 | if (name.empty()) return false; |
43 | |
44 | CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); |
45 | if (flag == nullptr || flag->IsRetired()) { |
46 | return false; |
47 | } |
48 | |
49 | assert(OUTPUT); |
50 | FillCommandLineFlagInfo(flag, OUTPUT); |
51 | return true; |
52 | } |
53 | |
54 | CommandLineFlagInfo GetCommandLineFlagInfoOrDie(absl::string_view name) { |
55 | CommandLineFlagInfo info; |
56 | if (!GetCommandLineFlagInfo(name, &info)) { |
57 | ABSL_INTERNAL_LOG(FATAL, absl::StrCat("Flag '" , name, "' does not exist" )); |
58 | } |
59 | return info; |
60 | } |
61 | |
62 | // -------------------------------------------------------------------- |
63 | |
64 | bool SetCommandLineOption(absl::string_view name, absl::string_view value) { |
65 | return SetCommandLineOptionWithMode(name, value, |
66 | flags_internal::SET_FLAGS_VALUE); |
67 | } |
68 | |
69 | bool SetCommandLineOptionWithMode(absl::string_view name, |
70 | absl::string_view value, |
71 | FlagSettingMode set_mode) { |
72 | CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); |
73 | |
74 | if (!flag || flag->IsRetired()) return false; |
75 | |
76 | std::string error; |
77 | if (!flag->SetFromString(value, set_mode, kProgrammaticChange, &error)) { |
78 | // Errors here are all of the form: the provided name was a recognized |
79 | // flag, but the value was invalid (bad type, or validation failed). |
80 | flags_internal::ReportUsageError(error, false); |
81 | return false; |
82 | } |
83 | |
84 | return true; |
85 | } |
86 | |
87 | // -------------------------------------------------------------------- |
88 | |
89 | bool IsValidFlagValue(absl::string_view name, absl::string_view value) { |
90 | CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); |
91 | if (flag == nullptr) { |
92 | return false; |
93 | } |
94 | |
95 | if (flag->IsRetired()) { |
96 | return true; |
97 | } |
98 | |
99 | // No need to lock the flag since we are not mutating it. |
100 | void* obj = Clone(flag->op, flag->def); |
101 | std::string ignored_error; |
102 | const bool result = |
103 | flags_internal::Parse(flag->marshalling_op, value, obj, &ignored_error) && |
104 | Validate(flag, obj); |
105 | Delete(flag->op, obj); |
106 | return result; |
107 | } |
108 | |
109 | // -------------------------------------------------------------------- |
110 | |
111 | bool SpecifiedOnCommandLine(absl::string_view name) { |
112 | CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); |
113 | if (flag != nullptr && !flag->IsRetired()) { |
114 | absl::MutexLock l(InitFlagIfNecessary(flag)); |
115 | return flag->IsSpecifiedOnCommandLine(); |
116 | } |
117 | return false; |
118 | } |
119 | |
120 | } // namespace flags_internal |
121 | } // namespace absl |
122 | |