mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Do not implicitly convert enums to ordinal in formatting functions.
This commit is contained in:
@@ -46,7 +46,7 @@ macro Char16[] @char16(String $string) @builtin
|
|||||||
|
|
||||||
@param [in] fmt : `The formatting string`
|
@param [in] fmt : `The formatting string`
|
||||||
*>
|
*>
|
||||||
fn ZString tformat_zstr(String fmt, args...)
|
fn ZString tformat_zstr(String fmt, args...) @format(0)
|
||||||
{
|
{
|
||||||
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
|
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
|
||||||
str.appendf(fmt, ...args);
|
str.appendf(fmt, ...args);
|
||||||
@@ -59,7 +59,7 @@ fn ZString tformat_zstr(String fmt, args...)
|
|||||||
@param [inout] allocator : `The allocator to use`
|
@param [inout] allocator : `The allocator to use`
|
||||||
@param [in] fmt : `The formatting string`
|
@param [in] fmt : `The formatting string`
|
||||||
*>
|
*>
|
||||||
fn String format(Allocator allocator, String fmt, args...) => @pool()
|
fn String format(Allocator allocator, String fmt, args...) @format(1) => @pool()
|
||||||
{
|
{
|
||||||
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
|
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
|
||||||
str.appendf(fmt, ...args);
|
str.appendf(fmt, ...args);
|
||||||
@@ -71,7 +71,7 @@ fn String format(Allocator allocator, String fmt, args...) => @pool()
|
|||||||
|
|
||||||
@param [in] fmt : `The formatting string`
|
@param [in] fmt : `The formatting string`
|
||||||
*>
|
*>
|
||||||
fn String tformat(String fmt, args...)
|
fn String tformat(String fmt, args...) @format(0)
|
||||||
{
|
{
|
||||||
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
|
DString str = dstring::temp_with_capacity(fmt.len + args.len * 8);
|
||||||
str.appendf(fmt, ...args);
|
str.appendf(fmt, ...args);
|
||||||
|
|||||||
@@ -339,7 +339,7 @@ macro usz? @wrap_bad(Formatter* f, #action)
|
|||||||
case INTERNAL_BUFFER_EXCEEDED:
|
case INTERNAL_BUFFER_EXCEEDED:
|
||||||
return f.first_err(err)?;
|
return f.first_err(err)?;
|
||||||
default:
|
default:
|
||||||
err = f.first_err(INVALID_ARGUMENT);
|
err = f.first_err(INVALID_ARGUMENT);
|
||||||
f.out_substr("<INVALID>")!;
|
f.out_substr("<INVALID>")!;
|
||||||
return err?;
|
return err?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ fn uint128? int_from_any(any arg, bool *is_neg) @private
|
|||||||
*is_neg = false;
|
*is_neg = false;
|
||||||
return (uint128)(uptr)*(void**)arg.ptr;
|
return (uint128)(uptr)*(void**)arg.ptr;
|
||||||
case TypeKind.DISTINCT:
|
case TypeKind.DISTINCT:
|
||||||
case TypeKind.ENUM:
|
|
||||||
return int_from_any(arg.as_inner(), is_neg);
|
return int_from_any(arg.as_inner(), is_neg);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -45,18 +45,18 @@ fn String format(Allocator allocator, DateTimeFormat type, TzDateTime dt)
|
|||||||
return string::format(allocator, "%s, %02d %s %d %02d:%02d:%02d %s", dt.weekday.abbrev, dt.day, dt.month.abbrev, dt.year, dt.hour, dt.min, dt.sec, temp_numeric_tzsuffix(dt.gmt_offset));
|
return string::format(allocator, "%s, %02d %s %d %02d:%02d:%02d %s", dt.weekday.abbrev, dt.day, dt.month.abbrev, dt.year, dt.hour, dt.min, dt.sec, temp_numeric_tzsuffix(dt.gmt_offset));
|
||||||
case RFC3339:
|
case RFC3339:
|
||||||
dt = dt.to_gmt_offset(0);
|
dt = dt.to_gmt_offset(0);
|
||||||
return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02dZ", dt.year, dt.month + 1, dt.day, dt.hour, dt.min, dt.sec);
|
return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02dZ", dt.year, dt.month.ordinal + 1, dt.day, dt.hour, dt.min, dt.sec);
|
||||||
case RFC3339Z:
|
case RFC3339Z:
|
||||||
return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02d%s", dt.year, dt.month + 1, dt.day, dt.hour, dt.min, dt.sec, temp_numeric_tzsuffix_colon(dt.gmt_offset));
|
return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02d%s", dt.year, dt.month.ordinal + 1, dt.day, dt.hour, dt.min, dt.sec, temp_numeric_tzsuffix_colon(dt.gmt_offset));
|
||||||
case RFC3339MS:
|
case RFC3339MS:
|
||||||
dt = dt.to_gmt_offset(0);
|
dt = dt.to_gmt_offset(0);
|
||||||
return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02d.%dZ", dt.year, dt.month + 1, dt.day, dt.hour, dt.min, dt.sec, dt.usec);
|
return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02d.%dZ", dt.year, dt.month.ordinal + 1, dt.day, dt.hour, dt.min, dt.sec, dt.usec);
|
||||||
case RFC3339ZMS:
|
case RFC3339ZMS:
|
||||||
return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02d.%d%s", dt.year, dt.month + 1, dt.day, dt.hour, dt.min, dt.sec, dt.usec, temp_numeric_tzsuffix_colon(dt.gmt_offset));
|
return string::format(allocator, "%04d-%02d-%02dT%02d:%02d:%02d.%d%s", dt.year, dt.month.ordinal + 1, dt.day, dt.hour, dt.min, dt.sec, dt.usec, temp_numeric_tzsuffix_colon(dt.gmt_offset));
|
||||||
case DATETIME:
|
case DATETIME:
|
||||||
return string::format(allocator, "%04d-%02d-%02d %02d:%02d:%02d", dt.year, dt.month + 1, dt.day, dt.hour, dt.min, dt.sec);
|
return string::format(allocator, "%04d-%02d-%02d %02d:%02d:%02d", dt.year, dt.month.ordinal + 1, dt.day, dt.hour, dt.min, dt.sec);
|
||||||
case DATEONLY:
|
case DATEONLY:
|
||||||
return string::format(allocator, "%04d-%02d-%02d", dt.year, dt.month + 1, dt.day);
|
return string::format(allocator, "%04d-%02d-%02d", dt.year, dt.month.ordinal + 1, dt.day);
|
||||||
case TIMEONLY:
|
case TIMEONLY:
|
||||||
return string::format(allocator, "%02d:%02d:%02d", dt.hour, dt.min, dt.sec);
|
return string::format(allocator, "%02d:%02d:%02d", dt.hour, dt.min, dt.sec);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
- `tmem` is now a variable.
|
- `tmem` is now a variable.
|
||||||
- Compile test and benchmark functions when invoking `--lsp` #2058.
|
- Compile test and benchmark functions when invoking `--lsp` #2058.
|
||||||
- Added `@format` attribute for compile time printf validation #2057.
|
- Added `@format` attribute for compile time printf validation #2057.
|
||||||
|
- Formatter no longer implicitly converts enums to ordinals.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Fix address sanitizer to work on MachO targets (e.g. MacOS).
|
- Fix address sanitizer to work on MachO targets (e.g. MacOS).
|
||||||
|
|||||||
@@ -1869,6 +1869,10 @@ CHECK_FORMAT:;
|
|||||||
case 'G':
|
case 'G':
|
||||||
if (!type_is_number_or_bool(type))
|
if (!type_is_number_or_bool(type))
|
||||||
{
|
{
|
||||||
|
if (type->type_kind == TYPE_ENUM)
|
||||||
|
{
|
||||||
|
RETURN_SEMA_ERROR(vaargs[idx], "An enum cannot directly be turned into a number. Use '.ordinal' to convert it to its value.", type_quoted_error_string(type));
|
||||||
|
}
|
||||||
RETURN_SEMA_ERROR(vaargs[idx], "Expected a number here, but was %s", type_quoted_error_string(type));
|
RETURN_SEMA_ERROR(vaargs[idx], "Expected a number here, but was %s", type_quoted_error_string(type));
|
||||||
}
|
}
|
||||||
goto NEXT;
|
goto NEXT;
|
||||||
|
|||||||
@@ -107,10 +107,10 @@ fn void printf_enum()
|
|||||||
assert(s == "ENUMB", "got '%s'; want 'ENUMB'", s);
|
assert(s == "ENUMB", "got '%s'; want 'ENUMB'", s);
|
||||||
free(s);
|
free(s);
|
||||||
|
|
||||||
s = string::format(mem, "%d", PrintfTest.ENUMA);
|
s = string::format(mem, "%d", PrintfTest.ENUMA.ordinal);
|
||||||
assert(s == "0", "got '%s'; want '0'", s);
|
assert(s == "0", "got '%s'; want '0'", s);
|
||||||
free(s);
|
free(s);
|
||||||
s = string::format(mem, "%d", PrintfTest.ENUMB);
|
s = string::format(mem, "%d", PrintfTest.ENUMB.ordinal);
|
||||||
assert(s == "1", "got '%s'; want '1'", s);
|
assert(s == "1", "got '%s'; want '1'", s);
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user