Add getdelim and getline

This commit is contained in:
Jeremy Soller
2018-11-25 16:39:14 -07:00
parent 96cc56a0b5
commit 5c4c49a9d1
2 changed files with 48 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
use alloc::vec::Vec;
use core::ptr;
use header::stdio::FILE;
use header::stdlib;
use io::BufRead;
use platform::types::*;
#[no_mangle]
pub extern "C" fn __getline(lineptr: *mut *mut c_char, n: *mut size_t, stream: *mut FILE) -> ssize_t {
__getdelim(lineptr, n, b'\n' as c_int, stream)
}
#[no_mangle]
pub extern "C" fn __getdelim(lineptr: *mut *mut c_char, n: *mut size_t, delim: c_int, stream: *mut FILE) -> ssize_t {
let lineptr = unsafe { &mut *lineptr };
let n = unsafe { &mut *n };
let delim = delim as u8;
//TODO: More efficient algorithm using lineptr and n instead of this vec
let mut buf = Vec::new();
let count = {
let mut stream = unsafe { &mut *stream }.lock();
match stream.read_until(delim, &mut buf) {
Ok(ok) => ok,
Err(err) => return -1,
}
};
//TODO: Check errors and improve safety
unsafe {
// Allocate lineptr to size of buf and set n to size of lineptr
*n = count + 1;
*lineptr = stdlib::realloc(*lineptr as *mut c_void, *n) as *mut c_char;
// Copy buf to lineptr
ptr::copy(buf.as_ptr(), *lineptr as *mut u8, count);
// NUL terminate lineptr
*lineptr.offset(count as isize) = 0;
// Return allocated size
*n as ssize_t
}
}
+3
View File
@@ -27,6 +27,9 @@ mod constants;
pub use self::default::*;
mod default;
pub use self::getdelim::*;
mod getdelim;
mod ext;
mod helpers;
mod printf;