diff --git a/usr/src/mei/printf/src/printf.rs b/usr/src/mei/printf/src/printf.rs index 7591734..b343e6d 100644 --- a/usr/src/mei/printf/src/printf.rs +++ b/usr/src/mei/printf/src/printf.rs @@ -43,7 +43,7 @@ use clap::Parser; #[command(name = "printf")] struct Args { format: Option, - argument: Option>, + argument: Vec, } #[inline] @@ -62,7 +62,7 @@ fn escape(escstr: String) -> String { ("\\t", "\t"), //("\\v", "\v"), ]; - let mut im = escstr; + let mut im = escstr.to_owned(); for esc in escmap { im = str::replace(im.as_str(), esc.0, esc.1); } @@ -71,20 +71,105 @@ fn escape(escstr: String) -> String { im.clone() } -fn fmt(fmtstr: String) -> String { - fmtstr.clone() +/* + * fn fmt(fmtstr: String, args: Vec) -> String { + * let mut formatted: String = "".to_string(); + * let mut data = args.into_iter(); + * let fmtiter = fmtstr.clone(); + * let mut fmtiter = fmtiter.chars().peekable(); + * for _idx in 1..fmtstr.len() { + * let c: Option = fmtiter.next(); + * match c { + * Some('%') => { + * let next: char = if let Some(v) = fmtiter.next() { + * v + * } else { + * formatted += String::from('%').as_str(); + * break; + * }; + * match next { + * 'd' => { + * if let Some(arg) = data.next() { + * if let Ok(i) = arg.parse::() { + * formatted += String::from(format!("{i}")).as_str(); + * } else { + * eprintln!("printf: trying to format non-int data as int"); + * } + * } else { + * eprintln!("printf: format argument not supplied"); + * } + * }, + * _ => formatted += {String::from('%') + String::from(next).as_str()}.as_str(), + * } + * }, + * Some(c) => formatted += String::from(c).as_str(), + * None => break, + * } + * } + * formatted.clone() + * } + */ + +fn fmtint(s: &str, d: Option) -> String { + if let Some(i) = d { + format!("{i}") + } else { + String::new() + } +} + +fn chkfmt(chkstr: &str) -> bool { + // TODO: check if the thing is correct + true +} + +fn fmt(fmtstr: String, args: Vec) -> String { + let mut formatted: String = "".to_string(); + let mut args = args.into_iter(); + let fmtb = fmtstr.as_bytes(); + let mut i = 0; + while i < fmtb.len() { + if fmtb[i] == b'%' { + if !(i + 1 >= fmtb.len()) { + let mut xe = i + 1; + // find end of format specifier and get its index + while xe < fmtb.len() { + match fmtb[xe] { + b'd' | b'i' | b'o' | b'u' | b'x' | b'X' | b'f' | b'e' | b'E' | b'g' + | b'G' | b'c' | b's' | b'%' => break, + _ => xe += 1, + } + } + if !(chkfmt(&fmtstr[i..xe])) { + eprintln!("printf: invalid format string"); + i += 1; + continue; + } + match fmtb[xe] { + b'd' => formatted += fmtint(&fmtstr[i..xe], args.next()).as_str(), + // at this point, this match should be impossible + _ => (), + }; + i = xe; + } + } else { + formatted += &fmtstr[i..i+1]; + } + i += 1; + } + formatted.clone() } fn main() -> ExitCode { let args = Args::parse(); - if args.format.clone().is_none() && args.argument.clone().is_none() { + if args.format.clone().is_none() { usage(); return ExitCode::FAILURE; } if let Some(fmtstr) = args.format { - let fmtstr = escape(fmtstr.clone()); + let fmtstr = fmt(escape(fmtstr), args.argument); print!("{fmtstr}"); }