Browse Source

Fix left aligned integer sign in string formatting

(cherry picked from commit 767134fd8d0fb489c78d527b4059b9b019fad23d)
Haoyu Qiu 3 years ago
parent
commit
a3f91b9fdc
2 changed files with 63 additions and 15 deletions
  1. 18 15
      core/ustring.cpp
  2. 45 0
      main/tests/test_string.cpp

+ 18 - 15
core/ustring.cpp

@@ -4201,7 +4201,7 @@ String String::sprintf(const Array &values, bool *error) const {
 	int min_chars = 0;
 	int min_chars = 0;
 	int min_decimals = 0;
 	int min_decimals = 0;
 	bool in_decimals = false;
 	bool in_decimals = false;
-	bool pad_with_zeroes = false;
+	bool pad_with_zeros = false;
 	bool left_justified = false;
 	bool left_justified = false;
 	bool show_sign = false;
 	bool show_sign = false;
 
 
@@ -4252,7 +4252,7 @@ String String::sprintf(const Array &values, bool *error) const {
 
 
 					// Padding.
 					// Padding.
 					int pad_chars_count = (value < 0 || show_sign) ? min_chars - 1 : min_chars;
 					int pad_chars_count = (value < 0 || show_sign) ? min_chars - 1 : min_chars;
-					String pad_char = pad_with_zeroes ? String("0") : String(" ");
+					String pad_char = pad_with_zeros ? String("0") : String(" ");
 					if (left_justified) {
 					if (left_justified) {
 						str = str.rpad(pad_chars_count, pad_char);
 						str = str.rpad(pad_chars_count, pad_char);
 					} else {
 					} else {
@@ -4260,10 +4260,13 @@ String String::sprintf(const Array &values, bool *error) const {
 					}
 					}
 
 
 					// Sign.
 					// Sign.
-					if (show_sign && value >= 0) {
-						str = str.insert(pad_with_zeroes ? 0 : str.length() - number_len, "+");
-					} else if (value < 0) {
-						str = str.insert(pad_with_zeroes ? 0 : str.length() - number_len, "-");
+					if (show_sign || value < 0) {
+						String sign_char = value < 0 ? "-" : "+";
+						if (left_justified) {
+							str = str.insert(0, sign_char);
+						} else {
+							str = str.insert(pad_with_zeros ? 0 : str.length() - number_len, sign_char);
+						}
 					}
 					}
 
 
 					formatted += str;
 					formatted += str;
@@ -4292,13 +4295,9 @@ String String::sprintf(const Array &values, bool *error) const {
 
 
 					// Padding. Leave room for sign later if required.
 					// Padding. Leave room for sign later if required.
 					int pad_chars_count = (is_negative || show_sign) ? min_chars - 1 : min_chars;
 					int pad_chars_count = (is_negative || show_sign) ? min_chars - 1 : min_chars;
-					String pad_char = pad_with_zeroes ? String("0") : String(" ");
+					String pad_char = pad_with_zeros ? String("0") : String(" ");
 					if (left_justified) {
 					if (left_justified) {
-						if (pad_with_zeroes) {
-							return "left justification cannot be used with zeros as the padding";
-						} else {
-							str = str.rpad(pad_chars_count, pad_char);
-						}
+						str = str.rpad(pad_chars_count, pad_char);
 					} else {
 					} else {
 						str = str.lpad(pad_chars_count, pad_char);
 						str = str.lpad(pad_chars_count, pad_char);
 					}
 					}
@@ -4309,7 +4308,7 @@ String String::sprintf(const Array &values, bool *error) const {
 						if (left_justified) {
 						if (left_justified) {
 							str = str.insert(0, sign_char);
 							str = str.insert(0, sign_char);
 						} else {
 						} else {
-							str = str.insert(pad_with_zeroes ? 0 : str.length() - initial_len, sign_char);
+							str = str.insert(pad_with_zeros ? 0 : str.length() - initial_len, sign_char);
 						}
 						}
 					}
 					}
 
 
@@ -4396,7 +4395,11 @@ String String::sprintf(const Array &values, bool *error) const {
 						min_decimals += n;
 						min_decimals += n;
 					} else {
 					} else {
 						if (c == '0' && min_chars == 0) {
 						if (c == '0' && min_chars == 0) {
-							pad_with_zeroes = true;
+							if (left_justified) {
+								WARN_PRINT("'0' flag ignored with '-' flag in string format");
+							} else {
+								pad_with_zeros = true;
+							}
 						} else {
 						} else {
 							min_chars *= 10;
 							min_chars *= 10;
 							min_chars += n;
 							min_chars += n;
@@ -4445,7 +4448,7 @@ String String::sprintf(const Array &values, bool *error) const {
 					// Back to defaults:
 					// Back to defaults:
 					min_chars = 0;
 					min_chars = 0;
 					min_decimals = 6;
 					min_decimals = 6;
-					pad_with_zeroes = false;
+					pad_with_zeros = false;
 					left_justified = false;
 					left_justified = false;
 					show_sign = false;
 					show_sign = false;
 					in_decimals = false;
 					in_decimals = false;

+ 45 - 0
main/tests/test_string.cpp

@@ -555,6 +555,42 @@ bool test_28() {
 	OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
 	OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
 	state = state && success;
 	state = state && success;
 
 
+	// Negative int left padded with spaces.
+	format = "fish %5d frog";
+	args.clear();
+	args.push_back(-5);
+	output = format.sprintf(args, &error);
+	success = (output == String("fish    -5 frog") && !error);
+	OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
+	state = state && success;
+
+	// Negative int left padded with zeros.
+	format = "fish %05d frog";
+	args.clear();
+	args.push_back(-5);
+	output = format.sprintf(args, &error);
+	success = (output == String("fish -0005 frog") && !error);
+	OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
+	state = state && success;
+
+	// Negative int right padded with spaces.
+	format = "fish %-5d frog";
+	args.clear();
+	args.push_back(-5);
+	output = format.sprintf(args, &error);
+	success = (output == String("fish -5    frog") && !error);
+	OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
+	state = state && success;
+
+	// Negative int right padded with zeros. (0 ignored)
+	format = "fish %-05d frog";
+	args.clear();
+	args.push_back(-5);
+	output = format.sprintf(args, &error);
+	success = (output == String("fish -5    frog") && !error);
+	OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
+	state = state && success;
+
 	// Hex (lower)
 	// Hex (lower)
 	format = "fish %x frog";
 	format = "fish %x frog";
 	args.clear();
 	args.clear();
@@ -656,6 +692,15 @@ bool test_28() {
 	OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
 	OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
 	state = state && success;
 	state = state && success;
 
 
+	// Negative real right padded with zeros. (0 ignored)
+	format = "fish %-011f frog";
+	args.clear();
+	args.push_back(-99.99);
+	output = format.sprintf(args, &error);
+	success = (output == String("fish -99.990000  frog") && !error);
+	OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL");
+	state = state && success;
+
 	/////// Strings.
 	/////// Strings.
 
 
 	// String
 	// String