Implement printf (very simple version)
This commit is contained in:
Generated
+7
@@ -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
@@ -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
@@ -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,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)
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -9,3 +9,4 @@ cbindgen = { path = "../cbindgen" }
|
||||
|
||||
[dependencies]
|
||||
platform = { path = "../platform" }
|
||||
va_list = { version = "0.1", features = ["no_std"] }
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
/create
|
||||
/create.out
|
||||
/math
|
||||
/printf
|
||||
/write
|
||||
|
||||
@@ -3,6 +3,7 @@ BINS=\
|
||||
args \
|
||||
create \
|
||||
math \
|
||||
printf \
|
||||
write
|
||||
|
||||
all: $(BINS)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user