diff --git a/usr/src/mei/echo/src/echo.rs b/usr/src/mei/echo/src/echo.rs index ad5eee9..6522788 100644 --- a/usr/src/mei/echo/src/echo.rs +++ b/usr/src/mei/echo/src/echo.rs @@ -27,64 +27,60 @@ use std::env; -fn main() { - let print: String = env::args().skip(1).collect::>().join(" "); - // This does not currently mimic functionality of illumos echo - if print.is_empty() { - println!(""); - } else { - println!("{print}"); +fn escape(escstr: String) -> String { + let escmap = vec![ + ("\\\\", "\\"), + //("\\a", "\a"), + //("\\b", "\b"), + //("\\f", "\f"), + ("\\n", "\n"), + ("\\r", "\r"), + ("\\t", "\t"), + //("\\v", "\v"), + ]; + let mut im = escstr.to_owned(); + for esc in escmap { + im = str::replace(im.as_str(), esc.0, esc.1); } - - // This mimics illumos echo functionality, or it should - /* - let mut esc: bool = false; - let mut is_num: bool = false; - let mut oct: String = "".to_string(); - let mut oc: u8 = 0; - - for c in print.chars() { - if !esc { - if c == '\\' { - esc = true; + // TODO: Handle octal esc \0n where n is 1-, 2-, or 3-digit octal number + let mut octstr: String = String::new(); + let escb = im.as_bytes(); + let mut i = 0; + while i < escb.len() { + if !(i + 1 >= escb.len()) { + let mut xe = i + 1; + if !(escb[i] == b'\\' && escb[xe] == b'0') { + octstr += &im[i..i + 1]; + i += 1; + continue; + } + i = xe + 1; + while char::from(escb[xe + 1]).is_digit(8) && i - xe < 3 { + xe += 1; + } + let c: u8 = if let Ok(x) = u8::from_str_radix(&im[i..xe], 8) { + x } else { - print!("{c}"); - } - } else { - match c { - // "unknown character escape" wtf rust these are valid. - //'a' => print!("\a"), - //'b' => print!("\b"), - //'c' => print!("\c"), - //'f' => print!("\f"), - 'n' => print!("\n"), - 'r' => print!("\r"), - 't' => print!("\t"), - //'v' => print!("\v"), - '\\' => print!("\\"), - '0' => is_num = true, - _ => print!("\\{c}"), - } - if is_num { - if oc < 3 { - oct.push(c); - oc = oc + 1; - } - if oc == 2 { - match u32::from_str_radix(oct.as_str(), 8) { - Ok(chr) => print!("{}", chr), - Err(_) => print!("\\0{}", oct), - } - is_num = false; - oct = "".to_string(); - oc = 0; - esc = false; - } - } else { - esc = false; - } + continue; + }; + octstr += char::from(c).to_string().as_str(); + i = xe; } } - print!("\n"); - */ + // TODO: find and handle \c + let mut retitr = octstr.split("\\c").peekable(); + if let Some(retstr) = retitr.next() { + if retitr.peek().is_none() { + (retstr.to_owned() + "\n").clone() + } else { + retstr.to_string().clone() + } + } else { + String::from("\n") + } +} + +fn main() { + let print: String = env::args().skip(1).collect::>().join(" "); + print!("{}", escape(print)); }