| 88 | } |
| 89 | |
| 90 | inline std::vector<std::string> SplitCommandLine(int argc, char ** argv) |
| 91 | { |
| 92 | // takes a string, and separates out according to embedded quoted strings |
| 93 | // the quotes are preserved, and quotes are escaped. |
| 94 | // examples |
| 95 | // * abc > abc |
| 96 | // * abc "def" > abc, "def" |
| 97 | // * a "def" ghi > a, "def", ghi |
| 98 | // * a\"bc > a\"bc |
| 99 | |
| 100 | auto Separate = [](const std::string & input) -> std::vector<std::string> |
| 101 | { |
| 102 | std::vector<std::string> output; |
| 103 | |
| 104 | size_t curr = 0; |
| 105 | size_t start = 0; |
| 106 | size_t end = input.length(); |
| 107 | bool inQuotes = false; |
| 108 | |
| 109 | while (curr < end) |
| 110 | { |
| 111 | if (input[curr] == '\\') |
| 112 | { |
| 113 | ++curr; |
| 114 | if (curr != end && input[curr] == '\"') |
| 115 | ++curr; |
| 116 | } |
| 117 | else |
| 118 | { |
| 119 | if (input[curr] == '\"') |
| 120 | { |
| 121 | // no empty string if not in quotes, otherwise preserve it |
| 122 | if (inQuotes || (start != curr)) |
| 123 | { |
| 124 | output.push_back(input.substr(start - (inQuotes ? 1 : 0), curr - start + (inQuotes ? 2 : 0))); |
| 125 | } |
| 126 | inQuotes = !inQuotes; |
| 127 | start = curr + 1; |
| 128 | } |
| 129 | ++curr; |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | // catch the case of a trailing substring that was not quoted, or a completely unquoted string |
| 134 | if (curr - start > 0) output.push_back(input.substr(start, curr - start)); |
| 135 | |
| 136 | return output; |
| 137 | }; |
| 138 | |
| 139 | // join the command line together so quoted strings can be found |
| 140 | std::string cmd; |
| 141 | for (int i = 1; i < argc; ++i) |
| 142 | { |
| 143 | if (i > 1) cmd += " "; |
| 144 | cmd += std::string(argv[i]); |
| 145 | } |
| 146 | |
| 147 | // separate the command line, respecting quoted strings |