| 152 | } |
| 153 | |
| 154 | bool CLICommand::ParseCommand(int argc, char **argv, po::options_description& visibleDesc, |
| 155 | po::options_description& hiddenDesc, |
| 156 | po::positional_options_description& positionalDesc, |
| 157 | po::variables_map& vm, String& cmdname, CLICommand::Ptr& command, bool autocomplete) |
| 158 | { |
| 159 | std::unique_lock<std::mutex> lock(GetRegistryMutex()); |
| 160 | |
| 161 | typedef std::map<std::vector<String>, CLICommand::Ptr>::value_type CLIKeyValue; |
| 162 | |
| 163 | std::vector<String> best_match; |
| 164 | int arg_end = 0; |
| 165 | bool tried_command = false; |
| 166 | |
| 167 | for (const CLIKeyValue& kv : GetRegistry()) { |
| 168 | const std::vector<String>& vname = kv.first; |
| 169 | |
| 170 | std::vector<String>::size_type i; |
| 171 | int k; |
| 172 | for (i = 0, k = 1; i < vname.size() && k < argc; i++, k++) { |
| 173 | if (strncmp(argv[k], "-", 1) == 0 || strncmp(argv[k], "--", 2) == 0) { |
| 174 | i--; |
| 175 | continue; |
| 176 | } |
| 177 | |
| 178 | tried_command = true; |
| 179 | |
| 180 | if (vname[i] != argv[k]) |
| 181 | break; |
| 182 | |
| 183 | if (i >= best_match.size()) |
| 184 | best_match.push_back(vname[i]); |
| 185 | |
| 186 | if (i == vname.size() - 1) { |
| 187 | cmdname = boost::algorithm::join(vname, " "); |
| 188 | command = kv.second; |
| 189 | arg_end = k; |
| 190 | goto found_command; |
| 191 | } |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | found_command: |
| 196 | lock.unlock(); |
| 197 | |
| 198 | if (command) { |
| 199 | po::options_description vdesc("Command options"); |
| 200 | command->InitParameters(vdesc, hiddenDesc); |
| 201 | visibleDesc.add(vdesc); |
| 202 | } |
| 203 | |
| 204 | if (autocomplete || (tried_command && !command)) |
| 205 | return true; |
| 206 | |
| 207 | po::options_description adesc; |
| 208 | adesc.add(visibleDesc); |
| 209 | adesc.add(hiddenDesc); |
| 210 | |
| 211 | if (command && command->IsDeprecated()) { |
nothing calls this directly
no test coverage detected