feature/variables #3

Merged
ahurac merged 4 commits from feature/variables into main 2023-12-11 19:44:35 +01:00
6 changed files with 62 additions and 26 deletions

View file

@ -17,6 +17,7 @@
- [ ] `exit` - [ ] `exit`
- [ ] Special variables - [ ] Special variables
- [ ] `_` - [ ] `_`
- [ ] `PS1` - [x] `PS1`
- [ ] Positional variables - [ ] Positional variables
- [ ] `RANDOM`
- [ ] Handle signals - [ ] Handle signals

View file

@ -1,15 +1,20 @@
use std::io as stdio; use std::io as stdio;
use stdio::stdin; use stdio::stdin;
use crate::parser; use crate::parser;
use crate::job;
use std::process::ExitStatus;
use std::io::Result;
pub struct Buffer { pub struct Buffer {
buffer: String, buffer: String,
argv: Vec<String>,
} }
impl Buffer { impl Buffer {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
buffer: String::new(), buffer: String::new(),
argv: vec![],
} }
} }
@ -28,9 +33,10 @@ impl Buffer {
} }
} }
pub fn parse(&self) -> Option<Vec<String>> { pub fn try_spawn(&mut self) -> Option<Result<ExitStatus>> {
if ! self.buffer.is_empty() { if ! self.buffer.is_empty() {
Some(parser::parse(&self.buffer)) self.argv = parser::parse(&self.buffer);
Some(job::execute(&mut self.argv))
} else { } else {
None None
} }

View file

@ -8,7 +8,7 @@ use std::io::{
ErrorKind, ErrorKind,
}; };
pub fn execute(mut argv: Vec<String>) -> Result<ExitStatus> { pub fn execute(argv: &mut Vec<String>) -> Result<ExitStatus> {
let mut command = Command::new(&argv[0]); let mut command = Command::new(&argv[0]);
argv.remove(0); argv.remove(0);
command.args(argv); command.args(argv);

View file

@ -1,36 +1,35 @@
mod input;
mod parser;
mod job;
mod variables;
use std::io::Result; use std::io::Result;
use std::process::{ use std::process::{
ExitStatus, ExitStatus,
exit, exit,
}; };
use variables::Variables;
mod input;
mod output;
mod parser;
mod job;
fn main() { fn main() {
let mut buffer = input::Buffer::new(); let mut buffer = input::Buffer::new();
let mut bytes_read: usize = 1; let mut bytes_read: usize = 1;
let mut argv: Option<Vec<String>>; let mut exit_status: Option<Result<ExitStatus>>;
let mut exit_status: Result<ExitStatus>;
let mut exit_code: i32 = 0; let mut exit_code: i32 = 0;
let mut variables = Variables::new();
while bytes_read != 0 { while bytes_read != 0 {
output::print_ps1(); variables.print_ps1();
bytes_read = buffer.read_line(); bytes_read = buffer.read_line();
argv = buffer.parse(); exit_status = buffer.try_spawn();
if argv.is_some() {
exit_status = job::execute(argv.unwrap());
if exit_status.is_some() {
let exit_status = exit_status.unwrap();
if exit_status.is_ok() { if exit_status.is_ok() {
let exit_status = exit_status.unwrap(); let exit_status = exit_status.unwrap();
if exit_status.code().is_some() { if exit_status.code().is_some() {
exit_code = exit_status.code().unwrap(); exit_code = exit_status.code().unwrap();
} else {
exit_code = 1;
} }
} else { } else {
exit_code = 1; exit_code = 1;

View file

@ -1,9 +0,0 @@
use std::io::stdout;
use std::io::Write;
pub fn print_ps1() {
print!("$ ");
if stdout().flush().is_err() {
eprintln!("error: can't fully flush stdout or reached EOF");
}
}

39
src/variables.rs Normal file
View file

@ -0,0 +1,39 @@
use std::collections::HashMap;
use std::io;
use std::io::Write;
use std::env;
pub struct Variables {
variables: HashMap<String, String>,
}
impl Variables {
pub fn new() -> Self {
Self {
variables: HashMap::new(),
}
}
pub fn get(&self, name: &str) -> String {
let content = env::var(name);
if content.is_ok() {
content.unwrap()
} else {
let content = self.variables.get(name);
if content.is_some() {
content.unwrap().to_string()
} else {
"".to_string()
}
}
}
pub fn print_ps1(&self) {
print!("{}", self.get("PS1"));
if io::stdout().flush().is_err() {
eprintln!("error: can't fully flush stdout or reached EOF");
}
}
}