| // flags.cc |
| // |
| // 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 |
| // |
| // http://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. |
| // |
| // Author: [email protected] (Michael Riley) |
| // |
| // \file |
| // Google-style flag handling definitions |
| |
| #include <cstring> |
| |
| #include <fst/compat.h> |
| #include <fst/flags.h> |
| |
| DEFINE_int32(v, 0, "verbose level"); |
| DEFINE_bool(help, false, "show usage information"); |
| DEFINE_bool(helpshort, false, "show brief usage information"); |
| DEFINE_string(tmpdir, "/tmp/", "temporary directory"); |
| |
| using namespace std; |
| |
| static string flag_usage; |
| static string prog_src; |
| |
| void SetFlags(const char *usage, int *argc, char ***argv, |
| bool remove_flags, const char *src) { |
| flag_usage = usage; |
| prog_src = src; |
| int index = 1; |
| for (; index < *argc; ++index) { |
| string argval = (*argv)[index]; |
| |
| if (argval[0] != '-' || argval == "-") |
| break; |
| while (argval[0] == '-') |
| argval = argval.substr(1); // remove initial '-'s |
| |
| string arg = argval; |
| string val = ""; |
| |
| // split argval (arg=val) into arg and val |
| size_t pos = argval.find("="); |
| if (pos != string::npos) { |
| arg = argval.substr(0, pos); |
| val = argval.substr(pos + 1); |
| } |
| |
| FlagRegister<bool> *bool_register = |
| FlagRegister<bool>::GetRegister(); |
| if (bool_register->SetFlag(arg, val)) |
| continue; |
| FlagRegister<string> *string_register = |
| FlagRegister<string>::GetRegister(); |
| if (string_register->SetFlag(arg, val)) |
| continue; |
| FlagRegister<int32> *int32_register = |
| FlagRegister<int32>::GetRegister(); |
| if (int32_register->SetFlag(arg, val)) |
| continue; |
| FlagRegister<int64> *int64_register = |
| FlagRegister<int64>::GetRegister(); |
| if (int64_register->SetFlag(arg, val)) |
| continue; |
| FlagRegister<double> *double_register = |
| FlagRegister<double>::GetRegister(); |
| if (double_register->SetFlag(arg, val)) |
| continue; |
| |
| LOG(FATAL) << "SetFlags: Bad option: " << (*argv)[index]; |
| } |
| |
| if (remove_flags) { |
| for (int i = 0; i < *argc - index; ++i) |
| (*argv)[i + 1] = (*argv)[i + index]; |
| *argc -= index - 1; |
| } |
| |
| if (FLAGS_help) { |
| ShowUsage(true); |
| exit(1); |
| } |
| |
| if (FLAGS_helpshort) { |
| ShowUsage(false); |
| exit(1); |
| } |
| } |
| |
| // If flag is defined in file 'src' and 'in_src' true or is not |
| // defined in file 'src' and 'in_src' is false, then print usage. |
| static void |
| ShowUsageRestrict(const std::set< pair<string, string> > &usage_set, |
| const string &src, bool in_src, bool show_file) { |
| string old_file; |
| bool file_out = false; |
| bool usage_out = false; |
| for (std::set< pair<string, string> >::const_iterator it = |
| usage_set.begin(); |
| it != usage_set.end(); |
| ++it) { |
| const string &file = it->first; |
| const string &usage = it->second; |
| |
| bool match = file == src; |
| if ((match && !in_src) || (!match && in_src)) |
| continue; |
| |
| if (file != old_file) { |
| if (show_file) { |
| if (file_out) cout << "\n"; |
| cout << "Flags from: " << file << "\n"; |
| file_out = true; |
| } |
| old_file = file; |
| } |
| cout << usage << "\n"; |
| usage_out = true; |
| } |
| if (usage_out) cout << "\n"; |
| } |
| |
| void ShowUsage(bool long_usage) { |
| std::set< pair<string, string> > usage_set; |
| |
| cout << flag_usage << "\n"; |
| |
| FlagRegister<bool> *bool_register = FlagRegister<bool>::GetRegister(); |
| bool_register->GetUsage(&usage_set); |
| FlagRegister<string> *string_register = FlagRegister<string>::GetRegister(); |
| string_register->GetUsage(&usage_set); |
| FlagRegister<int32> *int32_register = FlagRegister<int32>::GetRegister(); |
| int32_register->GetUsage(&usage_set); |
| FlagRegister<int64> *int64_register = FlagRegister<int64>::GetRegister(); |
| int64_register->GetUsage(&usage_set); |
| FlagRegister<double> *double_register = FlagRegister<double>::GetRegister(); |
| double_register->GetUsage(&usage_set); |
| |
| if (!prog_src.empty()) { |
| cout << "PROGRAM FLAGS:\n\n"; |
| ShowUsageRestrict(usage_set, prog_src, true, false); |
| } |
| |
| if (!long_usage) |
| return; |
| |
| if (!prog_src.empty()) |
| cout << "LIBRARY FLAGS:\n\n"; |
| |
| ShowUsageRestrict(usage_set, prog_src, false, true); |
| } |