Browse Source

start on dealing with flag values

Simon Krajewski 6 years ago
parent
commit
c1e5290c1f
5 changed files with 174 additions and 118 deletions
  1. 5 0
      libs/uv/uv.ml
  2. 42 0
      libs/uv/uv_stubs.c
  3. 3 0
      src/macro/eval/evalStdLib.ml
  4. 46 40
      std/asys/FileOpenFlags.hx
  5. 78 78
      std/asys/uv/UVErrorType.hx

+ 5 - 0
libs/uv/uv.ml

@@ -271,3 +271,8 @@ external pipe_pending_count : t_pipe -> int = "w_pipe_pending_count"
 external pipe_accept_pending : t_loop -> t_pipe -> pipe_accepted uv_result = "w_pipe_accept_pending"
 external pipe_accept_pending : t_loop -> t_pipe -> pipe_accepted uv_result = "w_pipe_accept_pending"
 external pipe_getsockname : t_pipe -> string uv_result = "w_pipe_getsockname"
 external pipe_getsockname : t_pipe -> string uv_result = "w_pipe_getsockname"
 external pipe_getpeername : t_pipe -> string uv_result = "w_pipe_getpeername"
 external pipe_getpeername : t_pipe -> string uv_result = "w_pipe_getpeername"
+
+(* ------------- HAXE ---------------------------------------------- *)
+
+external get_file_open_flags : unit -> (string * int) array = "hx_get_file_open_flags"
+external get_errno : unit -> (string * int) array = "hx_get_errno"

+ 42 - 0
libs/uv/uv_stubs.c

@@ -1277,3 +1277,45 @@ CAMLprim value w_pipe_write_handle(value handle, value data, value send_handle,
 	UV_ERROR_CHECK_C(uv_write2(Write_val(req), Stream_val(handle), &buf, 1, Stream_val(send_handle), (void (*)(uv_write_t *, int))handle_stream_cb), UV_FREE_REQ(Write_val(req)));
 	UV_ERROR_CHECK_C(uv_write2(Write_val(req), Stream_val(handle), &buf, 1, Stream_val(send_handle), (void (*)(uv_write_t *, int))handle_stream_cb), UV_FREE_REQ(Write_val(req)));
 	UV_SUCCESS_UNIT;
 	UV_SUCCESS_UNIT;
 }
 }
+
+value build_fields(int num_fields, const char* names[], int values[]) {
+	int i;
+
+	value v_ret = caml_alloc(num_fields, 0);
+
+	for (i = 0; i < num_fields; ++i) {
+		value v_tuple = caml_alloc_tuple(2);
+		value v_name = caml_copy_string(names[i]);
+		value v_value = Val_int(values[i]);
+
+		Store_field(v_tuple, 0, v_name);
+		Store_field(v_tuple, 1, v_value);
+		Store_field(v_ret, i, v_tuple);
+	}
+
+	return v_ret;
+}
+
+CAMLprim value hx_get_file_open_flags(value unit) {
+	CAMLparam1(unit);
+
+	const char* names[] = {"Append", "Create", "Direct", "Directory", "Dsync", "Excl", "NoAtime", "NoCtty", "NoFollow", "NonBlock", "ReadOnly", "ReadWrite", "Sync", "Truncate", "WriteOnly"};
+	int values[] = {UV_FS_O_APPEND, UV_FS_O_CREAT, UV_FS_O_DIRECT, UV_FS_O_DIRECTORY, UV_FS_O_DSYNC, UV_FS_O_EXCL, UV_FS_O_NOATIME, UV_FS_O_NOCTTY, UV_FS_O_NOFOLLOW, UV_FS_O_NONBLOCK, UV_FS_O_RDONLY, UV_FS_O_RDWR, UV_FS_O_SYNC, UV_FS_O_TRUNC, UV_FS_O_WRONLY};
+
+	CAMLlocal1(v_ret);
+	v_ret = build_fields(15, names, values);
+
+	CAMLreturn(v_ret);
+}
+
+CAMLprim value hx_get_errno(value unit) {
+	CAMLparam1(unit);
+
+	const char* names[] = {"E2BIG", "EACCES", "EADDRINUSE", "EADDRNOTAVAIL", "EAFNOSUPPORT", "EAGAIN", "EAI_ADDRFAMILY", "EAI_AGAIN", "EAI_BADFLAGS", "EAI_BADHINTS", "EAI_CANCELED", "EAI_FAIL", "EAI_FAMILY", "EAI_MEMORY", "EAI_NODATA", "EAI_NONAME", "EAI_OVERFLOW", "EAI_PROTOCOL", "EAI_SERVICE", "EAI_SOCKTYPE", "EALREADY", "EBADF", "EBUSY", "ECANCELED", "ECHARSET", "ECONNABORTED", "ECONNREFUSED", "ECONNRESET", "EDESTADDRREQ", "EEXIST", "EFAULT", "EFBIG", "EHOSTUNREACH", "EINTR", "EINVAL", "EIO", "EISCONN", "EISDIR", "ELOOP", "EMFILE", "EMSGSIZE", "ENAMETOOLONG", "ENETDOWN", "ENETUNREACH", "ENFILE", "ENOBUFS", "ENODEV", "ENOENT", "ENOMEM", "ENONET", "ENOPROTOOPT", "ENOSPC", "ENOSYS", "ENOTCONN", "ENOTDIR", "ENOTEMPTY", "ENOTSOCK", "ENOTSUP", "EPERM", "EPIPE", "EPROTO", "EPROTONOSUPPORT", "EPROTOTYPE", "ERANGE", "EROFS", "ESHUTDOWN", "ESPIPE", "ESRCH", "ETIMEDOUT", "ETXTBSY", "EXDEV", "UNKNOWN", "EOF", "ENXIO", "EMLINK", "EHOSTDOWN", "EOTHER"};
+	int values[] = {UV_E2BIG, UV_EACCES, UV_EADDRINUSE, UV_EADDRNOTAVAIL, UV_EAFNOSUPPORT, UV_EAGAIN, UV_EAI_ADDRFAMILY, UV_EAI_AGAIN, UV_EAI_BADFLAGS, UV_EAI_BADHINTS, UV_EAI_CANCELED, UV_EAI_FAIL, UV_EAI_FAMILY, UV_EAI_MEMORY, UV_EAI_NODATA, UV_EAI_NONAME, UV_EAI_OVERFLOW, UV_EAI_PROTOCOL, UV_EAI_SERVICE, UV_EAI_SOCKTYPE, UV_EALREADY, UV_EBADF, UV_EBUSY, UV_ECANCELED, UV_ECHARSET, UV_ECONNABORTED, UV_ECONNREFUSED, UV_ECONNRESET, UV_EDESTADDRREQ, UV_EEXIST, UV_EFAULT, UV_EFBIG, UV_EHOSTUNREACH, UV_EINTR, UV_EINVAL, UV_EIO, UV_EISCONN, UV_EISDIR, UV_ELOOP, UV_EMFILE, UV_EMSGSIZE, UV_ENAMETOOLONG, UV_ENETDOWN, UV_ENETUNREACH, UV_ENFILE, UV_ENOBUFS, UV_ENODEV, UV_ENOENT, UV_ENOMEM, UV_ENONET, UV_ENOPROTOOPT, UV_ENOSPC, UV_ENOSYS, UV_ENOTCONN, UV_ENOTDIR, UV_ENOTEMPTY, UV_ENOTSOCK, UV_ENOTSUP, UV_EPERM, UV_EPIPE, UV_EPROTO, UV_EPROTONOSUPPORT, UV_EPROTOTYPE, UV_ERANGE, UV_EROFS, UV_ESHUTDOWN, UV_ESPIPE, UV_ESRCH, UV_ETIMEDOUT, UV_ETXTBSY, UV_EXDEV, UV_UNKNOWN, UV_EOF, UV_ENXIO, UV_EMLINK, UV_EHOSTDOWN, 0};
+
+	CAMLlocal1(v_ret);
+	v_ret = build_fields(77, names, values);
+
+	CAMLreturn(v_ret);
+}

+ 3 - 0
src/macro/eval/evalStdLib.ml

@@ -4543,6 +4543,9 @@ let init_standard_library builtins =
 		"addChar",StdUtf8.addChar;
 		"addChar",StdUtf8.addChar;
 		"toString",StdUtf8.toString;
 		"toString",StdUtf8.toString;
 	];
 	];
+	let uv_statics a = List.map (fun (s,i) -> s,vint i) (Array.to_list a) in
+	init_fields builtins (["asys"],"FileOpenFlagsImpl") (uv_statics (Uv.get_file_open_flags())) [];
+	init_fields builtins (["asys";"uv";"_UVErrorType"],"UVErrorType_Impl_") (uv_statics (Uv.get_errno())) [];
 	init_fields builtins (["eval";"uv"],"File") [] [];
 	init_fields builtins (["eval";"uv"],"File") [] [];
 	init_fields builtins (["eval"],"Uv") [
 	init_fields builtins (["eval"],"Uv") [
 		"init",StdUv.init;
 		"init",StdUv.init;

+ 46 - 40
std/asys/FileOpenFlags.hx

@@ -1,28 +1,7 @@
 package asys;
 package asys;
 
 
-/**
-	Flags used when opening a file with `asys.FileSystem.open` or other file
-	functions. Specify whether the opened file:
-
-	- will be readable
-	- will be writable
-	- will be truncated (all data lost) first
-	- will be in append mode
-	- will be opened exclusively by this process
-
-	Instances of this type can be created by combining flags with the bitwise or
-	operator:
-
-	```haxe
-	Truncate | Create | WriteOnly
-	```
-
-	Well-known combinations of flags can be specified with a string. The
-	supported modes are: `r`, `r+`, `rs+`, `sr+`, `w`, `w+`, `a`, `a+`, `wx`,
-	`xw`, `wx+`, `xw+`, `ax`, `xa`, `as`, `sa`, `ax+`, `xa+`, `as+`, `sa+`.
-**/
-enum abstract FileOpenFlags(Int) {
-	@:from public static function fromString(flags:String):FileOpenFlags {
+class FileOpenFlagsImpl {
+	public static function fromString(flags:String):FileOpenFlags {
 		return (switch (flags) {
 		return (switch (flags) {
 			case "r": ReadOnly;
 			case "r": ReadOnly;
 			case "r+": ReadWrite;
 			case "r+": ReadWrite;
@@ -47,29 +26,56 @@ enum abstract FileOpenFlags(Int) {
 			case _: throw "invalid file open flags";
 			case _: throw "invalid file open flags";
 		});
 		});
 	}
 	}
+}
+
+
+/**
+	Flags used when opening a file with `asys.FileSystem.open` or other file
+	functions. Specify whether the opened file:
+
+	- will be readable
+	- will be writable
+	- will be truncated (all data lost) first
+	- will be in append mode
+	- will be opened exclusively by this process
+
+	Instances of this type can be created by combining flags with the bitwise or
+	operator:
+
+	```haxe
+	Truncate | Create | WriteOnly
+	```
+
+	Well-known combinations of flags can be specified with a string. The
+	supported modes are: `r`, `r+`, `rs+`, `sr+`, `w`, `w+`, `a`, `a+`, `wx`,
+	`xw`, `wx+`, `xw+`, `ax`, `xa`, `as`, `sa`, `ax+`, `xa+`, `as+`, `sa+`.
+**/
+@:native("asys.FileOpenFlagsImpl")
+extern enum abstract FileOpenFlags(Int) {
+	@:from public static function fromString(flags:String):FileOpenFlags;
 
 
-	function new(value:Int)
+	inline function new(value:Int)
 		this = value;
 		this = value;
 
 
 	inline function get_raw():Int return this;
 	inline function get_raw():Int return this;
 
 
 	@:op(A | B)
 	@:op(A | B)
-	inline function join(other:FileOpenFlags) return new FileOpenFlags(this | other.get_raw());
+	inline function join(other:FileOpenFlags):FileOpenFlags return new FileOpenFlags(this | other.get_raw());
 
 
 	// TODO: some of these don't make sense in Haxe-wrapped libuv
 	// TODO: some of these don't make sense in Haxe-wrapped libuv
-	var Append = 0x400;
-	var Create = 0x40;
-	var Direct = 0x4000;
-	var Directory = 0x10000;
-	var Dsync = 0x1000;
-	var Excl = 0x80;
-	var NoAtime = 0x40000;
-	var NoCtty = 0x100;
-	var NoFollow = 0x20000;
-	var NonBlock = 0x800;
-	var ReadOnly = 0x0;
-	var ReadWrite = 0x2;
-	var Sync = 0x101000;
-	var Truncate = 0x200;
-	var WriteOnly = 0x1;
+	var Append;
+	var Create;
+	var Direct;
+	var Directory;
+	var Dsync;
+	var Excl;
+	var NoAtime;
+	var NoCtty;
+	var NoFollow;
+	var NonBlock;
+	var ReadOnly;
+	var ReadWrite;
+	var Sync;
+	var Truncate;
+	var WriteOnly;
 }
 }

+ 78 - 78
std/asys/uv/UVErrorType.hx

@@ -1,81 +1,81 @@
 package asys.uv;
 package asys.uv;
 
 
-enum abstract UVErrorType(Int) {
-	var E2BIG = -7; // "argument list too long"
-	var EACCES = -13; // "permission denied"
-	var EADDRINUSE = -48; // "address already in use"
-	var EADDRNOTAVAIL = -49; // "address not available"
-	var EAFNOSUPPORT = -47; // "address family not supported"
-	var EAGAIN = -35; // "resource temporarily unavailable"
-	var EAI_ADDRFAMILY = -3000; // "address family not supported"
-	var EAI_AGAIN = -3001; // "temporary failure"
-	var EAI_BADFLAGS = -3002; // "bad ai_flags value"
-	var EAI_BADHINTS = -3013; // "invalid value for hints"
-	var EAI_CANCELED = -3003; // "request canceled"
-	var EAI_FAIL = -3004; // "permanent failure"
-	var EAI_FAMILY = -3005; // "ai_family not supported"
-	var EAI_MEMORY = -3006; // "out of memory"
-	var EAI_NODATA = -3007; // "no address"
-	var EAI_NONAME = -3008; // "unknown node or service"
-	var EAI_OVERFLOW = -3009; // "argument buffer overflow"
-	var EAI_PROTOCOL = -3014; // "resolved protocol is unknown"
-	var EAI_SERVICE = -3010; // "service not available for socket type"
-	var EAI_SOCKTYPE = -3011; // "socket type not supported"
-	var EALREADY = -37; // "connection already in progress"
-	var EBADF = -9; // "bad file descriptor"
-	var EBUSY = -16; // "resource busy or locked"
-	var ECANCELED = -89; // "operation canceled"
-	var ECHARSET = -4080; // "invalid Unicode character"
-	var ECONNABORTED = -53; // "software caused connection abort"
-	var ECONNREFUSED = -61; // "connection refused"
-	var ECONNRESET = -54; // "connection reset by peer"
-	var EDESTADDRREQ = -39; // "destination address required"
-	var EEXIST = -17; // "file already exists"
-	var EFAULT = -14; // "bad address in system call argument"
-	var EFBIG = -27; // "file too large"
-	var EHOSTUNREACH = -65; // "host is unreachable"
-	var EINTR = -4; // "interrupted system call"
-	var EINVAL = -22; // "invalid argument"
-	var EIO = -5; // "i/o error"
-	var EISCONN = -56; // "socket is already connected"
-	var EISDIR = -21; // "illegal operation on a directory"
-	var ELOOP = -62; // "too many symbolic links encountered"
-	var EMFILE = -24; // "too many open files"
-	var EMSGSIZE = -40; // "message too long"
-	var ENAMETOOLONG = -63; // "name too long"
-	var ENETDOWN = -50; // "network is down"
-	var ENETUNREACH = -51; // "network is unreachable"
-	var ENFILE = -23; // "file table overflow"
-	var ENOBUFS = -55; // "no buffer space available"
-	var ENODEV = -19; // "no such device"
-	var ENOENT = -2; // "no such file or directory"
-	var ENOMEM = -12; // "not enough memory"
-	var ENONET = -4056; // "machine is not on the network"
-	var ENOPROTOOPT = -42; // "protocol not available"
-	var ENOSPC = -28; // "no space left on device"
-	var ENOSYS = -78; // "function not implemented"
-	var ENOTCONN = -57; // "socket is not connected"
-	var ENOTDIR = -20; // "not a directory"
-	var ENOTEMPTY = -66; // "directory not empty"
-	var ENOTSOCK = -38; // "socket operation on non-socket"
-	var ENOTSUP = -45; // "operation not supported on socket"
-	var EPERM = -1; // "operation not permitted"
-	var EPIPE = -32; // "broken pipe"
-	var EPROTO = -100; // "protocol error"
-	var EPROTONOSUPPORT = -43; // "protocol not supported"
-	var EPROTOTYPE = -41; // "protocol wrong type for socket"
-	var ERANGE = -34; // "result too large"
-	var EROFS = -30; // "read-only file system"
-	var ESHUTDOWN = -58; // "cannot send after transport endpoint shutdown"
-	var ESPIPE = -29; // "invalid seek"
-	var ESRCH = -3; // "no such process"
-	var ETIMEDOUT = -60; // "connection timed out"
-	var ETXTBSY = -26; // "text file is busy"
-	var EXDEV = -18; // "cross-device link not permitted"
-	var UNKNOWN = -4094; // "unknown error"
-	var EOF = -4095; // "end of file"
-	var ENXIO = -6; // "no such device or address"
-	var EMLINK = -31; // "too many links"
-	var EHOSTDOWN = -64; // "host is down"
-	var EOTHER = 0;
+extern enum abstract UVErrorType(Int) {
+	var E2BIG; // "argument list too long"
+	var EACCES; // "permission denied"
+	var EADDRINUSE; // "address already in use"
+	var EADDRNOTAVAIL; // "address not available"
+	var EAFNOSUPPORT; // "address family not supported"
+	var EAGAIN; // "resource temporarily unavailable"
+	var EAI_ADDRFAMILY; // "address family not supported"
+	var EAI_AGAIN; // "temporary failure"
+	var EAI_BADFLAGS; // "bad ai_flags value"
+	var EAI_BADHINTS; // "invalid value for hints"
+	var EAI_CANCELED; // "request canceled"
+	var EAI_FAIL; // "permanent failure"
+	var EAI_FAMILY; // "ai_family not supported"
+	var EAI_MEMORY; // "out of memory"
+	var EAI_NODATA; // "no address"
+	var EAI_NONAME; // "unknown node or service"
+	var EAI_OVERFLOW; // "argument buffer overflow"
+	var EAI_PROTOCOL; // "resolved protocol is unknown"
+	var EAI_SERVICE; // "service not available for socket type"
+	var EAI_SOCKTYPE; // "socket type not supported"
+	var EALREADY; // "connection already in progress"
+	var EBADF; // "bad file descriptor"
+	var EBUSY; // "resource busy or locked"
+	var ECANCELED; // "operation canceled"
+	var ECHARSET; // "invalid Unicode character"
+	var ECONNABORTED; // "software caused connection abort"
+	var ECONNREFUSED; // "connection refused"
+	var ECONNRESET; // "connection reset by peer"
+	var EDESTADDRREQ; // "destination address required"
+	var EEXIST; // "file already exists"
+	var EFAULT; // "bad address in system call argument"
+	var EFBIG; // "file too large"
+	var EHOSTUNREACH; // "host is unreachable"
+	var EINTR; // "interrupted system call"
+	var EINVAL; // "invalid argument"
+	var EIO; // "i/o error"
+	var EISCONN; // "socket is already connected"
+	var EISDIR; // "illegal operation on a directory"
+	var ELOOP; // "too many symbolic links encountered"
+	var EMFILE; // "too many open files"
+	var EMSGSIZE; // "message too long"
+	var ENAMETOOLONG; // "name too long"
+	var ENETDOWN; // "network is down"
+	var ENETUNREACH; // "network is unreachable"
+	var ENFILE; // "file table overflow"
+	var ENOBUFS; // "no buffer space available"
+	var ENODEV; // "no such device"
+	var ENOENT; // "no such file or directory"
+	var ENOMEM; // "not enough memory"
+	var ENONET; // "machine is not on the network"
+	var ENOPROTOOPT; // "protocol not available"
+	var ENOSPC; // "no space left on device"
+	var ENOSYS; // "function not implemented"
+	var ENOTCONN; // "socket is not connected"
+	var ENOTDIR; // "not a directory"
+	var ENOTEMPTY; // "directory not empty"
+	var ENOTSOCK; // "socket operation on non-socket"
+	var ENOTSUP; // "operation not supported on socket"
+	var EPERM; // "operation not permitted"
+	var EPIPE; // "broken pipe"
+	var EPROTO; // "protocol error"
+	var EPROTONOSUPPORT; // "protocol not supported"
+	var EPROTOTYPE; // "protocol wrong type for socket"
+	var ERANGE; // "result too large"
+	var EROFS; // "read-only file system"
+	var ESHUTDOWN; // "cannot send after transport endpoint shutdown"
+	var ESPIPE; // "invalid seek"
+	var ESRCH; // "no such process"
+	var ETIMEDOUT; // "connection timed out"
+	var ETXTBSY; // "text file is busy"
+	var EXDEV; // "cross-device link not permitted"
+	var UNKNOWN; // "unknown error"
+	var EOF; // "end of file"
+	var ENXIO; // "no such device or address"
+	var EMLINK; // "too many links"
+	var EHOSTDOWN; // "host is down"
+	var EOTHER;
 }
 }