fc50ddcbbb3161648bd580bd25c1ff27dbd30143
[oota-llvm.git] / support / lib / Support / ProgramOptions.cpp
1 // $Id$
2 //***************************************************************************
3 //
4 // File:
5 //    ProgramOptions.C
6 //
7 // Purpose:
8 //    General options processing for any program.
9 //
10 // History:
11 //    08/08/95 - adve  - created in the dHPF compiler
12 //    10/10/96 - mpal, dbaker - converted to const member functions.
13 //    11/26/96 - adve  - fixed to handle options that consume 0+ arguments
14 //    07/15/01 - vadve - Copied to LLVM system and modified
15 //
16 //**************************************************************************/
17
18 //************************** System Include Files **************************/
19
20 #include <iostream.h>
21 #include <assert.h>
22 #include <stdlib.h>
23 #include <math.h>
24 #include <string>
25 #ifndef MAXINT
26 #define MAXINT  ((1 << sizeof(int)-1) - 1)
27 #endif
28
29 //*************************** User Include Files ***************************/
30
31 #include "llvm/Support/ProgramOptions.h"
32 #include "llvm/Support/ProgramOption.h"
33
34
35 //************************** Method Definitions ****************************/
36
37 ProgramOptions::ProgramOptions(int _argc,
38                                const char* _argv[],
39                                const char* _envp[])
40   : optionRegistry(),
41     argc(_argc),
42     argv(_argv),
43     envp(_envp),
44     argsConsumed(0)
45 {}
46
47 string ProgramOptions::StringOptionValue(const string &optString) const {
48     const StringOption* handler = (const StringOption*)OptionHandler(optString);
49     return (handler == NULL) ? string("") : handler->Value();
50 }
51
52 bool
53 ProgramOptions::FlagOptionValue(const string &optString) const
54 {
55     const FlagOption* handler = (const FlagOption*) OptionHandler(optString);
56     return (handler == NULL) ? false : handler->Value();
57 }
58
59 double
60 ProgramOptions::RealOptionValue(const string &optString) const
61 {
62     const RealValuedOption* handler =
63         (const RealValuedOption*) OptionHandler(optString);
64     return (handler == NULL) ? MAXFLOAT : handler->Value();
65 }
66
67 int
68 ProgramOptions::IntOptionValue(const string &optString) const
69 {
70     const IntegerValuedOption* handler =
71         (const IntegerValuedOption*) OptionHandler(optString);
72     return (handler == NULL) ? MAXINT : handler->Value();
73 }
74
75 bool
76 ProgramOptions::OptionSpecified(const string &optString) const
77 {
78     const ProgramOption* handler = OptionHandler(optString);
79     return handler->OptionSpecified();
80 }
81
82 const char* 
83 ProgramOptions::ProgramName() const
84 {
85     return argv[0];
86 }
87
88 int
89 ProgramOptions::NumberOfOtherOptions() const
90 {
91    return argc - argsConsumed;
92
93
94 const char*
95 ProgramOptions::OtherOption(int i) const
96 {
97    i += argsConsumed;
98    assert(i >= 0 && i < argc);
99    return argv[i];
100 }
101
102 const char**
103 ProgramOptions::GetOriginalArgs() const
104 {
105    return argv;
106 }
107
108 vector<string>
109 ProgramOptions::GetDescription() const
110 {  
111   vector<string> optDesc;
112   
113   if (optDesc.size() < (unsigned) argc)
114     {
115       for (hash_map<string,ProgramOption*>::const_iterator iter=optionRegistry.begin();
116            ! (iter == optionRegistry.end());
117            ++iter)
118         {
119           const ProgramOption* handler = iter->second;
120           optDesc.push_back(handler->ArgString());      // 1st
121           optDesc.push_back(handler->HelpMesg());       // 2nd
122           optDesc.push_back(handler->GetTextValue());           // 3rd
123         }
124     }
125   
126   return optDesc;
127 }
128
129 void
130 ProgramOptions::Register(ProgramOption* option)
131 {
132   optionRegistry[option->ArgString()] = option;
133 }
134
135 //----------------------------------------------------------------------
136 // function ProgramOptions::ParseArgs
137 // 
138 // Parse command-line options until you run out of options or see
139 // an unrecognized option.  `getopt' is a standard package to do this,
140 // but incredibly, it limited to single-letter options.
141 //
142 // -- Each option can consume zero or one additional arguments of argv
143 // -- "--" can be used to mark the end of options
144 //        so that a program argument can also start with "-".
145 //---------------------------------------------------------------------/
146
147 void
148 ProgramOptions::ParseArgs(int argc,
149                           const char* argv[],
150                           const char* envp[])
151 {
152   if (argc == 0) {
153     Usage();
154   }
155   // consume the program name
156   argsConsumed = 1;
157   
158   while (argsConsumed < argc)
159     {
160       const char* arg = argv[argsConsumed];
161       if (arg[0] == '-')
162         {
163           if (strcmp(arg, "--") == 0) { // "--" marks end of options
164             argsConsumed++;             // consume and
165             break;                      // discontinue the for loop
166           }
167           ProgramOption* handler = OptionHandler(arg+1);
168           if (handler == NULL) {
169             cerr << "Unrecognized option: " << arg+1 << endl;
170             Usage();
171           }
172
173           if (argc - argsConsumed < handler->MinExpectedArgs()) {
174             cerr << "Option " << (char*) arg+1 << " needs "
175                  << handler->MinExpectedArgs() << " arguments" << endl;
176             Usage();
177           }
178
179           argsConsumed++;  // consumed the option
180
181           const char* nextArg = (argsConsumed < argc)? argv[argsConsumed]
182                                                      : "";
183           int numAdditionalArgsConsumed = handler->EvalOpt(nextArg);
184           if (numAdditionalArgsConsumed < 0)
185             Usage();
186           argsConsumed += numAdditionalArgsConsumed;
187         }
188       else
189         {
190           break; // quit the while loop 
191         }
192     }
193   
194   ParseExtraArgs(); 
195 }
196
197 void
198 ProgramOptions::PrintArgs(ostream& stream) const
199 {
200   for (int i = 0; i < argc; i++) {
201     stream << argv[i] << " ";
202   }
203   stream << endl; 
204 }
205
206
207 void
208 ProgramOptions::PrintOptions(ostream& stream) const
209 {
210   stream << "OPTIONS:" << endl;
211   stream << "\tUse argument 0 to turn OFF a flag option: "
212          << "-<flag_opt> 0" << endl << endl;
213     
214   for (hash_map<string,ProgramOption*>::const_iterator iter = optionRegistry.begin();
215        iter != optionRegistry.end(); ++iter) {
216       const ProgramOption* handler = (*iter).second;
217       
218       stream << "\t-" << handler->ArgString();
219       
220       const char* const showarg = " <arg>";
221       int i = 1;
222       for (i=1; i <= handler->MinExpectedArgs(); i++)
223         stream << showarg; 
224       
225       int numCharsPrinted = 1 + handler->ArgString().length()
226         + 6 * handler->MinExpectedArgs();
227       for (i=1; i > numCharsPrinted / 8; i--)
228         stream << "\t";
229       
230       stream << "\t" << handler->HelpMesg()
231              << endl;
232     }
233 }
234
235 void
236 ProgramOptions::Usage() const
237 {
238   PrintUsage(cerr); 
239   exit(1); 
240 }
241
242
243 //**************************************************************************/