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