Browse Source

Merge pull request #1765 from Kelimion/more_opt_handling

Handle negative integer flags, add deprecation warnings.
Jeroen van Rijn 3 years ago
parent
commit
6aaab4988e
3 changed files with 53 additions and 23 deletions
  1. 27 3
      src/big_int.cpp
  2. 5 1
      src/exact_value.cpp
  3. 21 19
      src/main.cpp

+ 27 - 3
src/big_int.cpp

@@ -40,7 +40,7 @@ typedef mp_int BigInt;
 void big_int_from_u64(BigInt *dst, u64 x);
 void big_int_from_u64(BigInt *dst, u64 x);
 void big_int_from_i64(BigInt *dst, i64 x);
 void big_int_from_i64(BigInt *dst, i64 x);
 void big_int_init    (BigInt *dst, BigInt const *src);
 void big_int_init    (BigInt *dst, BigInt const *src);
-void big_int_from_string(BigInt *dst, String const &s);
+void big_int_from_string(BigInt *dst, String const &s, bool *success);
 
 
 void big_int_dealloc(BigInt *dst) {
 void big_int_dealloc(BigInt *dst) {
 	mp_clear(dst);
 	mp_clear(dst);
@@ -84,7 +84,7 @@ void big_int_quo_eq(BigInt *dst, BigInt const *x);
 void big_int_rem_eq(BigInt *dst, BigInt const *x);
 void big_int_rem_eq(BigInt *dst, BigInt const *x);
 
 
 bool big_int_is_neg(BigInt const *x);
 bool big_int_is_neg(BigInt const *x);
-
+void big_int_neg(BigInt *dst, BigInt const *x);
 
 
 void big_int_add_eq(BigInt *dst, BigInt const *x) {
 void big_int_add_eq(BigInt *dst, BigInt const *x) {
 	BigInt res = {};
 	BigInt res = {};
@@ -169,7 +169,11 @@ BigInt big_int_make_i64(i64 x) {
 }
 }
 
 
 
 
-void big_int_from_string(BigInt *dst, String const &s) {
+void big_int_from_string(BigInt *dst, String const &s, bool *success) {
+	*success = true;
+
+	bool is_negative = false;
+
 	u64 base = 10;
 	u64 base = 10;
 	bool has_prefix = false;
 	bool has_prefix = false;
 	if (s.len > 2 && s[0] == '0') {
 	if (s.len > 2 && s[0] == '0') {
@@ -197,11 +201,26 @@ void big_int_from_string(BigInt *dst, String const &s) {
 	isize i = 0;
 	isize i = 0;
 	for (; i < len; i++) {
 	for (; i < len; i++) {
 		Rune r = cast(Rune)text[i];
 		Rune r = cast(Rune)text[i];
+
+		if (r == '-') {
+			if (is_negative) {
+				// NOTE(Jeroen): Can't have a doubly negative number.
+				*success = false;
+				return;
+			}
+			is_negative = true;
+			continue;
+		}
+
 		if (r == '_') {
 		if (r == '_') {
 			continue;
 			continue;
 		}
 		}
 		u64 v = u64_digit_value(r);
 		u64 v = u64_digit_value(r);
 		if (v >= base) {
 		if (v >= base) {
+			// NOTE(Jeroen): Can still be a valid integer if the next character is an `e` or `E`.
+			if (r != 'e' && r != 'E') {
+				*success = false;
+			}
 			break;
 			break;
 		}
 		}
 		BigInt val = big_int_make_u64(v);
 		BigInt val = big_int_make_u64(v);
@@ -225,6 +244,7 @@ void big_int_from_string(BigInt *dst, String const &s) {
 			if (gb_char_is_digit(r)) {
 			if (gb_char_is_digit(r)) {
 				v = u64_digit_value(r);
 				v = u64_digit_value(r);
 			} else {
 			} else {
+				*success = false;
 				break;
 				break;
 			}
 			}
 			exp *= 10;
 			exp *= 10;
@@ -234,6 +254,10 @@ void big_int_from_string(BigInt *dst, String const &s) {
 			big_int_mul_eq(dst, &b);
 			big_int_mul_eq(dst, &b);
 		}
 		}
 	}
 	}
+
+	if (is_negative) {
+		big_int_neg(dst, dst);
+	}
 }
 }
 
 
 
 

+ 5 - 1
src/exact_value.cpp

@@ -177,7 +177,11 @@ ExactValue exact_value_typeid(Type *type) {
 
 
 ExactValue exact_value_integer_from_string(String const &string) {
 ExactValue exact_value_integer_from_string(String const &string) {
 	ExactValue result = {ExactValue_Integer};
 	ExactValue result = {ExactValue_Integer};
-	big_int_from_string(&result.value_integer, string);
+	bool success;
+	big_int_from_string(&result.value_integer, string, &success);
+	if (!success) {
+		result = {ExactValue_Invalid};
+	}
 	return result;
 	return result;
 }
 }
 
 

+ 21 - 19
src/main.cpp

@@ -825,11 +825,19 @@ bool parse_build_flags(Array<String> args) {
 
 
 		String name = substring(flag, 1, flag.len);
 		String name = substring(flag, 1, flag.len);
 		isize end = 0;
 		isize end = 0;
+		bool have_equals = false;
 		for (; end < name.len; end++) {
 		for (; end < name.len; end++) {
 			if (name[end] == ':') break;
 			if (name[end] == ':') break;
-			if (name[end] == '=') break; // IMPORTANT TODO(bill): DEPRECATE THIS!!!!
+			if (name[end] == '=') {
+				have_equals = true;
+				break;
+			}
 		}
 		}
 		name = substring(name, 0, end);
 		name = substring(name, 0, end);
+		if (have_equals && name != "opt") {
+			gb_printf_err("`flag=value` has been deprecated and will be removed next release. Use `%.*s:` instead.\n", LIT(name), LIT(name));
+		}
+
 		String param = {};
 		String param = {};
 		if (end < flag.len-1) param = substring(flag, 2+end, flag.len);
 		if (end < flag.len-1) param = substring(flag, 2+end, flag.len);
 
 
@@ -903,35 +911,35 @@ bool parse_build_flags(Array<String> args) {
 						switch (bf.param_kind) {
 						switch (bf.param_kind) {
 						case BuildFlagParam_None:
 						case BuildFlagParam_None:
 							if (value.kind != ExactValue_Invalid) {
 							if (value.kind != ExactValue_Invalid) {
-								gb_printf_err("%.*s expected no value, got %.*s", LIT(name), LIT(param));
+								gb_printf_err("%.*s expected no value, got %.*s\n", LIT(name), LIT(param));
 								bad_flags = true;
 								bad_flags = true;
 								ok = false;
 								ok = false;
 							}
 							}
 							break;
 							break;
 						case BuildFlagParam_Boolean:
 						case BuildFlagParam_Boolean:
 							if (value.kind != ExactValue_Bool) {
 							if (value.kind != ExactValue_Bool) {
-								gb_printf_err("%.*s expected a boolean, got %.*s", LIT(name), LIT(param));
+								gb_printf_err("%.*s expected a boolean, got %.*s\n", LIT(name), LIT(param));
 								bad_flags = true;
 								bad_flags = true;
 								ok = false;
 								ok = false;
 							}
 							}
 							break;
 							break;
 						case BuildFlagParam_Integer:
 						case BuildFlagParam_Integer:
 							if (value.kind != ExactValue_Integer) {
 							if (value.kind != ExactValue_Integer) {
-								gb_printf_err("%.*s expected an integer, got %.*s", LIT(name), LIT(param));
+								gb_printf_err("%.*s expected an integer, got %.*s\n", LIT(name), LIT(param));
 								bad_flags = true;
 								bad_flags = true;
 								ok = false;
 								ok = false;
 							}
 							}
 							break;
 							break;
 						case BuildFlagParam_Float:
 						case BuildFlagParam_Float:
 							if (value.kind != ExactValue_Float) {
 							if (value.kind != ExactValue_Float) {
-								gb_printf_err("%.*s expected a floating pointer number, got %.*s", LIT(name), LIT(param));
+								gb_printf_err("%.*s expected a floating pointer number, got %.*s\n", LIT(name), LIT(param));
 								bad_flags = true;
 								bad_flags = true;
 								ok = false;
 								ok = false;
 							}
 							}
 							break;
 							break;
 						case BuildFlagParam_String:
 						case BuildFlagParam_String:
 							if (value.kind != ExactValue_String) {
 							if (value.kind != ExactValue_String) {
-								gb_printf_err("%.*s expected a string, got %.*s", LIT(name), LIT(param));
+								gb_printf_err("%.*s expected a string, got %.*s\n", LIT(name), LIT(param));
 								bad_flags = true;
 								bad_flags = true;
 								ok = false;
 								ok = false;
 							}
 							}
@@ -961,19 +969,10 @@ bool parse_build_flags(Array<String> args) {
 								bad_flags = true;
 								bad_flags = true;
 								break;
 								break;
 							}
 							}
-							// NOTE(Jeroen): We can't rely on `value.value_integer` here, because words will be returned as `0`.
-							// Meaning that -opt:speed will coerce to opt:0. That's not what the user intended.
-							// Instead we'll just compare 0..3 directly.
-							if        (param == "0") {
-								build_context.optimization_level = 0;
-							} else if (param == "1") {
-								build_context.optimization_level = 1;
-							} else if (param == "2") {
-								build_context.optimization_level = 2;
-							} else if (param == "3") {
-								build_context.optimization_level = 3;
-							} else {
-								gb_printf_err("Invalid optimization level for -o:<integer>, got %.*s\n", LIT(param));
+
+							build_context.optimization_level = cast(i32)big_int_to_i64(&value.value_integer);
+							if (build_context.optimization_level < 0 || build_context.optimization_level > 3) {
+								gb_printf_err("Invalid optimization level for -o:<integer>, got %d\n", build_context.optimization_level);
 								gb_printf_err("Valid optimization levels:\n");
 								gb_printf_err("Valid optimization levels:\n");
 								gb_printf_err("\t0\n");
 								gb_printf_err("\t0\n");
 								gb_printf_err("\t1\n");
 								gb_printf_err("\t1\n");
@@ -981,6 +980,9 @@ bool parse_build_flags(Array<String> args) {
 								gb_printf_err("\t3\n");
 								gb_printf_err("\t3\n");
 								bad_flags = true;
 								bad_flags = true;
 							}
 							}
+
+							// Deprecation warning.
+							gb_printf_err("`-opt` has been deprecated and will be removed next release. Use `-o:minimal`, etc.\n");
 							break;
 							break;
 						}
 						}
 						case BuildFlag_OptimizationMode: {
 						case BuildFlag_OptimizationMode: {