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