*WIP* error sets converting std lib
This commit is contained in:
parent
5161d70620
commit
5f518dbeb9
5
TODO
Normal file
5
TODO
Normal file
@ -0,0 +1,5 @@
|
||||
sed -i 's/\(\bfn .*) \)%\(.*{\)$/\1!\2/g' $(find .. -name "*.zig")
|
||||
|
||||
comptime assert(error{} ! i32 == i32);
|
||||
|
||||
|
@ -10,7 +10,7 @@ const ArrayList = std.ArrayList;
|
||||
const Buffer = std.Buffer;
|
||||
const io = std.io;
|
||||
|
||||
pub fn build(b: &Builder) %void {
|
||||
pub fn build(b: &Builder) !void {
|
||||
const mode = b.standardReleaseOptions();
|
||||
|
||||
var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
|
||||
@ -149,7 +149,7 @@ const LibraryDep = struct {
|
||||
includes: ArrayList([]const u8),
|
||||
};
|
||||
|
||||
fn findLLVM(b: &Builder, llvm_config_exe: []const u8) %LibraryDep {
|
||||
fn findLLVM(b: &Builder, llvm_config_exe: []const u8) !LibraryDep {
|
||||
const libs_output = try b.exec([][]const u8{llvm_config_exe, "--libs", "--system-libs"});
|
||||
const includes_output = try b.exec([][]const u8{llvm_config_exe, "--includedir"});
|
||||
const libdir_output = try b.exec([][]const u8{llvm_config_exe, "--libdir"});
|
||||
|
@ -12,7 +12,7 @@ const exe_ext = std.build.Target(std.build.Target.Native).exeFileExt();
|
||||
const obj_ext = std.build.Target(std.build.Target.Native).oFileExt();
|
||||
const tmp_dir_name = "docgen_tmp";
|
||||
|
||||
pub fn main() %void {
|
||||
pub fn main() !void {
|
||||
// TODO use a more general purpose allocator here
|
||||
var inc_allocator = try std.heap.IncrementingAllocator.init(max_doc_file_size);
|
||||
defer inc_allocator.deinit();
|
||||
@ -243,13 +243,13 @@ fn parseError(tokenizer: &Tokenizer, token: &const Token, comptime fmt: []const
|
||||
return error.ParseError;
|
||||
}
|
||||
|
||||
fn assertToken(tokenizer: &Tokenizer, token: &const Token, id: Token.Id) %void {
|
||||
fn assertToken(tokenizer: &Tokenizer, token: &const Token, id: Token.Id) !void {
|
||||
if (token.id != id) {
|
||||
return parseError(tokenizer, token, "expected {}, found {}", @tagName(id), @tagName(token.id));
|
||||
}
|
||||
}
|
||||
|
||||
fn eatToken(tokenizer: &Tokenizer, id: Token.Id) %Token {
|
||||
fn eatToken(tokenizer: &Tokenizer, id: Token.Id) !Token {
|
||||
const token = tokenizer.next();
|
||||
try assertToken(tokenizer, token, id);
|
||||
return token;
|
||||
@ -316,7 +316,7 @@ const Action = enum {
|
||||
Close,
|
||||
};
|
||||
|
||||
fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) %Toc {
|
||||
fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {
|
||||
var urls = std.HashMap([]const u8, Token, mem.hash_slice_u8, mem.eql_slice_u8).init(allocator);
|
||||
errdefer urls.deinit();
|
||||
|
||||
@ -540,7 +540,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) %Toc {
|
||||
};
|
||||
}
|
||||
|
||||
fn urlize(allocator: &mem.Allocator, input: []const u8) %[]u8 {
|
||||
fn urlize(allocator: &mem.Allocator, input: []const u8) ![]u8 {
|
||||
var buf = try std.Buffer.initSize(allocator, 0);
|
||||
defer buf.deinit();
|
||||
|
||||
@ -560,7 +560,7 @@ fn urlize(allocator: &mem.Allocator, input: []const u8) %[]u8 {
|
||||
return buf.toOwnedSlice();
|
||||
}
|
||||
|
||||
fn escapeHtml(allocator: &mem.Allocator, input: []const u8) %[]u8 {
|
||||
fn escapeHtml(allocator: &mem.Allocator, input: []const u8) ![]u8 {
|
||||
var buf = try std.Buffer.initSize(allocator, 0);
|
||||
defer buf.deinit();
|
||||
|
||||
@ -604,7 +604,7 @@ test "term color" {
|
||||
assert(mem.eql(u8, result, "A<span class=\"t32\">green</span>B"));
|
||||
}
|
||||
|
||||
fn termColor(allocator: &mem.Allocator, input: []const u8) %[]u8 {
|
||||
fn termColor(allocator: &mem.Allocator, input: []const u8) ![]u8 {
|
||||
var buf = try std.Buffer.initSize(allocator, 0);
|
||||
defer buf.deinit();
|
||||
|
||||
@ -686,7 +686,7 @@ fn termColor(allocator: &mem.Allocator, input: []const u8) %[]u8 {
|
||||
|
||||
error ExampleFailedToCompile;
|
||||
|
||||
fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io.OutStream, zig_exe: []const u8) %void {
|
||||
fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io.OutStream, zig_exe: []const u8) !void {
|
||||
var code_progress_index: usize = 0;
|
||||
for (toc.nodes) |node| {
|
||||
switch (node) {
|
||||
@ -977,7 +977,7 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io
|
||||
error ChildCrashed;
|
||||
error ChildExitError;
|
||||
|
||||
fn exec(allocator: &mem.Allocator, args: []const []const u8) %os.ChildProcess.ExecResult {
|
||||
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);
|
||||
switch (result.term) {
|
||||
os.ChildProcess.Term.Exited => |exit_code| {
|
||||
|
@ -5598,7 +5598,9 @@ Block = option(Symbol ":") "{" many(Statement) "}"
|
||||
|
||||
Statement = LocalVarDecl ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";"
|
||||
|
||||
TypeExpr = PrefixOpExpression | "var"
|
||||
TypeExpr = ErrorSetExpr | "var"
|
||||
|
||||
ErrorSetExpr = (PrefixOpExpression "!" PrefixOpExpression) | PrefixOpExpression
|
||||
|
||||
BlockOrExpression = Block | Expression
|
||||
|
||||
@ -5680,7 +5682,7 @@ MultiplyExpression = CurlySuffixExpression MultiplyOperator MultiplyExpression |
|
||||
|
||||
CurlySuffixExpression = TypeExpr option(ContainerInitExpression)
|
||||
|
||||
MultiplyOperator = "!" | "*" | "/" | "%" | "**" | "*%"
|
||||
MultiplyOperator = "*" | "/" | "%" | "**" | "*%"
|
||||
|
||||
PrefixOpExpression = PrefixOp PrefixOpExpression | SuffixOpExpression
|
||||
|
||||
|
@ -5,7 +5,7 @@ const os = std.os;
|
||||
const warn = std.debug.warn;
|
||||
const allocator = std.debug.global_allocator;
|
||||
|
||||
pub fn main() %void {
|
||||
pub fn main() !void {
|
||||
var args_it = os.args();
|
||||
const exe = try unwrapArg(??args_it.next(allocator));
|
||||
var catted_anything = false;
|
||||
@ -36,12 +36,12 @@ pub fn main() %void {
|
||||
}
|
||||
}
|
||||
|
||||
fn usage(exe: []const u8) %void {
|
||||
fn usage(exe: []const u8) !void {
|
||||
warn("Usage: {} [FILE]...\n", exe);
|
||||
return error.Invalid;
|
||||
}
|
||||
|
||||
fn cat_file(stdout: &io.File, file: &io.File) %void {
|
||||
fn cat_file(stdout: &io.File, file: &io.File) !void {
|
||||
var buf: [1024 * 4]u8 = undefined;
|
||||
|
||||
while (true) {
|
||||
@ -61,7 +61,7 @@ fn cat_file(stdout: &io.File, file: &io.File) %void {
|
||||
}
|
||||
}
|
||||
|
||||
fn unwrapArg(arg: %[]u8) %[]u8 {
|
||||
fn unwrapArg(arg: %[]u8) ![]u8 {
|
||||
return arg catch |err| {
|
||||
warn("Unable to parse command line: {}\n", err);
|
||||
return err;
|
||||
|
@ -5,7 +5,7 @@ const fmt = std.fmt;
|
||||
const Rand = std.rand.Rand;
|
||||
const os = std.os;
|
||||
|
||||
pub fn main() %void {
|
||||
pub fn main() !void {
|
||||
var stdout_file = try io.getStdOut();
|
||||
var stdout_file_stream = io.FileOutStream.init(&stdout_file);
|
||||
const stdout = &stdout_file_stream.stream;
|
||||
|
@ -1,6 +1,6 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() %void {
|
||||
pub fn main() !void {
|
||||
// If this program is run without stdout attached, exit with an error.
|
||||
var stdout_file = try std.io.getStdOut();
|
||||
// If this program encounters pipe failure when printing to stdout, exit
|
||||
|
@ -1,6 +1,6 @@
|
||||
const Builder = @import("std").build.Builder;
|
||||
|
||||
pub fn build(b: &Builder) %void {
|
||||
pub fn build(b: &Builder) !void {
|
||||
const obj = b.addObject("base64", "base64.zig");
|
||||
|
||||
const exe = b.addCExecutable("test");
|
||||
|
@ -1,6 +1,6 @@
|
||||
const Builder = @import("std").build.Builder;
|
||||
|
||||
pub fn build(b: &Builder) %void {
|
||||
pub fn build(b: &Builder) !void {
|
||||
const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));
|
||||
|
||||
const exe = b.addCExecutable("test");
|
||||
|
@ -20,7 +20,7 @@ error ZigInstallationNotFound;
|
||||
|
||||
const default_zig_cache_name = "zig-cache";
|
||||
|
||||
pub fn main() %void {
|
||||
pub fn main() !void {
|
||||
main2() catch |err| {
|
||||
if (err != error.InvalidCommandLineArguments) {
|
||||
warn("{}\n", @errorName(err));
|
||||
@ -48,7 +48,7 @@ fn badArgs(comptime format: []const u8, args: ...) error {
|
||||
return error.InvalidCommandLineArguments;
|
||||
}
|
||||
|
||||
pub fn main2() %void {
|
||||
pub fn main2() !void {
|
||||
const allocator = std.heap.c_allocator;
|
||||
|
||||
const args = try os.argsAlloc(allocator);
|
||||
@ -472,7 +472,7 @@ pub fn main2() %void {
|
||||
}
|
||||
}
|
||||
|
||||
fn printUsage(stream: &io.OutStream) %void {
|
||||
fn printUsage(stream: &io.OutStream) !void {
|
||||
try stream.write(
|
||||
\\Usage: zig [command] [options]
|
||||
\\
|
||||
@ -548,7 +548,7 @@ fn printUsage(stream: &io.OutStream) %void {
|
||||
);
|
||||
}
|
||||
|
||||
fn printZen() %void {
|
||||
fn printZen() !void {
|
||||
var stdout_file = try io.getStdErr();
|
||||
try stdout_file.write(
|
||||
\\
|
||||
@ -569,7 +569,7 @@ fn printZen() %void {
|
||||
}
|
||||
|
||||
/// Caller must free result
|
||||
fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) %[]u8 {
|
||||
fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) ![]u8 {
|
||||
if (zig_install_prefix_arg) |zig_install_prefix| {
|
||||
return testZigInstallPrefix(allocator, zig_install_prefix) catch |err| {
|
||||
warn("No Zig installation found at prefix {}: {}\n", zig_install_prefix_arg, @errorName(err));
|
||||
@ -585,7 +585,7 @@ fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const
|
||||
}
|
||||
|
||||
/// Caller must free result
|
||||
fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) %[]u8 {
|
||||
fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) ![]u8 {
|
||||
const test_zig_dir = try os.path.join(allocator, test_path, "lib", "zig");
|
||||
errdefer allocator.free(test_zig_dir);
|
||||
|
||||
@ -599,7 +599,7 @@ fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) %[]u8
|
||||
}
|
||||
|
||||
/// Caller must free result
|
||||
fn findZigLibDir(allocator: &mem.Allocator) %[]u8 {
|
||||
fn findZigLibDir(allocator: &mem.Allocator) ![]u8 {
|
||||
const self_exe_path = try os.selfExeDirPath(allocator);
|
||||
defer allocator.free(self_exe_path);
|
||||
|
||||
|
@ -198,7 +198,7 @@ pub const Module = struct {
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
pub fn build(self: &Module) %void {
|
||||
pub fn build(self: &Module) !void {
|
||||
if (self.llvm_argv.len != 0) {
|
||||
var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator,
|
||||
[][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, });
|
||||
@ -263,11 +263,11 @@ pub const Module = struct {
|
||||
|
||||
}
|
||||
|
||||
pub fn link(self: &Module, out_file: ?[]const u8) %void {
|
||||
pub fn link(self: &Module, out_file: ?[]const u8) !void {
|
||||
warn("TODO link");
|
||||
}
|
||||
|
||||
pub fn addLinkLib(self: &Module, name: []const u8, provided_explicitly: bool) %&LinkLib {
|
||||
pub fn addLinkLib(self: &Module, name: []const u8, provided_explicitly: bool) !&LinkLib {
|
||||
const is_libc = mem.eql(u8, name, "c");
|
||||
|
||||
if (is_libc) {
|
||||
@ -297,7 +297,7 @@ pub const Module = struct {
|
||||
}
|
||||
};
|
||||
|
||||
fn printError(comptime format: []const u8, args: ...) %void {
|
||||
fn printError(comptime format: []const u8, args: ...) !void {
|
||||
var stderr_file = try std.io.getStdErr();
|
||||
var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file);
|
||||
const out_stream = &stderr_file_out_stream.stream;
|
||||
|
@ -63,7 +63,7 @@ pub const Parser = struct {
|
||||
NullableField: &?&ast.Node,
|
||||
List: &ArrayList(&ast.Node),
|
||||
|
||||
pub fn store(self: &const DestPtr, value: &ast.Node) %void {
|
||||
pub fn store(self: &const DestPtr, value: &ast.Node) !void {
|
||||
switch (*self) {
|
||||
DestPtr.Field => |ptr| *ptr = value,
|
||||
DestPtr.NullableField => |ptr| *ptr = value,
|
||||
@ -99,7 +99,7 @@ pub const Parser = struct {
|
||||
|
||||
/// Returns an AST tree, allocated with the parser's allocator.
|
||||
/// Result should be freed with `freeAst` when done.
|
||||
pub fn parse(self: &Parser) %Tree {
|
||||
pub fn parse(self: &Parser) !Tree {
|
||||
var stack = self.initUtilityArrayList(State);
|
||||
defer self.deinitUtilityArrayList(stack);
|
||||
|
||||
@ -544,7 +544,7 @@ pub const Parser = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn createRoot(self: &Parser) %&ast.NodeRoot {
|
||||
fn createRoot(self: &Parser) !&ast.NodeRoot {
|
||||
const node = try self.allocator.create(ast.NodeRoot);
|
||||
|
||||
*node = ast.NodeRoot {
|
||||
@ -599,7 +599,7 @@ pub const Parser = struct {
|
||||
return node;
|
||||
}
|
||||
|
||||
fn createParamDecl(self: &Parser) %&ast.NodeParamDecl {
|
||||
fn createParamDecl(self: &Parser) !&ast.NodeParamDecl {
|
||||
const node = try self.allocator.create(ast.NodeParamDecl);
|
||||
|
||||
*node = ast.NodeParamDecl {
|
||||
@ -613,7 +613,7 @@ pub const Parser = struct {
|
||||
return node;
|
||||
}
|
||||
|
||||
fn createBlock(self: &Parser, begin_token: &const Token) %&ast.NodeBlock {
|
||||
fn createBlock(self: &Parser, begin_token: &const Token) !&ast.NodeBlock {
|
||||
const node = try self.allocator.create(ast.NodeBlock);
|
||||
|
||||
*node = ast.NodeBlock {
|
||||
@ -625,7 +625,7 @@ pub const Parser = struct {
|
||||
return node;
|
||||
}
|
||||
|
||||
fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) %&ast.NodeInfixOp {
|
||||
fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) !&ast.NodeInfixOp {
|
||||
const node = try self.allocator.create(ast.NodeInfixOp);
|
||||
|
||||
*node = ast.NodeInfixOp {
|
||||
@ -638,7 +638,7 @@ pub const Parser = struct {
|
||||
return node;
|
||||
}
|
||||
|
||||
fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) %&ast.NodePrefixOp {
|
||||
fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) !&ast.NodePrefixOp {
|
||||
const node = try self.allocator.create(ast.NodePrefixOp);
|
||||
|
||||
*node = ast.NodePrefixOp {
|
||||
@ -650,7 +650,7 @@ pub const Parser = struct {
|
||||
return node;
|
||||
}
|
||||
|
||||
fn createIdentifier(self: &Parser, name_token: &const Token) %&ast.NodeIdentifier {
|
||||
fn createIdentifier(self: &Parser, name_token: &const Token) !&ast.NodeIdentifier {
|
||||
const node = try self.allocator.create(ast.NodeIdentifier);
|
||||
|
||||
*node = ast.NodeIdentifier {
|
||||
@ -660,7 +660,7 @@ pub const Parser = struct {
|
||||
return node;
|
||||
}
|
||||
|
||||
fn createIntegerLiteral(self: &Parser, token: &const Token) %&ast.NodeIntegerLiteral {
|
||||
fn createIntegerLiteral(self: &Parser, token: &const Token) !&ast.NodeIntegerLiteral {
|
||||
const node = try self.allocator.create(ast.NodeIntegerLiteral);
|
||||
|
||||
*node = ast.NodeIntegerLiteral {
|
||||
@ -670,7 +670,7 @@ pub const Parser = struct {
|
||||
return node;
|
||||
}
|
||||
|
||||
fn createFloatLiteral(self: &Parser, token: &const Token) %&ast.NodeFloatLiteral {
|
||||
fn createFloatLiteral(self: &Parser, token: &const Token) !&ast.NodeFloatLiteral {
|
||||
const node = try self.allocator.create(ast.NodeFloatLiteral);
|
||||
|
||||
*node = ast.NodeFloatLiteral {
|
||||
@ -680,13 +680,13 @@ pub const Parser = struct {
|
||||
return node;
|
||||
}
|
||||
|
||||
fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) %&ast.NodeIdentifier {
|
||||
fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) !&ast.NodeIdentifier {
|
||||
const node = try self.createIdentifier(name_token);
|
||||
try dest_ptr.store(&node.base);
|
||||
return node;
|
||||
}
|
||||
|
||||
fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) %&ast.NodeParamDecl {
|
||||
fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) !&ast.NodeParamDecl {
|
||||
const node = try self.createParamDecl();
|
||||
try list.append(&node.base);
|
||||
return node;
|
||||
@ -730,13 +730,13 @@ pub const Parser = struct {
|
||||
return error.ParseError;
|
||||
}
|
||||
|
||||
fn expectToken(self: &Parser, token: &const Token, id: @TagType(Token.Id)) %void {
|
||||
fn expectToken(self: &Parser, token: &const Token, id: @TagType(Token.Id)) !void {
|
||||
if (token.id != id) {
|
||||
return self.parseError(token, "expected {}, found {}", @tagName(id), @tagName(token.id));
|
||||
}
|
||||
}
|
||||
|
||||
fn eatToken(self: &Parser, id: @TagType(Token.Id)) %Token {
|
||||
fn eatToken(self: &Parser, id: @TagType(Token.Id)) !Token {
|
||||
const token = self.getNextToken();
|
||||
try self.expectToken(token, id);
|
||||
return token;
|
||||
@ -763,7 +763,7 @@ pub const Parser = struct {
|
||||
indent: usize,
|
||||
};
|
||||
|
||||
pub fn renderAst(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) %void {
|
||||
pub fn renderAst(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) !void {
|
||||
var stack = self.initUtilityArrayList(RenderAstFrame);
|
||||
defer self.deinitUtilityArrayList(stack);
|
||||
|
||||
@ -802,7 +802,7 @@ pub const Parser = struct {
|
||||
Indent: usize,
|
||||
};
|
||||
|
||||
pub fn renderSource(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) %void {
|
||||
pub fn renderSource(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) !void {
|
||||
var stack = self.initUtilityArrayList(RenderState);
|
||||
defer self.deinitUtilityArrayList(stack);
|
||||
|
||||
@ -1038,7 +1038,7 @@ pub const Parser = struct {
|
||||
|
||||
var fixed_buffer_mem: [100 * 1024]u8 = undefined;
|
||||
|
||||
fn testParse(source: []const u8, allocator: &mem.Allocator) %[]u8 {
|
||||
fn testParse(source: []const u8, allocator: &mem.Allocator) ![]u8 {
|
||||
var padded_source: [0x100]u8 = undefined;
|
||||
std.mem.copy(u8, padded_source[0..source.len], source);
|
||||
padded_source[source.len + 0] = '\n';
|
||||
@ -1064,7 +1064,7 @@ error MemoryLeakDetected;
|
||||
|
||||
// TODO test for memory leaks
|
||||
// TODO test for valid frees
|
||||
fn testCanonical(source: []const u8) %void {
|
||||
fn testCanonical(source: []const u8) !void {
|
||||
const needed_alloc_count = x: {
|
||||
// Try it once with unlimited memory, make sure it works
|
||||
var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
|
||||
|
@ -516,6 +516,7 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
|
||||
|
||||
TypeTableEntry *get_error_union_type(CodeGen *g, TypeTableEntry *err_set_type, TypeTableEntry *payload_type) {
|
||||
assert(err_set_type->id == TypeTableEntryIdErrorSet);
|
||||
assert(!type_is_invalid(payload_type));
|
||||
|
||||
TypeId type_id = {};
|
||||
type_id.id = TypeTableEntryIdErrorUnion;
|
||||
@ -1409,6 +1410,11 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
|
||||
}
|
||||
|
||||
TypeTableEntry *specified_return_type = analyze_type_expr(g, child_scope, fn_proto->return_type);
|
||||
if (type_is_invalid(specified_return_type)) {
|
||||
fn_type_id.return_type = g->builtin_types.entry_invalid;
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
if (fn_proto->auto_err_set) {
|
||||
TypeTableEntry *inferred_err_set_type = get_auto_err_set_type(g, fn_entry);
|
||||
fn_type_id.return_type = get_error_union_type(g, inferred_err_set_type, specified_return_type);
|
||||
@ -1416,10 +1422,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
|
||||
fn_type_id.return_type = specified_return_type;
|
||||
}
|
||||
|
||||
if (type_is_invalid(fn_type_id.return_type)) {
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, fn_type_id.return_type)) {
|
||||
add_node_error(g, fn_proto->return_type,
|
||||
buf_sprintf("return type '%s' not allowed in function with calling convention '%s'",
|
||||
|
@ -241,7 +241,28 @@ static Token *ast_eat_token(ParseContext *pc, size_t *token_index, TokenId token
|
||||
}
|
||||
|
||||
/*
|
||||
TypeExpr = PrefixOpExpression | "var"
|
||||
ErrorSetExpr = (PrefixOpExpression "!" PrefixOpExpression) | PrefixOpExpression
|
||||
*/
|
||||
static AstNode *ast_parse_error_set_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
|
||||
AstNode *prefix_op_expr = ast_parse_prefix_op_expr(pc, token_index, mandatory);
|
||||
if (!prefix_op_expr) {
|
||||
return nullptr;
|
||||
}
|
||||
Token *token = &pc->tokens->at(*token_index);
|
||||
if (token->id == TokenIdBang) {
|
||||
*token_index += 1;
|
||||
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
|
||||
node->data.bin_op_expr.op1 = prefix_op_expr;
|
||||
node->data.bin_op_expr.bin_op = BinOpTypeErrorUnion;
|
||||
node->data.bin_op_expr.op2 = ast_parse_prefix_op_expr(pc, token_index, true);
|
||||
return node;
|
||||
} else {
|
||||
return prefix_op_expr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TypeExpr = ErrorSetExpr | "var"
|
||||
*/
|
||||
static AstNode *ast_parse_type_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
|
||||
Token *token = &pc->tokens->at(*token_index);
|
||||
@ -250,7 +271,7 @@ static AstNode *ast_parse_type_expr(ParseContext *pc, size_t *token_index, bool
|
||||
*token_index += 1;
|
||||
return node;
|
||||
} else {
|
||||
return ast_parse_prefix_op_expr(pc, token_index, mandatory);
|
||||
return ast_parse_error_set_expr(pc, token_index, mandatory);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2346,10 +2367,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
|
||||
node->data.fn_proto.return_type = ast_create_node(pc, NodeTypeErrorType, next_token);
|
||||
return node;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
if (next_token->id == TokenIdBang) {
|
||||
} else if (next_token->id == TokenIdBang) {
|
||||
*token_index += 1;
|
||||
node->data.fn_proto.auto_err_set = true;
|
||||
next_token = &pc->tokens->at(*token_index);
|
||||
|
@ -59,18 +59,18 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn append(l: &Self, item: &const T) %void {
|
||||
pub fn append(l: &Self, item: &const T) !void {
|
||||
const new_item_ptr = try l.addOne();
|
||||
*new_item_ptr = *item;
|
||||
}
|
||||
|
||||
pub fn appendSlice(l: &Self, items: []align(A) const T) %void {
|
||||
pub fn appendSlice(l: &Self, items: []align(A) const T) !void {
|
||||
try l.ensureCapacity(l.len + items.len);
|
||||
mem.copy(T, l.items[l.len..], items);
|
||||
l.len += items.len;
|
||||
}
|
||||
|
||||
pub fn resize(l: &Self, new_len: usize) %void {
|
||||
pub fn resize(l: &Self, new_len: usize) !void {
|
||||
try l.ensureCapacity(new_len);
|
||||
l.len = new_len;
|
||||
}
|
||||
@ -80,7 +80,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
|
||||
l.len = new_len;
|
||||
}
|
||||
|
||||
pub fn ensureCapacity(l: &Self, new_capacity: usize) %void {
|
||||
pub fn ensureCapacity(l: &Self, new_capacity: usize) !void {
|
||||
var better_capacity = l.items.len;
|
||||
if (better_capacity >= new_capacity) return;
|
||||
while (true) {
|
||||
@ -90,7 +90,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
|
||||
l.items = try l.allocator.alignedRealloc(T, A, l.items, better_capacity);
|
||||
}
|
||||
|
||||
pub fn addOne(l: &Self) %&T {
|
||||
pub fn addOne(l: &Self) !&T {
|
||||
const new_length = l.len + 1;
|
||||
try l.ensureCapacity(new_length);
|
||||
const result = &l.items[l.len];
|
||||
|
@ -79,8 +79,6 @@ pub const Base64Encoder = struct {
|
||||
};
|
||||
|
||||
pub const standard_decoder = Base64Decoder.init(standard_alphabet_chars, standard_pad_char);
|
||||
error InvalidPadding;
|
||||
error InvalidCharacter;
|
||||
|
||||
pub const Base64Decoder = struct {
|
||||
/// e.g. 'A' => 0.
|
||||
@ -111,7 +109,7 @@ pub const Base64Decoder = struct {
|
||||
}
|
||||
|
||||
/// If the encoded buffer is detected to be invalid, returns error.InvalidPadding.
|
||||
pub fn calcSize(decoder: &const Base64Decoder, source: []const u8) %usize {
|
||||
pub fn calcSize(decoder: &const Base64Decoder, source: []const u8) !usize {
|
||||
if (source.len % 4 != 0) return error.InvalidPadding;
|
||||
return calcDecodedSizeExactUnsafe(source, decoder.pad_char);
|
||||
}
|
||||
@ -119,7 +117,7 @@ pub const Base64Decoder = struct {
|
||||
/// dest.len must be what you get from ::calcSize.
|
||||
/// invalid characters result in error.InvalidCharacter.
|
||||
/// invalid padding results in error.InvalidPadding.
|
||||
pub fn decode(decoder: &const Base64Decoder, dest: []u8, source: []const u8) %void {
|
||||
pub fn decode(decoder: &const Base64Decoder, dest: []u8, source: []const u8) !void {
|
||||
assert(dest.len == (decoder.calcSize(source) catch unreachable));
|
||||
assert(source.len % 4 == 0);
|
||||
|
||||
@ -163,8 +161,6 @@ pub const Base64Decoder = struct {
|
||||
}
|
||||
};
|
||||
|
||||
error OutputTooSmall;
|
||||
|
||||
pub const Base64DecoderWithIgnore = struct {
|
||||
decoder: Base64Decoder,
|
||||
char_is_ignored: [256]bool,
|
||||
@ -185,7 +181,7 @@ pub const Base64DecoderWithIgnore = struct {
|
||||
}
|
||||
|
||||
/// If no characters end up being ignored or padding, this will be the exact decoded size.
|
||||
pub fn calcSizeUpperBound(encoded_len: usize) %usize {
|
||||
pub fn calcSizeUpperBound(encoded_len: usize) !usize {
|
||||
return @divTrunc(encoded_len, 4) * 3;
|
||||
}
|
||||
|
||||
@ -193,7 +189,7 @@ pub const Base64DecoderWithIgnore = struct {
|
||||
/// Invalid padding results in error.InvalidPadding.
|
||||
/// Decoding more data than can fit in dest results in error.OutputTooSmall. See also ::calcSizeUpperBound.
|
||||
/// Returns the number of bytes writen to dest.
|
||||
pub fn decode(decoder_with_ignore: &const Base64DecoderWithIgnore, dest: []u8, source: []const u8) %usize {
|
||||
pub fn decode(decoder_with_ignore: &const Base64DecoderWithIgnore, dest: []u8, source: []const u8) !usize {
|
||||
const decoder = &decoder_with_ignore.decoder;
|
||||
|
||||
var src_cursor: usize = 0;
|
||||
@ -378,7 +374,7 @@ test "base64" {
|
||||
comptime (testBase64() catch unreachable);
|
||||
}
|
||||
|
||||
fn testBase64() %void {
|
||||
fn testBase64() !void {
|
||||
try testAllApis("", "");
|
||||
try testAllApis("f", "Zg==");
|
||||
try testAllApis("fo", "Zm8=");
|
||||
@ -412,7 +408,7 @@ fn testBase64() %void {
|
||||
try testOutputTooSmallError("AAAAAA==");
|
||||
}
|
||||
|
||||
fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) %void {
|
||||
fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) !void {
|
||||
// Base64Encoder
|
||||
{
|
||||
var buffer: [0x100]u8 = undefined;
|
||||
@ -449,7 +445,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) %void
|
||||
}
|
||||
}
|
||||
|
||||
fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) %void {
|
||||
fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) !void {
|
||||
const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
|
||||
standard_alphabet_chars, standard_pad_char, " ");
|
||||
var buffer: [0x100]u8 = undefined;
|
||||
@ -458,8 +454,7 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) %voi
|
||||
assert(mem.eql(u8, decoded[0..written], expected_decoded));
|
||||
}
|
||||
|
||||
error ExpectedError;
|
||||
fn testError(encoded: []const u8, expected_err: error) %void {
|
||||
fn testError(encoded: []const u8, expected_err: error) !void {
|
||||
const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
|
||||
standard_alphabet_chars, standard_pad_char, " ");
|
||||
var buffer: [0x100]u8 = undefined;
|
||||
@ -475,7 +470,7 @@ fn testError(encoded: []const u8, expected_err: error) %void {
|
||||
} else |err| if (err != expected_err) return err;
|
||||
}
|
||||
|
||||
fn testOutputTooSmallError(encoded: []const u8) %void {
|
||||
fn testOutputTooSmallError(encoded: []const u8) !void {
|
||||
const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
|
||||
standard_alphabet_chars, standard_pad_char, " ");
|
||||
var buffer: [0x100]u8 = undefined;
|
||||
|
@ -27,7 +27,7 @@ pub const BufMap = struct {
|
||||
self.hash_map.deinit();
|
||||
}
|
||||
|
||||
pub fn set(self: &BufMap, key: []const u8, value: []const u8) %void {
|
||||
pub fn set(self: &BufMap, key: []const u8, value: []const u8) !void {
|
||||
if (self.hash_map.get(key)) |entry| {
|
||||
const value_copy = try self.copy(value);
|
||||
errdefer self.free(value_copy);
|
||||
@ -67,7 +67,7 @@ pub const BufMap = struct {
|
||||
self.hash_map.allocator.free(mut_value);
|
||||
}
|
||||
|
||||
fn copy(self: &BufMap, value: []const u8) %[]const u8 {
|
||||
fn copy(self: &BufMap, value: []const u8) ![]const u8 {
|
||||
const result = try self.hash_map.allocator.alloc(u8, value.len);
|
||||
mem.copy(u8, result, value);
|
||||
return result;
|
||||
|
@ -24,7 +24,7 @@ pub const BufSet = struct {
|
||||
self.hash_map.deinit();
|
||||
}
|
||||
|
||||
pub fn put(self: &BufSet, key: []const u8) %void {
|
||||
pub fn put(self: &BufSet, key: []const u8) !void {
|
||||
if (self.hash_map.get(key) == null) {
|
||||
const key_copy = try self.copy(key);
|
||||
errdefer self.free(key_copy);
|
||||
@ -55,7 +55,7 @@ pub const BufSet = struct {
|
||||
self.hash_map.allocator.free(mut_value);
|
||||
}
|
||||
|
||||
fn copy(self: &BufSet, value: []const u8) %[]const u8 {
|
||||
fn copy(self: &BufSet, value: []const u8) ![]const u8 {
|
||||
const result = try self.hash_map.allocator.alloc(u8, value.len);
|
||||
mem.copy(u8, result, value);
|
||||
return result;
|
||||
|
@ -12,14 +12,14 @@ pub const Buffer = struct {
|
||||
list: ArrayList(u8),
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn init(allocator: &Allocator, m: []const u8) %Buffer {
|
||||
pub fn init(allocator: &Allocator, m: []const u8) !Buffer {
|
||||
var self = try initSize(allocator, m.len);
|
||||
mem.copy(u8, self.list.items, m);
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn initSize(allocator: &Allocator, size: usize) %Buffer {
|
||||
pub fn initSize(allocator: &Allocator, size: usize) !Buffer {
|
||||
var self = initNull(allocator);
|
||||
try self.resize(size);
|
||||
return self;
|
||||
@ -37,7 +37,7 @@ pub const Buffer = struct {
|
||||
}
|
||||
|
||||
/// Must deinitialize with deinit.
|
||||
pub fn initFromBuffer(buffer: &const Buffer) %Buffer {
|
||||
pub fn initFromBuffer(buffer: &const Buffer) !Buffer {
|
||||
return Buffer.init(buffer.list.allocator, buffer.toSliceConst());
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ pub const Buffer = struct {
|
||||
self.list.items[self.len()] = 0;
|
||||
}
|
||||
|
||||
pub fn resize(self: &Buffer, new_len: usize) %void {
|
||||
pub fn resize(self: &Buffer, new_len: usize) !void {
|
||||
try self.list.resize(new_len + 1);
|
||||
self.list.items[self.len()] = 0;
|
||||
}
|
||||
@ -93,24 +93,24 @@ pub const Buffer = struct {
|
||||
return self.list.len - 1;
|
||||
}
|
||||
|
||||
pub fn append(self: &Buffer, m: []const u8) %void {
|
||||
pub fn append(self: &Buffer, m: []const u8) !void {
|
||||
const old_len = self.len();
|
||||
try self.resize(old_len + m.len);
|
||||
mem.copy(u8, self.list.toSlice()[old_len..], m);
|
||||
}
|
||||
|
||||
// TODO: remove, use OutStream for this
|
||||
pub fn appendFormat(self: &Buffer, comptime format: []const u8, args: ...) %void {
|
||||
pub fn appendFormat(self: &Buffer, comptime format: []const u8, args: ...) !void {
|
||||
return fmt.format(self, append, format, args);
|
||||
}
|
||||
|
||||
// TODO: remove, use OutStream for this
|
||||
pub fn appendByte(self: &Buffer, byte: u8) %void {
|
||||
pub fn appendByte(self: &Buffer, byte: u8) !void {
|
||||
return self.appendByteNTimes(byte, 1);
|
||||
}
|
||||
|
||||
// TODO: remove, use OutStream for this
|
||||
pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) %void {
|
||||
pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) !void {
|
||||
var prev_size: usize = self.len();
|
||||
const new_size = prev_size + count;
|
||||
try self.resize(new_size);
|
||||
@ -137,7 +137,7 @@ pub const Buffer = struct {
|
||||
return mem.eql(u8, self.list.items[start..l], m);
|
||||
}
|
||||
|
||||
pub fn replaceContents(self: &const Buffer, m: []const u8) %void {
|
||||
pub fn replaceContents(self: &const Buffer, m: []const u8) !void {
|
||||
try self.resize(m.len);
|
||||
mem.copy(u8, self.list.toSlice(), m);
|
||||
}
|
||||
|
@ -15,13 +15,6 @@ const BufSet = std.BufSet;
|
||||
const BufMap = std.BufMap;
|
||||
const fmt_lib = std.fmt;
|
||||
|
||||
error ExtraArg;
|
||||
error UncleanExit;
|
||||
error InvalidStepName;
|
||||
error DependencyLoopDetected;
|
||||
error NoCompilerFound;
|
||||
error NeedAnObject;
|
||||
|
||||
pub const Builder = struct {
|
||||
uninstall_tls: TopLevelStep,
|
||||
install_tls: TopLevelStep,
|
||||
@ -242,7 +235,7 @@ pub const Builder = struct {
|
||||
self.lib_paths.append(path) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn make(self: &Builder, step_names: []const []const u8) %void {
|
||||
pub fn make(self: &Builder, step_names: []const []const u8) !void {
|
||||
var wanted_steps = ArrayList(&Step).init(self.allocator);
|
||||
defer wanted_steps.deinit();
|
||||
|
||||
@ -278,7 +271,7 @@ pub const Builder = struct {
|
||||
return &self.uninstall_tls.step;
|
||||
}
|
||||
|
||||
fn makeUninstall(uninstall_step: &Step) %void {
|
||||
fn makeUninstall(uninstall_step: &Step) !void {
|
||||
const uninstall_tls = @fieldParentPtr(TopLevelStep, "step", uninstall_step);
|
||||
const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls);
|
||||
|
||||
@ -292,7 +285,7 @@ pub const Builder = struct {
|
||||
// TODO remove empty directories
|
||||
}
|
||||
|
||||
fn makeOneStep(self: &Builder, s: &Step) %void {
|
||||
fn makeOneStep(self: &Builder, s: &Step) !void {
|
||||
if (s.loop_flag) {
|
||||
warn("Dependency loop detected:\n {}\n", s.name);
|
||||
return error.DependencyLoopDetected;
|
||||
@ -313,7 +306,7 @@ pub const Builder = struct {
|
||||
try s.make();
|
||||
}
|
||||
|
||||
fn getTopLevelStepByName(self: &Builder, name: []const u8) %&Step {
|
||||
fn getTopLevelStepByName(self: &Builder, name: []const u8) !&Step {
|
||||
for (self.top_level_steps.toSliceConst()) |top_level_step| {
|
||||
if (mem.eql(u8, top_level_step.step.name, name)) {
|
||||
return &top_level_step.step;
|
||||
@ -548,7 +541,7 @@ pub const Builder = struct {
|
||||
return self.invalid_user_input;
|
||||
}
|
||||
|
||||
fn spawnChild(self: &Builder, argv: []const []const u8) %void {
|
||||
fn spawnChild(self: &Builder, argv: []const []const u8) !void {
|
||||
return self.spawnChildEnvMap(null, &self.env_map, argv);
|
||||
}
|
||||
|
||||
@ -595,7 +588,7 @@ pub const Builder = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn makePath(self: &Builder, path: []const u8) %void {
|
||||
pub fn makePath(self: &Builder, path: []const u8) !void {
|
||||
os.makePath(self.allocator, self.pathFromRoot(path)) catch |err| {
|
||||
warn("Unable to create path {}: {}\n", path, @errorName(err));
|
||||
return err;
|
||||
@ -630,11 +623,11 @@ pub const Builder = struct {
|
||||
self.installed_files.append(full_path) catch unreachable;
|
||||
}
|
||||
|
||||
fn copyFile(self: &Builder, source_path: []const u8, dest_path: []const u8) %void {
|
||||
fn copyFile(self: &Builder, source_path: []const u8, dest_path: []const u8) !void {
|
||||
return self.copyFileMode(source_path, dest_path, 0o666);
|
||||
}
|
||||
|
||||
fn copyFileMode(self: &Builder, source_path: []const u8, dest_path: []const u8, mode: usize) %void {
|
||||
fn copyFileMode(self: &Builder, source_path: []const u8, dest_path: []const u8, mode: usize) !void {
|
||||
if (self.verbose) {
|
||||
warn("cp {} {}\n", source_path, dest_path);
|
||||
}
|
||||
@ -672,7 +665,7 @@ pub const Builder = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) %[]const u8 {
|
||||
pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) ![]const u8 {
|
||||
// TODO report error for ambiguous situations
|
||||
const exe_extension = (Target { .Native = {}}).exeFileExt();
|
||||
for (self.search_prefixes.toSliceConst()) |search_prefix| {
|
||||
@ -721,7 +714,7 @@ pub const Builder = struct {
|
||||
return error.FileNotFound;
|
||||
}
|
||||
|
||||
pub fn exec(self: &Builder, argv: []const []const u8) %[]u8 {
|
||||
pub fn exec(self: &Builder, argv: []const []const u8) ![]u8 {
|
||||
const max_output_size = 100 * 1024;
|
||||
const result = try os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size);
|
||||
switch (result.term) {
|
||||
@ -1180,12 +1173,12 @@ pub const LibExeObjStep = struct {
|
||||
self.disable_libc = disable;
|
||||
}
|
||||
|
||||
fn make(step: &Step) %void {
|
||||
fn make(step: &Step) !void {
|
||||
const self = @fieldParentPtr(LibExeObjStep, "step", step);
|
||||
return if (self.is_zig) self.makeZig() else self.makeC();
|
||||
}
|
||||
|
||||
fn makeZig(self: &LibExeObjStep) %void {
|
||||
fn makeZig(self: &LibExeObjStep) !void {
|
||||
const builder = self.builder;
|
||||
|
||||
assert(self.is_zig);
|
||||
@ -1396,7 +1389,7 @@ pub const LibExeObjStep = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn makeC(self: &LibExeObjStep) %void {
|
||||
fn makeC(self: &LibExeObjStep) !void {
|
||||
const builder = self.builder;
|
||||
|
||||
const cc = builder.getCCExe();
|
||||
@ -1687,7 +1680,7 @@ pub const TestStep = struct {
|
||||
self.exec_cmd_args = args;
|
||||
}
|
||||
|
||||
fn make(step: &Step) %void {
|
||||
fn make(step: &Step) !void {
|
||||
const self = @fieldParentPtr(TestStep, "step", step);
|
||||
const builder = self.builder;
|
||||
|
||||
@ -1796,7 +1789,7 @@ pub const CommandStep = struct {
|
||||
return self;
|
||||
}
|
||||
|
||||
fn make(step: &Step) %void {
|
||||
fn make(step: &Step) !void {
|
||||
const self = @fieldParentPtr(CommandStep, "step", step);
|
||||
|
||||
const cwd = if (self.cwd) |cwd| self.builder.pathFromRoot(cwd) else self.builder.build_root;
|
||||
@ -1836,7 +1829,7 @@ const InstallArtifactStep = struct {
|
||||
return self;
|
||||
}
|
||||
|
||||
fn make(step: &Step) %void {
|
||||
fn make(step: &Step) !void {
|
||||
const self = @fieldParentPtr(Self, "step", step);
|
||||
const builder = self.builder;
|
||||
|
||||
@ -1868,7 +1861,7 @@ pub const InstallFileStep = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn make(step: &Step) %void {
|
||||
fn make(step: &Step) !void {
|
||||
const self = @fieldParentPtr(InstallFileStep, "step", step);
|
||||
try self.builder.copyFile(self.src_path, self.dest_path);
|
||||
}
|
||||
@ -1889,7 +1882,7 @@ pub const WriteFileStep = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn make(step: &Step) %void {
|
||||
fn make(step: &Step) !void {
|
||||
const self = @fieldParentPtr(WriteFileStep, "step", step);
|
||||
const full_path = self.builder.pathFromRoot(self.file_path);
|
||||
const full_path_dir = os.path.dirname(full_path);
|
||||
@ -1917,7 +1910,7 @@ pub const LogStep = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn make(step: &Step) %void {
|
||||
fn make(step: &Step) !void {
|
||||
const self = @fieldParentPtr(LogStep, "step", step);
|
||||
warn("{}", self.data);
|
||||
}
|
||||
@ -1936,7 +1929,7 @@ pub const RemoveDirStep = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn make(step: &Step) %void {
|
||||
fn make(step: &Step) !void {
|
||||
const self = @fieldParentPtr(RemoveDirStep, "step", step);
|
||||
|
||||
const full_path = self.builder.pathFromRoot(self.dir_path);
|
||||
@ -1967,7 +1960,7 @@ pub const Step = struct {
|
||||
return init(name, allocator, makeNoOp);
|
||||
}
|
||||
|
||||
pub fn make(self: &Step) %void {
|
||||
pub fn make(self: &Step) !void {
|
||||
if (self.done_flag)
|
||||
return;
|
||||
|
||||
|
@ -18,7 +18,7 @@ const c = @cImport({
|
||||
|
||||
const Mb = 1024 * 1024;
|
||||
|
||||
pub fn main() %void {
|
||||
pub fn main() !void {
|
||||
var stdout_file = try std.io.getStdOut();
|
||||
var stdout_out_stream = std.io.FileOutStream.init(&stdout_file);
|
||||
const stdout = &stdout_out_stream.stream;
|
||||
|
@ -42,7 +42,7 @@ fn testCStrFnsImpl() void {
|
||||
/// Returns a mutable slice with exactly the same size which is guaranteed to
|
||||
/// have a null byte after it.
|
||||
/// Caller owns the returned memory.
|
||||
pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) %[]u8 {
|
||||
pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) ![]u8 {
|
||||
const result = try allocator.alloc(u8, slice.len + 1);
|
||||
mem.copy(u8, result, slice);
|
||||
result[slice.len] = 0;
|
||||
@ -56,7 +56,7 @@ pub const NullTerminated2DArray = struct {
|
||||
|
||||
/// Takes N lists of strings, concatenates the lists together, and adds a null terminator
|
||||
/// Caller must deinit result
|
||||
pub fn fromSlices(allocator: &mem.Allocator, slices: []const []const []const u8) %NullTerminated2DArray {
|
||||
pub fn fromSlices(allocator: &mem.Allocator, slices: []const []const []const u8) !NullTerminated2DArray {
|
||||
var new_len: usize = 1; // 1 for the list null
|
||||
var byte_count: usize = 0;
|
||||
for (slices) |slice| {
|
||||
|
@ -28,7 +28,7 @@ pub const FailingAllocator = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn alloc(allocator: &mem.Allocator, n: usize, alignment: u29) %[]u8 {
|
||||
fn alloc(allocator: &mem.Allocator, n: usize, alignment: u29) ![]u8 {
|
||||
const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
|
||||
if (self.index == self.fail_index) {
|
||||
return error.OutOfMemory;
|
||||
@ -39,7 +39,7 @@ pub const FailingAllocator = struct {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn realloc(allocator: &mem.Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
|
||||
fn realloc(allocator: &mem.Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
|
||||
const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
|
||||
if (new_size <= old_mem.len) {
|
||||
self.freed_bytes += old_mem.len - new_size;
|
||||
|
10
std/elf.zig
10
std/elf.zig
@ -6,8 +6,6 @@ const mem = std.mem;
|
||||
const debug = std.debug;
|
||||
const InStream = std.stream.InStream;
|
||||
|
||||
error InvalidFormat;
|
||||
|
||||
pub const SHT_NULL = 0;
|
||||
pub const SHT_PROGBITS = 1;
|
||||
pub const SHT_SYMTAB = 2;
|
||||
@ -81,14 +79,14 @@ pub const Elf = struct {
|
||||
prealloc_file: io.File,
|
||||
|
||||
/// Call close when done.
|
||||
pub fn openPath(elf: &Elf, allocator: &mem.Allocator, path: []const u8) %void {
|
||||
pub fn openPath(elf: &Elf, allocator: &mem.Allocator, path: []const u8) !void {
|
||||
try elf.prealloc_file.open(path);
|
||||
try elf.openFile(allocator, &elf.prealloc_file);
|
||||
elf.auto_close_stream = true;
|
||||
}
|
||||
|
||||
/// Call close when done.
|
||||
pub fn openFile(elf: &Elf, allocator: &mem.Allocator, file: &io.File) %void {
|
||||
pub fn openFile(elf: &Elf, allocator: &mem.Allocator, file: &io.File) !void {
|
||||
elf.allocator = allocator;
|
||||
elf.in_file = file;
|
||||
elf.auto_close_stream = false;
|
||||
@ -239,7 +237,7 @@ pub const Elf = struct {
|
||||
elf.in_file.close();
|
||||
}
|
||||
|
||||
pub fn findSection(elf: &Elf, name: []const u8) %?&SectionHeader {
|
||||
pub fn findSection(elf: &Elf, name: []const u8) !?&SectionHeader {
|
||||
var file_stream = io.FileInStream.init(elf.in_file);
|
||||
const in = &file_stream.stream;
|
||||
|
||||
@ -263,7 +261,7 @@ pub const Elf = struct {
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) %void {
|
||||
pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) !void {
|
||||
try elf.in_file.seekTo(elf_section.offset);
|
||||
}
|
||||
};
|
||||
|
@ -24,8 +24,8 @@ const State = enum { // TODO put inside format function and make sure the name a
|
||||
/// Renders fmt string with args, calling output with slices of bytes.
|
||||
/// If `output` returns an error, the error is returned from `format` and
|
||||
/// `output` is not called again.
|
||||
pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
|
||||
comptime fmt: []const u8, args: ...) %void
|
||||
pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8) Errors!void,
|
||||
comptime fmt: []const u8, args: ...) Errors!void
|
||||
{
|
||||
comptime var start_index = 0;
|
||||
comptime var state = State.Start;
|
||||
@ -58,7 +58,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
|
||||
start_index = i;
|
||||
},
|
||||
'}' => {
|
||||
try formatValue(args[next_arg], context, output);
|
||||
try formatValue(args[next_arg], context, Errors, output);
|
||||
next_arg += 1;
|
||||
state = State.Start;
|
||||
start_index = i + 1;
|
||||
@ -110,7 +110,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
|
||||
},
|
||||
State.Integer => switch (c) {
|
||||
'}' => {
|
||||
try formatInt(args[next_arg], radix, uppercase, width, context, output);
|
||||
try formatInt(args[next_arg], radix, uppercase, width, context, Errors, output);
|
||||
next_arg += 1;
|
||||
state = State.Start;
|
||||
start_index = i + 1;
|
||||
@ -124,7 +124,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
|
||||
State.IntegerWidth => switch (c) {
|
||||
'}' => {
|
||||
width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable);
|
||||
try formatInt(args[next_arg], radix, uppercase, width, context, output);
|
||||
try formatInt(args[next_arg], radix, uppercase, width, context, Errors, output);
|
||||
next_arg += 1;
|
||||
state = State.Start;
|
||||
start_index = i + 1;
|
||||
@ -134,7 +134,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
|
||||
},
|
||||
State.Float => switch (c) {
|
||||
'}' => {
|
||||
try formatFloatDecimal(args[next_arg], 0, context, output);
|
||||
try formatFloatDecimal(args[next_arg], 0, context, Errors, output);
|
||||
next_arg += 1;
|
||||
state = State.Start;
|
||||
start_index = i + 1;
|
||||
@ -148,7 +148,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
|
||||
State.FloatWidth => switch (c) {
|
||||
'}' => {
|
||||
width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable);
|
||||
try formatFloatDecimal(args[next_arg], width, context, output);
|
||||
try formatFloatDecimal(args[next_arg], width, context, Errors, output);
|
||||
next_arg += 1;
|
||||
state = State.Start;
|
||||
start_index = i + 1;
|
||||
@ -159,7 +159,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
|
||||
State.BufWidth => switch (c) {
|
||||
'}' => {
|
||||
width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable);
|
||||
try formatBuf(args[next_arg], width, context, output);
|
||||
try formatBuf(args[next_arg], width, context, Errors, output);
|
||||
next_arg += 1;
|
||||
state = State.Start;
|
||||
start_index = i + 1;
|
||||
@ -169,7 +169,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
|
||||
},
|
||||
State.Character => switch (c) {
|
||||
'}' => {
|
||||
try formatAsciiChar(args[next_arg], context, output);
|
||||
try formatAsciiChar(args[next_arg], context, Errors, output);
|
||||
next_arg += 1;
|
||||
state = State.Start;
|
||||
start_index = i + 1;
|
||||
@ -191,7 +191,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
|
||||
pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void {
|
||||
const T = @typeOf(value);
|
||||
switch (@typeId(T)) {
|
||||
builtin.TypeId.Int => {
|
||||
@ -208,16 +208,16 @@ pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []cons
|
||||
},
|
||||
builtin.TypeId.Nullable => {
|
||||
if (value) |payload| {
|
||||
return formatValue(payload, context, output);
|
||||
return formatValue(payload, context, Errors, output);
|
||||
} else {
|
||||
return output(context, "null");
|
||||
}
|
||||
},
|
||||
builtin.TypeId.ErrorUnion => {
|
||||
if (value) |payload| {
|
||||
return formatValue(payload, context, output);
|
||||
return formatValue(payload, context, Errors, output);
|
||||
} else |err| {
|
||||
return formatValue(err, context, output);
|
||||
return formatValue(err, context, Errors, output);
|
||||
}
|
||||
},
|
||||
builtin.TypeId.Error => {
|
||||
@ -240,12 +240,12 @@ pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []cons
|
||||
}
|
||||
}
|
||||
|
||||
pub fn formatAsciiChar(c: u8, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
|
||||
pub fn formatAsciiChar(c: u8, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void {
|
||||
return output(context, (&c)[0..1]);
|
||||
}
|
||||
|
||||
pub fn formatBuf(buf: []const u8, width: usize,
|
||||
context: var, output: fn(@typeOf(context), []const u8)%void) %void
|
||||
context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
|
||||
{
|
||||
try output(context, buf);
|
||||
|
||||
@ -256,7 +256,7 @@ pub fn formatBuf(buf: []const u8, width: usize,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
|
||||
pub fn formatFloat(value: var, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void {
|
||||
var x = f64(value);
|
||||
|
||||
// Errol doesn't handle these special cases.
|
||||
@ -294,7 +294,7 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons
|
||||
}
|
||||
}
|
||||
|
||||
pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
|
||||
pub fn formatFloatDecimal(value: var, precision: usize, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void {
|
||||
var x = f64(value);
|
||||
|
||||
// Errol doesn't handle these special cases.
|
||||
@ -336,7 +336,7 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn
|
||||
|
||||
|
||||
pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
|
||||
context: var, output: fn(@typeOf(context), []const u8)%void) %void
|
||||
context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)errors!void) errors!void
|
||||
{
|
||||
if (@typeOf(value).is_signed) {
|
||||
return formatIntSigned(value, base, uppercase, width, context, output);
|
||||
@ -346,7 +346,7 @@ pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
|
||||
}
|
||||
|
||||
fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
|
||||
context: var, output: fn(@typeOf(context), []const u8)%void) %void
|
||||
context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
|
||||
{
|
||||
const uint = @IntType(false, @typeOf(value).bit_count);
|
||||
if (value < 0) {
|
||||
@ -367,7 +367,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
|
||||
}
|
||||
|
||||
fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
|
||||
context: var, output: fn(@typeOf(context), []const u8)%void) %void
|
||||
context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
|
||||
{
|
||||
// max_int_digits accounts for the minus sign. when printing an unsigned
|
||||
// number we don't need to do that.
|
||||
@ -417,12 +417,12 @@ const FormatIntBuf = struct {
|
||||
out_buf: []u8,
|
||||
index: usize,
|
||||
};
|
||||
fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) %void {
|
||||
fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) !void {
|
||||
mem.copy(u8, context.out_buf[context.index..], bytes);
|
||||
context.index += bytes.len;
|
||||
}
|
||||
|
||||
pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) %T {
|
||||
pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) !T {
|
||||
if (!T.is_signed)
|
||||
return parseUnsigned(T, buf, radix);
|
||||
if (buf.len == 0)
|
||||
@ -446,7 +446,7 @@ test "fmt.parseInt" {
|
||||
assert(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);
|
||||
}
|
||||
|
||||
pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) %T {
|
||||
pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) !T {
|
||||
var x: T = 0;
|
||||
|
||||
for (buf) |c| {
|
||||
@ -458,8 +458,7 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) %T {
|
||||
return x;
|
||||
}
|
||||
|
||||
error InvalidChar;
|
||||
fn charToDigit(c: u8, radix: u8) %u8 {
|
||||
fn charToDigit(c: u8, radix: u8) !u8 {
|
||||
const value = switch (c) {
|
||||
'0' ... '9' => c - '0',
|
||||
'A' ... 'Z' => c - 'A' + 10,
|
||||
@ -485,28 +484,26 @@ const BufPrintContext = struct {
|
||||
remaining: []u8,
|
||||
};
|
||||
|
||||
error BufferTooSmall;
|
||||
fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) %void {
|
||||
fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) !void {
|
||||
if (context.remaining.len < bytes.len) return error.BufferTooSmall;
|
||||
mem.copy(u8, context.remaining, bytes);
|
||||
context.remaining = context.remaining[bytes.len..];
|
||||
}
|
||||
|
||||
pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) %[]u8 {
|
||||
pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) ![]u8 {
|
||||
var context = BufPrintContext { .remaining = buf, };
|
||||
try format(&context, bufPrintWrite, fmt, args);
|
||||
return buf[0..buf.len - context.remaining.len];
|
||||
}
|
||||
|
||||
pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) %[]u8 {
|
||||
pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) ![]u8 {
|
||||
var size: usize = 0;
|
||||
// Cannot fail because `countSize` cannot fail.
|
||||
format(&size, countSize, fmt, args) catch unreachable;
|
||||
format(&size, error{}, countSize, fmt, args);
|
||||
const buf = try allocator.alloc(u8, size);
|
||||
return bufPrint(buf, fmt, args);
|
||||
}
|
||||
|
||||
fn countSize(size: &usize, bytes: []const u8) %void {
|
||||
fn countSize(size: &usize, bytes: []const u8) void {
|
||||
*size += bytes.len;
|
||||
}
|
||||
|
||||
@ -561,13 +558,13 @@ test "fmt.format" {
|
||||
}
|
||||
{
|
||||
var buf1: [32]u8 = undefined;
|
||||
const value: %i32 = 1234;
|
||||
const value: error!i32 = 1234;
|
||||
const result = try bufPrint(buf1[0..], "error union: {}\n", value);
|
||||
assert(mem.eql(u8, result, "error union: 1234\n"));
|
||||
}
|
||||
{
|
||||
var buf1: [32]u8 = undefined;
|
||||
const value: %i32 = error.InvalidChar;
|
||||
const value: error!i32 = error.InvalidChar;
|
||||
const result = try bufPrint(buf1[0..], "error union: {}\n", value);
|
||||
assert(mem.eql(u8, result, "error union: error.InvalidChar\n"));
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
|
||||
}
|
||||
|
||||
/// Returns the value that was already there.
|
||||
pub fn put(hm: &Self, key: K, value: &const V) %?V {
|
||||
pub fn put(hm: &Self, key: K, value: &const V) !?V {
|
||||
if (hm.entries.len == 0) {
|
||||
try hm.initCapacity(16);
|
||||
}
|
||||
@ -151,7 +151,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
|
||||
};
|
||||
}
|
||||
|
||||
fn initCapacity(hm: &Self, capacity: usize) %void {
|
||||
fn initCapacity(hm: &Self, capacity: usize) !void {
|
||||
hm.entries = try hm.allocator.alloc(Entry, capacity);
|
||||
hm.size = 0;
|
||||
hm.max_distance_from_start_index = 0;
|
||||
|
12
std/heap.zig
12
std/heap.zig
@ -9,8 +9,6 @@ const c = std.c;
|
||||
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
error OutOfMemory;
|
||||
|
||||
pub const c_allocator = &c_allocator_state;
|
||||
var c_allocator_state = Allocator {
|
||||
.allocFn = cAlloc,
|
||||
@ -18,14 +16,14 @@ var c_allocator_state = Allocator {
|
||||
.freeFn = cFree,
|
||||
};
|
||||
|
||||
fn cAlloc(self: &Allocator, n: usize, alignment: u29) %[]u8 {
|
||||
fn cAlloc(self: &Allocator, n: usize, alignment: u29) ![]u8 {
|
||||
return if (c.malloc(usize(n))) |buf|
|
||||
@ptrCast(&u8, buf)[0..n]
|
||||
else
|
||||
error.OutOfMemory;
|
||||
}
|
||||
|
||||
fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
|
||||
fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
|
||||
const old_ptr = @ptrCast(&c_void, old_mem.ptr);
|
||||
if (c.realloc(old_ptr, new_size)) |buf| {
|
||||
return @ptrCast(&u8, buf)[0..new_size];
|
||||
@ -47,7 +45,7 @@ pub const IncrementingAllocator = struct {
|
||||
end_index: usize,
|
||||
heap_handle: if (builtin.os == Os.windows) os.windows.HANDLE else void,
|
||||
|
||||
fn init(capacity: usize) %IncrementingAllocator {
|
||||
fn init(capacity: usize) !IncrementingAllocator {
|
||||
switch (builtin.os) {
|
||||
Os.linux, Os.macosx, Os.ios => {
|
||||
const p = os.posix;
|
||||
@ -105,7 +103,7 @@ pub const IncrementingAllocator = struct {
|
||||
return self.bytes.len - self.end_index;
|
||||
}
|
||||
|
||||
fn alloc(allocator: &Allocator, n: usize, alignment: u29) %[]u8 {
|
||||
fn alloc(allocator: &Allocator, n: usize, alignment: u29) ![]u8 {
|
||||
const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator);
|
||||
const addr = @ptrToInt(&self.bytes[self.end_index]);
|
||||
const rem = @rem(addr, alignment);
|
||||
@ -120,7 +118,7 @@ pub const IncrementingAllocator = struct {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
|
||||
fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
|
||||
if (new_size <= old_mem.len) {
|
||||
return old_mem[0..new_size];
|
||||
} else {
|
||||
|
108
std/io.zig
108
std/io.zig
@ -26,31 +26,7 @@ test "import io tests" {
|
||||
}
|
||||
}
|
||||
|
||||
/// The function received invalid input at runtime. An Invalid error means a
|
||||
/// bug in the program that called the function.
|
||||
error Invalid;
|
||||
|
||||
error DiskQuota;
|
||||
error FileTooBig;
|
||||
error Io;
|
||||
error NoSpaceLeft;
|
||||
error BadPerm;
|
||||
error BrokenPipe;
|
||||
error BadFd;
|
||||
error IsDir;
|
||||
error NotDir;
|
||||
error SymLinkLoop;
|
||||
error ProcessFdQuotaExceeded;
|
||||
error SystemFdQuotaExceeded;
|
||||
error NameTooLong;
|
||||
error NoDevice;
|
||||
error PathNotFound;
|
||||
error OutOfMemory;
|
||||
error Unseekable;
|
||||
error EndOfFile;
|
||||
error FilePosLargerThanPointerRange;
|
||||
|
||||
pub fn getStdErr() %File {
|
||||
pub fn getStdErr() !File {
|
||||
const handle = if (is_windows)
|
||||
try os.windowsGetStdHandle(system.STD_ERROR_HANDLE)
|
||||
else if (is_posix)
|
||||
@ -60,7 +36,7 @@ pub fn getStdErr() %File {
|
||||
return File.openHandle(handle);
|
||||
}
|
||||
|
||||
pub fn getStdOut() %File {
|
||||
pub fn getStdOut() !File {
|
||||
const handle = if (is_windows)
|
||||
try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)
|
||||
else if (is_posix)
|
||||
@ -70,7 +46,7 @@ pub fn getStdOut() %File {
|
||||
return File.openHandle(handle);
|
||||
}
|
||||
|
||||
pub fn getStdIn() %File {
|
||||
pub fn getStdIn() !File {
|
||||
const handle = if (is_windows)
|
||||
try os.windowsGetStdHandle(system.STD_INPUT_HANDLE)
|
||||
else if (is_posix)
|
||||
@ -94,7 +70,7 @@ pub const FileInStream = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn readFn(in_stream: &InStream, buffer: []u8) %usize {
|
||||
fn readFn(in_stream: &InStream, buffer: []u8) !usize {
|
||||
const self = @fieldParentPtr(FileInStream, "stream", in_stream);
|
||||
return self.file.read(buffer);
|
||||
}
|
||||
@ -114,7 +90,7 @@ pub const FileOutStream = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
|
||||
fn writeFn(out_stream: &OutStream, bytes: []const u8) !void {
|
||||
const self = @fieldParentPtr(FileOutStream, "stream", out_stream);
|
||||
return self.file.write(bytes);
|
||||
}
|
||||
@ -129,7 +105,7 @@ pub const File = struct {
|
||||
/// size buffer is too small, and the provided allocator is null, error.NameTooLong is returned.
|
||||
/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
|
||||
/// Call close to clean up.
|
||||
pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) %File {
|
||||
pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) !File {
|
||||
if (is_posix) {
|
||||
const flags = system.O_LARGEFILE|system.O_RDONLY;
|
||||
const fd = try os.posixOpen(path, flags, 0, allocator);
|
||||
@ -144,7 +120,7 @@ pub const File = struct {
|
||||
}
|
||||
|
||||
/// Calls `openWriteMode` with 0o666 for the mode.
|
||||
pub fn openWrite(path: []const u8, allocator: ?&mem.Allocator) %File {
|
||||
pub fn openWrite(path: []const u8, allocator: ?&mem.Allocator) !File {
|
||||
return openWriteMode(path, 0o666, allocator);
|
||||
|
||||
}
|
||||
@ -154,7 +130,7 @@ pub const File = struct {
|
||||
/// size buffer is too small, and the provided allocator is null, error.NameTooLong is returned.
|
||||
/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
|
||||
/// Call close to clean up.
|
||||
pub fn openWriteMode(path: []const u8, mode: usize, allocator: ?&mem.Allocator) %File {
|
||||
pub fn openWriteMode(path: []const u8, mode: usize, allocator: ?&mem.Allocator) !File {
|
||||
if (is_posix) {
|
||||
const flags = system.O_LARGEFILE|system.O_WRONLY|system.O_CREAT|system.O_CLOEXEC|system.O_TRUNC;
|
||||
const fd = try os.posixOpen(path, flags, mode, allocator);
|
||||
@ -189,7 +165,7 @@ pub const File = struct {
|
||||
return os.isTty(self.handle);
|
||||
}
|
||||
|
||||
pub fn seekForward(self: &File, amount: isize) %void {
|
||||
pub fn seekForward(self: &File, amount: isize) !void {
|
||||
switch (builtin.os) {
|
||||
Os.linux, Os.macosx, Os.ios => {
|
||||
const result = system.lseek(self.handle, amount, system.SEEK_CUR);
|
||||
@ -218,7 +194,7 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn seekTo(self: &File, pos: usize) %void {
|
||||
pub fn seekTo(self: &File, pos: usize) !void {
|
||||
switch (builtin.os) {
|
||||
Os.linux, Os.macosx, Os.ios => {
|
||||
const ipos = try math.cast(isize, pos);
|
||||
@ -249,7 +225,7 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getPos(self: &File) %usize {
|
||||
pub fn getPos(self: &File) !usize {
|
||||
switch (builtin.os) {
|
||||
Os.linux, Os.macosx, Os.ios => {
|
||||
const result = system.lseek(self.handle, 0, system.SEEK_CUR);
|
||||
@ -289,7 +265,7 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getEndPos(self: &File) %usize {
|
||||
pub fn getEndPos(self: &File) !usize {
|
||||
if (is_posix) {
|
||||
var stat: system.Stat = undefined;
|
||||
const err = system.getErrno(system.fstat(self.handle, &stat));
|
||||
@ -318,7 +294,7 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(self: &File, buffer: []u8) %usize {
|
||||
pub fn read(self: &File, buffer: []u8) !usize {
|
||||
if (is_posix) {
|
||||
var index: usize = 0;
|
||||
while (index < buffer.len) {
|
||||
@ -360,7 +336,7 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn write(self: &File, bytes: []const u8) %void {
|
||||
fn write(self: &File, bytes: []const u8) !void {
|
||||
if (is_posix) {
|
||||
try os.posixWrite(self.handle, bytes);
|
||||
} else if (is_windows) {
|
||||
@ -371,19 +347,16 @@ pub const File = struct {
|
||||
}
|
||||
};
|
||||
|
||||
error StreamTooLong;
|
||||
error EndOfStream;
|
||||
|
||||
pub const InStream = struct {
|
||||
/// Return the number of bytes read. If the number read is smaller than buf.len, it
|
||||
/// means the stream reached the end. Reaching the end of a stream is not an error
|
||||
/// condition.
|
||||
readFn: fn(self: &InStream, buffer: []u8) %usize,
|
||||
readFn: fn(self: &InStream, buffer: []u8) !usize,
|
||||
|
||||
/// Replaces `buffer` contents by reading from the stream until it is finished.
|
||||
/// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and
|
||||
/// the contents read from the stream are lost.
|
||||
pub fn readAllBuffer(self: &InStream, buffer: &Buffer, max_size: usize) %void {
|
||||
pub fn readAllBuffer(self: &InStream, buffer: &Buffer, max_size: usize) !void {
|
||||
try buffer.resize(0);
|
||||
|
||||
var actual_buf_len: usize = 0;
|
||||
@ -408,7 +381,7 @@ pub const InStream = struct {
|
||||
/// memory would be greater than `max_size`, returns `error.StreamTooLong`.
|
||||
/// Caller owns returned memory.
|
||||
/// If this function returns an error, the contents from the stream read so far are lost.
|
||||
pub fn readAllAlloc(self: &InStream, allocator: &mem.Allocator, max_size: usize) %[]u8 {
|
||||
pub fn readAllAlloc(self: &InStream, allocator: &mem.Allocator, max_size: usize) ![]u8 {
|
||||
var buf = Buffer.initNull(allocator);
|
||||
defer buf.deinit();
|
||||
|
||||
@ -420,7 +393,7 @@ pub const InStream = struct {
|
||||
/// Does not include the delimiter in the result.
|
||||
/// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and the contents
|
||||
/// read from the stream so far are lost.
|
||||
pub fn readUntilDelimiterBuffer(self: &InStream, buffer: &Buffer, delimiter: u8, max_size: usize) %void {
|
||||
pub fn readUntilDelimiterBuffer(self: &InStream, buffer: &Buffer, delimiter: u8, max_size: usize) !void {
|
||||
try buf.resize(0);
|
||||
|
||||
while (true) {
|
||||
@ -443,7 +416,7 @@ pub const InStream = struct {
|
||||
/// Caller owns returned memory.
|
||||
/// If this function returns an error, the contents from the stream read so far are lost.
|
||||
pub fn readUntilDelimiterAlloc(self: &InStream, allocator: &mem.Allocator,
|
||||
delimiter: u8, max_size: usize) %[]u8
|
||||
delimiter: u8, max_size: usize) ![]u8
|
||||
{
|
||||
var buf = Buffer.initNull(allocator);
|
||||
defer buf.deinit();
|
||||
@ -455,43 +428,43 @@ pub const InStream = struct {
|
||||
/// Returns the number of bytes read. If the number read is smaller than buf.len, it
|
||||
/// means the stream reached the end. Reaching the end of a stream is not an error
|
||||
/// condition.
|
||||
pub fn read(self: &InStream, buffer: []u8) %usize {
|
||||
pub fn read(self: &InStream, buffer: []u8) !usize {
|
||||
return self.readFn(self, buffer);
|
||||
}
|
||||
|
||||
/// Same as `read` but end of stream returns `error.EndOfStream`.
|
||||
pub fn readNoEof(self: &InStream, buf: []u8) %void {
|
||||
pub fn readNoEof(self: &InStream, buf: []u8) !void {
|
||||
const amt_read = try self.read(buf);
|
||||
if (amt_read < buf.len) return error.EndOfStream;
|
||||
}
|
||||
|
||||
/// Reads 1 byte from the stream or returns `error.EndOfStream`.
|
||||
pub fn readByte(self: &InStream) %u8 {
|
||||
pub fn readByte(self: &InStream) !u8 {
|
||||
var result: [1]u8 = undefined;
|
||||
try self.readNoEof(result[0..]);
|
||||
return result[0];
|
||||
}
|
||||
|
||||
/// Same as `readByte` except the returned byte is signed.
|
||||
pub fn readByteSigned(self: &InStream) %i8 {
|
||||
pub fn readByteSigned(self: &InStream) !i8 {
|
||||
return @bitCast(i8, try self.readByte());
|
||||
}
|
||||
|
||||
pub fn readIntLe(self: &InStream, comptime T: type) %T {
|
||||
pub fn readIntLe(self: &InStream, comptime T: type) !T {
|
||||
return self.readInt(builtin.Endian.Little, T);
|
||||
}
|
||||
|
||||
pub fn readIntBe(self: &InStream, comptime T: type) %T {
|
||||
pub fn readIntBe(self: &InStream, comptime T: type) !T {
|
||||
return self.readInt(builtin.Endian.Big, T);
|
||||
}
|
||||
|
||||
pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) %T {
|
||||
pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) !T {
|
||||
var bytes: [@sizeOf(T)]u8 = undefined;
|
||||
try self.readNoEof(bytes[0..]);
|
||||
return mem.readInt(bytes, T, endian);
|
||||
}
|
||||
|
||||
pub fn readVarInt(self: &InStream, endian: builtin.Endian, comptime T: type, size: usize) %T {
|
||||
pub fn readVarInt(self: &InStream, endian: builtin.Endian, comptime T: type, size: usize) !T {
|
||||
assert(size <= @sizeOf(T));
|
||||
assert(size <= 8);
|
||||
var input_buf: [8]u8 = undefined;
|
||||
@ -504,22 +477,23 @@ pub const InStream = struct {
|
||||
};
|
||||
|
||||
pub const OutStream = struct {
|
||||
writeFn: fn(self: &OutStream, bytes: []const u8) %void,
|
||||
// TODO allow specifying the error set
|
||||
writeFn: fn(self: &OutStream, bytes: []const u8) error!void,
|
||||
|
||||
pub fn print(self: &OutStream, comptime format: []const u8, args: ...) %void {
|
||||
return std.fmt.format(self, self.writeFn, format, args);
|
||||
pub fn print(self: &OutStream, comptime format: []const u8, args: ...) !void {
|
||||
return std.fmt.format(self, error, self.writeFn, format, args);
|
||||
}
|
||||
|
||||
pub fn write(self: &OutStream, bytes: []const u8) %void {
|
||||
pub fn write(self: &OutStream, bytes: []const u8) !void {
|
||||
return self.writeFn(self, bytes);
|
||||
}
|
||||
|
||||
pub fn writeByte(self: &OutStream, byte: u8) %void {
|
||||
pub fn writeByte(self: &OutStream, byte: u8) !void {
|
||||
const slice = (&byte)[0..1];
|
||||
return self.writeFn(self, slice);
|
||||
}
|
||||
|
||||
pub fn writeByteNTimes(self: &OutStream, byte: u8, n: usize) %void {
|
||||
pub fn writeByteNTimes(self: &OutStream, byte: u8, n: usize) !void {
|
||||
const slice = (&byte)[0..1];
|
||||
var i: usize = 0;
|
||||
while (i < n) : (i += 1) {
|
||||
@ -532,19 +506,19 @@ pub const OutStream = struct {
|
||||
/// a fixed size buffer of size `std.os.max_noalloc_path_len` is an attempted solution. If the fixed
|
||||
/// size buffer is too small, and the provided allocator is null, `error.NameTooLong` is returned.
|
||||
/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
|
||||
pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator) %void {
|
||||
pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator) !void {
|
||||
var file = try File.openWrite(path, allocator);
|
||||
defer file.close();
|
||||
try file.write(data);
|
||||
}
|
||||
|
||||
/// On success, caller owns returned buffer.
|
||||
pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) %[]u8 {
|
||||
pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) ![]u8 {
|
||||
return readFileAllocExtra(path, allocator, 0);
|
||||
}
|
||||
/// On success, caller owns returned buffer.
|
||||
/// Allocates extra_len extra bytes at the end of the file buffer, which are uninitialized.
|
||||
pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) %[]u8 {
|
||||
pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) ![]u8 {
|
||||
var file = try File.openRead(path, allocator);
|
||||
defer file.close();
|
||||
|
||||
@ -589,7 +563,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) type {
|
||||
};
|
||||
}
|
||||
|
||||
fn readFn(in_stream: &InStream, dest: []u8) %usize {
|
||||
fn readFn(in_stream: &InStream, dest: []u8) !usize {
|
||||
const self = @fieldParentPtr(Self, "stream", in_stream);
|
||||
|
||||
var dest_index: usize = 0;
|
||||
@ -652,7 +626,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) type {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn flush(self: &Self) %void {
|
||||
pub fn flush(self: &Self) !void {
|
||||
if (self.index == 0)
|
||||
return;
|
||||
|
||||
@ -660,7 +634,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) type {
|
||||
self.index = 0;
|
||||
}
|
||||
|
||||
fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
|
||||
fn writeFn(out_stream: &OutStream, bytes: []const u8) !void {
|
||||
const self = @fieldParentPtr(Self, "stream", out_stream);
|
||||
|
||||
if (bytes.len >= self.buffer.len) {
|
||||
@ -698,7 +672,7 @@ pub const BufferOutStream = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
|
||||
fn writeFn(out_stream: &OutStream, bytes: []const u8) !void {
|
||||
const self = @fieldParentPtr(BufferOutStream, "stream", out_stream);
|
||||
return self.buffer.append(bytes);
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
|
||||
///
|
||||
/// Returns:
|
||||
/// A pointer to the new node.
|
||||
pub fn allocateNode(list: &Self, allocator: &Allocator) %&Node {
|
||||
pub fn allocateNode(list: &Self, allocator: &Allocator) !&Node {
|
||||
comptime assert(!isIntrusive());
|
||||
return allocator.create(Node);
|
||||
}
|
||||
@ -213,7 +213,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
|
||||
///
|
||||
/// Returns:
|
||||
/// A pointer to the new node.
|
||||
pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) %&Node {
|
||||
pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) !&Node {
|
||||
comptime assert(!isIntrusive());
|
||||
var node = try list.allocateNode(allocator);
|
||||
*node = Node.init(data);
|
||||
|
@ -191,30 +191,26 @@ test "math.max" {
|
||||
assert(max(i32(-1), i32(2)) == 2);
|
||||
}
|
||||
|
||||
error Overflow;
|
||||
pub fn mul(comptime T: type, a: T, b: T) %T {
|
||||
pub fn mul(comptime T: type, a: T, b: T) !T {
|
||||
var answer: T = undefined;
|
||||
return if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer;
|
||||
}
|
||||
|
||||
error Overflow;
|
||||
pub fn add(comptime T: type, a: T, b: T) %T {
|
||||
pub fn add(comptime T: type, a: T, b: T) !T {
|
||||
var answer: T = undefined;
|
||||
return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
|
||||
}
|
||||
|
||||
error Overflow;
|
||||
pub fn sub(comptime T: type, a: T, b: T) %T {
|
||||
pub fn sub(comptime T: type, a: T, b: T) !T {
|
||||
var answer: T = undefined;
|
||||
return if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer;
|
||||
}
|
||||
|
||||
pub fn negate(x: var) %@typeOf(x) {
|
||||
pub fn negate(x: var) !@typeOf(x) {
|
||||
return sub(@typeOf(x), 0, x);
|
||||
}
|
||||
|
||||
error Overflow;
|
||||
pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) %T {
|
||||
pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) !T {
|
||||
var answer: T = undefined;
|
||||
return if (@shlWithOverflow(T, a, shift_amt, &answer)) error.Overflow else answer;
|
||||
}
|
||||
@ -323,8 +319,7 @@ fn testOverflow() void {
|
||||
}
|
||||
|
||||
|
||||
error Overflow;
|
||||
pub fn absInt(x: var) %@typeOf(x) {
|
||||
pub fn absInt(x: var) !@typeOf(x) {
|
||||
const T = @typeOf(x);
|
||||
comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt
|
||||
comptime assert(T.is_signed); // must pass a signed integer to absInt
|
||||
@ -347,9 +342,7 @@ fn testAbsInt() void {
|
||||
|
||||
pub const absFloat = @import("fabs.zig").fabs;
|
||||
|
||||
error DivisionByZero;
|
||||
error Overflow;
|
||||
pub fn divTrunc(comptime T: type, numerator: T, denominator: T) %T {
|
||||
pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T {
|
||||
@setRuntimeSafety(false);
|
||||
if (denominator == 0)
|
||||
return error.DivisionByZero;
|
||||
@ -372,9 +365,7 @@ fn testDivTrunc() void {
|
||||
assert((divTrunc(f32, -5.0, 3.0) catch unreachable) == -1.0);
|
||||
}
|
||||
|
||||
error DivisionByZero;
|
||||
error Overflow;
|
||||
pub fn divFloor(comptime T: type, numerator: T, denominator: T) %T {
|
||||
pub fn divFloor(comptime T: type, numerator: T, denominator: T) !T {
|
||||
@setRuntimeSafety(false);
|
||||
if (denominator == 0)
|
||||
return error.DivisionByZero;
|
||||
@ -397,10 +388,7 @@ fn testDivFloor() void {
|
||||
assert((divFloor(f32, -5.0, 3.0) catch unreachable) == -2.0);
|
||||
}
|
||||
|
||||
error DivisionByZero;
|
||||
error Overflow;
|
||||
error UnexpectedRemainder;
|
||||
pub fn divExact(comptime T: type, numerator: T, denominator: T) %T {
|
||||
pub fn divExact(comptime T: type, numerator: T, denominator: T) !T {
|
||||
@setRuntimeSafety(false);
|
||||
if (denominator == 0)
|
||||
return error.DivisionByZero;
|
||||
@ -428,9 +416,7 @@ fn testDivExact() void {
|
||||
if (divExact(f32, 5.0, 2.0)) |_| unreachable else |err| assert(err == error.UnexpectedRemainder);
|
||||
}
|
||||
|
||||
error DivisionByZero;
|
||||
error NegativeDenominator;
|
||||
pub fn mod(comptime T: type, numerator: T, denominator: T) %T {
|
||||
pub fn mod(comptime T: type, numerator: T, denominator: T) !T {
|
||||
@setRuntimeSafety(false);
|
||||
if (denominator == 0)
|
||||
return error.DivisionByZero;
|
||||
@ -455,9 +441,7 @@ fn testMod() void {
|
||||
if (mod(f32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
|
||||
}
|
||||
|
||||
error DivisionByZero;
|
||||
error NegativeDenominator;
|
||||
pub fn rem(comptime T: type, numerator: T, denominator: T) %T {
|
||||
pub fn rem(comptime T: type, numerator: T, denominator: T) !T {
|
||||
@setRuntimeSafety(false);
|
||||
if (denominator == 0)
|
||||
return error.DivisionByZero;
|
||||
@ -505,8 +489,7 @@ test "math.absCast" {
|
||||
|
||||
/// Returns the negation of the integer parameter.
|
||||
/// Result is a signed integer.
|
||||
error Overflow;
|
||||
pub fn negateCast(x: var) %@IntType(true, @typeOf(x).bit_count) {
|
||||
pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) {
|
||||
if (@typeOf(x).is_signed)
|
||||
return negate(x);
|
||||
|
||||
@ -532,8 +515,7 @@ test "math.negateCast" {
|
||||
|
||||
/// Cast an integer to a different integer type. If the value doesn't fit,
|
||||
/// return an error.
|
||||
error Overflow;
|
||||
pub fn cast(comptime T: type, x: var) %T {
|
||||
pub fn cast(comptime T: type, x: var) !T {
|
||||
comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer
|
||||
if (x > @maxValue(T)) {
|
||||
return error.Overflow;
|
||||
|
22
std/mem.zig
22
std/mem.zig
@ -4,13 +4,13 @@ const assert = debug.assert;
|
||||
const math = std.math;
|
||||
const builtin = @import("builtin");
|
||||
|
||||
error OutOfMemory;
|
||||
|
||||
pub const Allocator = struct {
|
||||
const Errors = error {OutOfMemory};
|
||||
|
||||
/// Allocate byte_count bytes and return them in a slice, with the
|
||||
/// slice's pointer aligned at least to alignment bytes.
|
||||
/// The returned newly allocated memory is undefined.
|
||||
allocFn: fn (self: &Allocator, byte_count: usize, alignment: u29) %[]u8,
|
||||
allocFn: fn (self: &Allocator, byte_count: usize, alignment: u29) Errors![]u8,
|
||||
|
||||
/// If `new_byte_count > old_mem.len`:
|
||||
/// * `old_mem.len` is the same as what was returned from allocFn or reallocFn.
|
||||
@ -21,12 +21,12 @@ pub const Allocator = struct {
|
||||
/// * alignment <= alignment of old_mem.ptr
|
||||
///
|
||||
/// The returned newly allocated memory is undefined.
|
||||
reallocFn: fn (self: &Allocator, old_mem: []u8, new_byte_count: usize, alignment: u29) %[]u8,
|
||||
reallocFn: fn (self: &Allocator, old_mem: []u8, new_byte_count: usize, alignment: u29) Errors![]u8,
|
||||
|
||||
/// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`
|
||||
freeFn: fn (self: &Allocator, old_mem: []u8) void,
|
||||
|
||||
fn create(self: &Allocator, comptime T: type) %&T {
|
||||
fn create(self: &Allocator, comptime T: type) !&T {
|
||||
const slice = try self.alloc(T, 1);
|
||||
return &slice[0];
|
||||
}
|
||||
@ -35,7 +35,7 @@ pub const Allocator = struct {
|
||||
self.free(ptr[0..1]);
|
||||
}
|
||||
|
||||
fn alloc(self: &Allocator, comptime T: type, n: usize) %[]T {
|
||||
fn alloc(self: &Allocator, comptime T: type, n: usize) ![]T {
|
||||
return self.alignedAlloc(T, @alignOf(T), n);
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ pub const Allocator = struct {
|
||||
return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
|
||||
}
|
||||
|
||||
fn realloc(self: &Allocator, comptime T: type, old_mem: []T, n: usize) %[]T {
|
||||
fn realloc(self: &Allocator, comptime T: type, old_mem: []T, n: usize) ![]T {
|
||||
return self.alignedRealloc(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ pub const FixedBufferAllocator = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn alloc(allocator: &Allocator, n: usize, alignment: u29) %[]u8 {
|
||||
fn alloc(allocator: &Allocator, n: usize, alignment: u29) ![]u8 {
|
||||
const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
|
||||
const addr = @ptrToInt(&self.buffer[self.end_index]);
|
||||
const rem = @rem(addr, alignment);
|
||||
@ -138,7 +138,7 @@ pub const FixedBufferAllocator = struct {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
|
||||
fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
|
||||
if (new_size <= old_mem.len) {
|
||||
return old_mem[0..new_size];
|
||||
} else {
|
||||
@ -197,7 +197,7 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool {
|
||||
}
|
||||
|
||||
/// Copies ::m to newly allocated memory. Caller is responsible to free it.
|
||||
pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) %[]T {
|
||||
pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) ![]T {
|
||||
const new_buf = try allocator.alloc(T, m.len);
|
||||
copy(T, new_buf, m);
|
||||
return new_buf;
|
||||
@ -428,7 +428,7 @@ const SplitIterator = struct {
|
||||
|
||||
/// Naively combines a series of strings with a separator.
|
||||
/// Allocates memory for the result, which must be freed by the caller.
|
||||
pub fn join(allocator: &Allocator, sep: u8, strings: ...) %[]u8 {
|
||||
pub fn join(allocator: &Allocator, sep: u8, strings: ...) ![]u8 {
|
||||
comptime assert(strings.len >= 1);
|
||||
var total_strings_len: usize = strings.len; // 1 sep per string
|
||||
{
|
||||
|
34
std/net.zig
34
std/net.zig
@ -5,19 +5,10 @@ const endian = std.endian;
|
||||
|
||||
// TODO don't trust this file, it bit rotted. start over
|
||||
|
||||
error SigInterrupt;
|
||||
error Io;
|
||||
error TimedOut;
|
||||
error ConnectionReset;
|
||||
error ConnectionRefused;
|
||||
error OutOfMemory;
|
||||
error NotSocket;
|
||||
error BadFd;
|
||||
|
||||
const Connection = struct {
|
||||
socket_fd: i32,
|
||||
|
||||
pub fn send(c: Connection, buf: []const u8) %usize {
|
||||
pub fn send(c: Connection, buf: []const u8) !usize {
|
||||
const send_ret = linux.sendto(c.socket_fd, buf.ptr, buf.len, 0, null, 0);
|
||||
const send_err = linux.getErrno(send_ret);
|
||||
switch (send_err) {
|
||||
@ -31,7 +22,7 @@ const Connection = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn recv(c: Connection, buf: []u8) %[]u8 {
|
||||
pub fn recv(c: Connection, buf: []u8) ![]u8 {
|
||||
const recv_ret = linux.recvfrom(c.socket_fd, buf.ptr, buf.len, 0, null, null);
|
||||
const recv_err = linux.getErrno(recv_ret);
|
||||
switch (recv_err) {
|
||||
@ -48,7 +39,7 @@ const Connection = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn close(c: Connection) %void {
|
||||
pub fn close(c: Connection) !void {
|
||||
switch (linux.getErrno(linux.close(c.socket_fd))) {
|
||||
0 => return,
|
||||
linux.EBADF => unreachable,
|
||||
@ -66,7 +57,7 @@ const Address = struct {
|
||||
sort_key: i32,
|
||||
};
|
||||
|
||||
pub fn lookup(hostname: []const u8, out_addrs: []Address) %[]Address {
|
||||
pub fn lookup(hostname: []const u8, out_addrs: []Address) ![]Address {
|
||||
if (hostname.len == 0) {
|
||||
|
||||
unreachable; // TODO
|
||||
@ -75,7 +66,7 @@ pub fn lookup(hostname: []const u8, out_addrs: []Address) %[]Address {
|
||||
unreachable; // TODO
|
||||
}
|
||||
|
||||
pub fn connectAddr(addr: &Address, port: u16) %Connection {
|
||||
pub fn connectAddr(addr: &Address, port: u16) !Connection {
|
||||
const socket_ret = linux.socket(addr.family, linux.SOCK_STREAM, linux.PROTO_tcp);
|
||||
const socket_err = linux.getErrno(socket_ret);
|
||||
if (socket_err > 0) {
|
||||
@ -118,7 +109,7 @@ pub fn connectAddr(addr: &Address, port: u16) %Connection {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn connect(hostname: []const u8, port: u16) %Connection {
|
||||
pub fn connect(hostname: []const u8, port: u16) !Connection {
|
||||
var addrs_buf: [1]Address = undefined;
|
||||
const addrs_slice = try lookup(hostname, addrs_buf[0..]);
|
||||
const main_addr = &addrs_slice[0];
|
||||
@ -126,9 +117,7 @@ pub fn connect(hostname: []const u8, port: u16) %Connection {
|
||||
return connectAddr(main_addr, port);
|
||||
}
|
||||
|
||||
error InvalidIpLiteral;
|
||||
|
||||
pub fn parseIpLiteral(buf: []const u8) %Address {
|
||||
pub fn parseIpLiteral(buf: []const u8) !Address {
|
||||
|
||||
return error.InvalidIpLiteral;
|
||||
}
|
||||
@ -146,12 +135,7 @@ fn hexDigit(c: u8) u8 {
|
||||
}
|
||||
}
|
||||
|
||||
error InvalidChar;
|
||||
error Overflow;
|
||||
error JunkAtEnd;
|
||||
error Incomplete;
|
||||
|
||||
fn parseIp6(buf: []const u8) %Address {
|
||||
fn parseIp6(buf: []const u8) !Address {
|
||||
var result: Address = undefined;
|
||||
result.family = linux.AF_INET6;
|
||||
result.scope_id = 0;
|
||||
@ -232,7 +216,7 @@ fn parseIp6(buf: []const u8) %Address {
|
||||
return error.Incomplete;
|
||||
}
|
||||
|
||||
fn parseIp4(buf: []const u8) %u32 {
|
||||
fn parseIp4(buf: []const u8) !u32 {
|
||||
var result: u32 = undefined;
|
||||
const out_ptr = ([]u8)((&result)[0..1]);
|
||||
|
||||
|
@ -13,10 +13,6 @@ const builtin = @import("builtin");
|
||||
const Os = builtin.Os;
|
||||
const LinkedList = std.LinkedList;
|
||||
|
||||
error PermissionDenied;
|
||||
error ProcessNotFound;
|
||||
error InvalidName;
|
||||
|
||||
var children_nodes = LinkedList(&ChildProcess).init();
|
||||
|
||||
const is_windows = builtin.os == Os.windows;
|
||||
@ -74,7 +70,7 @@ pub const ChildProcess = struct {
|
||||
|
||||
/// First argument in argv is the executable.
|
||||
/// On success must call deinit.
|
||||
pub fn init(argv: []const []const u8, allocator: &mem.Allocator) %&ChildProcess {
|
||||
pub fn init(argv: []const []const u8, allocator: &mem.Allocator) !&ChildProcess {
|
||||
const child = try allocator.create(ChildProcess);
|
||||
errdefer allocator.destroy(child);
|
||||
|
||||
@ -103,7 +99,7 @@ pub const ChildProcess = struct {
|
||||
return child;
|
||||
}
|
||||
|
||||
pub fn setUserName(self: &ChildProcess, name: []const u8) %void {
|
||||
pub fn setUserName(self: &ChildProcess, name: []const u8) !void {
|
||||
const user_info = try os.getUserInfo(name);
|
||||
self.uid = user_info.uid;
|
||||
self.gid = user_info.gid;
|
||||
@ -111,7 +107,7 @@ pub const ChildProcess = struct {
|
||||
|
||||
/// onTerm can be called before `spawn` returns.
|
||||
/// On success must call `kill` or `wait`.
|
||||
pub fn spawn(self: &ChildProcess) %void {
|
||||
pub fn spawn(self: &ChildProcess) !void {
|
||||
if (is_windows) {
|
||||
return self.spawnWindows();
|
||||
} else {
|
||||
@ -119,13 +115,13 @@ pub const ChildProcess = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawnAndWait(self: &ChildProcess) %Term {
|
||||
pub fn spawnAndWait(self: &ChildProcess) !Term {
|
||||
try self.spawn();
|
||||
return self.wait();
|
||||
}
|
||||
|
||||
/// Forcibly terminates child process and then cleans up all resources.
|
||||
pub fn kill(self: &ChildProcess) %Term {
|
||||
pub fn kill(self: &ChildProcess) !Term {
|
||||
if (is_windows) {
|
||||
return self.killWindows(1);
|
||||
} else {
|
||||
@ -133,7 +129,7 @@ pub const ChildProcess = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn killWindows(self: &ChildProcess, exit_code: windows.UINT) %Term {
|
||||
pub fn killWindows(self: &ChildProcess, exit_code: windows.UINT) !Term {
|
||||
if (self.term) |term| {
|
||||
self.cleanupStreams();
|
||||
return term;
|
||||
@ -149,7 +145,7 @@ pub const ChildProcess = struct {
|
||||
return ??self.term;
|
||||
}
|
||||
|
||||
pub fn killPosix(self: &ChildProcess) %Term {
|
||||
pub fn killPosix(self: &ChildProcess) !Term {
|
||||
block_SIGCHLD();
|
||||
defer restore_SIGCHLD();
|
||||
|
||||
@ -172,7 +168,7 @@ pub const ChildProcess = struct {
|
||||
}
|
||||
|
||||
/// Blocks until child process terminates and then cleans up all resources.
|
||||
pub fn wait(self: &ChildProcess) %Term {
|
||||
pub fn wait(self: &ChildProcess) !Term {
|
||||
if (is_windows) {
|
||||
return self.waitWindows();
|
||||
} else {
|
||||
@ -220,7 +216,7 @@ pub const ChildProcess = struct {
|
||||
};
|
||||
}
|
||||
|
||||
fn waitWindows(self: &ChildProcess) %Term {
|
||||
fn waitWindows(self: &ChildProcess) !Term {
|
||||
if (self.term) |term| {
|
||||
self.cleanupStreams();
|
||||
return term;
|
||||
@ -230,7 +226,7 @@ pub const ChildProcess = struct {
|
||||
return ??self.term;
|
||||
}
|
||||
|
||||
fn waitPosix(self: &ChildProcess) %Term {
|
||||
fn waitPosix(self: &ChildProcess) !Term {
|
||||
block_SIGCHLD();
|
||||
defer restore_SIGCHLD();
|
||||
|
||||
@ -247,7 +243,7 @@ pub const ChildProcess = struct {
|
||||
self.allocator.destroy(self);
|
||||
}
|
||||
|
||||
fn waitUnwrappedWindows(self: &ChildProcess) %void {
|
||||
fn waitUnwrappedWindows(self: &ChildProcess) !void {
|
||||
const result = os.windowsWaitSingle(self.handle, windows.INFINITE);
|
||||
|
||||
self.term = (%Term)(x: {
|
||||
@ -295,7 +291,7 @@ pub const ChildProcess = struct {
|
||||
if (self.stderr) |*stderr| { stderr.close(); self.stderr = null; }
|
||||
}
|
||||
|
||||
fn cleanupAfterWait(self: &ChildProcess, status: i32) %Term {
|
||||
fn cleanupAfterWait(self: &ChildProcess, status: i32) !Term {
|
||||
children_nodes.remove(&self.llnode);
|
||||
|
||||
defer {
|
||||
@ -331,7 +327,7 @@ pub const ChildProcess = struct {
|
||||
;
|
||||
}
|
||||
|
||||
fn spawnPosix(self: &ChildProcess) %void {
|
||||
fn spawnPosix(self: &ChildProcess) !void {
|
||||
// TODO atomically set a flag saying that we already did this
|
||||
install_SIGCHLD_handler();
|
||||
|
||||
@ -440,7 +436,7 @@ pub const ChildProcess = struct {
|
||||
if (self.stderr_behavior == StdIo.Pipe) { os.close(stderr_pipe[1]); }
|
||||
}
|
||||
|
||||
fn spawnWindows(self: &ChildProcess) %void {
|
||||
fn spawnWindows(self: &ChildProcess) !void {
|
||||
const saAttr = windows.SECURITY_ATTRIBUTES {
|
||||
.nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),
|
||||
.bInheritHandle = windows.TRUE,
|
||||
@ -623,7 +619,7 @@ pub const ChildProcess = struct {
|
||||
if (self.stdout_behavior == StdIo.Pipe) { os.close(??g_hChildStd_OUT_Wr); }
|
||||
}
|
||||
|
||||
fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) %void {
|
||||
fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) !void {
|
||||
switch (stdio) {
|
||||
StdIo.Pipe => try os.posixDup2(pipe_fd, std_fileno),
|
||||
StdIo.Close => os.close(std_fileno),
|
||||
@ -655,7 +651,7 @@ fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?
|
||||
|
||||
/// Caller must dealloc.
|
||||
/// Guarantees a null byte at result[result.len].
|
||||
fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) %[]u8 {
|
||||
fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) ![]u8 {
|
||||
var buf = try Buffer.initSize(allocator, 0);
|
||||
defer buf.deinit();
|
||||
|
||||
@ -700,7 +696,7 @@ fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) void {
|
||||
// a namespace field lookup
|
||||
const SECURITY_ATTRIBUTES = windows.SECURITY_ATTRIBUTES;
|
||||
|
||||
fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) %void {
|
||||
fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) !void {
|
||||
if (windows.CreatePipe(rd, wr, sattr, 0) == 0) {
|
||||
const err = windows.GetLastError();
|
||||
return switch (err) {
|
||||
@ -709,7 +705,7 @@ fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECUR
|
||||
}
|
||||
}
|
||||
|
||||
fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.DWORD) %void {
|
||||
fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.DWORD) !void {
|
||||
if (windows.SetHandleInformation(h, mask, flags) == 0) {
|
||||
const err = windows.GetLastError();
|
||||
return switch (err) {
|
||||
@ -718,7 +714,7 @@ fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.D
|
||||
}
|
||||
}
|
||||
|
||||
fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) %void {
|
||||
fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) !void {
|
||||
var rd_h: windows.HANDLE = undefined;
|
||||
var wr_h: windows.HANDLE = undefined;
|
||||
try windowsMakePipe(&rd_h, &wr_h, sattr);
|
||||
@ -728,7 +724,7 @@ fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const S
|
||||
*wr = wr_h;
|
||||
}
|
||||
|
||||
fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) %void {
|
||||
fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) !void {
|
||||
var rd_h: windows.HANDLE = undefined;
|
||||
var wr_h: windows.HANDLE = undefined;
|
||||
try windowsMakePipe(&rd_h, &wr_h, sattr);
|
||||
@ -738,7 +734,7 @@ fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const
|
||||
*wr = wr_h;
|
||||
}
|
||||
|
||||
fn makePipe() %[2]i32 {
|
||||
fn makePipe() ![2]i32 {
|
||||
var fds: [2]i32 = undefined;
|
||||
const err = posix.getErrno(posix.pipe(&fds));
|
||||
if (err > 0) {
|
||||
@ -764,13 +760,13 @@ fn forkChildErrReport(fd: i32, err: error) noreturn {
|
||||
|
||||
const ErrInt = @IntType(false, @sizeOf(error) * 8);
|
||||
|
||||
fn writeIntFd(fd: i32, value: ErrInt) %void {
|
||||
fn writeIntFd(fd: i32, value: ErrInt) !void {
|
||||
var bytes: [@sizeOf(ErrInt)]u8 = undefined;
|
||||
mem.writeInt(bytes[0..], value, builtin.endian);
|
||||
os.posixWrite(fd, bytes[0..]) catch return error.SystemResources;
|
||||
}
|
||||
|
||||
fn readIntFd(fd: i32) %ErrInt {
|
||||
fn readIntFd(fd: i32) !ErrInt {
|
||||
var bytes: [@sizeOf(ErrInt)]u8 = undefined;
|
||||
os.posixRead(fd, bytes[0..]) catch return error.SystemResources;
|
||||
return mem.readInt(bytes[0..], ErrInt, builtin.endian);
|
||||
|
@ -9,7 +9,7 @@ pub const UserInfo = struct {
|
||||
};
|
||||
|
||||
/// POSIX function which gets a uid from username.
|
||||
pub fn getUserInfo(name: []const u8) %UserInfo {
|
||||
pub fn getUserInfo(name: []const u8) !UserInfo {
|
||||
return switch (builtin.os) {
|
||||
Os.linux, Os.macosx, Os.ios => posixGetUserInfo(name),
|
||||
else => @compileError("Unsupported OS"),
|
||||
@ -24,13 +24,10 @@ const State = enum {
|
||||
ReadGroupId,
|
||||
};
|
||||
|
||||
error UserNotFound;
|
||||
error CorruptPasswordFile;
|
||||
|
||||
// TODO this reads /etc/passwd. But sometimes the user/id mapping is in something else
|
||||
// like NIS, AD, etc. See `man nss` or look at an strace for `id myuser`.
|
||||
|
||||
pub fn posixGetUserInfo(name: []const u8) %UserInfo {
|
||||
pub fn posixGetUserInfo(name: []const u8) !UserInfo {
|
||||
var in_stream = try io.InStream.open("/etc/passwd", null);
|
||||
defer in_stream.close();
|
||||
|
||||
|
@ -1470,8 +1470,6 @@ test "std.os" {
|
||||
}
|
||||
|
||||
|
||||
error Unexpected;
|
||||
|
||||
// TODO make this a build variable that you can set
|
||||
const unexpected_error_tracing = false;
|
||||
|
||||
|
@ -720,7 +720,7 @@ pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags:
|
||||
// error SystemResources;
|
||||
// error Io;
|
||||
//
|
||||
// pub fn if_nametoindex(name: []u8) %u32 {
|
||||
// pub fn if_nametoindex(name: []u8) !u32 {
|
||||
// var ifr: ifreq = undefined;
|
||||
//
|
||||
// if (name.len >= ifr.ifr_name.len) {
|
||||
|
@ -32,7 +32,7 @@ pub fn isSep(byte: u8) bool {
|
||||
|
||||
/// Naively combines a series of paths with the native path seperator.
|
||||
/// Allocates memory for the result, which must be freed by the caller.
|
||||
pub fn join(allocator: &Allocator, paths: ...) %[]u8 {
|
||||
pub fn join(allocator: &Allocator, paths: ...) ![]u8 {
|
||||
if (is_windows) {
|
||||
return joinWindows(allocator, paths);
|
||||
} else {
|
||||
@ -40,11 +40,11 @@ pub fn join(allocator: &Allocator, paths: ...) %[]u8 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn joinWindows(allocator: &Allocator, paths: ...) %[]u8 {
|
||||
pub fn joinWindows(allocator: &Allocator, paths: ...) ![]u8 {
|
||||
return mem.join(allocator, sep_windows, paths);
|
||||
}
|
||||
|
||||
pub fn joinPosix(allocator: &Allocator, paths: ...) %[]u8 {
|
||||
pub fn joinPosix(allocator: &Allocator, paths: ...) ![]u8 {
|
||||
return mem.join(allocator, sep_posix, paths);
|
||||
}
|
||||
|
||||
@ -313,7 +313,7 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) bool {
|
||||
}
|
||||
|
||||
/// Converts the command line arguments into a slice and calls `resolveSlice`.
|
||||
pub fn resolve(allocator: &Allocator, args: ...) %[]u8 {
|
||||
pub fn resolve(allocator: &Allocator, args: ...) ![]u8 {
|
||||
var paths: [args.len][]const u8 = undefined;
|
||||
comptime var arg_i = 0;
|
||||
inline while (arg_i < args.len) : (arg_i += 1) {
|
||||
@ -323,7 +323,7 @@ pub fn resolve(allocator: &Allocator, args: ...) %[]u8 {
|
||||
}
|
||||
|
||||
/// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`.
|
||||
pub fn resolveSlice(allocator: &Allocator, paths: []const []const u8) %[]u8 {
|
||||
pub fn resolveSlice(allocator: &Allocator, paths: []const []const u8) ![]u8 {
|
||||
if (is_windows) {
|
||||
return resolveWindows(allocator, paths);
|
||||
} else {
|
||||
@ -337,7 +337,7 @@ pub fn resolveSlice(allocator: &Allocator, paths: []const []const u8) %[]u8 {
|
||||
/// If all paths are relative it uses the current working directory as a starting point.
|
||||
/// Each drive has its own current working directory.
|
||||
/// Path separators are canonicalized to '\\' and drives are canonicalized to capital letters.
|
||||
pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) %[]u8 {
|
||||
pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) ![]u8 {
|
||||
if (paths.len == 0) {
|
||||
assert(is_windows); // resolveWindows called on non windows can't use getCwd
|
||||
return os.getCwd(allocator);
|
||||
@ -520,7 +520,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) %[]u8 {
|
||||
/// It resolves "." and "..".
|
||||
/// The result does not have a trailing path separator.
|
||||
/// If all paths are relative it uses the current working directory as a starting point.
|
||||
pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) %[]u8 {
|
||||
pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) ![]u8 {
|
||||
if (paths.len == 0) {
|
||||
assert(!is_windows); // resolvePosix called on windows can't use getCwd
|
||||
return os.getCwd(allocator);
|
||||
@ -890,7 +890,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) void {
|
||||
/// resolve to the same path (after calling `resolve` on each), a zero-length
|
||||
/// string is returned.
|
||||
/// On Windows this canonicalizes the drive to a capital letter and paths to `\\`.
|
||||
pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) %[]u8 {
|
||||
pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) ![]u8 {
|
||||
if (is_windows) {
|
||||
return relativeWindows(allocator, from, to);
|
||||
} else {
|
||||
@ -898,7 +898,7 @@ pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) %[]u8 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) %[]u8 {
|
||||
pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) ![]u8 {
|
||||
const resolved_from = try resolveWindows(allocator, [][]const u8{from});
|
||||
defer allocator.free(resolved_from);
|
||||
|
||||
@ -971,7 +971,7 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8)
|
||||
return []u8{};
|
||||
}
|
||||
|
||||
pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) %[]u8 {
|
||||
pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) ![]u8 {
|
||||
const resolved_from = try resolvePosix(allocator, [][]const u8{from});
|
||||
defer allocator.free(resolved_from);
|
||||
|
||||
@ -1066,18 +1066,11 @@ fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []cons
|
||||
assert(mem.eql(u8, result, expected_output));
|
||||
}
|
||||
|
||||
error AccessDenied;
|
||||
error FileNotFound;
|
||||
error NotSupported;
|
||||
error NotDir;
|
||||
error NameTooLong;
|
||||
error SymLinkLoop;
|
||||
error InputOutput;
|
||||
/// Return the canonicalized absolute pathname.
|
||||
/// Expands all symbolic links and resolves references to `.`, `..`, and
|
||||
/// extra `/` characters in ::pathname.
|
||||
/// Caller must deallocate result.
|
||||
pub fn real(allocator: &Allocator, pathname: []const u8) %[]u8 {
|
||||
pub fn real(allocator: &Allocator, pathname: []const u8) ![]u8 {
|
||||
switch (builtin.os) {
|
||||
Os.windows => {
|
||||
const pathname_buf = try allocator.alloc(u8, pathname.len + 1);
|
||||
|
@ -6,11 +6,7 @@ const mem = std.mem;
|
||||
const BufMap = std.BufMap;
|
||||
const cstr = std.cstr;
|
||||
|
||||
error WaitAbandoned;
|
||||
error WaitTimeOut;
|
||||
error Unexpected;
|
||||
|
||||
pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) %void {
|
||||
pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) !void {
|
||||
const result = windows.WaitForSingleObject(handle, milliseconds);
|
||||
return switch (result) {
|
||||
windows.WAIT_ABANDONED => error.WaitAbandoned,
|
||||
@ -30,12 +26,7 @@ pub fn windowsClose(handle: windows.HANDLE) void {
|
||||
assert(windows.CloseHandle(handle) != 0);
|
||||
}
|
||||
|
||||
error SystemResources;
|
||||
error OperationAborted;
|
||||
error IoPending;
|
||||
error BrokenPipe;
|
||||
|
||||
pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) %void {
|
||||
pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) !void {
|
||||
if (windows.WriteFile(handle, @ptrCast(&const c_void, bytes.ptr), u32(bytes.len), null, null) == 0) {
|
||||
const err = windows.GetLastError();
|
||||
return switch (err) {
|
||||
@ -75,9 +66,6 @@ pub fn windowsIsCygwinPty(handle: windows.HANDLE) bool {
|
||||
mem.indexOf(u16, name_wide, []u16{'-','p','t','y'}) != null;
|
||||
}
|
||||
|
||||
error SharingViolation;
|
||||
error PipeBusy;
|
||||
|
||||
/// `file_path` may need to be copied in memory to add a null terminating byte. In this case
|
||||
/// a fixed size buffer of size ::max_noalloc_path_len is an attempted solution. If the fixed
|
||||
/// size buffer is too small, and the provided allocator is null, ::error.NameTooLong is returned.
|
||||
@ -120,7 +108,7 @@ pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_m
|
||||
}
|
||||
|
||||
/// Caller must free result.
|
||||
pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) %[]u8 {
|
||||
pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) ![]u8 {
|
||||
// count bytes needed
|
||||
const bytes_needed = x: {
|
||||
var bytes_needed: usize = 1; // 1 for the final null byte
|
||||
@ -151,8 +139,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap)
|
||||
return result;
|
||||
}
|
||||
|
||||
error DllNotFound;
|
||||
pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) %windows.HMODULE {
|
||||
pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) !windows.HMODULE {
|
||||
const padded_buff = try cstr.addNullByte(allocator, dll_path);
|
||||
defer allocator.free(padded_buff);
|
||||
return windows.LoadLibraryA(padded_buff.ptr) ?? error.DllNotFound;
|
||||
|
@ -1,6 +1,6 @@
|
||||
const Builder = @import("std").build.Builder;
|
||||
|
||||
pub fn build(b: &Builder) %void {
|
||||
pub fn build(b: &Builder) !void {
|
||||
const mode = b.standardReleaseOptions();
|
||||
const exe = b.addExecutable("YOUR_NAME_HERE", "src/main.zig");
|
||||
exe.setBuildMode(mode);
|
||||
|
@ -8,9 +8,7 @@ const mem = std.mem;
|
||||
const ArrayList = std.ArrayList;
|
||||
const warn = std.debug.warn;
|
||||
|
||||
error InvalidArgs;
|
||||
|
||||
pub fn main() %void {
|
||||
pub fn main() !void {
|
||||
var arg_it = os.args();
|
||||
|
||||
// TODO use a more general purpose allocator here
|
||||
@ -125,7 +123,7 @@ pub fn main() %void {
|
||||
};
|
||||
}
|
||||
|
||||
fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) %void {
|
||||
fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) !void {
|
||||
// run the build script to collect the options
|
||||
if (!already_ran_build) {
|
||||
builder.setInstallPrefix(null);
|
||||
@ -188,7 +186,7 @@ fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: &io.OutSt
|
||||
return error.InvalidArgs;
|
||||
}
|
||||
|
||||
fn unwrapArg(arg: %[]u8) %[]u8 {
|
||||
fn unwrapArg(arg: %[]u8) ![]u8 {
|
||||
return arg catch |err| {
|
||||
warn("Unable to parse command line: {}\n", err);
|
||||
return err;
|
||||
|
@ -1,11 +1,9 @@
|
||||
const std = @import("./index.zig");
|
||||
|
||||
error Utf8InvalidStartByte;
|
||||
|
||||
/// Given the first byte of a UTF-8 codepoint,
|
||||
/// returns a number 1-4 indicating the total length of the codepoint in bytes.
|
||||
/// If this byte does not match the form of a UTF-8 start byte, returns Utf8InvalidStartByte.
|
||||
pub fn utf8ByteSequenceLength(first_byte: u8) %u3 {
|
||||
pub fn utf8ByteSequenceLength(first_byte: u8) !u3 {
|
||||
if (first_byte < 0b10000000) return u3(1);
|
||||
if (first_byte & 0b11100000 == 0b11000000) return u3(2);
|
||||
if (first_byte & 0b11110000 == 0b11100000) return u3(3);
|
||||
@ -13,16 +11,11 @@ pub fn utf8ByteSequenceLength(first_byte: u8) %u3 {
|
||||
return error.Utf8InvalidStartByte;
|
||||
}
|
||||
|
||||
error Utf8OverlongEncoding;
|
||||
error Utf8ExpectedContinuation;
|
||||
error Utf8EncodesSurrogateHalf;
|
||||
error Utf8CodepointTooLarge;
|
||||
|
||||
/// Decodes the UTF-8 codepoint encoded in the given slice of bytes.
|
||||
/// bytes.len must be equal to utf8ByteSequenceLength(bytes[0]) catch unreachable.
|
||||
/// If you already know the length at comptime, you can call one of
|
||||
/// utf8Decode2,utf8Decode3,utf8Decode4 directly instead of this function.
|
||||
pub fn utf8Decode(bytes: []const u8) %u32 {
|
||||
pub fn utf8Decode(bytes: []const u8) !u32 {
|
||||
return switch (bytes.len) {
|
||||
1 => u32(bytes[0]),
|
||||
2 => utf8Decode2(bytes),
|
||||
@ -31,7 +24,7 @@ pub fn utf8Decode(bytes: []const u8) %u32 {
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
pub fn utf8Decode2(bytes: []const u8) %u32 {
|
||||
pub fn utf8Decode2(bytes: []const u8) !u32 {
|
||||
std.debug.assert(bytes.len == 2);
|
||||
std.debug.assert(bytes[0] & 0b11100000 == 0b11000000);
|
||||
var value: u32 = bytes[0] & 0b00011111;
|
||||
@ -44,7 +37,7 @@ pub fn utf8Decode2(bytes: []const u8) %u32 {
|
||||
|
||||
return value;
|
||||
}
|
||||
pub fn utf8Decode3(bytes: []const u8) %u32 {
|
||||
pub fn utf8Decode3(bytes: []const u8) !u32 {
|
||||
std.debug.assert(bytes.len == 3);
|
||||
std.debug.assert(bytes[0] & 0b11110000 == 0b11100000);
|
||||
var value: u32 = bytes[0] & 0b00001111;
|
||||
@ -62,7 +55,7 @@ pub fn utf8Decode3(bytes: []const u8) %u32 {
|
||||
|
||||
return value;
|
||||
}
|
||||
pub fn utf8Decode4(bytes: []const u8) %u32 {
|
||||
pub fn utf8Decode4(bytes: []const u8) !u32 {
|
||||
std.debug.assert(bytes.len == 4);
|
||||
std.debug.assert(bytes[0] & 0b11111000 == 0b11110000);
|
||||
var value: u32 = bytes[0] & 0b00000111;
|
||||
@ -85,7 +78,6 @@ pub fn utf8Decode4(bytes: []const u8) %u32 {
|
||||
return value;
|
||||
}
|
||||
|
||||
error UnexpectedEof;
|
||||
test "valid utf8" {
|
||||
testValid("\x00", 0x0);
|
||||
testValid("\x20", 0x20);
|
||||
@ -161,7 +153,7 @@ fn testValid(bytes: []const u8, expected_codepoint: u32) void {
|
||||
std.debug.assert((testDecode(bytes) catch unreachable) == expected_codepoint);
|
||||
}
|
||||
|
||||
fn testDecode(bytes: []const u8) %u32 {
|
||||
fn testDecode(bytes: []const u8) !u32 {
|
||||
const length = try utf8ByteSequenceLength(bytes[0]);
|
||||
if (bytes.len < length) return error.UnexpectedEof;
|
||||
std.debug.assert(bytes.len == length);
|
||||
|
@ -32,7 +32,6 @@ fn funcWithConstPtrPtr(x: &const &i32) void {
|
||||
**x += 1;
|
||||
}
|
||||
|
||||
error ItBroke;
|
||||
test "explicit cast from integer to error type" {
|
||||
testCastIntToErr(error.ItBroke);
|
||||
comptime testCastIntToErr(error.ItBroke);
|
||||
@ -110,11 +109,11 @@ test "return null from fn() %?&T" {
|
||||
const b = returnNullLitFromMaybeTypeErrorRef();
|
||||
assert((try a) == null and (try b) == null);
|
||||
}
|
||||
fn returnNullFromMaybeTypeErrorRef() %?&A {
|
||||
fn returnNullFromMaybeTypeErrorRef() !?&A {
|
||||
const a: ?&A = null;
|
||||
return a;
|
||||
}
|
||||
fn returnNullLitFromMaybeTypeErrorRef() %?&A {
|
||||
fn returnNullLitFromMaybeTypeErrorRef() !?&A {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -170,7 +169,7 @@ fn testCastZeroArrayToErrSliceMut() void {
|
||||
assert((gimmeErrOrSlice() catch unreachable).len == 0);
|
||||
}
|
||||
|
||||
fn gimmeErrOrSlice() %[]u8 {
|
||||
fn gimmeErrOrSlice() ![]u8 {
|
||||
return []u8{};
|
||||
}
|
||||
|
||||
@ -188,7 +187,7 @@ test "peer type resolution: [0]u8, []const u8, and %[]u8" {
|
||||
assert((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
|
||||
}
|
||||
}
|
||||
fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) %[]u8 {
|
||||
fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) ![]u8 {
|
||||
if (a) {
|
||||
return []u8{};
|
||||
}
|
||||
@ -238,14 +237,13 @@ test "peer type resolution: error and [N]T" {
|
||||
comptime assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
|
||||
}
|
||||
|
||||
error BadValue;
|
||||
//fn testPeerErrorAndArray(x: u8) %[]const u8 {
|
||||
//fn testPeerErrorAndArray(x: u8) ![]const u8 {
|
||||
// return switch (x) {
|
||||
// 0x00 => "OK",
|
||||
// else => error.BadValue,
|
||||
// };
|
||||
//}
|
||||
fn testPeerErrorAndArray2(x: u8) %[]const u8 {
|
||||
fn testPeerErrorAndArray2(x: u8) ![]const u8 {
|
||||
return switch (x) {
|
||||
0x00 => "OK",
|
||||
0x01 => "OKK",
|
||||
|
@ -3,9 +3,7 @@ const assert = @import("std").debug.assert;
|
||||
var result: [3]u8 = undefined;
|
||||
var index: usize = undefined;
|
||||
|
||||
error FalseNotAllowed;
|
||||
|
||||
fn runSomeErrorDefers(x: bool) %bool {
|
||||
fn runSomeErrorDefers(x: bool) !bool {
|
||||
index = 0;
|
||||
defer {result[index] = 'a'; index += 1;}
|
||||
errdefer {result[index] = 'b'; index += 1;}
|
||||
|
@ -6,7 +6,7 @@ const ET = union(enum) {
|
||||
SINT: i32,
|
||||
UINT: u32,
|
||||
|
||||
pub fn print(a: &const ET, buf: []u8) %usize {
|
||||
pub fn print(a: &const ET, buf: []u8) !usize {
|
||||
return switch (*a) {
|
||||
ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
|
||||
ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
|
||||
|
@ -1,16 +1,16 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
const mem = @import("std").mem;
|
||||
|
||||
pub fn foo() %i32 {
|
||||
pub fn foo() !i32 {
|
||||
const x = try bar();
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
pub fn bar() %i32 {
|
||||
pub fn bar() !i32 {
|
||||
return 13;
|
||||
}
|
||||
|
||||
pub fn baz() %i32 {
|
||||
pub fn baz() !i32 {
|
||||
const y = foo() catch 1234;
|
||||
return y + 1;
|
||||
}
|
||||
@ -19,7 +19,6 @@ test "error wrapping" {
|
||||
assert((baz() catch unreachable) == 15);
|
||||
}
|
||||
|
||||
error ItBroke;
|
||||
fn gimmeItBroke() []const u8 {
|
||||
return @errorName(error.ItBroke);
|
||||
}
|
||||
@ -28,8 +27,6 @@ test "@errorName" {
|
||||
assert(mem.eql(u8, @errorName(error.AnError), "AnError"));
|
||||
assert(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));
|
||||
}
|
||||
error AnError;
|
||||
error ALongerErrorName;
|
||||
|
||||
|
||||
test "error values" {
|
||||
@ -37,16 +34,11 @@ test "error values" {
|
||||
const b = i32(error.err2);
|
||||
assert(a != b);
|
||||
}
|
||||
error err1;
|
||||
error err2;
|
||||
|
||||
|
||||
test "redefinition of error values allowed" {
|
||||
shouldBeNotEqual(error.AnError, error.SecondError);
|
||||
}
|
||||
error AnError;
|
||||
error AnError;
|
||||
error SecondError;
|
||||
fn shouldBeNotEqual(a: error, b: error) void {
|
||||
if (a == b) unreachable;
|
||||
}
|
||||
@ -58,8 +50,7 @@ test "error binary operator" {
|
||||
assert(a == 3);
|
||||
assert(b == 10);
|
||||
}
|
||||
error ItBroke;
|
||||
fn errBinaryOperatorG(x: bool) %isize {
|
||||
fn errBinaryOperatorG(x: bool) !isize {
|
||||
return if (x) error.ItBroke else isize(10);
|
||||
}
|
||||
|
||||
@ -75,11 +66,11 @@ test "error return in assignment" {
|
||||
doErrReturnInAssignment() catch unreachable;
|
||||
}
|
||||
|
||||
fn doErrReturnInAssignment() %void {
|
||||
fn doErrReturnInAssignment() !void {
|
||||
var x : i32 = undefined;
|
||||
x = try makeANonErr();
|
||||
}
|
||||
|
||||
fn makeANonErr() %i32 {
|
||||
fn makeANonErr() !i32 {
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn foo(id: u64) %i32 {
|
||||
fn foo(id: u64) !i32 {
|
||||
return switch (id) {
|
||||
1 => getErrInt(),
|
||||
2 => {
|
||||
@ -13,8 +13,6 @@ fn foo(id: u64) %i32 {
|
||||
|
||||
fn getErrInt() %i32 { return 0; }
|
||||
|
||||
error ItBroke;
|
||||
|
||||
test "ir block deps" {
|
||||
assert((foo(1) catch unreachable) == 0);
|
||||
assert((foo(2) catch unreachable) == 0);
|
||||
|
@ -262,7 +262,7 @@ test "generic malloc free" {
|
||||
memFree(u8, a);
|
||||
}
|
||||
const some_mem : [100]u8 = undefined;
|
||||
fn memAlloc(comptime T: type, n: usize) %[]T {
|
||||
fn memAlloc(comptime T: type, n: usize) ![]T {
|
||||
return @ptrCast(&T, &some_mem[0])[0..n];
|
||||
}
|
||||
fn memFree(comptime T: type, memory: []T) void { }
|
||||
@ -419,7 +419,7 @@ test "cast slice to u8 slice" {
|
||||
test "pointer to void return type" {
|
||||
testPointerToVoidReturnType() catch unreachable;
|
||||
}
|
||||
fn testPointerToVoidReturnType() %void {
|
||||
fn testPointerToVoidReturnType() !void {
|
||||
const a = testPointerToVoidReturnType2();
|
||||
return *a;
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ fn switchWithUnreachable(x: i32) i32 {
|
||||
return 10;
|
||||
}
|
||||
|
||||
fn return_a_number() %i32 {
|
||||
fn return_a_number() !i32 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2,19 +2,17 @@ const assert = @import("std").debug.assert;
|
||||
|
||||
var read_count: u64 = 0;
|
||||
|
||||
fn readOnce() %u64 {
|
||||
fn readOnce() !u64 {
|
||||
read_count += 1;
|
||||
return read_count;
|
||||
}
|
||||
|
||||
error InvalidDebugInfo;
|
||||
|
||||
const FormValue = union(enum) {
|
||||
Address: u64,
|
||||
Other: bool,
|
||||
};
|
||||
|
||||
fn doThing(form_id: u64) %FormValue {
|
||||
fn doThing(form_id: u64) !FormValue {
|
||||
return switch (form_id) {
|
||||
17 => FormValue { .Address = try readOnce() },
|
||||
else => error.InvalidDebugInfo,
|
||||
|
@ -5,9 +5,7 @@ const FormValue = union(enum) {
|
||||
Two: bool,
|
||||
};
|
||||
|
||||
error Whatever;
|
||||
|
||||
fn foo(id: u64) %FormValue {
|
||||
fn foo(id: u64) !FormValue {
|
||||
return switch (id) {
|
||||
2 => FormValue { .Two = true },
|
||||
1 => FormValue { .One = {} },
|
||||
|
@ -17,10 +17,7 @@ fn tryOnErrorUnionImpl() void {
|
||||
assert(x == 11);
|
||||
}
|
||||
|
||||
error ItBroke;
|
||||
error NoMem;
|
||||
error CrappedOut;
|
||||
fn returnsTen() %i32 {
|
||||
fn returnsTen() !i32 {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@ -32,7 +29,7 @@ test "try without vars" {
|
||||
assert(result2 == 1);
|
||||
}
|
||||
|
||||
fn failIfTrue(ok: bool) %void {
|
||||
fn failIfTrue(ok: bool) !void {
|
||||
if (ok) {
|
||||
return error.ItBroke;
|
||||
} else {
|
||||
|
@ -50,7 +50,7 @@ fn runContinueAndBreakTest() void {
|
||||
test "return with implicit cast from while loop" {
|
||||
returnWithImplicitCastFromWhileLoopTest() catch unreachable;
|
||||
}
|
||||
fn returnWithImplicitCastFromWhileLoopTest() %void {
|
||||
fn returnWithImplicitCastFromWhileLoopTest() !void {
|
||||
while (true) {
|
||||
return;
|
||||
}
|
||||
@ -116,8 +116,7 @@ test "while with error union condition" {
|
||||
}
|
||||
|
||||
var numbers_left: i32 = undefined;
|
||||
error OutOfNumbers;
|
||||
fn getNumberOrErr() %i32 {
|
||||
fn getNumberOrErr() !i32 {
|
||||
return if (numbers_left == 0)
|
||||
error.OutOfNumbers
|
||||
else x: {
|
||||
@ -205,7 +204,6 @@ fn testContinueOuter() void {
|
||||
|
||||
fn returnNull() ?i32 { return null; }
|
||||
fn returnMaybe(x: i32) ?i32 { return x; }
|
||||
error YouWantedAnError;
|
||||
fn returnError() %i32 { return error.YouWantedAnError; }
|
||||
fn returnSuccess(x: i32) %i32 { return x; }
|
||||
fn returnFalse() bool { return false; }
|
||||
|
@ -15,7 +15,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\use @import("std").io;
|
||||
\\use @import("foo.zig");
|
||||
\\
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ privateFunction();
|
||||
\\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);
|
||||
\\ stdout.print("OK 2\n") catch unreachable;
|
||||
@ -49,7 +49,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\use @import("foo.zig");
|
||||
\\use @import("bar.zig");
|
||||
\\
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ foo_function();
|
||||
\\ bar_function();
|
||||
\\}
|
||||
@ -89,7 +89,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
var tc = cases.create("two files use import each other",
|
||||
\\use @import("a.zig");
|
||||
\\
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ ok();
|
||||
\\}
|
||||
, "OK\n");
|
||||
@ -118,7 +118,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
cases.add("hello world without libc",
|
||||
\\const io = @import("std").io;
|
||||
\\
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
|
||||
\\ stdout.print("Hello, world!\n{d4} {x3} {c}\n", u32(12), u16(0x12), u8('a')) catch unreachable;
|
||||
\\}
|
||||
@ -268,7 +268,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\const z = io.stdin_fileno;
|
||||
\\const x : @typeOf(y) = 1234;
|
||||
\\const y : u16 = 5678;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ var x_local : i32 = print_ok(x);
|
||||
\\}
|
||||
\\fn print_ok(val: @typeOf(x)) @typeOf(foo) {
|
||||
@ -351,7 +351,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ fn method(b: &const Bar) bool { return true; }
|
||||
\\};
|
||||
\\
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const bar = Bar {.field2 = 13,};
|
||||
\\ const foo = Foo {.field1 = bar,};
|
||||
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
|
||||
@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
|
||||
cases.add("defer with only fallthrough",
|
||||
\\const io = @import("std").io;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
|
||||
\\ stdout.print("before\n") catch unreachable;
|
||||
\\ defer stdout.print("defer1\n") catch unreachable;
|
||||
@ -380,7 +380,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
cases.add("defer with return",
|
||||
\\const io = @import("std").io;
|
||||
\\const os = @import("std").os;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
|
||||
\\ stdout.print("before\n") catch unreachable;
|
||||
\\ defer stdout.print("defer1\n") catch unreachable;
|
||||
@ -394,10 +394,10 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
|
||||
cases.add("errdefer and it fails",
|
||||
\\const io = @import("std").io;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ do_test() catch return;
|
||||
\\}
|
||||
\\fn do_test() %void {
|
||||
\\fn do_test() !void {
|
||||
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
|
||||
\\ stdout.print("before\n") catch unreachable;
|
||||
\\ defer stdout.print("defer1\n") catch unreachable;
|
||||
@ -407,17 +407,17 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ stdout.print("after\n") catch unreachable;
|
||||
\\}
|
||||
\\error IToldYouItWouldFail;
|
||||
\\fn its_gonna_fail() %void {
|
||||
\\fn its_gonna_fail() !void {
|
||||
\\ return error.IToldYouItWouldFail;
|
||||
\\}
|
||||
, "before\ndeferErr\ndefer1\n");
|
||||
|
||||
cases.add("errdefer and it passes",
|
||||
\\const io = @import("std").io;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ do_test() catch return;
|
||||
\\}
|
||||
\\fn do_test() %void {
|
||||
\\fn do_test() !void {
|
||||
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
|
||||
\\ stdout.print("before\n") catch unreachable;
|
||||
\\ defer stdout.print("defer1\n") catch unreachable;
|
||||
@ -434,7 +434,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\const foo_txt = @embedFile("foo.txt");
|
||||
\\const io = @import("std").io;
|
||||
\\
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
|
||||
\\ stdout.print(foo_txt) catch unreachable;
|
||||
\\}
|
||||
@ -452,7 +452,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\const os = std.os;
|
||||
\\const allocator = std.debug.global_allocator;
|
||||
\\
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ var args_it = os.args();
|
||||
\\ var stdout_file = try io.getStdOut();
|
||||
\\ var stdout_adapter = io.FileOutStream.init(&stdout_file);
|
||||
@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\const os = std.os;
|
||||
\\const allocator = std.debug.global_allocator;
|
||||
\\
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ var args_it = os.args();
|
||||
\\ var stdout_file = try io.getStdOut();
|
||||
\\ var stdout_adapter = io.FileOutStream.init(&stdout_file);
|
||||
|
@ -1383,7 +1383,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
|
||||
, ".tmp_source.zig:6:13: error: cannot assign to constant");
|
||||
|
||||
cases.add("return from defer expression",
|
||||
\\pub fn testTrickyDefer() %void {
|
||||
\\pub fn testTrickyDefer() !void {
|
||||
\\ defer canFail() catch {};
|
||||
\\
|
||||
\\ defer try canFail();
|
||||
@ -1970,7 +1970,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
|
||||
\\fn foo1(args: ...) void {}
|
||||
\\fn foo2(args: ...) void {}
|
||||
\\
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ foos[0]();
|
||||
\\}
|
||||
,
|
||||
@ -1982,7 +1982,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
|
||||
\\fn foo1(arg: var) void {}
|
||||
\\fn foo2(arg: var) void {}
|
||||
\\
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ foos[0](true);
|
||||
\\}
|
||||
,
|
||||
|
@ -5,7 +5,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ @panic("oh no");
|
||||
\\}
|
||||
);
|
||||
@ -14,7 +14,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const a = []i32{1, 2, 3, 4};
|
||||
\\ baz(bar(a));
|
||||
\\}
|
||||
@ -29,7 +29,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = add(65530, 10);
|
||||
\\ if (x == 0) return error.Whatever;
|
||||
\\}
|
||||
@ -43,7 +43,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = sub(10, 20);
|
||||
\\ if (x == 0) return error.Whatever;
|
||||
\\}
|
||||
@ -57,7 +57,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = mul(300, 6000);
|
||||
\\ if (x == 0) return error.Whatever;
|
||||
\\}
|
||||
@ -71,7 +71,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = neg(-32768);
|
||||
\\ if (x == 32767) return error.Whatever;
|
||||
\\}
|
||||
@ -85,7 +85,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = div(-32768, -1);
|
||||
\\ if (x == 32767) return error.Whatever;
|
||||
\\}
|
||||
@ -99,7 +99,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = shl(-16385, 1);
|
||||
\\ if (x == 0) return error.Whatever;
|
||||
\\}
|
||||
@ -113,7 +113,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = shl(0b0010111111111111, 3);
|
||||
\\ if (x == 0) return error.Whatever;
|
||||
\\}
|
||||
@ -127,7 +127,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = shr(-16385, 1);
|
||||
\\ if (x == 0) return error.Whatever;
|
||||
\\}
|
||||
@ -141,7 +141,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = shr(0b0010111111111111, 3);
|
||||
\\ if (x == 0) return error.Whatever;
|
||||
\\}
|
||||
@ -155,7 +155,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = div0(999, 0);
|
||||
\\}
|
||||
\\fn div0(a: i32, b: i32) i32 {
|
||||
@ -168,7 +168,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = divExact(10, 3);
|
||||
\\ if (x == 0) return error.Whatever;
|
||||
\\}
|
||||
@ -182,7 +182,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = widenSlice([]u8{1, 2, 3, 4, 5});
|
||||
\\ if (x.len == 0) return error.Whatever;
|
||||
\\}
|
||||
@ -196,7 +196,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = shorten_cast(200);
|
||||
\\ if (x == 0) return error.Whatever;
|
||||
\\}
|
||||
@ -210,7 +210,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ const x = unsigned_cast(-10);
|
||||
\\ if (x == 0) return error.Whatever;
|
||||
\\}
|
||||
@ -227,10 +227,10 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(0); // test failed
|
||||
\\}
|
||||
\\error Whatever;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ bar() catch unreachable;
|
||||
\\}
|
||||
\\fn bar() %void {
|
||||
\\fn bar() !void {
|
||||
\\ return error.Whatever;
|
||||
\\}
|
||||
);
|
||||
@ -239,7 +239,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ _ = bar(9999);
|
||||
\\}
|
||||
\\fn bar(x: u32) error {
|
||||
@ -252,7 +252,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ @import("std").os.exit(126);
|
||||
\\}
|
||||
\\error Wrong;
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ var array align(4) = []u32{0x11111111, 0x11111111};
|
||||
\\ const bytes = ([]u8)(array[0..]);
|
||||
\\ if (foo(bytes) != 0x11111111) return error.Wrong;
|
||||
@ -274,7 +274,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
|
||||
\\ int: u32,
|
||||
\\};
|
||||
\\
|
||||
\\pub fn main() %void {
|
||||
\\pub fn main() !void {
|
||||
\\ var f = Foo { .int = 42 };
|
||||
\\ bar(&f);
|
||||
\\}
|
||||
|
@ -1,6 +1,6 @@
|
||||
const Builder = @import("std").build.Builder;
|
||||
|
||||
pub fn build(b: &Builder) %void {
|
||||
pub fn build(b: &Builder) !void {
|
||||
const main = b.addTest("main.zig");
|
||||
main.setBuildMode(b.standardReleaseOptions());
|
||||
|
||||
|
@ -6,9 +6,6 @@ const assert = debug.assert;
|
||||
const Buffer = std.Buffer;
|
||||
const ArrayList = std.ArrayList;
|
||||
|
||||
error InvalidInput;
|
||||
error OutOfMem;
|
||||
|
||||
const Token = union(enum) {
|
||||
Word: []const u8,
|
||||
OpenBrace,
|
||||
@ -19,7 +16,7 @@ const Token = union(enum) {
|
||||
|
||||
var global_allocator: &mem.Allocator = undefined;
|
||||
|
||||
fn tokenize(input:[] const u8) %ArrayList(Token) {
|
||||
fn tokenize(input:[] const u8) !ArrayList(Token) {
|
||||
const State = enum {
|
||||
Start,
|
||||
Word,
|
||||
@ -71,7 +68,7 @@ const Node = union(enum) {
|
||||
Combine: []Node,
|
||||
};
|
||||
|
||||
fn parse(tokens: &const ArrayList(Token), token_index: &usize) %Node {
|
||||
fn parse(tokens: &const ArrayList(Token), token_index: &usize) !Node {
|
||||
const first_token = tokens.items[*token_index];
|
||||
*token_index += 1;
|
||||
|
||||
@ -107,7 +104,7 @@ fn parse(tokens: &const ArrayList(Token), token_index: &usize) %Node {
|
||||
}
|
||||
}
|
||||
|
||||
fn expandString(input: []const u8, output: &Buffer) %void {
|
||||
fn expandString(input: []const u8, output: &Buffer) !void {
|
||||
const tokens = try tokenize(input);
|
||||
if (tokens.len == 1) {
|
||||
return output.resize(0);
|
||||
@ -135,7 +132,7 @@ fn expandString(input: []const u8, output: &Buffer) %void {
|
||||
}
|
||||
}
|
||||
|
||||
fn expandNode(node: &const Node, output: &ArrayList(Buffer)) %void {
|
||||
fn expandNode(node: &const Node, output: &ArrayList(Buffer)) !void {
|
||||
assert(output.len == 0);
|
||||
switch (*node) {
|
||||
Node.Scalar => |scalar| {
|
||||
@ -172,7 +169,7 @@ fn expandNode(node: &const Node, output: &ArrayList(Buffer)) %void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() %void {
|
||||
pub fn main() !void {
|
||||
var stdin_file = try io.getStdIn();
|
||||
var stdout_file = try io.getStdOut();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
const Builder = @import("std").build.Builder;
|
||||
|
||||
pub fn build(b: &Builder) %void {
|
||||
pub fn build(b: &Builder) !void {
|
||||
const obj = b.addObject("test", "test.zig");
|
||||
|
||||
const test_step = b.step("test", "Test the program");
|
||||
|
@ -1,6 +1,6 @@
|
||||
const Builder = @import("std").build.Builder;
|
||||
|
||||
pub fn build(b: &Builder) %void {
|
||||
pub fn build(b: &Builder) !void {
|
||||
const exe = b.addExecutable("test", "test.zig");
|
||||
exe.addPackagePath("my_pkg", "pkg.zig");
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
const my_pkg = @import("my_pkg");
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
pub fn main() %void {
|
||||
pub fn main() !void {
|
||||
assert(my_pkg.add(10, 20) == 30);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
const Builder = @import("std").build.Builder;
|
||||
|
||||
pub fn build(b: &Builder) %void {
|
||||
pub fn build(b: &Builder) !void {
|
||||
b.addCIncludePath(".");
|
||||
|
||||
const main = b.addTest("main.zig");
|
||||
|
@ -45,9 +45,6 @@ const test_targets = []TestTarget {
|
||||
},
|
||||
};
|
||||
|
||||
error TestFailed;
|
||||
error CompilationIncorrectlySucceeded;
|
||||
|
||||
const max_stdout_size = 1 * 1024 * 1024; // 1 MB
|
||||
|
||||
pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
|
||||
@ -248,7 +245,7 @@ pub const CompareOutputContext = struct {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
fn make(step: &build.Step) %void {
|
||||
fn make(step: &build.Step) !void {
|
||||
const self = @fieldParentPtr(RunCompareOutputStep, "step", step);
|
||||
const b = self.context.b;
|
||||
|
||||
@ -337,7 +334,7 @@ pub const CompareOutputContext = struct {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
fn make(step: &build.Step) %void {
|
||||
fn make(step: &build.Step) !void {
|
||||
const self = @fieldParentPtr(RuntimeSafetyRunStep, "step", step);
|
||||
const b = self.context.b;
|
||||
|
||||
@ -563,7 +560,7 @@ pub const CompileErrorContext = struct {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
fn make(step: &build.Step) %void {
|
||||
fn make(step: &build.Step) !void {
|
||||
const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);
|
||||
const b = self.context.b;
|
||||
|
||||
@ -847,7 +844,7 @@ pub const TranslateCContext = struct {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
fn make(step: &build.Step) %void {
|
||||
fn make(step: &build.Step) !void {
|
||||
const self = @fieldParentPtr(TranslateCCmpOutputStep, "step", step);
|
||||
const b = self.context.b;
|
||||
|
||||
@ -1045,7 +1042,7 @@ pub const GenHContext = struct {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
fn make(step: &build.Step) %void {
|
||||
fn make(step: &build.Step) !void {
|
||||
const self = @fieldParentPtr(GenHCmpOutputStep, "step", step);
|
||||
const b = self.context.b;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user