diff --git a/bash-5.1/Cargo.toml b/bash-5.1/Cargo.toml index c97a043982fb4940ac83d2b873095cb9395ff920..aca5602b61b44cfb680059a592d04899c71e340b 100644 --- a/bash-5.1/Cargo.toml +++ b/bash-5.1/Cargo.toml @@ -8,7 +8,8 @@ crate-type = ["cdylib"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [workspace] -members = ["builtins_rust/read", "builtins/command1", "builtins/command2", "builtins_rust/history", "builtins_rust/kill"] +members = ["builtins_rust/read", "builtins/command1", "builtins/command2", "builtins_rust/history", "builtins_rust/kill", +"builtins_rust/rlet"] [dependencies] libc = "0.2" @@ -17,3 +18,4 @@ command2 = {path = "./builtins/command2"} read = {path = "./builtins_rust/read"} history = {path = "./builtins_rust/history"} kill = {path = "./builtins_rust/kill"} +rlet = {path = "./builtins_rust/rlet"} diff --git a/bash-5.1/builtins_rust/rlet/Cargo.toml b/bash-5.1/builtins_rust/rlet/Cargo.toml index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..dbc2ca83784575b1dfcddd37d226e7b76c722f6e 100644 --- a/bash-5.1/builtins_rust/rlet/Cargo.toml +++ b/bash-5.1/builtins_rust/rlet/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "rlet" +version = "0.1.0" +edition = "2021" +authors = ["lvgenggeng"] +build = "../build.rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +name = "rlet" +crate-type = ["cdylib"] + +[dependencies] +libc = "0.2" +nix = "0.23" diff --git a/bash-5.1/builtins_rust/rlet/src/intercdep.rs b/bash-5.1/builtins_rust/rlet/src/intercdep.rs new file mode 100644 index 0000000000000000000000000000000000000000..d2246f94d4f21090d6d6a2aaee70c126f7bd358c --- /dev/null +++ b/bash-5.1/builtins_rust/rlet/src/intercdep.rs @@ -0,0 +1,46 @@ + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct word_desc { + pub word: *mut c_char, + pub flags: c_int, +} +pub type WORD_DESC = word_desc; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct word_list { + pub next: *mut word_list, + pub word: *mut WORD_DESC, +} +pub type WORD_LIST = word_list; + +pub const EXECUTION_SUCCESS : c_int = 0; +pub const EXECUTION_FAILURE : c_int = 1; +pub const EX_USAGE: c_int = 258; + +pub const EXP_EXPANDED: c_int = 0x01; + +pub type histdata_t = *mut libc::c_void; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct _hist_entry { + pub line: *mut c_char, + pub timestamp: *mut c_char, + pub data: histdata_t, +} +pub type HIST_ENTRY = _hist_entry; + +extern "C" { + pub fn string_list(list: *mut WORD_LIST) -> *mut c_char; + + pub fn builtin_usage(); + pub fn builtin_help(); + pub fn builtin_error(format: *const c_char, ...); + + pub fn evalexp (expr: *mut c_char, flags: c_int, validp: *mut c_int) -> c_long; + + pub static mut list_optarg : *mut libc::c_char; + pub static mut loptend : *mut WORD_LIST; + +} diff --git a/bash-5.1/builtins_rust/rlet/src/lib.rs b/bash-5.1/builtins_rust/rlet/src/lib.rs index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7fe5af59585a4c068c134779322d1daa71b3d4d5 100644 --- a/bash-5.1/builtins_rust/rlet/src/lib.rs +++ b/bash-5.1/builtins_rust/rlet/src/lib.rs @@ -0,0 +1,63 @@ +use std::ffi::CStr; +use libc::{c_int, c_char, c_long, c_void}; + +include!(concat!("intercdep.rs")); + +#[no_mangle] +pub extern "C" fn r_let_builtin(mut list: *mut WORD_LIST) -> i32 { + println!("r_let_builtin call"); +unsafe { + let mut ret: c_long = 0; + let mut expok: c_int = 0; + + if !list.is_null() && !(*list).word.is_null() && + libc::strcmp((*((*list).word)).word, "--help\0".as_ptr() as *const c_char) == 0 { + builtin_help (); + return EX_USAGE; + } + + if !list.is_null() && !(*list).word.is_null() && is_option((*((*list).word)).word, b'-') { + list = (*list).next; + } + + if list.is_null() { + builtin_error("expression expected\0".as_ptr() as *mut c_char); + return EXECUTION_FAILURE; + } + + while !list.is_null() { + ret = evalexp((*((*list).word)).word, EXP_EXPANDED, std::mem::transmute(&expok)); + if expok == 0 { + return EXECUTION_FAILURE; + } + list = (*list).next; + } + + return if ret == 0 {EXECUTION_FAILURE} else {EXECUTION_SUCCESS}; +} +} + +#[no_mangle] +pub extern "C" fn r_exp_builtin(mut list: *mut WORD_LIST) -> i32 { + println!("r_exp_builtin call"); + +unsafe { + let mut expok: c_int = 0; + + if list.is_null() { + builtin_error("expression expected\0".as_ptr() as *const c_char); + return EXECUTION_FAILURE; + } + + let exp = string_list(list); + let ret = evalexp(exp, EXP_EXPANDED, std::mem::transmute(&expok)); + libc::free(exp as *mut c_void); + return if ret == 0 || expok == 0 {EXECUTION_FAILURE} else {EXECUTION_SUCCESS}; +} +} + +unsafe fn is_option(s: *mut c_char, c: u8) -> bool +{ + let str = CStr::from_ptr(s).to_bytes_with_nul(); + return str[0] == b'-' && str[1] == c && str[2] != 0 +} \ No newline at end of file diff --git a/record.txt b/record.txt index fb8812a9b9c3f8f581af9afe958354b83673a34d..622d73b55363069f0b9cf6028ca6f73447e003da 100644 --- a/record.txt +++ b/record.txt @@ -1,3 +1,4 @@ 20 21 22 +23