Skip to content

Commit e3ad13e

Browse files
committed
fix windows argument parsing
1 parent f87f980 commit e3ad13e

5 files changed

Lines changed: 27 additions & 16 deletions

File tree

src/codegen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,7 +1220,6 @@ pub const ArgIteratorPosix = struct {
12201220
pub 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,26 +1316,27 @@ 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 {
13211327
return buf.toOwnedSlice();
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
}
13291336
}
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

14051414
fn testWindowsCmdLine(input_cmd_line: &const u8, expected_args: []const []const u8) {

test/compile_errors.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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 {

0 commit comments

Comments
 (0)