0.3.0: add dual-toolchain VaList ABI probe and macros (relibc check passes)

This commit is contained in:
Red Bear OS
2026-07-06 20:33:17 +03:00
parent 5004e94d1d
commit 628d5c2a51
17 changed files with 153 additions and 71 deletions
+9 -9
View File
@@ -1415,7 +1415,7 @@ pub unsafe extern "C" fn fprintf(
format: *const c_char,
mut __valist: ...
) -> c_int {
unsafe { vfprintf(file, format, __valist.as_va_list()) }
unsafe { vfprintf(file, format, relibc_as_va_list!(__valist)) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vdprintf.html>.
@@ -1433,7 +1433,7 @@ pub unsafe extern "C" fn vdprintf(fd: c_int, format: *const c_char, ap: va_list)
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/dprintf.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn dprintf(fd: c_int, format: *const c_char, mut __valist: ...) -> c_int {
unsafe { vdprintf(fd, format, __valist.as_va_list()) }
unsafe { vdprintf(fd, format, relibc_as_va_list!(__valist)) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfprintf.html>.
@@ -1445,7 +1445,7 @@ pub unsafe extern "C" fn vprintf(format: *const c_char, ap: va_list) -> c_int {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fprintf.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn printf(format: *const c_char, mut __valist: ...) -> c_int {
unsafe { vfprintf(&raw mut *stdout, format, __valist.as_va_list()) }
unsafe { vfprintf(&raw mut *stdout, format, relibc_as_va_list!(__valist)) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfprintf.html>.
@@ -1470,7 +1470,7 @@ pub unsafe extern "C" fn asprintf(
format: *const c_char,
mut __valist: ...
) -> c_int {
unsafe { vasprintf(strp, format, __valist.as_va_list()) }
unsafe { vasprintf(strp, format, relibc_as_va_list!(__valist)) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfprintf.html>.
@@ -1502,7 +1502,7 @@ pub unsafe extern "C" fn snprintf(
printf::printf(
&mut platform::StringWriter(s.cast::<u8>(), n),
CStr::from_ptr(format),
__valist.as_va_list(),
relibc_as_va_list!(__valist),
)
}
}
@@ -1530,7 +1530,7 @@ pub unsafe extern "C" fn sprintf(
printf::printf(
&mut platform::UnsafeStringWriter(s.cast::<u8>()),
CStr::from_ptr(format),
__valist.as_va_list(),
relibc_as_va_list!(__valist),
)
}
}
@@ -1558,7 +1558,7 @@ pub unsafe extern "C" fn fscanf(
format: *const c_char,
mut __valist: ...
) -> c_int {
unsafe { vfscanf(file, format, __valist.as_va_list()) }
unsafe { vfscanf(file, format, relibc_as_va_list!(__valist)) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfscanf.html>.
@@ -1570,7 +1570,7 @@ pub unsafe extern "C" fn vscanf(format: *const c_char, ap: va_list) -> c_int {
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/fscanf.html>.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn scanf(format: *const c_char, mut __valist: ...) -> c_int {
unsafe { vfscanf(&raw mut *stdin, format, __valist.as_va_list()) }
unsafe { vfscanf(&raw mut *stdin, format, relibc_as_va_list!(__valist)) }
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/vfscanf.html>.
@@ -1593,7 +1593,7 @@ pub unsafe extern "C" fn sscanf(
unsafe {
let format = CStr::from_ptr(format);
let s = CStr::from_ptr(s);
scanf::scanf(s.into(), format.into(), __valist.as_va_list())
scanf::scanf(s.into(), format.into(), relibc_as_va_list!(__valist))
}
}
+14 -14
View File
@@ -127,36 +127,36 @@ impl VaArg {
(FmtKind::Percent, _) => panic!("Can't call arg_from on %"),
(FmtKind::Char, IntKind::Long) | (FmtKind::Char, IntKind::LongLong) => {
VaArg::wint_t(unsafe { ap.arg::<wint_t>() })
VaArg::wint_t(unsafe { relibc_va_arg!(ap, wint_t) })
}
(FmtKind::Char, _)
| (FmtKind::Unsigned, IntKind::Byte)
| (FmtKind::Signed, IntKind::Byte) => {
// c_int is passed but truncated to c_char
VaArg::c_char(unsafe { ap.arg::<c_int>() } as c_char)
VaArg::c_char(unsafe { relibc_va_arg!(ap, c_int) } as c_char)
}
(FmtKind::Unsigned, IntKind::Short) | (FmtKind::Signed, IntKind::Short) => {
// c_int is passed but truncated to c_short
VaArg::c_short(unsafe { ap.arg::<c_int>() } as c_short)
VaArg::c_short(unsafe { relibc_va_arg!(ap, c_int) } as c_short)
}
(FmtKind::Unsigned, IntKind::Int) | (FmtKind::Signed, IntKind::Int) => {
VaArg::c_int(unsafe { ap.arg::<c_int>() })
VaArg::c_int(unsafe { relibc_va_arg!(ap, c_int) })
}
(FmtKind::Unsigned, IntKind::Long) | (FmtKind::Signed, IntKind::Long) => {
VaArg::c_long(unsafe { ap.arg::<c_long>() })
VaArg::c_long(unsafe { relibc_va_arg!(ap, c_long) })
}
(FmtKind::Unsigned, IntKind::LongLong) | (FmtKind::Signed, IntKind::LongLong) => {
VaArg::c_longlong(unsafe { ap.arg::<c_longlong>() })
VaArg::c_longlong(unsafe { relibc_va_arg!(ap, c_longlong) })
}
(FmtKind::Unsigned, IntKind::IntMax) | (FmtKind::Signed, IntKind::IntMax) => {
VaArg::intmax_t(unsafe { ap.arg::<intmax_t>() })
VaArg::intmax_t(unsafe { relibc_va_arg!(ap, intmax_t) })
}
(FmtKind::Unsigned, IntKind::PtrDiff) | (FmtKind::Signed, IntKind::PtrDiff) => {
VaArg::ptrdiff_t(unsafe { ap.arg::<ptrdiff_t>() })
VaArg::ptrdiff_t(unsafe { relibc_va_arg!(ap, ptrdiff_t) })
}
(FmtKind::Unsigned, IntKind::Size) | (FmtKind::Signed, IntKind::Size) => {
VaArg::ssize_t(unsafe { ap.arg::<ssize_t>() })
VaArg::ssize_t(unsafe { relibc_va_arg!(ap, ssize_t) })
}
(FmtKind::AnyNotation, IntKind::LongLong)
@@ -165,11 +165,11 @@ impl VaArg {
VaArg::c_longdouble(unsafe { VaArg::extract_longdouble(ap) })
}
(FmtKind::AnyNotation, _) | (FmtKind::Decimal, _) | (FmtKind::Scientific, _) => {
VaArg::c_double(unsafe { ap.arg::<c_double>() })
VaArg::c_double(unsafe { relibc_va_arg!(ap, c_double) })
}
(FmtKind::GetWritten, _) | (FmtKind::Pointer, _) | (FmtKind::String, _) => {
VaArg::pointer(unsafe { ap.arg::<*const c_void>() })
VaArg::pointer(unsafe { relibc_va_arg!(ap, *const c_void) })
}
}
}
@@ -348,13 +348,13 @@ impl VaListCache {
// point. Reaching here means there are unused gaps in the
// arguments. Ultimately we'll have to settle down with
// defaulting to c_int.
self.args.push(VaArg::c_int(unsafe { ap.arg::<c_int>() }))
self.args.push(VaArg::c_int(unsafe { relibc_va_arg!(ap, c_int) }))
}
// Add the value to the cache
self.args.push(match default {
Some((fmtkind, intkind)) => unsafe { VaArg::arg_from(fmtkind, intkind, ap) },
None => VaArg::c_int(unsafe { ap.arg::<c_int>() }),
None => VaArg::c_int(unsafe { relibc_va_arg!(ap, c_int) }),
});
// Return the value
@@ -774,7 +774,7 @@ pub(crate) unsafe fn inner_printf<T: c_str::Kind>(
match num {
Number::Next => varargs
.args
.push(VaArg::c_int(unsafe { ap.arg::<c_int>() })),
.push(VaArg::c_int(unsafe { relibc_va_arg!(ap, c_int) })),
Number::Index(i) => {
positional.insert(i - 1, (FmtKind::Signed, IntKind::Int));
}
+6 -6
View File
@@ -244,7 +244,7 @@ pub unsafe fn inner_scanf<T: Kind>(
n.parse::<$type>().map_err(|_| 0)?
};
if !ignore {
unsafe { *ap.arg::<*mut $type>() = n };
unsafe { *relibc_va_arg!(ap, *mut $type) = n };
matched += 1;
}
}};
@@ -264,7 +264,7 @@ pub unsafe fn inner_scanf<T: Kind>(
$type::from_str_radix(&n, radix).map_err(|_| 0)?
};
if !ignore {
unsafe { *ap.arg::<*mut $final>() = n as $final };
unsafe { *relibc_va_arg!(ap, *mut $final) = n as $final };
matched += 1;
}
}};
@@ -346,7 +346,7 @@ pub unsafe fn inner_scanf<T: Kind>(
}
let mut ptr: Option<*mut $type> =
if ignore { None } else { Some(ap.arg()) };
if ignore { None } else { Some(relibc_va_arg!(ap)) };
while width.map(|w| w > 0).unwrap_or(true) && !character.is_whitespace()
{
@@ -391,7 +391,7 @@ pub unsafe fn inner_scanf<T: Kind>(
let ptr: Option<*mut $type> = if ignore {
None
} else {
Some(unsafe { ap.arg() })
Some(unsafe { relibc_va_arg!(ap) })
};
for i in 0..width.unwrap_or(1) {
@@ -456,7 +456,7 @@ pub unsafe fn inner_scanf<T: Kind>(
let mut ptr: Option<*mut c_char> = if ignore {
None
} else {
Some(unsafe { ap.arg() })
Some(unsafe { relibc_va_arg!(ap) })
};
// While we haven't used up all the width, and it matches
@@ -486,7 +486,7 @@ pub unsafe fn inner_scanf<T: Kind>(
}
'n' => {
if !ignore {
unsafe { *ap.arg::<*mut c_int>() = count as c_int };
unsafe { *relibc_va_arg!(ap, *mut c_int) = count as c_int };
}
}
_ => return Err(-1),