diff options
author | John Wiegley <johnw@newartisans.com> | 2009-02-02 15:54:28 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-02-02 15:54:28 -0400 |
commit | c1cb06e00922ba5c15c128bab05c71220077fdce (patch) | |
tree | db00cc04a338c33c540c3be98c53742a1e2902ca | |
parent | bd9ffed9db00e31e4ad526f4558d0d2929c8ac39 (diff) | |
download | fork-ledger-c1cb06e00922ba5c15c128bab05c71220077fdce.tar.gz fork-ledger-c1cb06e00922ba5c15c128bab05c71220077fdce.tar.bz2 fork-ledger-c1cb06e00922ba5c15c128bab05c71220077fdce.zip |
Updated some internal documentation.
-rw-r--r-- | src/ledger.h | 31 | ||||
-rw-r--r-- | src/main.cc | 107 | ||||
-rw-r--r-- | src/report.h | 12 | ||||
-rw-r--r-- | src/session.cc | 8 | ||||
-rw-r--r-- | src/session.h | 15 | ||||
-rw-r--r-- | src/work.cc | 4 | ||||
-rwxr-xr-x | tools/push | 2 |
7 files changed, 104 insertions, 75 deletions
diff --git a/src/ledger.h b/src/ledger.h index 66fa2c8f..3051dad2 100644 --- a/src/ledger.h +++ b/src/ledger.h @@ -35,7 +35,36 @@ * * @mainpage Ledger Accounting Tool * - * A command-line tool for general double-entry accounting. + * There are essentially nine steps involved in realizing a ledger reporting + * session, with steps 5 and 8 -- which relate to the user's journal file -- + * being optional in the case of "pre-commands", since they do not require the + * user's data to be read. + * + * \section global_init Initialize the global environment + * + * \section create_objs Create session and report objects + * + * jww (2009-02-02): Set the "session context". + * + * \section process_opts Process user options + * + * This configures session and report objects + * + * - environment + * - initialization file + * - command-line options + * + * \section lookup_cmd Locate object relating to command verb + * + * \section parse_data Parse the user's journal files + * + * \section create_out Create the output stream + * + * \section invoke_cmd Invoke the command object + * + * \section write_cache Write out binary cache file, if necessary + * + * \section shutdown Wrap up, closing everything and releasing memory */ #ifndef _LEDGER_H #define _LEDGER_H diff --git a/src/main.cc b/src/main.cc index 06bb2339..736893a4 100644 --- a/src/main.cc +++ b/src/main.cc @@ -29,73 +29,68 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <ledger.h> +#include <ledger.h> // Read this file for a top-level overview -#include "work.h" // this is where the top-level code is +#include "work.h" // This is where the meat of main() is, which + // was moved there for the sake of clarity int main(int argc, char * argv[], char * envp[]) { using namespace ledger; - // The very first thing we do is handle some very special command-line - // options, since they affect how the whole environment is setup: - // - // --verify ; turns on memory tracing - // --verbose ; turns on logging - // --debug CATEGORY ; turns on debug logging - // --trace LEVEL ; turns on trace logging - handle_debug_options(argc, argv); - - IF_VERIFY() - initialize_memory_tracing(); - - // Initialize the global C++ environment - std::ios::sync_with_stdio(false); - filesystem::path::default_name_check(filesystem::portable_posix_name); - - // Initialization of Ledger can now begin. The whole series of operations - // is contained in a try block, so we can report errors in a nicer fashion. - INFO("Ledger starting"); - session_t * session = NULL; int status = 1; try { + // The very first thing we do is handle some very special command-line + // options, since they affect how the environment is setup: + // + // --verify ; turns on memory tracing + // --verbose ; turns on logging + // --debug CATEGORY ; turns on debug logging + // --trace LEVEL ; turns on trace logging + handle_debug_options(argc, argv); + IF_VERIFY() initialize_memory_tracing(); + + INFO("Ledger starting"); + + // Initialize global Boost/C++ environment + std::ios::sync_with_stdio(false); + filesystem::path::default_name_check(filesystem::portable_posix_name); + // Create the session object, which maintains nearly all state relating to - // this invocation of Ledger. + // this invocation of Ledger; and register all known journal parsers. session = new LEDGER_SESSION_T; - set_session_context(session); - - // Register all known journal parsers. The order of these is important. register_journal_parsers(*session); + set_session_context(session); // Create the report object, which maintains state relating to each - // command invocation. Because we're running this from main() the - // distinction between session and report doesn't matter, but if a GUI - // were calling into Ledger, it would have one session object, with a - // separate report object for each report it generated. + // command invocation. Because we're running from main(), the distinction + // between session and report doesn't really matter, but if a GUI were + // calling into Ledger it would have one session object per open document, + // with a separate report_t object for each report it generated. session->report.reset(new report_t(*session)); report_t& report(*session->report.get()); - // Read user option settings, first in the environment, then from the - // user's initialization file and then from the command-line. The first - // non-option argument thereafter is the "command verb". + // Read the user's options, in the following order: + // + // 1. environment variables (LEDGER_<option>) + // 2. initialization file (~/.ledgerrc) + // 3. command-line (--option or -o) + // + // Before processing command-line options, we must notify the session + // object that such options are beginning, since options like -f cause a + // complete override of files found anywhere else. read_environment_settings(report, envp); - session->read_init(); - - // Notify the session object that all option handlers invoked beyond this - // point came from the command-line + session->read_init(); // accesses report object via session.report session->now_at_command_line(true); - - strings_list args = read_command_line_arguments(report, argc, argv); - string_iterator arg = args.begin(); - string verb = *arg++; + strings_list args = read_command_line_arguments(report, argc, argv); // Look for a precommand first, which is defined as any defined function // whose name starts with "ledger_precmd_". The difference between a // precommand and a regular command is that precommands ignore the journal // data file completely, nor is the user's init file read. // - // Here are some examples: + // Here are some examples of pre-commands: // // parse STRING ; show how a value expression is parsed // eval STRING ; simply evaluate a value expression @@ -103,22 +98,27 @@ int main(int argc, char * argv[], char * envp[]) // // If such a command is found, create the output stream for the result and // then invoke the command. + string_iterator arg = args.begin(); + string verb = *arg++; + if (function_t command = look_for_precommand(report, verb)) { + // Create the output stream (it might be a file, the console or a PAGER + // subprocess) and invoke the report command. create_output_stream(report); invoke_command_verb(report, command, arg, args.end()); } else if (function_t command = look_for_command(report, verb)) { - // Parse the user's journal files. + // This is regular command verb, so parse the user's data. if (journal_t * journal = read_journal_files(*session)) { - normalize_report_options(report, verb); // this is a total hack + normalize_report_options(report, verb); // jww (2009-02-02): a hack // Create the output stream (it might be a file, the console or a // PAGER subprocess) and invoke the report command. create_output_stream(report); invoke_command_verb(report, command, arg, args.end()); - // Write out a binary cache of the journal data, if needed and - // appropriate to do so + // Write out a binary cache of the journal data, if needful and + // appropriate to do so. write_binary_cache(*session, journal); } } @@ -126,21 +126,22 @@ int main(int argc, char * argv[], char * envp[]) throw_(std::logic_error, "Unrecognized command '" << verb << "'"); } - // If we got here, everything succeeded just fine. Ledger uses exceptions - // to notify of any error conditions, so if you're using gdb, type "catch - // throw" to find the source of any errors. + // If we've reached this point, everything succeeded fine. Ledger uses + // exceptions to notify of error conditions, so if you're using gdb, just + // type "catch throw" to find the source point of any error. status = 0; } catch (const std::exception& err) { - std::cout.flush(); + std::cout.flush(); // first display anything that was pending std::cerr << error_context() << std::endl << "Error: " << err.what() << std::endl; } catch (int _status) { - status = _status; + status = _status; // used for a "quick" exit, and is used only + // if help text (such as --help) was displayed } - // Close the output stream, waiting on the pager process if need be + // Close the output stream, waiting on the pager process to exit if need be session->report->output_stream.close(); // If memory verification is being performed (which can be very slow), clean @@ -159,6 +160,8 @@ int main(int argc, char * argv[], char * envp[]) INFO("Ledger ended"); } + // Return the final status to the operating system, either 1 for error or 0 + // for a successful completion. return status; } diff --git a/src/report.h b/src/report.h index 54f24845..2654d7c6 100644 --- a/src/report.h +++ b/src/report.h @@ -216,32 +216,32 @@ public: value_t option_full_help(call_scope_t& args) { // H option_full_help(std::cout); - throw 0; + throw int(0); } value_t option_help(call_scope_t& args) { // h option_help(std::cout); - throw 0; + throw int(0); } value_t option_help_calc(call_scope_t& args) { option_calc_help(std::cout); - throw 0; + throw int(0); } value_t option_help_disp(call_scope_t& args) { option_disp_help(std::cout); - throw 0; + throw int(0); } value_t option_help_comm(call_scope_t& args) { option_comm_help(std::cout); - throw 0; + throw int(0); } value_t option_version(call_scope_t& args) { // v show_version(std::cout); - throw 0; + throw int(0); } value_t option_init_file(call_scope_t& args) { // i: diff --git a/src/session.cc b/src/session.cc index fc0601d5..9d926550 100644 --- a/src/session.cc +++ b/src/session.cc @@ -178,10 +178,10 @@ void session_t::read_init() journal_t temp; if (read_journal(temp, *init_file) > 0 || - temp.auto_entries.size() > 0 || - temp.period_entries.size() > 0) - throw_(parse_error, "Entries found in initialization file '" << - init_file << "'"); + temp.auto_entries.size() > 0 || temp.period_entries.size() > 0) { + throw_(parse_error, + "Entries found in initialization file '" << init_file << "'"); + } TRACE_FINISH(init, 1); } diff --git a/src/session.h b/src/session.h index 3723369d..d7023045 100644 --- a/src/session.h +++ b/src/session.h @@ -264,15 +264,14 @@ See LICENSE file included with the distribution for details and disclaimer.\n"; }; /** - * This sets the current session context, transferring all static - * globals to point at the data structures related to this session. - * Although Ledger itself is not thread-safe, by locking, switching - * session context, then unlocking after the operation is done, - * multiple threads can sequentially make use of the library. Thus, a - * session_t maintains all of the information relating to a single - * usage of the Ledger library. + * Set the current session context, transferring all static globals to point + * at the data structures related to this session. Although Ledger itself is + * not thread-safe, by locking, switching session context, then unlocking + * after an operation is done, multiple threads can sequentially make use of + * the library. Thus, a session_t maintains all of the information relating + * to a single usage of the Ledger library. */ -void set_session_context(session_t * session = NULL); +void set_session_context(session_t * session); } // namespace ledger diff --git a/src/work.cc b/src/work.cc index 95f3dee4..bc14bd04 100644 --- a/src/work.cc +++ b/src/work.cc @@ -65,9 +65,7 @@ void handle_debug_options(int argc, char * argv[]) _trace_level = boost::lexical_cast<int>(argv[i + 1]); } catch (const boost::bad_lexical_cast& e) { - std::cerr << "Argument to --trace must be an integer." - << std::endl; - throw int(1); + throw std::logic_error("Argument to --trace must be an integer"); } i++; #endif @@ -8,4 +8,4 @@ git push --tags mirror git remote update -github network fetch +#github network fetch |