summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2004-08-13 17:02:25 -0400
committerJohn Wiegley <johnw@newartisans.com>2004-08-13 17:02:25 -0400
commit6944e5950a90b17d53a6efe87c71512085d4e1f7 (patch)
treeedad327a21739b9fabd5ccc72f0d22d73bb5d791
parent8a70bbed521662e76c1b3c42460743bb891c2deb (diff)
downloadfork-ledger-6944e5950a90b17d53a6efe87c71512085d4e1f7.tar.gz
fork-ledger-6944e5950a90b17d53a6efe87c71512085d4e1f7.tar.bz2
fork-ledger-6944e5950a90b17d53a6efe87c71512085d4e1f7.zip
more options fixes
-rw-r--r--ledger.cc52
-rw-r--r--ledger.h6
-rw-r--r--main.cc68
-rw-r--r--option.cc47
-rw-r--r--option.h6
-rw-r--r--textual.cc3
6 files changed, 93 insertions, 89 deletions
diff --git a/ledger.cc b/ledger.cc
index 8dfa0b98..19be9d62 100644
--- a/ledger.cc
+++ b/ledger.cc
@@ -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);
}
diff --git a/ledger.h b/ledger.h
index 9d34316b..8a781c53 100644
--- a/ledger.h
+++ b/ledger.h
@@ -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);
diff --git a/main.cc b/main.cc
index 9a39cf48..b22c5260 100644
--- a/main.cc
+++ b/main.cc
@@ -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 {
diff --git a/option.cc b/option.cc
index 586037b1..a75c8c40 100644
--- a/option.cc
+++ b/option.cc
@@ -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++)
diff --git a/option.h b/option.h
index 33b54933..943d5193 100644
--- a/option.h
+++ b/option.h
@@ -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; \
diff --git a/textual.cc b/textual.cc
index d2685a00..b9533886 100644
--- a/textual.cc
+++ b/textual.cc
@@ -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;
}