authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-15 20:15:01-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-15 20:19:15-04:00
loge3ad13e05425b3afc9dbac19438ee8a978dcd1e8
tree2f40618c7cf94b979b7fa4770df134d3ba7cca73
parentf87f98015ca0def0faa717748ace151aeff39c40

fix windows argument parsing


5 files changed, 27 insertions(+), 16 deletions(-)

src/codegen.cpp+1-1
......@@ -4436,7 +4436,7 @@ static void do_code_gen(CodeGen *g) {
44364436 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
44374437 LLVMObjectFile, &err_msg, g->build_mode == BuildModeDebug))
44384438 {
4439 zig_panic("unable to write object file: %s", err_msg);
4439 zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg);
44404440 }
44414441
44424442 validate_inline_fns(g);
src/os.cpp+3-3
......@@ -230,7 +230,7 @@ void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path) {
230230 buf_init_from_buf(out_full_path, dirname);
231231 uint8_t c = *(buf_ptr(out_full_path) + buf_len(out_full_path) - 1);
232232 if (!os_is_sep(c))
233 buf_append_char(out_full_path, '/');
233 buf_append_char(out_full_path, ZIG_OS_SEP_CHAR);
234234 buf_append_buf(out_full_path, basename);
235235}
236236
......@@ -838,7 +838,7 @@ int os_make_path(Buf *path) {
838838 // march end_index backward until next path component
839839 while (true) {
840840 end_index -= 1;
841 if (buf_ptr(resolved_path)[end_index] == '/')
841 if (os_is_sep(buf_ptr(resolved_path)[end_index]))
842842 break;
843843 }
844844 continue;
......@@ -851,7 +851,7 @@ int os_make_path(Buf *path) {
851851 // march end_index forward until next path component
852852 while (true) {
853853 end_index += 1;
854 if (end_index == buf_len(resolved_path) || buf_ptr(resolved_path)[end_index] == '/')
854 if (end_index == buf_len(resolved_path) || os_is_sep(buf_ptr(resolved_path)[end_index]))
855855 break;
856856 }
857857 }
src/os.hpp+2
......@@ -97,12 +97,14 @@ int os_self_exe_path(Buf *out_path);
9797#define ZIG_PRI_llu "I64u"
9898#define ZIG_PRI_x64 "I64x"
9999#define OS_SEP "\\"
100#define ZIG_OS_SEP_CHAR '\\'
100101#else
101102#define ZIG_PRI_usize "zu"
102103#define ZIG_PRI_u64 PRIu64
103104#define ZIG_PRI_llu "llu"
104105#define ZIG_PRI_x64 PRIx64
105106#define OS_SEP "/"
107#define ZIG_OS_SEP_CHAR '/'
106108#endif
107109
108110#endif
std/os/index.zig+20-11
......@@ -1220,7 +1220,6 @@ pub const ArgIteratorPosix = struct {
12201220pub const ArgIteratorWindows = struct {
12211221 index: usize,
12221222 cmd_line: &const u8,
1223 backslash_count: usize,
12241223 in_quote: bool,
12251224 quote_count: usize,
12261225 seen_quote_count: usize,
......@@ -1233,7 +1232,6 @@ pub const ArgIteratorWindows = struct {
12331232 return ArgIteratorWindows {
12341233 .index = 0,
12351234 .cmd_line = cmd_line,
1236 .backslash_count = 0,
12371235 .in_quote = false,
12381236 .quote_count = countQuotes(cmd_line),
12391237 .seen_quote_count = 0,
......@@ -1266,25 +1264,30 @@ pub const ArgIteratorWindows = struct {
12661264 }
12671265 }
12681266
1267 var backslash_count: usize = 0;
12691268 while (true) : (self.index += 1) {
12701269 const byte = self.cmd_line[self.index];
12711270 switch (byte) {
12721271 0 => return true,
12731272 '"' => {
1274 const quote_is_real = self.backslash_count % 2 == 0;
1273 const quote_is_real = backslash_count % 2 == 0;
12751274 if (quote_is_real) {
12761275 self.seen_quote_count += 1;
12771276 }
12781277 },
12791278 '\\' => {
1280 self.backslash_count += 1;
1279 backslash_count += 1;
12811280 },
12821281 ' ', '\t' => {
12831282 if (self.seen_quote_count % 2 == 0 or self.seen_quote_count == self.quote_count) {
12841283 return true;
12851284 }
1285 backslash_count = 0;
1286 },
1287 else => {
1288 backslash_count = 0;
1289 continue;
12861290 },
1287 else => continue,
12881291 }
12891292 }
12901293 }
......@@ -1293,13 +1296,15 @@ pub const ArgIteratorWindows = struct {
12931296 var buf = %return Buffer.initSize(allocator, 0);
12941297 defer buf.deinit();
12951298
1299 var backslash_count: usize = 0;
12961300 while (true) : (self.index += 1) {
12971301 const byte = self.cmd_line[self.index];
12981302 switch (byte) {
12991303 0 => return buf.toOwnedSlice(),
13001304 '"' => {
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;
13031308
13041309 if (quote_is_real) {
13051310 self.seen_quote_count += 1;
......@@ -1311,10 +1316,11 @@ pub const ArgIteratorWindows = struct {
13111316 }
13121317 },
13131318 '\\' => {
1314 self.backslash_count += 1;
1319 backslash_count += 1;
13151320 },
13161321 ' ', '\t' => {
1317 %return self.emitBackslashes(&buf, self.backslash_count);
1322 %return self.emitBackslashes(&buf, backslash_count);
1323 backslash_count = 0;
13181324 if (self.seen_quote_count % 2 == 1 and self.seen_quote_count != self.quote_count) {
13191325 %return buf.appendByte(byte);
13201326 } else {
......@@ -1322,7 +1328,8 @@ pub const ArgIteratorWindows = struct {
13221328 }
13231329 },
13241330 else => {
1325 %return self.emitBackslashes(&buf, self.backslash_count);
1331 %return self.emitBackslashes(&buf, backslash_count);
1332 backslash_count = 0;
13261333 %return buf.appendByte(byte);
13271334 },
13281335 }
......@@ -1330,7 +1337,6 @@ pub const ArgIteratorWindows = struct {
13301337 }
13311338
13321339 fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) -> %void {
1333 self.backslash_count = 0;
13341340 var i: usize = 0;
13351341 while (i < emit_count) : (i += 1) {
13361342 %return buf.appendByte('\\');
......@@ -1400,6 +1406,9 @@ test "windows arg parsing" {
14001406 testWindowsCmdLine(c"a\\\\\\\"b c d", [][]const u8{"a\\\"b", "c", "d"});
14011407 testWindowsCmdLine(c"a\\\\\\\\\"b c\" d e", [][]const u8{"a\\\\b c", "d", "e"});
14021408 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"});
14031412}
14041413
14051414fn testWindowsCmdLine(input_cmd_line: &const u8, expected_args: []const []const u8) {
test/compile_errors.zig+1-1
......@@ -889,7 +889,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
889889 \\const resource = @embedFile("bogus.txt");
890890 \\
891891 \\export fn entry() -> usize { @sizeOf(@typeOf(resource)) }
892 , ".tmp_source.zig:1:29: error: unable to find '", "/bogus.txt'");
892 , ".tmp_source.zig:1:29: error: unable to find '", "bogus.txt'");
893893
894894 cases.add("non-const expression in struct literal outside function",
895895 \\const Foo = struct {