summaryrefslogtreecommitdiff
path: root/hscript
diff options
context:
space:
mode:
Diffstat (limited to 'hscript')
-rw-r--r--hscript/script.cc74
-rw-r--r--hscript/script.hh29
2 files changed, 72 insertions, 31 deletions
diff --git a/hscript/script.cc b/hscript/script.cc
index 748b09a..a9c39ab 100644
--- a/hscript/script.cc
+++ b/hscript/script.cc
@@ -18,6 +18,10 @@
#include "network.hh"
#include "user.hh"
+#include "util/output.hh"
+
+#define LINE_MAX 512
+
namespace Horizon {
struct Script::ScriptPrivate {
@@ -34,35 +38,67 @@ struct Script::ScriptPrivate {
};
Script::Script() {
+ internal = new ScriptPrivate;
}
const Script *Script::load(std::string path, ScriptOptions opts) {
- std::ifstream file;
- std::string maybe_error;
-
- file.exceptions(std::ios::badbit);
- try {
- file.open(path);
- } catch(const std::ios::failure &error) {
- maybe_error = error.what();
- } catch(const std::exception &error) {
- maybe_error = error.what();
- }
+ std::ifstream file(path);
if(!file) {
- std::cerr << "Cannot open installfile at \"" << path << "\": ";
- std::cerr << maybe_error;
- std::cerr << std::endl;
+ output_error(path, "Cannot open installfile", "",
+ (opts.test(Pretty)));
return nullptr;
}
return Script::load(file, opts);
}
-const Script *Script::load(std::istream &, ScriptOptions) {
- Script *foo = new Script;
- delete foo;
- std::cout << "loaded" << std::endl;
- return nullptr;
+const Script *Script::load(std::istream &sstream, ScriptOptions opts) {
+ Script *the_script = new Script;
+
+ int lineno = 0;
+ char nextline[LINE_MAX];
+ const std::string delim(" \t");
+
+ while(sstream.getline(nextline, sizeof(nextline))) {
+ lineno++;
+ if(nextline[0] == '#') {
+ /* This is a comment line; ignore it. */
+ continue;
+ }
+
+ const std::string line(nextline);
+ std::string::size_type start, key_end;
+ start = line.find_first_not_of(delim);
+ if(start == std::string::npos) {
+ /* This is a blank line; ignore it. */
+ continue;
+ }
+
+ key_end = line.find_first_of(delim, start);
+ if(key_end == std::string::npos) {
+ /* Key without value */
+ output_error("installfile:" + std::to_string(lineno),
+ "key '" + line.substr(start) + "' has no value",
+ "", (opts.test(Pretty)));
+ }
+ }
+
+ if(sstream.fail() && !sstream.eof()) {
+ output_error("installfile:" + std::to_string(lineno + 1),
+ "line exceeds maximum length",
+ "Maximum length for line is " + std::to_string(LINE_MAX),
+ (opts.test(Pretty)));
+ delete the_script;
+ return nullptr;
+ }
+
+ if(sstream.bad() && !sstream.eof()) {
+ output_error("installfile:" + std::to_string(lineno),
+ "I/O error reading installfile", "",
+ (opts.test(Pretty)));
+ }
+
+ return the_script;
}
bool Script::validate() {
diff --git a/hscript/script.hh b/hscript/script.hh
index 1150e78..8c0f619 100644
--- a/hscript/script.hh
+++ b/hscript/script.hh
@@ -16,24 +16,29 @@
#include <string>
#include <vector>
#include <memory>
+#include <bitset>
namespace Horizon {
/**** Script option flags ****/
-/*! Don't stop after the first error. */
-#define SCRIPT_KEEP_GOING 0x0001
-/*! Ensure network resources are available. */
-#define SCRIPT_USE_NETWORK 0x0002
-/*! Treat warnings as errors. */
-#define SCRIPT_STRICT_MODE 0x0004
-/*! This is an Installation Environment - validate more keys. */
-#define SCRIPT_INSTALL_ENV 0x0008
-/*! "Pretty" output - used in interactive tooling only. */
-#define SCRIPT_PRETTY 0x0010
+enum ScriptOptionFlags {
+ /*! Don't stop after the first error. */
+ KeepGoing,
+ /*! Ensure network resources are available. */
+ UseNetwork,
+ /*! Treat warnings as errors. */
+ StrictMode,
+ /*! This is an Installation Environment - validate more keys. */
+ InstallEnvironment,
+ /*! "Pretty" output - used in interactive tooling only. */
+ Pretty,
+ /*! Count of flags */
+ NumFlags
+};
-typedef uint32_t ScriptOptions;
+typedef std::bitset<ScriptOptionFlags::NumFlags> ScriptOptions;
/*! Defines the Script class, which represents a HorizonScript. */
@@ -61,7 +66,7 @@ public:
private:
struct ScriptPrivate;
/*! Internal data. */
- const std::unique_ptr<ScriptPrivate> internal;
+ ScriptPrivate *internal;
};
}