| 922 | |
| 923 | |
| 924 | int Commands::ProcessCommandLine(int argc, char **argv) |
| 925 | { |
| 926 | std::string baseprog = simple_basename(argv[0]); |
| 927 | |
| 928 | if (2 > argc) |
| 929 | { |
| 930 | std::cout << "Missing command. See '" << baseprog |
| 931 | << " help' for details" |
| 932 | << std::endl; |
| 933 | return 1; |
| 934 | } |
| 935 | |
| 936 | // Implicit declaration of the generic help screen. |
| 937 | std::string cmd(argv[1]); |
| 938 | if ("help" == cmd || "--help" == cmd || "-h" == cmd) |
| 939 | { |
| 940 | print_generic_help(baseprog); |
| 941 | return 0; |
| 942 | } |
| 943 | |
| 944 | // Link the ShellCompletion helper object with this Commands object |
| 945 | // The ShellCompletion sub-class needs access to the commands |
| 946 | // std::vector to be able to generate the needed strings to be used |
| 947 | // by the shell completion functions outside of the program itself |
| 948 | shellcompl->SetMainCommands(this); |
| 949 | |
| 950 | // Find the proper registered command and let that object |
| 951 | // continue the command line parsing and run the callback function |
| 952 | for (auto &c : commands) |
| 953 | { |
| 954 | // If we found our command ... |
| 955 | if (c->CheckCommandName(cmd)) |
| 956 | { |
| 957 | // Copy over the arguments, skip argv[0] and build another one |
| 958 | // instead. Ideally, this should not be needed - but |
| 959 | // getopt_long() needs it for its error reporting. And |
| 960 | // removing the error reporting, things gets much more |
| 961 | // complicated and limited. |
| 962 | // |
| 963 | // Also ensure we have one extra element as a NULL terminator |
| 964 | // |
| 965 | char **cmdargv = (char **)calloc(sizeof(char *), argc + 1); |
| 966 | if (NULL == cmdargv) |
| 967 | { |
| 968 | throw CommandException(baseprog, |
| 969 | "Could not allocate memory for argument parsing"); |
| 970 | } |
| 971 | |
| 972 | // Build up the new argv[0] to be used instead |
| 973 | const std::string cmdarg0_str = baseprog + "/" + cmd; |
| 974 | cmdargv[0] = strdup(cmdarg0_str.c_str()); |
| 975 | int cmdargc = 1; |
| 976 | |
| 977 | // copy over the arguments, ignoring the initial argv[0] |
| 978 | for (int i = 1; i < argc; i++) |
| 979 | { |
| 980 | cmdargv[cmdargc++] = argv[i]; |
| 981 | } |