summaryrefslogtreecommitdiff
path: root/amount.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2003-10-02 05:04:38 +0000
committerJohn Wiegley <johnw@newartisans.com>2003-10-02 05:04:38 +0000
commit3cfae2794784c1629dd98c0b600b2731e27a3f57 (patch)
tree5339db0e7df4b6f925788270d8c805111e729ae1 /amount.cc
parentbfff951c310b0b1b4f2ddaf3d69549bd3bac2717 (diff)
downloadfork-ledger-3cfae2794784c1629dd98c0b600b2731e27a3f57.tar.gz
fork-ledger-3cfae2794784c1629dd98c0b600b2731e27a3f57.tar.bz2
fork-ledger-3cfae2794784c1629dd98c0b600b2731e27a3f57.zip
*** empty log message ***
Diffstat (limited to 'amount.cc')
-rw-r--r--amount.cc55
1 files changed, 33 insertions, 22 deletions
diff --git a/amount.cc b/amount.cc
index 6098ebde..8d1752a0 100644
--- a/amount.cc
+++ b/amount.cc
@@ -1,20 +1,24 @@
-#include <sstream>
+#include "ledger.h"
+#include <sstream>
#include <gmp.h> // GNU multi-precision library
-#include "ledger.h"
-
namespace ledger {
#define MAX_PRECISION 10 // must be 2 or higher
//////////////////////////////////////////////////////////////////////
//
-// The `amount' structure. Every transaction has an associated amount,
-// which is represented by this structure. `amount' uses the GNU
-// multi-precision library, allowing for arbitrarily large amounts.
-// Each amount is a quantity of commodity at a certain price; the
-// default commodity is the US dollar, with a price of 1.00.
+// The `amount' structure. Every transaction has an associated
+// amount, which is represented by this structure. `amount' uses the
+// GNU multi-precision library, allowing for arbitrarily large
+// amounts. Each amount is a quantity of a certain commodity, with
+// an optional price per-unit for that commodity at the time the
+// amount was stated.
+//
+// To create an amount, for example:
+//
+// amount * cost = create_amount("50.2 MSFT @ $100.50");
//
class gmp_amount : public amount
@@ -57,20 +61,21 @@ class gmp_amount : public amount
}
virtual void set_value(const amount * val);
- virtual operator bool() const;
+ virtual bool is_zero() const;
virtual void negate() {
mpz_ui_sub(quantity, 0, quantity);
}
virtual void credit(const amount * other);
- virtual void parse(const char * num);
- virtual std::string as_str(bool full_prec) const;
+ virtual void parse(const std::string& num);
+ virtual const std::string as_str(bool full_prec) const;
- friend amount * create_amount(const char * value, const amount * cost);
+ friend amount * create_amount(const std::string& value,
+ const amount * cost);
};
-amount * create_amount(const char * value, const amount * cost)
+amount * create_amount(const std::string& value, const amount * cost)
{
gmp_amount * a = new gmp_amount();
a->parse(value);
@@ -277,7 +282,7 @@ void gmp_amount::set_value(const amount * val)
mpz_clear(addend);
}
-gmp_amount::operator bool() const
+bool gmp_amount::is_zero() const
{
mpz_t copy;
mpz_init_set(copy, quantity);
@@ -286,7 +291,7 @@ gmp_amount::operator bool() const
round(copy, copy, quantity_comm->precision);
bool zero = mpz_sgn(copy) == 0;
mpz_clear(copy);
- return ! zero;
+ return zero;
}
static std::string amount_to_str(const commodity * comm, const mpz_t val,
@@ -416,7 +421,7 @@ static std::string amount_to_str(const commodity * comm, const mpz_t val,
return s.str();
}
-std::string gmp_amount::as_str(bool full_prec) const
+const std::string gmp_amount::as_str(bool full_prec) const
{
std::ostringstream s;
@@ -430,8 +435,11 @@ std::string gmp_amount::as_str(bool full_prec) const
return s.str();
}
-static void parse_number(mpz_t out, const char * num, commodity * comm)
+static void parse_number(mpz_t out, const std::string& number,
+ commodity * comm)
{
+ const char * num = number.c_str();
+
if (char * p = std::strchr(num, '/')) {
mpz_t numer;
mpz_t val;
@@ -559,7 +567,7 @@ static commodity * parse_amount(mpz_t out, const char * num,
return comm;
}
-void gmp_amount::parse(const char * num)
+void gmp_amount::parse(const std::string& number)
{
// Compile the regular expression used for parsing amounts
static pcre * re = NULL;
@@ -576,17 +584,20 @@ void gmp_amount::parse(const char * num)
int ovector[60];
int matched;
- matched = pcre_exec(re, NULL, num, std::strlen(num), 0, 0, ovector, 60);
+ matched = pcre_exec(re, NULL, number.c_str(), number.length(),
+ 0, 0, ovector, 60);
if (matched > 0) {
- quantity_comm = parse_amount(quantity, num, matched, ovector, 1);
+ quantity_comm = parse_amount(quantity, number.c_str(), matched,
+ ovector, 1);
// If the following succeeded, then we have a price
if (ovector[8 * 2] >= 0) {
priced = true;
- price_comm = parse_amount(price, num, matched, ovector, 9);
+ price_comm = parse_amount(price, number.c_str(), matched,
+ ovector, 9);
}
} else {
- std::cerr << "Failed to parse amount: " << num << std::endl;
+ std::cerr << "Failed to parse amount: " << number << std::endl;
}
}