Skip to content

Commit

Permalink
Support shopt -u and -s
Browse files Browse the repository at this point in the history
  • Loading branch information
ryuichiueda committed Jul 14, 2024
1 parent 4505dc0 commit 6e5886b
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 49 deletions.
47 changes: 30 additions & 17 deletions src/core/builtins/shopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,42 @@

use crate::ShellCore;

pub fn shopt(core: &mut ShellCore, args: &mut Vec<String>) -> i32 {
if args.len() == 1 {
pub fn shopt_print(core: &mut ShellCore, args: &mut Vec<String>, all: bool) -> i32 {
if all {
core.shopts.print_all();
return 0;
}

if args[1] == "-s" {
if args.len() == 2 {
core.shopts.print_if(true);
}else{
core.shopts.set(&args[2], true);
}
return 0;
let mut res = true;
match args[1].as_str() {
"-s" => core.shopts.print_if(true),
"-u" => core.shopts.print_if(false),
opt => res = core.shopts.print_opt(opt),
}

if args[1] == "-u" {
if args.len() == 2 {
core.shopts.print_if(false);
}else{
core.shopts.set(&args[2], false);
}
return 0;
match res {
true => 0,
false => 1,
}
}

0
pub fn shopt(core: &mut ShellCore, args: &mut Vec<String>) -> i32 {
if args.len() < 3 {
return shopt_print(core, args, args.len() < 2);
}

let res = match args[1].as_str() {
"-s" => core.shopts.set(&args[2], true),
"-u" => core.shopts.set(&args[2], false),
arg => {
eprintln!("sush: shopt: {}: invalid shell option name", arg);
eprintln!("shopt: usage: shopt [-su] [optname ...]");
false
},
};

match res {
true => 0,
false => 1,
}
}
71 changes: 39 additions & 32 deletions src/core/shopts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,44 +36,45 @@ impl Shopts {
shopts
}

pub fn print_all(&self) {
let mut list = vec![];

for opt in &self.opts {
let onoff = match opt.1 {
true => "on",
false => "off",
};
if opt.0.len() < 16 {
list.push(format!("{:16}{}", opt.0, onoff));
}else{
list.push(format!("{}\t{}", opt.0, onoff));
}
}

list.sort();
list.iter().for_each(|e| println!("{}", e));
}

pub fn print_if(&self, onoff: bool) {
let mut list = vec![];

pub fn format(opt: &str, onoff: bool) -> String {
let onoff_str = match onoff {
true => "on",
false => "off",
};

for opt in &self.opts {
if *opt.1 != onoff {
continue;
}
match opt.len() < 16 {
true => format!("{:16}{}", opt, onoff_str),
false => format!("{}\t{}", opt, onoff_str),
}
}

if opt.0.len() < 16 {
list.push(format!("{:16}{}", opt.0, onoff_str));
}else{
list.push(format!("{}\t{}", opt.0, onoff_str));
}
pub fn print_opt(&self, opt: &str) -> bool {
match self.opts.get_key_value(opt) {
None => {
eprintln!("sush: shopt: {}: invalid shell option name", opt);
false
},
Some(kv) => {
println!("{}", Self::format(kv.0, *kv.1));
true
},
}
}

pub fn print_all(&self) {
let mut list = self.opts.iter()
.map(|opt| Self::format(opt.0, *opt.1))
.collect::<Vec<String>>();

list.sort();
list.iter().for_each(|e| println!("{}", e));
}

pub fn print_if(&self, onoff: bool) {
let mut list = self.opts.iter()
.filter(|opt| *opt.1 == onoff)
.map(|opt| Self::format(opt.0, *opt.1))
.collect::<Vec<String>>();

list.sort();
list.iter().for_each(|e| println!("{}", e));
Expand All @@ -83,7 +84,13 @@ impl Shopts {
self.opts[opt]
}

pub fn set(&mut self, opt: &str, onoff: bool) {
pub fn set(&mut self, opt: &str, onoff: bool) -> bool {
if ! self.opts.contains_key(opt) {
eprintln!("sush: shopt: {}: invalid shell option name", opt);
return false;
}

self.opts.insert(opt.to_string(), onoff);
true
}
}

0 comments on commit 6e5886b

Please sign in to comment.