diff options
-rw-r--r-- | README | 107 | ||||
-rw-r--r-- | binary.cc | 29 | ||||
-rw-r--r-- | ledger.h | 2 | ||||
-rw-r--r-- | main.cc | 6 | ||||
-rw-r--r-- | util.h | 38 |
5 files changed, 123 insertions, 59 deletions
@@ -914,12 +914,13 @@ If you are an accountant, or you are familiar with accounting terminology, then you might be tearing your hair out after reading the above. Please don't! -Ledger is a lightweight tool that gets people comfortable with their -finances. Contemporary accounting practices will often seem -counter-intuitive and confusing to the layman. To make Ledger more -accessible, it deviates from the accounting conventions and -terminology. However, Ledger is flexible enough that you can -interpret your transactions however you wish. +Ledger is intended to make people comfortable with their finances; to +help them better control the flow of their money. Contemporary +accounting practices, on the other hand, often seem counter-intuitive +and confusing to the layman. To make Ledger more accessible, it +avoids the use of standard accounting conventions and terminology. +However, Ledger is flexible enough that you may interpret what is +happening however you wish. Most probably, the following section will confuse you, and you should skip it if you've managed to understand everything so far. However, @@ -1101,13 +1102,12 @@ ledger, with the attached prefix "Billable": * Running Ledger -Now that you have an orderly and well-organized general ledger, it's -time to start generating some orderly and well-organized reports. -This is where the Ledger tool comes in. With it, you can balance your +Once you have an orderly and well-organized general ledger, the next +step is to generate orderly and well-organized reports. This is where +the Ledger command-line tool comes in. With it, you can balance your checkbook, see where your money is going, tell whether you've made a -profit this year, and even compute the present day value of your -retirement accounts. And all with the simplest of interfaces: the -command-line. +profit this year, and compute the present value of your retirement +accounts. And all with the simplest of interfaces, the command-line. The most often used command will be the "balance" command: @@ -1344,26 +1344,66 @@ There is a shell script in the distribution called "entry", which simplifies the task of adding a new entry to your ledger, and then launches =vi= to let you confirm that the entry looks appropriate. -** Option summary +** Using command options + +With all of the commands, various command-line options are allowed +that will modify the behavior of the command in some way. And while +the basic commands themselves are useful, you will often find +yourselves adding option flags to the command-line to modify those +commands. + +The command-line options always occur before the command word. This +is done to distinguish them from the matching expressions that always +occur after the command word. The basic form of any command is: + +<example> +ledger [OPTIONS] COMMAND [MATCH] +</example> + +Both the OPTIONS and MATCH expressions are optional. You could, for +example, just use "ledger balance" without any modification. This +would print the summarized total of all account types. But to get +more specific reporting, or to change the way the output looks, you +must use the options. *** Basic options -**-v** :: - Display the version of ledger being used. +The =--help= (=-h=) option causes ledger to print a summary of all the +options, and what they are used for. This can be a handy way to +remember which options do what. This help screen is also printed if +ledger is run without a command. + +=--version= (=-v=) prints the current version of ledger and exits. +This is useful for sending bug reports (to johnw@newartisans.com), to +let the author know which version of ledger you are using. + +=--init FILE= (=-i FILE=) causes FILE to be read by ledger before any +other ledger file. This file may not contain any transactions, but it +may contain option settings. To specify options in the init file, use +the same syntax as the command-line. Here's an example init file: -**-h** :: - Print out quick help on the various options and commands. +<example> +--price-db ~/finance/.pricedb +</example> + +Option settings on the command-line or in the environment always take +precedence over settings in the init file. + +=--file FILE= (=-f FILE=) reads FILE as a ledger file. This command +may be used multiple times. FILE may also be a list of file names +separated by colons. Typically, the environment variable +=LEDGER_FILE= is set, rather than using this command-line option. -**-f FILE[<verbatim>=</verbatim>ACCOUNT]** :: - Read ledger entries from FILE. This takes precedence over the - environment variable LEDGER. If "<verbatim>=</verbatim>ACCOUNT" is - appended to the filename, then all of the entries are seen as if the - transactions accounts were prefixed by "ACCOUNT:". There may be - multiple occurrences of the =-f= option. +=--cache FILE= identifies FILE as the default binary cache file. That +is, if the ledger files to be read are specified using the environment +variable =LEDGER_FILE=, then whenever a command is finished a binary +copy will be written to the specified cache, to speed up the loading +time of subsequent queries. This filename can also be given using the +environment variable =LEDGER_CACHE=, or by putting the option into +your init file. -**-i FILE** :: - Read in the list of patterns to include/exclude from FILE. - Ordinarily, these are specified as arguments after the command. +=--output FILE= (=-o FILE=) redirects output from any command to +=FILE=. By default, all output goes to standard output. *** Filtering options @@ -1505,21 +1545,6 @@ launches =vi= to let you confirm that the entry looks appropriate. use: -p "$=0.00280112 AU" (or whatever the current exchange rate is). -** Environment variables - -=LEDGER= :: - A colon-separated list of files to be parsed whenever ledger is run. - Easier than typing =-f= all the time. - -=PRICE_HIST= :: - The ledger file used to hold pricing data. =~/.pricedb= would be a - good choice. - -=PRICE_EXP= :: - The number of minutes before pricing data becomes out-of-date. The - default is one day. Use =-L= to temporarily decrease or increase - the value. - Footnotes: [1] In some special cases, it will automatically balance the entry for you. @@ -13,8 +13,8 @@ namespace ledger { - unsigned long binary_magic_number = 0xFFEED765; -static unsigned long format_version = 0x0002000a; +const unsigned long binary_magic_number = 0xFFEED765; +static const unsigned long format_version = 0x0002000b; static std::vector<account_t *> accounts; static account_t::ident_t ident; @@ -82,7 +82,7 @@ void read_binary_amount(std::istream& in, amount_t& amt) { commodity_t::ident_t id; read_binary_number(in, id); - if (id == 0xffff) + if (id == 0xffffffff) amt.commodity = NULL; else amt.commodity = commodities[id]; @@ -94,9 +94,7 @@ transaction_t * read_binary_transaction(std::istream& in, entry_t * entry) { transaction_t * xact = new transaction_t(entry, NULL); - account_t::ident_t id; - read_binary_number(in, id); - xact->account = accounts[id]; + xact->account = accounts[read_binary_number<account_t::ident_t>(in)]; xact->account->add_transaction(xact); read_binary_amount(in, xact->amount); @@ -131,10 +129,8 @@ commodity_t * read_binary_commodity(std::istream& in) commodity_t * commodity = new commodity_t; commodities.push_back(commodity); - commodity_t::ident_t id; - read_binary_number(in, id); - commodity->ident = id; - assert(id == commodities.size() - 1); + commodity->ident = read_binary_number<commodity_t::ident_t>(in); + assert(commodity->ident == commodities.size() - 1); read_binary_string(in, commodity->symbol); read_binary_string(in, commodity->name); @@ -162,13 +158,12 @@ account_t * read_binary_account(std::istream& in, account_t * master = NULL) account_t * acct = new account_t(NULL); accounts.push_back(acct); - account_t::ident_t id; - read_binary_number(in, id); - acct->ident = id; - assert(id == accounts.size() - 1); + acct->ident = read_binary_number<account_t::ident_t>(in); + assert(acct->ident == accounts.size() - 1); + account_t::ident_t id; read_binary_number(in, id); // parent id - if (id == 0xffff) + if (id == 0xffffffff) acct->parent = NULL; else acct->parent = accounts[id]; @@ -289,7 +284,7 @@ void write_binary_amount(std::ostream& out, const amount_t& amt) if (amt.commodity) write_binary_number(out, amt.commodity->ident); else - write_binary_number<commodity_t::ident_t>(out, 0xffff); + write_binary_number<commodity_t::ident_t>(out, 0xffffffff); amt.write_quantity(out); } @@ -349,7 +344,7 @@ void write_binary_account(std::ostream& out, account_t * account) if (account->parent) write_binary_number(out, account->parent->ident); else - write_binary_number<account_t::ident_t>(out, 0xffff); + write_binary_number<account_t::ident_t>(out, 0xffffffff); write_binary_string(out, account->name); write_binary_string(out, account->note); @@ -229,7 +229,7 @@ unsigned int parse_textual_journal(std::istream& in, journal_t * ledger, account_t * master = NULL); -extern unsigned long binary_magic_number; +extern const unsigned long binary_magic_number; unsigned int read_binary_journal(std::istream& in, journal_t * journal, @@ -97,12 +97,16 @@ int main(int argc, char * argv[], char * envp[]) process_environment(envp, "LEDGER_"); +#if 1 + // These are here until 3.x, for backwards compatability. + if (const char * p = std::getenv("LEDGER")) process_option("file", p); if (const char * p = std::getenv("PRICE_HIST")) process_option("price-db", p); if (const char * p = std::getenv("PRICE_EXP")) process_option("price-exp", p); +#endif TIMER_STOP(process_env); @@ -123,9 +127,11 @@ int main(int argc, char * argv[], char * envp[]) journal->sources.pop_front(); // remove cache_file strings_list exceptions; +#if 0 std::set_difference(journal->sources.begin(), journal->sources.end(), config->files.begin(), config->files.end(), exceptions.begin()); +#endif if (entry_count == 0 || exceptions.size() > 0) { journal.reset(new journal_t); @@ -0,0 +1,38 @@ +#ifndef _UTIL_H +#define _UTIL_H + +inline char * skip_ws(char * ptr) { + while (*ptr == ' ' || *ptr == '\t' || *ptr == '\n') + ptr++; + return ptr; +} + +inline char peek_next_nonws(std::istream& in) { + char c = in.peek(); + while (! in.eof() && std::isspace(c)) { + in.get(c); + c = in.peek(); + } + return c; +} + +#define READ_INTO(str, targ, size, var, cond) { \ + char * _p = targ; \ + var = str.peek(); \ + while (! str.eof() && (cond)) { \ + str.get(var); \ + if (str.eof()) \ + break; \ + if (var == '\\') { \ + str.get(var); \ + if (in.eof()) \ + break; \ + } \ + *_p++ = var; \ + var = str.peek(); \ + } \ + assert(_p < targ + ((size) - 1)); \ + *_p = '\0'; \ +} + +#endif // _UTIL_H |