FST  openfst-1.8.3
OpenFst Library
flags.h
Go to the documentation of this file.
1 // Copyright 2005-2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the 'License');
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an 'AS IS' BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // See www.openfst.org for extensive documentation on this weighted
16 // finite-state transducer library.
17 //
18 // Google-style flag handling declarations and inline definitions.
19 
20 #ifndef FST_FLAGS_H_
21 #define FST_FLAGS_H_
22 
23 #include <cstdint>
24 #include <cstdlib>
25 #include <iostream>
26 #include <map>
27 #include <set>
28 #include <sstream>
29 #include <string>
30 #include <string_view>
31 #include <utility>
32 
33 #include <fst/lock.h>
34 
35 // FLAGS USAGE:
36 //
37 // Definition example:
38 //
39 // DEFINE_int32(length, 0, "length");
40 //
41 // This defines variable FST_FLAGS_length, initialized to 0.
42 //
43 // Declaration example:
44 //
45 // DECLARE_int32(length);
46 //
47 // SET_FLAGS() can be used to set flags from the command line
48 // using, for example, '--length=2'.
49 //
50 // ShowUsage() can be used to print out command and flag usage.
51 
52 #define DECLARE_bool(name) extern bool FST_FLAGS_ ## name
53 #define DECLARE_string(name) extern std::string FST_FLAGS_##name
54 #define DECLARE_int32(name) extern int32_t FST_FLAGS_##name
55 #define DECLARE_int64(name) extern int64_t FST_FLAGS_##name
56 #define DECLARE_uint64(name) extern uint64_t FST_FLAGS_##name
57 #define DECLARE_double(name) extern double FST_FLAGS_ ## name
58 
59 template <typename T>
61  FlagDescription(T *addr, std::string_view doc, std::string_view type,
62  std::string_view file, const T val)
63  : address(addr),
64  doc_string(doc),
65  type_name(type),
66  file_name(file),
67  default_value(val) {}
68 
69  T *address;
70  std::string_view doc_string;
71  std::string_view type_name;
72  std::string_view file_name;
73  const T default_value;
74 };
75 
76 template <typename T>
77 class FlagRegister {
78  public:
80  static auto reg = new FlagRegister<T>;
81  return reg;
82  }
83 
84  const FlagDescription<T> &GetFlagDescription(const std::string &name) const {
85  fst::MutexLock l(&flag_lock_);
86  auto it = flag_table_.find(name);
87  return it != flag_table_.end() ? it->second : 0;
88  }
89 
90  void SetDescription(const std::string &name, const FlagDescription<T> &desc) {
91  fst::MutexLock l(&flag_lock_);
92  flag_table_.insert(std::make_pair(name, desc));
93  }
94 
95  bool SetFlag(const std::string &val, bool *address) const {
96  if (val == "true" || val == "1" || val.empty()) {
97  *address = true;
98  return true;
99  } else if (val == "false" || val == "0") {
100  *address = false;
101  return true;
102  } else {
103  return false;
104  }
105  }
106 
107  bool SetFlag(const std::string &val, std::string *address) const {
108  *address = val;
109  return true;
110  }
111 
112  bool SetFlag(const std::string &val, int32_t *address) const {
113  char *p = nullptr;
114  *address = strtol(val.c_str(), &p, 0);
115  return !val.empty() && *p == '\0';
116  }
117 
118  bool SetFlag(const std::string &val, int64_t *address) const {
119  char *p = nullptr;
120  *address = strtoll(val.c_str(), &p, 0);
121  return !val.empty() && *p == '\0';
122  }
123 
124  bool SetFlag(const std::string &val, uint64_t *address) const {
125  char *p = nullptr;
126  *address = strtoull(val.c_str(), &p, 0);
127  return !val.empty() && *p == '\0';
128  }
129 
130  bool SetFlag(const std::string &val, double *address) const {
131  char *p = nullptr;
132  *address = strtod(val.c_str(), &p);
133  return !val.empty() && *p == '\0';
134  }
135 
136  bool SetFlag(const std::string &arg, const std::string &val) const {
137  for (const auto &kv : flag_table_) {
138  const auto &name = kv.first;
139  const FlagDescription<T> &desc = kv.second;
140  if (arg == name) return SetFlag(val, desc.address);
141  }
142  return false;
143  }
144 
145  void GetUsage(
146  std::set<std::pair<std::string, std::string>> *usage_set) const {
147  for (auto it = flag_table_.begin(); it != flag_table_.end(); ++it) {
148  const auto &name = it->first;
149  const FlagDescription<T> &desc = it->second;
150  std::string usage = " --" + name;
151  usage += ": type = ";
152  usage += desc.type_name;
153  usage += ", default = ";
154  usage += GetDefault(desc.default_value) + "\n ";
155  usage += desc.doc_string;
156  usage_set->insert(std::make_pair(std::string(desc.file_name), usage));
157  }
158  }
159 
160  private:
161  std::string GetDefault(bool default_value) const {
162  return default_value ? "true" : "false";
163  }
164 
165  std::string GetDefault(const std::string &default_value) const {
166  return "\"" + default_value + "\"";
167  }
168 
169  template <class V>
170  std::string GetDefault(const V &default_value) const {
171  std::ostringstream strm;
172  strm << default_value;
173  return strm.str();
174  }
175 
176  mutable fst::Mutex flag_lock_; // Multithreading lock.
177  std::map<std::string, FlagDescription<T>> flag_table_;
178 };
179 
180 template <typename T>
182  public:
183  FlagRegisterer(const std::string &name, const FlagDescription<T> &desc) {
184  auto registr = FlagRegister<T>::GetRegister();
185  registr->SetDescription(name, desc);
186  }
187 
188  private:
189  FlagRegisterer(const FlagRegisterer &) = delete;
190  FlagRegisterer &operator=(const FlagRegisterer &) = delete;
191 };
192 
193 
194 #define DEFINE_VAR(type, name, value, doc) \
195  type FST_FLAGS_ ## name = value; \
196  static FlagRegisterer<type> \
197  name ## _flags_registerer(#name, FlagDescription<type>(&FST_FLAGS_ ## name, \
198  doc, \
199  #type, \
200  __FILE__, \
201  value))
202 
203 #define DEFINE_bool(name, value, doc) DEFINE_VAR(bool, name, value, doc)
204 #define DEFINE_string(name, value, doc) \
205  DEFINE_VAR(std::string, name, value, doc)
206 #define DEFINE_int32(name, value, doc) DEFINE_VAR(int32_t, name, value, doc)
207 #define DEFINE_int64(name, value, doc) DEFINE_VAR(int64_t, name, value, doc)
208 #define DEFINE_uint64(name, value, doc) DEFINE_VAR(uint64_t, name, value, doc)
209 #define DEFINE_double(name, value, doc) DEFINE_VAR(double, name, value, doc)
210 
211 
212 // Temporary directory.
213 DECLARE_string(tmpdir);
214 
215 void SetFlags(const char *usage, int *argc, char ***argv, bool remove_flags,
216  const char *src = "");
217 
218 // This is an unpleasant hack around SetFlag API.
219 template <typename Type, typename Value>
220 void SetFlag(Type *flag, Value value) {
221  *flag = Type(value);
222 }
223 
224 void FailedNewHandler();
225 
226 #define SET_FLAGS(usage, argc, argv, rmflags) \
227 std::set_new_handler(FailedNewHandler); \
228 SetFlags(usage, argc, argv, rmflags, __FILE__)
229 
230 // Deprecated; for backward compatibility.
231 inline void InitFst(const char *usage, int *argc, char ***argv, bool rmflags) {
232  return SetFlags(usage, argc, argv, rmflags);
233 }
234 
235 void ShowUsage(bool long_usage = true);
236 
237 #endif // FST_FLAGS_H_
void ShowUsage(bool long_usage=true)
Definition: flags.cc:138
std::string_view doc_string
Definition: flags.h:70
void InitFst(const char *usage, int *argc, char ***argv, bool rmflags)
Definition: flags.h:231
T * address
Definition: flags.h:69
bool SetFlag(const std::string &val, double *address) const
Definition: flags.h:130
bool SetFlag(const std::string &val, std::string *address) const
Definition: flags.h:107
bool SetFlag(const std::string &val, bool *address) const
Definition: flags.h:95
const FlagDescription< T > & GetFlagDescription(const std::string &name) const
Definition: flags.h:84
void SetFlags(const char *usage, int *argc, char ***argv, bool remove_flags, const char *src="")
Definition: flags.cc:57
static FlagRegister< T > * GetRegister()
Definition: flags.h:79
bool SetFlag(const std::string &val, int64_t *address) const
Definition: flags.h:118
const T default_value
Definition: flags.h:73
std::string_view file_name
Definition: flags.h:72
FlagDescription(T *addr, std::string_view doc, std::string_view type, std::string_view file, const T val)
Definition: flags.h:61
bool SetFlag(const std::string &arg, const std::string &val) const
Definition: flags.h:136
void GetUsage(std::set< std::pair< std::string, std::string >> *usage_set) const
Definition: flags.h:145
#define DECLARE_string(name)
Definition: flags.h:53
FlagRegisterer(const std::string &name, const FlagDescription< T > &desc)
Definition: flags.h:183
void FailedNewHandler()
Definition: flags.cc:133
std::string_view type_name
Definition: flags.h:71
bool SetFlag(const std::string &val, int32_t *address) const
Definition: flags.h:112
void SetDescription(const std::string &name, const FlagDescription< T > &desc)
Definition: flags.h:90
void SetFlag(Type *flag, Value value)
Definition: flags.h:220
bool SetFlag(const std::string &val, uint64_t *address) const
Definition: flags.h:124