FST  openfst-1.8.1
OpenFst Library
flags.cc
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 //
13 // Google-style flag handling definitions.
14 
15 #include <cstring>
16 #include <string>
17 
18 #include <fst/compat.h>
19 #include <fst/flags.h>
20 
21 static const char *private_tmpdir = getenv("TMPDIR");
22 
23 DEFINE_int32(v, 0, "verbosity level");
24 DEFINE_bool(help, false, "show usage information");
25 DEFINE_bool(helpshort, false, "show brief usage information");
26 DEFINE_string(tmpdir, private_tmpdir ? private_tmpdir : "/tmp",
27  "temporary directory");
28 
29 static std::string flag_usage;
30 static std::string prog_src;
31 
32 // Sets prog_src to src.
33 static void SetProgSrc(const char *src) {
34  prog_src = src;
35  // Remove "-main" in src filename. Flags are defined in fstx.cc but SetFlags()
36  // is called in fstx-main.cc, which results in a filename mismatch in
37  // ShowUsageRestrict() below.
38  static constexpr char kMainSuffix[] = "-main.cc";
39  const int prefix_length = prog_src.size() - strlen(kMainSuffix);
40  if (prefix_length > 0 && prog_src.substr(prefix_length) == kMainSuffix) {
41  prog_src.erase(prefix_length, strlen("-main"));
42  }
43 }
44 
45 void SetFlags(const char *usage, int *argc, char ***argv,
46  bool remove_flags, const char *src) {
47  flag_usage = usage;
48  SetProgSrc(src);
49 
50  int index = 1;
51  for (; index < *argc; ++index) {
52  std::string argval = (*argv)[index];
53  if (argval[0] != '-' || argval == "-") break;
54  while (argval[0] == '-') argval = argval.substr(1); // Removes initial '-'.
55  std::string arg = argval;
56  std::string val = "";
57  // Splits argval (arg=val) into arg and val.
58  auto pos = argval.find("=");
59  if (pos != std::string::npos) {
60  arg = argval.substr(0, pos);
61  val = argval.substr(pos + 1);
62  }
63  auto bool_register = FlagRegister<bool>::GetRegister();
64  if (bool_register->SetFlag(arg, val))
65  continue;
66  auto string_register = FlagRegister<std::string>::GetRegister();
67  if (string_register->SetFlag(arg, val)) continue;
68  auto int32_register = FlagRegister<int32>::GetRegister();
69  if (int32_register->SetFlag(arg, val)) continue;
70  auto int64_register = FlagRegister<int64>::GetRegister();
71  if (int64_register->SetFlag(arg, val)) continue;
72  auto uint64_register = FlagRegister<uint64>::GetRegister();
73  if (uint64_register->SetFlag(arg, val)) continue;
74  auto double_register = FlagRegister<double>::GetRegister();
75  if (double_register->SetFlag(arg, val)) continue;
76  LOG(FATAL) << "SetFlags: Bad option: " << (*argv)[index];
77  }
78  if (remove_flags) {
79  for (auto i = 0; i < *argc - index; ++i) {
80  (*argv)[i + 1] = (*argv)[i + index];
81  }
82  *argc -= index - 1;
83  }
84  if (FST_FLAGS_help) {
85  ShowUsage(true);
86  exit(1);
87  }
88  if (FST_FLAGS_helpshort) {
89  ShowUsage(false);
90  exit(1);
91  }
92 }
93 
94 // If flag is defined in file 'src' and 'in_src' true or is not
95 // defined in file 'src' and 'in_src' is false, then print usage.
96 static void ShowUsageRestrict(
97  const std::set<std::pair<std::string, std::string>> &usage_set,
98  const std::string &src, bool in_src, bool show_file) {
99  std::string old_file;
100  bool file_out = false;
101  bool usage_out = false;
102  for (const auto &pair : usage_set) {
103  const auto &file = pair.first;
104  const auto &usage = pair.second;
105  bool match = file == src;
106  if ((match && !in_src) || (!match && in_src)) continue;
107  if (file != old_file) {
108  if (show_file) {
109  if (file_out) std::cout << std::endl;;
110  std::cout << "Flags from: " << file << std::endl;
111  file_out = true;
112  }
113  old_file = file;
114  }
115  std::cout << usage << std::endl;
116  ;
117  usage_out = true;
118  }
119  if (usage_out) std::cout << std::endl;
120  ;
121 }
122 
123 void ShowUsage(bool long_usage) {
124  std::set<std::pair<std::string, std::string>> usage_set;
125  std::cout << flag_usage << std::endl;
126  ;
127  auto bool_register = FlagRegister<bool>::GetRegister();
128  bool_register->GetUsage(&usage_set);
129  auto string_register = FlagRegister<std::string>::GetRegister();
130  string_register->GetUsage(&usage_set);
131  auto int32_register = FlagRegister<int32>::GetRegister();
132  int32_register->GetUsage(&usage_set);
133  auto int64_register = FlagRegister<int64>::GetRegister();
134  int64_register->GetUsage(&usage_set);
135  auto uint64_register = FlagRegister<uint64>::GetRegister();
136  uint64_register->GetUsage(&usage_set);
137  auto double_register = FlagRegister<double>::GetRegister();
138  double_register->GetUsage(&usage_set);
139  if (!prog_src.empty()) {
140  std::cout << "PROGRAM FLAGS:" << std::endl << std::endl;
141  ;
142  ShowUsageRestrict(usage_set, prog_src, true, false);
143  }
144  if (!long_usage) return;
145  if (!prog_src.empty()) {
146  std::cout << "LIBRARY FLAGS:" << std::endl << std::endl;
147  }
148  ShowUsageRestrict(usage_set, prog_src, false, true);
149 }
#define LOG(type)
Definition: log.h:46
static FlagRegister< T > * GetRegister()
Definition: flags.h:76
DEFINE_bool(help, false,"show usage information")
void SetFlags(const char *usage, int *argc, char ***argv, bool remove_flags, const char *src)
Definition: flags.cc:45
DEFINE_int32(v, 0,"verbosity level")
DEFINE_string(tmpdir, private_tmpdir?private_tmpdir:"/tmp","temporary directory")
void ShowUsage(bool long_usage)
Definition: flags.cc:123