summaryrefslogtreecommitdiff
path: root/src/main.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-01-30 00:40:46 -0400
committerJohn Wiegley <johnw@newartisans.com>2009-01-30 00:40:46 -0400
commitcdb123974cd6657d4e8d47af9aef5a80d49f2810 (patch)
tree6bb28be7dee3adab341dd12f5e07f303155585e7 /src/main.cc
parentc96635fe605f142f0402e5728e5d2a49b48c1453 (diff)
downloadfork-ledger-cdb123974cd6657d4e8d47af9aef5a80d49f2810.tar.gz
fork-ledger-cdb123974cd6657d4e8d47af9aef5a80d49f2810.tar.bz2
fork-ledger-cdb123974cd6657d4e8d47af9aef5a80d49f2810.zip
Created a new stream.h file for dealing with output streaming.
Diffstat (limited to 'src/main.cc')
-rw-r--r--src/main.cc200
1 files changed, 32 insertions, 168 deletions
diff --git a/src/main.cc b/src/main.cc
index 2f51a5bf..dfbeeb75 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -45,12 +45,6 @@
#include "ofx.h"
#endif
-#ifdef HAVE_UNIX_PIPES
-#include <sys/types.h>
-#include <sys/wait.h>
-#include "fdstream.h"
-#endif
-
namespace ledger {
int read_and_report(ledger::report_t& report,
int argc, char * argv[], char * envp[])
@@ -133,176 +127,58 @@ namespace ledger {
TRACE_FINISH(arguments, 1);
- // Configure the output stream
-
-#ifdef HAVE_UNIX_PIPES
- int status, pfd[2]; // Pipe file descriptors
-#endif
- report.output_stream = &std::cout;
-
- if (report.output_file) {
- report.output_stream = 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(), NULL);
- perror("execl");
- exit(1);
- }
- else { // parent
- close(pfd[0]);
- report.output_stream = new boost::fdostream(pfd[1]);
- }
- }
-#endif
-
// Read the command word and see if it's any of the debugging commands
// that Ledger supports.
- std::ostream& out(*report.output_stream);
-
string verb = *arg++;
- if (verb == "parse") {
- out << "--- Input text ---" << std::endl;
- out << *arg << std::endl;
-
- out << std::endl << "--- Text as parsed ---" << std::endl;
- expr_t expr(*arg);
- expr.print(out);
- out << std::endl;
-
- out << std::endl << "--- Expression tree ---" << std::endl;
- expr.dump(out);
-
- out << std::endl << "--- Calculated value ---" << std::endl;
- expr.calc(report).print(out);
- out << std::endl;
-
- return 0;
- }
- else if (verb == "compile") {
- out << "--- Input text ---" << std::endl;
- out << *arg << std::endl;
-
- out << std::endl << "--- Text as parsed ---" << std::endl;
- expr_t expr(*arg);
- expr.print(out);
- out << std::endl;
-
- out << std::endl << "--- Expression tree ---" << std::endl;
- expr.dump(out);
-
- expr.compile(report);
-
- out << std::endl << "--- Compiled tree ---" << std::endl;
- expr.dump(out);
-
- out << std::endl << "--- Calculated value ---" << std::endl;
- expr.calc(report).print(out);
- out << std::endl;
-
- return 0;
- }
- else if (verb == "eval") {
- expr_t expr(*arg);
- out << expr.calc(report).strip_annotations() << std::endl;
- return 0;
- }
- else if (verb == "format") {
- format_t fmt(*arg);
- fmt.dump(out);
- return 0;
- }
- else if (verb == "period") {
- interval_t interval(*arg);
-
- if (! is_valid(interval.begin)) {
- out << "Time period has no beginning." << std::endl;
- } else {
- out << "begin: " << format_date(interval.begin) << std::endl;
- out << " end: " << format_date(interval.end) << std::endl;
- out << std::endl;
-
- date_t date = interval.first();
-
- for (int i = 0; i < 20; i++) {
- out << std::right;
- out.width(2);
-
- out << i << ": " << format_date(date) << std::endl;
-
- date = interval.increment(date);
- if (is_valid(interval.end) && date >= interval.end)
- break;
- }
- }
- return 0;
- }
+ function_t command;
+ if (expr_t::ptr_op_t def = report.lookup(string("ledger_precmd_") + verb))
+ command = def->as_function();
// Parse the initialization file, which can only be textual; then
- // parse the journal data.
+ // parse the journal data. But only do this if there was no
+ // "pre-command", which are always executed without doing any
+ // parsing.
- INFO_START(journal, "Read journal file");
+ if (! command) {
+ INFO_START(journal, "Read journal file");
- journal_t& journal(*session.create_journal());
+ journal_t& journal(*session.create_journal());
- std::size_t count = session.read_data(journal, report.account);
- if (count == 0)
- throw_(parse_error, "Failed to locate any journal entries; "
- "did you specify a valid file with -f?");
+ std::size_t count = session.read_data(journal, report.account);
+ if (count == 0)
+ throw_(parse_error, "Failed to locate any journal entries; "
+ "did you specify a valid file with -f?");
- INFO_FINISH(journal);
+ INFO_FINISH(journal);
- INFO("Found " << count << " entries");
+ INFO("Found " << count << " entries");
- TRACE_FINISH(entry_text, 1);
- TRACE_FINISH(entry_date, 1);
- TRACE_FINISH(entry_details, 1);
- TRACE_FINISH(entry_xacts, 1);
- TRACE_FINISH(entries, 1);
- TRACE_FINISH(parsing_total, 1);
+ TRACE_FINISH(entry_text, 1);
+ TRACE_FINISH(entry_details, 1);
+ TRACE_FINISH(entry_xacts, 1);
+ TRACE_FINISH(entries, 1);
+ TRACE_FINISH(session_parser, 1);
+ TRACE_FINISH(parsing_total, 1);
- // Lookup the command object corresponding to the command verb.
+ // Lookup the command object corresponding to the command verb.
- function_t command;
- if (expr_t::ptr_op_t def = report.lookup(string("cmd_") + verb))
- command = def->as_function();
+ if (expr_t::ptr_op_t def = report.lookup(string("ledger_cmd_") + verb))
+ command = def->as_function();
+ }
if (! command)
throw_(std::logic_error, string("Unrecognized command '") + verb + "'");
+#if 1
// Patch up some of the reporting options based on what kind of
// command it was.
// jww (2008-08-14): This code really needs to be rationalized away
// for 3.0.
- if (verb[0] == 'p' || verb == "entry" || verb == "dump") {
+ if (verb == "print" || verb == "entry" || verb == "dump") {
report.show_related = true;
report.show_all_related = true;
}
@@ -340,6 +216,7 @@ namespace ledger {
report.display_predicate = "amount";
}
}
+#endif
// Now setup the various formatting strings
@@ -357,6 +234,10 @@ namespace ledger {
if (! report.report_period.empty() && ! report.sort_all)
report.entry_sort = true;
+ // Setup the output stream, which might involve invoking the pager
+
+ report.output_stream.initialize(report.output_file, report.pager_path);
+
// Create an argument scope containing the report command's
// arguments, and then invoke the command.
@@ -384,23 +265,6 @@ namespace ledger {
}
#endif
- // If the user specified a pager, wait for it to exit now
-
-#ifdef HAVE_UNIX_PIPES
- if (! report.output_file && report.pager) {
- checked_delete(report.output_stream);
- close(pfd[1]);
-
- // Wait for child to finish
- wait(&status);
- if (status & 0xffff != 0)
- throw_(std::logic_error, "Something went wrong in the pager");
- }
-#endif
- else if (DO_VERIFY() && report.output_file) {
- checked_delete(report.output_stream);
- }
-
return 0;
}
}