Splits a string at the ARG_SEPARATOR unless it is escaped with a backslash. Backslash itself can be escaped with another backslash.
| 133 | // Splits a string at the ARG_SEPARATOR unless it is escaped with a backslash. |
| 134 | // Backslash itself can be escaped with another backslash. |
| 135 | std::vector<std::string> splitEscaped(const std::string &str) { |
| 136 | // Protect \\ and \<separator> against splitting. |
| 137 | const std::string BACKSLASH_BACKSLASH_REPLACEMENT = |
| 138 | "%%JAZZER_BACKSLASH_BACKSLASH_REPLACEMENT%%"; |
| 139 | const std::string BACKSLASH_SEPARATOR_REPLACEMENT = |
| 140 | "%%JAZZER_BACKSLASH_SEPARATOR_REPLACEMENT%%"; |
| 141 | std::string protected_str = |
| 142 | absl::StrReplaceAll(str, {{"\\\\", BACKSLASH_BACKSLASH_REPLACEMENT}}); |
| 143 | protected_str = absl::StrReplaceAll( |
| 144 | protected_str, {{"\\" ARG_SEPARATOR, BACKSLASH_SEPARATOR_REPLACEMENT}}); |
| 145 | |
| 146 | std::vector<std::string> parts = absl::StrSplit(protected_str, ARG_SEPARATOR); |
| 147 | std::transform(parts.begin(), parts.end(), parts.begin(), |
| 148 | [&BACKSLASH_SEPARATOR_REPLACEMENT, |
| 149 | &BACKSLASH_BACKSLASH_REPLACEMENT](const std::string &part) { |
| 150 | return absl::StrReplaceAll( |
| 151 | part, |
| 152 | { |
| 153 | {BACKSLASH_SEPARATOR_REPLACEMENT, ARG_SEPARATOR}, |
| 154 | {BACKSLASH_BACKSLASH_REPLACEMENT, "\\"}, |
| 155 | }); |
| 156 | }); |
| 157 | |
| 158 | return parts; |
| 159 | } |
| 160 | } // namespace |
| 161 | |
| 162 | namespace jazzer { |