aboutsummaryrefslogtreecommitdiff
path: root/libbutl/manifest-parser.mxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-09-22 23:32:28 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-09-22 23:32:28 +0200
commitc09cd7512491cee1e82c1ad8128ce9fd4bc3f79b (patch)
treea659ed768d849130ab5780a11b7f791a463a1a91 /libbutl/manifest-parser.mxx
parent2a00871f07067f8f9e2de08bb9c8f50e1bf6a650 (diff)
Initial modularization with both Clang and VC hacks
Note: gave up on VC about half way though.
Diffstat (limited to 'libbutl/manifest-parser.mxx')
-rw-r--r--libbutl/manifest-parser.mxx116
1 files changed, 116 insertions, 0 deletions
diff --git a/libbutl/manifest-parser.mxx b/libbutl/manifest-parser.mxx
new file mode 100644
index 0000000..c21ccc1
--- /dev/null
+++ b/libbutl/manifest-parser.mxx
@@ -0,0 +1,116 @@
+// file : libbutl/manifest-parser.mxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef __cpp_modules
+#pragma once
+#endif
+
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <iosfwd>
+#include <cstdint> // uint64_t
+#include <utility> // pair
+#include <stdexcept> // runtime_error
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.manifest_parser;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.char_scanner;
+#else
+#include <libbutl/char-scanner.mxx>
+#endif
+
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
+{
+ class LIBBUTL_SYMEXPORT manifest_parsing: public std::runtime_error
+ {
+ public:
+ manifest_parsing (const std::string& name,
+ std::uint64_t line,
+ std::uint64_t column,
+ const std::string& description);
+
+ std::string name;
+ std::uint64_t line;
+ std::uint64_t column;
+ std::string description;
+ };
+
+ class manifest_name_value
+ {
+ public:
+ std::string name;
+ std::string value;
+
+ std::uint64_t name_line;
+ std::uint64_t name_column;
+
+ std::uint64_t value_line;
+ std::uint64_t value_column;
+
+ bool
+ empty () const {return name.empty () && value.empty ();}
+ };
+
+ class LIBBUTL_SYMEXPORT manifest_parser: protected butl::char_scanner
+ {
+ public:
+ manifest_parser (std::istream& is, const std::string& name)
+ : char_scanner (is), name_ (name) {}
+
+ const std::string&
+ name () const {return name_;}
+
+ // The first returned pair is special "start-of-manifest" with
+ // empty name and value being the format version: {"", "<ver>"}.
+ // After that we have a sequence of ordinary pairs which are
+ // the manifest. At the end of the manifest we have the special
+ // "end-of-manifest" pair with empty name and value: {"", ""}.
+ // After that we can either get another start-of-manifest pair
+ // (in which case the whole sequence repeats from the beginning)
+ // or we get another end-of-manifest pair which signals the end
+ // of stream (aka EOF). To put it another way, the parse sequence
+ // always has the following form:
+ //
+ // ({"", "<ver>"} {"<name>", "<value>"}* {"", ""})* {"", ""}
+ //
+ manifest_name_value
+ next ();
+
+ // Split the manifest value, optionally followed by ';' character and a
+ // comment into the value/comment pair. Note that ';' characters in the
+ // value must be escaped by the backslash.
+ //
+ static std::pair<std::string, std::string>
+ split_comment (const std::string&);
+
+ private:
+ void
+ parse_name (manifest_name_value&);
+
+ void
+ parse_value (manifest_name_value&);
+
+ // Skip spaces and return the first peeked non-space character.
+ //
+ xchar
+ skip_spaces ();
+
+ private:
+ const std::string name_;
+
+ enum {start, body, end} s_ = start;
+ std::string version_; // Current format version.
+ };
+}