fix windows argument parsing

master
Andrew Kelley 2017-10-15 20:15:01 -04:00
parent f87f98015c
commit e3ad13e054
5 changed files with 27 additions and 16 deletions

View File

@ -4436,7 +4436,7 @@ static void do_code_gen(CodeGen *g) {
if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
LLVMObjectFile, &err_msg, g->build_mode == BuildModeDebug)) 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); validate_inline_fns(g);

View File

@ -230,7 +230,7 @@ void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path) {
buf_init_from_buf(out_full_path, dirname); buf_init_from_buf(out_full_path, dirname);
uint8_t c = *(buf_ptr(out_full_path) + buf_len(out_full_path) - 1); uint8_t c = *(buf_ptr(out_full_path) + buf_len(out_full_path) - 1);
if (!os_is_sep(c)) 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); buf_append_buf(out_full_path, basename);
} }
@ -838,7 +838,7 @@ int os_make_path(Buf *path) {
// march end_index backward until next path component // march end_index backward until next path component
while (true) { while (true) {
end_index -= 1; end_index -= 1;
if (buf_ptr(resolved_path)[end_index] == '/') if (os_is_sep(buf_ptr(resolved_path)[end_index]))
break; break;
} }
continue; continue;
@ -851,7 +851,7 @@ int os_make_path(Buf *path) {
// march end_index forward until next path component // march end_index forward until next path component
while (true) { while (true) {
end_index += 1; 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; break;
} }
} }

View File

@ -97,12 +97,14 @@ int os_self_exe_path(Buf *out_path);
#define ZIG_PRI_llu "I64u" #define ZIG_PRI_llu "I64u"
#define ZIG_PRI_x64 "I64x" #define ZIG_PRI_x64 "I64x"
#define OS_SEP "\\" #define OS_SEP "\\"
#define ZIG_OS_SEP_CHAR '\\'
#else #else
#define ZIG_PRI_usize "zu" #define ZIG_PRI_usize "zu"
#define ZIG_PRI_u64 PRIu64 #define ZIG_PRI_u64 PRIu64
#define ZIG_PRI_llu "llu" #define ZIG_PRI_llu "llu"
#define ZIG_PRI_x64 PRIx64 #define ZIG_PRI_x64 PRIx64
#define OS_SEP "/" #define OS_SEP "/"
#define ZIG_OS_SEP_CHAR '/'
#endif #endif
#endif #endif

View File

@ -1220,7 +1220,6 @@ pub const ArgIteratorPosix = struct {
pub const ArgIteratorWindows = struct { pub const ArgIteratorWindows = struct {
index: usize, index: usize,
cmd_line: &const u8, cmd_line: &const u8,
backslash_count: usize,
in_quote: bool, in_quote: bool,
quote_count: usize, quote_count: usize,
seen_quote_count: usize, seen_quote_count: usize,
@ -1233,7 +1232,6 @@ pub const ArgIteratorWindows = struct {
return ArgIteratorWindows { return ArgIteratorWindows {
.index = 0, .index = 0,
.cmd_line = cmd_line, .cmd_line = cmd_line,
.backslash_count = 0,
.in_quote = false, .in_quote = false,
.quote_count = countQuotes(cmd_line), .quote_count = countQuotes(cmd_line),
.seen_quote_count = 0, .seen_quote_count = 0,
@ -1266,25 +1264,30 @@ pub const ArgIteratorWindows = struct {
} }
} }
var backslash_count: usize = 0;
while (true) : (self.index += 1) { while (true) : (self.index += 1) {
const byte = self.cmd_line[self.index]; const byte = self.cmd_line[self.index];
switch (byte) { switch (byte) {
0 => return true, 0 => return true,
'"' => { '"' => {
const quote_is_real = self.backslash_count % 2 == 0; const quote_is_real = backslash_count % 2 == 0;
if (quote_is_real) { if (quote_is_real) {
self.seen_quote_count += 1; self.seen_quote_count += 1;
} }
}, },
'\\' => { '\\' => {
self.backslash_count += 1; backslash_count += 1;
}, },
' ', '\t' => { ' ', '\t' => {
if (self.seen_quote_count % 2 == 0 or self.seen_quote_count == self.quote_count) { if (self.seen_quote_count % 2 == 0 or self.seen_quote_count == self.quote_count) {
return true; return true;
} }
backslash_count = 0;
},
else => {
backslash_count = 0;
continue;
}, },
else => continue,
} }
} }
} }
@ -1293,13 +1296,15 @@ pub const ArgIteratorWindows = struct {
var buf = %return Buffer.initSize(allocator, 0); var buf = %return Buffer.initSize(allocator, 0);
defer buf.deinit(); defer buf.deinit();
var backslash_count: usize = 0;
while (true) : (self.index += 1) { while (true) : (self.index += 1) {
const byte = self.cmd_line[self.index]; const byte = self.cmd_line[self.index];
switch (byte) { switch (byte) {
0 => return buf.toOwnedSlice(), 0 => return buf.toOwnedSlice(),
'"' => { '"' => {
const quote_is_real = self.backslash_count % 2 == 0; const quote_is_real = backslash_count % 2 == 0;
%return self.emitBackslashes(&buf, self.backslash_count / 2); %return self.emitBackslashes(&buf, backslash_count / 2);
backslash_count = 0;
if (quote_is_real) { if (quote_is_real) {
self.seen_quote_count += 1; self.seen_quote_count += 1;
@ -1311,10 +1316,11 @@ pub const ArgIteratorWindows = struct {
} }
}, },
'\\' => { '\\' => {
self.backslash_count += 1; backslash_count += 1;
}, },
' ', '\t' => { ' ', '\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) { if (self.seen_quote_count % 2 == 1 and self.seen_quote_count != self.quote_count) {
%return buf.appendByte(byte); %return buf.appendByte(byte);
} else { } else {
@ -1322,7 +1328,8 @@ pub const ArgIteratorWindows = struct {
} }
}, },
else => { else => {
%return self.emitBackslashes(&buf, self.backslash_count); %return self.emitBackslashes(&buf, backslash_count);
backslash_count = 0;
%return buf.appendByte(byte); %return buf.appendByte(byte);
}, },
} }
@ -1330,7 +1337,6 @@ pub const ArgIteratorWindows = struct {
} }
fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) -> %void { fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) -> %void {
self.backslash_count = 0;
var i: usize = 0; var i: usize = 0;
while (i < emit_count) : (i += 1) { while (i < emit_count) : (i += 1) {
%return buf.appendByte('\\'); %return buf.appendByte('\\');
@ -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", [][]const u8{"a\\\"b", "c", "d"});
testWindowsCmdLine(c"a\\\\\\\\\"b c\" d e", [][]const u8{"a\\\\b c", "d", "e"}); 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"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) { fn testWindowsCmdLine(input_cmd_line: &const u8, expected_args: []const []const u8) {

View File

@ -889,7 +889,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
\\const resource = @embedFile("bogus.txt"); \\const resource = @embedFile("bogus.txt");
\\ \\
\\export fn entry() -> usize { @sizeOf(@typeOf(resource)) } \\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", cases.add("non-const expression in struct literal outside function",
\\const Foo = struct { \\const Foo = struct {