Browse Source

started hl sys impl

Nicolas Cannasse 9 years ago
parent
commit
a890b19d0e

+ 6 - 0
std/hl/_std/Date.hx

@@ -87,6 +87,12 @@ import hl.types.Ref;
 		return d;
 	}
 
+	static function fromInt( t : Int ) : Date {
+		var d : Date = untyped $new(Date);
+		d.t = t;
+		return d;
+	}
+	
 	public static function fromTime( t : Float ) : Date {
 		var d : Date = untyped $new(Date);
 		d.t = date_from_time(t);

+ 1 - 1
std/hl/_std/Reflect.hx

@@ -89,7 +89,7 @@ class Reflect {
 	public static function fields( o : Dynamic ) : Array<String> {
 		var fields = getObjectFields(o, true);
 		if( fields == null ) return [];
-		return [for( f in fields ) @:privateAccess String.__alloc__(f,f.ucs2Length(0))];
+		return [for( f in fields ) @:privateAccess String.fromUCS2(f)];
 	}
 
 	public static inline function isFunction( f : Dynamic ) : Bool {

+ 7 - 0
std/hl/_std/String.hx

@@ -173,6 +173,13 @@ class String {
 		return s.bytes;
 	}
 
+	inline static function fromUCS2( b : hl.types.Bytes ) : String {
+		var s : String = untyped $new(String);
+		s.bytes = b;
+		s.length = @:privateAccess b.ucs2Length(0);
+		return s;
+	}
+
 	@:keep static function fromUTF8( b : hl.types.Bytes ) : String {
 		var outLen = 0;
 		var b2 = @:privateAccess b.utf8ToUtf16(0, outLen);

+ 122 - 6
std/hl/_std/Sys.hx

@@ -1,11 +1,127 @@
+class SysError {
+	public var msg : String;
+	public function new(msg) {
+		this.msg = msg;
+	}
+	@:keep public function toString() {
+		return "SysError("+msg+")";
+	}
+}
+
+@:coreApi
+@:access(String)
 class Sys {
-	
-	public static function println( v : Dynamic ) {
-		_print(@:privateAccess (Std.string(v)+"\n").bytes);
+
+	public static function print( v : Dynamic ) : Void {
+		_print(Std.string(v).bytes);
 	}
-	
-	@:hlNative("std","sys_print") static function _print( v : hl.types.Bytes ) : Void {};
+
+	public static function println( v : Dynamic ) : Void {
+		_print(Std.string(v).bytes);
+		_print("\n".bytes);
+	}
+
+	public static function args() : Array<String> {
+		return [for( a in sys_args() ) String.fromUCS2(a)];
+	}
+
+	public static function stdin() : haxe.io.Input {
+		return @:privateAccess new sys.io.FileInput(sys_stdin());
+	}
+
+	public static function stdout() : haxe.io.Output {
+		return @:privateAccess new sys.io.FileOutput(sys_stdout());
+	}
+
+	public static function stderr() : haxe.io.Output {
+		return @:privateAccess new sys.io.FileOutput(sys_stderr());
+	}
+
+	public static function getEnv( s : String ) : String {
+		var v = get_env(s.bytes);
+		if( v == null )
+			return null;
+		return String.fromUCS2(v);
+	}
+
+	public static function putEnv( s : String, v : String ) : Void {
+		put_env(s.bytes,if( v == null ) null else v.bytes);
+	}
+
+	@:hlNative("std","sys_sleep")
+	public static function sleep( seconds : Float ) : Void {
+	}
+
+	public static function setTimeLocale( loc : String ) : Bool {
+		return set_time_locale(loc.bytes);
+	}
+
+	public static function getCwd() : String {
+		return String.fromUCS2(get_cwd());
+	}
+
+	public static function setCwd( s : String ) : Void {
+		if( !set_cwd(s.bytes) ) throw new SysError("Failed to set path to " + s);
+	}
+
+	public static function systemName() : String {
+		return String.fromUCS2(sys_string());
+	}
+
+	public static function command( cmd : String, ?args : Array<String> ) : Int {
+		var code = 0;
+		var ok;
+		if (args == null) {
+			ok = sys_command(cmd.bytes, code);
+		} else {
+			switch (systemName()) {
+				case "Windows":
+					cmd = [
+						for (a in [StringTools.replace(cmd, "/", "\\")].concat(args))
+						StringTools.quoteWinArg(a, true)
+					].join(" ");
+					ok = sys_command(cmd.bytes, code);
+				case _:
+					cmd = [cmd].concat(args).map(StringTools.quoteUnixArg).join(" ");
+					ok = sys_command(cmd.bytes, code);
+			}
+		}
+		if( !ok ) throw new SysError("Failed to run command " + cmd);
+		return code;
+	}
+
+	public static function executablePath() : String {
+		return String.fromUCS2(sys_exe_path());
+	}
+
+	public static function environment() : Map<String,String> {
+		var env = sys_env();
+		var h = new haxe.ds.StringMap();
+		for( i in 0...env.length >> 1 ) {
+			var p = i << 1;
+			h.set(String.fromUCS2(env[p]), String.fromUCS2(env[p + 1]));
+		}
+		return h;
+	}
+
 	@:hlNative("std","sys_time") public static function time() : Float { return 0.; };
 	@:hlNative("std","sys_exit") public static function exit( code : Int ) : Void {};
-	
+	@:hlNative("std", "sys_cpu_time") public static function cpuTime() : Float { return 0.; };
+	@:hlNative("std", "sys_get_char") public static function getChar( echo : Bool ) : Int { return 0; }
+
+	@:hlNative("std","sys_print") static function _print( v : hl.types.Bytes ) : Void {};
+	@:hlNative("std", "sys_stdin") static function sys_stdin() : sys.io.File.FileHandle { return null; }
+	@:hlNative("std", "sys_stdout") static function sys_stdout() : sys.io.File.FileHandle { return null; }
+	@:hlNative("std", "sys_stderr") static function sys_stderr() : sys.io.File.FileHandle { return null; }
+	@:hlNative("std", "sys_args") static function sys_args() : hl.types.NativeArray<hl.types.Bytes> { return null; }
+	@:hlNative("std", "sys_get_env") static function get_env( key : hl.types.Bytes ) : hl.types.Bytes { return null; }
+	@:hlNative("std", "sys_put_env") static function put_env( key : hl.types.Bytes, val : hl.types.Bytes ) : Void {}
+	@:hlNative("std", "sys_env") static function sys_env() : hl.types.NativeArray<hl.types.Bytes> { return null; }
+	@:hlNative("std", "sys_set_time_locale") static function set_time_locale( loc : hl.types.Bytes ) : Bool { return true; }
+	@:hlNative("std", "sys_get_cwd") static function get_cwd() : hl.types.Bytes { return null; }
+	@:hlNative("std", "sys_set_cwd") static function set_cwd( path : hl.types.Bytes ) : Bool { return true; }
+	@:hlNative("std", "sys_command") static function sys_command( cmd : hl.types.Bytes, code : hl.types.Ref<Int> ) : Bool { return false; }
+	@:hlNative("std", "sys_exe_path") static function sys_exe_path() : hl.types.Bytes { return null; }
+	@:hlNative("std", "sys_string") static function sys_string() : hl.types.Bytes { return null; }
+
 }

+ 1 - 1
std/hl/_std/Type.hx

@@ -116,7 +116,7 @@ class Type {
 	public static function getInstanceFields( c : Class<Dynamic> ) : Array<String> @:privateAccess {
 		var c : hl.types.BaseType.Class = cast c;
 		var fields = c.__type__.getInstanceFields();
-		return [for( f in fields ) String.__alloc__(f,f.ucs2Length(0))];
+		return [for( f in fields ) String.fromUCS2(f)];
 	}
 
 	public static function getClassFields( c : Class<Dynamic> ) : Array<String> {

+ 1 - 1
std/hl/_std/haxe/Resource.hx

@@ -33,7 +33,7 @@ class Resource {
 	static var content : hl.types.NativeArray<ResourceContent>;
 
 	public static function listNames() : Array<String> {
-		return [for (x in content) @:privateAccess String.__alloc__(x.name, x.name.ucs2Length(0))];
+		return [for (x in content) @:privateAccess String.fromUCS2(x.name)];
 	}
 
 	public static function getString( name : String ) : String {

+ 1 - 1
std/hl/_std/haxe/ds/StringMap.hx

@@ -39,7 +39,7 @@ private class StringMapKeysIterator {
 
 	public inline function next() @:privateAccess {
 		var b = arr[pos++];
-		return String.__alloc__(b,b.ucs2Length(0));
+		return String.fromUCS2(b);
 	}
 
 }

+ 115 - 0
std/hl/_std/sys/FileSystem.hx

@@ -0,0 +1,115 @@
+/*
+ * Copyright (C)2005-2016 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package sys;
+
+@:coreApi
+@:access(String)
+class FileSystem {
+
+	public static function exists( path : String ) : Bool {
+		return sys_exists(makeCompatiblePath(path).bytes);
+	}
+
+	public static function rename( path : String, newPath : String ) : Void {
+		if( !sys_rename(path.bytes, newPath.bytes) ) throw new Sys.SysError("Failed to rename " + path + " to " + newPath);
+	}
+
+	public static function stat( path : String ) : FileStat {
+		var values = sys_stat(makeCompatiblePath(path).bytes);
+		if( values == null ) throw new Sys.SysError("Failed to stat " + path);
+		return {
+			gid : values[0],
+			uid : values[1],
+			atime : @:privateAccess Date.fromInt(values[2]),
+			mtime : @:privateAccess Date.fromInt(values[3]),
+			ctime : @:privateAccess Date.fromInt(values[4]),
+			size : values[5],
+			dev : values[6],
+			ino : values[7],
+			nlink : values[8],
+			rdev : values[9],
+			mode : values[10],
+		};
+	}
+
+	public static function fullPath( relPath : String ) : String {
+		return String.fromUCS2(file_full_path(relPath.bytes));
+	}
+
+	public static function absolutePath ( relPath : String ) : String {
+		if (haxe.io.Path.isAbsolute(relPath)) return relPath;
+		return haxe.io.Path.join([Sys.getCwd(), relPath]);
+	}
+
+	public static function isDirectory( path : String ) : Bool {
+		return sys_is_dir(makeCompatiblePath(path).bytes);
+	}
+
+	public static function createDirectory( path : String ) : Void {
+		var path = haxe.io.Path.addTrailingSlash(path);
+		var _p = null;
+		var parts = [];
+		while (path != (_p = haxe.io.Path.directory(path))) {
+			parts.unshift(path);
+			path = _p;
+		}
+		for (part in parts) {
+			if (part.charCodeAt(part.length - 1) != ":".code && !exists(part))
+				if( !sys_create_dir(part.bytes, 493) )
+					throw new Sys.SysError("Failed to create directory " + part);
+		}
+	}
+
+	public static function deleteFile( path : String ) : Void {
+		if( !file_delete(path.bytes) ) throw new Sys.SysError("Can't delete file " + path);
+	}
+
+	public static function deleteDirectory( path : String ) : Void {
+		if( !sys_remove_dir(path.bytes) ) throw new Sys.SysError("Can't delete directory " + path);
+	}
+
+	public static function readDirectory( path : String ) : Array<String> {
+		var content = sys_read_dir(path.bytes);
+		if( content == null )
+			throw new Sys.SysError("Failed to read directory " + path);
+		return [for( c in content ) String.fromUCS2(c)];
+	}
+
+	private static inline function makeCompatiblePath(path:String):String {
+		return if (path.charCodeAt(1) == ":".code && path.length <= 3) {
+			haxe.io.Path.addTrailingSlash(path);
+		} else {
+			haxe.io.Path.removeTrailingSlashes(path);
+		}
+	}
+
+	@:hlNative("std", "sys_read_dir") static function sys_read_dir( path : hl.types.Bytes ) : hl.types.NativeArray<hl.types.Bytes> { return null; }
+	@:hlNative("std", "sys_create_dir") static function sys_create_dir( path : hl.types.Bytes, rights : Int ) : Bool { return false; }
+	@:hlNative("std", "sys_is_dir") static function sys_is_dir( path : hl.types.Bytes ) : Bool { return false; }
+	@:hlNative("std", "sys_stat") static function sys_stat( path : hl.types.Bytes ) : hl.types.NativeArray<Int> { return null; }
+	@:hlNative("std", "sys_rename") static function sys_rename( path : hl.types.Bytes, to : hl.types.Bytes ) : Bool { return true; }
+	@:hlNative("std", "file_delete") static function file_delete( path : hl.types.Bytes ) : Bool { return true; };
+	@:hlNative("std", "file_full_path") static function file_full_path( path : hl.types.Bytes ) : hl.types.Bytes { return null; }
+	@:hlNative("std", "sys_remove_dir") static function sys_remove_dir( path : hl.types.Bytes ) : Bool { return true; }
+	@:hlNative("std", "sys_exists") static function sys_exists( path : hl.types.Bytes ) : Bool { return true; }
+
+}

+ 84 - 0
std/hl/_std/sys/io/File.hx

@@ -0,0 +1,84 @@
+/*
+ * Copyright (C)2005-2016 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package sys.io;
+
+typedef FileHandle = hl.types.NativeAbstract<"fd">;
+
+@:access(String)
+@:coreApi class File {
+
+	public static function getContent( path : String ) : String {
+		var size = 0;
+		var bytes = file_contents(path.bytes, size);
+		if( bytes == null ) throw new Sys.SysError("Can't read "+path);
+		return String.fromUTF8(bytes);
+	}
+
+	public static function getBytes( path : String ) : haxe.io.Bytes {
+		var size = 0;
+		var bytes = file_contents(path.bytes, size);
+		if( bytes == null ) throw new Sys.SysError("Can't open "+path);
+		return haxe.io.Bytes.ofData(new haxe.io.BytesData(bytes,size));
+	}
+
+	public static function saveContent( path : String, content : String ) : Void {
+		var f = write(path);
+		f.writeString(content);
+		f.close();
+	}
+
+	public static function saveBytes( path : String, bytes : haxe.io.Bytes ) : Void {
+		var f = write(path);
+		f.write(bytes);
+		f.close();
+	}
+
+	public static function read( path : String, binary : Bool = true ) : FileInput {
+		var f = file_open(path.bytes,(if( binary ) "rb" else "r").bytes);
+		if( f == null ) throw new Sys.SysError("Can't open "+path);
+		return @:privateAccess new FileInput(f);
+	}
+
+	public static function write( path : String, binary : Bool = true ) : FileOutput {
+		var f = file_open(path.bytes,(if( binary ) "wb" else "w").bytes);
+		if( f == null ) throw new Sys.SysError("Can't open "+path+" for writing");
+		return @:privateAccess new FileOutput(f);
+	}
+
+	public static function append( path : String, binary : Bool = true ) : FileOutput {
+		var f = file_open(path.bytes,(if( binary ) "ab" else "a").bytes);
+		if( f == null ) throw new Sys.SysError("Can't open "+path+" for append");
+		return @:privateAccess new FileOutput(f);
+	}
+
+	public static function copy( srcPath : String, dstPath : String ) : Void {
+		var s = read(srcPath,true);
+		var d = write(dstPath,true);
+		d.writeInput(s);
+		s.close();
+		d.close();
+	}
+
+	@:hlNative("std", "file_open") static function file_open( path : hl.types.Bytes, access : hl.types.Bytes ) : FileHandle { return null; }
+	@:hlNative("std", "file_contents") static function file_contents( path : hl.types.Bytes, size : hl.types.Ref<Int> ) : hl.types.Bytes { return null; }
+
+}

+ 69 - 0
std/hl/_std/sys/io/FileInput.hx

@@ -0,0 +1,69 @@
+/*
+ * Copyright (C)2005-2016 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package sys.io;
+import sys.io.File;
+
+@:coreApi class FileInput extends haxe.io.Input {
+
+	private var __f : FileHandle;
+
+	function new(f:FileHandle) : Void {
+		__f = f;
+	}
+
+	public override function readByte() : Int {
+		var c = file_read_char(__f);
+		if( c < 0 ) throw new haxe.io.Eof();
+		return c;
+	}
+
+	public override function readBytes( s : haxe.io.Bytes, p : Int, l : Int ) : Int {
+		var v = file_read(__f, s.getData().b, p, l);
+		if( v < 0 ) throw new haxe.io.Eof();
+		return v;
+	}
+
+	public override function close() : Void {
+		super.close();
+		file_close(__f);
+	}
+
+	public function seek( p : Int, pos : FileSeek ) : Void {
+		file_seek(__f,p,switch( pos ) { case SeekBegin: 0; case SeekCur: 1; case SeekEnd: 2; });
+	}
+
+	public function tell() : Int {
+		return file_tell(__f);
+	}
+
+	public function eof() : Bool {
+		return file_eof(__f);
+	}
+
+	@:hlNative("std", "file_eof") static function file_eof( f : FileHandle ) : Bool { return false; }
+	@:hlNative("std", "file_read") static function file_read( f : FileHandle, bytes : hl.types.Bytes, pos : Int, len : Int ) : Int { return 0; }
+	@:hlNative("std", "file_read_char") static function file_read_char( f : FileHandle ) : Int { return 0; }
+	@:hlNative("std", "file_close") static function file_close( f : FileHandle ) : Void { }
+	@:hlNative("std", "file_seek") static function file_seek( f : FileHandle, pos : Int, from : Int ) : Void { }
+	@:hlNative("std", "file_tell") static function file_tell( f : FileHandle ) : Int { return 0; }
+
+}

+ 64 - 0
std/hl/_std/sys/io/FileOutput.hx

@@ -0,0 +1,64 @@
+/*
+ * Copyright (C)2005-2016 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package sys.io;
+import sys.io.File;
+
+@:coreApi class FileOutput extends haxe.io.Output {
+
+	private var __f : FileHandle;
+
+	function new(f:FileHandle) : Void {
+		__f = f;
+	}
+
+	public override function writeByte( c : Int ) : Void {
+		if( !file_write_char(__f, c) ) throw new haxe.io.Eof();
+	}
+
+	public override function writeBytes( s : haxe.io.Bytes, p : Int, l : Int ) : Int {
+		var v = file_write(__f, s.getData().b, p, l);
+		if( v < 0 ) throw new haxe.io.Eof();
+		return v;
+	}
+
+	public override function flush() : Void {
+		file_flush(__f);
+	}
+
+	public override function close() : Void {
+		super.close();
+		@:privateAccess FileInput.file_close(__f);
+	}
+
+	public function seek( p : Int, pos : FileSeek ) : Void {
+		@:privateAccess FileInput.file_seek(__f,p,switch( pos ) { case SeekBegin: 0; case SeekCur: 1; case SeekEnd: 2; });
+	}
+
+	public function tell() : Int {
+		return @:privateAccess FileInput.file_tell(__f);
+	}
+
+	@:hlNative("std","file_flush") static function file_flush( f : FileHandle ) : Void {}
+	@:hlNative("std", "file_write") static function file_write( f : FileHandle, bytes : hl.types.Bytes, pos : Int, len : Int ) : Int { return 0; }
+	@:hlNative("std", "file_write_char") static function file_write_char( f : FileHandle, v : Int ) : Bool { return true; }
+
+}

+ 132 - 0
std/hl/_std/sys/io/Process.hx

@@ -0,0 +1,132 @@
+/*
+ * Copyright (C)2005-2016 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package sys.io;
+
+private typedef ProcessHandle = hl.types.NativeAbstract<"process">;
+
+private class Stdin extends haxe.io.Output {
+
+	var p : Dynamic;
+	var buf : haxe.io.Bytes;
+
+	public function new(p) {
+		this.p = p;
+		buf = haxe.io.Bytes.alloc(1);
+	}
+
+	public override function close() {
+		super.close();
+		_stdin_close(p);
+	}
+
+	public override function writeByte(c) {
+		buf.set(0,c);
+		writeBytes(buf,0,1);
+	}
+
+	public override function writeBytes( buf : haxe.io.Bytes, pos : Int, len : Int ) : Int {
+		var v = _stdin_write(p, buf.getData().b, pos, len);
+		if( v < 0 ) throw new haxe.io.Eof();
+		return v;
+	}
+
+	@:hlNative("std","process_stdin_write") static function _stdin_write( p : ProcessHandle, bytes : hl.types.Bytes, pos : Int, len : Int ) : Int { return 0; }
+	@:hlNative("std","process_stdin_close") static function _stdin_close( p : ProcessHandle ) : Void { }
+
+}
+
+private class Stdout extends haxe.io.Input {
+
+	var p : ProcessHandle;
+	var out : Bool;
+	var buf : haxe.io.Bytes;
+
+	public function new(p,out) {
+		this.p = p;
+		this.out = out;
+		buf = haxe.io.Bytes.alloc(1);
+	}
+
+	public override function readByte() {
+		if( readBytes(buf,0,1) == 0 )
+			throw haxe.io.Error.Blocked;
+		return buf.get(0);
+	}
+
+	public override function readBytes( str : haxe.io.Bytes, pos : Int, len : Int ) : Int {
+		var v = out ? _stdout_read(p,str.getData().b,pos,len) : _stderr_read(p,str.getData().b,pos,len);
+		if( v < 0 ) throw new haxe.io.Eof();
+		return v;
+	}
+
+	@:hlNative("std","process_stdout_read") static function _stdout_read( p : ProcessHandle, bytes : hl.types.Bytes, pos : Int, len : Int ) : Int { return 0; }
+	@:hlNative("std","process_stderr_read") static function _stderr_read( p : ProcessHandle, bytes : hl.types.Bytes, pos : Int, len : Int ) : Int { return 0; }
+
+}
+
+@:coreApi class Process {
+
+	var p : ProcessHandle;
+	public var stdout(default,null) : haxe.io.Input;
+	public var stderr(default,null) : haxe.io.Input;
+	public var stdin(default,null) : haxe.io.Output;
+
+	public function new( cmd : String, ?args : Array<String> ) : Void {
+		@:privateAccess {
+			var aargs = null;
+			if( args != null ) {
+				aargs = new hl.types.NativeArray<hl.types.Bytes>(args.length);
+				for( i in 0...args.length )
+					aargs[i] = args[i].bytes;
+			}
+			p = _run(cmd.bytes, aargs);
+		}
+		if( p == null )
+			throw new Sys.SysError("Process creation failure : "+cmd);
+		stdin = new Stdin(p);
+		stdout = new Stdout(p,true);
+		stderr = new Stdout(p,false);
+	}
+
+	public function getPid() : Int {
+		return _pid(p);
+	}
+
+	public function exitCode() : Int {
+		return _exit(p);
+	}
+
+	public function close() : Void {
+		_close(p);
+	}
+
+	public function kill() : Void {
+		_kill(p);
+	}
+
+	@:hlNative("std","process_run")	static function _run( cmd : hl.types.Bytes, args : hl.types.NativeArray<hl.types.Bytes> ) : ProcessHandle { return null; }
+	@:hlNative("std", "process_exit") static function _exit( p : ProcessHandle ) : Int { return 0; }
+	@:hlNative("std", "process_pid") static function _pid( p : ProcessHandle ) : Int { return 0; }
+	@:hlNative("std","process_close") static function _close( p : ProcessHandle ) : Void { }
+	@:hlNative("std","process_kill") static function _kill( p : ProcessHandle ) : Void { }
+
+}

+ 1 - 1
std/hl/types/BaseType.hx

@@ -28,7 +28,7 @@ class Enum extends BaseType {
 		for( i in 0...cl.length ) {
 			var name = cl[i];
 			__emap__.set(name, i);
-			__constructs__.push(String.__alloc__(name, name.ucs2Length(0)));
+			__constructs__.push(String.fromUCS2(name));
 		}
 		std.Type.register(__ename__.bytes,this);
 	}

+ 3 - 3
std/hl/types/Bytes.hx

@@ -91,7 +91,7 @@ package hl.types;
 	}
 
 	@:hlNative("std", "ucs2length")
-	function ucs2Length( bytePos : Int ) : Int {
+	public function ucs2Length( bytePos : Int ) : Int {
 		return 0;
 	}
 
@@ -101,12 +101,12 @@ package hl.types;
 	}
 
 	@:hlNative("std","utf8_to_utf16")
-	function utf8ToUtf16( bytePos : Int, outSize : Ref<Int> ) : Bytes {
+	public function utf8ToUtf16( bytePos : Int, outSize : Ref<Int> ) : Bytes {
 		return null;
 	}
 
 	@:hlNative("std","utf16_to_utf8")
-	function utf16ToUtf8( bytePos : Int, outSize : Ref<Int> ) : Bytes {
+	public function utf16ToUtf8( bytePos : Int, outSize : Ref<Int> ) : Bytes {
 		return null;
 	}
 

+ 1 - 1
std/hl/types/Type.hx

@@ -49,7 +49,7 @@ abstract TypeKind(Int) {
 
 	@:extern public inline function getName() : String {
 		var s = getNameBytes();
-		return @:privateAccess String.__alloc__(s, s.ucs2Length(0));
+		return @:privateAccess String.fromUCS2(s);
 	}
 
 	@:hlNative("std","type_instance_fields") public function getInstanceFields() : NativeArray<Bytes> {

+ 13 - 0
tests/sys/compile-hl.hxml

@@ -0,0 +1,13 @@
+compile-each.hxml
+-main Main
+-hl bin/_main.c
+
+--next
+compile-each.hxml
+-main TestArguments
+-cpp bin/_args.c
+
+--next
+compile-each.hxml
+-main ExitCode
+-cpp bin/_exit.c

+ 1 - 0
tests/sys/compile.hxml

@@ -7,3 +7,4 @@
 --next compile-cs.hxml
 --next compile-java.hxml
 --next compile-php.hxml
+--next compile-hl.hxml