aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/buffer.zig4
-rw-r--r--lib/std/cstr.zig12
-rw-r--r--lib/std/debug.zig34
-rw-r--r--lib/std/fs.zig9
-rw-r--r--lib/std/mem.zig9
-rw-r--r--lib/std/os.zig25
-rw-r--r--lib/std/zig/ast.zig5
-rw-r--r--lib/std/zig/parse.zig7
-rw-r--r--lib/std/zig/parser_test.zig3
-rw-r--r--lib/std/zig/render.zig8
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); // ]
},