Browse Source

[python] fix Std.parseInt() for haxedecimal with leading whitespaces
#8970

Aleksandr Kuzmenko 5 years ago
parent
commit
582fed42db
3 changed files with 41 additions and 19 deletions
  1. 0 1
      std/cs/_std/Std.hx
  2. 0 1
      std/java/_std/Std.hx
  3. 41 17
      std/python/_std/Std.hx

+ 0 - 1
std/cs/_std/Std.hx

@@ -79,7 +79,6 @@ import cs.internal.Exceptions;
 		if (x == null)
 			return null;
 
-		var ret = 0;
 		var base = 10;
 		var len = x.length;
 		var foundCount = 0;

+ 0 - 1
std/java/_std/Std.hx

@@ -63,7 +63,6 @@ import java.internal.Exceptions;
 		if (x == null)
 			return null;
 
-		var ret = 0;
 		var base = 10;
 		var len = x.length;
 		var foundCount = 0;

+ 41 - 17
std/python/_std/Std.hx

@@ -130,26 +130,50 @@ import python.Syntax;
 		try {
 			return UBuiltins.int(x);
 		} catch (e:Dynamic) {
-			try {
-				var prefix = x.substr(0, 2).toLowerCase();
-
-				if (prefix == "0x") {
-					return UBuiltins.int(x, 16);
+			var base = 10;
+			var len = x.length;
+			var foundCount = 0;
+			var sign = 0;
+			var firstDigitIndex = 0;
+			var lastDigitIndex = -1;
+			var previous = 0;
+
+			for(i in 0...len) {
+				var c = StringTools.fastCodeAt(x, i);
+				switch c {
+					case _ if((c > 8 && c < 14) || c == 32):
+						if(foundCount > 0) {
+							return null;
+						}
+						continue;
+					case '-'.code if(foundCount == 0):
+						sign = -1;
+					case '+'.code if(foundCount == 0):
+						sign = 1;
+					case '0'.code if(foundCount == 0 || (foundCount == 1 && sign != 0)):
+					case 'x'.code | 'X'.code if(previous == '0'.code && ((foundCount == 1 && sign == 0) || (foundCount == 2 && sign != 0))):
+						base = 16;
+					case _ if('0'.code <= c && c <= '9'.code):
+					case _ if(base == 16 && (('a'.code <= c && c <= 'z'.code) || ('A'.code <= c && c <= 'Z'.code))):
+					case _:
+						break;
+				}
+				if((foundCount == 0 && sign == 0) || (foundCount == 1 && sign != 0)) {
+					firstDigitIndex = i;
 				}
-				throw "fail";
-			} catch (e:Dynamic) {
-				var r = int(parseFloat(x));
-
-				if (r == null) {
-					var r1 = shortenPossibleNumber(x);
-					if (r1 != x) {
-						return parseInt(r1);
-					} else {
-						return null;
-					}
+				foundCount++;
+				lastDigitIndex = i;
+				previous = c;
+			}
+			if(firstDigitIndex <= lastDigitIndex) {
+				var digits = x.substring(firstDigitIndex, lastDigitIndex + 1);
+				return try {
+					(sign == -1 ? -1 : 1) * UBuiltins.int(digits, base);
+				} catch(e:Dynamic) {
+					null;
 				}
-				return r;
 			}
+			return null;
 		}
 	}