diff options
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/buffer.zig | 4 | ||||
| -rw-r--r-- | lib/std/cstr.zig | 12 | ||||
| -rw-r--r-- | lib/std/debug.zig | 34 | ||||
| -rw-r--r-- | lib/std/fs.zig | 9 | ||||
| -rw-r--r-- | lib/std/mem.zig | 9 | ||||
| -rw-r--r-- | lib/std/os.zig | 25 | ||||
| -rw-r--r-- | lib/std/zig/ast.zig | 5 | ||||
| -rw-r--r-- | lib/std/zig/parse.zig | 7 | ||||
| -rw-r--r-- | lib/std/zig/parser_test.zig | 3 | ||||
| -rw-r--r-- | lib/std/zig/render.zig | 8 |
10 files changed, 70 insertions, 46 deletions
diff --git a/lib/std/buffer.zig b/lib/std/buffer.zig index 55a5a890d6..6313d693b7 100644 --- a/lib/std/buffer.zig +++ b/lib/std/buffer.zig @@ -82,11 +82,11 @@ pub const Buffer = struct { } pub fn toSlice(self: Buffer) [:0]u8 { - return self.list.toSlice()[0..self.len()]; + return self.list.toSlice()[0..self.len() :0]; } pub fn toSliceConst(self: Buffer) [:0]const u8 { - return self.list.toSliceConst()[0..self.len()]; + return self.list.toSliceConst()[0..self.len() :0]; } pub fn shrink(self: *Buffer, new_len: usize) void { diff --git a/lib/std/cstr.zig b/lib/std/cstr.zig index 6dbae8342e..5194dc1a13 100644 --- a/lib/std/cstr.zig +++ b/lib/std/cstr.zig @@ -31,13 +31,21 @@ fn testCStrFnsImpl() void { testing.expect(mem.len(u8, "123456789") == 9); } -/// Returns a mutable slice with 1 more byte of length which is a null byte. +/// Returns a mutable, null-terminated slice with the same length as `slice`. /// Caller owns the returned memory. pub fn addNullByte(allocator: *mem.Allocator, slice: []const u8) ![:0]u8 { const result = try allocator.alloc(u8, slice.len + 1); mem.copy(u8, result, slice); result[slice.len] = 0; - return result; + return result[0..slice.len :0]; +} + +test "addNullByte" { + var buf: [30]u8 = undefined; + const allocator = &std.heap.FixedBufferAllocator.init(&buf).allocator; + const slice = try addNullByte(allocator, "hello"[0..4]); + testing.expect(slice.len == 4); + testing.expect(slice[4] == 0); } pub const NullTerminated2DArray = struct { diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 9b24e1acd3..76685666ad 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -219,7 +219,7 @@ pub fn panic(comptime format: []const u8, args: var) noreturn { } /// TODO multithreaded awareness -var panicking: u8 = 0; // TODO make this a bool +var panicking: u8 = 0; pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, comptime format: []const u8, args: var) noreturn { @setCold(true); @@ -230,21 +230,25 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c resetSegfaultHandler(); } - if (@atomicRmw(u8, &panicking, builtin.AtomicRmwOp.Xchg, 1, builtin.AtomicOrder.SeqCst) == 1) { - // Panicked during a panic. - - // TODO detect if a different thread caused the panic, because in that case - // we would want to return here instead of calling abort, so that the thread - // which first called panic can finish printing a stack trace. - os.abort(); - } - const stderr = getStderrStream(); - stderr.print(format ++ "\n", args) catch os.abort(); - if (trace) |t| { - dumpStackTrace(t.*); + switch (@atomicRmw(u8, &panicking, .Add, 1, .SeqCst)) { + 0 => { + const stderr = getStderrStream(); + stderr.print(format ++ "\n", args) catch os.abort(); + if (trace) |t| { + dumpStackTrace(t.*); + } + dumpCurrentStackTrace(first_trace_addr); + }, + 1 => { + // TODO detect if a different thread caused the panic, because in that case + // we would want to return here instead of calling abort, so that the thread + // which first called panic can finish printing a stack trace. + warn("Panicked during a panic. Aborting.\n", .{}); + }, + else => { + // Panicked while printing "Panicked during a panic." + }, } - dumpCurrentStackTrace(first_trace_addr); - os.abort(); } diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 9e7daf0a9a..ea62086f59 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -221,16 +221,16 @@ pub const AtomicFile = struct { } tmp_path_buf[tmp_path_len] = 0; + const tmp_path_slice = tmp_path_buf[0..tmp_path_len :0]; const my_cwd = cwd(); while (true) { try crypto.randomBytes(rand_buf[0..]); - b64_fs_encoder.encode(tmp_path_buf[dirname_component_len..tmp_path_len], &rand_buf); + b64_fs_encoder.encode(tmp_path_slice[dirname_component_len..tmp_path_len], &rand_buf); - // TODO https://github.com/ziglang/zig/issues/3770 to clean up this @ptrCast const file = my_cwd.createFileC( - @ptrCast([*:0]u8, &tmp_path_buf), + tmp_path_slice, .{ .mode = mode, .exclusive = true }, ) catch |err| switch (err) { error.PathAlreadyExists => continue, @@ -1488,8 +1488,7 @@ pub fn openSelfExe() OpenSelfExeError!File { var buf: [MAX_PATH_BYTES]u8 = undefined; const self_exe_path = try selfExePath(&buf); buf[self_exe_path.len] = 0; - // TODO avoid @ptrCast here using slice syntax with https://github.com/ziglang/zig/issues/3770 - return openFileAbsoluteC(@ptrCast([*:0]u8, self_exe_path.ptr), .{}); + return openFileAbsoluteC(self_exe_path[0..self_exe_path.len :0].ptr, .{}); } test "openSelfExe" { diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 8082d31063..133e3b8a2d 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -231,9 +231,10 @@ pub const Allocator = struct { pub fn free(self: *Allocator, memory: var) void { const Slice = @typeInfo(@TypeOf(memory)).Pointer; const bytes = @sliceToBytes(memory); - if (bytes.len == 0) return; + const bytes_len = bytes.len + @boolToInt(Slice.sentinel != null); + if (bytes_len == 0) return; const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr)); - const shrink_result = self.shrinkFn(self, non_const_ptr[0..bytes.len], Slice.alignment, 0, 1); + const shrink_result = self.shrinkFn(self, non_const_ptr[0..bytes_len], Slice.alignment, 0, 1); assert(shrink_result.len == 0); } }; @@ -363,11 +364,11 @@ pub fn len(comptime T: type, ptr: [*:0]const T) usize { } pub fn toSliceConst(comptime T: type, ptr: [*:0]const T) [:0]const T { - return ptr[0..len(T, ptr)]; + return ptr[0..len(T, ptr) :0]; } pub fn toSlice(comptime T: type, ptr: [*:0]T) [:0]T { - return ptr[0..len(T, ptr)]; + return ptr[0..len(T, ptr) :0]; } /// Returns true if all elements in a slice are equal to the scalar value provided diff --git a/lib/std/os.zig b/lib/std/os.zig index 6d49bcd38e..3cc43357bd 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -805,9 +805,9 @@ pub fn execvpeC(file: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, e mem.copy(u8, &path_buf, search_path); path_buf[search_path.len] = '/'; mem.copy(u8, path_buf[search_path.len + 1 ..], file_slice); - path_buf[search_path.len + file_slice.len + 1] = 0; - // TODO avoid @ptrCast here using slice syntax with https://github.com/ziglang/zig/issues/3770 - err = execveC(@ptrCast([*:0]u8, &path_buf), child_argv, envp); + const path_len = search_path.len + file_slice.len + 1; + path_buf[path_len] = 0; + err = execveC(path_buf[0..path_len :0].ptr, child_argv, envp); switch (err) { error.AccessDenied => seen_eacces = true, error.FileNotFound, error.NotDir => {}, @@ -841,18 +841,14 @@ pub fn execvpe( const arg_buf = try allocator.alloc(u8, arg.len + 1); @memcpy(arg_buf.ptr, arg.ptr, arg.len); arg_buf[arg.len] = 0; - - // TODO avoid @ptrCast using slice syntax with https://github.com/ziglang/zig/issues/3770 - argv_buf[i] = @ptrCast([*:0]u8, arg_buf.ptr); + argv_buf[i] = arg_buf[0..arg.len :0].ptr; } argv_buf[argv_slice.len] = null; + const argv_ptr = argv_buf[0..argv_slice.len :null].ptr; const envp_buf = try createNullDelimitedEnvMap(allocator, env_map); defer freeNullDelimitedEnvMap(allocator, envp_buf); - // TODO avoid @ptrCast here using slice syntax with https://github.com/ziglang/zig/issues/3770 - const argv_ptr = @ptrCast([*:null]?[*:0]u8, argv_buf.ptr); - return execvpeC(argv_buf.ptr[0].?, argv_ptr, envp_buf.ptr); } @@ -869,16 +865,13 @@ pub fn createNullDelimitedEnvMap(allocator: *mem.Allocator, env_map: *const std. @memcpy(env_buf.ptr, pair.key.ptr, pair.key.len); env_buf[pair.key.len] = '='; @memcpy(env_buf.ptr + pair.key.len + 1, pair.value.ptr, pair.value.len); - env_buf[env_buf.len - 1] = 0; - - // TODO avoid @ptrCast here using slice syntax with https://github.com/ziglang/zig/issues/3770 - envp_buf[i] = @ptrCast([*:0]u8, env_buf.ptr); + const len = env_buf.len - 1; + env_buf[len] = 0; + envp_buf[i] = env_buf[0..len :0].ptr; } assert(i == envp_count); } - // TODO avoid @ptrCast here using slice syntax with https://github.com/ziglang/zig/issues/3770 - assert(envp_buf[envp_count] == null); - return @ptrCast([*:null]?[*:0]u8, envp_buf.ptr)[0..envp_count]; + return envp_buf[0..envp_count :null]; } pub fn freeNullDelimitedEnvMap(allocator: *mem.Allocator, envp_buf: []?[*:0]u8) void { diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index 47933917b1..e27e62c094 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -1701,6 +1701,7 @@ pub const Node = struct { pub const Slice = struct { start: *Node, end: ?*Node, + sentinel: ?*Node, }; }; @@ -1732,6 +1733,10 @@ pub const Node = struct { if (i < 1) return end; i -= 1; } + if (range.sentinel) |sentinel| { + if (i < 1) return sentinel; + i -= 1; + } }, .ArrayInitializer => |*exprs| { if (i < exprs.len) return exprs.at(i).*; diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index bcf0ea01da..5b168be2e1 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -2331,7 +2331,7 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node } /// SuffixOp -/// <- LBRACKET Expr (DOT2 Expr?)? RBRACKET +/// <- LBRACKET Expr (DOT2 (Expr (COLON Expr)?)?)? RBRACKET /// / DOT IDENTIFIER /// / DOTASTERISK /// / DOTQUESTIONMARK @@ -2349,11 +2349,16 @@ fn parseSuffixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { if (eatToken(it, .Ellipsis2) != null) { const end_expr = try parseExpr(arena, it, tree); + const sentinel: ?*ast.Node = if (eatToken(it, .Colon) != null) + try parseExpr(arena, it, tree) + else + null; break :blk OpAndToken{ .op = Op{ .Slice = Op.Slice{ .start = index_expr, .end = end_expr, + .sentinel = sentinel, }, }, .token = try expectToken(it, tree, .RBracket), diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index ba022eec95..f193e1b6ef 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -419,10 +419,13 @@ test "zig fmt: pointer of unknown length" { test "zig fmt: spaces around slice operator" { try testCanonical( \\var a = b[c..d]; + \\var a = b[c..d :0]; \\var a = b[c + 1 .. d]; \\var a = b[c + 1 ..]; \\var a = b[c .. d + 1]; + \\var a = b[c .. d + 1 :0]; \\var a = b[c.a..d.e]; + \\var a = b[c.a..d.e :0]; \\ ); } diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 41b8c48b10..263f45a88b 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -689,7 +689,13 @@ fn renderExpression( try renderExpression(allocator, stream, tree, indent, start_col, range.start, after_start_space); try renderToken(tree, stream, dotdot, indent, start_col, after_op_space); // .. if (range.end) |end| { - try renderExpression(allocator, stream, tree, indent, start_col, end, Space.None); + const after_end_space = if (range.sentinel != null) Space.Space else Space.None; + try renderExpression(allocator, stream, tree, indent, start_col, end, after_end_space); + } + if (range.sentinel) |sentinel| { + const colon = tree.prevToken(sentinel.firstToken()); + try renderToken(tree, stream, colon, indent, start_col, Space.None); // : + try renderExpression(allocator, stream, tree, indent, start_col, sentinel, Space.None); } return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // ] }, |
