hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit eabd5cd08462c5731fa5156d8e58c664ff671df2
parent 10f02df0935ff377ab4db8f3a344e999d92a39ff
Author: Alexey Yerin <yyp@disroot.org>
Date:   Wed, 10 Apr 2024 20:31:54 +0300

all: Use optional parameters for flags

Signed-off-by: Alexey Yerin <yyp@disroot.org>

Diffstat:
Mfnmatch/+test.ha | 6+++++-
Mfnmatch/fnmatch.ha | 12++++--------
Mfs/fs.ha | 34++++++++++++++++------------------
Mfs/types.ha | 8++++----
Mglob/glob.ha | 8++------
Mhare/lex/+test.ha | 8++++----
Mhare/lex/lex.ha | 12++++++------
Mnet/+freebsd.ha | 11+++--------
Mnet/+linux.ha | 11+++--------
Mnet/+openbsd.ha | 11+++--------
Mnet/tcp/listener.ha | 4++--
Mnet/unix/listener.ha | 4++--
Mnet/unix/socketpair.ha | 11+++--------
Mos/+freebsd/dirfdfs.ha | 29+++++++++--------------------
Mos/+linux/dirfdfs.ha | 59++++++++++++++++++++++++-----------------------------------
Mos/+openbsd/dirfdfs.ha | 29+++++++++--------------------
Mos/os.ha | 14+++++---------
Munix/+freebsd/pipe.ha | 10+++-------
Munix/+linux/pipe.ha | 10+++-------
Munix/+openbsd/pipe.ha | 10+++-------
Mwordexp/+test.ha | 2+-
Mwordexp/wordexp.ha | 2+-
22 files changed, 115 insertions(+), 190 deletions(-)

diff --git a/fnmatch/+test.ha b/fnmatch/+test.ha @@ -186,7 +186,11 @@ const testcases: [_]testcase = [ @test fn fnmatch() void = { for (let tc .. testcases) { - assert(fnmatch(tc.0, tc.1, tc.3...) == tc.2); + let flags = flag::NONE; + for (let fl .. tc.3) { + flags |= fl; + }; + assert(fnmatch(tc.0, tc.1, flags) == tc.2); }; }; diff --git a/fnmatch/fnmatch.ha b/fnmatch/fnmatch.ha @@ -43,15 +43,11 @@ type token = (rune | bracket | star | question | end); // // A set of flags that alter the matching behavior may be passed to // [[fnmatch]]. For an explanation of their meaning, see [[flag]]. -export fn fnmatch(pattern: str, string: str, flags: flag...) bool = { - let fl: flag = 0; - for (let flag .. flags) { - fl |= flag; - }; - let b = if (fl & flag::PATHNAME != 0) { - yield fnmatch_pathname(pattern, string, fl); +export fn fnmatch(pattern: str, string: str, flags: flag = flag::NONE) bool = { + let b = if (flags & flag::PATHNAME != 0) { + yield fnmatch_pathname(pattern, string, flags); } else { - yield fnmatch_internal(pattern, string, fl); + yield fnmatch_internal(pattern, string, flags); }; return b is bool && b: bool; }; diff --git a/fs/fs.ha b/fs/fs.ha @@ -17,16 +17,18 @@ export fn close(fs: *fs) void = { // Opens a file. // -// If no flags are provided, [[flag::RDONLY]] is used when opening the file. -// // [[flag::CREATE]] isn't very useful with this function, since the new file's // mode is set to zero. For this use-case, use [[create]] instead. -export fn open(fs: *fs, path: str, flags: flag...) (io::handle | error) = { +export fn open( + fs: *fs, + path: str, + flags: flag = flag::RDONLY, +) (io::handle | error) = { match (fs.open) { case null => return errors::unsupported; case let f: *openfunc => - return f(fs, path, flags...); + return f(fs, path, flags); }; }; @@ -34,35 +36,34 @@ export fn open(fs: *fs, path: str, flags: flag...) (io::handle | error) = { // handle on the host operating system, which may not be possible with all // filesystem implementations (such cases will return [[io::unsupported]]). // -// If no flags are provided, [[flag::RDONLY]] is used when opening the file. -// // [[flag::CREATE]] isn't very useful with this function, since the new file's // mode is set to zero. For this use-case, use [[create_file]] instead. -export fn open_file(fs: *fs, path: str, flags: flag...) (io::file | error) = { +export fn open_file( + fs: *fs, + path: str, + flags: flag = flag::RDONLY, +) (io::file | error) = { match (fs.openfile) { case null => return errors::unsupported; case let f: *openfilefunc => - return f(fs, path, flags...); + return f(fs, path, flags); }; }; // Creates a new file with the given mode if it doesn't already exist, and opens // it for writing. -// -// If no flags are provided, [[flag::WRONLY]] and [[flag::TRUNC]] are used when -// opening the file. export fn create( fs: *fs, path: str, mode: mode, - flags: flag... + flags: flag = flag::WRONLY | flag::TRUNC, ) (io::handle | error) = { match (fs.create) { case null => return errors::unsupported; case let f: *createfunc => - return f(fs, path, mode, flags...); + return f(fs, path, mode, flags); }; }; @@ -70,20 +71,17 @@ export fn create( // it as an [[io::file]] for writing. This file will be backed by an open file // handle on the host operating system, which may not be possible with all // filesystem implementations (such cases will return [[io::unsupported]]). -// -// If no flags are provided, [[flag::WRONLY]] and [[flag::TRUNC]] are used when -// opening the file. export fn create_file( fs: *fs, path: str, mode: mode, - flags: flag... + flags: flag = flag::WRONLY | flag::TRUNC, ) (io::file | error) = { match (fs.createfile) { case null => return errors::unsupported; case let f: *createfilefunc => - return f(fs, path, mode, flags...); + return f(fs, path, mode, flags); }; }; diff --git a/fs/types.ha b/fs/types.ha @@ -222,27 +222,27 @@ export type symlinkfunc = fn(fs: *fs, target: str, path: str) (void | error); export type openfunc = fn( fs: *fs, path: str, - flags: flag... + flags: flag, ) (io::handle | error); export type openfilefunc = fn( fs: *fs, path: str, - flags: flag... + flags: flag, ) (io::file | error); export type createfunc = fn( fs: *fs, path: str, mode: mode, - flags: flag... + flags: flag, ) (io::handle | error); export type createfilefunc = fn( fs: *fs, path: str, mode: mode, - flags: flag... + flags: flag, ) (io::file | error); // An abstract implementation of a filesystem, which provides common filesystem diff --git a/glob/glob.ha b/glob/glob.ha @@ -64,17 +64,13 @@ export fn strerror(err: failure) str = { // Returns a generator of pathnames matching a pattern. The result must be // freed using [[finish]]. -export fn glob(pattern: str, flags: flag...) generator = { +export fn glob(pattern: str, flags: flag = flag::NONE) generator = { let ss = strstack_init(); memio::concat(strstack_push(&ss), pattern)!; - let bs = flag::NONE; - for (let flag .. flags) { - bs |= flag; - }; return generator { pats = ss, matc = 0, - flgs = bs, + flgs = flags, tmpp = pattern_init(), }; }; diff --git a/hare/lex/+test.ha b/hare/lex/+test.ha @@ -7,7 +7,7 @@ use io; use memio; use strings; -fn initbuf(in: []u8, flags: flag...) lexer = { +fn initbuf(in: []u8, flags: flag = flag::NONE) lexer = { static let buf: [256]u8 = [0...]; static let s = memio::stream { stream = null: io::stream, @@ -21,11 +21,11 @@ fn initbuf(in: []u8, flags: flag...) lexer = { s = memio::fixed(in); sc = bufio::newscanner_static(&s, buf); - return init(&sc, "<test>", flags...); + return init(&sc, "<test>", flags); }; -fn initstr(in: str, flags: flag...) lexer = { - return initbuf(strings::toutf8(in), flags...); +fn initstr(in: str, flags: flag = flag::NONE) lexer = { + return initbuf(strings::toutf8(in), flags); }; @test fn unlex() void = { diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha @@ -55,11 +55,11 @@ export fn strerror(err: error) const str = { // Initializes a new lexer for the given [[bufio::scanner]]. The path is // borrowed. -export fn init(in: *bufio::scanner, path: str, flags: flag...) lexer = { - let f = flag::NONE; - for (let i = 0z; i < len(flags); i += 1) { - f |= flags[i]; - }; +export fn init( + in: *bufio::scanner, + path: str, + flags: flag = flag::NONE, +) lexer = { const loc = location { path = path, line = 1, col = 1 }; return lexer { in = in, @@ -68,7 +68,7 @@ export fn init(in: *bufio::scanner, path: str, flags: flag...) lexer = { prevrloc = (1, 1), un = (ltok::EOF, void, loc), prevunlocs = [((1, 1), (1, 1))...], - flags = f, + flags = flags, ... }; }; diff --git a/net/+freebsd.ha b/net/+freebsd.ha @@ -19,14 +19,9 @@ export type sockflag = enum int { // Accepts the next connection from a socket. Blocks until a new connection is // available. Optionally accepts NOCLOEXEC and NONBLOCK flags. If flags are // supplied, the [[io::file]] returned will have the supplied flags set. -export fn accept(sock: socket, flags: sockflag...) (socket | error) = { - // Apply any supplied flags - let f = 0i; - for (let i = 0z; i < len(flags); i += 1) { - f |= flags[i]; - }; - f ^= rt::SOCK_CLOEXEC; // invert CLOEXEC - const fd = match (rt::accept4(sock, null, null, f)) { +export fn accept(sock: socket, flags: sockflag = 0) (socket | error) = { + flags ^= rt::SOCK_CLOEXEC: sockflag; // invert CLOEXEC + const fd = match (rt::accept4(sock, null, null, flags)) { case let err: rt::errno => return errors::errno(err); case let fd: int => diff --git a/net/+linux.ha b/net/+linux.ha @@ -19,14 +19,9 @@ export type sockflag = enum int { // Accepts the next connection from a socket. Blocks until a new connection is // available. Optionally accepts NOCLOEXEC and NONBLOCK flags. If flags are // supplied, the [[io::file]] returned will have the supplied flags set. -export fn accept(sock: socket, flags: sockflag...) (socket | error) = { - // Apply any supplied flags - let f = 0i; - for (let i = 0z; i < len(flags); i += 1) { - f |= flags[i]; - }; - f ^= rt::SOCK_CLOEXEC; // invert CLOEXEC - const fd = match (rt::accept4(sock, null, null, f: int)) { +export fn accept(sock: socket, flags: sockflag = 0) (socket | error) = { + flags ^= rt::SOCK_CLOEXEC: sockflag; // invert CLOEXEC + const fd = match (rt::accept4(sock, null, null, flags)) { case let err: rt::errno => return errors::errno(err); case let fd: int => diff --git a/net/+openbsd.ha b/net/+openbsd.ha @@ -19,14 +19,9 @@ export type sockflag = enum int { // Accepts the next connection from a socket. Blocks until a new connection is // available. Optionally accepts NOCLOEXEC and NONBLOCK flags. If flags are // supplied, the [[io::file]] returned will have the supplied flags set. -export fn accept(sock: socket, flags: sockflag...) (socket | error) = { - // Apply any supplied flags - let f = 0i; - for (let i = 0z; i < len(flags); i += 1) { - f |= flags[i]; - }; - f ^= rt::SOCK_CLOEXEC; // invert CLOEXEC - const fd = match (rt::accept4(sock, null, null, f: int)) { +export fn accept(sock: socket, flags: sockflag = 0) (socket | error) = { + flags ^= rt::SOCK_CLOEXEC: sockflag; // invert CLOEXEC + const fd = match (rt::accept4(sock, null, null, flags)) { case let err: rt::errno => return errors::errno(err); case let fd: int => diff --git a/net/tcp/listener.ha b/net/tcp/listener.ha @@ -7,5 +7,5 @@ use net; // available. This is a convenience wrapper around [[net::accept]]. export fn accept( sock: net::socket, - flags: net::sockflag... -) (net::socket | net::error) = net::accept(sock, flags...); + flags: net::sockflag, +) (net::socket | net::error) = net::accept(sock, flags); diff --git a/net/unix/listener.ha b/net/unix/listener.ha @@ -7,5 +7,5 @@ use net; // available. This is a convenience wrapper around [[net::accept]]. export fn accept( sock: net::socket, - flags: net::sockflag... -) (net::socket | net::error) = net::accept(sock, flags...); + flags: net::sockflag, +) (net::socket | net::error) = net::accept(sock, flags); diff --git a/net/unix/socketpair.ha b/net/unix/socketpair.ha @@ -8,15 +8,10 @@ use rt; // A thin wrapper around socketpair(2) that presumes [[rt::AF_UNIX]] for the // domain and returns an unnamed pair of sockets of type [[rt::SOCK_STREAM]]. -export fn socketpair(flags: net::sockflag...) ((net::socket, net::socket) | net::error) = { +export fn socketpair(flags: net::sockflag = 0) ((net::socket, net::socket) | net::error) = { let sv: [2]int = [0...]; - // Apply any supplied flags - let f = 0i; - for (let i = 0z; i < len(flags); i += 1) { - f |= flags[i]; - }; - f ^= rt::SOCK_CLOEXEC; // invert CLOEXEC - match (rt::socketpair(rt::AF_UNIX: int, (rt::SOCK_STREAM | f): int, 0, &sv)) { + flags ^= rt::SOCK_CLOEXEC: net::sockflag; // invert CLOEXEC + match (rt::socketpair(rt::AF_UNIX: int, rt::SOCK_STREAM | flags, 0, &sv)) { case let err: rt::errno => return errors::errno(err); case => diff --git a/os/+freebsd/dirfdfs.ha b/os/+freebsd/dirfdfs.ha @@ -165,45 +165,34 @@ fn fsflags_to_bsd(flags: fs::flag) (int | errors::unsupported) = { fn fs_open_file( fs: *fs::fs, path: str, - flags: fs::flag... + flags: fs::flag, ) (io::file | fs::error) = { - let oflags = fs::flag::RDONLY; - for (let flag .. flags) { - oflags |= flag; - }; - return _fs_open(fs, path, fsflags_to_bsd(oflags)?, 0); + return _fs_open(fs, path, fsflags_to_bsd(flags)?, 0); }; fn fs_open( fs: *fs::fs, path: str, - flags: fs::flag... -) (io::handle | fs::error) = fs_open_file(fs, path, flags...)?; + flags: fs::flag, +) (io::handle | fs::error) = fs_open_file(fs, path, flags)?; fn fs_create_file( fs: *fs::fs, path: str, mode: fs::mode, - flags: fs::flag... + flags: fs::flag, ) (io::file | fs::error) = { - let oflags: fs::flag = 0; - if (len(flags) == 0z) { - oflags |= fs::flag::WRONLY | fs::flag::TRUNC; - }; - for (let flag .. flags) { - oflags |= flag; - }; - oflags |= fs::flag::CREATE; - return _fs_open(fs, path, fsflags_to_bsd(oflags)?, mode)?; + flags |= fs::flag::CREATE; + return _fs_open(fs, path, fsflags_to_bsd(flags)?, mode)?; }; fn fs_create( fs: *fs::fs, path: str, mode: fs::mode, - flags: fs::flag... + flags: fs::flag, ) (io::handle | fs::error) = { - return fs_create_file(fs, path, mode, flags...)?; + return fs_create_file(fs, path, mode, flags)?; }; fn fs_remove(fs: *fs::fs, path: str) (void | fs::error) = { diff --git a/os/+linux/dirfdfs.ha b/os/+linux/dirfdfs.ha @@ -49,13 +49,12 @@ type os_filesystem = struct { // Opens a file descriptor as an [[fs::fs]]. This file descriptor must be a // directory file. The file will be closed when the fs is closed. -export fn dirfdopen(fd: io::file, resolve_flags: resolve_flag...) *fs::fs = { - let ofs = alloc(os_filesystem { ... }); +export fn dirfdopen( + fd: io::file, + resolve_flags: resolve_flag = resolve_flag::NORMAL, +) *fs::fs = { + let ofs = alloc(os_filesystem { resolve = resolve_flags, ... }); let fs = static_dirfdopen(fd, ofs); - - for (let flag .. resolve_flags) { - ofs.resolve |= flag; - }; fs.close = &fs_close; return fs; }; @@ -95,13 +94,14 @@ fn static_dirfdopen(fd: io::file, filesystem: *os_filesystem) *fs::fs = { // Clones a dirfd filesystem, optionally adding additional [[resolve_flag]] // constraints. -export fn dirfs_clone(fs: *fs::fs, resolve_flags: resolve_flag...) *fs::fs = { +export fn dirfs_clone( + fs: *fs::fs, + resolve_flags: resolve_flag = resolve_flag::NORMAL, +) *fs::fs = { assert(fs.open == &fs_open); let fs = fs: *os_filesystem; let new = alloc(*fs); - for (let flag .. resolve_flags) { - fs.resolve |= flag; - }; + fs.resolve |= resolve_flags; new.dirfd = rt::fcntl(new.dirfd, rt::F_DUPFD_CLOEXEC, 0) as int; return &new.fs; }; @@ -167,22 +167,18 @@ fn _fs_open( fn fs_open_file( fs: *fs::fs, path: str, - flags: fs::flag... + flags: fs::flag, ) (io::file | fs::error) = { - let oflags = fs::flag::RDONLY: int; - for (let flag .. flags) { - oflags |= flag: int; - }; - oflags ^= fs::flag::CTTY | fs::flag::NOCLOEXEC; // invert NOCTTY/CLOEXEC + flags ^= fs::flag::CTTY | fs::flag::NOCLOEXEC; // invert NOCTTY/CLOEXEC - if ((oflags: fs::flag & fs::flag::DIRECTORY) == fs::flag::DIRECTORY) { + if ((flags & fs::flag::DIRECTORY) == fs::flag::DIRECTORY) { // This is arch-specific - oflags &= ~fs::flag::DIRECTORY: int; - oflags |= rt::O_DIRECTORY: int; + flags &= ~fs::flag::DIRECTORY; + flags |= rt::O_DIRECTORY: fs::flag; }; let oh = rt::open_how { - flags = oflags: u64, + flags = flags: u64, ... }; return _fs_open(fs, path, &oh); @@ -191,27 +187,20 @@ fn fs_open_file( fn fs_open( fs: *fs::fs, path: str, - flags: fs::flag... -) (io::handle | fs::error) = fs_open_file(fs, path, flags...)?; + flags: fs::flag, +) (io::handle | fs::error) = fs_open_file(fs, path, flags)?; fn fs_create_file( fs: *fs::fs, path: str, mode: fs::mode, - flags: fs::flag... + flags: fs::flag, ) (io::file | fs::error) = { - let oflags = 0; - if (len(flags) == 0) { - oflags |= fs::flag::WRONLY | fs::flag::TRUNC; - }; - for (let flag .. flags) { - oflags |= flag: int; - }; - oflags ^= fs::flag::CTTY | fs::flag::NOCLOEXEC; // invert NOCTTY/CLOEXEC - oflags |= fs::flag::CREATE: int; + flags ^= fs::flag::CTTY | fs::flag::NOCLOEXEC; // invert NOCTTY/CLOEXEC + flags |= fs::flag::CREATE; let oh = rt::open_how { - flags = oflags: u64, + flags = flags: u64, mode = mode: u64, ... }; @@ -222,9 +211,9 @@ fn fs_create( fs: *fs::fs, path: str, mode: fs::mode, - flags: fs::flag... + flags: fs::flag, ) (io::handle | fs::error) = { - return fs_create_file(fs, path, mode, flags...)?; + return fs_create_file(fs, path, mode, flags)?; }; fn fs_remove(fs: *fs::fs, path: str) (void | fs::error) = { diff --git a/os/+openbsd/dirfdfs.ha b/os/+openbsd/dirfdfs.ha @@ -87,20 +87,16 @@ fn _fs_open( fn fs_open_file( fs: *fs::fs, path: str, - flags: fs::flag... + flags: fs::flag, ) (io::file | fs::error) = { - let oflags = fs::flag::RDONLY; - for (let flag .. flags) { - oflags |= flag; - }; - return _fs_open(fs, path, fsflags_to_bsd(oflags)?, 0); + return _fs_open(fs, path, fsflags_to_bsd(flags)?, 0); }; fn fs_open( fs: *fs::fs, path: str, - flags: fs::flag... -) (io::handle | fs::error) = fs_open_file(fs, path, flags...)?; + flags: fs::flag, +) (io::handle | fs::error) = fs_open_file(fs, path, flags)?; fn fs_readlink(fs: *fs::fs, path: str) (str | fs::error) = { let fs = fs: *os_filesystem; @@ -123,25 +119,18 @@ fn fs_create_file( fs: *fs::fs, path: str, mode: fs::mode, - flags: fs::flag... + flags: fs::flag, ) (io::file | fs::error) = { - let oflags: fs::flag = 0; - if (len(flags) == 0z) { - oflags |= fs::flag::WRONLY | fs::flag::TRUNC; - }; - for (let flag .. flags) { - oflags |= flag; - }; - oflags |= fs::flag::CREATE; - return _fs_open(fs, path, fsflags_to_bsd(oflags)?, mode)?; + flags |= fs::flag::CREATE; + return _fs_open(fs, path, fsflags_to_bsd(flags)?, mode)?; }; fn fs_create( fs: *fs::fs, path: str, mode: fs::mode, - flags: fs::flag... -) (io::handle | fs::error) = fs_create_file(fs, path, mode, flags...)?; + flags: fs::flag, +) (io::handle | fs::error) = fs_create_file(fs, path, mode, flags)?; fn fs_remove(fs: *fs::fs, path: str) (void | fs::error) = { let fs = fs: *os_filesystem; diff --git a/os/os.ha b/os/os.ha @@ -107,20 +107,16 @@ export fn symlink(target: str, path: str) (void | fs::error) = // Opens a file. // -// If no flags are provided, [[fs::flag::RDONLY]] is used when opening the -// file. -// // [[fs::flag::CREATE]] isn't very useful with this function, since the new // file's mode is set to zero. For this use-case, use [[create]] instead. -export fn open(path: str, flags: fs::flag...) (io::file | fs::error) = - fs::open_file(cwd, path, flags...); +export fn open( + path: str, + flags: fs::flag = fs::flag::RDONLY, +) (io::file | fs::error) = fs::open_file(cwd, path, flags); // Creates a new file with the given mode if it doesn't already exist and opens // it for writing. // -// If no flags are provided, [[fs::flag::WRONLY]] and [[fs::flag::TRUNC]] are -// used when opening the file. -// // Only the permission bits of the mode are used. If other bits are set, they // are discarded. // @@ -128,7 +124,7 @@ export fn open(path: str, flags: fs::flag...) (io::file | fs::error) = export fn create( path: str, mode: fs::mode, - flags: fs::flag... + flags: fs::flag = fs::flag::WRONLY | fs::flag::TRUNC, ) (io::file | fs::error) = fs::create_file(cwd, path, mode, flags...); // Canonicalizes a path in this filesystem by resolving all symlinks and diff --git a/unix/+freebsd/pipe.ha b/unix/+freebsd/pipe.ha @@ -15,14 +15,10 @@ export type pipe_flag = enum { // Create a pair of two linked [[io::file]]s, such that any data written to the // second [[io::file]] may be read from the first. -export fn pipe(flags: pipe_flag...) ((io::file, io::file) | errors::error) = { +export fn pipe(flags: pipe_flag = 0) ((io::file, io::file) | errors::error) = { let fds: [2]int = [0...]; - let flag: pipe_flag = 0; - for (let i = 0z; i < len(flags); i += 1) { - flag |= flags[i]; - }; - flag ^= pipe_flag::NOCLOEXEC; // invert CLOEXEC - match (rt::pipe2(&fds, flag)) { + flags ^= pipe_flag::NOCLOEXEC; // invert CLOEXEC + match (rt::pipe2(&fds, flags)) { case void => void; case let e: rt::errno => return errors::errno(e); diff --git a/unix/+linux/pipe.ha b/unix/+linux/pipe.ha @@ -15,14 +15,10 @@ export type pipe_flag = enum { // Create a pair of two linked [[io::file]]s, such that any data written to the // second [[io::file]] may be read from the first. -export fn pipe(flags: pipe_flag...) ((io::file, io::file) | errors::error) = { +export fn pipe(flags: pipe_flag = 0) ((io::file, io::file) | errors::error) = { let fds: [2]int = [0...]; - let flag: pipe_flag = 0; - for (let i = 0z; i < len(flags); i += 1) { - flag |= flags[i]; - }; - flag ^= pipe_flag::NOCLOEXEC; // invert CLOEXEC - match (rt::pipe2(&fds, flag)) { + flags ^= pipe_flag::NOCLOEXEC; // invert CLOEXEC + match (rt::pipe2(&fds, flags)) { case void => void; case let e: rt::errno => return errors::errno(e); diff --git a/unix/+openbsd/pipe.ha b/unix/+openbsd/pipe.ha @@ -14,14 +14,10 @@ export type pipe_flag = enum { // Create a pair of two linked [[io::file]]s, such that any data written to the // second [[io::file]] may be read from the first. -export fn pipe(flags: pipe_flag...) ((io::file, io::file) | errors::error) = { +export fn pipe(flags: pipe_flag = 0) ((io::file, io::file) | errors::error) = { let fds: [2]int = [0...]; - let flag: pipe_flag = 0; - for (let i = 0z; i < len(flags); i += 1) { - flag |= flags[i]; - }; - flag ^= pipe_flag::NOCLOEXEC; // invert CLOEXEC - match (rt::pipe2(&fds, flag)) { + flags ^= pipe_flag::NOCLOEXEC; // invert CLOEXEC + match (rt::pipe2(&fds, flags)) { case void => void; case let e: rt::errno => return errors::errno(e); diff --git a/wordexp/+test.ha b/wordexp/+test.ha @@ -32,7 +32,7 @@ fn streq(a: []str, b: []str) bool = { for (let i = 0z; i < len(cases); i += 1) { const (in, out) = cases[i]; - const words = wordexp(in, flag::NONE)!; + const words = wordexp(in)!; defer strings::freeall(words); assert(streq(words, out)); }; diff --git a/wordexp/wordexp.ha b/wordexp/wordexp.ha @@ -26,7 +26,7 @@ export type flag = enum uint { // // Pass the return value to [[strings::freeall]] to free resources associated // with the return value. -export fn wordexp(s: str, flags: flag) ([]str | error) = { +export fn wordexp(s: str, flags: flag = flag::NONE) ([]str | error) = { const (rd, wr) = exec::pipe(); // "x" is added to handle the list of expanded words being empty