summaryrefslogtreecommitdiff
path: root/main.cc
diff options
context:
space:
mode:
Diffstat (limited to 'main.cc')
-rw-r--r--main.cc229
1 files changed, 97 insertions, 132 deletions
diff --git a/main.cc b/main.cc
index a776448e..6646d5b8 100644
--- a/main.cc
+++ b/main.cc
@@ -45,17 +45,6 @@
#include <fdstream.hpp>
#endif
-namespace ledger {
- value_t register_command(expr::call_scope_t& args)
- {
- expr::var_t<std::ostream> ostream(args, "ostream");
-
- *ostream << "This (will be) the register command.\n";
-
- return true;
- }
-}
-
static int read_and_report(ledger::report_t& report, int argc, char * argv[],
char * envp[])
{
@@ -114,44 +103,58 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
if (! session.use_cache)
INFO("Binary cache mechanism will not be used");
- // Read the command word and create a command object based on it
+ // Configure the output stream
- string verb = *arg++;
+#ifdef HAVE_UNIX_PIPES
+ int status, pfd[2]; // Pipe file descriptors
+#endif
+ std::ostream * out = &std::cout;
- expr::function_t command;
+ if (report.output_file) {
+ out = new ofstream(*report.output_file);
+ }
+#ifdef HAVE_UNIX_PIPES
+ else if (report.pager) {
+ status = pipe(pfd);
+ if (status == -1)
+ throw_(std::logic_error, "Failed to create pipe");
- if (verb == "register" || verb == "reg" || verb == "r")
- command = register_command;
-#if 0
- else if (verb == "balance" || verb == "bal" || verb == "b")
- command = balance_command();
- else if (verb == "print" || verb == "p")
- command = print_command();
- else if (verb == "equity")
- command = equity_command();
- else if (verb == "entry")
- command = entry_command();
- else if (verb == "dump")
- command = dump_command();
- else if (verb == "output")
- command = output_command();
- else if (verb == "prices")
- command = prices_command();
- else if (verb == "pricesdb")
- command = pricesdb_command();
- else if (verb == "csv")
- command = csv_command();
- else if (verb == "emacs" || verb == "lisp")
- command = emacs_command();
- else if (verb == "xml")
- command = bind(xml_command, _1);
- ;
+ status = fork();
+ if (status < 0) {
+ throw_(std::logic_error, "Failed to fork child process");
+ }
+ else if (status == 0) { // child
+ // Duplicate pipe's reading end into stdin
+ status = dup2(pfd[0], STDIN_FILENO);
+ if (status == -1)
+ perror("dup2");
+
+ // Close unuseful file descriptors: the pipe's writing and
+ // reading ends (the latter is not needed anymore, after the
+ // duplication).
+ close(pfd[1]);
+ close(pfd[0]);
+
+ // Find command name: its the substring starting right of the
+ // rightmost '/' character in the pager pathname. See manpage
+ // for strrchr.
+ execlp(report.pager->native_file_string().c_str(),
+ basename(*report.pager).c_str(), (char *)0);
+ perror("execl");
+ exit(1);
+ }
+ else { // parent
+ close(pfd[0]);
+ out = new boost::fdostream(pfd[1]);
+ }
+ }
#endif
- else if (verb == "expr")
- ;
- else if (verb == "xpath")
- ;
- else if (verb == "parse") {
+
+ // Read the command word and create a command object based on it
+
+ string verb = *arg++;
+
+ if (verb == "parse") {
value_expr expr(*arg);
#if 0
@@ -184,17 +187,6 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
return 0;
}
- else {
- char buf[128];
- std::strcpy(buf, "command_");
- std::strcat(buf, verb.c_str());
-
- if (expr::ptr_op_t def = report.lookup(buf))
- command = def->as_function();
-
- if (! command)
- throw_(std::logic_error, string("Unrecognized command '") + verb + "'");
- }
// Parse the initialization file, which can only be textual; then
// parse the journal data.
@@ -221,55 +213,6 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
TRACE_FINISH(entries, 1);
TRACE_FINISH(parsing_total, 1);
- // Configure the output stream
-
-#ifdef HAVE_UNIX_PIPES
- int status, pfd[2]; // Pipe file descriptors
-#endif
- std::ostream * out = &std::cout;
-
- if (report.output_file) {
- out = new ofstream(*report.output_file);
- }
-#ifdef HAVE_UNIX_PIPES
- else if (report.pager) {
- status = pipe(pfd);
- if (status == -1)
- throw_(std::logic_error, "Failed to create pipe");
-
- status = fork();
- if (status < 0) {
- throw_(std::logic_error, "Failed to fork child process");
- }
- else if (status == 0) { // child
- // Duplicate pipe's reading end into stdin
- status = dup2(pfd[0], STDIN_FILENO);
- if (status == -1)
- perror("dup2");
-
- // Close unuseful file descriptors: the pipe's writing and
- // reading ends (the latter is not needed anymore, after the
- // duplication).
- close(pfd[1]);
- close(pfd[0]);
-
- // Find command name: its the substring starting right of the
- // rightmost '/' character in the pager pathname. See manpage
- // for strrchr.
- execlp(report.pager->native_file_string().c_str(),
- basename(*report.pager).c_str(), (char *)0);
- perror("execl");
- exit(1);
- }
- else { // parent
- close(pfd[0]);
- out = new boost::fdostream(pfd[1]);
- }
- }
-#endif
-
- report.define("ostream", value_t(out));
-
// Are we handling the expr commands? Do so now.
if (verb == "expr") {
@@ -294,11 +237,52 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
return 0;
}
- // Apply transforms to the hierarchical document structure
+ // Read the command word and create a command object based on it
- INFO_START(transforms, "Applied transforms");
- report.apply_transforms(*expr::global_scope);
- INFO_FINISH(transforms);
+ if (verb == "register" || verb == "reg" || verb == "r")
+ report.transactions_report
+ (xact_handler_ptr(new format_transactions(*out, session.register_format)));
+ else if (verb == "balance" || verb == "bal" || verb == "b")
+ report.accounts_report
+ (acct_handler_ptr(new format_accounts(*out, session.balance_format,
+ report.display_predicate)));
+#if 0
+ else if (verb == "print" || verb == "p")
+ command = print_command();
+ else if (verb == "equity")
+ command = equity_command();
+ else if (verb == "entry")
+ command = entry_command();
+ else if (verb == "dump")
+ command = dump_command();
+ else if (verb == "output")
+ command = output_command();
+ else if (verb == "prices")
+ command = prices_command();
+ else if (verb == "pricesdb")
+ command = pricesdb_command();
+ else if (verb == "csv")
+ command = csv_command();
+ else if (verb == "emacs" || verb == "lisp")
+ command = emacs_command();
+ else if (verb == "xml")
+ command = bind(xml_command, _1);
+ ;
+ else if (verb == "expr")
+ ;
+ else if (verb == "xpath")
+ ;
+ else {
+ char buf[128];
+ std::strcpy(buf, "command_");
+ std::strcat(buf, verb.c_str());
+
+ if (expr::ptr_op_t def = report.lookup(buf))
+ command = def->as_function();
+
+ if (! command)
+ throw_(std::logic_error, string("Unrecognized command '") + verb + "'");
+ }
// Create an argument scope containing the report command's
// arguments, and then invoke the command.
@@ -313,31 +297,12 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
command(command_args);
INFO_FINISH(command);
-
- // Clean up memory, if we
-
- if (DO_VERIFY()) {
- TRACE_START(cleanup, 1, "Cleaning up allocated memory");
-
- clear_transaction_xdata xact_cleaner;
- walk_entries(journal.entries, xact_cleaner);
-
- clear_account_xdata acct_cleaner;
- walk_accounts(*journal.master, acct_cleaner);
-
- if (report.output_file)
- checked_delete(out);
-
-#if 0
- for (std::list<item_handler<transaction_t> *>::iterator i
- = formatter_ptrs.begin();
- i != formatter_ptrs.end();
- i++)
- checked_delete(*i);
#endif
- TRACE_FINISH(cleanup, 1);
- }
+ // Clean up memory, if it matters
+
+ if (DO_VERIFY() && report.output_file)
+ checked_delete(out);
// Write out the binary cache, if need be