diff options
-rwxr-xr-x | acprep | 30 | ||||
-rw-r--r-- | doc/ledger3.texi | 36 | ||||
-rw-r--r-- | src/global.cc | 4 | ||||
-rw-r--r-- | src/output.cc | 25 | ||||
-rw-r--r-- | src/strptime.cc | 2 | ||||
-rw-r--r-- | src/textual.cc | 3 | ||||
-rw-r--r-- | test/regress/1182_1.test | 12 | ||||
-rw-r--r-- | test/regress/1182_2.test | 17 |
8 files changed, 105 insertions, 24 deletions
@@ -66,6 +66,16 @@ class BoostInfo(object): if system == 'centos': return [ 'boost-devel' ] + elif system == 'ubuntu-xenial': + return [ 'libboost-dev', + 'libboost-date-time-dev', + 'libboost-filesystem-dev', + 'libboost-iostreams-dev', + 'libboost-python-dev', + 'libboost-regex-dev', + 'libboost-system-dev', + 'libboost-test-dev' ] + elif system == 'ubuntu-trusty': return [ 'libboost-dev', 'libboost-date-time-dev', @@ -565,6 +575,26 @@ class PrepareBuild(CommandLineApp): 'libutfcpp-dev', 'sloccount' ] + BoostInfo().dependencies('ubuntu-trusty') + elif re.search('xenial', info): + self.log.info('Looks like you are using APT on Ubuntu Xenial') + packages = [ + 'sudo', 'apt-get', 'install', + 'build-essential', + 'doxygen', + 'cmake', + 'ninja-build', + 'zlib1g-dev', + 'libbz2-dev', + 'python-dev', + 'libgmp3-dev', + 'libmpfr-dev', + 'gettext', + 'libedit-dev', + 'texinfo', + 'lcov', + 'libutfcpp-dev', + 'sloccount' + ] + BoostInfo().dependencies('ubuntu-xenial') elif re.search('saucy', info): self.log.info('Looks like you are using APT on Ubuntu Saucy') packages = [ diff --git a/doc/ledger3.texi b/doc/ledger3.texi index c724316e..5a01d509 100644 --- a/doc/ledger3.texi +++ b/doc/ledger3.texi @@ -179,7 +179,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Ledger is a command-line accounting tool that provides double-entry accounting based on a text journal. It provides no bells or whistles, and returns the user to the days before user interfaces were even a -twinkling in their father's CRT. +twinkling in their fathers' CRTs. @end ifnottex @@ -212,6 +212,7 @@ twinkling in their father's CRT. * Fat-free Accounting:: * Building the program:: * Getting help:: +* Third-Party Ledger Tutorials:: @end menu @node Fat-free Accounting, Building the program, Introduction to Ledger, Introduction to Ledger @@ -400,7 +401,7 @@ options. You can run `make check` to confirm the result, and `make install` to install. If these intructions do not work for you can check the `INSTALL.md` in the source directory for more up do date build instructions. -@node Getting help, , Building the program, Introduction to Ledger +@node Getting help, , Building the program, Introduction to Ledger @section Getting help @findex help @@ -417,6 +418,23 @@ join the Ledger mailing list at You can also find help in the @code{#ledger} channel on the IRC server @code{irc.freenode.net}. +@node Third-Party Ledger Tutorials, , Getting help, Introduction to Ledger +@section Third-Party Ledger Tutorials + +There are plenty of people using Ledger for accounting applications. +Some have documented how they use Ledger's features to solve their +accounting problems. + +Once such tutorial, specifically designed for non-profit charities that seek +to use Ledger, can be found at +@url{https://k.sfconservancy.org/npo-ledger-cli} (with a copy on GitHub also +available at @url{https://github.com/conservancy/npo-ledger-cli/}). If +you're looking for information about how to use Ledger's tagging system to +handle invoicing, track expenses by program targets, and other such concepts, +you might find the tutorial useful. (Some of the auditor reporting scripts +that relate to the aformentioned Ledger setup can be found +@var{contrib/non-profit-audit-reports/} in Ledger's own source repository.) + @node Ledger Tutorial, Principles of Accounting with Ledger, Introduction to Ledger, Top @chapter Ledger Tutorial @cindex tutorial @@ -1255,7 +1273,7 @@ worth $5000, then you have $5000 in equity in that car. In order to turn that car (a commodity) into a cash flow, or a credit to your bank account, you will have to debit the equity by selling it. -When you start a ledger, you are probably already worth something. +When you start a ledger, you are probably already have a net worth. Your net worth is your current equity. By transferring the money in the ledger from your equity to your bank accounts, you are crediting the ledger account based on your prior equity. That is why, when you @@ -3056,7 +3074,7 @@ used as the payee name for that posting. This affects the This is useful when for example you deposit 4 checks at a time to the bank. On the bank statement, there is just one amount @samp{$400}, but -you can specify from whom each check came from, as shown by example +you can specify from whom each check came, as shown by example below: @smallexample @c input:9B43E57 @@ -3505,7 +3523,7 @@ But this does not do what you might expect: @smallexample 2012-04-10 My Broker Assets:Brokerage 10 AAPL @@ $50.00 - Assets:Brokerage:Cash $750.00 + Assets:Brokerage:Cash $-500.00 2012-04-10 My Broker Assets:Brokerage:Cash $375.00 @@ -3531,11 +3549,11 @@ following two transactions are equivalent: @smallexample 2012-04-10 My Broker Assets:Brokerage 10 AAPL @@ $50.00 - Assets:Brokerage:Cash $750.00 + Assets:Brokerage:Cash $-500.00 2012-04-10 My Broker Assets:Brokerage 10 AAPL @{$50.00@} - Assets:Brokerage:Cash $750.00 + Assets:Brokerage:Cash $-500.00 @end smallexample However, note that what you see in some reports may differ, for @@ -3554,7 +3572,7 @@ at the time of a transaction. This is done using @samp{@{=AMOUNT@}}: @smallexample 2012-04-10 My Broker Assets:Brokerage 10 AAPL @{=$50.00@} - Assets:Brokerage:Cash $750.00 + Assets:Brokerage:Cash $-500.00 @end smallexample These 10 AAPL will now always be reported as being worth $50, no @@ -3570,7 +3588,7 @@ fixated prices by way of the cost: @smallexample 2012-04-10 My Broker Assets:Brokerage 10 AAPL @@ =$50.00 - Assets:Brokerage:Cash $750.00 + Assets:Brokerage:Cash $-500.00 @end smallexample This is the same as the previous transaction, with the same caveats diff --git a/src/global.cc b/src/global.cc index b1c45d45..37765a9b 100644 --- a/src/global.cc +++ b/src/global.cc @@ -136,9 +136,7 @@ void global_scope_t::read_init() path init_file; if (HANDLED(init_file_)) { init_file=HANDLER(init_file_).str(); - if (exists(init_file)) { - parse_init(init_file); - } else { + if (!exists(init_file)) { throw_(parse_error, _f("Could not find specified init file %1%") % init_file); } } else { diff --git a/src/output.cc b/src/output.cc index c6c8ecd7..2a8c8201 100644 --- a/src/output.cc +++ b/src/output.cc @@ -332,18 +332,19 @@ void report_tags::flush() void report_tags::gather_metadata(item_t& item) { - if (item.metadata) - foreach (const item_t::string_map::value_type& data, *item.metadata) { - string tag(data.first); - if (report.HANDLED(values) && data.second.first) - tag += ": " + data.second.first.get().to_string(); - - std::map<string, std::size_t>::iterator i = tags.find(tag); - if (i == tags.end()) - tags.insert(tags_pair(tag, 1)); - else - (*i).second++; - } + if (! item.metadata) + return; + foreach (const item_t::string_map::value_type& data, *item.metadata) { + string tag(data.first); + if (report.HANDLED(values) && data.second.first) + tag += ": " + data.second.first.get().to_string(); + + std::map<string, std::size_t>::iterator i = tags.find(tag); + if (i == tags.end()) + tags.insert(tags_pair(tag, 1)); + else + (*i).second++; + } } void report_tags::operator()(post_t& post) diff --git a/src/strptime.cc b/src/strptime.cc index 6f670baf..069b9267 100644 --- a/src/strptime.cc +++ b/src/strptime.cc @@ -21,6 +21,7 @@ #include <ctype.h> #include <string.h> +#if defined(__CYGWIN__) // Define strnicmp for Cygwin. #ifndef strcmpi #define strcmpi strcasecmp @@ -34,6 +35,7 @@ #ifndef strnicmp #define strnicmp strncasecmp #endif +#endif static const char* kWeekFull[] = { "Sunday", "Monday", "Tuesday", "Wednesday", diff --git a/src/textual.cc b/src/textual.cc index dcb69858..7ad98809 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -563,6 +563,9 @@ void instance_t::automated_xact_directive(char * line) expr_t::ptr_op_t expr = query.parse_args(string_value(skip_ws(line + 1)).to_sequence(), keeper, false, true); + if (!expr) { + throw parse_error(_("Expected predicate after '='")); + } unique_ptr<auto_xact_t> ae(new auto_xact_t(predicate_t(expr, keeper))); ae->pos = position_t(); diff --git a/test/regress/1182_1.test b/test/regress/1182_1.test new file mode 100644 index 00000000..e9c399e6 --- /dev/null +++ b/test/regress/1182_1.test @@ -0,0 +1,12 @@ += +2000/01/01 Test + A $1.00 + B + +test bal -> 1 +__ERROR__ +While parsing file "$FILE", line 1: +While parsing automated transaction: +> = +Error: Expected predicate after '=' +end test diff --git a/test/regress/1182_2.test b/test/regress/1182_2.test new file mode 100644 index 00000000..d3c88dd8 --- /dev/null +++ b/test/regress/1182_2.test @@ -0,0 +1,17 @@ +2000/01/01 Test + A $1.00 + B + +============ + +2000/01/02 Test + A $1.00 + B + +test bal -> 1 +__ERROR__ +While parsing file "$FILE", line 5: +While parsing automated transaction: +> ============ +Error: Expected predicate after '=' +end test |