diff options
author | John Wiegley <johnw@newartisans.com> | 2004-08-13 17:02:25 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2004-08-13 17:02:25 -0400 |
commit | 6944e5950a90b17d53a6efe87c71512085d4e1f7 (patch) | |
tree | edad327a21739b9fabd5ccc72f0d22d73bb5d791 | |
parent | 8a70bbed521662e76c1b3c42460743bb891c2deb (diff) | |
download | fork-ledger-6944e5950a90b17d53a6efe87c71512085d4e1f7.tar.gz fork-ledger-6944e5950a90b17d53a6efe87c71512085d4e1f7.tar.bz2 fork-ledger-6944e5950a90b17d53a6efe87c71512085d4e1f7.zip |
more options fixes
-rw-r--r-- | ledger.cc | 52 | ||||
-rw-r--r-- | ledger.h | 6 | ||||
-rw-r--r-- | main.cc | 68 | ||||
-rw-r--r-- | option.cc | 47 | ||||
-rw-r--r-- | option.h | 6 | ||||
-rw-r--r-- | textual.cc | 3 |
6 files changed, 93 insertions, 89 deletions
@@ -52,43 +52,41 @@ bool journal_t::remove_entry(entry_t * entry) return true; } -entry_t * journal_t::derive_entry(int argc, char **argv) const +entry_t * journal_t::derive_entry(strings_list::iterator i, + strings_list::iterator end) const { - entry_t * added = new entry_t; - entry_t * matching = NULL; - int index = 0; + entry_t * added = new entry_t; + entry_t * matching = NULL; - assert(index < argc); - - if (! parse_date(argv[index++], &added->date)) { - std::cerr << "Error: Bad entry date: " << argv[index - 1] - << std::endl; + if (! parse_date((*i).c_str(), &added->date)) { + std::cerr << "Error: Bad entry date: " << *i << std::endl; return false; } + ++i; - if (index == argc) { + if (i == end) { std::cerr << "Error: Too few arguments to 'entry'." << std::endl; return false; } - mask_t regexp(argv[index++]); + mask_t regexp(*i++); - for (entries_list::const_reverse_iterator i = entries.rbegin(); - i != entries.rend(); - i++) - if (regexp.match((*i)->payee)) { - matching = *i; + for (entries_list::const_reverse_iterator j = entries.rbegin(); + j != entries.rend(); + j++) + if (regexp.match((*j)->payee)) { + matching = *j; break; } added->payee = matching ? matching->payee : regexp.pattern; - if (index == argc) { + if (i == end) { std::cerr << "Error: Too few arguments to 'entry'." << std::endl; return false; } - if (argv[index][0] == '-' || std::isdigit(argv[index][0])) { + if ((*i)[0] == '-' || std::isdigit((*i)[0])) { if (! matching) { std::cerr << "Error: Missing account name for non-matching entry." << std::endl; @@ -98,7 +96,7 @@ entry_t * journal_t::derive_entry(int argc, char **argv) const transaction_t * m_xact, * xact, * first; m_xact = matching->transactions.front(); - amount_t amt(argv[index++]); + amount_t amt(*i++); first = xact = new transaction_t(added, m_xact->account, amt, amt); if (xact->amount.commodity->symbol.empty()) { @@ -113,12 +111,12 @@ entry_t * journal_t::derive_entry(int argc, char **argv) const - first->amount, - first->amount); added->add_transaction(xact); - if ((index + 1) < argc && std::string(argv[index]) == "-from") - if (account_t * acct = find_account(argv[++index])) + if (std::string(*i++) == "-from" && i != end) + if (account_t * acct = find_account(*i)) added->transactions.back()->account = acct; } else { - while (index < argc && std::string(argv[index]) != "-from") { - mask_t acct_regex(argv[index++]); + while (std::string(*i) != "-from") { + mask_t acct_regex(*i++); account_t * acct = NULL; commodity_t * cmdty = NULL; @@ -145,12 +143,12 @@ entry_t * journal_t::derive_entry(int argc, char **argv) const return false; } - if (index == argc) { + if (i == end) { std::cerr << "Error: Too few arguments to 'entry'." << std::endl; return false; } - amount_t amt(argv[index]++); + amount_t amt(*i++); transaction_t * xact = new transaction_t(added, acct, amt, amt); if (! xact->amount.commodity) @@ -159,8 +157,8 @@ entry_t * journal_t::derive_entry(int argc, char **argv) const added->add_transaction(xact); } - if ((index + 1) < argc && std::string(argv[index]) == "-from") { - if (account_t * acct = find_account(argv[++index])) { + if (std::string(*i++) == "-from" && i != end) { + if (account_t * acct = find_account(*i++)) { transaction_t * xact = new transaction_t(NULL, acct); added->add_transaction(xact); } @@ -165,7 +165,8 @@ inline std::ostream& operator<<(std::ostream& out, const account_t& acct) { } -typedef std::list<entry_t *> entries_list; +typedef std::list<entry_t *> entries_list; +typedef std::list<std::string> strings_list; class journal_t { @@ -208,7 +209,8 @@ class journal_t bool add_entry(entry_t * entry); bool remove_entry(entry_t * entry); - entry_t * derive_entry(int argc, char **argv) const; + entry_t * derive_entry(strings_list::iterator begin, + strings_list::iterator end) const; }; int parse_journal_file(char * p, journal_t * journal); @@ -109,6 +109,7 @@ namespace { bool use_cache = false; } +// jww (2004-08-13): fix this static std::string ledger_cache_file() { std::string cache_file; @@ -175,12 +176,12 @@ static void show_help(std::ostream& out) } -DEF_OPT_HANDLERS(); - ////////////////////////////////////////////////////////////////////// // // Basic options +DEF_OPT_HANDLERS(); + OPT_BEGIN(help, "h", false) { show_help(std::cout); std::exit(0); @@ -191,10 +192,10 @@ OPT_BEGIN(version, "v", false) { std::exit(0); } OPT_END(version); -OPT_BEGIN(init_file, "i:", true) { +OPT_BEGIN(init, "i:", true) { std::ifstream stream(optarg); parse_textual_journal(stream, journal.get(), journal->master); -} OPT_END(init_file); +} OPT_END(init); OPT_BEGIN(file, "f:", true) { files.push_back(optarg); @@ -428,22 +429,14 @@ int main(int argc, char * argv[], char * envp[]) { #ifdef DEBUG_ENABLED if (char * p = std::getenv("DEBUG_FILE")) { - debug_stream = new std::ofstream(p); + debug_stream = new std::ofstream(p); free_debug_stream = true; } #endif - // Initialize some variables based on environment variable settings - - // jww (2004-08-13): fix these - if (char * p = std::getenv("PRICE_HIST")) - price_db = p; - - if (char * p = std::getenv("PRICE_EXP")) - pricing_leeway = std::atol(p) * 60; - // A ledger data file must be specified + // jww (2004-08-13): use LEDGER_FILE use_cache = std::getenv("LEDGER") != NULL; if (use_cache) { @@ -475,19 +468,23 @@ int main(int argc, char * argv[], char * envp[]) // Parse the command-line options - std::vector<char *> args; - process_arguments(args, argc, argv); + std::list<std::string> args; + process_arguments(argc, argv, false, args); if (args.empty()) { show_help(std::cerr); return 1; } - argc = args.size(); - int index = 0; + std::list<std::string>::iterator arg = args.begin(); // Process options from the environment - process_environment(envp); + process_environment(envp, "LEDGER_"); + + if (char * p = std::getenv("PRICE_HIST")) + process_option("price-db", p); + if (char * p = std::getenv("PRICE_EXP")) + process_option("price-exp", p); // Read the ledger file, unless we already read it from the cache @@ -534,7 +531,7 @@ int main(int argc, char * argv[], char * envp[]) // Read the command word, and then check and simplify it - std::string command = args[index++]; + std::string command = *arg++; if (command == "balance" || command == "bal" || command == "b") command = "b"; @@ -556,32 +553,25 @@ int main(int argc, char * argv[], char * envp[]) std::auto_ptr<entry_t> new_entry; if (command == "e") { - new_entry.reset(journal->derive_entry(argc - index, &args[index])); + new_entry.reset(journal->derive_entry(arg, args.end())); } else { // Treat the remaining command-line arguments as regular // expressions, used for refining report results. - int start = index; - for (; index < argc; index++) - if (std::strcmp(args[index], "--") == 0) { - index++; + std::list<std::string>::iterator i = args.begin(); + for (; i != args.end(); i++) + if (*i == "--") break; - } - if (start < index) { - std::list<std::string> regexps(&args[start], &args[index]); - std::string pred = regexps_to_predicate(regexps.begin(), regexps.end()); - if (! pred.empty()) { - if (! predicate.empty()) - predicate += "&"; - predicate += pred; - } + std::string pred = regexps_to_predicate(arg, i); + if (! pred.empty()) { + if (! predicate.empty()) + predicate += "&"; + predicate += pred; } - if (index < argc) { - std::list<std::string> regexps(&args[index], &args[argc]); - std::string pred = regexps_to_predicate(regexps.begin(), regexps.end(), - false); + if (i != args.end()) { + std::string pred = regexps_to_predicate(i, args.end(), false); if (! pred.empty()) { if (! predicate.empty()) predicate += "&"; @@ -608,7 +598,7 @@ int main(int argc, char * argv[], char * envp[]) } } - // Compile the sort criteria + // Compile the sorting criteria if (! sort_string.empty()) { try { @@ -31,18 +31,6 @@ option_handler::option_handler(const std::string& label, options.push_back(opt); } -bool process_option(const std::string& opt, const char * arg) -{ - option_handler_map::iterator handler = option_handler::handlers.find(opt); - if (handler != option_handler::handlers.end() && - (! (*handler).second->handled || (*handler).second->multiple)) { - (*handler).second->handle_option(arg); - (*handler).second->handled = true; - return true; - } - return false; -} - static inline void process_option(const option_t& opt, const char * arg = NULL) { if (! opt.handler->handled || opt.handler->multiple) { @@ -51,18 +39,41 @@ static inline void process_option(const option_t& opt, } } -void process_arguments(std::vector<char *>& args, int argc, char ** argv) +bool process_option(const std::string& opt, const char * arg) +{ + option_handler_map::iterator handler = option_handler::handlers.find(opt); + if (handler != option_handler::handlers.end()) { + if (! (*handler).second->handled || (*handler).second->multiple) { + (*handler).second->handle_option(arg); + (*handler).second->handled = true; + } + return true; + } + return false; +} + +void process_arguments(int argc, char ** argv, const bool anywhere, + std::list<std::string>& args) { int index = 1; for (char ** i = argv + 1; index < argc; i++, index++) { if ((*i)[0] != '-') { - args.push_back(*i); - continue; + if (anywhere) { + args.push_back(*i); + continue; + } else { + for (; index < argc; i++, index++) + args.push_back(*i); + break; + } } // --long-option - again: + again: if ((*i)[1] == '-') { + if ((*i)[2] == '\0') + break; + for (std::vector<option_t>::iterator j = option_handler::options.begin(); j != option_handler::options.end(); @@ -114,10 +125,10 @@ void process_arguments(std::vector<char *>& args, int argc, char ** argv) } } -void process_environment(char ** envp) +void process_environment(char ** envp, const std::string& tag) { for (char ** p = envp; *p; p++) - if (std::strncmp(*p, "LEDGER_", 7) == 0) { + if (std::strncmp(*p, tag.c_str(), 7) == 0) { std::string opt; char * q; for (q = *p + 7; *q && *q != '='; q++) @@ -2,6 +2,7 @@ #define _OPTION_H #include <map> +#include <list> #include <vector> #include <string> @@ -34,8 +35,9 @@ struct option_handler { }; bool process_option(const std::string& opt, const char * arg = NULL); -void process_arguments(std::vector<char *>& args, int argc, char ** argv); -void process_environment(char ** envp); +void process_arguments(int argc, char ** argv, const bool anywhere, + std::list<std::string>& args); +void process_environment(char ** envp, const std::string& tag); #define DEF_OPT_HANDLERS() \ std::vector<option_t> option_handler::options; \ @@ -477,7 +477,8 @@ unsigned int parse_textual_journal(std::istream& in, journal_t * journal, in >> opt; in.getline(line, MAX_LINE); linenum++; - process_option(opt, line + 1); + char * p = skip_ws(line); + process_option(opt, *p == '\n' ? NULL : p); break; } |