From ee40035c4b1932db3101a066bf7c49df08c4b200 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jeremy@system76.com> Date: Sun, 9 Dec 2018 12:45:04 -0700 Subject: [PATCH] Add asprintf --- include/bits/stdio.h | 1 + include/math.h | 4 ++++ src/c/stdio.c | 11 +++++++++++ src/header/stdio/mod.rs | 8 ++++++++ src/platform/mod.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+) diff --git a/include/bits/stdio.h b/include/bits/stdio.h index 0af8e6acd..428cded59 100644 --- a/include/bits/stdio.h +++ b/include/bits/stdio.h @@ -9,6 +9,7 @@ typedef struct FILE FILE; extern "C" { #endif +int asprintf(char **strp, const char * fmt, ...); int fprintf(FILE * stream, const char * fmt, ...); int printf(const char * fmt, ...); int snprintf(char *s, size_t n, const char * fmt, ...); diff --git a/include/math.h b/include/math.h index 82d66d596..a0cd1d106 100644 --- a/include/math.h +++ b/include/math.h @@ -1 +1,5 @@ #include <openlibm_math.h> + +// Included to fix mesa issues +#define M_PI_2 (M_PI/2.0) +#define M_PI_4 (M_PI/4.0) diff --git a/src/c/stdio.c b/src/c/stdio.c index a3afa7b2e..fe4ab46b4 100644 --- a/src/c/stdio.c +++ b/src/c/stdio.c @@ -3,6 +3,17 @@ typedef struct FILE FILE; +int vasprintf(char ** strp, const char * fmt, va_list ap); + +int asprintf(char ** strp, const char * fmt, ...) { + int ret; + va_list ap; + va_start(ap, fmt); + ret = vasprintf(strp, fmt, ap); + va_end(ap); + return ret; +} + int vfprintf(FILE * stream, const char * fmt, va_list ap); int fprintf(FILE * stream, const char * fmt, ...) { diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs index 8ed46f147..e313849e0 100644 --- a/src/header/stdio/mod.rs +++ b/src/header/stdio/mod.rs @@ -920,6 +920,14 @@ pub unsafe extern "C" fn vprintf(format: *const c_char, ap: va_list) -> c_int { vfprintf(&mut *stdout, format, ap) } +#[no_mangle] +pub unsafe extern "C" fn vasprintf(strp: *mut *mut c_char, format: *const c_char, ap: va_list) -> c_int { + let mut alloc_writer = platform::AllocStringWriter(ptr::null_mut(), 0); + let ret = printf::printf(&mut alloc_writer, format, ap); + *strp = alloc_writer.0 as *mut c_char; + ret +} + #[no_mangle] pub unsafe extern "C" fn vsnprintf( s: *mut c_char, diff --git a/src/platform/mod.rs b/src/platform/mod.rs index 238e38500..d94515a7d 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -99,6 +99,47 @@ impl Read for FileReader { } } +pub struct AllocStringWriter(pub *mut u8, pub usize); +impl Write for AllocStringWriter { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + let ptr = unsafe { + realloc(self.0 as *mut c_void, self.1 + buf.len() + 1) as *mut u8 + }; + if ptr.is_null() { + return Err(io::Error::new( + io::ErrorKind::Other, + "AllocStringWriter::write failed to allocate" + )); + } + self.0 = ptr; + + unsafe { + ptr::copy_nonoverlapping(buf.as_ptr(), self.0.add(self.1), buf.len()); + self.1 += buf.len(); + *self.0.add(self.1) = 0; + } + + Ok(buf.len()) + } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} +impl fmt::Write for AllocStringWriter { + fn write_str(&mut self, s: &str) -> fmt::Result { + // can't fail + self.write(s.as_bytes()).unwrap(); + Ok(()) + } +} +impl WriteByte for AllocStringWriter { + fn write_u8(&mut self, byte: u8) -> fmt::Result { + // can't fail + self.write(&[byte]).unwrap(); + Ok(()) + } +} + pub struct StringWriter(pub *mut u8, pub usize); impl Write for StringWriter { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { -- GitLab