diff options
Diffstat (limited to 'lib/Driver/Option.cpp')
-rw-r--r-- | lib/Driver/Option.cpp | 106 |
1 files changed, 79 insertions, 27 deletions
diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp index 17d00f5..dd48af8 100644 --- a/lib/Driver/Option.cpp +++ b/lib/Driver/Option.cpp @@ -20,7 +20,6 @@ Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name, const OptionGroup *_Group, const Option *_Alias) : Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias), Unsupported(false), LinkerInput(false), NoOptAsInput(false), - ForceSeparateRender(false), ForceJoinedRender(false), DriverOption(false), NoArgumentUnused(false) { // Multi-level aliases are not supported, and alias options cannot @@ -28,6 +27,31 @@ Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name, // inherent limitation. assert((!Alias || (!Alias->Alias && !Group)) && "Multi-level aliases and aliases with groups are unsupported."); + + // Initialize rendering options based on the class. + switch (Kind) { + case GroupClass: + case InputClass: + case UnknownClass: + RenderStyle = RenderValuesStyle; + break; + + case JoinedClass: + case JoinedAndSeparateClass: + RenderStyle = RenderJoinedStyle; + break; + + case CommaJoinedClass: + RenderStyle = RenderCommaJoinedStyle; + break; + + case FlagClass: + case SeparateClass: + case MultiArgClass: + case JoinedOrSeparateClass: + RenderStyle = RenderSeparateStyle; + break; + } } Option::~Option() { @@ -89,7 +113,7 @@ OptionGroup::OptionGroup(OptSpecifier ID, const char *Name, : Option(Option::GroupClass, ID, Name, Group, 0) { } -Arg *OptionGroup::accept(const InputArgList &Args, unsigned &Index) const { +Arg *OptionGroup::accept(const ArgList &Args, unsigned &Index) const { assert(0 && "accept() should never be called on an OptionGroup"); return 0; } @@ -98,7 +122,7 @@ InputOption::InputOption(OptSpecifier ID) : Option(Option::InputClass, ID, "<input>", 0, 0) { } -Arg *InputOption::accept(const InputArgList &Args, unsigned &Index) const { +Arg *InputOption::accept(const ArgList &Args, unsigned &Index) const { assert(0 && "accept() should never be called on an InputOption"); return 0; } @@ -107,7 +131,7 @@ UnknownOption::UnknownOption(OptSpecifier ID) : Option(Option::UnknownClass, ID, "<unknown>", 0, 0) { } -Arg *UnknownOption::accept(const InputArgList &Args, unsigned &Index) const { +Arg *UnknownOption::accept(const ArgList &Args, unsigned &Index) const { assert(0 && "accept() should never be called on an UnknownOption"); return 0; } @@ -117,13 +141,13 @@ FlagOption::FlagOption(OptSpecifier ID, const char *Name, : Option(Option::FlagClass, ID, Name, Group, Alias) { } -Arg *FlagOption::accept(const InputArgList &Args, unsigned &Index) const { +Arg *FlagOption::accept(const ArgList &Args, unsigned &Index) const { // Matches iff this is an exact match. // FIXME: Avoid strlen. if (strlen(getName()) != strlen(Args.getArgString(Index))) return 0; - return new FlagArg(this, Index++); + return new Arg(getUnaliasedOption(), Index++); } JoinedOption::JoinedOption(OptSpecifier ID, const char *Name, @@ -131,9 +155,10 @@ JoinedOption::JoinedOption(OptSpecifier ID, const char *Name, : Option(Option::JoinedClass, ID, Name, Group, Alias) { } -Arg *JoinedOption::accept(const InputArgList &Args, unsigned &Index) const { +Arg *JoinedOption::accept(const ArgList &Args, unsigned &Index) const { // Always matches. - return new JoinedArg(this, Index++); + const char *Value = Args.getArgString(Index) + strlen(getName()); + return new Arg(getUnaliasedOption(), Index++, Value); } CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name, @@ -142,15 +167,34 @@ CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name, : Option(Option::CommaJoinedClass, ID, Name, Group, Alias) { } -Arg *CommaJoinedOption::accept(const InputArgList &Args, +Arg *CommaJoinedOption::accept(const ArgList &Args, unsigned &Index) const { - // Always matches. We count the commas now so we can answer - // getNumValues easily. + // Always matches. + const char *Str = Args.getArgString(Index) + strlen(getName()); + Arg *A = new Arg(getUnaliasedOption(), Index++); + + // Parse out the comma separated values. + const char *Prev = Str; + for (;; ++Str) { + char c = *Str; + + if (!c || c == ',') { + if (Prev != Str) { + char *Value = new char[Str - Prev + 1]; + memcpy(Value, Prev, Str - Prev); + Value[Str - Prev] = '\0'; + A->getValues().push_back(Value); + } + + if (!c) + break; + + Prev = Str + 1; + } + } + A->setOwnsValues(true); - // Get the suffix string. - // FIXME: Avoid strlen, and move to helper method? - const char *Suffix = Args.getArgString(Index) + strlen(getName()); - return new CommaJoinedArg(this, Index++, Suffix); + return A; } SeparateOption::SeparateOption(OptSpecifier ID, const char *Name, @@ -158,7 +202,7 @@ SeparateOption::SeparateOption(OptSpecifier ID, const char *Name, : Option(Option::SeparateClass, ID, Name, Group, Alias) { } -Arg *SeparateOption::accept(const InputArgList &Args, unsigned &Index) const { +Arg *SeparateOption::accept(const ArgList &Args, unsigned &Index) const { // Matches iff this is an exact match. // FIXME: Avoid strlen. if (strlen(getName()) != strlen(Args.getArgString(Index))) @@ -168,7 +212,7 @@ Arg *SeparateOption::accept(const InputArgList &Args, unsigned &Index) const { if (Index > Args.getNumInputArgStrings()) return 0; - return new SeparateArg(this, Index - 2, 1); + return new Arg(getUnaliasedOption(), Index - 2, Args.getArgString(Index - 1)); } MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name, @@ -178,7 +222,7 @@ MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name, assert(NumArgs > 1 && "Invalid MultiArgOption!"); } -Arg *MultiArgOption::accept(const InputArgList &Args, unsigned &Index) const { +Arg *MultiArgOption::accept(const ArgList &Args, unsigned &Index) const { // Matches iff this is an exact match. // FIXME: Avoid strlen. if (strlen(getName()) != strlen(Args.getArgString(Index))) @@ -188,28 +232,35 @@ Arg *MultiArgOption::accept(const InputArgList &Args, unsigned &Index) const { if (Index > Args.getNumInputArgStrings()) return 0; - return new SeparateArg(this, Index - 1 - NumArgs, NumArgs); + Arg *A = new Arg(getUnaliasedOption(), Index - 1 - NumArgs, + Args.getArgString(Index - NumArgs)); + for (unsigned i = 1; i != NumArgs; ++i) + A->getValues().push_back(Args.getArgString(Index - NumArgs + i)); + return A; } -JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID, const char *Name, +JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID, + const char *Name, const OptionGroup *Group, const Option *Alias) : Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) { } -Arg *JoinedOrSeparateOption::accept(const InputArgList &Args, +Arg *JoinedOrSeparateOption::accept(const ArgList &Args, unsigned &Index) const { // If this is not an exact match, it is a joined arg. // FIXME: Avoid strlen. - if (strlen(getName()) != strlen(Args.getArgString(Index))) - return new JoinedArg(this, Index++); + if (strlen(getName()) != strlen(Args.getArgString(Index))) { + const char *Value = Args.getArgString(Index) + strlen(getName()); + return new Arg(this, Index++, Value); + } // Otherwise it must be separate. Index += 2; if (Index > Args.getNumInputArgStrings()) return 0; - return new SeparateArg(this, Index - 2, 1); + return new Arg(getUnaliasedOption(), Index - 2, Args.getArgString(Index - 1)); } JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID, @@ -219,7 +270,7 @@ JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID, : Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) { } -Arg *JoinedAndSeparateOption::accept(const InputArgList &Args, +Arg *JoinedAndSeparateOption::accept(const ArgList &Args, unsigned &Index) const { // Always matches. @@ -227,6 +278,7 @@ Arg *JoinedAndSeparateOption::accept(const InputArgList &Args, if (Index > Args.getNumInputArgStrings()) return 0; - return new JoinedAndSeparateArg(this, Index - 2); + return new Arg(getUnaliasedOption(), Index - 2, + Args.getArgString(Index-2)+strlen(getName()), + Args.getArgString(Index-1)); } - |