use std::io::Write;
pub(super) fn printf(w: &mut dyn Write, fmt: &str, args: &[&[u8]]) {
let mut out = Vec::with_capacity(fmt.len() + 64);
let mut args = args.iter();
let b = fmt.as_bytes();
let mut i = 0;
while i < b.len() {
if b[i] != b'%' {
out.push(b[i]);
i += 1;
continue;
}
i += 1;
if b.get(i) == Some(&b'%') {
out.push(b'%');
i += 1;
continue;
}
while i < b.len() && !matches!(b[i], b's' | b'd' | b'i' | b'c' | b'X') {
i += 1;
}
i += 1;
out.extend_from_slice(args.next().copied().unwrap_or_default());
}
let _ = w.write_all(&out);
}
pub(super) const PERROR: &str = "%s: %s\n";
pub(super) const PERROR_BARE: &str = "%s\n";
pub(super) const UNKNOWN_FLAG: &str = "Unknown flag: '%c'; ";
pub(super) const MISSING_MAXBITS: &str = "Missing maxbits\n";
pub(super) const STDIN_COMPRESSION: &str = "Compression: ";
pub(super) const NO_FILES_RECURSIVE: &str = "no files processed after recursive search\n";
pub(super) const USAGE: &str = concat!(
"Usage: %s [-dfhvcVr] [-b maxbits] [--] [path ...]\n",
" -- Halt option processing and treat all remaining args as paths.\n",
" -d If given, decompression is done instead.\n",
" -c Write output on stdout, don't remove original.\n",
" -k Keep input files (do not automatically remove).\n",
" -b Parameter limits the max number of bits/code.\n",
" -f Forces output file to be generated, even if one already.\n",
" exists, and even if no space is saved by compressing.\n",
" If -f is not used, the user will be prompted if stdin is.\n",
" a tty, otherwise, the output file will not be overwritten.\n",
" -h This help output.\n",
" -v Write compression statistics.\n",
" -V Output version and compile options.\n",
" -r Recursive. If a path is a directory, compress everything in it.\n",
);
pub(super) const NOT_REGULAR: &str = "%s: Not a regular file.\n";
pub(super) const IS_DIRECTORY: &str = "%s is a directory -- ignored\n";
pub(super) const NO_Z_SUFFIX: &str = "%s - no .Z suffix\n";
pub(super) const HAS_Z_SUFFIX: &str = "%s: already has .Z suffix -- no change\n";
pub(super) const OTHER_LINKS: &str = "%s has %jd other links: unchanged\n";
pub(super) const ALREADY_EXISTS: &str = "%s already exists.\n";
pub(super) const OVERWRITE: &str = "Do you wish to overwrite %s (y or n)? ";
pub(super) const NOT_OVERWRITTEN: &str = "%s not overwritten\n";
pub(super) const CANT_REMOVE: &str = "Can't remove old output file\n";
pub(super) const NAME: &str = "%s: ";
pub(super) const NO_COMPRESSION: &str = "No compression -- %s unchanged\n";
pub(super) const UNLINK_ERROR_NL: &str = "\nunlink error (ignored) ";
pub(super) const UNLINK_ERROR: &str = "unlink error (ignored) ";
pub(super) const REPLACED_WITH: &str = " -- replaced with %s";
pub(super) const COMPRESSION: &str = " Compression: ";
pub(super) const NEWLINE: &str = "\n";
#[cfg(unix)]
pub(super) const UTIME_ERROR: &str = "\nutime error (ignored) ";
#[cfg(unix)]
pub(super) const CHMOD_ERROR: &str = "\nchmod error (ignored) ";
#[cfg(unix)]
pub(super) const CHOWN_ERROR: &str = "\nchown error (ignored) ";
pub(super) const NOT_DIR_OR_REGULAR: &str = "%s is not a directory or a regular file - ignored\n";
pub(super) const UNREADABLE: &str = "%s unreadable\n";
pub(super) const NOT_COMPRESSED: &str = "%s: not in compressed format\n";
pub(super) const TOO_MANY_BITS: &str = "%s: compressed with %d bits, can only handle %d bits\n";
pub(super) const FIRST_CODE: &str = "oldcode:-1 code:%i\n";
pub(super) const BAD_CODE: &str = "insize:%d posbits:%d inbuf:%02X %02X %02X %02X %02X (%d)\n";
pub(super) const CORRUPT_INPUT: &str = "uncompress: corrupt input\n";
pub(super) const READ_ERROR: &str = "\nread error on";
pub(super) const WRITE_ERROR: &str = "\nwrite error on";
pub(super) const ABOUT: &str = concat!(
"Compress version: (N)compress 5.0\n",
"Compile options:\n",
" FAST, \n",
" IBUFSIZ=8192, OBUFSIZ=8192, BITS=16\n",
"\n",
"Author version 5.x (Modernization):\n",
"Author version 4.2.4.x (Maintenance):\n",
" Mike Frysinger (vapier@gmail.com)\n",
"\n",
"Author version 4.2 (Speed improvement & source cleanup):\n",
" Peter Jannesen (peter@ncs.nl)\n",
"\n",
"Author version 4.1 (Added recursive directory compress):\n",
" Dave Mack (csu@alembic.acs.com)\n",
"\n",
"Authors version 4.0 (World release in 1985):\n",
" Spencer W. Thomas, Jim McKie, Steve Davies,\n",
" Ken Turkowski, James A. Woods, Joe Orost\n",
);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn printf_takes_any_conversion_in_order() {
let mut out = Vec::new();
printf(
&mut out,
BAD_CODE,
&[b"9", b"42", b"06", b"00", b"FF", b"FF", b"FF", b"2"],
);
assert_eq!(out, b"insize:9 posbits:42 inbuf:06 00 FF FF FF (2)\n");
let mut out = Vec::new();
printf(&mut out, OTHER_LINKS, &[b"f", b"1"]);
assert_eq!(out, b"f has 1 other links: unchanged\n");
let mut out = Vec::new();
printf(&mut out, "%c%%", &[b"x"]);
assert_eq!(out, b"x%");
}
#[test]
fn about_is_ubuntus() {
assert_eq!(ABOUT.len(), 556);
assert!(
ABOUT.contains("\n FAST, \n IBUFSIZ=8192, OBUFSIZ=8192, BITS=16\n\n")
);
}
}