| ... | ... | @@ -1220,7 +1220,6 @@ pub const ArgIteratorPosix = struct { |
| 1220 | 1220 | pub const ArgIteratorWindows = struct { |
| 1221 | 1221 | index: usize, |
| 1222 | 1222 | cmd_line: &const u8, |
| 1223 | | backslash_count: usize, |
| 1224 | 1223 | in_quote: bool, |
| 1225 | 1224 | quote_count: usize, |
| 1226 | 1225 | seen_quote_count: usize, |
| ... | ... | @@ -1233,7 +1232,6 @@ pub const ArgIteratorWindows = struct { |
| 1233 | 1232 | return ArgIteratorWindows { |
| 1234 | 1233 | .index = 0, |
| 1235 | 1234 | .cmd_line = cmd_line, |
| 1236 | | .backslash_count = 0, |
| 1237 | 1235 | .in_quote = false, |
| 1238 | 1236 | .quote_count = countQuotes(cmd_line), |
| 1239 | 1237 | .seen_quote_count = 0, |
| ... | ... | @@ -1266,25 +1264,30 @@ pub const ArgIteratorWindows = struct { |
| 1266 | 1264 | } |
| 1267 | 1265 | } |
| 1268 | 1266 | |
| 1267 | var backslash_count: usize = 0; |
| 1269 | 1268 | while (true) : (self.index += 1) { |
| 1270 | 1269 | const byte = self.cmd_line[self.index]; |
| 1271 | 1270 | switch (byte) { |
| 1272 | 1271 | 0 => return true, |
| 1273 | 1272 | '"' => { |
| 1274 | | const quote_is_real = self.backslash_count % 2 == 0; |
| 1273 | const quote_is_real = backslash_count % 2 == 0; |
| 1275 | 1274 | if (quote_is_real) { |
| 1276 | 1275 | self.seen_quote_count += 1; |
| 1277 | 1276 | } |
| 1278 | 1277 | }, |
| 1279 | 1278 | '\\' => { |
| 1280 | | self.backslash_count += 1; |
| 1279 | backslash_count += 1; |
| 1281 | 1280 | }, |
| 1282 | 1281 | ' ', '\t' => { |
| 1283 | 1282 | if (self.seen_quote_count % 2 == 0 or self.seen_quote_count == self.quote_count) { |
| 1284 | 1283 | return true; |
| 1285 | 1284 | } |
| 1285 | backslash_count = 0; |
| 1286 | }, |
| 1287 | else => { |
| 1288 | backslash_count = 0; |
| 1289 | continue; |
| 1286 | 1290 | }, |
| 1287 | | else => continue, |
| 1288 | 1291 | } |
| 1289 | 1292 | } |
| 1290 | 1293 | } |
| ... | ... | @@ -1293,13 +1296,15 @@ pub const ArgIteratorWindows = struct { |
| 1293 | 1296 | var buf = %return Buffer.initSize(allocator, 0); |
| 1294 | 1297 | defer buf.deinit(); |
| 1295 | 1298 | |
| 1299 | var backslash_count: usize = 0; |
| 1296 | 1300 | while (true) : (self.index += 1) { |
| 1297 | 1301 | const byte = self.cmd_line[self.index]; |
| 1298 | 1302 | switch (byte) { |
| 1299 | 1303 | 0 => return buf.toOwnedSlice(), |
| 1300 | 1304 | '"' => { |
| 1301 | | const quote_is_real = self.backslash_count % 2 == 0; |
| 1302 | | %return self.emitBackslashes(&buf, self.backslash_count / 2); |
| 1305 | const quote_is_real = backslash_count % 2 == 0; |
| 1306 | %return self.emitBackslashes(&buf, backslash_count / 2); |
| 1307 | backslash_count = 0; |
| 1303 | 1308 | |
| 1304 | 1309 | if (quote_is_real) { |
| 1305 | 1310 | self.seen_quote_count += 1; |
| ... | ... | @@ -1311,10 +1316,11 @@ pub const ArgIteratorWindows = struct { |
| 1311 | 1316 | } |
| 1312 | 1317 | }, |
| 1313 | 1318 | '\\' => { |
| 1314 | | self.backslash_count += 1; |
| 1319 | backslash_count += 1; |
| 1315 | 1320 | }, |
| 1316 | 1321 | ' ', '\t' => { |
| 1317 | | %return self.emitBackslashes(&buf, self.backslash_count); |
| 1322 | %return self.emitBackslashes(&buf, backslash_count); |
| 1323 | backslash_count = 0; |
| 1318 | 1324 | if (self.seen_quote_count % 2 == 1 and self.seen_quote_count != self.quote_count) { |
| 1319 | 1325 | %return buf.appendByte(byte); |
| 1320 | 1326 | } else { |
| ... | ... | @@ -1322,7 +1328,8 @@ pub const ArgIteratorWindows = struct { |
| 1322 | 1328 | } |
| 1323 | 1329 | }, |
| 1324 | 1330 | else => { |
| 1325 | | %return self.emitBackslashes(&buf, self.backslash_count); |
| 1331 | %return self.emitBackslashes(&buf, backslash_count); |
| 1332 | backslash_count = 0; |
| 1326 | 1333 | %return buf.appendByte(byte); |
| 1327 | 1334 | }, |
| 1328 | 1335 | } |
| ... | ... | @@ -1330,7 +1337,6 @@ pub const ArgIteratorWindows = struct { |
| 1330 | 1337 | } |
| 1331 | 1338 | |
| 1332 | 1339 | fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) -> %void { |
| 1333 | | self.backslash_count = 0; |
| 1334 | 1340 | var i: usize = 0; |
| 1335 | 1341 | while (i < emit_count) : (i += 1) { |
| 1336 | 1342 | %return buf.appendByte('\\'); |
| ... | ... | @@ -1400,6 +1406,9 @@ test "windows arg parsing" { |
| 1400 | 1406 | testWindowsCmdLine(c"a\\\\\\\"b c d", [][]const u8{"a\\\"b", "c", "d"}); |
| 1401 | 1407 | testWindowsCmdLine(c"a\\\\\\\\\"b c\" d e", [][]const u8{"a\\\\b c", "d", "e"}); |
| 1402 | 1408 | testWindowsCmdLine(c"a b\tc \"d f", [][]const u8{"a", "b", "c", "\"d", "f"}); |
| 1409 | |
| 1410 | testWindowsCmdLine(c"\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"", |
| 1411 | [][]const u8{".\\..\\zig-cache\\build", "bin\\zig.exe", ".\\..", ".\\..\\zig-cache", "--help"}); |
| 1403 | 1412 | } |
| 1404 | 1413 | |
| 1405 | 1414 | fn testWindowsCmdLine(input_cmd_line: &const u8, expected_args: []const []const u8) { |