mirror of
https://git.sr.ht/~spicywolf/k2spice
synced 2025-01-18 17:59:39 +00:00
breaking rust in the good way
This commit is contained in:
parent
2bbeb0c8e6
commit
80c9771e93
|
@ -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}");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue