Răsfoiți Sursa

Moved quoteWinArg, quotUnixArg, isEof out of StringTools to haxe.SysTools (#8151)

* Moved quoteWinArg, quotUnixArg, isEof out of StringTools to haxe.SysTools (closes #8109)

* minor

* changed StringTools.winMetaCharacters to be an alias for SysTools.winMetaCharacters

* fixed fastCodeAt doc to point to the new SysTools.isEofChar()

* StringTools.isEof() is back

* typo

* one more time
Alexander Kuzmenko 6 ani în urmă
părinte
comite
2f98d032ec

+ 7 - 77
std/StringTools.hx

@@ -500,11 +500,7 @@ class StringTools {
 		return c != c; // fast NaN
 		#elseif (neko || lua || eval)
 		return c == null;
-		#elseif cs
-		return c == -1;
-		#elseif java
-		return c == -1;
-		#elseif python
+		#elseif (cs || java || python)
 		return c == -1;
 		#else
 		return false;
@@ -517,26 +513,17 @@ class StringTools {
 		The input will be quoted, or escaped if necessary.
 	**/
 	@:noCompletion
+	@:deprecated('StringTools.quoteUnixArg() is deprecated. Use haxe.SysTools.quoteUnixArg() instead.')
 	public static function quoteUnixArg(argument:String):String {
-		// Based on cpython's shlex.quote().
-		// https://hg.python.org/cpython/file/a3f076d4f54f/Lib/shlex.py#l278
-
-		if (argument == "")
-			return "''";
-
-		if (!~/[^a-zA-Z0-9_@%+=:,.\/-]/.match(argument))
-			return argument;
-
-		// use single quotes, and put single quotes into double quotes
-		// the string $'b is then quoted as '$'"'"'b'
-		return "'" + replace(argument, "'", "'\"'\"'") + "'";
+		return inline haxe.SysTools.quoteUnixArg(argument);
 	}
 
 	/**
 		Character codes of the characters that will be escaped by `quoteWinArg(_, true)`.
 	**/
 	@:noCompletion
-	public static var winMetaCharacters = [" ".code, "(".code, ")".code, "%".code, "!".code, "^".code, "\"".code, "<".code, ">".code, "&".code, "|".code, "\n".code, "\r".code, ",".code, ";".code];
+	@:deprecated('StringTools.winMetaCharacters is deprecated. Use haxe.SysTools.winMetaCharacters instead.')
+	public static var winMetaCharacters:Array<Int> = cast haxe.SysTools.winMetaCharacters;
 
 	/**
 		Returns a String that can be used as a single command line argument
@@ -552,66 +539,9 @@ class StringTools {
 		```
 	**/
 	@:noCompletion
+	@:deprecated('StringTools.quoteWinArg() is deprecated. Use haxe.SysTools.quoteWinArg() instead.')
 	public static function quoteWinArg(argument:String, escapeMetaCharacters:Bool):String {
-		// If there is no space, tab, back-slash, or double-quotes, and it is not an empty string.
-		if (!~/^[^ \t\\"]+$/.match(argument)) {
-
-			// Based on cpython's subprocess.list2cmdline().
-			// https://hg.python.org/cpython/file/50741316dd3a/Lib/subprocess.py#l620
-
-			var result = new StringBuf();
-			var needquote = argument.indexOf(" ") != -1 || argument.indexOf("\t") != -1 || argument == "";
-
-			if (needquote)
-				result.add('"');
-
-			var bs_buf = new StringBuf();
-			for (i in 0...argument.length) {
-				switch (argument.charCodeAt(i)) {
-					case "\\".code:
-						// Don't know if we need to double yet.
-						bs_buf.add("\\");
-					case '"'.code:
-						// Double backslashes.
-						var bs = bs_buf.toString();
-						result.add(bs);
-						result.add(bs);
-						bs_buf = new StringBuf();
-						result.add('\\"');
-					case var c:
-						// Normal char
-						if (bs_buf.length > 0) {
-							result.add(bs_buf.toString());
-							bs_buf = new StringBuf();
-						}
-						result.addChar(c);
-				}
-			}
-
-			// Add remaining backslashes, if any.
-			result.add(bs_buf.toString());
-
-			if (needquote) {
-				result.add(bs_buf.toString());
-				result.add('"');
-			}
-
-			argument = result.toString();
-		}
-
-		if (escapeMetaCharacters) {
-			var result = new StringBuf();
-			for (i in 0...argument.length) {
-				var c = argument.charCodeAt(i);
-				if (winMetaCharacters.indexOf(c) >= 0) {
-					result.addChar("^".code);
-				}
-				result.addChar(c);
-			}
-			return result.toString();
-		} else {
-			return argument;
-		}
+		return inline haxe.SysTools.quoteWinArg(argument, escapeMetaCharacters);
 	}
 
 	#if java

+ 3 - 2
std/cpp/_std/Sys.hx

@@ -20,6 +20,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 import cpp.NativeSys;
+import haxe.SysTools;
 
 @:coreApi class Sys {
 
@@ -93,11 +94,11 @@ import cpp.NativeSys;
 				case "Windows":
 					cmd = [
 						for (a in [StringTools.replace(cmd, "/", "\\")].concat(args))
-						StringTools.quoteWinArg(a, true)
+						SysTools.quoteWinArg(a, true)
 					].join(" ");
 					return NativeSys.sys_command(cmd);
 				case _:
-					cmd = [cmd].concat(args).map(StringTools.quoteUnixArg).join(" ");
+					cmd = [cmd].concat(args).map(SysTools.quoteUnixArg).join(" ");
 					return NativeSys.sys_command(cmd);
 			}
 		}

+ 1 - 1
std/cs/_std/sys/io/Process.hx

@@ -80,7 +80,7 @@ class Process {
 			case "Windows":
 				[
 					for (a in args)
-					StringTools.quoteWinArg(a, false)
+					haxe.SysTools.quoteWinArg(a, false)
 				].join(" ");
 			case _:
 				// mono uses a slightly different quoting/escaping rule...

+ 3 - 2
std/eval/_std/Sys.hx

@@ -19,6 +19,7 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
+import haxe.SysTools;
 
 @:require(sys)
 @:coreApi
@@ -45,11 +46,11 @@ class Sys {
 				case "Windows":
 					cmd = [
 						for (a in [StringTools.replace(cmd, "/", "\\")].concat(args))
-						StringTools.quoteWinArg(a, true)
+						SysTools.quoteWinArg(a, true)
 					].join(" ");
 					return _command(cmd);
 				case _:
-					cmd = [cmd].concat(args).map(StringTools.quoteUnixArg).join(" ");
+					cmd = [cmd].concat(args).map(SysTools.quoteUnixArg).join(" ");
 					return _command(cmd);
 			}
 		}

+ 106 - 0
std/haxe/SysTools.hx

@@ -0,0 +1,106 @@
+package haxe;
+
+import haxe.ds.ReadOnlyArray;
+
+class SysTools {
+
+	/**
+		Character codes of the characters that will be escaped by `quoteWinArg(_, true)`.
+	**/
+	public static final winMetaCharacters:ReadOnlyArray<Int> = [" ".code, "(".code, ")".code, "%".code, "!".code, "^".code, "\"".code, "<".code, ">".code, "&".code, "|".code, "\n".code, "\r".code, ",".code, ";".code];
+
+	/**
+		Returns a String that can be used as a single command line argument
+		on Unix.
+		The input will be quoted, or escaped if necessary.
+	**/
+	public static function quoteUnixArg(argument:String):String {
+		// Based on cpython's shlex.quote().
+		// https://hg.python.org/cpython/file/a3f076d4f54f/Lib/shlex.py#l278
+
+		if (argument == "")
+			return "''";
+
+		if (!~/[^a-zA-Z0-9_@%+=:,.\/-]/.match(argument))
+			return argument;
+
+		// use single quotes, and put single quotes into double quotes
+		// the string $'b is then quoted as '$'"'"'b'
+		return "'" + StringTools.replace(argument, "'", "'\"'\"'") + "'";
+	}
+
+	/**
+		Returns a String that can be used as a single command line argument
+		on Windows.
+		The input will be quoted, or escaped if necessary, such that the output
+		will be parsed as a single argument using the rule specified in
+		http://msdn.microsoft.com/en-us/library/ms880421
+
+		Examples:
+		```haxe
+		quoteWinArg("abc") == "abc";
+		quoteWinArg("ab c") == '"ab c"';
+		```
+	**/
+	public static function quoteWinArg(argument:String, escapeMetaCharacters:Bool):String {
+		// If there is no space, tab, back-slash, or double-quotes, and it is not an empty string.
+		if (!~/^[^ \t\\"]+$/.match(argument)) {
+
+			// Based on cpython's subprocess.list2cmdline().
+			// https://hg.python.org/cpython/file/50741316dd3a/Lib/subprocess.py#l620
+
+			var result = new StringBuf();
+			var needquote = argument.indexOf(" ") != -1 || argument.indexOf("\t") != -1 || argument == "";
+
+			if (needquote)
+				result.add('"');
+
+			var bs_buf = new StringBuf();
+			for (i in 0...argument.length) {
+				switch (argument.charCodeAt(i)) {
+					case "\\".code:
+						// Don't know if we need to double yet.
+						bs_buf.add("\\");
+					case '"'.code:
+						// Double backslashes.
+						var bs = bs_buf.toString();
+						result.add(bs);
+						result.add(bs);
+						bs_buf = new StringBuf();
+						result.add('\\"');
+					case var c:
+						// Normal char
+						if (bs_buf.length > 0) {
+							result.add(bs_buf.toString());
+							bs_buf = new StringBuf();
+						}
+						result.addChar(c);
+				}
+			}
+
+			// Add remaining backslashes, if any.
+			result.add(bs_buf.toString());
+
+			if (needquote) {
+				result.add(bs_buf.toString());
+				result.add('"');
+			}
+
+			argument = result.toString();
+		}
+
+		if (escapeMetaCharacters) {
+			var result = new StringBuf();
+			for (i in 0...argument.length) {
+				var c = argument.charCodeAt(i);
+				if (winMetaCharacters.indexOf(c) >= 0) {
+					result.addChar("^".code);
+				}
+				result.addChar(c);
+			}
+			return result.toString();
+		} else {
+			return argument;
+		}
+	}
+}

+ 1 - 1
std/haxe/xml/Parser.hx

@@ -112,7 +112,7 @@ class Parser
 
 	/**
 		Parses the String into an XML Document. Set strict parsing to true in order to enable a strict check of XML attributes and entities.
-		
+
 		@throws haxe.xml.XmlParserException
 	**/
 	static public function parse(str:String, strict = false)

+ 4 - 2
std/hl/_std/Sys.hx

@@ -19,6 +19,8 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
+import haxe.SysTools;
+
 class SysError {
 	public var msg : String;
 	public function new(msg) {
@@ -121,11 +123,11 @@ class Sys {
 				case "Windows":
 					cmd = [
 						for (a in [StringTools.replace(cmd, "/", "\\")].concat(args))
-						StringTools.quoteWinArg(a, true)
+						SysTools.quoteWinArg(a, true)
 					].join(" ");
 					code = sys_command(getPath(cmd));
 				case _:
-					cmd = [cmd].concat(args).map(StringTools.quoteUnixArg).join(" ");
+					cmd = [cmd].concat(args).map(SysTools.quoteUnixArg).join(" ");
 					code = sys_command(getPath(cmd));
 			}
 		}

+ 4 - 2
std/java/_std/sys/io/Process.hx

@@ -20,6 +20,8 @@
  * DEALINGS IN THE SOFTWARE.
  */
 package sys.io;
+
+import haxe.SysTools;
 import haxe.io.Bytes;
 import haxe.io.BytesInput;
 import haxe.io.Eof;
@@ -60,10 +62,10 @@ class Process {
 			pargs = new NativeArray(args.length + 1);
 			switch (sysName) {
 				case "Windows":
-					pargs[0] = StringTools.quoteWinArg(cmd, false);
+					pargs[0] = SysTools.quoteWinArg(cmd, false);
 					for (i in 0...args.length)
 					{
-						pargs[i + 1] = StringTools.quoteWinArg(args[i], false);
+						pargs[i + 1] = SysTools.quoteWinArg(args[i], false);
 					}
 				case _:
 					pargs[0] = cmd;

+ 3 - 2
std/lua/Boot.hx

@@ -23,6 +23,7 @@
 package lua;
 
 import haxe.Constraints.Function;
+import haxe.SysTools;
 
 
 @:dox(hide)
@@ -338,10 +339,10 @@ class Boot {
 				case "Windows":
 					cmd = [
 						for (a in [StringTools.replace(cmd, "/", "\\")].concat(args))
-						StringTools.quoteWinArg(a, true)
+						SysTools.quoteWinArg(a, true)
 					].join(" ");
 				case _:
-					cmd = [cmd].concat(args).map(StringTools.quoteUnixArg).join(" ");
+					cmd = [cmd].concat(args).map(SysTools.quoteUnixArg).join(" ");
 			}
 		}
 		return cmd;

+ 4 - 2
std/lua/_std/sys/io/File.hx

@@ -20,6 +20,8 @@
  * DEALINGS IN THE SOFTWARE.
  */
 package sys.io;
+
+import haxe.SysTools;
 import lua.Lua;
 import lua.Io;
 import lua.Os;
@@ -49,8 +51,8 @@ class File {
 
 	public static function copy( srcPath : String, dstPath : String ) : Void {
 		var result = switch (Sys.systemName()) {
-			case "Windows" : Os.execute('copy ${StringTools.quoteWinArg(srcPath, true)} ${StringTools.quoteWinArg(dstPath,true)}');
-			default : Os.execute('cp ${StringTools.quoteUnixArg(srcPath)} ${StringTools.quoteUnixArg(dstPath)}');
+			case "Windows" : Os.execute('copy ${SysTools.quoteWinArg(srcPath, true)} ${SysTools.quoteWinArg(dstPath,true)}');
+			default : Os.execute('cp ${SysTools.quoteUnixArg(srcPath)} ${SysTools.quoteUnixArg(dstPath)}');
 		};
 		if(
 			#if (lua_ver >= 5.2) !result.success

+ 2 - 1
std/lua/_std/sys/io/Process.hx

@@ -29,6 +29,7 @@ import lua.Boot;
 import lua.Table;
 import lua.NativeStringTools;
 
+import haxe.SysTools;
 import haxe.io.Bytes;
 import haxe.io.Error;
 import haxe.io.Eof;
@@ -44,7 +45,7 @@ class Process {
 	public var stderr(default,null) : haxe.io.Input;
 	public var  stdin(default,null) : haxe.io.Output;
 
-	static var argQuote = Sys.systemName() == "Windows" ? function(x) return StringTools.quoteWinArg(x,true) : StringTools.quoteUnixArg;
+	static var argQuote = Sys.systemName() == "Windows" ? function(x) return SysTools.quoteWinArg(x,true) : SysTools.quoteUnixArg;
 	static var _shell = Sys.systemName() == "Windows" ? 'cmd.exe' : '/bin/sh';
 
 	/**

+ 4 - 2
std/neko/_std/Sys.hx

@@ -19,6 +19,8 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
+import haxe.SysTools;
+
 @:coreApi class Sys {
 
 	public static function print( v : Dynamic ) : Void {
@@ -99,11 +101,11 @@
 				case "Windows":
 					cmd = [
 						for (a in [StringTools.replace(cmd, "/", "\\")].concat(args))
-						StringTools.quoteWinArg(a, true)
+						SysTools.quoteWinArg(a, true)
 					].join(" ");
 					return sys_command(untyped cmd.__s);
 				case _:
-					cmd = [cmd].concat(args).map(StringTools.quoteUnixArg).join(" ");
+					cmd = [cmd].concat(args).map(SysTools.quoteUnixArg).join(" ");
 					return sys_command(untyped cmd.__s);
 			}
 		}

+ 13 - 97
std/php/_std/StringTools.hx

@@ -120,107 +120,23 @@ import php.*;
 		return Boot.unsafeOrd(char);
 	}
 
-	public static inline function isEof( c : Int ) : Bool {
+	@:noUsing public static inline function isEof( c : Int ) : Bool {
 		return c == 0;
 	}
 
-	/**
-		Returns a String that can be used as a single command line argument
-		on Unix.
-		The input will be quoted, or escaped if necessary.
-	**/
+	@:noCompletion
+	@:deprecated('StringTools.quoteUnixArg() is deprecated. Use haxe.SysTools.quoteUnixArg() instead.')
 	public static function quoteUnixArg(argument:String):String {
-		// Based on cpython's shlex.quote().
-		// https://hg.python.org/cpython/file/a3f076d4f54f/Lib/shlex.py#l278
-
-		if (argument == "")
-			return "''";
-
-		if (!~/[^a-zA-Z0-9_@%+=:,.\/-]/.match(argument))
-			return argument;
-
-		// use single quotes, and put single quotes into double quotes
-		// the string $'b is then quoted as '$'"'"'b'
-		return "'" + replace(argument, "'", "'\"'\"'") + "'";
-	}
-
-	/**
-		Character codes of the characters that will be escaped by `quoteWinArg(_, true)`.
-	**/
-	public static var winMetaCharacters = [";".code, ",".code, " ".code, "(".code, ")".code, "%".code, "!".code, "^".code, "\"".code, "<".code, ">".code, "&".code, "|".code, "\n".code, "\r".code];
-
-	/**
-		Returns a String that can be used as a single command line argument
-		on Windows.
-		The input will be quoted, or escaped if necessary, such that the output
-		will be parsed as a single argument using the rule specified in
-		http://msdn.microsoft.com/en-us/library/ms880421
-
-		Examples:
-		```haxe
-		quoteWinArg("abc") == "abc";
-		quoteWinArg("ab c") == '"ab c"';
-		```
-	**/
-	public static function quoteWinArg(argument:String, escapeMetaCharacters:Bool):String {
-		// If there is no space, tab, back-slash, or double-quotes, and it is not an empty string.
-		if (!~/^[^ \t\\"]+$/.match(argument)) {
-
-			// Based on cpython's subprocess.list2cmdline().
-			// https://hg.python.org/cpython/file/50741316dd3a/Lib/subprocess.py#l620
-
-			var result = new StringBuf();
-			var needquote = argument.indexOf(" ") != -1 || argument.indexOf("\t") != -1 || argument == "";
-
-			if (needquote)
-				result.add('"');
-
-			var bs_buf = new StringBuf();
-			for (i in 0...argument.length) {
-				switch (argument.charCodeAt(i)) {
-					case "\\".code:
-						// Don't know if we need to double yet.
-						bs_buf.add("\\");
-					case '"'.code:
-						// Double backslashes.
-						var bs = bs_buf.toString();
-						result.add(bs);
-						result.add(bs);
-						bs_buf = new StringBuf();
-						result.add('\\"');
-					case var c:
-						// Normal char
-						if (bs_buf.length > 0) {
-							result.add(bs_buf.toString());
-							bs_buf = new StringBuf();
-						}
-						result.addChar(c);
-				}
-			}
-
-			// Add remaining backslashes, if any.
-			result.add(bs_buf.toString());
-
-			if (needquote) {
-				result.add(bs_buf.toString());
-				result.add('"');
-			}
-
-			argument = result.toString();
-		}
+		return inline haxe.SysTools.quoteUnixArg(argument);
+	}
 
-		if (escapeMetaCharacters) {
-			var result = new StringBuf();
-			for (i in 0...argument.length) {
-				var c = argument.charCodeAt(i);
-				if (winMetaCharacters.indexOf(c) >= 0) {
-					result.addChar("^".code);
-				}
-				result.addChar(c);
-			}
-			return result.toString();
-		} else {
-			return argument;
-		}
+	@:noCompletion
+	@:deprecated('StringTools.winMetaCharacters is deprecated. Use haxe.SysTools.winMetaCharacters instead.')
+	public static var winMetaCharacters:Array<Int> =  cast haxe.SysTools.winMetaCharacters;
+
+	@:noCompletion
+	@:deprecated('StringTools.quoteWinArg() is deprecated. Use haxe.SysTools.quoteWinArg() instead.')
+	public static function quoteWinArg(argument:String, escapeMetaCharacters:Bool):String {
+		return inline haxe.SysTools.quoteWinArg(argument, escapeMetaCharacters);
 	}
 }

+ 3 - 2
std/php/_std/Sys.hx

@@ -23,6 +23,7 @@
 import php.*;
 import sys.io.FileOutput;
 import sys.io.FileInput;
+import haxe.SysTools;
 
 @:coreApi class Sys {
 	/** Environment variables set by `Sys.putEnv()` */
@@ -85,10 +86,10 @@ import sys.io.FileInput;
 				case "Windows":
 					cmd = [
 						for (a in [StringTools.replace(cmd, "/", "\\")].concat(args))
-						StringTools.quoteWinArg(a, true)
+						SysTools.quoteWinArg(a, true)
 					].join(" ");
 				case _:
-					cmd = [cmd].concat(args).map(StringTools.quoteUnixArg).join(" ");
+					cmd = [cmd].concat(args).map(SysTools.quoteUnixArg).join(" ");
 			}
 		}
 		var result = Boot.deref(0);

+ 3 - 2
std/php/_std/sys/io/Process.hx

@@ -23,6 +23,7 @@ package sys.io;
 
 import php.*;
 import haxe.io.*;
+import haxe.SysTools;
 
 using StringTools;
 using php.Global;
@@ -194,9 +195,9 @@ class Process {
 
 		return switch (Sys.systemName()) {
 			case "Windows":
-				[cmd.replace("/", "\\")].concat(args).map(StringTools.quoteWinArg.bind(_, true)).join(" ");
+				[cmd.replace("/", "\\")].concat(args).map(SysTools.quoteWinArg.bind(_, true)).join(" ");
 			case _:
-				[cmd].concat(args).map(StringTools.quoteUnixArg).join(" ");
+				[cmd].concat(args).map(SysTools.quoteUnixArg).join(" ");
 		}
 	}
 

+ 3 - 3
tests/unit/src/unitstd/StringTools.unit.hx

@@ -128,12 +128,12 @@ var str = "abc";
 StringTools.fastCodeAt(str, 0) == "a".code;
 StringTools.fastCodeAt(str, 1) == "b".code;
 StringTools.fastCodeAt(str, 2) == "c".code;
+StringTools.fastCodeAt(String.fromCharCode(128), 0) == 128;
+StringTools.fastCodeAt(String.fromCharCode(255), 0) == 255;
 StringTools.isEof(StringTools.fastCodeAt(str, 0)) == false;
 StringTools.isEof(StringTools.fastCodeAt(str, 1)) == false;
 StringTools.isEof(StringTools.fastCodeAt(str, 2)) == false;
 StringTools.isEof(StringTools.fastCodeAt(str, 3)) == true;
-StringTools.fastCodeAt(String.fromCharCode(128), 0) == 128;
-StringTools.fastCodeAt(String.fromCharCode(255), 0) == 255;
 StringTools.isEof(StringTools.fastCodeAt(str, 2)) == false;
 StringTools.isEof(StringTools.fastCodeAt(str, 3)) == true;
 StringTools.isEof(StringTools.fastCodeAt("", 0)) == true;
@@ -147,4 +147,4 @@ StringTools.isEof( -1) == true;
 // how do I test this here?
 #else
 StringTools.isEof(0) == true;
-#end
+#end