diff options
author | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2019-10-08 16:40:06 -0500 |
---|---|---|
committer | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2019-10-08 16:40:06 -0500 |
commit | e242f93977d28b8d645b53f28fe052071dcbf10d (patch) | |
tree | 31d1bf67c8adaff53ee22eb76349b9fe898443db | |
parent | 48f192b9eddd8ea38a1850fa4e499401ca957339 (diff) | |
download | horizon-e242f93977d28b8d645b53f28fe052071dcbf10d.tar.gz horizon-e242f93977d28b8d645b53f28fe052071dcbf10d.tar.bz2 horizon-e242f93977d28b8d645b53f28fe052071dcbf10d.tar.xz horizon-e242f93977d28b8d645b53f28fe052071dcbf10d.zip |
hscript: Code
-rw-r--r-- | hscript/key.cc | 2 | ||||
-rw-r--r-- | hscript/key.hh | 14 | ||||
-rw-r--r-- | hscript/network.cc | 4 | ||||
-rw-r--r-- | hscript/network.hh | 4 | ||||
-rw-r--r-- | hscript/script.cc | 45 | ||||
-rw-r--r-- | tests/scripts/0018-duplicate-network.installfile | 6 | ||||
-rw-r--r-- | tests/scripts/0019-duplicate-hostname.installfile | 6 | ||||
-rw-r--r-- | tests/scripts/0020-duplicate-rootpw.installfile | 6 | ||||
-rw-r--r-- | tests/scripts/0021-duplicate-root-mount.installfile | 6 |
9 files changed, 84 insertions, 9 deletions
diff --git a/hscript/key.cc b/hscript/key.cc index d51e7d2..b5bbe31 100644 --- a/hscript/key.cc +++ b/hscript/key.cc @@ -32,7 +32,7 @@ bool Horizon::Keys::BooleanKey::parse(const std::string what, return true; } -bool Horizon::Keys::BooleanKey::validate() { +bool Horizon::Keys::BooleanKey::validate() const { /* Key will fail init if it is not valid, so this is always a no-op. */ return true; } diff --git a/hscript/key.hh b/hscript/key.hh index 9c7755b..1045592 100644 --- a/hscript/key.hh +++ b/hscript/key.hh @@ -23,6 +23,10 @@ namespace Keys { * return a different type of data. For example, `network` may return `bool`. */ class Key { +protected: + /*! The line number where this Key appeared. */ + int line; + Key(int _line) : line(_line) {} public: virtual ~Key() {} @@ -41,12 +45,14 @@ public: #undef UNUSED /*! Determines if the data associated with the Key is valid. */ - virtual bool validate() = 0; + virtual bool validate() const = 0; /*! Executes the action associated with this Key. * @note Will always return `false` if `validate` is `false`. */ - virtual bool execute() = 0; + virtual bool execute() const = 0; + + int lineno() const { return this->line; } }; @@ -58,7 +64,7 @@ public: */ class BooleanKey : public Key { protected: - BooleanKey(bool my_value) : value(my_value) {} + BooleanKey(int _line, bool my_value) : Key(_line), value(my_value) {} bool value; /*! Parse a string into a boolean. @@ -77,7 +83,7 @@ public: bool test() const { return this->value; } /*! Key will fail to init if valid is invalid. */ - bool validate() override; + bool validate() const override; }; } diff --git a/hscript/network.cc b/hscript/network.cc index 9456d09..e26ac93 100644 --- a/hscript/network.cc +++ b/hscript/network.cc @@ -22,9 +22,9 @@ Key *Network::parseFromData(const std::string data, int lineno, int *errors, if(errors) *errors += 1; return nullptr; } - return new Network(value); + return new Network(lineno, value); } -bool Network::execute() { +bool Network::execute() const { return false; } diff --git a/hscript/network.hh b/hscript/network.hh index 7fc0504..ce64ca6 100644 --- a/hscript/network.hh +++ b/hscript/network.hh @@ -21,11 +21,11 @@ namespace Keys { class Network : public BooleanKey { private: - Network(bool _value) : BooleanKey(_value) {} + Network(int _line, bool _value) : BooleanKey(_line, _value) {} public: static Key *parseFromData(const std::string data, int lineno, int *errors, int *warnings); - bool execute() override; + bool execute() const override; }; class NetAddress : public Key { diff --git a/hscript/script.cc b/hscript/script.cc index 0cd7531..a07af15 100644 --- a/hscript/script.cc +++ b/hscript/script.cc @@ -76,8 +76,46 @@ struct Script::ScriptPrivate { std::unique_ptr<Horizon::Keys::RootPassphrase> rootpw; /*! Target system's mountpoints. */ std::vector< std::unique_ptr<Horizon::Keys::Mount> > mounts; + + /*! Store +key_obj+ representing the key +key_name+. + * @param key_name The name of the key that is being stored. + * @param key_obj The Key object associated with the key. + * @param errors Output parameter: if given, incremented on error. + * @param warnings Output parameter: if given, incremented on warning. + */ + bool store_key(const std::string key_name, Keys::Key *key_obj, int lineno, + int *errors, int *warnings) { + if(key_name == "network") { + if(this->network) { + std::string err_str("previous value was "); + err_str += this->network->test() ? "true" : "false"; + err_str += " at installfile:"; + err_str += std::to_string(this->network->lineno()); + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "'network' key has already been specified", + err_str); + return false; + } + std::unique_ptr<Keys::Network> net(dynamic_cast<Keys::Network *>(key_obj)); + this->network = std::move(net); + return true; + } else if(key_name == "hostname") { + /*! TODO: implement */ + return false; + } else if(key_name == "pkginstall") { + /*! TODO: implement */ + return false; + } else if(key_name == "rootpw") { + /*! TODO: implement */ + return false; + } else { + return false; + } + } }; + Script::Script() { internal = new ScriptPrivate; } @@ -156,6 +194,13 @@ const Script *Script::load(std::istream &sstream, const ScriptOptions opts) { &errors, &warnings); if(!key_obj) { PARSER_ERROR("value for key '" + key + "' was invalid") + continue; + } + + if(!the_script->internal->store_key(key, key_obj, lineno, &errors, + &warnings)) { + PARSER_ERROR("stopping due to prior errors") + continue; } } diff --git a/tests/scripts/0018-duplicate-network.installfile b/tests/scripts/0018-duplicate-network.installfile new file mode 100644 index 0000000..bce490c --- /dev/null +++ b/tests/scripts/0018-duplicate-network.installfile @@ -0,0 +1,6 @@ +network true +hostname test.machine +pkginstall adelie-base +network false +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +mount /dev/sda1 / diff --git a/tests/scripts/0019-duplicate-hostname.installfile b/tests/scripts/0019-duplicate-hostname.installfile new file mode 100644 index 0000000..ae7f199 --- /dev/null +++ b/tests/scripts/0019-duplicate-hostname.installfile @@ -0,0 +1,6 @@ +network true +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +mount /dev/sda1 / +hostname foo.bar diff --git a/tests/scripts/0020-duplicate-rootpw.installfile b/tests/scripts/0020-duplicate-rootpw.installfile new file mode 100644 index 0000000..c3727d2 --- /dev/null +++ b/tests/scripts/0020-duplicate-rootpw.installfile @@ -0,0 +1,6 @@ +network true +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +mount /dev/sda1 / +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ diff --git a/tests/scripts/0021-duplicate-root-mount.installfile b/tests/scripts/0021-duplicate-root-mount.installfile new file mode 100644 index 0000000..0d009cd --- /dev/null +++ b/tests/scripts/0021-duplicate-root-mount.installfile @@ -0,0 +1,6 @@ +network true +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +mount /dev/sda1 / +mount /dev/sda2 / |