فهرست منبع

Added `Sys.programPath()` and deprecated `Sys.executablePath()`. See #3401.

Andy Li 9 سال پیش
والد
کامیت
c4ee4ab60d
11فایلهای تغییر یافته به همراه122 افزوده شده و 8 حذف شده
  1. 14 0
      interp.ml
  2. 8 1
      std/Sys.hx
  3. 5 1
      std/cpp/_std/Sys.hx
  4. 5 1
      std/cs/_std/Sys.hx
  5. 5 1
      std/hl/_std/Sys.hx
  6. 8 1
      std/java/_std/Sys.hx
  7. 37 1
      std/neko/_std/Sys.hx
  8. 7 1
      std/php/_std/Sys.hx
  9. 7 1
      std/python/_std/Sys.hx
  10. 1 0
      std/python/lib/Inspect.hx
  11. 25 0
      tests/sys/src/TestSys.hx

+ 14 - 0
interp.ml

@@ -1775,6 +1775,20 @@ let std_lib =
 		"sys_exe_path", Fun0 (fun() ->
 			VString (Sys.argv.(0))
 		);
+		"sys_program_path", Fun0 (fun() ->
+			let ctx = get_ctx() in
+			let com = ctx.curapi.get_com() in
+			match com.main_class with
+			| None -> error()
+			| Some p ->
+				let path_s path =
+					match path with | ([], s) -> s | (p, s) -> (String.concat "." (fst path)) ^ "." ^ (snd path)
+				in
+				match ctx.curapi.get_type (path_s p) with
+				| Some(TInst (c, _)) ->
+					VString (Extc.get_full_path c.cl_pos.Ast.pfile)
+				| _ -> error();
+		);
 		"sys_env", Fun0 (fun() ->
 			let env = Unix.environment() in
 			let rec loop acc i =

+ 8 - 1
std/Sys.hx

@@ -116,7 +116,14 @@ extern class Sys {
 	/**
 		Returns the path to the current executable that we are running.
 	**/
-	static function executablePath() : String;
+	@:deprecated("Use programPath instead") static function executablePath() : String;
+
+	/**
+		Returns the absolute path to the current program file that we are running.
+		Concretely, for an executable binary, it returns the path to the binary.
+		For a script (e.g. a PHP file), it returns the path to the script.
+	**/
+	static function programPath() : String;
 
 	/**
 		Read a single input character from the standard input (without blocking) and returns it. Setting [echo] to true will also display it on the output.

+ 5 - 1
std/cpp/_std/Sys.hx

@@ -111,7 +111,11 @@
 		return sys_cpu_time();
 	}
 
-	public static function executablePath() : String {
+	@:deprecated("Use programPath instead") public static function executablePath() : String {
+		return new String(sys_exe_path());
+	}
+
+	public static function programPath() : String {
 		return new String(sys_exe_path());
 	}
 

+ 5 - 1
std/cs/_std/Sys.hx

@@ -156,11 +156,15 @@ class Sys {
 		return Environment.TickCount / 1000;
 	}
 
-	public static inline function executablePath() : String
+	@:deprecated("Use programPath instead") public static inline function executablePath() : String
 	{
 		return cs.system.reflection.Assembly.GetExecutingAssembly().GetName().CodeBase;
 	}
 
+	public static function programPath() : String {
+		return cs.system.reflection.Assembly.GetExecutingAssembly().Location;
+	}
+
 	public static function getChar( echo : Bool ) : Int
 	{
 		#if !(Xbox || CF || MF) //Xbox, Compact Framework, Micro Framework

+ 5 - 1
std/hl/_std/Sys.hx

@@ -114,7 +114,11 @@ class Sys {
 		return code;
 	}
 
-	public static function executablePath() : String {
+	@:deprecated("Use programPath instead") public static function executablePath() : String {
+		return makePath(sys_exe_path());
+	}
+
+	public static function programPath() : String {
 		return makePath(sys_exe_path());
 	}
 

+ 8 - 1
std/java/_std/Sys.hx

@@ -137,11 +137,18 @@ using haxe.Int64;
 		return cast(System.nanoTime(), Float) / 1000000000;
 	}
 
-	public static function executablePath() : String
+	@:deprecated("Use programPath instead") public static function executablePath() : String
 	{
 		return getCwd();
 	}
 
+	public static function programPath() : String {
+		return java.Lib.toNativeType(Sys)
+			.getProtectionDomain()
+			.getCodeSource()
+			.getLocation().toURI().getPath();
+	}
+
 	public static function getChar( echo : Bool ) : Int
 	{
 		//TODO

+ 37 - 1
std/neko/_std/Sys.hx

@@ -121,10 +121,18 @@
 		return sys_cpu_time();
 	}
 
-	public static function executablePath() : String {
+	@:deprecated("Use programPath instead") public static function executablePath() : String {
 		return new String(sys_exe_path());
 	}
 
+	public static function programPath() : String {
+		#if interp
+		return new String(sys_program_path());
+		#else
+		return sys_program_path();
+		#end
+	}
+
 	public static function environment() : Map<String,String> {
 		var l : Array<Dynamic> = sys_env();
 		var h = new haxe.ds.StringMap();
@@ -147,6 +155,34 @@
 	private static var sys_time = neko.Lib.load("std","sys_time",0);
 	private static var sys_cpu_time = neko.Lib.load("std","sys_cpu_time",0);
 	private static var sys_exe_path = neko.Lib.load("std","sys_exe_path",0);
+	#if interp
+	private static var sys_program_path = neko.Lib.load("std","sys_program_path",0);
+	#else
+	// It has to be initialized before any call to loadModule or Sys.setCwd()...
+	private static var sys_program_path = {
+		switch ([for (m in neko.vm.Loader.local().getCache().keys()) m]) {
+			case [m]:
+				try {
+					var p = sys.FileSystem.fullPath(m);
+					function() return p;
+				} catch (e:Dynamic) {
+					// maybe the neko module name was supplied without .n extension...
+					if (!StringTools.endsWith(m, ".n")) {
+						try {
+							var p = sys.FileSystem.fullPath(m + ".n");
+							function() return p;
+						} catch (e:Dynamic) {
+							function() return m;
+						}
+					} else {
+						function() return m;
+					}
+				}
+			case modules:
+				function() return throw "cannot detemine the main module from cache: " + modules;
+		}
+	}
+	#end
 	private static var sys_env = neko.Lib.load("std","sys_env",0);
 
 	private static var file_stdin = neko.Lib.load("std","file_stdin",0);

+ 7 - 1
std/php/_std/Sys.hx

@@ -99,10 +99,16 @@
 		return untyped __call__("microtime", true) - __php__("$_SERVER['REQUEST_TIME']");
 	}
 
-	public static function executablePath() : String {
+	@:deprecated("Use programPath instead") public static function executablePath() : String {
 		return untyped __php__("$_SERVER['SCRIPT_FILENAME']");
 	}
 
+	// It has to be initialized before any call to Sys.setCwd()...
+	static var _programPath = sys.FileSystem.fullPath(untyped __php__("$_SERVER['SCRIPT_FILENAME']"));
+	public static function programPath() : String {
+		return _programPath;
+	}
+
 	public static function environment() : Map<String,String> {
 		return php.Lib.hashOfAssociativeArray(untyped __php__("$_SERVER"));
 	}

+ 7 - 1
std/python/_std/Sys.hx

@@ -111,10 +111,16 @@ class Sys {
 		return python.lib.Time.clock();
 	}
 
-	public static function executablePath() : String {
+	@:deprecated("Use programPath instead") public static function executablePath() : String {
 		return python.lib.Sys.argv[0];
 	}
 
+	// It has to be initialized before any call to Sys.setCwd()...
+	static var _programPath = sys.FileSystem.fullPath(python.lib.Inspect.getsourcefile(Sys));
+	public static function programPath() : String {
+		return _programPath;
+	}
+
 	public static function getChar( echo : Bool ) : Int {
 
 		var ch = switch (systemName()) {

+ 1 - 0
std/python/lib/Inspect.hx

@@ -29,4 +29,5 @@ extern class Inspect {
 	static function ismethod(object:Dynamic):Bool;
 	static function isclass(object:Dynamic):Bool;
 	static function isfunction(object:Dynamic):Bool;
+	static function getsourcefile(object:Dynamic):String;
 }

+ 25 - 0
tests/sys/src/TestSys.hx

@@ -16,6 +16,31 @@ class TestSys extends TestCommandBase {
 		#end
 	}
 
+	function testProgramPath() {
+		var p = Sys.programPath();
+
+		assertTrue(haxe.io.Path.isAbsolute(p));
+
+		#if interp
+			assertTrue(StringTools.endsWith(p, "Main.hx"));
+		#elseif neko
+			assertTrue(StringTools.endsWith(p, "sys.n"));
+		#elseif cpp
+			switch (Sys.systemName()) {
+				case "Windows":
+					assertTrue(StringTools.endsWith(p, "Main-debug.exe"));
+				case _:
+					assertTrue(StringTools.endsWith(p, "Main-debug"));
+			}
+		#elseif cs
+			assertTrue(StringTools.endsWith(p, "Main-Debug.exe"));
+		#elseif java
+			assertTrue(StringTools.endsWith(p, "Main-Debug.jar"));
+		#elseif python
+			assertTrue(StringTools.endsWith(p, "sys.py"));
+		#end
+	}
+
 	#if !java
 	function testCwd() {
 		var cur = Sys.getCwd();