68 lines
1.7 KiB
Rust
68 lines
1.7 KiB
Rust
mod args;
|
|
mod errors;
|
|
pub use args::Args;
|
|
pub use errors::*;
|
|
|
|
use crate::{
|
|
exit,
|
|
EX_USAGE,
|
|
};
|
|
|
|
use libc::{
|
|
c_int,
|
|
strlen,
|
|
};
|
|
|
|
use libc_print::libc_eprintln;
|
|
|
|
///Converts C string to Rust's, verifying it is UTF-8
|
|
///
|
|
///It is UB to pass non-C string as it requires \0
|
|
pub unsafe fn c_str_to_rust(
|
|
ptr: *const u8
|
|
) -> Result<&'static str, core::str::Utf8Error> {
|
|
let len = strlen(ptr as *const i8);
|
|
let parts = core::slice::from_raw_parts(ptr, len);
|
|
core::str::from_utf8(parts)
|
|
}
|
|
|
|
///Converts C string to Rust's one assuming it is UTF-8
|
|
///
|
|
///It is UB to pass non-C string as it requires \0
|
|
pub unsafe fn c_str_to_rust_unchecked(ptr: *const u8) -> &'static str {
|
|
let len = strlen(ptr as *const i8);
|
|
let parts = core::slice::from_raw_parts(ptr, len);
|
|
core::str::from_utf8_unchecked(parts)
|
|
}
|
|
|
|
extern "Rust" {
|
|
fn rust_main(args: args::Args) -> Result<u32, YacError>;
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
#[cfg(not(test))]
|
|
#[no_mangle]
|
|
pub unsafe extern fn main(argc: c_int, argv: *const *const u8) -> c_int {
|
|
match Args::new(argc as isize, argv) {
|
|
Ok(args) => {
|
|
let argv0 = &args
|
|
.into_iter()
|
|
.next()
|
|
.unwrap_or_else(|| {
|
|
libc_eprintln!("Unable to ascertain argv[0].");
|
|
exit(71);
|
|
});
|
|
rust_main(args).unwrap_or_else(|err| {
|
|
if err.code == EX_USAGE {
|
|
libc_eprintln!("Usage: {} {}", argv0, err.message);
|
|
} else { libc_eprintln!("{}: {}", argv0, err.message); }
|
|
err.code
|
|
}) as _
|
|
},
|
|
Err(_) => {
|
|
libc_eprintln!("Arguments are not valid UTF-8.");
|
|
65
|
|
},
|
|
}
|
|
}
|