Skip to content

Commit

Permalink
fix windows argument parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewrk committed Oct 16, 2017
1 parent f87f980 commit e3ad13e
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/codegen.cpp
Expand Up @@ -4436,7 +4436,7 @@ static void do_code_gen(CodeGen *g) {
if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
LLVMObjectFile, &err_msg, g->build_mode == BuildModeDebug))
{
zig_panic("unable to write object file: %s", err_msg);
zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg);
}

validate_inline_fns(g);
Expand Down
6 changes: 3 additions & 3 deletions src/os.cpp
Expand Up @@ -230,7 +230,7 @@ void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path) {
buf_init_from_buf(out_full_path, dirname);
uint8_t c = *(buf_ptr(out_full_path) + buf_len(out_full_path) - 1);
if (!os_is_sep(c))
buf_append_char(out_full_path, '/');
buf_append_char(out_full_path, ZIG_OS_SEP_CHAR);
buf_append_buf(out_full_path, basename);
}

Expand Down Expand Up @@ -838,7 +838,7 @@ int os_make_path(Buf *path) {
// march end_index backward until next path component
while (true) {
end_index -= 1;
if (buf_ptr(resolved_path)[end_index] == '/')
if (os_is_sep(buf_ptr(resolved_path)[end_index]))
break;
}
continue;
Expand All @@ -851,7 +851,7 @@ int os_make_path(Buf *path) {
// march end_index forward until next path component
while (true) {
end_index += 1;
if (end_index == buf_len(resolved_path) || buf_ptr(resolved_path)[end_index] == '/')
if (end_index == buf_len(resolved_path) || os_is_sep(buf_ptr(resolved_path)[end_index]))
break;
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/os.hpp
Expand Up @@ -97,12 +97,14 @@ int os_self_exe_path(Buf *out_path);
#define ZIG_PRI_llu "I64u"
#define ZIG_PRI_x64 "I64x"
#define OS_SEP "\\"
#define ZIG_OS_SEP_CHAR '\\'
#else
#define ZIG_PRI_usize "zu"
#define ZIG_PRI_u64 PRIu64
#define ZIG_PRI_llu "llu"
#define ZIG_PRI_x64 PRIx64
#define OS_SEP "/"
#define ZIG_OS_SEP_CHAR '/'
#endif

#endif
31 changes: 20 additions & 11 deletions std/os/index.zig
Expand Up @@ -1220,7 +1220,6 @@ pub const ArgIteratorPosix = struct {
pub const ArgIteratorWindows = struct {
index: usize,
cmd_line: &const u8,
backslash_count: usize,
in_quote: bool,
quote_count: usize,
seen_quote_count: usize,
Expand All @@ -1233,7 +1232,6 @@ pub const ArgIteratorWindows = struct {
return ArgIteratorWindows {
.index = 0,
.cmd_line = cmd_line,
.backslash_count = 0,
.in_quote = false,
.quote_count = countQuotes(cmd_line),
.seen_quote_count = 0,
Expand Down Expand Up @@ -1266,25 +1264,30 @@ pub const ArgIteratorWindows = struct {
}
}

var backslash_count: usize = 0;
while (true) : (self.index += 1) {
const byte = self.cmd_line[self.index];
switch (byte) {
0 => return true,
'"' => {
const quote_is_real = self.backslash_count % 2 == 0;
const quote_is_real = backslash_count % 2 == 0;
if (quote_is_real) {
self.seen_quote_count += 1;
}
},
'\\' => {
self.backslash_count += 1;
backslash_count += 1;
},
' ', '\t' => {
if (self.seen_quote_count % 2 == 0 or self.seen_quote_count == self.quote_count) {
return true;
}
backslash_count = 0;
},
else => {
backslash_count = 0;
continue;
},
else => continue,
}
}
}
Expand All @@ -1293,13 +1296,15 @@ pub const ArgIteratorWindows = struct {
var buf = %return Buffer.initSize(allocator, 0);
defer buf.deinit();

var backslash_count: usize = 0;
while (true) : (self.index += 1) {
const byte = self.cmd_line[self.index];
switch (byte) {
0 => return buf.toOwnedSlice(),
'"' => {
const quote_is_real = self.backslash_count % 2 == 0;
%return self.emitBackslashes(&buf, self.backslash_count / 2);
const quote_is_real = backslash_count % 2 == 0;
%return self.emitBackslashes(&buf, backslash_count / 2);
backslash_count = 0;

if (quote_is_real) {
self.seen_quote_count += 1;
Expand All @@ -1311,26 +1316,27 @@ pub const ArgIteratorWindows = struct {
}
},
'\\' => {
self.backslash_count += 1;
backslash_count += 1;
},
' ', '\t' => {
%return self.emitBackslashes(&buf, self.backslash_count);
%return self.emitBackslashes(&buf, backslash_count);
backslash_count = 0;
if (self.seen_quote_count % 2 == 1 and self.seen_quote_count != self.quote_count) {
%return buf.appendByte(byte);
} else {
return buf.toOwnedSlice();
}
},
else => {
%return self.emitBackslashes(&buf, self.backslash_count);
%return self.emitBackslashes(&buf, backslash_count);
backslash_count = 0;
%return buf.appendByte(byte);
},
}
}
}

fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) -> %void {
self.backslash_count = 0;
var i: usize = 0;
while (i < emit_count) : (i += 1) {
%return buf.appendByte('\\');
Expand Down Expand Up @@ -1400,6 +1406,9 @@ test "windows arg parsing" {
testWindowsCmdLine(c"a\\\\\\\"b c d", [][]const u8{"a\\\"b", "c", "d"});
testWindowsCmdLine(c"a\\\\\\\\\"b c\" d e", [][]const u8{"a\\\\b c", "d", "e"});
testWindowsCmdLine(c"a b\tc \"d f", [][]const u8{"a", "b", "c", "\"d", "f"});

testWindowsCmdLine(c"\".\\..\\zig-cache\\build\" \"bin\\zig.exe\" \".\\..\" \".\\..\\zig-cache\" \"--help\"",
[][]const u8{".\\..\\zig-cache\\build", "bin\\zig.exe", ".\\..", ".\\..\\zig-cache", "--help"});
}

fn testWindowsCmdLine(input_cmd_line: &const u8, expected_args: []const []const u8) {
Expand Down
2 changes: 1 addition & 1 deletion test/compile_errors.zig
Expand Up @@ -889,7 +889,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
\\const resource = @embedFile("bogus.txt");
\\
\\export fn entry() -> usize { @sizeOf(@typeOf(resource)) }
, ".tmp_source.zig:1:29: error: unable to find '", "/bogus.txt'");
, ".tmp_source.zig:1:29: error: unable to find '", "bogus.txt'");

cases.add("non-const expression in struct literal outside function",
\\const Foo = struct {
Expand Down

0 comments on commit e3ad13e

Please sign in to comment.