ncalendar

Reimplementation of the BSD calendar(1) program in Rust

git clone https://git.8pit.net/ncalendar.git

 1use std::convert;
 2use std::fs::File;
 3use std::io::Read;
 4use std::path;
 5use std::process::{Command, Stdio};
 6use std::str;
 7
 8use crate::Error;
 9
10pub fn has_cpp() -> bool {
11    // XXX: This is a bit hacky as we don't know if the spawn failed
12    // because cpp(1) doesn't exist or because of some other reason.
13    //
14    // Unfournuately, std::process doesn't have a function to iterate
15    // over binaries in $PATH (e.g. analog to Go's LookPath) and we
16    // can't check the spawn error for ENOENT either it seems.
17    return Command::new("cpp")
18        .stdin(Stdio::null())
19        .stdout(Stdio::null())
20        .spawn()
21        .is_ok();
22}
23
24pub fn preprocess<P: convert::AsRef<path::Path>>(fp: P) -> Result<String, Error> {
25    if has_cpp() {
26        let f = File::open(fp)?;
27        let child = Command::new("cpp")
28            .arg("-traditional")
29            .arg("-undef")
30            .arg("-U__GNUC__")
31            .arg("-w")
32            .arg("-P")
33            .stdin(f)
34            .stdout(Stdio::piped())
35            .spawn()?;
36
37        let out = child.wait_with_output()?;
38        Ok(str::from_utf8(&out.stdout).map(|s| s.to_string())?)
39    } else {
40        let mut f = File::open(fp)?;
41        let mut buf = String::new();
42
43        f.read_to_string(&mut buf)?;
44        Ok(buf)
45    }
46}