diff options
| author | Teddy Wing | 2018-10-26 00:47:26 +0200 | 
|---|---|---|
| committer | Teddy Wing | 2018-10-26 00:47:26 +0200 | 
| commit | 88d3f71dc79ebd5fc6b21999240935930da84273 (patch) | |
| tree | 541c2f9e081d64dc7b0227219e4011a49104b3ba /src/config.rs | |
| parent | 1f800bc121eb5caa712a94dc018ec9c19c718060 (diff) | |
| download | dome-key-map-88d3f71dc79ebd5fc6b21999240935930da84273.tar.bz2 | |
Add a `--license` command line argument
Add a new argument that allows users to pass in the path to a license
file. Doing so should get picked up by the Objective-C code which will
copy and validate the license.
In order for the Objective-C code to pick up the path string, we add a
`license` field to the `Config.Args` struct.
The new `license` field is a `*mut c_char`, which means we can't derive
Default any more and need to implement a custom `Default` impl for
`Args`.
Additionally, 'getopts' gives us a Rust string (of course), which needs
to be converted into a raw `CString` before we can stick it in the
`license` field in `Args`. I previously wrote `dkeprintln` to be able to
print an error here at the conversion point between `CString` and raw C
string.
Since we used `CString#into_raw()`, we need to call `from_raw()` on the
pointer to free it, otherwise we end up with a memory leak. This
necessitated adding some additional code to `config_free()` to free the
`license` field if non-null.
In order to access `config.args.license` from within `config_free()`, I
also needed to make the `args` and `license` struct fields public, since
the free function is in a different module. Instead of making only those
two fields public, I decided to make them all public, as all the fields
are technically accessible from C code, and are needed by that C code.
Finally, move the module declaration of `prefix_println` to the top of
the module list instead of listing it alphabetically, because otherwise
any modules declared before it (like `config`) don't get access to its
macro. Also add a `#[macro_use]` attribute to the module declaration
because we do want to export its macro.
(https://stackoverflow.com/questions/26731243/how-do-i-use-a-macro-across-module-files#comment78329437_31749071)
Diffstat (limited to 'src/config.rs')
| -rw-r--r-- | src/config.rs | 37 | 
1 files changed, 31 insertions, 6 deletions
| diff --git a/src/config.rs b/src/config.rs index feaf578..b4cab10 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,18 +1,32 @@ +use std::ffi::CString;  use std::fs; +use std::ptr; +use libc::c_char;  use getopts::Options;  use toml;  use xdg;  use errors::*; +use prefix_println;  type Milliseconds = u16;  #[repr(C)] -#[derive(Default)] -struct Args { -    reload: bool, -    daemon: bool, +pub struct Args { +    pub reload: bool, +    pub daemon: bool, +    pub license: *mut c_char, +} + +impl Default for Args { +    fn default() -> Self { +        Args { +            reload: false, +            daemon: false, +            license: ptr::null_mut(), +        } +    }  }  #[repr(C)] @@ -20,8 +34,8 @@ struct Args {  #[serde(default)]  pub struct Config {      #[serde(skip)] -    args: Args, -    timeout: Milliseconds, +    pub args: Args, +    pub timeout: Milliseconds,  }  impl Default for Config { @@ -43,6 +57,12 @@ pub fn parse_args<'a>(args: &[String], config: &'a mut Config) -> &'a mut Config      opts.optflag("d", "daemon", "run the daemon in the current shell");      opts.optflag("r", "reload-mappings", "reload the mappings file"); +    opts.optopt( +        "", +        "license", +        "register the software using a license plist file", +        "FILE" +    );      opts.optflag("h", "help", "print this help menu");      let matches = match opts.parse(&args[1..]) { @@ -59,6 +79,11 @@ pub fn parse_args<'a>(args: &[String], config: &'a mut Config) -> &'a mut Config          config.args.reload = true;      } else if matches.opt_present("d") {          config.args.daemon = true; +    } else if let Some(license_path) = matches.opt_str("license") { +        match CString::new(license_path) { +            Ok(str) => config.args.license = str.into_raw(), +            Err(e) => dkeprintln!("{}", e), +        }      } else {          print_usage(opts);      } | 
