aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYour Name <you@example.com>2021-05-06 17:00:00 -0400
committerYour Name <you@example.com>2021-05-06 17:00:00 -0400
commitbf6db4e57895430d84503e800cec9e8b407212a8 (patch)
treebc21559fc0bff2ad616c5d69a45b5a22cc8cea60 /src
parent5ed030a38810e4a3bb9c969db6892065581340c6 (diff)
downloaddmtool-bf6db4e57895430d84503e800cec9e8b407212a8.tar.gz
dmtool-bf6db4e57895430d84503e800cec9e8b407212a8.tar.bz2
dmtool-bf6db4e57895430d84503e800cec9e8b407212a8.zip
Added a real configuration file (plus a dependency on libconfuse)
Diffstat (limited to 'src')
-rw-r--r--src/dmtool.bash139
-rw-r--r--src/dmtool.cc23
-rw-r--r--src/settings.cc56
3 files changed, 34 insertions, 184 deletions
diff --git a/src/dmtool.bash b/src/dmtool.bash
deleted file mode 100644
index ffc75f7..0000000
--- a/src/dmtool.bash
+++ /dev/null
@@ -1,139 +0,0 @@
-# bash completion file for dmtool
-
-# Modified from bash completion for password-store
-
-_dmtool_complete_entries () {
- local prefix1="${HOME}/.dmtool/"
- prefix1="${prefix1%/}/"
- local prefix2="/usr/share/dmtool/"
- prefix2="${prefix2%/}/"
- local suffix=".json"
- local autoexpand=${1:-0}
-
- local IFS=$'\n'
- local items=($(compgen -f $prefix1$cur))
- items+=($(compgen -f $prefix2$cur))
-
- # Remember the value of the first item, to see if it is a directory. If
- # it is a directory, then don't add a space to the completion
- local firstitem=""
- # Use counter, can't use ${#items[@]} as we skip hidden directories
- local i=0 item
-
- for item in ${items[@]}; do
- [[ $item =~ /\.[^/]*$ ]] && continue
-
- # if there is a unique match, and it is a directory with one entry
- # autocomplete the subentry as well (recursively)
- if [[ ${#items[@]} -eq 1 && $autoexpand -eq 1 ]]; then
- while [[ -d $item ]]; do
- local subitems=($(compgen -f "$item/"))
- local filtereditems=( ) item2
- for item2 in "${subitems[@]}"; do
- [[ $item2 =~ /\.[^/]*$ ]] && continue
- filtereditems+=( "$item2" )
- done
- if [[ ${#filtereditems[@]} -eq 1 ]]; then
- item="${filtereditems[0]}"
- else
- break
- fi
- done
- fi
-
- # append / to directories
- [[ -d $item ]] && item="$item/"
-
- item="${item%$suffix}"
- local prefix1ed="${item#$prefix1}"
- COMPREPLY+=("${prefix1ed#$prefix2}")
- if [[ $i -eq 0 ]]; then
- firstitem=$item
- fi
- let i+=1
- done
-
- # The only time we want to add a space to the end is if there is only
- # one match, and it is not a directory
- if [[ $i -gt 1 || ( $i -eq 1 && -d $firstitem ) ]]; then
- compopt -o nospace
- fi
-}
-
-_dmtool_skills()
-{
- echo -e "athletics\nacrobatics\nstealth\narcana\nhistory\ninvestigation\nnature\nreligion\ninsight\nmedicine\nperception\nsurvival\ndeception\nintimidation\nperformance\npersuasion\nsleight of hand\nanimal handling"
-}
-
-_dmtool_abilities()
-{
- echo -e "str\ndex\ncon\nint\nwis\ncha"
-}
-
-_dmtool_complete_skills_abilities()
-{
- local IFS=$'\n'
- COMPREPLY+=($(compgen -W "$(_dmtool_skills)" -- ${cur}))
- COMPREPLY+=($(compgen -W "$(_dmtool_abilities)" -- ${cur}))
-}
-
-_dmtool()
-{
- COMPREPLY=()
- local cur="${COMP_WORDS[COMP_CWORD]}"
- local commands="ls cp mkdir mv rm attacks roll damage heal reset set edit add del help"
- if [[ $COMP_CWORD -gt 1 ]]; then
- local lastarg="${COMP_WORDS[$COMP_CWORD-1]}"
- case "${COMP_WORDS[1]}" in
- ls|mkdir|rm|reset)
- _dmtool_complete_entries
- ;;
- cp|mv|add)
- if [[ $COMP_CWORD -le 3 ]]; then
- _dmtool_complete_entries
- fi
- ;;
- attacks|roll|damage|heal|set|edit|del)
- if [[ $COMP_CWORD -le 2 ]]; then
- _dmtool_complete_entries
- else
- case "${COMP_WORDS[1]}" in
- roll)
- _dmtool_complete_skills_abilities
- # Add in attacks
- local IFS=$'\n'
- opts="$(${COMP_WORDS[0]} attacks ${COMP_WORDS[2]})"
- COMPREPLY+=($(compgen -W "$opts" -- ${cur}))
- ;;
- damage)
- COMPREPLY+=($(compgen -W "--magical -m --silvered -s --adamantine -a" -- ${cur}))
- if [[ $COMP_CWORD -eq 4 ]]; then
- COMPREPLY+=($(compgen -W "slashing piercing bludgeoning poison acid fire cold radiant necrotic lightning thunder force psychic" -- ${cur}))
- fi
- ;;
- set)
- if [[ $COMP_CWORD -eq 3 ]]; then
- _dmtool_complete_skills_abilities
- COMPREPLY+=($(compgen -W "proficiency name" -- ${cur}))
- elif [[ $COMP_CWORD -eq 4 ]]; then
- local skills="$(_dmtool_skills)"
- if [[ "$skills" =~ "$lastarg" ]]; then
- COMPREPLY+=($(compgen -W "none proficient expert" -- ${cur}))
- fi
- fi
- ;;
- del)
- #TODO: Add items and spells
- _dmtool_complete_skills_abilities
- ;;
- esac
- fi
- ;;
- esac
- else
- COMPREPLY+=($(compgen -W "${commands}" -- ${cur}))
- _dmtool_complete_entries 1
- fi
-}
-
-complete -o filenames -F _dmtool dmtool
diff --git a/src/dmtool.cc b/src/dmtool.cc
index 30f73b5..3c5d3a1 100644
--- a/src/dmtool.cc
+++ b/src/dmtool.cc
@@ -41,18 +41,19 @@ std::vector<std::string> extractFlags(std::vector<std::string>& args) {
}
int main(int argc, char *argv[]) {
- std::string exename = argv[0];
- std::vector<std::string> args(&argv[1], &argv[argc]);
- std::vector<std::string> flags = extractFlags(args);
- cmd::mkdir({cmd::getTruePath("")});
- if(args.empty()) {
- std::cout << cmd::list(args);
- return 0;
- }
- std::string cmd = args[0];
- std::vector<std::string> argsOrig(args);
- args.erase(args.begin());
+ // Full thing is surrounded in try/catch to pleasantly print out any errors
try {
+ std::string exename = argv[0];
+ std::vector<std::string> args(&argv[1], &argv[argc]);
+ std::vector<std::string> flags = extractFlags(args);
+ cmd::mkdir({cmd::getTruePath("")});
+ if(args.empty()) {
+ std::cout << cmd::list(args);
+ return 0;
+ }
+ std::string cmd = args[0];
+ std::vector<std::string> argsOrig(args);
+ args.erase(args.begin());
checkArgs(cmd, args);
if(cmd == "ls") std::cout << cmd::list(args);
else if(cmd == "cp") std::cout << cmd::cp(args);
diff --git a/src/settings.cc b/src/settings.cc
index 380ae62..ba15945 100644
--- a/src/settings.cc
+++ b/src/settings.cc
@@ -3,44 +3,32 @@
#include <cstdlib>
#include <regex>
#include <stdexcept>
+#include <confuse.h>
+#include <errno.h>
namespace settings {
- const std::map<std::string, std::string> dummySettings {
- {"weapons", "/usr/share/dmtool/weapons/"},
- {"armor", "/usr/share/dmtool/armor/"},
- {"spells", "/usr/share/dmtool/spells/"},
- {"creatures", "/usr/share/dmtool/creatures/"},
- {"savedir", "~/.dmtool/"},
- {"editor", "vi"}
- };
-
-
- // Update the input string.
- // Obtained from https://stackoverflow.com/a/23442780
- void autoExpandEnvironmentVariables(std::string& text) {
- std::size_t tilde;
- while((tilde = text.find("~")) != std::string::npos) {
- text.replace(tilde, tilde+1, "${HOME}");
- }
- static std::regex env("\\$(?:\\{([^}]+)\\}|([^/]+))");
- std::smatch match;
- while(std::regex_search(text, match, env)) {
- std::string matchStr = match[1].str().empty()? match[2].str() : match[1].str();
- auto s = getenv(matchStr.c_str());
- const std::string var(s == NULL? "" : s);
- text.replace(match[0].first, match[0].second, var);
- }
- }
-
- // Returns the setting, or an exception in the case of an error
std::string getString(const std::string& key) {
- if(! dummySettings.contains(key)) {
- throw std::invalid_argument("Cannot find key: \"" + key + "\"");
+ cfg_opt_t opts[] = {
+ CFG_STR("weapons", "/usr/share/dmtool/weapons/", CFGF_NONE),
+ CFG_STR("armor", "/usr/share/dmtool/armor/", CFGF_NONE),
+ CFG_STR("spells", "/usr/share/dmtool/spells/", CFGF_NONE),
+ CFG_STR("creatures", "/usr/share/dmtool/creatures/", CFGF_NONE),
+ CFG_STR("savedir", NULL, CFGF_NONE),
+ CFG_STR("editor", "vi", CFGF_NONE),
+ CFG_END()
+ };
+ cfg_t *cfg = cfg_init(opts, CFGF_IGNORE_UNKNOWN);
+ if(cfg_parse(cfg, "/etc/dmtool.conf") == CFG_PARSE_ERROR) {
+ throw std::runtime_error("Configuration file /etc/dmtool.conf could not be read: " + std::string(strerror(errno)));
+ }
+ try {
+ std::string result(cfg_getstr(cfg, key.c_str()));
+ cfg_free(cfg);
+ return result;
+ } catch(std::exception& e) {
+ throw std::runtime_error("Cannot find key in configuration file: \"" + key + "\"");
}
- std::string ret = dummySettings.at(key);
- autoExpandEnvironmentVariables(ret);
- return ret;
}
-
+
const std::vector<std::string> objectTypes {"weapons", "armor", "spells"};
}