Implement printf (very simple version)

This commit is contained in:
Jeremy Soller
2018-03-03 19:47:01 -07:00
parent bf987098dc
commit 5520526bef
11 changed files with 176 additions and 19 deletions
Generated
+7
View File
@@ -393,6 +393,7 @@ version = "0.1.0"
dependencies = [
"cbindgen 0.5.0",
"platform 0.1.0",
"va_list 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -512,6 +513,11 @@ dependencies = [
"platform 0.1.0",
]
[[package]]
name = "va_list"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vec_map"
version = "0.8.0"
@@ -600,6 +606,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum va_list 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7365862faee55ed0dbc112491aa5f0451ca01bf98afcc6463183b5aaa5bd3128"
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
+1 -1
View File
@@ -51,6 +51,6 @@ pub unsafe extern "C" fn _start_rust(sp: &'static Stack) -> ! {
}
#[lang = "panic_fmt"]
pub extern "C" fn rust_begin_unwind(fmt: ::core::fmt::Arguments, file: &str, line: u32) -> ! {
pub extern "C" fn rust_begin_unwind(_fmt: ::core::fmt::Arguments, _file: &str, _line: u32) -> ! {
loop {}
}
+11 -2
View File
@@ -1,11 +1,20 @@
#ifndef _BITS_STDIO_H
#define _BITS_STDIO_H
int printf(const char *restrict fmt, ...) {
int fprintf(FILE * stream, const char * fmt, ...) {
int ret;
va_list ap;
va_start(ap, fmt);
ret = vfprintf(stdout, fmt, ap);
ret = vfprintf(stream, fmt, ap);
va_end(ap);
return ret;
}
int printf(const char * fmt, ...) {
int ret;
va_list ap;
va_start(ap, fmt);
ret = vprintf(fmt, ap);
va_end(ap);
return ret;
}
+1
View File
@@ -1,6 +1,7 @@
#ifndef _STDARG_H
#define _STDARG_H
typedef __builtin_va_list va_list;
#define va_start(v,l) __builtin_va_start(v,l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)
+19
View File
@@ -17,3 +17,22 @@ mod sys;
mod sys;
pub mod types;
use core::fmt;
use types::c_int;
pub struct FileWriter(pub c_int);
impl FileWriter {
pub fn write(&mut self, buf: &[u8]) {
write(self.0, buf);
}
}
impl fmt::Write for FileWriter {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.write(s.as_bytes());
Ok(())
}
}
+7 -16
View File
@@ -10,27 +10,17 @@ extern crate stdlib;
extern crate string;
extern crate unistd;
use core::fmt;
struct PanicWriter;
impl fmt::Write for PanicWriter {
fn write_str(&mut self, s: &str) -> fmt::Result {
platform::write(2, s.as_bytes());
Ok(())
}
}
#[lang = "eh_personality"]
#[no_mangle]
pub extern "C" fn rust_eh_personality() {}
#[lang = "panic_fmt"]
#[no_mangle]
pub extern "C" fn rust_begin_unwind(fmt: fmt::Arguments, file: &str, line: u32) -> ! {
use fmt::Write;
pub extern "C" fn rust_begin_unwind(fmt: ::core::fmt::Arguments, file: &str, line: u32) -> ! {
use core::fmt::Write;
let _ = PanicWriter.write_fmt(format_args!("{}:{}: {}\n", file, line, fmt));
let mut w = platform::FileWriter(2);
let _ = w.write_fmt(format_args!("{}:{}: {}\n", file, line, fmt));
platform::exit(1);
}
@@ -38,9 +28,10 @@ pub extern "C" fn rust_begin_unwind(fmt: fmt::Arguments, file: &str, line: u32)
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn _Unwind_Resume() -> ! {
use fmt::Write;
use core::fmt::Write;
let _ = PanicWriter.write_str("_Unwind_Resume\n");
let mut w = platform::FileWriter(2);
let _ = w.write_str("_Unwind_Resume\n");
platform::exit(1);
}
+1
View File
@@ -9,3 +9,4 @@ cbindgen = { path = "../cbindgen" }
[dependencies]
platform = { path = "../platform" }
va_list = { version = "0.1", features = ["no_std"] }
+112
View File
@@ -3,13 +3,125 @@
#![no_std]
extern crate platform;
extern crate va_list as vl;
use platform::types::*;
use vl::VaList as va_list;
pub const BUFSIZ: c_int = 4096;
pub const FILENAME_MAX: c_int = 4096;
pub struct FILE;
pub static mut stdout: *mut FILE = 1 as *mut FILE;
pub static mut stderr: *mut FILE = 2 as *mut FILE;
#[no_mangle]
pub unsafe extern "C" fn vfprintf(file: *mut FILE, format: *const c_char, mut ap: va_list) -> c_int {
use core::fmt::Write;
use core::slice;
use core::str;
extern "C" {
fn strlen(s: *const c_char) -> size_t;
}
let mut w = platform::FileWriter(file as c_int);
let format = slice::from_raw_parts(format as *const u8, strlen(format));
let mut i = 0;
let mut found_percent = false;
while i < format.len() {
let b = format[i];
if found_percent {
match b as char {
'%' => {
w.write_char('%');
found_percent = false;
},
'c' => {
let a = ap.get::<u32>();
w.write_char(a as u8 as char);
found_percent = false;
},
'd' | 'i' => {
let a = ap.get::<c_int>();
w.write_fmt(format_args!("{}", a));
found_percent = false;
},
'n' => {
let _a = ap.get::<c_int>();
found_percent = false;
},
'p' => {
let a = ap.get::<usize>();
w.write_fmt(format_args!("0x{:x}", a));
found_percent = false;
},
's' => {
let a = ap.get::<usize>();
w.write_str(str::from_utf8_unchecked(
slice::from_raw_parts(a as *const u8, strlen(a as *const c_char))
));
found_percent = false;
},
'u' => {
let a = ap.get::<c_uint>();
w.write_fmt(format_args!("{}", a));
found_percent = false;
},
'x' => {
let a = ap.get::<c_uint>();
w.write_fmt(format_args!("{:x}", a));
found_percent = false;
},
'X' => {
let a = ap.get::<c_uint>();
w.write_fmt(format_args!("{:X}", a));
found_percent = false;
},
'-' => {},
'+' => {},
' ' => {},
'#' => {},
'0' ... '9' => {},
_ => {}
}
} else if b == b'%' {
found_percent = true;
} else {
w.write_char(b as char);
}
i += 1;
}
0
}
#[no_mangle]
pub unsafe extern "C" fn vprintf(format: *const c_char, ap: va_list) -> c_int {
vfprintf(stdout, format, ap)
}
/*
#[no_mangle]
pub extern "C" fn func(args) -> c_int {
+1
View File
@@ -3,4 +3,5 @@
/create
/create.out
/math
/printf
/write
+1
View File
@@ -3,6 +3,7 @@ BINS=\
args \
create \
math \
printf \
write
all: $(BINS)
+15
View File
@@ -0,0 +1,15 @@
#include <stdio.h>
int main(int argc, char ** argv) {
printf(
"percent: %%\nstring: %s\nchar: %c\nint: %d\nuint: %u\nhex: %x\nHEX: %X\nstring: %s\n",
"String",
'c',
-16,
32,
0xbeef,
0xC0FFEE,
"end"
);
return 0;
}