Skip to main content

libps_mem/conf/
parse.rs

1//
2use flood_tide::parse_simple_gnu_style;
3use flood_tide::HelpVersion;
4use flood_tide::{Arg, NameVal, Opt, OptNum};
5use flood_tide::{OptParseError, OptParseErrors};
6
7use crate::util::OptSortOrder;
8use crate::util::OptUcXParam;
9
10//----------------------------------------------------------------------
11include!("cmd.help.rs.txt");
12
13//{{{ TEXT
14const DESCRIPTIONS_TEXT: &str = r#"print processes memory by sort,
15or print one processe memory
16"#;
17//const PARAMS_TEXT: &str = r#""#;
18//const ARGUMENTS_TEXT: &str = r#""#;
19//const ENV_TEXT: &str = r#""#;
20const EXAMPLES_TEXT: &str = r#"Examples:
21  Show all prosesses memory:
22    ps-mem --all
23  Show one prosess memory:
24    ps-mem --pid 1234
25  Show invoked one prosess memory:
26    ps-mem -- find / -type f
27"#;
28//}}} TEXT
29
30//----------------------------------------------------------------------
31#[rustfmt::skip]
32fn version_message(_program: &str) -> String {
33    format!( "{} {}",
34        env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"))
35}
36
37#[rustfmt::skip]
38fn usage_message(program: &str) -> String {
39    let usage1 = format!("  {} {}", program, "[options]");
40    let usage2 = format!(
41        "  {} {}",
42        program, "[options] <command> {<arg1> <arg2> ...}"
43    );
44    format!("Usage:\n{usage1}\n{usage2}\n")
45}
46
47#[rustfmt::skip]
48fn help_message(program: &str) -> String {
49    let ver = version_message(program);
50    let usa = usage_message(env!("CARGO_PKG_NAME"));
51    [ &ver, "", &usa, DESCRIPTIONS_TEXT, OPTIONS_TEXT, EXAMPLES_TEXT].join("\n")
52}
53
54#[rustfmt::skip]
55fn opt_uc_x_help_message(_program: &str) -> String {
56    let z_opts = concat!(
57        "Options:\n",
58        "  -X rust-version-info     display package version info and exit\n",
59        "  -X base_dir=<path>       set <path> is base directory\n",
60    );
61    z_opts.to_string()
62}
63
64#[rustfmt::skip]
65fn opt_uc_x_package_version_info(_program: &str) -> String {
66    #[cfg(feature = "debian_build")]
67    {
68        use std::io::Read;
69        let mut string = String::new();
70        let fnm = format!("/usr/share/doc/{}/rust-version-info.txt", env!("CARGO_PKG_NAME"));
71        let file = std::fs::File::open(&fnm);
72        match file {
73            Ok(mut f) => {
74                f.read_to_string(&mut string).unwrap();
75                string
76            },
77            Err(err) => {
78                format!("ERROR: {}: '{}'", err, fnm)
79            },
80        }
81    }
82    #[cfg(not(feature = "debian_build"))]
83    {
84        const VS: &str = include_str!(concat!(env!("OUT_DIR"), "/rust-version-info.txt"));
85        VS.to_string()
86    }
87}
88
89//----------------------------------------------------------------------
90fn parse_match(conf: &mut CmdOptConf, nv: &NameVal<'_>) -> Result<(), OptParseError> {
91    include!("cmd.match.rs.txt");
92    Ok(())
93}
94
95pub fn parse_cmdopts(a_prog_name: &str, args: &[&str]) -> Result<CmdOptConf, OptParseErrors> {
96    //
97    let mut conf = CmdOptConf {
98        prog_name: a_prog_name.to_string(),
99        // default sleep msec: 10ms to capture short-lived memory peaks
100        opt_sleep: 10,
101        ..Default::default()
102    };
103    let (opt_free, r_errs) =
104        parse_simple_gnu_style(&mut conf, &OPT_ARY, &OPT_ARY_SHO_IDX, args, parse_match);
105    //
106    if conf.is_help() {
107        let mut errs = OptParseErrors::new();
108        errs.push(OptParseError::help_message(&help_message(&conf.prog_name)));
109        return Err(errs);
110    }
111    if conf.is_version() {
112        let mut errs = OptParseErrors::new();
113        errs.push(OptParseError::version_message(&version_message(
114            &conf.prog_name,
115        )));
116        return Err(errs);
117    }
118    if !conf.opt_uc_x.is_empty() {
119        if conf.is_opt_uc_x_help() {
120            let mut errs = OptParseErrors::new();
121            errs.push(OptParseError::help_message(&opt_uc_x_help_message(
122                &conf.prog_name,
123            )));
124            return Err(errs);
125        }
126        if conf.is_opt_uc_x_package_version_info() {
127            let mut errs = OptParseErrors::new();
128            errs.push(OptParseError::help_message(&opt_uc_x_package_version_info(
129                &conf.prog_name,
130            )));
131            return Err(errs);
132        }
133    }
134    //
135    {
136        let errs = if let Err(errs) = r_errs {
137            errs
138        } else {
139            OptParseErrors::new()
140        };
141        //
142        if let Some(free) = opt_free {
143            if !free.is_empty() {
144                conf.arg_params.extend(free.iter().map(|s| s.to_string()));
145            }
146        };
147        if !errs.is_empty() {
148            return Err(errs);
149        }
150    }
151    //
152    Ok(conf)
153}