1 //===--- OptTable.cpp - Option Table Implementation -----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Option/OptTable.h"
11 #include "llvm/Option/Arg.h"
12 #include "llvm/Option/ArgList.h"
13 #include "llvm/Option/Option.h"
14 #include "llvm/Support/ErrorHandling.h"
15 #include "llvm/Support/raw_ostream.h"
21 using namespace llvm::opt
;
26 // Ordering on Info. The ordering is *almost* case-insensitive lexicographic,
27 // with an exceptions. '\0' comes at the end of the alphabet instead of the
28 // beginning (thus options precede any other options which prefix them).
29 static int StrCmpOptionNameIgnoreCase(const char *A
, const char *B
) {
30 const char *X
= A
, *Y
= B
;
31 char a
= tolower(*A
), b
= tolower(*B
);
40 if (a
== '\0') // A is a prefix of B.
42 if (b
== '\0') // B is a prefix of A.
45 // Otherwise lexicographic.
46 return (a
< b
) ? -1 : 1;
50 static int StrCmpOptionName(const char *A
, const char *B
) {
51 if (int N
= StrCmpOptionNameIgnoreCase(A
, B
))
56 static inline bool operator<(const OptTable::Info
&A
, const OptTable::Info
&B
) {
60 if (int N
= StrCmpOptionName(A
.Name
, B
.Name
))
63 for (const char * const *APre
= A
.Prefixes
,
64 * const *BPre
= B
.Prefixes
;
65 *APre
!= nullptr && *BPre
!= nullptr; ++APre
, ++BPre
){
66 if (int N
= StrCmpOptionName(*APre
, *BPre
))
70 // Names are the same, check that classes are in order; exactly one
71 // should be joined, and it should succeed the other.
72 assert(((A
.Kind
== Option::JoinedClass
) ^ (B
.Kind
== Option::JoinedClass
)) &&
73 "Unexpected classes for options with same name.");
74 return B
.Kind
== Option::JoinedClass
;
78 // Support lower_bound between info and an option name.
79 static inline bool operator<(const OptTable::Info
&I
, const char *Name
) {
80 return StrCmpOptionNameIgnoreCase(I
.Name
, Name
) < 0;
85 OptSpecifier::OptSpecifier(const Option
*Opt
) : ID(Opt
->getID()) {}
87 OptTable::OptTable(const Info
*_OptionInfos
, unsigned _NumOptionInfos
,
89 : OptionInfos(_OptionInfos
),
90 NumOptionInfos(_NumOptionInfos
),
91 IgnoreCase(_IgnoreCase
),
93 TheUnknownOptionID(0),
94 FirstSearchableIndex(0)
96 // Explicitly zero initialize the error to work around a bug in array
97 // value-initialization on MinGW with gcc 4.3.5.
99 // Find start of normal options.
100 for (unsigned i
= 0, e
= getNumOptions(); i
!= e
; ++i
) {
101 unsigned Kind
= getInfo(i
+ 1).Kind
;
102 if (Kind
== Option::InputClass
) {
103 assert(!TheInputOptionID
&& "Cannot have multiple input options!");
104 TheInputOptionID
= getInfo(i
+ 1).ID
;
105 } else if (Kind
== Option::UnknownClass
) {
106 assert(!TheUnknownOptionID
&& "Cannot have multiple unknown options!");
107 TheUnknownOptionID
= getInfo(i
+ 1).ID
;
108 } else if (Kind
!= Option::GroupClass
) {
109 FirstSearchableIndex
= i
;
113 assert(FirstSearchableIndex
!= 0 && "No searchable options?");
116 // Check that everything after the first searchable option is a
117 // regular option class.
118 for (unsigned i
= FirstSearchableIndex
, e
= getNumOptions(); i
!= e
; ++i
) {
119 Option::OptionClass Kind
= (Option::OptionClass
) getInfo(i
+ 1).Kind
;
120 assert((Kind
!= Option::InputClass
&& Kind
!= Option::UnknownClass
&&
121 Kind
!= Option::GroupClass
) &&
122 "Special options should be defined first!");
125 // Check that options are in order.
126 for (unsigned i
= FirstSearchableIndex
+ 1, e
= getNumOptions(); i
!= e
; ++i
){
127 if (!(getInfo(i
) < getInfo(i
+ 1))) {
129 getOption(i
+ 1).dump();
130 llvm_unreachable("Options are not in order!");
136 for (unsigned i
= FirstSearchableIndex
+ 1, e
= getNumOptions() + 1;
138 if (const char *const *P
= getInfo(i
).Prefixes
) {
139 for (; *P
!= nullptr; ++P
) {
140 PrefixesUnion
.insert(*P
);
145 // Build prefix chars.
146 for (llvm::StringSet
<>::const_iterator I
= PrefixesUnion
.begin(),
147 E
= PrefixesUnion
.end(); I
!= E
; ++I
) {
148 StringRef Prefix
= I
->getKey();
149 for (StringRef::const_iterator C
= Prefix
.begin(), CE
= Prefix
.end();
151 if (std::find(PrefixChars
.begin(), PrefixChars
.end(), *C
)
152 == PrefixChars
.end())
153 PrefixChars
.push_back(*C
);
157 OptTable::~OptTable() {
160 const Option
OptTable::getOption(OptSpecifier Opt
) const {
161 unsigned id
= Opt
.getID();
163 return Option(nullptr, nullptr);
164 assert((unsigned) (id
- 1) < getNumOptions() && "Invalid ID.");
165 return Option(&getInfo(id
), this);
168 static bool isInput(const llvm::StringSet
<> &Prefixes
, StringRef Arg
) {
171 for (llvm::StringSet
<>::const_iterator I
= Prefixes
.begin(),
172 E
= Prefixes
.end(); I
!= E
; ++I
)
173 if (Arg
.startswith(I
->getKey()))
178 /// \returns Matched size. 0 means no match.
179 static unsigned matchOption(const OptTable::Info
*I
, StringRef Str
,
181 for (const char * const *Pre
= I
->Prefixes
; *Pre
!= nullptr; ++Pre
) {
182 StringRef
Prefix(*Pre
);
183 if (Str
.startswith(Prefix
)) {
184 StringRef Rest
= Str
.substr(Prefix
.size());
185 bool Matched
= IgnoreCase
186 ? Rest
.startswith_lower(I
->Name
)
187 : Rest
.startswith(I
->Name
);
189 return Prefix
.size() + StringRef(I
->Name
).size();
195 Arg
*OptTable::ParseOneArg(const ArgList
&Args
, unsigned &Index
,
196 unsigned FlagsToInclude
,
197 unsigned FlagsToExclude
) const {
198 unsigned Prev
= Index
;
199 const char *Str
= Args
.getArgString(Index
);
201 // Anything that doesn't start with PrefixesUnion is an input, as is '-'
203 if (isInput(PrefixesUnion
, Str
))
204 return new Arg(getOption(TheInputOptionID
), Str
, Index
++, Str
);
206 const Info
*Start
= OptionInfos
+ FirstSearchableIndex
;
207 const Info
*End
= OptionInfos
+ getNumOptions();
208 StringRef Name
= StringRef(Str
).ltrim(PrefixChars
);
210 // Search for the first next option which could be a prefix.
211 Start
= std::lower_bound(Start
, End
, Name
.data());
213 // Options are stored in sorted order, with '\0' at the end of the
214 // alphabet. Since the only options which can accept a string must
215 // prefix it, we iteratively search for the next option which could
218 // FIXME: This is searching much more than necessary, but I am
219 // blanking on the simplest way to make it fast. We can solve this
220 // problem when we move to TableGen.
221 for (; Start
!= End
; ++Start
) {
222 unsigned ArgSize
= 0;
223 // Scan for first option which is a proper prefix.
224 for (; Start
!= End
; ++Start
)
225 if ((ArgSize
= matchOption(Start
, Str
, IgnoreCase
)))
230 Option
Opt(Start
, this);
232 if (FlagsToInclude
&& !Opt
.hasFlag(FlagsToInclude
))
234 if (Opt
.hasFlag(FlagsToExclude
))
237 // See if this option matches.
238 if (Arg
*A
= Opt
.accept(Args
, Index
, ArgSize
))
241 // Otherwise, see if this argument was missing values.
246 // If we failed to find an option and this arg started with /, then it's
247 // probably an input path.
249 return new Arg(getOption(TheInputOptionID
), Str
, Index
++, Str
);
251 return new Arg(getOption(TheUnknownOptionID
), Str
, Index
++, Str
);
254 InputArgList
*OptTable::ParseArgs(const char *const *ArgBegin
,
255 const char *const *ArgEnd
,
256 unsigned &MissingArgIndex
,
257 unsigned &MissingArgCount
,
258 unsigned FlagsToInclude
,
259 unsigned FlagsToExclude
) const {
260 InputArgList
*Args
= new InputArgList(ArgBegin
, ArgEnd
);
262 // FIXME: Handle '@' args (or at least error on them).
264 MissingArgIndex
= MissingArgCount
= 0;
265 unsigned Index
= 0, End
= ArgEnd
- ArgBegin
;
266 while (Index
< End
) {
267 // Ingore nullptrs, they are response file's EOL markers
268 if (Args
->getArgString(Index
) == nullptr) {
272 // Ignore empty arguments (other things may still take them as arguments).
273 StringRef Str
= Args
->getArgString(Index
);
279 unsigned Prev
= Index
;
280 Arg
*A
= ParseOneArg(*Args
, Index
, FlagsToInclude
, FlagsToExclude
);
281 assert(Index
> Prev
&& "Parser failed to consume argument.");
283 // Check for missing argument error.
285 assert(Index
>= End
&& "Unexpected parser error.");
286 assert(Index
- Prev
- 1 && "No missing arguments!");
287 MissingArgIndex
= Prev
;
288 MissingArgCount
= Index
- Prev
- 1;
298 static std::string
getOptionHelpName(const OptTable
&Opts
, OptSpecifier Id
) {
299 const Option O
= Opts
.getOption(Id
);
300 std::string Name
= O
.getPrefixedName();
302 // Add metavar, if used.
303 switch (O
.getKind()) {
304 case Option::GroupClass
: case Option::InputClass
: case Option::UnknownClass
:
305 llvm_unreachable("Invalid option with help text.");
307 case Option::MultiArgClass
:
308 if (const char *MetaVarName
= Opts
.getOptionMetaVar(Id
)) {
309 // For MultiArgs, metavar is full list of all argument names.
314 // For MultiArgs<N>, if metavar not supplied, print <value> N times.
315 for (unsigned i
=0, e
=O
.getNumArgs(); i
< e
; ++i
) {
321 case Option::FlagClass
:
324 case Option::SeparateClass
: case Option::JoinedOrSeparateClass
:
325 case Option::RemainingArgsClass
:
328 case Option::JoinedClass
: case Option::CommaJoinedClass
:
329 case Option::JoinedAndSeparateClass
:
330 if (const char *MetaVarName
= Opts
.getOptionMetaVar(Id
))
340 static void PrintHelpOptionList(raw_ostream
&OS
, StringRef Title
,
341 std::vector
<std::pair
<std::string
,
342 const char*> > &OptionHelp
) {
343 OS
<< Title
<< ":\n";
345 // Find the maximum option length.
346 unsigned OptionFieldWidth
= 0;
347 for (unsigned i
= 0, e
= OptionHelp
.size(); i
!= e
; ++i
) {
349 if (!OptionHelp
[i
].second
)
352 // Limit the amount of padding we are willing to give up for alignment.
353 unsigned Length
= OptionHelp
[i
].first
.size();
355 OptionFieldWidth
= std::max(OptionFieldWidth
, Length
);
358 const unsigned InitialPad
= 2;
359 for (unsigned i
= 0, e
= OptionHelp
.size(); i
!= e
; ++i
) {
360 const std::string
&Option
= OptionHelp
[i
].first
;
361 int Pad
= OptionFieldWidth
- int(Option
.size());
362 OS
.indent(InitialPad
) << Option
;
364 // Break on long option names.
367 Pad
= OptionFieldWidth
+ InitialPad
;
369 OS
.indent(Pad
+ 1) << OptionHelp
[i
].second
<< '\n';
373 static const char *getOptionHelpGroup(const OptTable
&Opts
, OptSpecifier Id
) {
374 unsigned GroupID
= Opts
.getOptionGroupID(Id
);
376 // If not in a group, return the default help group.
380 // Abuse the help text of the option groups to store the "help group"
383 // FIXME: Split out option groups.
384 if (const char *GroupHelp
= Opts
.getOptionHelpText(GroupID
))
387 // Otherwise keep looking.
388 return getOptionHelpGroup(Opts
, GroupID
);
391 void OptTable::PrintHelp(raw_ostream
&OS
, const char *Name
, const char *Title
,
392 bool ShowHidden
) const {
393 PrintHelp(OS
, Name
, Title
, /*Include*/ 0, /*Exclude*/
394 (ShowHidden
? 0 : HelpHidden
));
398 void OptTable::PrintHelp(raw_ostream
&OS
, const char *Name
, const char *Title
,
399 unsigned FlagsToInclude
,
400 unsigned FlagsToExclude
) const {
401 OS
<< "OVERVIEW: " << Title
<< "\n";
403 OS
<< "USAGE: " << Name
<< " [options] <inputs>\n";
406 // Render help text into a map of group-name to a list of (option, help)
408 typedef std::map
<std::string
,
409 std::vector
<std::pair
<std::string
, const char*> > > helpmap_ty
;
410 helpmap_ty GroupedOptionHelp
;
412 for (unsigned i
= 0, e
= getNumOptions(); i
!= e
; ++i
) {
415 // FIXME: Split out option groups.
416 if (getOptionKind(Id
) == Option::GroupClass
)
419 unsigned Flags
= getInfo(Id
).Flags
;
420 if (FlagsToInclude
&& !(Flags
& FlagsToInclude
))
422 if (Flags
& FlagsToExclude
)
425 if (const char *Text
= getOptionHelpText(Id
)) {
426 const char *HelpGroup
= getOptionHelpGroup(*this, Id
);
427 const std::string
&OptName
= getOptionHelpName(*this, Id
);
428 GroupedOptionHelp
[HelpGroup
].push_back(std::make_pair(OptName
, Text
));
432 for (helpmap_ty::iterator it
= GroupedOptionHelp
.begin(),
433 ie
= GroupedOptionHelp
.end(); it
!= ie
; ++it
) {
434 if (it
!= GroupedOptionHelp
.begin())
436 PrintHelpOptionList(OS
, it
->first
, it
->second
);