diff options
author | John Wiegley <johnw@newartisans.com> | 2005-02-14 08:27:53 +0000 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-04-13 02:41:00 -0400 |
commit | 8fd5f4ee57f146d8486c39becced0a75ee622d31 (patch) | |
tree | ffccdf177a546262ab3aeb2bd01c8d6a220456df | |
parent | 219492564c6a4f6027c2eff37bc0a7b1455ad969 (diff) | |
download | fork-ledger-8fd5f4ee57f146d8486c39becced0a75ee622d31.tar.gz fork-ledger-8fd5f4ee57f146d8486c39becced0a75ee622d31.tar.bz2 fork-ledger-8fd5f4ee57f146d8486c39becced0a75ee622d31.zip |
Added support for "--pager PROGRAM". A likely way to define it in
your login file would be: "export LEDGER_PAGER=$PAGER".
-rw-r--r-- | config.cc | 4 | ||||
-rw-r--r-- | config.h | 1 | ||||
-rw-r--r-- | main.cc | 74 |
3 files changed, 75 insertions, 4 deletions
@@ -725,6 +725,10 @@ OPT_BEGIN(tail, ":") { config.tail_entries = std::atoi(optarg); } OPT_END(tail); +OPT_BEGIN(pager, ":") { + config.pager = optarg; +} OPT_END(pager); + OPT_BEGIN(empty, "E") { config.show_empty = true; } OPT_END(empty); @@ -49,6 +49,7 @@ struct config_t std::string forecast_limit; std::string reconcile_balance; std::string reconcile_date; + std::string pager; unsigned long budget_flags; unsigned long pricing_leeway; int head_entries; @@ -15,10 +15,18 @@ using namespace ledger; #include <exception> #include <iterator> #include <string> +#include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> +#ifdef HAVE_UNIX_PIPES +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include "fdstream.hpp" +#endif + #if !defined(DEBUG_LEVEL) || DEBUG_LEVEL <= RELEASE #define auto_ptr bogus_auto_ptr @@ -306,9 +314,57 @@ int parse_and_report(int argc, char * argv[], char * envp[]) // Configure the output stream +#ifdef HAVE_UNIX_PIPES + int status, pfd[2]; // Pipe file descriptors +#endif std::ostream * out = &std::cout; - if (! config.output_file.empty()) + + if (! config.output_file.empty()) { out = new std::ofstream(config.output_file.c_str()); + } +#ifdef HAVE_UNIX_PIPES + else if (! config.pager.empty()) { + status = pipe(pfd); + if (status == -1) + throw error("Failed to create pipe"); + + status = fork(); + if (status < 0) { + throw error("Failed to fork child process"); + } + else if (status == 0) { // child + const char *arg0; + + // 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. + arg0 = std::strrchr(config.pager.c_str(), '/'); + if (arg0 != NULL) + arg0++; + else + arg0 = config.pager.c_str(); // No slashes in pager. + + execlp(config.pager.c_str(), arg0, (char *)0); + perror("execl"); + exit(1); + } + else { // parent + close(pfd[0]); + out = new boost::fdostream(pfd[1]); + } + } +#endif // Compile the format strings @@ -446,7 +502,6 @@ def vmax(d, val):\n\ } #if DEBUG_LEVEL >= BETA - clear_all_xdata(); if (! config.output_file.empty()) @@ -458,8 +513,7 @@ def vmax(d, val):\n\ i++) delete *i; formatter_ptrs.clear(); - -#endif // DEBUG_LEVEL >= BETA +#endif // Write out the binary cache, if need be @@ -468,6 +522,18 @@ def vmax(d, val):\n\ write_binary_journal(stream, journal.get()); } +#ifdef HAVE_UNIX_PIPES + if (! config.pager.empty()) { + delete out; + close(pfd[1]); + + // Wait for child to finish + wait(&status); + if (status & 0xffff != 0) + throw error("Something went wrong in the pager"); + } +#endif + return 0; } |