All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
commandlineflags.cpp
Go to the documentation of this file.
1 #include "commandlineflags.h"
2 
3 #ifdef USE_STD_NAMESPACE
4 
5 namespace tesseract {
6 bool IntFlagExists(const char* flag_name, inT32* value) {
7  STRING full_flag_name("FLAGS_");
8  full_flag_name += flag_name;
10  IntParam *p = ParamUtils::FindParam<IntParam>(
11  full_flag_name.string(), GlobalParams()->int_params, empty);
12  if (p == NULL) return false;
13  *value = (inT32)(*p);
14  return true;
15 }
16 
17 bool DoubleFlagExists(const char* flag_name, double* value) {
18  STRING full_flag_name("FLAGS_");
19  full_flag_name += flag_name;
21  DoubleParam *p = ParamUtils::FindParam<DoubleParam>(
22  full_flag_name.string(), GlobalParams()->double_params, empty);
23  if (p == NULL) return false;
24  *value = static_cast<double>(*p);
25  return true;
26 }
27 
28 bool BoolFlagExists(const char* flag_name, bool* value) {
29  STRING full_flag_name("FLAGS_");
30  full_flag_name += flag_name;
32  BoolParam *p = ParamUtils::FindParam<BoolParam>(
33  full_flag_name.string(), GlobalParams()->bool_params, empty);
34  if (p == NULL) return false;
35  *value = (BOOL8)(*p);
36  return true;
37 }
38 
39 bool StringFlagExists(const char* flag_name, const char** value) {
40  STRING full_flag_name("FLAGS_");
41  full_flag_name += flag_name;
43  StringParam *p = ParamUtils::FindParam<StringParam>(
44  full_flag_name.string(), GlobalParams()->string_params, empty);
45  *value = (p != NULL) ? p->string() : NULL;
46  return p != NULL;
47 }
48 
49 
50 void SetIntFlagValue(const char* flag_name, const inT32 new_val) {
51  STRING full_flag_name("FLAGS_");
52  full_flag_name += flag_name;
54  IntParam *p = ParamUtils::FindParam<IntParam>(
55  full_flag_name.string(), GlobalParams()->int_params, empty);
56  ASSERT_HOST(p != NULL);
57  p->set_value(new_val);
58 }
59 
60 void SetDoubleFlagValue(const char* flag_name, const double new_val) {
61  STRING full_flag_name("FLAGS_");
62  full_flag_name += flag_name;
64  DoubleParam *p = ParamUtils::FindParam<DoubleParam>(
65  full_flag_name.string(), GlobalParams()->double_params, empty);
66  ASSERT_HOST(p != NULL);
67  p->set_value(new_val);
68 }
69 
70 void SetBoolFlagValue(const char* flag_name, const bool new_val) {
71  STRING full_flag_name("FLAGS_");
72  full_flag_name += flag_name;
74  BoolParam *p = ParamUtils::FindParam<BoolParam>(
75  full_flag_name.string(), GlobalParams()->bool_params, empty);
76  ASSERT_HOST(p != NULL);
77  p->set_value(new_val);
78 }
79 
80 void SetStringFlagValue(const char* flag_name, const char* new_val) {
81  STRING full_flag_name("FLAGS_");
82  full_flag_name += flag_name;
84  StringParam *p = ParamUtils::FindParam<StringParam>(
85  full_flag_name.string(), GlobalParams()->string_params, empty);
86  ASSERT_HOST(p != NULL);
87  p->set_value(STRING(new_val));
88 }
89 
90 bool SafeAtoi(const char* str, int* val) {
91  char *endptr = NULL;
92  *val = strtol(str, &endptr, 10);
93  return endptr != NULL && *endptr == '\0';
94 }
95 
96 bool SafeAtod(const char* str, double* val) {
97  char *endptr = NULL;
98  *val = strtod(str, &endptr);
99  return endptr != NULL && *endptr == '\0';
100 }
101 
102 void PrintCommandLineFlags() {
103  const char* kFlagNamePrefix = "FLAGS_";
104  const int kFlagNamePrefixLen = strlen(kFlagNamePrefix);
105  for (int i = 0; i < GlobalParams()->int_params.size(); ++i) {
106  if (!strncmp(GlobalParams()->int_params[i]->name_str(),
107  kFlagNamePrefix, kFlagNamePrefixLen)) {
108  tprintf(" --%s %s (type:int default:%d)\n",
109  GlobalParams()->int_params[i]->name_str() + kFlagNamePrefixLen,
110  GlobalParams()->int_params[i]->info_str(),
111  inT32(*(GlobalParams()->int_params[i])));
112  }
113  }
114  for (int i = 0; i < GlobalParams()->double_params.size(); ++i) {
115  if (!strncmp(GlobalParams()->double_params[i]->name_str(),
116  kFlagNamePrefix, kFlagNamePrefixLen)) {
117  tprintf(" --%s %s (type:double default:%g)\n",
118  GlobalParams()->double_params[i]->name_str() + kFlagNamePrefixLen,
119  GlobalParams()->double_params[i]->info_str(),
120  static_cast<double>(*(GlobalParams()->double_params[i])));
121  }
122  }
123  for (int i = 0; i < GlobalParams()->bool_params.size(); ++i) {
124  if (!strncmp(GlobalParams()->bool_params[i]->name_str(),
125  kFlagNamePrefix, kFlagNamePrefixLen)) {
126  tprintf(" --%s %s (type:bool default:%s)\n",
127  GlobalParams()->bool_params[i]->name_str() + kFlagNamePrefixLen,
128  GlobalParams()->bool_params[i]->info_str(),
129  (BOOL8(*(GlobalParams()->bool_params[i])) ? "true" : "false"));
130  }
131  }
132  for (int i = 0; i < GlobalParams()->string_params.size(); ++i) {
133  if (!strncmp(GlobalParams()->string_params[i]->name_str(),
134  kFlagNamePrefix, kFlagNamePrefixLen)) {
135  tprintf(" --%s %s (type:string default:%s)\n",
136  GlobalParams()->string_params[i]->name_str() + kFlagNamePrefixLen,
137  GlobalParams()->string_params[i]->info_str(),
138  GlobalParams()->string_params[i]->string());
139  }
140  }
141 }
142 
143 
144 void ParseCommandLineFlags(const char* usage,
145  int* argc, char*** argv,
146  const bool remove_flags) {
147  unsigned int i = 1;
148  for (i = 1; i < *argc; ++i) {
149  const char* current_arg = (*argv)[i];
150  // If argument does not start with a hyphen then break.
151  if (current_arg[0] != '-') {
152  break;
153  }
154  // Position current_arg after startings hyphens. We treat a sequence of
155  // consecutive hyphens of any length identically.
156  while (*current_arg == '-') {
157  ++current_arg;
158  }
159  // If this is asking for usage, print the help message and abort.
160  if (!strcmp(current_arg, "help") ||
161  !strcmp(current_arg, "helpshort")) {
162  tprintf("USAGE: %s\n", usage);
163  PrintCommandLineFlags();
164  exit(0);
165  }
166  // Find the starting position of the value if it was specified in this
167  // string.
168  const char* equals_position = strchr(current_arg, '=');
169  const char* rhs = NULL;
170  if (equals_position != NULL) {
171  rhs = equals_position + 1;
172  }
173  // Extract the flag name.
174  STRING lhs;
175  if (equals_position == NULL) {
176  lhs = current_arg;
177  } else {
178  lhs.assign(current_arg, equals_position - current_arg);
179  }
180  if (!lhs.length()) {
181  tprintf("ERROR: Bad argument: %s\n", (*argv)[i]);
182  exit(1);
183  }
184 
185  // Find the flag name in the list of global flags.
186  // inT32 flag
187  inT32 int_val;
188  if (IntFlagExists(lhs.string(), &int_val)) {
189  if (rhs != NULL) {
190  if (!strlen(rhs)) {
191  // Bad input of the format --int_flag=
192  tprintf("ERROR: Bad argument: %s\n", (*argv)[i]);
193  exit(1);
194  }
195  if (!SafeAtoi(rhs, &int_val)) {
196  tprintf("ERROR: Could not parse int from %s in flag %s\n",
197  rhs, (*argv)[i]);
198  exit(1);
199  }
200  } else {
201  // We need to parse the next argument
202  if (i + 1 >= *argc) {
203  tprintf("ERROR: Could not find value argument for flag %s\n",
204  lhs.string());
205  exit(1);
206  } else {
207  ++i;
208  if (!SafeAtoi((*argv)[i], &int_val)) {
209  tprintf("ERROR: Could not parse inT32 from %s\n", (*argv)[i]);
210  exit(1);
211  }
212  }
213  }
214  SetIntFlagValue(lhs.string(), int_val);
215  continue;
216  }
217 
218  // double flag
219  double double_val;
220  if (DoubleFlagExists(lhs.string(), &double_val)) {
221  if (rhs != NULL) {
222  if (!strlen(rhs)) {
223  // Bad input of the format --double_flag=
224  tprintf("ERROR: Bad argument: %s\n", (*argv)[i]);
225  exit(1);
226  }
227  if (!SafeAtod(rhs, &double_val)) {
228  tprintf("ERROR: Could not parse double from %s in flag %s\n",
229  rhs, (*argv)[i]);
230  exit(1);
231  }
232  } else {
233  // We need to parse the next argument
234  if (i + 1 >= *argc) {
235  tprintf("ERROR: Could not find value argument for flag %s\n",
236  lhs.string());
237  exit(1);
238  } else {
239  ++i;
240  if (!SafeAtod((*argv)[i], &double_val)) {
241  tprintf("ERROR: Could not parse double from %s\n", (*argv)[i]);
242  exit(1);
243  }
244  }
245  }
246  SetDoubleFlagValue(lhs.string(), double_val);
247  continue;
248  }
249 
250  // Bool flag. Allow input forms --flag (equivalent to --flag=true),
251  // --flag=false, --flag=true, --flag=0 and --flag=1
252  bool bool_val;
253  if (BoolFlagExists(lhs.string(), &bool_val)) {
254  if (rhs == NULL) {
255  // --flag form
256  bool_val = true;
257  } else {
258  if (!strlen(rhs)) {
259  // Bad input of the format --bool_flag=
260  tprintf("ERROR: Bad argument: %s\n", (*argv)[i]);
261  exit(1);
262  }
263  if (!strcmp(rhs, "false") || !strcmp(rhs, "0")) {
264  bool_val = false;
265  } else if (!strcmp(rhs, "true") || !strcmp(rhs, "1")) {
266  bool_val = true;
267  } else {
268  tprintf("ERROR: Could not parse bool from flag %s\n", (*argv)[i]);
269  exit(1);
270  }
271  }
272  SetBoolFlagValue(lhs.string(), bool_val);
273  continue;
274  }
275 
276  // string flag
277  const char* string_val;
278  if (StringFlagExists(lhs.string(), &string_val)) {
279  if (rhs != NULL) {
280  string_val = rhs;
281  } else {
282  // Pick the next argument
283  if (i + 1 >= *argc) {
284  tprintf("ERROR: Could not find string value for flag %s\n",
285  lhs.string());
286  exit(1);
287  } else {
288  string_val = (*argv)[++i];
289  }
290  }
291  SetStringFlagValue(lhs.string(), string_val);
292  continue;
293  }
294 
295  // Flag was not found. Exit with an error message.
296  tprintf("ERROR: Non-existent flag %s\n", (*argv)[i]);
297  exit(1);
298  } // for each argv
299  if (remove_flags) {
300  (*argv)[i - 1] = (*argv)[0];
301  (*argv) += (i - 1);
302  (*argc) -= (i - 1);
303  }
304 }
305 } // namespace tesseract
306 
307 #else
308 
309 #include "base/init_google.h"
310 
311 namespace tesseract {
312 void ParseCommandLineFlags(const char* usage,
313  int* argc, char*** argv,
314  const bool remove_flags) {
315  InitGoogle(usage, argc, argv, remove_flags);
316 }
317 } // namespace tesseract
318 
319 #endif
#define tprintf(...)
Definition: tprintf.h:31
void ParseCommandLineFlags(const char *usage, int *argc, char ***argv, const bool remove_flags)
unsigned char BOOL8
Definition: host.h:113
inT32 length() const
Definition: strngs.cpp:188
#define ASSERT_HOST(x)
Definition: errcode.h:84
GenericVector< IntParam * > int_params
Definition: params.h:44
GenericVector< BoolParam * > bool_params
Definition: params.h:45
void assign(const char *cstr, int len)
Definition: strngs.cpp:417
GenericVector< DoubleParam * > double_params
Definition: params.h:47
Definition: strngs.h:44
tesseract::ParamsVectors * GlobalParams()
Definition: params.cpp:33
#define NULL
Definition: host.h:144
const char * string() const
Definition: strngs.cpp:193
GenericVector< StringParam * > string_params
Definition: params.h:46
int inT32
Definition: host.h:102