• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // flags.cc
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 // Author: riley@google.com (Michael Riley)
16 //
17 // \file
18 // Google-style flag handling definitions
19 
20 #include <cstring>
21 
22 #include <fst/compat.h>
23 #include <fst/flags.h>
24 
25 DEFINE_int32(v, 0, "verbose level");
26 DEFINE_bool(help, false, "show usage information");
27 DEFINE_bool(helpshort, false, "show brief usage information");
28 DEFINE_string(tmpdir, "/tmp/", "temporary directory");
29 
30 using namespace std;
31 
32 static string flag_usage;
33 static string prog_src;
34 
SetFlags(const char * usage,int * argc,char *** argv,bool remove_flags,const char * src)35 void SetFlags(const char *usage, int *argc, char ***argv,
36               bool remove_flags, const char *src) {
37   flag_usage = usage;
38   prog_src = src;
39   int index = 1;
40   for (; index < *argc; ++index) {
41     string argval = (*argv)[index];
42 
43     if (argval[0] != '-' || argval == "-")
44       break;
45     while (argval[0] == '-')
46       argval = argval.substr(1);  // remove initial '-'s
47 
48     string arg = argval;
49     string val = "";
50 
51     // split argval (arg=val) into arg and val
52     size_t pos = argval.find("=");
53     if (pos != string::npos) {
54       arg = argval.substr(0, pos);
55       val = argval.substr(pos + 1);
56     }
57 
58     FlagRegister<bool> *bool_register =
59       FlagRegister<bool>::GetRegister();
60     if (bool_register->SetFlag(arg, val))
61       continue;
62     FlagRegister<string> *string_register =
63       FlagRegister<string>::GetRegister();
64     if (string_register->SetFlag(arg, val))
65       continue;
66     FlagRegister<int32> *int32_register =
67       FlagRegister<int32>::GetRegister();
68     if (int32_register->SetFlag(arg, val))
69       continue;
70     FlagRegister<int64> *int64_register =
71       FlagRegister<int64>::GetRegister();
72     if (int64_register->SetFlag(arg, val))
73       continue;
74     FlagRegister<double> *double_register =
75       FlagRegister<double>::GetRegister();
76     if (double_register->SetFlag(arg, val))
77       continue;
78 
79     LOG(FATAL) << "SetFlags: Bad option: " << (*argv)[index];
80   }
81 
82   if (remove_flags) {
83     for (int i = 0; i < *argc - index; ++i)
84       (*argv)[i + 1] = (*argv)[i + index];
85     *argc -= index - 1;
86   }
87 
88   if (FLAGS_help) {
89     ShowUsage(true);
90     exit(1);
91   }
92 
93   if (FLAGS_helpshort) {
94     ShowUsage(false);
95     exit(1);
96   }
97 }
98 
99 // If flag is defined in file 'src' and 'in_src' true or is not
100 // defined in file 'src' and 'in_src' is false, then print usage.
101 static void
ShowUsageRestrict(const std::set<pair<string,string>> & usage_set,const string & src,bool in_src,bool show_file)102 ShowUsageRestrict(const std::set< pair<string, string> > &usage_set,
103 		  const string &src, bool in_src, bool show_file) {
104   string old_file;
105   bool file_out = false;
106   bool usage_out = false;
107   for (std::set< pair<string, string> >::const_iterator it =
108 	 usage_set.begin();
109        it != usage_set.end();
110        ++it) {
111     const string &file = it->first;
112     const string &usage = it->second;
113 
114     bool match = file == src;
115     if ((match && !in_src) || (!match && in_src))
116       continue;
117 
118     if (file != old_file) {
119       if (show_file) {
120         if (file_out) cout << "\n";
121 	cout << "Flags from: " << file << "\n";
122         file_out = true;
123       }
124       old_file = file;
125     }
126     cout << usage << "\n";
127     usage_out = true;
128   }
129   if (usage_out) cout << "\n";
130 }
131 
ShowUsage(bool long_usage)132 void ShowUsage(bool long_usage) {
133   std::set< pair<string, string> > usage_set;
134 
135   cout << flag_usage << "\n";
136 
137   FlagRegister<bool> *bool_register = FlagRegister<bool>::GetRegister();
138   bool_register->GetUsage(&usage_set);
139   FlagRegister<string> *string_register = FlagRegister<string>::GetRegister();
140   string_register->GetUsage(&usage_set);
141   FlagRegister<int32> *int32_register = FlagRegister<int32>::GetRegister();
142   int32_register->GetUsage(&usage_set);
143   FlagRegister<int64> *int64_register = FlagRegister<int64>::GetRegister();
144   int64_register->GetUsage(&usage_set);
145   FlagRegister<double> *double_register = FlagRegister<double>::GetRegister();
146   double_register->GetUsage(&usage_set);
147 
148   if (!prog_src.empty()) {
149     cout << "PROGRAM FLAGS:\n\n";
150     ShowUsageRestrict(usage_set, prog_src, true, false);
151   }
152 
153   if (!long_usage)
154     return;
155 
156   if (!prog_src.empty())
157     cout << "LIBRARY FLAGS:\n\n";
158 
159   ShowUsageRestrict(usage_set, prog_src, false, true);
160 }
161