diff options
Diffstat (limited to 'apt-pkg')
-rw-r--r-- | apt-pkg/contrib/cmndline.cc | 62 | ||||
-rw-r--r-- | apt-pkg/contrib/cmndline.h | 11 |
2 files changed, 71 insertions, 2 deletions
diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc index 40365237e..60ce90f1f 100644 --- a/apt-pkg/contrib/cmndline.cc +++ b/apt-pkg/contrib/cmndline.cc @@ -84,6 +84,43 @@ char const * CommandLine::GetCommand(Dispatch const * const Map, } return NULL; } +char const * CommandLine::GetCommand(DispatchWithHelp const * const Map, + unsigned int const argc, char const * const * const argv) +{ + // if there is a -- on the line there must be the word we search for either + // before it (as -- marks the end of the options) or right after it (as we can't + // decide if the command is actually an option, given that in theory, you could + // have parameters named like commands) + for (size_t i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "--") != 0) + continue; + // check if command is before -- + for (size_t k = 1; k < i; ++k) + for (size_t j = 0; Map[j].Match != NULL; ++j) + if (strcmp(argv[k], Map[j].Match) == 0) + return Map[j].Match; + // see if the next token after -- is the command + ++i; + if (i < argc) + for (size_t j = 0; Map[j].Match != NULL; ++j) + if (strcmp(argv[i], Map[j].Match) == 0) + return Map[j].Match; + // we found a --, but not a command + return NULL; + } + // no --, so search for the first word matching a command + // FIXME: How like is it that an option parameter will be also a valid Match ? + for (size_t i = 1; i < argc; ++i) + { + if (*(argv[i]) == '-') + continue; + for (size_t j = 0; Map[j].Match != NULL; ++j) + if (strcmp(argv[i], Map[j].Match) == 0) + return Map[j].Match; + } + return NULL; +} /*}}}*/ // CommandLine::Parse - Main action member /*{{{*/ // --------------------------------------------------------------------- @@ -374,8 +411,29 @@ unsigned int CommandLine::FileSize() const } /*}}}*/ // CommandLine::DispatchArg - Do something with the first arg /*{{{*/ -// --------------------------------------------------------------------- -/* */ +bool CommandLine::DispatchArg(DispatchWithHelp *Map,bool NoMatch) +{ + int I; + for (I = 0; Map[I].Match != 0; I++) + { + if (strcmp(FileList[0],Map[I].Match) == 0) + { + bool Res = Map[I].Handler(*this); + if (Res == false && _error->PendingError() == false) + _error->Error("Handler silently failed"); + return Res; + } + } + + // No matching name + if (Map[I].Match == 0) + { + if (NoMatch == true) + _error->Error(_("Invalid operation %s"),FileList[0]); + } + + return false; +} bool CommandLine::DispatchArg(Dispatch *Map,bool NoMatch) { int I; diff --git a/apt-pkg/contrib/cmndline.h b/apt-pkg/contrib/cmndline.h index 58cbaa8c3..a698a18b8 100644 --- a/apt-pkg/contrib/cmndline.h +++ b/apt-pkg/contrib/cmndline.h @@ -57,6 +57,7 @@ class CommandLine public: struct Args; struct Dispatch; + struct DispatchWithHelp; protected: @@ -84,9 +85,13 @@ class CommandLine void ShowHelp(); unsigned int FileSize() const APT_PURE; bool DispatchArg(Dispatch *List,bool NoMatch = true); + bool DispatchArg(DispatchWithHelp *List,bool NoMatch = true); static char const * GetCommand(Dispatch const * const Map, unsigned int const argc, char const * const * const argv) APT_PURE; + static char const * GetCommand(DispatchWithHelp const * const Map, + unsigned int const argc, char const * const * const argv) APT_PURE; + static CommandLine::Args MakeArgs(char ShortOpt, char const *LongOpt, char const *ConfName, unsigned long Flags) APT_CONST; @@ -112,5 +117,11 @@ struct CommandLine::Dispatch const char *Match; bool (*Handler)(CommandLine &); }; +struct CommandLine::DispatchWithHelp +{ + const char *Match; + bool (*Handler)(CommandLine &); + const char *Help; +}; #endif |