aboutsummaryrefslogtreecommitdiff
path: root/libbutl/tab-parser.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbutl/tab-parser.cxx')
-rw-r--r--libbutl/tab-parser.cxx88
1 files changed, 88 insertions, 0 deletions
diff --git a/libbutl/tab-parser.cxx b/libbutl/tab-parser.cxx
new file mode 100644
index 0000000..bf0a7dd
--- /dev/null
+++ b/libbutl/tab-parser.cxx
@@ -0,0 +1,88 @@
+// file : libbutl/tab-parser.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <libbutl/tab-parser.hxx>
+
+#include <cassert>
+#include <sstream>
+
+#include <libbutl/string-parser.hxx>
+
+using namespace std;
+
+namespace butl
+{
+ using parsing = tab_parsing;
+
+ // tab_parser
+ //
+ tab_fields tab_parser::
+ next ()
+ {
+ tab_fields r;
+
+ // Read lines until a non-empty one or EOF is encountered. In the first
+ // case parse the line and bail out.
+ //
+ // Note that we check for character presence in the stream prior to the
+ // getline() call, to prevent it from setting the failbit.
+ //
+ while (!is_.eof () && is_.peek () != istream::traits_type::eof ())
+ {
+ string s;
+ getline (is_, s);
+
+ ++line_;
+
+ // Skip empty line.
+ //
+ auto i (s.begin ());
+ auto e (s.end ());
+ for (; i != e && (*i == ' ' || *i == '\t'); ++i) ; // Skip spaces.
+
+ if (i == e || *i == '#')
+ continue;
+
+ r.line = line_;
+ r.end_column = s.size () + 1; // Newline position.
+
+ vector<std::pair<string, size_t>> sp;
+
+ try
+ {
+ sp = string_parser::parse_quoted_position (s, false);
+ }
+ catch (const invalid_string& e)
+ {
+ throw parsing (name_, line_, e.position + 1, e.what ());
+ }
+
+ for (auto& s: sp)
+ r.emplace_back (tab_field ({move (s.first), s.second + 1}));
+
+ break;
+ }
+
+ return r;
+ }
+
+ // tab_parsing
+ //
+ static string
+ format (const string& n, uint64_t l, uint64_t c, const string& d)
+ {
+ ostringstream os;
+ if (!n.empty ())
+ os << n << ':';
+ os << l << ':' << c << ": error: " << d;
+ return os.str ();
+ }
+
+ tab_parsing::
+ tab_parsing (const string& n, uint64_t l, uint64_t c, const string& d)
+ : runtime_error (format (n, l, c, d)),
+ name (n), line (l), column (c), description (d)
+ {
+ }
+}