summaryrefslogtreecommitdiff
path: root/src/context.h
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2012-03-01 03:31:28 -0600
committerJohn Wiegley <johnw@newartisans.com>2012-03-01 03:31:28 -0600
commit944e580825f0d9ce060b6dcdffe8990b6c2cca20 (patch)
treee2651b0df622d9b8d3831f35743e7dbd31c16897 /src/context.h
parente2afc783db0dff1927b00dc506390353d9e3bbd2 (diff)
downloadfork-ledger-944e580825f0d9ce060b6dcdffe8990b6c2cca20.tar.gz
fork-ledger-944e580825f0d9ce060b6dcdffe8990b6c2cca20.tar.bz2
fork-ledger-944e580825f0d9ce060b6dcdffe8990b6c2cca20.zip
Refactored the notion of "the current parsing context"
Diffstat (limited to 'src/context.h')
-rw-r--r--src/context.h151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/context.h b/src/context.h
new file mode 100644
index 00000000..0533536f
--- /dev/null
+++ b/src/context.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2003-2012, John Wiegley. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of New Artisans LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @addtogroup data
+ */
+
+/**
+ * @file context.h
+ * @author John Wiegley
+ *
+ * @ingroup data
+ */
+#ifndef _CONTEXT_H
+#define _CONTEXT_H
+
+#include "utils.h"
+#include "times.h"
+
+namespace ledger {
+
+class journal_t;
+class account_t;
+class scope_t;
+
+class parse_context_t
+{
+public:
+ static const std::size_t MAX_LINE = 4096;
+
+ shared_ptr<std::istream> stream;
+
+ path pathname;
+ path current_directory;
+ journal_t * journal;
+ account_t * master;
+ scope_t * scope;
+ char linebuf[MAX_LINE + 1];
+ istream_pos_type line_beg_pos;
+ istream_pos_type curr_pos;
+ std::size_t linenum;
+ std::size_t errors;
+ std::size_t count;
+ std::size_t sequence;
+
+ explicit parse_context_t(shared_ptr<std::istream> _stream,
+ const path& cwd)
+ : stream(_stream), current_directory(cwd), master(NULL),
+ scope(NULL), linenum(0), errors(0), count(0), sequence(1) {}
+
+ parse_context_t(const parse_context_t& context)
+ : stream(context.stream),
+ pathname(context.pathname),
+ current_directory(context.current_directory),
+ journal(context.journal),
+ master(context.master),
+ scope(context.scope),
+ line_beg_pos(context.line_beg_pos),
+ curr_pos(context.curr_pos),
+ linenum(context.linenum),
+ errors(context.errors),
+ count(context.count),
+ sequence(context.sequence) {
+ std::memcpy(linebuf, context.linebuf, MAX_LINE);
+ }
+
+ string location() const {
+ return file_context(pathname, linenum);
+ }
+
+ void warning(const string& what) const {
+ warning_func(location() + what);
+ }
+};
+
+inline parse_context_t open_for_reading(const path& pathname,
+ const path& cwd)
+{
+ path filename = resolve_path(pathname);
+
+ if (! exists(filename))
+ throw_(std::runtime_error,
+ _("Cannot read journal file %1") << filename);
+
+ path parent(filesystem::absolute(pathname, cwd).parent_path());
+ shared_ptr<std::istream> stream(new ifstream(filename));
+ parse_context_t context(stream, parent);
+ context.pathname = filename;
+ return context;
+}
+
+class parse_context_stack_t
+{
+ std::list<parse_context_t> parsing_context;
+
+public:
+ void push(shared_ptr<std::istream> stream,
+ const path& cwd = filesystem::current_path()) {
+ parsing_context.push_front(parse_context_t(stream, cwd));
+ }
+ void push(const path& pathname,
+ const path& cwd = filesystem::current_path()) {
+ parsing_context.push_front(open_for_reading(pathname, cwd));
+ }
+
+ void push(const parse_context_t& context) {
+ parsing_context.push_front(context);
+ }
+
+ void pop() {
+ assert(! parsing_context.empty());
+ parsing_context.pop_front();
+ }
+
+ parse_context_t& get_current() {
+ assert(! parsing_context.empty());
+ return parsing_context.front();
+ }
+};
+
+} // namespace ledger
+
+#endif // _CONTEXT_H