summaryrefslogtreecommitdiffstats
path: root/gold/ledger/lib/balance
diff options
context:
space:
mode:
Diffstat (limited to 'gold/ledger/lib/balance')
-rwxr-xr-xgold/ledger/lib/balance88
1 files changed, 88 insertions, 0 deletions
diff --git a/gold/ledger/lib/balance b/gold/ledger/lib/balance
new file mode 100755
index 00000000..deb50d15
--- /dev/null
+++ b/gold/ledger/lib/balance
@@ -0,0 +1,88 @@
+#! /usr/bin/awk -f
+#
+# ledger balance calculator
+#
+# usage:
+# [colorize=false] [scale=N] //ledger/lib/balance LEDGER_FILE...
+# [colorize=false] [scale=N] //ledger/lib/balance < LEDGER_FILE
+#
+# description:
+# The ledger balance calculator computes the balance of each account it
+# encounters in the provided ledger files.
+#
+# example:
+# //ledger/lib/balance < //cholerab/ledger-spec.markdown
+#
+# see also:
+# //cholerab/ledger-spec.markdown (ledger file format)
+#
+
+BEGIN {
+ colorize = ENVIRON["colorize"] == "" || ENVIRON["colorize"] == "true"
+ # TODO use bc for arbitrary precision arithmetic
+ scale = ENVIRON["scale"]
+}
+
+/^[[:space:]]*[0-9]+-[0-9][0-9]-[0-9][0-9]/{
+ tx($2, $3, $4, $5)
+}
+
+END {
+ display_accounts()
+}
+
+function tx (dst, src, amt, u) {
+ withdraw(src, amt, u)
+ deposit(dst, amt, u)
+}
+
+function deposit (name, amt, u) {
+ accounts[name][u] += amt
+}
+
+function withdraw (name, amt, u) {
+ accounts[name][u] -= amt
+}
+
+function display_accounts() {
+ max_name_len = 0
+ for (name in accounts) {
+ if (length(name) > max_name_len) {
+ max_name_len = length(name)
+ }
+ }
+
+ max_balance_len = 0
+ for (name in accounts) {
+ for (u in accounts[name]) {
+ n = length(int(accounts[name][u]))
+ if (n > max_balance_len) {
+ max_balance_len = n
+ }
+ }
+ }
+ if (scale > 0) {
+ max_balance_len += length(".") + scale
+ }
+
+ for (name in accounts) {
+ for (u in accounts[name]) {
+ balance = accounts[name][u]
+ if (balance == 0) {
+ continue
+ }
+
+ fmt = "NAME BALANCE UNIT\n"
+
+ if (colorize) {
+ sub("BALANCE", "[" (balance < 0 ? 31 : 32) "m&", fmt)
+ }
+
+ sub("NAME", "%-" max_name_len "s", fmt)
+ sub("BALANCE", "%" max_balance_len "." scale "f", fmt)
+ sub("UNIT", "%s", fmt)
+
+ printf fmt, name, balance, u
+ }
+ }
+}