about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorRen Kararou <[email protected]>2023-11-15 13:59:02 -0600
committerRen Kararou <[email protected]>2023-11-15 13:59:02 -0600
commit80c9771e932e8d665ee127dc78bd2f6a6794243f (patch)
tree7dec59889d0c25242c93f0086e90483583c95bee
parent2bbeb0c8e6e2a5ae20c992db019c2bb3dbe4f419 (diff)
downloadk2spice-80c9771e932e8d665ee127dc78bd2f6a6794243f.tar.gz
k2spice-80c9771e932e8d665ee127dc78bd2f6a6794243f.tar.bz2
k2spice-80c9771e932e8d665ee127dc78bd2f6a6794243f.zip
breaking rust in the good way
-rw-r--r--usr/src/mei/printf/src/printf.rs97
1 files changed, 91 insertions, 6 deletions
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<String>,
-    argument: Option<Vec<String>>,
+    argument: Vec<String>,
 }
 
 #[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>) -> 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<char> = 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::<i64>() {
+ *                                 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>) -> 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>) -> 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}");
     }