diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-02-08 02:08:45 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-02-08 02:08:45 -0500 |
| commit | 0d5ff6f4622a492dddbb1fc2b19b3157237500b1 (patch) | |
| tree | 4a707f626dc12adeeed3438b5966876c6b401ea0 /std | |
| parent | 68238d5678a4c055bb6f1206254dcac2e0c634f0 (diff) | |
| download | zig-0d5ff6f4622a492dddbb1fc2b19b3157237500b1.tar.gz zig-0d5ff6f4622a492dddbb1fc2b19b3157237500b1.zip | |
error sets - most tests passing
Diffstat (limited to 'std')
| -rw-r--r-- | std/build.zig | 8 | ||||
| -rw-r--r-- | std/fmt/index.zig | 2 | ||||
| -rw-r--r-- | std/io.zig | 4 | ||||
| -rw-r--r-- | std/os/child_process.zig | 21 | ||||
| -rw-r--r-- | std/os/index.zig | 99 | ||||
| -rw-r--r-- | std/os/windows/util.zig | 3 | ||||
| -rw-r--r-- | std/special/bootstrap.zig | 4 | ||||
| -rw-r--r-- | std/special/build_runner.zig | 25 |
8 files changed, 127 insertions, 39 deletions
diff --git a/std/build.zig b/std/build.zig index 216699f355..ee1990a349 100644 --- a/std/build.zig +++ b/std/build.zig @@ -271,7 +271,7 @@ pub const Builder = struct { return &self.uninstall_tls.step; } - fn makeUninstall(uninstall_step: &Step) !void { + fn makeUninstall(uninstall_step: &Step) error!void { const uninstall_tls = @fieldParentPtr(TopLevelStep, "step", uninstall_step); const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls); @@ -285,7 +285,7 @@ pub const Builder = struct { // TODO remove empty directories } - fn makeOneStep(self: &Builder, s: &Step) !void { + fn makeOneStep(self: &Builder, s: &Step) error!void { if (s.loop_flag) { warn("Dependency loop detected:\n {}\n", s.name); return error.DependencyLoopDetected; @@ -1910,7 +1910,7 @@ pub const LogStep = struct { }; } - fn make(step: &Step) !void { + fn make(step: &Step) error!void { const self = @fieldParentPtr(LogStep, "step", step); warn("{}", self.data); } @@ -1972,7 +1972,7 @@ pub const Step = struct { self.dependencies.append(other) catch unreachable; } - fn makeNoOp(self: &Step) (error{}!void) {} + fn makeNoOp(self: &Step) error!void {} }; fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_major_only: []const u8, diff --git a/std/fmt/index.zig b/std/fmt/index.zig index 407ffd901b..98f8d3d26b 100644 --- a/std/fmt/index.zig +++ b/std/fmt/index.zig @@ -510,7 +510,7 @@ pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ... return bufPrint(buf, fmt, args); } -fn countSize(size: &usize, bytes: []const u8) !void { +fn countSize(size: &usize, bytes: []const u8) (error{}!void) { *size += bytes.len; } diff --git a/std/io.zig b/std/io.zig index 842c30a0e4..9f16c5f496 100644 --- a/std/io.zig +++ b/std/io.zig @@ -694,13 +694,13 @@ pub const BufferOutStream = struct { pub fn init(buffer: &Buffer) BufferOutStream { return BufferOutStream { .buffer = buffer, - .stream = OutStream { + .stream = Stream { .writeFn = writeFn, }, }; } - fn writeFn(out_stream: &OutStream, bytes: []const u8) !void { + fn writeFn(out_stream: &Stream, bytes: []const u8) !void { const self = @fieldParentPtr(BufferOutStream, "stream", out_stream); return self.buffer.append(bytes); } diff --git a/std/os/child_process.zig b/std/os/child_process.zig index 360a1bfb93..1b7639fb71 100644 --- a/std/os/child_process.zig +++ b/std/os/child_process.zig @@ -55,7 +55,22 @@ pub const ChildProcess = struct { llnode: if (is_windows) void else LinkedList(&ChildProcess).Node, pub const SpawnError = error { - + ProcessFdQuotaExceeded, + Unexpected, + NotDir, + SystemResources, + FileNotFound, + NameTooLong, + SymLinkLoop, + FileSystem, + OutOfMemory, + AccessDenied, + PermissionDenied, + InvalidUserId, + ResourceLimitReached, + InvalidExe, + IsDir, + FileBusy, }; pub const Term = union(enum) { @@ -313,7 +328,7 @@ pub const ChildProcess = struct { // Here we potentially return the fork child's error // from the parent pid. if (err_int != @maxValue(ErrInt)) { - return error(err_int); + return SpawnError(err_int); } return statusToTerm(status); @@ -757,7 +772,7 @@ fn destroyPipe(pipe: &const [2]i32) void { // Child of fork calls this to report an error to the fork parent. // Then the child exits. -fn forkChildErrReport(fd: i32, err: error) noreturn { +fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { _ = writeIntFd(fd, ErrInt(err)); posix.exit(1); } diff --git a/std/os/index.zig b/std/os/index.zig index 33707676bb..c5191c8d74 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -243,7 +243,6 @@ pub const PosixOpenError = error { SystemResources, NoSpaceLeft, NotDir, - AccessDenied, PathAlreadyExists, Unexpected, }; @@ -411,7 +410,19 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, return posixExecveErrnoToErr(err); } -fn posixExecveErrnoToErr(err: usize) error { +pub const PosixExecveError = error { + SystemResources, + AccessDenied, + InvalidExe, + FileSystem, + IsDir, + FileNotFound, + NotDir, + FileBusy, + Unexpected, +}; + +fn posixExecveErrnoToErr(err: usize) PosixExecveError { assert(err > 0); return switch (err) { posix.EFAULT => unreachable, @@ -904,24 +915,68 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) !void { /// removes it. If it cannot be removed because it is a non-empty directory, /// this function recursively removes its entries and then tries again. // TODO non-recursive implementation -pub fn deleteTree(allocator: &Allocator, full_path: []const u8) !void { +const DeleteTreeError = error { + OutOfMemory, + AccessDenied, + FileTooBig, + IsDir, + SymLinkLoop, + ProcessFdQuotaExceeded, + NameTooLong, + SystemFdQuotaExceeded, + NoDevice, + PathNotFound, + SystemResources, + NoSpaceLeft, + PathAlreadyExists, + ReadOnlyFileSystem, + NotDir, + FileNotFound, + FileSystem, + FileBusy, + DirNotEmpty, + Unexpected, +}; +pub fn deleteTree(allocator: &Allocator, full_path: []const u8) DeleteTreeError!void { start_over: while (true) { // First, try deleting the item as a file. This way we don't follow sym links. if (deleteFile(allocator, full_path)) { return; - } else |err| { - if (err == error.FileNotFound) - return; - if (err != error.IsDir) - return err; + } else |err| switch (err) { + error.FileNotFound => return, + error.IsDir => {}, + + error.OutOfMemory, + error.AccessDenied, + error.SymLinkLoop, + error.NameTooLong, + error.SystemResources, + error.ReadOnlyFileSystem, + error.NotDir, + error.FileSystem, + error.FileBusy, + error.Unexpected + => return err, } { - var dir = Dir.open(allocator, full_path) catch |err| { - if (err == error.FileNotFound) - return; - if (err == error.NotDir) - continue :start_over; - return err; + var dir = Dir.open(allocator, full_path) catch |err| switch (err) { + error.NotDir => continue :start_over, + + error.OutOfMemory, + error.AccessDenied, + error.FileTooBig, + error.IsDir, + error.SymLinkLoop, + error.ProcessFdQuotaExceeded, + error.NameTooLong, + error.SystemFdQuotaExceeded, + error.NoDevice, + error.PathNotFound, + error.SystemResources, + error.NoSpaceLeft, + error.PathAlreadyExists, + error.Unexpected + => return err, }; defer dir.close(); @@ -1252,6 +1307,8 @@ pub const ArgIteratorWindows = struct { quote_count: usize, seen_quote_count: usize, + pub const NextError = error{OutOfMemory}; + pub fn init() ArgIteratorWindows { return initWithCmdLine(windows.GetCommandLineA()); } @@ -1267,7 +1324,7 @@ pub const ArgIteratorWindows = struct { } /// You must free the returned memory when done. - pub fn next(self: &ArgIteratorWindows, allocator: &Allocator) ?(@typeOf(internalNext).ReturnType.ErrorSet![]u8) { + pub fn next(self: &ArgIteratorWindows, allocator: &Allocator) ?(NextError![]u8) { // march forward over whitespace while (true) : (self.index += 1) { const byte = self.cmd_line[self.index]; @@ -1320,7 +1377,7 @@ pub const ArgIteratorWindows = struct { } } - fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) ![]u8 { + fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) NextError![]u8 { var buf = try Buffer.initSize(allocator, 0); defer buf.deinit(); @@ -1394,16 +1451,20 @@ pub const ArgIteratorWindows = struct { }; pub const ArgIterator = struct { - inner: if (builtin.os == Os.windows) ArgIteratorWindows else ArgIteratorPosix, + const InnerType = if (builtin.os == Os.windows) ArgIteratorWindows else ArgIteratorPosix; + + inner: InnerType, pub fn init() ArgIterator { return ArgIterator { - .inner = if (builtin.os == Os.windows) ArgIteratorWindows.init() else ArgIteratorPosix.init(), + .inner = InnerType.init(), }; } + + pub const NextError = ArgIteratorWindows.NextError; /// You must free the returned memory when done. - pub fn next(self: &ArgIterator, allocator: &Allocator) ?![]u8 { + pub fn next(self: &ArgIterator, allocator: &Allocator) ?(NextError![]u8) { if (builtin.os == Os.windows) { return self.inner.next(allocator); } else { diff --git a/std/os/windows/util.zig b/std/os/windows/util.zig index 2569763489..e2d7c14149 100644 --- a/std/os/windows/util.zig +++ b/std/os/windows/util.zig @@ -30,7 +30,6 @@ pub fn windowsClose(handle: windows.HANDLE) void { pub const WriteError = error { SystemResources, OperationAborted, - SystemResources, IoPending, BrokenPipe, Unexpected, @@ -83,6 +82,8 @@ pub const OpenError = error { AccessDenied, PipeBusy, Unexpected, + OutOfMemory, + NameTooLong, }; /// `file_path` may need to be copied in memory to add a null terminating byte. In this case diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig index bcb3456353..f5754638b0 100644 --- a/std/special/bootstrap.zig +++ b/std/special/bootstrap.zig @@ -77,7 +77,7 @@ fn callMain() u8 { }, builtin.TypeId.Int => { if (@typeOf(root.main).ReturnType.bit_count != 8) { - @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '%void'"); + @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"); } return root.main(); }, @@ -91,6 +91,6 @@ fn callMain() u8 { }; return 0; }, - else => @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '%void'"), + else => @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"), } } diff --git a/std/special/build_runner.zig b/std/special/build_runner.zig index 198199b941..0661d26a98 100644 --- a/std/special/build_runner.zig +++ b/std/special/build_runner.zig @@ -1,5 +1,6 @@ const root = @import("@build"); const std = @import("std"); +const builtin = @import("builtin"); const io = std.io; const fmt = std.fmt; const os = std.os; @@ -43,14 +44,14 @@ pub fn main() !void { var stderr_file = io.getStdErr(); var stderr_file_stream: io.FileOutStream = undefined; - var stderr_stream: %&io.OutStream = if (stderr_file) |*f| x: { + var stderr_stream = if (stderr_file) |*f| x: { stderr_file_stream = io.FileOutStream.init(f); break :x &stderr_file_stream.stream; } else |err| err; var stdout_file = io.getStdOut(); var stdout_file_stream: io.FileOutStream = undefined; - var stdout_stream: %&io.OutStream = if (stdout_file) |*f| x: { + var stdout_stream = if (stdout_file) |*f| x: { stdout_file_stream = io.FileOutStream.init(f); break :x &stdout_file_stream.stream; } else |err| err; @@ -110,7 +111,7 @@ pub fn main() !void { } builder.setInstallPrefix(prefix); - try root.build(&builder); + try runBuild(&builder); if (builder.validateUserInputDidItFail()) return usageAndErr(&builder, true, try stderr_stream); @@ -123,11 +124,19 @@ pub fn main() !void { }; } -fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) !void { +fn runBuild(builder: &Builder) error!void { + switch (@typeId(@typeOf(root.build).ReturnType)) { + builtin.TypeId.Void => root.build(builder), + builtin.TypeId.ErrorUnion => try root.build(builder), + else => @compileError("expected return type of build to be 'void' or '!void'"), + } +} + +fn usage(builder: &Builder, already_ran_build: bool, out_stream: var) !void { // run the build script to collect the options if (!already_ran_build) { builder.setInstallPrefix(null); - try root.build(builder); + try runBuild(builder); } // This usage text has to be synchronized with src/main.cpp @@ -181,12 +190,14 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) ); } -fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) error { +fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: var) error { usage(builder, already_ran_build, out_stream) catch {}; return error.InvalidArgs; } -fn unwrapArg(arg: %[]u8) ![]u8 { +const UnwrapArgError = error {OutOfMemory}; + +fn unwrapArg(arg: UnwrapArgError![]u8) UnwrapArgError![]u8 { return arg catch |err| { warn("Unable to parse command line: {}\n", err); return err; |
