mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 13:30:45 +00:00
Merge remote-tracking branch 'origin/master' into m-n-threading
This commit is contained in:
commit
3f4d0ecd7e
@ -689,7 +689,10 @@ fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 {
|
||||
fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var, zig_exe: []const u8) !void {
|
||||
var code_progress_index: usize = 0;
|
||||
|
||||
const builtin_code = try escapeHtml(allocator, try getBuiltinCode(allocator, zig_exe));
|
||||
var env_map = try os.getEnvMap(allocator);
|
||||
try env_map.set("ZIG_DEBUG_COLOR", "1");
|
||||
|
||||
const builtin_code = try escapeHtml(allocator, try getBuiltinCode(allocator, &env_map, zig_exe));
|
||||
|
||||
for (toc.nodes) |node| {
|
||||
switch (node) {
|
||||
@ -778,12 +781,12 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
try build_args.append("c");
|
||||
try out.print(" --library c");
|
||||
}
|
||||
_ = exec(allocator, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
|
||||
_ = exec(allocator, &env_map, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
|
||||
|
||||
const run_args = [][]const u8{tmp_bin_file_name};
|
||||
|
||||
const result = if (expected_outcome == ExpectedOutcome.Fail) blk: {
|
||||
const result = try os.ChildProcess.exec(allocator, run_args, null, null, max_doc_file_size);
|
||||
const result = try os.ChildProcess.exec(allocator, run_args, null, &env_map, max_doc_file_size);
|
||||
switch (result.term) {
|
||||
os.ChildProcess.Term.Exited => |exit_code| {
|
||||
if (exit_code == 0) {
|
||||
@ -799,7 +802,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
}
|
||||
break :blk result;
|
||||
} else blk: {
|
||||
break :blk exec(allocator, run_args) catch return parseError(tokenizer, code.source_token, "example crashed");
|
||||
break :blk exec(allocator, &env_map, run_args) catch return parseError(tokenizer, code.source_token, "example crashed");
|
||||
};
|
||||
|
||||
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
||||
@ -845,7 +848,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
"msvc",
|
||||
});
|
||||
}
|
||||
const result = exec(allocator, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed");
|
||||
const result = exec(allocator, &env_map, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed");
|
||||
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
||||
const escaped_stdout = try escapeHtml(allocator, result.stdout);
|
||||
try out.print("\n{}{}</code></pre>\n", escaped_stderr, escaped_stdout);
|
||||
@ -877,7 +880,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
try out.print(" --release-small");
|
||||
},
|
||||
}
|
||||
const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size);
|
||||
const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, &env_map, max_doc_file_size);
|
||||
switch (result.term) {
|
||||
os.ChildProcess.Term.Exited => |exit_code| {
|
||||
if (exit_code == 0) {
|
||||
@ -923,7 +926,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
builtin.Mode.ReleaseSmall => try test_args.append("--release-small"),
|
||||
}
|
||||
|
||||
const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size);
|
||||
const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, &env_map, max_doc_file_size);
|
||||
switch (result.term) {
|
||||
os.ChildProcess.Term.Exited => |exit_code| {
|
||||
if (exit_code == 0) {
|
||||
@ -1000,7 +1003,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
}
|
||||
|
||||
if (maybe_error_match) |error_match| {
|
||||
const result = try os.ChildProcess.exec(allocator, build_args.toSliceConst(), null, null, max_doc_file_size);
|
||||
const result = try os.ChildProcess.exec(allocator, build_args.toSliceConst(), null, &env_map, max_doc_file_size);
|
||||
switch (result.term) {
|
||||
os.ChildProcess.Term.Exited => |exit_code| {
|
||||
if (exit_code == 0) {
|
||||
@ -1032,7 +1035,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
try out.print("</code></pre>\n");
|
||||
}
|
||||
} else {
|
||||
_ = exec(allocator, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
|
||||
_ = exec(allocator, &env_map, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
|
||||
}
|
||||
if (!code.is_inline) {
|
||||
try out.print("</code></pre>\n");
|
||||
@ -1045,8 +1048,8 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
}
|
||||
}
|
||||
|
||||
fn exec(allocator: *mem.Allocator, args: []const []const u8) !os.ChildProcess.ExecResult {
|
||||
const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);
|
||||
fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u8) !os.ChildProcess.ExecResult {
|
||||
const result = try os.ChildProcess.exec(allocator, args, null, env_map, max_doc_file_size);
|
||||
switch (result.term) {
|
||||
os.ChildProcess.Term.Exited => |exit_code| {
|
||||
if (exit_code != 0) {
|
||||
@ -1070,8 +1073,8 @@ fn exec(allocator: *mem.Allocator, args: []const []const u8) !os.ChildProcess.Ex
|
||||
return result;
|
||||
}
|
||||
|
||||
fn getBuiltinCode(allocator: *mem.Allocator, zig_exe: []const u8) ![]const u8 {
|
||||
const result = try exec(allocator, []const []const u8{
|
||||
fn getBuiltinCode(allocator: *mem.Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 {
|
||||
const result = try exec(allocator, env_map, []const []const u8{
|
||||
zig_exe,
|
||||
"builtin",
|
||||
});
|
||||
|
||||
@ -6649,12 +6649,60 @@ pub fn main() void {
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Invalid Error Set Cast#}
|
||||
<p>TODO</p>
|
||||
<p>At compile-time:</p>
|
||||
{#code_begin|test_err|error.B not a member of error set 'Set2'#}
|
||||
const Set1 = error{
|
||||
A,
|
||||
B,
|
||||
};
|
||||
const Set2 = error{
|
||||
A,
|
||||
C,
|
||||
};
|
||||
comptime {
|
||||
_ = @errSetCast(Set2, Set1.B);
|
||||
}
|
||||
{#code_end#}
|
||||
<p>At runtime:</p>
|
||||
{#code_begin|exe_err#}
|
||||
const Set1 = error{
|
||||
A,
|
||||
B,
|
||||
};
|
||||
const Set2 = error{
|
||||
A,
|
||||
C,
|
||||
};
|
||||
pub fn main() void {
|
||||
_ = foo(Set1.B);
|
||||
}
|
||||
fn foo(set1: Set1) Set2 {
|
||||
return @errSetCast(Set2, set1);
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Incorrect Pointer Alignment#}
|
||||
<p>TODO</p>
|
||||
|
||||
<p>At compile-time:</p>
|
||||
{#code_begin|test_err|pointer address 0x1 is not aligned to 4 bytes#}
|
||||
comptime {
|
||||
const ptr = @intToPtr(*i32, 0x1);
|
||||
const aligned = @alignCast(4, ptr);
|
||||
}
|
||||
{#code_end#}
|
||||
<p>At runtime:</p>
|
||||
{#code_begin|exe_err#}
|
||||
pub fn main() !void {
|
||||
var array align(4) = []u32{ 0x11111111, 0x11111111 };
|
||||
const bytes = @sliceToBytes(array[0..]);
|
||||
if (foo(bytes) != 0x11111111) return error.Wrong;
|
||||
}
|
||||
fn foo(bytes: []u8) u32 {
|
||||
const slice4 = bytes[1..5];
|
||||
const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));
|
||||
return int_slice[0];
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
{#header_open|Wrong Union Field Access#}
|
||||
<p>TODO</p>
|
||||
|
||||
15
src/ir.cpp
15
src/ir.cpp
@ -19370,6 +19370,15 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3
|
||||
if (!val)
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr &&
|
||||
val->data.x_ptr.data.hard_coded_addr.addr % align_bytes != 0)
|
||||
{
|
||||
ir_add_error(ira, target,
|
||||
buf_sprintf("pointer address 0x%" ZIG_PRI_x64 " is not aligned to %" PRIu32 " bytes",
|
||||
val->data.x_ptr.data.hard_coded_addr.addr, align_bytes));
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
|
||||
IrInstruction *result = ir_create_const(&ira->new_irb, target->scope, target->source_node, result_type);
|
||||
copy_const_val(&result->value, val, false);
|
||||
result->value.type = result_type;
|
||||
@ -19796,6 +19805,12 @@ static TypeTableEntry *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstr
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
if (!type_has_bits(target->value.type)) {
|
||||
ir_add_error(ira, target,
|
||||
buf_sprintf("pointer to size 0 type has no address"));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
if (instr_is_comptime(target)) {
|
||||
ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
|
||||
if (!val)
|
||||
|
||||
@ -814,6 +814,7 @@ pub const LibExeObjStep = struct {
|
||||
out_h_filename: []const u8,
|
||||
assembly_files: ArrayList([]const u8),
|
||||
packages: ArrayList(Pkg),
|
||||
build_options_contents: std.Buffer,
|
||||
|
||||
// C only stuff
|
||||
source_files: ArrayList([]const u8),
|
||||
@ -905,6 +906,7 @@ pub const LibExeObjStep = struct {
|
||||
.lib_paths = ArrayList([]const u8).init(builder.allocator),
|
||||
.object_src = undefined,
|
||||
.disable_libc = true,
|
||||
.build_options_contents = std.Buffer.initSize(builder.allocator, 0) catch unreachable,
|
||||
};
|
||||
self.computeOutFileNames();
|
||||
return self;
|
||||
@ -945,6 +947,7 @@ pub const LibExeObjStep = struct {
|
||||
.out_h_filename = undefined,
|
||||
.assembly_files = undefined,
|
||||
.packages = undefined,
|
||||
.build_options_contents = undefined,
|
||||
};
|
||||
self.computeOutFileNames();
|
||||
return self;
|
||||
@ -1096,6 +1099,12 @@ pub const LibExeObjStep = struct {
|
||||
self.include_dirs.append(self.builder.cache_root) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn addBuildOption(self: *LibExeObjStep, comptime T: type, name: []const u8, value: T) void {
|
||||
assert(self.is_zig);
|
||||
const out = &std.io.BufferOutStream.init(&self.build_options_contents).stream;
|
||||
out.print("pub const {} = {};\n", name, value) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn addIncludeDir(self: *LibExeObjStep, path: []const u8) void {
|
||||
self.include_dirs.append(path) catch unreachable;
|
||||
}
|
||||
@ -1155,6 +1164,15 @@ pub const LibExeObjStep = struct {
|
||||
zig_args.append(builder.pathFromRoot(root_src)) catch unreachable;
|
||||
}
|
||||
|
||||
if (self.build_options_contents.len() > 0) {
|
||||
const build_options_file = try os.path.join(builder.allocator, builder.cache_root, builder.fmt("{}_build_options.zig", self.name));
|
||||
try std.io.writeFile(builder.allocator, build_options_file, self.build_options_contents.toSliceConst());
|
||||
try zig_args.append("--pkg-begin");
|
||||
try zig_args.append("build_options");
|
||||
try zig_args.append(builder.pathFromRoot(build_options_file));
|
||||
try zig_args.append("--pkg-end");
|
||||
}
|
||||
|
||||
for (self.object_files.toSliceConst()) |object_file| {
|
||||
zig_args.append("--object") catch unreachable;
|
||||
zig_args.append(builder.pathFromRoot(object_file)) catch unreachable;
|
||||
|
||||
@ -10,6 +10,7 @@ const ArrayList = std.ArrayList;
|
||||
const builtin = @import("builtin");
|
||||
|
||||
pub const FailingAllocator = @import("failing_allocator.zig").FailingAllocator;
|
||||
pub const failing_allocator = FailingAllocator.init(global_allocator, 0);
|
||||
|
||||
pub const runtime_safety = switch (builtin.mode) {
|
||||
builtin.Mode.Debug, builtin.Mode.ReleaseSafe => true,
|
||||
@ -49,6 +50,12 @@ pub fn getSelfDebugInfo() !*ElfStackTrace {
|
||||
}
|
||||
}
|
||||
|
||||
fn wantTtyColor() bool {
|
||||
var bytes: [128]u8 = undefined;
|
||||
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
||||
return if (std.os.getEnvVarOwned(allocator, "ZIG_DEBUG_COLOR")) |_| true else |_| stderr_file.isTty();
|
||||
}
|
||||
|
||||
/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
|
||||
pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
|
||||
const stderr = getStderrStream() catch return;
|
||||
@ -56,7 +63,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
|
||||
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;
|
||||
return;
|
||||
};
|
||||
writeCurrentStackTrace(stderr, getDebugInfoAllocator(), debug_info, stderr_file.isTty(), start_addr) catch |err| {
|
||||
writeCurrentStackTrace(stderr, getDebugInfoAllocator(), debug_info, wantTtyColor(), start_addr) catch |err| {
|
||||
stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;
|
||||
return;
|
||||
};
|
||||
@ -69,7 +76,7 @@ pub fn dumpStackTrace(stack_trace: *const builtin.StackTrace) void {
|
||||
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;
|
||||
return;
|
||||
};
|
||||
writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, stderr_file.isTty()) catch |err| {
|
||||
writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, wantTtyColor()) catch |err| {
|
||||
stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;
|
||||
return;
|
||||
};
|
||||
@ -161,7 +168,7 @@ pub fn writeStackTrace(stack_trace: *const builtin.StackTrace, out_stream: var,
|
||||
frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len;
|
||||
}) {
|
||||
const return_address = stack_trace.instruction_addresses[frame_index];
|
||||
try printSourceAtAddress(debug_info, out_stream, return_address);
|
||||
try printSourceAtAddress(debug_info, out_stream, return_address, tty_color);
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,13 +201,11 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_
|
||||
}
|
||||
},
|
||||
}
|
||||
try printSourceAtAddress(debug_info, out_stream, return_address);
|
||||
try printSourceAtAddress(debug_info, out_stream, return_address, tty_color);
|
||||
}
|
||||
}
|
||||
|
||||
fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: usize) !void {
|
||||
const ptr_hex = "0x{x}";
|
||||
|
||||
fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: usize, tty_color: bool) !void {
|
||||
switch (builtin.os) {
|
||||
builtin.Os.windows => return error.UnsupportedDebugInfo,
|
||||
builtin.Os.macosx => {
|
||||
@ -214,36 +219,58 @@ fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: us
|
||||
.address = address,
|
||||
};
|
||||
const symbol = debug_info.symbol_table.search(address) orelse &unknown;
|
||||
try out_stream.print(WHITE ++ "{}" ++ RESET ++ ": " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n", symbol.name, address);
|
||||
try out_stream.print(WHITE ++ "{}" ++ RESET ++ ": " ++ DIM ++ "0x{x}" ++ " in ??? (???)" ++ RESET ++ "\n", symbol.name, address);
|
||||
},
|
||||
else => {
|
||||
const compile_unit = findCompileUnit(debug_info, address) catch {
|
||||
try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n", address);
|
||||
if (tty_color) {
|
||||
try out_stream.print("???:?:?: " ++ DIM ++ "0x{x} in ??? (???)" ++ RESET ++ "\n ???\n\n", address);
|
||||
} else {
|
||||
try out_stream.print("???:?:?: 0x{x} in ??? (???)\n ???\n\n", address);
|
||||
}
|
||||
return;
|
||||
};
|
||||
const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name);
|
||||
if (getLineNumberInfo(debug_info, compile_unit, address - 1)) |line_info| {
|
||||
defer line_info.deinit();
|
||||
try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n", line_info.file_name, line_info.line, line_info.column, address, compile_unit_name);
|
||||
if (printLineFromFile(debug_info.allocator(), out_stream, line_info)) {
|
||||
if (line_info.column == 0) {
|
||||
try out_stream.write("\n");
|
||||
} else {
|
||||
{
|
||||
var col_i: usize = 1;
|
||||
while (col_i < line_info.column) : (col_i += 1) {
|
||||
try out_stream.writeByte(' ');
|
||||
if (tty_color) {
|
||||
try out_stream.print(
|
||||
WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ DIM ++ "0x{x} in ??? ({})" ++ RESET ++ "\n",
|
||||
line_info.file_name,
|
||||
line_info.line,
|
||||
line_info.column,
|
||||
address,
|
||||
compile_unit_name,
|
||||
);
|
||||
if (printLineFromFile(debug_info.allocator(), out_stream, line_info)) {
|
||||
if (line_info.column == 0) {
|
||||
try out_stream.write("\n");
|
||||
} else {
|
||||
{
|
||||
var col_i: usize = 1;
|
||||
while (col_i < line_info.column) : (col_i += 1) {
|
||||
try out_stream.writeByte(' ');
|
||||
}
|
||||
}
|
||||
try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n");
|
||||
}
|
||||
try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n");
|
||||
} else |err| switch (err) {
|
||||
error.EndOfFile => {},
|
||||
else => return err,
|
||||
}
|
||||
} else |err| switch (err) {
|
||||
error.EndOfFile => {},
|
||||
else => return err,
|
||||
} else {
|
||||
try out_stream.print(
|
||||
"{}:{}:{}: 0x{x} in ??? ({})\n",
|
||||
line_info.file_name,
|
||||
line_info.line,
|
||||
line_info.column,
|
||||
address,
|
||||
compile_unit_name,
|
||||
);
|
||||
}
|
||||
} else |err| switch (err) {
|
||||
error.MissingDebugInfo, error.InvalidDebugInfo => {
|
||||
try out_stream.print(ptr_hex ++ " in ??? ({})\n", address, compile_unit_name);
|
||||
try out_stream.print("0x{x} in ??? ({})\n", address, compile_unit_name);
|
||||
},
|
||||
else => return err,
|
||||
}
|
||||
|
||||
@ -259,14 +259,14 @@ test "basic hash map usage" {
|
||||
var map = HashMap(i32, i32, hash_i32, eql_i32).init(&direct_allocator.allocator);
|
||||
defer map.deinit();
|
||||
|
||||
assert((map.put(1, 11) catch unreachable) == null);
|
||||
assert((map.put(2, 22) catch unreachable) == null);
|
||||
assert((map.put(3, 33) catch unreachable) == null);
|
||||
assert((map.put(4, 44) catch unreachable) == null);
|
||||
assert((map.put(5, 55) catch unreachable) == null);
|
||||
assert((try map.put(1, 11)) == null);
|
||||
assert((try map.put(2, 22)) == null);
|
||||
assert((try map.put(3, 33)) == null);
|
||||
assert((try map.put(4, 44)) == null);
|
||||
assert((try map.put(5, 55)) == null);
|
||||
|
||||
assert((map.put(5, 66) catch unreachable).? == 55);
|
||||
assert((map.put(5, 55) catch unreachable).? == 66);
|
||||
assert((try map.put(5, 66)).? == 55);
|
||||
assert((try map.put(5, 55)).? == 66);
|
||||
|
||||
assert(map.contains(2));
|
||||
assert(map.get(2).?.value == 22);
|
||||
@ -282,9 +282,9 @@ test "iterator hash map" {
|
||||
var reset_map = HashMap(i32, i32, hash_i32, eql_i32).init(&direct_allocator.allocator);
|
||||
defer reset_map.deinit();
|
||||
|
||||
assert((reset_map.put(1, 11) catch unreachable) == null);
|
||||
assert((reset_map.put(2, 22) catch unreachable) == null);
|
||||
assert((reset_map.put(3, 33) catch unreachable) == null);
|
||||
assert((try reset_map.put(1, 11)) == null);
|
||||
assert((try reset_map.put(2, 22)) == null);
|
||||
assert((try reset_map.put(3, 33)) == null);
|
||||
|
||||
var keys = []i32{
|
||||
1,
|
||||
|
||||
@ -553,8 +553,13 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 {
|
||||
return null;
|
||||
}
|
||||
|
||||
pub const GetEnvVarOwnedError = error{
|
||||
OutOfMemory,
|
||||
EnvironmentVariableNotFound,
|
||||
};
|
||||
|
||||
/// Caller must free returned memory.
|
||||
pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) ![]u8 {
|
||||
pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
|
||||
if (is_windows) {
|
||||
const key_with_null = try cstr.addNullByte(allocator, key);
|
||||
defer allocator.free(key_with_null);
|
||||
@ -563,14 +568,17 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) ![]u8 {
|
||||
errdefer allocator.free(buf);
|
||||
|
||||
while (true) {
|
||||
const windows_buf_len = try math.cast(windows.DWORD, buf.len);
|
||||
const windows_buf_len = math.cast(windows.DWORD, buf.len) catch return error.OutOfMemory;
|
||||
const result = windows.GetEnvironmentVariableA(key_with_null.ptr, buf.ptr, windows_buf_len);
|
||||
|
||||
if (result == 0) {
|
||||
const err = windows.GetLastError();
|
||||
return switch (err) {
|
||||
windows.ERROR.ENVVAR_NOT_FOUND => error.EnvironmentVariableNotFound,
|
||||
else => unexpectedErrorWindows(err),
|
||||
else => {
|
||||
_ = unexpectedErrorWindows(err);
|
||||
return error.EnvironmentVariableNotFound;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -122,10 +122,13 @@ pub fn main() !void {
|
||||
return usageAndErr(&builder, true, try stderr_stream);
|
||||
|
||||
builder.make(targets.toSliceConst()) catch |err| {
|
||||
if (err == error.InvalidStepName) {
|
||||
return usageAndErr(&builder, true, try stderr_stream);
|
||||
switch (err) {
|
||||
error.InvalidStepName => {
|
||||
return usageAndErr(&builder, true, try stderr_stream);
|
||||
},
|
||||
error.UncleanExit => os.exit(1),
|
||||
else => return err,
|
||||
}
|
||||
return err;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -19,20 +19,18 @@ pub fn main() !void {
|
||||
}
|
||||
const end = timer.read();
|
||||
memory_used /= iterations;
|
||||
const elapsed_s = f64(end - start) / std.os.time.ns_per_s;
|
||||
const bytes_per_sec = f64(source.len * iterations) / elapsed_s;
|
||||
const elapsed_s = @intToFloat(f64, end - start) / std.os.time.ns_per_s;
|
||||
const bytes_per_sec = @intToFloat(f64, source.len * iterations) / elapsed_s;
|
||||
const mb_per_sec = bytes_per_sec / (1024 * 1024);
|
||||
|
||||
var stdout_file = try std.io.getStdOut();
|
||||
const stdout = *std.io.FileOutStream.init(*stdout_file).stream;
|
||||
try stdout.print("{.3} MB/s, {} KB used \n", mb_per_sec, memory_used / 1024);
|
||||
const stdout = &std.io.FileOutStream.init(&stdout_file).stream;
|
||||
try stdout.print("{.3} MiB/s, {} KiB used \n", mb_per_sec, memory_used / 1024);
|
||||
}
|
||||
|
||||
fn testOnce() usize {
|
||||
var fixed_buf_alloc = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
|
||||
var allocator = *fixed_buf_alloc.allocator;
|
||||
var tokenizer = Tokenizer.init(source);
|
||||
var parser = Parser.init(*tokenizer, allocator, "(memory buffer)");
|
||||
_ = parser.parse() catch @panic("parse failure");
|
||||
var allocator = &fixed_buf_alloc.allocator;
|
||||
_ = std.zig.parse(allocator, source) catch @panic("parse failure");
|
||||
return fixed_buf_alloc.end_index;
|
||||
}
|
||||
|
||||
@ -1,6 +1,25 @@
|
||||
const tests = @import("tests.zig");
|
||||
|
||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
cases.add(
|
||||
"bad @alignCast at comptime",
|
||||
\\comptime {
|
||||
\\ const ptr = @intToPtr(*i32, 0x1);
|
||||
\\ const aligned = @alignCast(4, ptr);
|
||||
\\}
|
||||
,
|
||||
".tmp_source.zig:3:35: error: pointer address 0x1 is not aligned to 4 bytes",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"@ptrToInt on *void",
|
||||
\\export fn entry() bool {
|
||||
\\ return @ptrToInt(&{}) == @ptrToInt(&{});
|
||||
\\}
|
||||
,
|
||||
".tmp_source.zig:2:23: error: pointer to size 0 type has no address",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"@popCount - non-integer",
|
||||
\\export fn entry(x: f32) u32 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user