aboutsummaryrefslogtreecommitdiffstats
path: root/src/config.rs
diff options
context:
space:
mode:
authorTeddy Wing2018-10-26 00:47:26 +0200
committerTeddy Wing2018-10-26 00:47:26 +0200
commit88d3f71dc79ebd5fc6b21999240935930da84273 (patch)
tree541c2f9e081d64dc7b0227219e4011a49104b3ba /src/config.rs
parent1f800bc121eb5caa712a94dc018ec9c19c718060 (diff)
downloaddome-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.rs37
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);
}