mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Merge pull request #1765 from Kelimion/more_opt_handling
Handle negative integer flags, add deprecation warnings.
This commit is contained in:
+27
-3
@@ -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
@@ -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
@@ -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.
|
build_context.optimization_level = cast(i32)big_int_to_i64(&value.value_integer);
|
||||||
// Instead we'll just compare 0..3 directly.
|
if (build_context.optimization_level < 0 || build_context.optimization_level > 3) {
|
||||||
if (param == "0") {
|
gb_printf_err("Invalid optimization level for -o:<integer>, got %d\n", build_context.optimization_level);
|
||||||
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));
|
|
||||||
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: {
|
||||||
|
|||||||
Reference in New Issue
Block a user