diff --git a/.clippy.toml b/.clippy.toml new file mode 100644 index 0000000..d2fb6fd --- /dev/null +++ b/.clippy.toml @@ -0,0 +1 @@ +large-error-threshold = 256 diff --git a/Cargo.lock b/Cargo.lock index 70a6d64..bf12b8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,7 +102,7 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "cicada" -version = "0.9.40" +version = "0.9.41" dependencies = [ "clap 3.2.25", "errno 0.3.9", diff --git a/Cargo.toml b/Cargo.toml index b3d8f4c..07ee058 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ edition = "2021" build = "src/build.rs" name = "cicada" -version = "0.9.40" +version = "0.9.41" authors = ["Hugo Wang "] description = "A simple Bash-like Unix shell." diff --git a/docs/install.md b/docs/install.md index 0be16c2..792670f 100644 --- a/docs/install.md +++ b/docs/install.md @@ -6,10 +6,10 @@ There are a few ways to install cicada into your system. ### Alpine Linux -[https://pkgs.alpinelinux.org/package/edge/testing/x86_64/cicada](https://pkgs.alpinelinux.org/package/edge/testing/x86_64/cicada) +[https://pkgs.alpinelinux.org/package/edge/community/x86_64/cicada](https://pkgs.alpinelinux.org/package/edge/community/x86_64/cicada) ``` -$ apk add cicada -X https://dl-cdn.alpinelinux.org/alpine/edge/testing/ +$ sudo apk add cicada -X https://dl-cdn.alpinelinux.org/alpine/edge/community/ ``` ### Arch Linux diff --git a/src/build.rs b/src/build.rs index 22a6963..b6251d3 100644 --- a/src/build.rs +++ b/src/build.rs @@ -4,7 +4,7 @@ use time::OffsetDateTime; fn main() { match Command::new("git") - .args(&["rev-parse", "--short", "HEAD"]) + .args(["rev-parse", "--short", "HEAD"]) .output() { Ok(x) => { @@ -17,7 +17,7 @@ fn main() { } match Command::new("git") - .args(&["rev-parse", "--abbrev-ref", "HEAD"]) + .args(["rev-parse", "--abbrev-ref", "HEAD"]) .output() { Ok(x) => { @@ -30,7 +30,7 @@ fn main() { } match Command::new("git") - .args(&["status", "--porcelain"]) + .args(["status", "--porcelain"]) .output() { Ok(x) => { @@ -42,7 +42,7 @@ fn main() { } } - match Command::new("rustc").args(&["-V"]).output() { + match Command::new("rustc").args(["-V"]).output() { Ok(x) => { let output = String::from_utf8_lossy(&x.stdout); println!("cargo:rustc-env=BUILD_RUSTC_VERSION={}", output); @@ -52,19 +52,16 @@ fn main() { } } - match OffsetDateTime::now_local() { - Ok(dt) => { - let dt_str = format!("{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:03}", - dt.year(), - dt.month() as u8, - dt.day(), - dt.hour(), - dt.minute(), - dt.second(), - dt.millisecond(), - ); - println!("cargo:rustc-env=BUILD_DATE={}", dt_str); - } - Err(_) => { } + if let Ok(dt) = OffsetDateTime::now_local() { + let dt_str = format!("{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:03}", + dt.year(), + dt.month() as u8, + dt.day(), + dt.hour(), + dt.minute(), + dt.second(), + dt.millisecond(), + ); + println!("cargo:rustc-env=BUILD_DATE={}", dt_str); } } diff --git a/src/builtins/bg.rs b/src/builtins/bg.rs index 48cbb40..9258d16 100644 --- a/src/builtins/bg.rs +++ b/src/builtins/bg.rs @@ -17,9 +17,8 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, let mut job_id = -1; if tokens.len() == 1 { - for (gid, _) in sh.jobs.iter() { + if let Some((gid, _)) = sh.jobs.iter().next() { job_id = *gid; - break; } } @@ -71,12 +70,12 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, } None => { let info = "cicada: bg: not such job"; - print_stderr_with_capture(&info, &mut cr, cl, cmd, capture); + print_stderr_with_capture(info, &mut cr, cl, cmd, capture); return cr; } } } jobc::mark_job_as_running(sh, gid, true); - return cr; + cr } diff --git a/src/builtins/cd.rs b/src/builtins/cd.rs index 2b27740..991d493 100644 --- a/src/builtins/cd.rs +++ b/src/builtins/cd.rs @@ -29,7 +29,7 @@ pub fn run(sh: &mut shell::Shell, cl: &CommandLine, cmd: &Command, }; if dir_to == "-" { - if sh.previous_dir == "" { + if sh.previous_dir.is_empty() { let info = "no previous dir"; print_stderr_with_capture(info, &mut cr, cl, cmd, capture); return cr; diff --git a/src/builtins/fg.rs b/src/builtins/fg.rs index ab292fe..cd4f4ca 100644 --- a/src/builtins/fg.rs +++ b/src/builtins/fg.rs @@ -18,9 +18,8 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, let mut job_id = -1; if tokens.len() == 1 { - for (gid, _) in sh.jobs.iter() { + if let Some((gid, _)) = sh.jobs.iter().next() { job_id = *gid; - break; } } @@ -52,7 +51,7 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, { let mut result = sh.get_job_by_id(job_id); // fall back to find job by using prcess group id - if let None = result { + if result.is_none() { result = sh.get_job_by_gid(job_id); } @@ -89,6 +88,6 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, log!("failed to give term to back to shell : {}", gid_shell); } - return cr; + cr } } diff --git a/src/builtins/history.rs b/src/builtins/history.rs index fcf1801..3613038 100644 --- a/src/builtins/history.rs +++ b/src/builtins/history.rs @@ -66,7 +66,7 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, let path = Path::new(hfile.as_str()); if !path.exists() { let info = "no history file"; - print_stderr_with_capture(&info, &mut cr, cl, cmd, capture); + print_stderr_with_capture(info, &mut cr, cl, cmd, capture); return cr; } let conn = match Conn::open(&hfile) { @@ -98,12 +98,12 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, let info = format!("deleted {} items", _count); print_stdout_with_capture(&info, &mut cr, cl, cmd, capture); } - return cr; + cr } Some(SubCommand::Add {timestamp: ts, input}) => { let ts = ts.unwrap_or(0 as f64); add_history(sh, ts, &input); - return cr; + cr } None => { let (str_out, str_err) = list_current_history(sh, &conn, &opt); @@ -113,7 +113,7 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, if !str_err.is_empty() { print_stderr_with_capture(&str_err, &mut cr, cl, cmd, capture); } - return cr; + cr } } } @@ -126,7 +126,7 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, print_stderr_with_capture(&info, &mut cr, cl, cmd, capture); cr.status = 1; } - return cr; + cr } } } @@ -144,7 +144,7 @@ fn list_current_history(sh: &Shell, conn: &Conn, let history_table = history::get_history_table(); let mut sql = format!("SELECT ROWID, inp, tsb FROM {} WHERE ROWID > 0", history_table); - if opt.pattern.len() > 0 { + if !opt.pattern.is_empty() { sql = format!("{} AND inp LIKE '%{}%'", sql, opt.pattern) } if opt.session { @@ -202,9 +202,9 @@ fn list_current_history(sh: &Shell, conn: &Conn, }; if opt.no_id { - lines.push(format!("{}", inp)); + lines.push(inp.to_string()); } else if opt.only_id { - lines.push(format!("{}", row_id)); + lines.push(row_id.to_string()); } else if opt.show_date { let tsb: f64 = match row.get(2) { Ok(x) => x, @@ -240,12 +240,10 @@ fn delete_history_item(conn: &Conn, rowid: usize) -> bool { let history_table = history::get_history_table(); let sql = format!("DELETE from {} where rowid = {}", history_table, rowid); match conn.execute(&sql, []) { - Ok(_) => { - return true; - } + Ok(_) => true, Err(e) => { - log!("history: prepare error - {:?}", e); - return false; + log!("history: error when delete: {:?}", e); + false } } } diff --git a/src/builtins/set.rs b/src/builtins/set.rs index be58d7a..3406f8d 100644 --- a/src/builtins/set.rs +++ b/src/builtins/set.rs @@ -25,11 +25,11 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, Ok(opt) => { if opt.exit_on_error { sh.exit_on_error = true; - return cr; + cr } else { let info = "cicada: set: option not implemented"; - print_stderr_with_capture(&info, &mut cr, cl, cmd, capture); - return cr; + print_stderr_with_capture(info, &mut cr, cl, cmd, capture); + cr } } Err(e) => { @@ -41,7 +41,7 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, print_stderr_with_capture(&info, &mut cr, cl, cmd, capture); cr.status = 1; } - return cr; + cr } } } diff --git a/src/builtins/source.rs b/src/builtins/source.rs index c039e8b..0ce9ffd 100644 --- a/src/builtins/source.rs +++ b/src/builtins/source.rs @@ -8,11 +8,11 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, capture: bool) -> CommandResult { let mut cr = CommandResult::new(); let tokens = &cmd.tokens; - let args = parsers::parser_line::tokens_to_args(&tokens); + let args = parsers::parser_line::tokens_to_args(tokens); if args.len() < 2 { let info = "cicada: source: no file specified"; - print_stderr_with_capture(&info, &mut cr, cl, cmd, capture); + print_stderr_with_capture(info, &mut cr, cl, cmd, capture); return cr; } diff --git a/src/builtins/ulimit.rs b/src/builtins/ulimit.rs index 8e7d59b..b8b0c9b 100644 --- a/src/builtins/ulimit.rs +++ b/src/builtins/ulimit.rs @@ -45,21 +45,18 @@ pub fn run(_sh: &mut Shell, cl: &CommandLine, cmd: &Command, println_stderr!("cicada: clap: {}", e); } } - print!("\n"); + println!(); return CommandResult::new(); } - let matches; - match app.try_get_matches_from(&args) { - Ok(x) => { - matches = x; - } + let matches = match app.try_get_matches_from(&args) { + Ok(x) => x, Err(e) => { let info = format!("ulimit error: {}", e); print_stderr_with_capture(&info, &mut cr, cl, cmd, capture); return cr; } - } + }; let open_files; match matches.value_of_t("open_files") { @@ -99,7 +96,7 @@ pub fn run(_sh: &mut Shell, cl: &CommandLine, cmd: &Command, } let for_hard = matches.is_present("for_hard"); - if matches.is_present("report_all") || options.len() == 0 { + if matches.is_present("report_all") || options.is_empty() { let (_out, _err) = report_all(for_hard); if !_out.is_empty() { print_stdout_with_capture(&_out, &mut cr, cl, cmd, capture); @@ -198,7 +195,7 @@ fn get_limit(limit_name: &str, single_print: bool, limit_id = libc::RLIMIT_CORE; } else { let info = "ulimit: error: invalid limit name"; - result_stderr.push_str(&info); + result_stderr.push_str(info); return (result_stdout, result_stderr); } @@ -212,12 +209,7 @@ fn get_limit(limit_name: &str, single_print: bool, return (result_stdout, result_stderr); } - let to_print; - if for_hard { - to_print = rlp.rlim_max; - } else { - to_print = rlp.rlim_cur; - } + let to_print = if for_hard { rlp.rlim_max } else { rlp.rlim_cur }; if single_print { if to_print == libc::RLIM_INFINITY { @@ -226,14 +218,12 @@ fn get_limit(limit_name: &str, single_print: bool, let info = format!("{}\n", to_print); result_stdout.push_str(&info); } + } else if to_print == libc::RLIM_INFINITY { + let info = format!("{}\t\tunlimited\n", desc); + result_stdout.push_str(&info); } else { - if to_print == libc::RLIM_INFINITY { - let info = format!("{}\t\tunlimited\n", desc); - result_stdout.push_str(&info); - } else { - let info = format!("{}\t\t{}\n", desc, to_print); - result_stdout.push_str(&info); - } + let info = format!("{}\t\t{}\n", desc, to_print); + result_stdout.push_str(&info); } } diff --git a/src/builtins/unalias.rs b/src/builtins/unalias.rs index 09a1e5e..0256468 100644 --- a/src/builtins/unalias.rs +++ b/src/builtins/unalias.rs @@ -9,7 +9,7 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, if tokens.len() != 2 { let info = "cicada: unalias: syntax error"; - print_stderr_with_capture(&info, &mut cr, cl, cmd, capture); + print_stderr_with_capture(info, &mut cr, cl, cmd, capture); return cr; } diff --git a/src/builtins/unpath.rs b/src/builtins/unpath.rs index 4e2d4f2..c1001ae 100644 --- a/src/builtins/unpath.rs +++ b/src/builtins/unpath.rs @@ -9,7 +9,7 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, if tokens.len() != 2 { let info = "cicada: unpath: syntax error"; - print_stderr_with_capture(&info, &mut cr, cl, cmd, capture); + print_stderr_with_capture(info, &mut cr, cl, cmd, capture); return cr; } diff --git a/src/builtins/unset.rs b/src/builtins/unset.rs index ec30441..3ba81df 100644 --- a/src/builtins/unset.rs +++ b/src/builtins/unset.rs @@ -9,7 +9,7 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, if tokens.len() != 2 { let info = "cicada: unset: syntax error"; - print_stderr_with_capture(&info, &mut cr, cl, cmd, capture); + print_stderr_with_capture(info, &mut cr, cl, cmd, capture); return cr; } diff --git a/src/builtins/vox.rs b/src/builtins/vox.rs index 5c930d7..be58ea9 100644 --- a/src/builtins/vox.rs +++ b/src/builtins/vox.rs @@ -10,25 +10,11 @@ use crate::shell::{self, Shell}; use crate::types::{self, CommandResult, CommandLine, Command}; fn in_env() -> bool { - if let Ok(x) = env::var("VIRTUAL_ENV") { - if x != "" { - return true; - } - } - false + env::var("VIRTUAL_ENV").map_or(false, |x| !x.is_empty()) } fn get_envs_home() -> String { - let home_envs; - match env::var("VIRTUALENV_HOME") { - Ok(x) => { - home_envs = x; - } - Err(_) => { - home_envs = String::new(); - } - } - home_envs + env::var("VIRTUALENV_HOME").unwrap_or_default() } fn get_all_venvs() -> Result, String> { @@ -50,16 +36,14 @@ fn get_all_venvs() -> Result, String> { let mut venvs = Vec::new(); let pdir = home_envs.clone(); if let Ok(list) = fs::read_dir(home_envs) { - for ent in list { - if let Ok(ent) = ent { - let ent_name = ent.file_name(); - if let Ok(path) = ent_name.into_string() { - let full_path = format!("{}/{}/bin/activate", pdir, path); - if !Path::new(full_path.as_str()).exists() { - continue; - } - venvs.push(path); + for ent in list.flatten() { + let ent_name = ent.file_name(); + if let Ok(path) = ent_name.into_string() { + let full_path = format!("{}/{}/bin/activate", pdir, path); + if !Path::new(full_path.as_str()).exists() { + continue; } + venvs.push(path); } } } @@ -69,7 +53,7 @@ fn get_all_venvs() -> Result, String> { fn enter_env(sh: &Shell, path: &str) -> String { if in_env() { - return format!("vox: already in env"); + return "vox: already in env".to_string(); } let home_envs = get_envs_home(); @@ -93,13 +77,12 @@ fn exit_env(sh: &Shell) -> String { return String::from("vox: not in an env"); } - let env_path; - match env::var("PATH") { - Ok(x) => env_path = x, + let env_path = match env::var("PATH") { + Ok(x) => x, Err(_) => { return String::from("vox: cannot read PATH env"); } - } + }; let mut _tokens: Vec<&str> = env_path.split(':').collect(); let mut path_virtual_env = String::from("${VIRTUAL_ENV}/bin"); @@ -142,15 +125,10 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, } if len == 3 && subcmd == "create" { - let pybin; - match env::var("VIRTUALENV_PYBIN") { - Ok(x) => { - pybin = x; - } - Err(_) => { - pybin = "python3".to_string(); - } - } + let pybin = match env::var("VIRTUALENV_PYBIN") { + Ok(x) => x, + Err(_) => "python3".to_string(), + }; let dir_venv = get_envs_home(); let venv_name = args[2].to_string(); let line = format!("{} -m venv \"{}/{}\"", pybin, dir_venv, venv_name); @@ -164,16 +142,16 @@ pub fn run(sh: &mut Shell, cl: &CommandLine, cmd: &Command, if !_err.is_empty() { print_stderr_with_capture(&_err, &mut cr, cl, cmd, capture); } - return cr; + cr } else if len == 2 && subcmd == "exit" { let _err = exit_env(sh); if !_err.is_empty() { print_stderr_with_capture(&_err, &mut cr, cl, cmd, capture); } - return cr; + cr } else { let info = "cicada: vox: invalid option"; - print_stderr_with_capture(&info, &mut cr, cl, cmd, capture); - return cr; + print_stderr_with_capture(info, &mut cr, cl, cmd, capture); + cr } } diff --git a/src/calculator/mod.rs b/src/calculator/mod.rs index 523ca54..fe03dc9 100644 --- a/src/calculator/mod.rs +++ b/src/calculator/mod.rs @@ -25,12 +25,7 @@ pub fn eval_int(expression: Pairs) -> i64 { PREC_CLIMBER.climb( expression, |pair: Pair| match pair.as_rule() { - Rule::num => { - match pair.as_str().parse::() { - Ok(n) => n, - Err(_) => 0, - } - } + Rule::num => pair.as_str().parse::().unwrap_or(0), Rule::expr => eval_int(pair.into_inner()), _ => unreachable!(), }, @@ -55,12 +50,7 @@ pub fn eval_float(expression: Pairs) -> f64 { PREC_CLIMBER.climb( expression, |pair: Pair| match pair.as_rule() { - Rule::num => { - match pair.as_str().parse::() { - Ok(f) => f, - Err(_) => 0.0, - } - } + Rule::num => pair.as_str().parse::().unwrap_or(0.0), Rule::expr => eval_float(pair.into_inner()), _ => unreachable!(), }, diff --git a/src/completers/dots.rs b/src/completers/dots.rs index 7825687..9135d9a 100644 --- a/src/completers/dots.rs +++ b/src/completers/dots.rs @@ -59,7 +59,8 @@ fn get_dot_file(line: &str) -> (String, String) { } else { "" }; - return (dot_file, sub_cmd.to_string()); + + (dot_file, sub_cmd.to_string()) } fn handle_lv1_string(res: &mut Vec, @@ -78,7 +79,7 @@ fn handle_lv1_string(res: &mut Vec, if s.trim().is_empty() { continue; } - handle_lv1_string(res, &s, word); + handle_lv1_string(res, s, word); } return; } @@ -136,16 +137,13 @@ fn complete_dots(line: &str, word: &str) -> Vec { } } - let docs; - match YamlLoader::load_from_str(&s) { - Ok(x) => { - docs = x; - } + let docs = match YamlLoader::load_from_str(&s) { + Ok(x) => x, Err(e) => { println_stderr!("\ncicada: Bad Yaml file: {}: {:?}", dot_file, e); return res; } - } + }; for doc in docs.iter() { match *doc { @@ -162,7 +160,7 @@ fn complete_dots(line: &str, word: &str) -> Vec { if sub_cmd.is_empty() { for k in h.keys() { if let Yaml::String(value) = k { - handle_lv1_string(&mut res, &value, word); + handle_lv1_string(&mut res, value, word); } } } else { diff --git a/src/completers/make.rs b/src/completers/make.rs index eaaed76..8ce9f85 100644 --- a/src/completers/make.rs +++ b/src/completers/make.rs @@ -25,46 +25,43 @@ impl Completer for MakeCompleter { fn handle_file(ci: &mut Vec, path: &str, file_path: &str, current_dir: &str) { if let Ok(f) = File::open(file_path) { let file = BufReader::new(&f); - let re_cmd; - match Regex::new(r"^ *([^ ]+):") { - Ok(x) => re_cmd = x, + let re_cmd = match Regex::new(r"^ *([^ ]+):") { + Ok(x) => x, Err(e) => { println_stderr!("cicada: regex build error: {:?}", e); return; } - } - let re_include; - match Regex::new(r"^ *include *([^ ]+) *$") { - Ok(x) => re_include = x, + }; + + let re_include = match Regex::new(r"^ *include *([^ ]+) *$") { + Ok(x) => x, Err(e) => { println_stderr!("cicada: regex build error: {:?}", e); return; } - } + }; - for (_, line) in file.lines().enumerate() { - if let Ok(line) = line { - if re_cmd.is_match(&line) { - for cap in re_cmd.captures_iter(&line) { - if !cap[1].starts_with(path) { - continue; - } - ci.push(Completion { - completion: cap[1].to_string(), - display: None, - suffix: Suffix::Default, - }); + for line in file.lines().map_while(Result::ok) { + if re_cmd.is_match(&line) { + for cap in re_cmd.captures_iter(&line) { + if !cap[1].starts_with(path) { + continue; } + ci.push(Completion { + completion: cap[1].to_string(), + display: None, + suffix: Suffix::Default, + }); } - if re_include.is_match(&line) { - for cap in re_include.captures_iter(&line) { - let _file = &cap[1]; - if _file.contains('/') { - handle_file(ci, path, &_file, current_dir); - } else { - let make_file = current_dir.to_owned() + "/" + _file; - handle_file(ci, path, &make_file, current_dir); - } + } + if re_include.is_match(&line) { + for cap in re_include.captures_iter(&line) { + let _file = &cap[1]; + if _file.contains('/') { + handle_file(ci, path, _file, current_dir); + } else { + let make_file = current_dir.to_owned() + "/" + _file; + handle_file(ci, path, &make_file, current_dir); } } } @@ -74,23 +71,21 @@ fn handle_file(ci: &mut Vec, path: &str, file_path: &str, current_di fn complete_make(path: &str) -> Vec { let mut res = Vec::new(); - let _current_dir; - match env::current_dir() { - Ok(x) => _current_dir = x, + let current_dir = match env::current_dir() { + Ok(dir) => match dir.to_str() { + Some(s) => s.to_string(), + None => { + println!("cicada: to_str error"); + return res; + } + }, Err(e) => { println!("cicada: get current_dir error: {:?}", e); return res; } - } - let current_dir; - match _current_dir.to_str() { - Some(x) => current_dir = x, - None => { - println!("cicada: to_str error"); - return res; - } - } - let make_file = current_dir.to_owned() + "/Makefile"; + }; + + let make_file = format!("{}/Makefile", current_dir); handle_file(&mut res, path, &make_file, ¤t_dir); res } diff --git a/src/completers/mod.rs b/src/completers/mod.rs index 4afd4cb..129f954 100644 --- a/src/completers/mod.rs +++ b/src/completers/mod.rs @@ -39,8 +39,7 @@ fn for_cd(line: &str) -> bool { fn for_bin(line: &str) -> bool { let ptn = r"(^ *(sudo|which|nohup)? *[a-zA-Z0-9_\.-]+$)|(^.+\| *(sudo|which|nohup)? *[a-zA-Z0-9_\.-]+$)"; - let result = libs::re::re_contains(line, ptn); - return result; + libs::re::re_contains(line, ptn) } fn for_dots(line: &str) -> bool { diff --git a/src/completers/path.rs b/src/completers/path.rs index a6348d7..6dbfe0a 100644 --- a/src/completers/path.rs +++ b/src/completers/path.rs @@ -111,49 +111,47 @@ pub fn complete_path(word: &str, for_dir: bool) -> Vec { }; // let dir_lookup = _dir_lookup.unwrap_or("."); if let Ok(entries) = read_dir(dir_lookup) { - for entry in entries { - if let Ok(entry) = entry { - let pathbuf = entry.path(); - let is_dir = pathbuf.is_dir(); - if for_dir && !is_dir { - continue; - } + for entry in entries.flatten() { + let pathbuf = entry.path(); + let is_dir = pathbuf.is_dir(); + if for_dir && !is_dir { + continue; + } - let entry_name = entry.file_name(); - // TODO: Deal with non-UTF8 paths in some way - if let Ok(_path) = entry_name.into_string() { - if _path.starts_with(&file_name) { - let (name, display) = if dir_orig != "" { - ( - format!("{}{}{}", dir_orig, MAIN_SEPARATOR, _path), - Some(_path), - ) - } else { - (_path, None) - }; - let mut name = str::replace(name.as_str(), "//", "/"); - if path_sep.is_empty() && !is_env { - name = tools::escape_path(&name); - } - let mut quoted = false; - if !path_sep.is_empty() { - name = tools::wrap_sep_string(&path_sep, &name); - quoted = true; - } - let suffix = if is_dir { - if quoted { - name.pop(); - } - Suffix::Some(MAIN_SEPARATOR) - } else { - Suffix::Default - }; - res.push(Completion { - completion: name, - display, - suffix, - }); + let entry_name = entry.file_name(); + // TODO: Deal with non-UTF8 paths in some way + if let Ok(_path) = entry_name.into_string() { + if _path.starts_with(&file_name) { + let (name, display) = if !dir_orig.is_empty() { + ( + format!("{}{}{}", dir_orig, MAIN_SEPARATOR, _path), + Some(_path), + ) + } else { + (_path, None) + }; + let mut name = str::replace(name.as_str(), "//", "/"); + if path_sep.is_empty() && !is_env { + name = tools::escape_path(&name); } + let mut quoted = false; + if !path_sep.is_empty() { + name = tools::wrap_sep_string(&path_sep, &name); + quoted = true; + } + let suffix = if is_dir { + if quoted { + name.pop(); + } + Suffix::Some(MAIN_SEPARATOR) + } else { + Suffix::Default + }; + res.push(Completion { + completion: name, + display, + suffix, + }); } } } @@ -172,8 +170,8 @@ fn split_pathname(path: &str, prefix: &str) -> (String, String, String) { match path.rfind('/') { Some(pos) => ( prefix.to_string(), - (&path[..=pos]).to_string(), - (&path[pos + 1..]).to_string(), + path[..=pos].to_string(), + path[pos + 1..].to_string(), ), None => (prefix.to_string(), String::new(), path.to_string()), } @@ -183,15 +181,13 @@ fn split_pathname(path: &str, prefix: &str) -> (String, String, String) { fn complete_bin(sh: &shell::Shell, path: &str) -> Vec { let mut res = Vec::new(); let (prefix, _, fname) = split_pathname(path, ""); - let env_path; - - match env::var("PATH") { - Ok(x) => env_path = x, + let env_path = match env::var("PATH") { + Ok(x) => x, Err(e) => { println_stderr!("cicada: env error when complete_bin: {:?}", e); return res; } - } + }; let mut checker: HashSet = HashSet::new(); @@ -250,39 +246,36 @@ fn complete_bin(sh: &shell::Shell, path: &str) -> Vec { for p in &path_list { if let Ok(list) = read_dir(p) { - for entry in list { - if let Ok(entry) = entry { - if let Ok(name) = entry.file_name().into_string() { - if name.starts_with(&fname) { - let _mode; - match entry.metadata() { - Ok(x) => _mode = x, - Err(e) => { - println_stderr!("cicada: metadata error: {:?}", e); - continue; - } - } - let mode = _mode.permissions().mode(); - if mode & 0o111 == 0 { - // not binary + for entry in list.flatten() { + if let Ok(name) = entry.file_name().into_string() { + if name.starts_with(&fname) { + let _mode = match entry.metadata() { + Ok(x) => x, + Err(e) => { + println_stderr!("cicada: metadata error: {:?}", e); continue; } - if checker.contains(&name) { - continue; - } - - let display = None; - let suffix = Suffix::Default; - checker.insert(name.clone()); - // TODO: need to handle quoted: `$ "foo#bar"` - let name_e = tools::escape_path(&name); - let name_e = format!("{}{}", prefix, name_e); - res.push(Completion { - completion: name_e, - display, - suffix, - }); + }; + let mode = _mode.permissions().mode(); + if mode & 0o111 == 0 { + // not binary + continue; } + if checker.contains(&name) { + continue; + } + + let display = None; + let suffix = Suffix::Default; + checker.insert(name.clone()); + // TODO: need to handle quoted: `$ "foo#bar"` + let name_e = tools::escape_path(&name); + let name_e = format!("{}{}", prefix, name_e); + res.push(Completion { + completion: name_e, + display, + suffix, + }); } } } diff --git a/src/completers/ssh.rs b/src/completers/ssh.rs index 3e67384..b76ba92 100644 --- a/src/completers/ssh.rs +++ b/src/completers/ssh.rs @@ -29,29 +29,26 @@ fn complete_ssh(path: &str) -> Vec { let ssh_config = home + "/.ssh/config"; if let Ok(f) = File::open(&ssh_config) { let file = BufReader::new(&f); - let re; - match Regex::new(r"^ *(?i)host +([^ ]+)") { - Ok(x) => re = x, + let re = match Regex::new(r"^ *(?i)host +([^ ]+)") { + Ok(x) => x, Err(e) => { println!("Regex build error: {:?}", e); return res; } - } - for (_, line) in file.lines().enumerate() { - if let Ok(line) = line { - if !re.is_match(&line) { + }; + for line in file.lines().map_while(Result::ok) { + if !re.is_match(&line) { + continue; + } + for cap in re.captures_iter(&line) { + if !cap[1].starts_with(path) { continue; } - for cap in re.captures_iter(&line) { - if !cap[1].starts_with(path) { - continue; - } - res.push(Completion { - completion: cap[1].to_string(), - display: None, - suffix: Suffix::Default, - }); - } + res.push(Completion { + completion: cap[1].to_string(), + display: None, + suffix: Suffix::Default, + }); } } } diff --git a/src/completers/utils.rs b/src/completers/utils.rs index f9c2d9f..a3b4062 100644 --- a/src/completers/utils.rs +++ b/src/completers/utils.rs @@ -33,7 +33,7 @@ pub fn expand_env_string(text: &mut String) { } let ptn = r"^\$([A-Za-z_][A-Za-z0-9_]*)"; let mut env_value = String::new(); - match libs::re::find_first_group(ptn, &text) { + match libs::re::find_first_group(ptn, text) { Some(x) => { if let Ok(val) = env::var(&x) { env_value = val; @@ -48,5 +48,5 @@ pub fn expand_env_string(text: &mut String) { return; } let t = text.clone(); - *text = libs::re::replace_all(&t, &ptn, &env_value); + *text = libs::re::replace_all(&t, ptn, &env_value); } diff --git a/src/core.rs b/src/core.rs index db379dc..fc8c39d 100644 --- a/src/core.rs +++ b/src/core.rs @@ -6,7 +6,6 @@ use std::os::unix::io::FromRawFd; use std::os::fd::RawFd; use std::process; -use libc; use nix::unistd::{execve, ForkResult}; use libs::pipes::pipe; @@ -130,7 +129,7 @@ pub fn run_pipeline( } // FIXME: move func-run into run single command - if let Some(cr) = try_run_func(sh, &cl, capture, log_cmd) { + if let Some(cr) = try_run_func(sh, cl, capture, log_cmd) { return (term_given, cr); } @@ -180,7 +179,7 @@ pub fn run_pipeline( false }; let options = CommandOptions { - isatty: isatty, + isatty, capture_output: capture, background: cl.background, envs: cl.envs.clone(), @@ -211,7 +210,7 @@ pub fn run_pipeline( let mut cmd_result = CommandResult::new(); for i in 0..length { - let child_id: i32 = _run_single_command( + let child_id: i32 = run_single_program( sh, cl, i, @@ -242,7 +241,7 @@ pub fn run_pipeline( if !fg_pids.is_empty() { let _cr = jobc::wait_fg_job(sh, pgid, &fg_pids); // for capture commands, e.g. `echo foo` in `echo "hello $(echo foo)" - // the cmd_result is already built in loop calling _run_single_command() + // the cmd_result is already built in loop calling run_single_program() // above. if !capture { cmd_result = _cr; @@ -253,7 +252,9 @@ pub fn run_pipeline( /// Run a single command. /// e.g. the `sort -k2` part of `ps ax | sort -k2 | head` -fn _run_single_command( +#[allow(clippy::needless_range_loop)] +#[allow(clippy::too_many_arguments)] +fn run_single_program( sh: &mut shell::Shell, cl: &CommandLine, idx_cmd: usize, @@ -261,7 +262,7 @@ fn _run_single_command( pgid: &mut i32, term_given: &mut bool, cmd_result: &mut CommandResult, - pipes: &Vec<(RawFd, RawFd)>, + pipes: &[(RawFd, RawFd)], fds_capture_stdout: &Option<(RawFd, RawFd)>, fds_capture_stderr: &Option<(RawFd, RawFd)>, ) -> i32 { @@ -469,7 +470,7 @@ fn _run_single_command( let path = if program.contains('/') { program.clone() } else { - libs::path::find_file_in_path(&program, true) + libs::path::find_file_in_path(program, true) }; if path.is_empty() { println_stderr!("cicada: {}: command not found", program); @@ -603,7 +604,7 @@ fn _run_single_command( }; } - return pid; + pid } Err(_) => { @@ -637,9 +638,9 @@ fn try_run_func( let mut stdout = String::new(); let mut stderr = String::new(); for cr in cr_list { - stdout.push_str(&cr.stdout.trim()); + stdout.push_str(cr.stdout.trim()); stdout.push(' '); - stderr.push_str(&cr.stderr.trim()); + stderr.push_str(cr.stderr.trim()); stderr.push(' '); } let mut cr = CommandResult::new(); @@ -687,7 +688,7 @@ pub fn run_calculator(line: &str) -> Result { } } Err(_) => { - return Err("syntax error"); + Err("syntax error") } } } diff --git a/src/ctime.rs b/src/ctime.rs index 939e857..86713fe 100644 --- a/src/ctime.rs +++ b/src/ctime.rs @@ -8,15 +8,10 @@ pub struct DateTime { impl DateTime { pub fn now() -> Self { - let odt: OffsetDateTime; - match OffsetDateTime::now_local() { - Ok(dt) => { - odt = dt; - } - Err(_) => { - odt = OffsetDateTime::now_utc(); - } - } + let odt: OffsetDateTime = match OffsetDateTime::now_local() { + Ok(dt) => dt, + Err(_) => OffsetDateTime::now_utc(), + }; DateTime { odt } } @@ -24,13 +19,10 @@ impl DateTime { let dummy_now = Self::now(); let offset_seconds = dummy_now.odt.offset().whole_minutes() * 60; let ts_nano = (ts + offset_seconds as f64) * 1000000000.0; - let odt: OffsetDateTime; - match OffsetDateTime::from_unix_timestamp_nanos(ts_nano as i128) { - Ok(x) => odt = x, - Err(_) => { - odt = OffsetDateTime::now_utc(); - } - } + let odt: OffsetDateTime = match OffsetDateTime::from_unix_timestamp_nanos(ts_nano as i128) { + Ok(x) => x, + Err(_) => OffsetDateTime::now_utc(), + }; DateTime { odt } } diff --git a/src/execute.rs b/src/execute.rs index ceccdc9..92970bd 100644 --- a/src/execute.rs +++ b/src/execute.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::io::{self, Read, Write}; -use libc; use regex::Regex; use crate::core; @@ -31,7 +30,7 @@ pub fn run_command_line(sh: &mut Shell, line: &str, tty: bool, let mut cr_list = Vec::new(); let mut status = 0; let mut sep = String::new(); - for token in parsers::parser_line::line_to_cmds(&line) { + for token in parsers::parser_line::line_to_cmds(line) { if token == ";" || token == "&&" || token == "||" { sep = token.clone(); continue; @@ -80,7 +79,7 @@ fn line_to_tokens(sh: &mut Shell, line: &str) -> (Tokens, HashMap) { @@ -95,7 +94,7 @@ fn set_shell_vars(sh: &mut Shell, envs: &HashMap) { fn run_proc(sh: &mut Shell, line: &str, tty: bool, capture: bool) -> CommandResult { let log_cmd = !sh.cmd.starts_with(' '); - match CommandLine::from_line(&line, sh) { + match CommandLine::from_line(line, sh) { Ok(cl) => { if cl.is_empty() { // for commands with only envs, e.g. @@ -114,23 +113,24 @@ fn run_proc(sh: &mut Shell, line: &str, tty: bool, shell::give_terminal_to(gid); } } - return cr; + + cr } Err(e) => { println_stderr!("cicada: {}", e); - return CommandResult::from_status(0, 1); + CommandResult::from_status(0, 1) } } } -fn run_with_shell<'a, 'b>(sh: &'a mut Shell, line: &'b str) -> CommandResult { - let (tokens, envs) = line_to_tokens(sh, &line); +fn run_with_shell(sh: &mut Shell, line: &str) -> CommandResult { + let (tokens, envs) = line_to_tokens(sh, line); if tokens.is_empty() { set_shell_vars(sh, &envs); return CommandResult::new(); } - match CommandLine::from_line(&line, sh) { + match CommandLine::from_line(line, sh) { Ok(c) => { let (term_given, cr) = core::run_pipeline(sh, &c, false, true, false); if term_given { @@ -140,18 +140,18 @@ fn run_with_shell<'a, 'b>(sh: &'a mut Shell, line: &'b str) -> CommandResult { } } - return cr; + cr } Err(e) => { println_stderr!("cicada: {}", e); - return CommandResult::from_status(0, 1); + CommandResult::from_status(0, 1) } } } pub fn run(line: &str) -> CommandResult { let mut sh = Shell::new(); - return run_with_shell(&mut sh, line); + run_with_shell(&mut sh, line) } #[cfg(test)] diff --git a/src/history.rs b/src/history.rs index 28e293e..b06dc86 100644 --- a/src/history.rs +++ b/src/history.rs @@ -15,22 +15,20 @@ use crate::tools; fn init_db(hfile: &str, htable: &str) { let path = Path::new(hfile); if !path.exists() { - let _parent; - match path.parent() { - Some(x) => _parent = x, + let _parent = match path.parent() { + Some(x) => x, None => { println_stderr!("cicada: history init - no parent found"); return; } - } - let parent; - match _parent.to_str() { - Some(x) => parent = x, + }; + let parent = match _parent.to_str() { + Some(x) => x, None => { println_stderr!("cicada: parent to_str is None"); return; } - } + }; match fs::create_dir_all(parent) { Ok(_) => {} Err(e) => { @@ -48,7 +46,7 @@ fn init_db(hfile: &str, htable: &str) { } } - let conn = match Conn::open(&hfile) { + let conn = match Conn::open(hfile) { Ok(x) => x, Err(e) => { println_stderr!("cicada: history: open db error: {}", e); @@ -126,34 +124,32 @@ pub fn init(rl: &mut Interface) { }; let mut dict_helper: HashMap = HashMap::new(); - for x in rows { - if let Ok(inp) = x { - let _inp: String = inp; - if dict_helper.contains_key(&_inp) { - continue; - } - dict_helper.insert(_inp.clone(), true); - rl.add_history(_inp.trim().to_string()); + for x in rows.flatten() { + let inp: String = x; + if dict_helper.contains_key(&inp) { + continue; } + dict_helper.insert(inp.clone(), true); + rl.add_history(inp.trim().to_string()); } } pub fn get_history_file() -> String { if let Ok(hfile) = env::var("HISTORY_FILE") { - return hfile; + hfile } else if let Ok(d) = env::var("XDG_DATA_HOME") { - return format!("{}/{}", d, "cicada/history.sqlite"); + format!("{}/{}", d, "cicada/history.sqlite") } else { let home = tools::get_user_home(); - return format!("{}/{}", home, ".local/share/cicada/history.sqlite"); + format!("{}/{}", home, ".local/share/cicada/history.sqlite") } } pub fn get_history_table() -> String { if let Ok(hfile) = env::var("HISTORY_TABLE") { - return hfile; + hfile } else { - return String::from("cicada_history"); + String::from("cicada_history") } } diff --git a/src/jobc.rs b/src/jobc.rs index 1613dce..1c7b964 100644 --- a/src/jobc.rs +++ b/src/jobc.rs @@ -94,30 +94,30 @@ pub fn waitpidx(wpid: i32, block: bool) -> types::WaitStatus { match waitpid(Pid::from_raw(wpid), options) { Ok(WS::Exited(pid, status)) => { let pid = i32::from(pid); - return types::WaitStatus::from_exited(pid, status); + types::WaitStatus::from_exited(pid, status) } Ok(WS::Stopped(pid, sig)) => { let pid = i32::from(pid); - return types::WaitStatus::from_stopped(pid, sig as i32); + types::WaitStatus::from_stopped(pid, sig as i32) } Ok(WS::Continued(pid)) => { let pid = i32::from(pid); - return types::WaitStatus::from_continuted(pid); + types::WaitStatus::from_continuted(pid) } Ok(WS::Signaled(pid, sig, _core_dumped)) => { let pid = i32::from(pid); - return types::WaitStatus::from_signaled(pid, sig as i32); + types::WaitStatus::from_signaled(pid, sig as i32) } Ok(WS::StillAlive) => { - return types::WaitStatus::empty(); + types::WaitStatus::empty() } Ok(_others) => { // this is for PtraceEvent and PtraceSyscall on Linux, // unreachable on other platforms. - return types::WaitStatus::from_others(); + types::WaitStatus::from_others() } Err(e) => { - return types::WaitStatus::from_error(e as i32); + types::WaitStatus::from_error(e as i32) } } } @@ -129,7 +129,7 @@ pub fn wait_fg_job(sh: &mut shell::Shell, gid: i32, pids: &[i32]) -> CommandResu if count_child == 0 { return cmd_result; } - let pid_last = pids.last().unwrap().clone(); + let pid_last = pids.last().unwrap(); loop { let ws = waitpidx(-1, true); @@ -182,7 +182,7 @@ pub fn wait_fg_job(sh: &mut shell::Shell, gid: i32, pids: &[i32]) -> CommandResu } } - if is_a_fg_child && pid == pid_last { + if is_a_fg_child && pid == *pid_last { let status = ws.get_status(); cmd_result.status = status; } diff --git a/src/libs/os_type.rs b/src/libs/os_type.rs index 8fc59cf..59ed00e 100644 --- a/src/libs/os_type.rs +++ b/src/libs/os_type.rs @@ -3,9 +3,9 @@ use crate::execute; pub fn get_os_name() -> String { let uname = get_uname(); if uname.to_lowercase() == "darwin" { - return get_macos_name(); + get_macos_name() } else { - return get_other_os_name(); + get_other_os_name() } } @@ -22,7 +22,7 @@ fn get_other_os_name() -> String { if !name.is_empty() { return name; } - return get_uname_mo() + get_uname_mo() } fn get_release_value(ptn: &str) -> String { diff --git a/src/libs/path.rs b/src/libs/path.rs index ce4215a..114ad64 100644 --- a/src/libs/path.rs +++ b/src/libs/path.rs @@ -8,7 +8,7 @@ use regex::Regex; use crate::tools; -pub fn basename<'a>(path: &'a str) -> Cow<'a, str> { +pub fn basename(path: &str) -> Cow<'_, str> { let mut pieces = path.rsplit('/'); match pieces.next() { Some(p) => p.into(), @@ -41,43 +41,39 @@ pub fn expand_home(text: &str) -> String { } pub fn find_file_in_path(filename: &str, exec: bool) -> String { - let env_path; - match env::var("PATH") { - Ok(x) => env_path = x, + let env_path = match env::var("PATH") { + Ok(x) => x, Err(e) => { println_stderr!("cicada: error with env PATH: {:?}", e); return String::new(); } - } + }; let vec_path: Vec<&str> = env_path.split(':').collect(); for p in &vec_path { match read_dir(p) { Ok(list) => { - for entry in list { - if let Ok(entry) = entry { - if let Ok(name) = entry.file_name().into_string() { - if name != filename { - continue; - } + for entry in list.flatten() { + if let Ok(name) = entry.file_name().into_string() { + if name != filename { + continue; + } - if exec { - let _mode; - match entry.metadata() { - Ok(x) => _mode = x, - Err(e) => { - println_stderr!("cicada: metadata error: {:?}", e); - continue; - } - } - let mode = _mode.permissions().mode(); - if mode & 0o111 == 0 { - // not binary + if exec { + let _mode = match entry.metadata() { + Ok(x) => x, + Err(e) => { + println_stderr!("cicada: metadata error: {:?}", e); continue; } + }; + let mode = _mode.permissions().mode(); + if mode & 0o111 == 0 { + // not binary + continue; } - - return entry.path().to_string_lossy().to_string(); } + + return entry.path().to_string_lossy().to_string(); } } } @@ -93,21 +89,20 @@ pub fn find_file_in_path(filename: &str, exec: bool) -> String { } pub fn current_dir() -> String { - let _current_dir; - match env::current_dir() { - Ok(x) => _current_dir = x, + let _current_dir = match env::current_dir() { + Ok(x) => x, Err(e) => { log!("cicada: PROMPT: env current_dir error: {}", e); return String::new(); } - } - let current_dir; - match _current_dir.to_str() { - Some(x) => current_dir = x, + }; + let current_dir = match _current_dir.to_str() { + Some(x) => x, None => { log!("cicada: PROMPT: to_str error"); return String::new(); } - } + }; + current_dir.to_string() } diff --git a/src/libs/progopts.rs b/src/libs/progopts.rs index b114dd6..f9fc1f5 100644 --- a/src/libs/progopts.rs +++ b/src/libs/progopts.rs @@ -1,5 +1,5 @@ -pub fn is_login(args: &Vec) -> bool { - if args.len() > 0 && args[0].starts_with("-") { +pub fn is_login(args: &[String]) -> bool { + if !args.is_empty() && args[0].starts_with("-") { return true; } @@ -10,11 +10,11 @@ pub fn is_login(args: &Vec) -> bool { false } -pub fn is_script(args: &Vec) -> bool { +pub fn is_script(args: &[String]) -> bool { args.len() > 1 && !args[1].starts_with("-") } -pub fn is_command_string(args: &Vec) -> bool { +pub fn is_command_string(args: &[String]) -> bool { args.len() > 1 && args[1] == "-c" } diff --git a/src/libs/re.rs b/src/libs/re.rs index 68cec0b..111d889 100644 --- a/src/libs/re.rs +++ b/src/libs/re.rs @@ -1,11 +1,10 @@ use regex; pub fn find_first_group(ptn: &str, text: &str) -> Option { - let re; - match regex::Regex::new(ptn) { - Ok(x) => re = x, + let re = match regex::Regex::new(ptn) { + Ok(x) => x, Err(_) => return None, - } + }; match re.captures(text) { Some(caps) => { if let Some(x) = caps.get(1) { @@ -20,16 +19,13 @@ pub fn find_first_group(ptn: &str, text: &str) -> Option { } pub fn re_contains(text: &str, ptn: &str) -> bool { - let re; - match regex::Regex::new(ptn) { - Ok(x) => { - re = x; - } + let re = match regex::Regex::new(ptn) { + Ok(x) => x, Err(e) => { println!("Regex new error: {:?}", e); return false; } - } + }; re.is_match(text) } diff --git a/src/parsers/parser_line.rs b/src/parsers/parser_line.rs index ef7688c..07732b9 100644 --- a/src/parsers/parser_line.rs +++ b/src/parsers/parser_line.rs @@ -94,14 +94,14 @@ pub fn line_to_cmds(line: &str) -> Vec { token.push(c); continue; } else { - let c_next; - match line.chars().nth(i + 1) { - Some(x) => c_next = x, + let c_next = match line.chars().nth(i + 1) { + Some(x) => x, None => { println!("chars nth error - should never happen"); continue; } - } + }; + if c_next != c { token.push(c); continue; @@ -455,7 +455,7 @@ pub fn parse_line(line: &str) -> LineInfo { } let mut is_line_complete = true; - if result.len() > 0 { + if !result.is_empty() { let token_last = result[result.len() - 1].clone(); if token_last.0.is_empty() && token_last.1 == "|" { is_line_complete = false; @@ -492,7 +492,7 @@ pub fn tokens_to_redirections(tokens: &Tokens) -> Result<(Tokens, Vec Result<(Tokens, Vec Result<(Tokens, Vec Result<(Tokens, Vec Result<(Tokens, Vec _current_dir = x, + let _current_dir = match env::current_dir() { + Ok(x) => x, Err(e) => { println_stderr!("cicada: PROMPT: env current_dir error: {}", e); return; } - } - let current_dir; - match _current_dir.to_str() { - Some(x) => current_dir = x, + }; + let current_dir = match _current_dir.to_str() { + Some(x) => x, None => { println_stderr!("cicada: PROMPT: to_str error"); return; } - } + }; let _tokens: Vec<&str> = current_dir.split('/').collect(); - let last; - match _tokens.last() { - Some(x) => last = x, + let last = match _tokens.last() { + Some(x) => x, None => { log!("cicada: PROMPT: token last error"); return; } - } + }; let home = tools::get_user_home(); let pwd = if last.is_empty() { @@ -381,14 +378,14 @@ pub fn apply_pyenv(prompt: &mut String) { if let Ok(x) = env::var("VIRTUAL_ENV") { if !x.is_empty() { let _tokens: Vec<&str> = x.split('/').collect(); - let env_name; - match _tokens.last() { - Some(x) => env_name = x, + let env_name = match _tokens.last() { + Some(x) => x, None => { log!("prompt token last error"); return; } - } + }; + apply_blue_b(prompt); prompt.push('('); prompt.push_str(env_name); diff --git a/src/scripting.rs b/src/scripting.rs index 2194f15..4389700 100644 --- a/src/scripting.rs +++ b/src/scripting.rs @@ -114,7 +114,7 @@ pub fn run_lines(sh: &mut shell::Shell, args: &Vec, capture: bool) -> Vec { let mut cr_list = Vec::new(); - match parsers::locust::parse_lines(&lines) { + match parsers::locust::parse_lines(lines) { Ok(pairs_exp) => { for pair in pairs_exp { let (mut _cr_list, _cont, _brk) = run_exp(sh, pair, args, false, capture); @@ -133,7 +133,7 @@ fn expand_args(line: &str, args: &[String]) -> String { let linfo = parsers::parser_line::parse_line(line); let mut tokens = linfo.tokens; expand_args_in_tokens(&mut tokens, args); - return parsers::parser_line::tokens_to_line(&tokens); + parsers::parser_line::tokens_to_line(&tokens) } fn expand_line_to_toknes(line: &str, @@ -209,7 +209,7 @@ fn expand_args_in_tokens(tokens: &mut types::Tokens, args: &[String]) { } for (i, text) in buff.iter().rev() { - tokens[*i as usize].1 = text.to_string(); + tokens[*i].1 = text.to_string(); } } @@ -284,7 +284,7 @@ fn run_exp_if(sh: &mut shell::Shell, fn get_for_result_from_init(sh: &mut shell::Shell, pair_init: Pair, - args: &Vec) -> Vec { + args: &[String]) -> Vec { let mut result: Vec = Vec::new(); let pairs = pair_init.into_inner(); for pair in pairs { @@ -308,7 +308,7 @@ fn get_for_result_from_init(sh: &mut shell::Shell, fn get_for_result_list(sh: &mut shell::Shell, pair_head: Pair, - args: &Vec) -> Vec { + args: &[String]) -> Vec { let pairs = pair_head.into_inner(); for pair in pairs { let rule = pair.as_rule(); @@ -316,7 +316,7 @@ fn get_for_result_list(sh: &mut shell::Shell, return get_for_result_from_init(sh, pair, args); } } - return Vec::new(); + Vec::new() } fn get_for_var_name(pair_head: Pair) -> String { @@ -354,7 +354,7 @@ fn run_exp_for(sh: &mut shell::Shell, } if rule == parsers::locust::Rule::EXP_BODY { for value in &result_list { - sh.set_env(&var_name, &value); + sh.set_env(&var_name, value); let (mut _cr_list, _cont, _brk) = run_exp( sh, pair.clone(), args, true, capture); cr_list.append(&mut _cr_list); diff --git a/src/shell.rs b/src/shell.rs index 2100be8..7e67d5c 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1,11 +1,9 @@ use errno::errno; -use libc; use std::collections::{HashMap, HashSet}; use std::env; use std::io::Write; use std::mem; -use glob; use regex::Regex; use uuid::Uuid; @@ -53,7 +51,7 @@ impl Shell { previous_status: 0, is_login: false, exit_on_error: false, - has_terminal: has_terminal, + has_terminal, session_id: session_id.to_string(), } } @@ -78,7 +76,7 @@ impl Shell { types::Job { cmd: cmd.to_string(), id: i, - gid: gid, + gid, pids: vec![pid], pids_stopped: HashSet::new(), status: status.to_string(), @@ -156,7 +154,7 @@ impl Shell { loop { if let Some(x) = self.jobs.get(&i) { if x.gid == gid { - return Some(&x); + return Some(x); } } @@ -283,13 +281,10 @@ impl Shell { } pub fn remove_path(&mut self, path: &str) { - match env::var("PATH") { - Ok(paths) => { - let mut paths_new: Vec<&str> = paths.split(":").collect(); - paths_new.retain(|&x| x != path); - env::set_var("PATH", paths_new.join(":").as_str()); - } - Err(_) => () + if let Ok(paths) = env::var("PATH") { + let mut paths_new: Vec<&str> = paths.split(":").collect(); + paths_new.retain(|&x| x != path); + env::set_var("PATH", paths_new.join(":").as_str()); } } @@ -302,10 +297,7 @@ impl Shell { } pub fn get_func(&self, name: &str) -> Option { - match self.funcs.get(name) { - Some(x) => Some(x.to_string()), - None => None, - } + self.funcs.get(name).map(|x| x.to_string()) } pub fn get_alias_list(&self) -> Vec<(String, String)> { @@ -326,19 +318,14 @@ impl Shell { pub fn remove_alias(&mut self, name: &str) -> bool { let opt = self.alias.remove(name); - return opt.is_some(); + opt.is_some() } pub fn get_alias_content(&self, name: &str) -> Option { - let result; - match self.alias.get(name) { - Some(x) => { - result = x.to_string(); - } - None => { - result = String::new(); - } - } + let result = match self.alias.get(name) { + Some(x) => x.to_string(), + None => String::new(), + }; if result.is_empty() { None } else { @@ -380,7 +367,7 @@ pub unsafe fn give_terminal_to(gid: i32) -> bool { fn needs_globbing(line: &str) -> bool { let re = Regex::new(r"\*+").expect("Invalid regex ptn"); - return re.is_match(line); + re.is_match(line) } pub fn expand_glob(tokens: &mut types::Tokens) { @@ -442,10 +429,10 @@ pub fn expand_glob(tokens: &mut types::Tokens) { } for (i, result) in buff.iter().rev() { - tokens.remove(*i as usize); + tokens.remove(*i); for (j, token) in result.iter().enumerate() { let sep = if token.contains(' ') { "\"" } else { "" }; - tokens.insert((*i + j) as usize, (sep.to_string(), token.clone())); + tokens.insert(*i + j, (sep.to_string(), token.clone())); } } } @@ -460,16 +447,16 @@ fn expand_one_env(sh: &Shell, token: &str) -> String { } let mut result = String::new(); - let match_re1 = re1.is_match(&token); - let match_re2 = re2.is_match(&token); + let match_re1 = re1.is_match(token); + let match_re2 = re2.is_match(token); if !match_re1 && !match_re2 { return token.to_string(); } let cap_results = if match_re1 { - re1.captures_iter(&token) + re1.captures_iter(token) } else { - re2.captures_iter(&token) + re2.captures_iter(token) }; for cap in cap_results { @@ -504,14 +491,13 @@ fn brace_getitem(s: &str, depth: i32) -> (Vec, String) { let mut out: Vec = vec![String::new()]; let mut ss = s.to_string(); let mut tmp; - while ss.len() > 0 { - let c; - match ss.chars().next() { - Some(x) => c = x, + while !ss.is_empty() { + let c = match ss.chars().next() { + Some(x) => x, None => { return (out, ss); } - } + }; if depth > 0 && (c == ',' || c == '}') { return (out, ss); } @@ -562,7 +548,7 @@ fn brace_getgroup(s: &str, depth: i32) -> Option<(Vec, String)> { let mut out: Vec = Vec::new(); let mut comma = false; let mut ss = s.to_string(); - while ss.len() > 0 { + while !ss.is_empty() { let (g, sss) = brace_getitem(ss.as_str(), depth); ss = sss.clone(); if ss.is_empty() { @@ -572,13 +558,12 @@ fn brace_getgroup(s: &str, depth: i32) -> Option<(Vec, String)> { out.push(x.clone()); } - let c; - match ss.chars().next() { - Some(x) => c = x, + let c = match ss.chars().next() { + Some(x) => x, None => { break; } - } + }; if c == '}' { let mut sss = ss.clone(); sss.remove(0); @@ -597,20 +582,21 @@ fn brace_getgroup(s: &str, depth: i32) -> Option<(Vec, String)> { ss.remove(0); } } - return None; + + None } fn expand_brace(tokens: &mut types::Tokens) { let mut idx: usize = 0; let mut buff = Vec::new(); for (sep, token) in tokens.iter() { - if !sep.is_empty() || !need_expand_brace(&token) { + if !sep.is_empty() || !need_expand_brace(token) { idx += 1; continue; } let mut result: Vec = Vec::new(); - let items = brace_getitem(&token, 0); + let items = brace_getitem(token, 0); for x in items.0 { result.push(x.clone()); } @@ -619,10 +605,10 @@ fn expand_brace(tokens: &mut types::Tokens) { } for (i, items) in buff.iter().rev() { - tokens.remove(*i as usize); + tokens.remove(*i); for (j, token) in items.iter().enumerate() { let sep = if token.contains(' ') { "\"" } else { "" }; - tokens.insert((*i + j) as usize, (sep.to_string(), token.clone())); + tokens.insert(*i + j, (sep.to_string(), token.clone())); } } } @@ -639,29 +625,29 @@ fn expand_brace_range(tokens: &mut types::Tokens) { let mut idx: usize = 0; let mut buff: Vec<(usize, Vec)> = Vec::new(); for (sep, token) in tokens.iter() { - if !sep.is_empty() || !re.is_match(&token) { + if !sep.is_empty() || !re.is_match(token) { idx += 1; continue; } // safe to unwrap here, since the `is_match` above already validated - let caps = re.captures(&token).unwrap(); - let start; - match caps[1].to_string().parse::() { - Ok(x) => start = x, + let caps = re.captures(token).unwrap(); + + let start = match caps[1].to_string().parse::() { + Ok(x) => x, Err(e) => { println_stderr!("cicada: {}", e); return; } - } - let end; - match caps[2].to_string().parse::() { - Ok(x) => end = x, + }; + + let end = match caps[2].to_string().parse::() { + Ok(x) => x, Err(e) => { println_stderr!("cicada: {}", e); return; } - } + }; // incr is always positive let mut incr = if caps.get(4).is_none() { @@ -698,10 +684,10 @@ fn expand_brace_range(tokens: &mut types::Tokens) { } for (i, items) in buff.iter().rev() { - tokens.remove(*i as usize); + tokens.remove(*i); for (j, token) in items.iter().enumerate() { let sep = if token.contains(' ') { "\"" } else { "" }; - tokens.insert((*i + j) as usize, (sep.to_string(), token.clone())); + tokens.insert(*i + j, (sep.to_string(), token.clone())); } } } @@ -721,13 +707,13 @@ fn expand_alias(sh: &Shell, tokens: &mut types::Tokens) { continue; } - if !is_head || !sh.is_alias(&text) { + if !is_head || !sh.is_alias(text) { idx += 1; is_head = false; continue; } - if let Some(value) = sh.get_alias_content(&text) { + if let Some(value) = sh.get_alias_content(text) { buff.push((idx, value.clone())); } @@ -736,11 +722,11 @@ fn expand_alias(sh: &Shell, tokens: &mut types::Tokens) { } for (i, text) in buff.iter().rev() { - let linfo = parsers::parser_line::parse_line(&text); + let linfo = parsers::parser_line::parse_line(text); let tokens_ = linfo.tokens; - tokens.remove(*i as usize); + tokens.remove(*i); for item in tokens_.iter().rev() { - tokens.insert(*i as usize, item.clone()); + tokens.insert(*i, item.clone()); } } } @@ -768,7 +754,7 @@ fn expand_home(tokens: &mut types::Tokens) { } for (i, text) in buff.iter().rev() { - tokens[*i as usize].1 = text.to_string(); + tokens[*i].1 = text.to_string(); } } @@ -797,7 +783,7 @@ fn env_in_token(token: &str) -> bool { // for cmd-line like `alias foo='echo $PWD'` let ptn_env = format!(r"='.*\$\{{?{}\}}?.*'$", ptn_env_name); - return !libs::re::re_contains(token, &ptn_env); + !libs::re::re_contains(token, &ptn_env) } pub fn expand_env(sh: &Shell, tokens: &mut types::Tokens) { @@ -824,7 +810,7 @@ pub fn expand_env(sh: &Shell, tokens: &mut types::Tokens) { } for (i, text) in buff.iter().rev() { - tokens[*i as usize].1 = text.to_string(); + tokens[*i].1 = text.to_string(); } } @@ -848,23 +834,20 @@ fn do_command_substitution_for_dollar(sh: &mut Shell, tokens: &mut types::Tokens if !should_do_dollar_command_extension(&line) { break; } + let ptn_cmd = r"\$\((.+)\)"; - let cmd; - match libs::re::find_first_group(ptn_cmd, &line) { - Some(x) => { - cmd = x; - } + let cmd = match libs::re::find_first_group(ptn_cmd, &line) { + Some(x) => x, None => { println_stderr!("cicada: calculator: no first group"); return; } - } + }; - let cmd_result; - match CommandLine::from_line(&cmd, sh) { + let cmd_result = match CommandLine::from_line(&cmd, sh) { Ok(c) => { log!("run subcmd dollar: {:?}", &cmd); - let (term_given, _cr) = core::run_pipeline(sh, &c, false, true, false); + let (term_given, cr) = core::run_pipeline(sh, &c, false, true, false); if term_given { unsafe { let gid = libc::getpgid(0); @@ -872,13 +855,14 @@ fn do_command_substitution_for_dollar(sh: &mut Shell, tokens: &mut types::Tokens } } - cmd_result = _cr; + cr } Err(e) => { println_stderr!("cicada: {}", e); continue; } - } + }; + let output_txt = cmd_result.stdout.trim(); let ptn = r"(?P[^\$]*)\$\(.+\)(?P.*)"; @@ -900,7 +884,7 @@ fn do_command_substitution_for_dollar(sh: &mut Shell, tokens: &mut types::Tokens } for (i, text) in buff.iter() { - tokens[*i as usize].1 = text.to_string(); + tokens[*i].1 = text.to_string(); } } @@ -911,8 +895,7 @@ fn do_command_substitution_for_dot(sh: &mut Shell, tokens: &mut types::Tokens) { let new_token: String; if sep == "`" { log!("run subcmd dot1: {:?}", token); - let cr; - match CommandLine::from_line(&token, sh) { + let cr = match CommandLine::from_line(token, sh) { Ok(c) => { let (term_given, _cr) = core::run_pipeline(sh, &c, false, true, false); if term_given { @@ -922,13 +905,13 @@ fn do_command_substitution_for_dot(sh: &mut Shell, tokens: &mut types::Tokens) { } } - cr = _cr; + _cr } Err(e) => { println_stderr!("cicada: {}", e); continue; } - } + }; new_token = cr.stdout.trim().to_string(); } else if sep == "\"" || sep.is_empty() { @@ -939,7 +922,7 @@ fn do_command_substitution_for_dot(sh: &mut Shell, tokens: &mut types::Tokens) { println_stderr!("cicada: re new error"); return; } - if !re.is_match(&token) { + if !re.is_match(token) { idx += 1; continue; } @@ -960,8 +943,7 @@ fn do_command_substitution_for_dot(sh: &mut Shell, tokens: &mut types::Tokens) { _tail = cap[3].to_string(); log!("run subcmd dot2: {:?}", &cap[2]); - let cr; - match CommandLine::from_line(&cap[2], sh) { + let cr = match CommandLine::from_line(&cap[2], sh) { Ok(c) => { let (term_given, _cr) = core::run_pipeline(sh, &c, false, true, false); if term_given { @@ -971,13 +953,13 @@ fn do_command_substitution_for_dot(sh: &mut Shell, tokens: &mut types::Tokens) { } } - cr = _cr; + _cr } Err(e) => { println_stderr!("cicada: {}", e); continue; } - } + }; _output = cr.stdout.trim().to_string(); } @@ -998,7 +980,7 @@ fn do_command_substitution_for_dot(sh: &mut Shell, tokens: &mut types::Tokens) { } for (i, text) in buff.iter() { - tokens[*i as usize].1 = text.to_string(); + tokens[*i].1 = text.to_string(); } } @@ -1010,13 +992,11 @@ fn do_command_substitution(sh: &mut Shell, tokens: &mut types::Tokens) { pub fn do_expansion(sh: &mut Shell, tokens: &mut types::Tokens) { let line = parsers::parser_line::tokens_to_line(tokens); if tools::is_arithmetic(&line) { - return + return; } - if tokens.len() >= 2 { - if tokens[0].1 == "export" && tokens[1].1.starts_with("PROMPT=") { - return; - } + if tokens.len() >= 2 && tokens[0].1 == "export" && tokens[1].1.starts_with("PROMPT=") { + return; } expand_alias(sh, tokens); @@ -1034,15 +1014,14 @@ pub fn trim_multiline_prompts(line: &str) -> String { // 2. `>>` is defined as `src/prompt/multilines.rs` let line_new = libs::re::replace_all(line, r"\\\n>> ", ""); let line_new = libs::re::replace_all(&line_new, r"\| *\n>> ", "| "); - let line_new = libs::re::replace_all(&line_new, r"(?P\n)>> ", "$NEWLINE"); - line_new + libs::re::replace_all(&line_new, r"(?P\n)>> ", "$NEWLINE") } fn proc_has_terminal() -> bool { unsafe { let tgid = libc::tcgetpgrp(0); let pgid = libc::getpgid(0); - return tgid == pgid; + tgid == pgid } } diff --git a/src/tlog.rs b/src/tlog.rs index 0af2ceb..f79f76e 100644 --- a/src/tlog.rs +++ b/src/tlog.rs @@ -17,8 +17,8 @@ macro_rules! log { let msg = $fmt; match std::fs::OpenOptions::new().append(true).create(true).open(&log_file) { Ok(mut cfile) => { - let pid = crate::tlog::getpid(); - let now = crate::ctime::DateTime::now(); + let pid = $crate::tlog::getpid(); + let now = $crate::ctime::DateTime::now(); let msg = format!("[{}][{}] {}", now, pid, msg); let msg = if msg.ends_with('\n') { msg } else { format!("{}\n", msg) }; match cfile.write_all(msg.as_bytes()) { diff --git a/src/tools.rs b/src/tools.rs index e49e930..0b18438 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -6,7 +6,6 @@ use std::io::Write; use std::os::unix::io::IntoRawFd; use std::path::{Path, PathBuf}; -use libc; use regex::Regex; use crate::execute; @@ -30,14 +29,7 @@ macro_rules! println_stderr { } pub fn is_signal_handler_enabled() -> bool { - match env::var("CICADA_ENABLE_SIG_HANDLER") { - Ok(x) => { - return x == "1"; - } - Err(_) => { - return false; - } - } + env::var("CICADA_ENABLE_SIG_HANDLER").map_or(false, |x| x == "1") } pub fn get_user_name() -> String { @@ -242,7 +234,7 @@ pub fn create_raw_fd_from_file(file_name: &str, append: bool) -> Result i32 { let path = Path::new(file_name); let display = path.display(); - let file = match File::open(&path) { + let file = match File::open(path) { Err(why) => { println_stderr!("cicada: {}: {}", display, why); return -1; @@ -313,7 +305,7 @@ pub fn is_builtin(s: &str) -> bool { pub fn init_path_env() { // order matters. took from `runc spec` let mut paths: Vec = vec![]; - for x in vec![ + for x in [ "/usr/local/sbin", "/usr/local/bin", "/usr/sbin", diff --git a/src/types.rs b/src/types.rs index c74d324..06972b4 100644 --- a/src/types.rs +++ b/src/types.rs @@ -132,7 +132,7 @@ pub struct LineInfo { impl LineInfo { pub fn new(tokens: Tokens) -> Self { - LineInfo { tokens: tokens, is_complete: true } + LineInfo { tokens, is_complete: true } } } @@ -213,8 +213,8 @@ impl Command { Ok(Command{ tokens: tokens_final, - redirects_to: redirects_to, - redirect_from: redirect_from, + redirects_to, + redirect_from, }) } @@ -247,11 +247,11 @@ pub struct Job { impl Job { pub fn all_members_stopped(&self) -> bool { for pid in &self.pids { - if !self.pids_stopped.contains(&pid) { + if !self.pids_stopped.contains(pid) { return false; } } - return true; + true } pub fn all_members_running(&self) -> bool { @@ -280,8 +280,8 @@ impl CommandResult { pub fn from_status(gid: i32, status: i32) -> CommandResult { CommandResult { - gid: gid, - status: status, + gid, + status, stdout: String::new(), stderr: String::new(), } @@ -380,9 +380,9 @@ impl CommandLine { Ok(CommandLine{ line: line.to_string(), - commands: commands, - envs: envs, - background: background, + commands, + envs, + background, }) }