From fe47c3103d7c012073825a475bfff6bd63629e60 Mon Sep 17 00:00:00 2001 From: emma Date: Sun, 26 Mar 2023 20:44:08 -0400 Subject: [PATCH] added error types and impls --- Cargo.toml | 5 ++++ src/{ => entry}/args.rs | 0 src/entry/mod.rs | 60 +++++++++++++++++++++++++++++++++++++++ src/errors.rs | 42 ++++++++++++++++++++++++++++ src/lib.rs | 62 ++++------------------------------------- 5 files changed, 113 insertions(+), 56 deletions(-) rename src/{ => entry}/args.rs (100%) create mode 100644 src/entry/mod.rs create mode 100644 src/errors.rs diff --git a/Cargo.toml b/Cargo.toml index d89317b..74f44f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,8 @@ libc-print = "0.1.21" [build-dependencies] bindgen = "0.63.0" + +[features] +default = [ "entry", "errors"] +entry = [] +errors = [] diff --git a/src/args.rs b/src/entry/args.rs similarity index 100% rename from src/args.rs rename to src/entry/args.rs diff --git a/src/entry/mod.rs b/src/entry/mod.rs new file mode 100644 index 0000000..b4a79d9 --- /dev/null +++ b/src/entry/mod.rs @@ -0,0 +1,60 @@ +mod args; +pub use args::Args; + +use crate::exit; + +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; +} + +#[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, code)| { + libc_eprintln!("{}: {}", argv0, err); + code + }) as _ + }, + Err(_) => { + libc_eprintln!("Arguments are not valid UTF-8."); + 65 + }, + } +} diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..5979594 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 Emma Tebibyte + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * This file is part of yacexits. + * + * Yacexits is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * Yacexits is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with yacexits. If not, see . + */ + +use alloc::string::String; + +#[allow(dead_code)] +pub struct YacError { + code: u32, + message: String, +} + +pub trait Shave { + fn code(&self) -> u32; + + fn message(&self) -> String; +} + +impl From for YacError { + fn from(err: T) -> Self { + let message = err.message(); + let code = err.code(); + let out = YacError { message, code }; + out + } +} diff --git a/src/lib.rs b/src/lib.rs index 07859bd..725dd55 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,65 +70,15 @@ include!(concat!(env!("OUT_DIR"), "/bindings.rs")); extern crate alloc; extern crate core; -mod args; -pub use args::Args; +#[cfg(feature = "entry")] +mod entry; +#[cfg(feature = "errors")] +mod errors; -use libc::{ - c_int, - strlen, -}; - -use libc_print::libc_eprintln; +pub use entry::Args; +pub use errors::*; pub fn exit(code: u32) -> ! { unsafe { libc::exit(code as i32 as libc::c_int); } } -///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; -} - -#[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, code)| { - libc_eprintln!("{}: {}", argv0, err); - code - }) as _ - }, - Err(_) => { - libc_eprintln!("Arguments are not valid UTF-8."); - 65 - }, - } -}