Ver Fonte

Added some more tests and error checking

Steven Hall há 8 anos atrás
pai
commit
ac575ffcc5

+ 20 - 7
src/runtime/gravity_core.c

@@ -1536,7 +1536,9 @@ static bool string_repeat (gravity_vm *vm, gravity_value_t *args, uint16_t nargs
 }
 
 
-// Returns -1 for error, and 0 otherwise
+// Returns -1 for out of bounds error
+// Returns -2 if we exit the loop wrong.
+// Returns 0 otherwise
 // Also return function arguments: index and ret
 // index: will help us to print out a runtime error if we go out of bounds
 // ret: is the returned string that our upper() and lower() methods return.
@@ -1557,7 +1559,8 @@ static int parse_arguments_for_upper_and_lower(gravity_vm *vm, int (*is_case)(in
 		// Check if all of search_string is already the case we want
 		bool is_all_correct_case = true;
 		for (int j = 0; j < search_str->len; ++j) {
-			if (!is_case(search_str->s[j])) {
+		 	// Better also make sure that it is an alpha character.
+			if (!is_case(search_str->s[j]) && isalpha(search_str->s[j])) {
 				is_all_correct_case = false;
 				break;
 			}
@@ -1568,7 +1571,9 @@ static int parse_arguments_for_upper_and_lower(gravity_vm *vm, int (*is_case)(in
 			return 0;
 		}
 
-		// Otherwise, parse it, and change the case it.
+		// Otherwise, parse it, and change the case
+		int iterations = 0;
+		bool isNotInfiniteLoop;
 		do {
 			char *ptr = strstr(ret, search_str->s);
 
@@ -1585,10 +1590,15 @@ static int parse_arguments_for_upper_and_lower(gravity_vm *vm, int (*is_case)(in
 				}
 				ret[j] = to_case(ret[j]);
 			}
-		} while(1); // Breaks out when no matches are found
-								// This results in an infinite loop if the user searches for
-								// a string that is already the correct case completely. Hence,
-								// the check further up
+			++iterations;
+		} while(isNotInfiniteLoop = iterations < ret_len);
+								// Breaks out when no matches are found
+								// We should never break out of this loop by this condition, as
+								// we should break out once we have no more matches. This is
+								// just a fail safe.
+		if (!isNotInfiniteLoop) {
+			return -2;
+		}
 	}
 	return 0;
 }
@@ -1624,6 +1634,9 @@ static bool string_upper (gravity_vm *vm, gravity_value_t *args, uint16_t nargs,
 			if (err == -1) {
 				RETURN_ERROR("Out of bounds error: index %d beyond bounds 0...%d", index, main_str->len-1);
 			}
+			else if (err == -2) {
+				RETURN_ERROR("search parse ran into an infinite loop");
+			}
 		}
 	}
 	RETURN_VALUE(VALUE_FROM_CSTRING(vm, ret), rindex);

+ 63 - 0
test/string/upper_lower_method_non_alpha.gravity

@@ -0,0 +1,63 @@
+#unittest {
+	name: "upper() and lower methods for string -- non alpha tests";
+	error: NONE;
+	result: true;
+};
+
+func main () {
+	var s = "Hello, World!"
+
+	// Full string
+	var a = s.upper() == "HELLO, WORLD!"
+	if (a == false) { System.print("a) failed"); return false }
+
+	var b = s.lower() == "hello, world!"
+	if (b == false) { System.print("b) failed"); return false }
+
+	// Single integer or string -- upper
+	var c = s.upper(5) == s
+	if (c == false) { System.print("c) failed"); return false }
+
+	var d = s.upper(",") == s
+	if (d == false) { System.print("d) failed"); return false }
+
+	// Single integer or string -- lower
+	var e = s.lower(5) == s
+	if (e == false) { System.print("e) failed"); return false }
+
+	var f = s.lower(",") == s
+	if (f == false) { System.print("f) failed"); return false }
+
+
+	// Longer strings -- upper
+	var g = s.upper("o,") == "HellO, World!"
+	if (g == false) { System.print("g) failed"); return false }
+
+	// Longer strings -- lower
+	var h = s.lower("o,") == s
+	if (h == false) { System.print("h) failed"); return false }
+
+	s = "HELLO, WORLD!"
+	var i = s.upper("O,") == s
+	if (i == false) { System.print("i) failed"); return false }
+
+	var j = s.lower("O,") == "HELLo, WORLD!"
+	if (j == false) { System.print("j) failed"); return false }
+
+	s = ","
+	var k = s.upper(",") == s
+	if (k == false) { System.print("k) failed"); return false }
+
+	var l = s.lower(",") == s
+	if (l == false) { System.print("l) failed"); return false }
+
+
+	s = ",!?:|"
+	var m = s.upper("!?") == s
+	if (m == false) { System.print("m) failed"); return false }
+
+	var n = s.lower("!?") == s
+	if (n == false) { System.print("m) failed"); return false }
+
+	return true
+}