Move commodity-related parsing code from amount.cc into commodity.cc.
This commit is contained in:
parent
42d799a1fd
commit
623e6e024c
4 changed files with 237 additions and 238 deletions
309
src/amount.cc
309
src/amount.cc
|
|
@ -799,49 +799,6 @@ void amount_t::annotate_commodity(const annotation_t& details)
|
|||
DEBUG("amounts.commodities", " Annotated amount is " << *this);
|
||||
}
|
||||
|
||||
amount_t amount_t::strip_annotations(const bool _keep_price,
|
||||
const bool _keep_date,
|
||||
const bool _keep_tag) const
|
||||
{
|
||||
if (! quantity)
|
||||
throw_(amount_error,
|
||||
"Cannot strip commodity annotations from an uninitialized amount");
|
||||
|
||||
if (! commodity().annotated ||
|
||||
(_keep_price && _keep_date && _keep_tag))
|
||||
return *this;
|
||||
|
||||
DEBUG("amounts.commodities", "Reducing commodity for amount "
|
||||
<< *this << std::endl
|
||||
<< " keep price " << _keep_price << " "
|
||||
<< " keep date " << _keep_date << " "
|
||||
<< " keep tag " << _keep_tag);
|
||||
|
||||
annotated_commodity_t& ann_comm(commodity().as_annotated());
|
||||
commodity_t * new_comm;
|
||||
|
||||
if ((_keep_price && ann_comm.details.price) ||
|
||||
(_keep_date && ann_comm.details.date) ||
|
||||
(_keep_tag && ann_comm.details.tag))
|
||||
{
|
||||
new_comm = ann_comm.parent().find_or_create
|
||||
(ann_comm.referent(),
|
||||
annotation_t(_keep_price ? ann_comm.details.price : optional<amount_t>(),
|
||||
_keep_date ? ann_comm.details.date : optional<moment_t>(),
|
||||
_keep_tag ? ann_comm.details.tag : optional<string>()));
|
||||
} else {
|
||||
new_comm = ann_comm.parent().find_or_create(ann_comm.base_symbol());
|
||||
}
|
||||
assert(new_comm);
|
||||
|
||||
amount_t t(*this);
|
||||
t.set_commodity(*new_comm);
|
||||
|
||||
DEBUG("amounts.commodities", " Stripped amount is " << t);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
bool amount_t::commodity_annotated() const
|
||||
{
|
||||
if (! quantity)
|
||||
|
|
@ -867,6 +824,25 @@ annotation_t amount_t::annotation_details() const
|
|||
return annotation_t();
|
||||
}
|
||||
|
||||
amount_t amount_t::strip_annotations(const bool _keep_price,
|
||||
const bool _keep_date,
|
||||
const bool _keep_tag) const
|
||||
{
|
||||
if (! quantity)
|
||||
throw_(amount_error,
|
||||
"Cannot strip commodity annotations from an uninitialized amount");
|
||||
|
||||
if (! commodity().annotated ||
|
||||
(_keep_price && _keep_date && _keep_tag))
|
||||
return *this;
|
||||
|
||||
amount_t t(*this);
|
||||
t.set_commodity(commodity().as_annotated().
|
||||
strip_annotations(_keep_price, _keep_date, _keep_tag));
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
void parse_quantity(std::istream& in, string& value)
|
||||
{
|
||||
|
|
@ -883,121 +859,6 @@ namespace {
|
|||
|
||||
value = buf;
|
||||
}
|
||||
|
||||
// Invalid commodity characters:
|
||||
// SPACE, TAB, NEWLINE, RETURN
|
||||
// 0-9 . , ; - + * / ^ ? : & | ! =
|
||||
// < > { } [ ] ( ) @
|
||||
|
||||
int invalid_chars[256] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||||
/* 00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
|
||||
/* 10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 20 */ 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
/* 30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
/* 40 */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 50 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0,
|
||||
/* 60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0,
|
||||
/* 80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* a0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* b0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* c0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* d0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* e0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* f0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
static void parse_commodity(std::istream& in, string& symbol)
|
||||
{
|
||||
char buf[256];
|
||||
char c = peek_next_nonws(in);
|
||||
if (c == '"') {
|
||||
in.get(c);
|
||||
READ_INTO(in, buf, 255, c, c != '"');
|
||||
if (c == '"')
|
||||
in.get(c);
|
||||
else
|
||||
throw_(amount_error, "Quoted commodity symbol lacks closing quote");
|
||||
} else {
|
||||
READ_INTO(in, buf, 255, c, ! invalid_chars[(unsigned char)c]);
|
||||
}
|
||||
symbol = buf;
|
||||
}
|
||||
|
||||
bool parse_annotations(std::istream& in, annotation_t& details)
|
||||
{
|
||||
do {
|
||||
char buf[256];
|
||||
char c = peek_next_nonws(in);
|
||||
if (c == '{') {
|
||||
if (details.price)
|
||||
throw_(amount_error, "Commodity specifies more than one price");
|
||||
|
||||
in.get(c);
|
||||
READ_INTO(in, buf, 255, c, c != '}');
|
||||
if (c == '}')
|
||||
in.get(c);
|
||||
else
|
||||
throw_(amount_error, "Commodity price lacks closing brace");
|
||||
|
||||
amount_t temp;
|
||||
temp.parse(buf, AMOUNT_PARSE_NO_MIGRATE);
|
||||
temp.in_place_reduce();
|
||||
|
||||
// Since this price will maintain its own precision, make sure
|
||||
// it is at least as large as the base commodity, since the user
|
||||
// may have only specified {$1} or something similar.
|
||||
|
||||
if (temp.has_commodity() &&
|
||||
temp.precision() < temp.commodity().precision())
|
||||
temp = temp.round(); // no need to retain individual precision
|
||||
|
||||
details.price = temp;
|
||||
}
|
||||
else if (c == '[') {
|
||||
if (details.date)
|
||||
throw_(amount_error, "Commodity specifies more than one date");
|
||||
|
||||
in.get(c);
|
||||
READ_INTO(in, buf, 255, c, c != ']');
|
||||
if (c == ']')
|
||||
in.get(c);
|
||||
else
|
||||
throw_(amount_error, "Commodity date lacks closing bracket");
|
||||
|
||||
details.date = parse_datetime(buf);
|
||||
}
|
||||
else if (c == '(') {
|
||||
if (details.tag)
|
||||
throw_(amount_error, "Commodity specifies more than one tag");
|
||||
|
||||
in.get(c);
|
||||
READ_INTO(in, buf, 255, c, c != ')');
|
||||
if (c == ')')
|
||||
in.get(c);
|
||||
else
|
||||
throw_(amount_error, "Commodity tag lacks closing parenthesis");
|
||||
|
||||
details.tag = buf;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
DEBUG("amounts.commodities",
|
||||
"Parsed commodity annotations: "
|
||||
<< " price "
|
||||
<< (details.price ? details.price->to_string() : "NONE") << " "
|
||||
<< " date "
|
||||
<< (details.date ? *details.date : moment_t()) << " "
|
||||
<< " tag "
|
||||
<< (details.tag ? *details.tag : "NONE"));
|
||||
|
||||
return details;
|
||||
}
|
||||
}
|
||||
|
||||
void amount_t::parse(std::istream& in, flags_t flags)
|
||||
|
|
@ -1029,16 +890,16 @@ void amount_t::parse(std::istream& in, flags_t flags)
|
|||
if (std::isspace(n))
|
||||
comm_flags |= COMMODITY_STYLE_SEPARATED;
|
||||
|
||||
parse_commodity(in, symbol);
|
||||
commodity_t::parse_symbol(in, symbol);
|
||||
|
||||
if (! symbol.empty())
|
||||
comm_flags |= COMMODITY_STYLE_SUFFIXED;
|
||||
|
||||
if (! in.eof() && ((n = in.peek()) != '\n'))
|
||||
parse_annotations(in, details);
|
||||
details.parse(in);
|
||||
}
|
||||
} else {
|
||||
parse_commodity(in, symbol);
|
||||
commodity_t::parse_symbol(in, symbol);
|
||||
|
||||
if (! in.eof() && ((n = in.peek()) != '\n')) {
|
||||
if (std::isspace(in.peek()))
|
||||
|
|
@ -1047,7 +908,7 @@ void amount_t::parse(std::istream& in, flags_t flags)
|
|||
parse_quantity(in, quant);
|
||||
|
||||
if (! quant.empty() && ! in.eof() && ((n = in.peek()) != '\n'))
|
||||
parse_annotations(in, details);
|
||||
details.parse(in);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1345,8 +1206,18 @@ void amount_t::print(std::ostream& _out, bool omit_commodity,
|
|||
}
|
||||
|
||||
|
||||
namespace {
|
||||
char * bigints;
|
||||
char * bigints_next;
|
||||
uint_fast32_t bigints_index;
|
||||
uint_fast32_t bigints_count;
|
||||
char buf[4096];
|
||||
}
|
||||
|
||||
void amount_t::read(std::istream& in)
|
||||
{
|
||||
// Read in the commodity for this amount
|
||||
|
||||
commodity_t::ident_t ident;
|
||||
read_binary_long(in, ident);
|
||||
if (ident == 0xffffffff)
|
||||
|
|
@ -1358,11 +1229,44 @@ void amount_t::read(std::istream& in)
|
|||
assert(commodity_);
|
||||
}
|
||||
|
||||
read_quantity(in);
|
||||
// Read in the quantity
|
||||
|
||||
char byte;
|
||||
in.read(&byte, sizeof(byte));
|
||||
|
||||
if (byte == 0) {
|
||||
quantity = NULL;
|
||||
}
|
||||
else if (byte == 1) {
|
||||
quantity = new bigint_t;
|
||||
|
||||
unsigned short len;
|
||||
in.read((char *)&len, sizeof(len));
|
||||
assert(len < 4096);
|
||||
in.read(buf, len);
|
||||
mpz_import(MPZ(quantity), len / sizeof(short), 1, sizeof(short),
|
||||
0, 0, buf);
|
||||
|
||||
char negative;
|
||||
in.read(&negative, sizeof(negative));
|
||||
if (negative)
|
||||
mpz_neg(MPZ(quantity), MPZ(quantity));
|
||||
|
||||
in.read((char *)&quantity->prec, sizeof(quantity->prec));
|
||||
|
||||
bigint_t::flags_t tflags;
|
||||
in.read((char *)&tflags, sizeof(tflags));
|
||||
quantity->set_flags(tflags);
|
||||
}
|
||||
else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void amount_t::read(char *& data)
|
||||
{
|
||||
// Read in the commodity for this amount
|
||||
|
||||
commodity_t::ident_t ident;
|
||||
read_binary_long(data, ident);
|
||||
if (ident == 0xffffffff)
|
||||
|
|
@ -1374,31 +1278,8 @@ void amount_t::read(char *& data)
|
|||
assert(commodity_);
|
||||
}
|
||||
|
||||
read_quantity(data);
|
||||
}
|
||||
// Read in the quantity
|
||||
|
||||
void amount_t::write(std::ostream& out) const
|
||||
{
|
||||
if (! quantity)
|
||||
throw_(amount_error, "Cannot serialize an uninitialized amount");
|
||||
|
||||
if (commodity_)
|
||||
write_binary_long(out, commodity_->ident);
|
||||
else
|
||||
write_binary_long<commodity_t::ident_t>(out, 0xffffffff);
|
||||
|
||||
write_quantity(out);
|
||||
}
|
||||
|
||||
#ifndef THREADSAFE
|
||||
static char * bigints;
|
||||
static char * bigints_next;
|
||||
static uint_fast32_t bigints_index;
|
||||
static uint_fast32_t bigints_count;
|
||||
#endif
|
||||
|
||||
void amount_t::read_quantity(char *& data)
|
||||
{
|
||||
char byte = *data++;;
|
||||
|
||||
if (byte == 0) {
|
||||
|
|
@ -1434,49 +1315,21 @@ void amount_t::read_quantity(char *& data)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef THREADSAFE
|
||||
static char buf[4096];
|
||||
#endif
|
||||
|
||||
void amount_t::read_quantity(std::istream& in)
|
||||
void amount_t::write(std::ostream& out) const
|
||||
{
|
||||
// Write out the commodity for this amount
|
||||
|
||||
if (! quantity)
|
||||
throw_(amount_error, "Cannot serialize an uninitialized amount");
|
||||
|
||||
if (commodity_)
|
||||
write_binary_long(out, commodity_->ident);
|
||||
else
|
||||
write_binary_long<commodity_t::ident_t>(out, 0xffffffff);
|
||||
|
||||
// Write out the quantity
|
||||
|
||||
char byte;
|
||||
in.read(&byte, sizeof(byte));
|
||||
|
||||
if (byte == 0) {
|
||||
quantity = NULL;
|
||||
}
|
||||
else if (byte == 1) {
|
||||
quantity = new bigint_t;
|
||||
|
||||
unsigned short len;
|
||||
in.read((char *)&len, sizeof(len));
|
||||
assert(len < 4096);
|
||||
in.read(buf, len);
|
||||
mpz_import(MPZ(quantity), len / sizeof(short), 1, sizeof(short),
|
||||
0, 0, buf);
|
||||
|
||||
char negative;
|
||||
in.read(&negative, sizeof(negative));
|
||||
if (negative)
|
||||
mpz_neg(MPZ(quantity), MPZ(quantity));
|
||||
|
||||
in.read((char *)&quantity->prec, sizeof(quantity->prec));
|
||||
|
||||
bigint_t::flags_t tflags;
|
||||
in.read((char *)&tflags, sizeof(tflags));
|
||||
quantity->set_flags(tflags);
|
||||
}
|
||||
else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void amount_t::write_quantity(std::ostream& out) const
|
||||
{
|
||||
char byte;
|
||||
|
||||
assert(quantity);
|
||||
|
||||
if (quantity->index == 0) {
|
||||
quantity->index = ++bigints_index;
|
||||
|
|
|
|||
|
|
@ -621,15 +621,8 @@ public:
|
|||
*/
|
||||
void read(std::istream& in);
|
||||
void read(char *& data);
|
||||
|
||||
void write(std::ostream& out) const;
|
||||
|
||||
private:
|
||||
void read_quantity(std::istream& in);
|
||||
void read_quantity(char *& data);
|
||||
void write_quantity(std::ostream& out) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Debugging methods. There are two methods defined to help with
|
||||
* debugging:
|
||||
|
|
|
|||
143
src/commodity.cc
143
src/commodity.cc
|
|
@ -40,6 +40,7 @@
|
|||
*/
|
||||
|
||||
#include "amount.h"
|
||||
#include "parser.h" // for parsing utility functions
|
||||
|
||||
namespace ledger {
|
||||
|
||||
|
|
@ -143,6 +144,48 @@ bool commodity_t::symbol_needs_quotes(const string& symbol)
|
|||
return false;
|
||||
}
|
||||
|
||||
void commodity_t::parse_symbol(std::istream& in, string& symbol)
|
||||
{
|
||||
// Invalid commodity characters:
|
||||
// SPACE, TAB, NEWLINE, RETURN
|
||||
// 0-9 . , ; - + * / ^ ? : & | ! =
|
||||
// < > { } [ ] ( ) @
|
||||
|
||||
static int invalid_chars[256] = {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||||
/* 00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
|
||||
/* 10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 20 */ 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
/* 30 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
/* 40 */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 50 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0,
|
||||
/* 60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0,
|
||||
/* 80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* a0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* b0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* c0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* d0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* e0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* f0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
char buf[256];
|
||||
char c = peek_next_nonws(in);
|
||||
if (c == '"') {
|
||||
in.get(c);
|
||||
READ_INTO(in, buf, 255, c, c != '"');
|
||||
if (c == '"')
|
||||
in.get(c);
|
||||
else
|
||||
throw_(amount_error, "Quoted commodity symbol lacks closing quote");
|
||||
} else {
|
||||
READ_INTO(in, buf, 255, c, ! invalid_chars[(unsigned char)c]);
|
||||
}
|
||||
symbol = buf;
|
||||
}
|
||||
|
||||
bool commodity_t::valid() const
|
||||
{
|
||||
if (symbol().empty() && this != parent().null_commodity) {
|
||||
|
|
@ -164,6 +207,71 @@ bool commodity_t::valid() const
|
|||
return true;
|
||||
}
|
||||
|
||||
void annotation_t::parse(std::istream& in)
|
||||
{
|
||||
do {
|
||||
char buf[256];
|
||||
char c = peek_next_nonws(in);
|
||||
if (c == '{') {
|
||||
if (price)
|
||||
throw_(amount_error, "Commodity specifies more than one price");
|
||||
|
||||
in.get(c);
|
||||
READ_INTO(in, buf, 255, c, c != '}');
|
||||
if (c == '}')
|
||||
in.get(c);
|
||||
else
|
||||
throw_(amount_error, "Commodity price lacks closing brace");
|
||||
|
||||
amount_t temp;
|
||||
temp.parse(buf, AMOUNT_PARSE_NO_MIGRATE);
|
||||
temp.in_place_reduce();
|
||||
|
||||
// Since this price will maintain its own precision, make sure
|
||||
// it is at least as large as the base commodity, since the user
|
||||
// may have only specified {$1} or something similar.
|
||||
|
||||
if (temp.has_commodity() &&
|
||||
temp.precision() < temp.commodity().precision())
|
||||
temp = temp.round(); // no need to retain individual precision
|
||||
|
||||
price = temp;
|
||||
}
|
||||
else if (c == '[') {
|
||||
if (date)
|
||||
throw_(amount_error, "Commodity specifies more than one date");
|
||||
|
||||
in.get(c);
|
||||
READ_INTO(in, buf, 255, c, c != ']');
|
||||
if (c == ']')
|
||||
in.get(c);
|
||||
else
|
||||
throw_(amount_error, "Commodity date lacks closing bracket");
|
||||
|
||||
date = parse_datetime(buf);
|
||||
}
|
||||
else if (c == '(') {
|
||||
if (tag)
|
||||
throw_(amount_error, "Commodity specifies more than one tag");
|
||||
|
||||
in.get(c);
|
||||
READ_INTO(in, buf, 255, c, c != ')');
|
||||
if (c == ')')
|
||||
in.get(c);
|
||||
else
|
||||
throw_(amount_error, "Commodity tag lacks closing parenthesis");
|
||||
|
||||
tag = buf;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
DEBUG("amounts.commodities",
|
||||
"Parsed commodity annotations: " << std::endl << *this);
|
||||
}
|
||||
|
||||
bool annotated_commodity_t::operator==(const commodity_t& comm) const
|
||||
{
|
||||
// If the base commodities don't match, the game's up.
|
||||
|
|
@ -180,9 +288,38 @@ bool annotated_commodity_t::operator==(const commodity_t& comm) const
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
annotated_commodity_t::write_annotations(std::ostream& out,
|
||||
const annotation_t& info)
|
||||
commodity_t&
|
||||
annotated_commodity_t::strip_annotations(const bool _keep_price,
|
||||
const bool _keep_date,
|
||||
const bool _keep_tag)
|
||||
{
|
||||
DEBUG("commodity.annotated.strip",
|
||||
"Reducing commodity " << *this << std::endl
|
||||
<< " keep price " << _keep_price << " "
|
||||
<< " keep date " << _keep_date << " "
|
||||
<< " keep tag " << _keep_tag);
|
||||
|
||||
commodity_t * new_comm;
|
||||
|
||||
if ((_keep_price && details.price) ||
|
||||
(_keep_date && details.date) ||
|
||||
(_keep_tag && details.tag))
|
||||
{
|
||||
new_comm = parent().find_or_create
|
||||
(referent(),
|
||||
annotation_t(_keep_price ? details.price : optional<amount_t>(),
|
||||
_keep_date ? details.date : optional<moment_t>(),
|
||||
_keep_tag ? details.tag : optional<string>()));
|
||||
} else {
|
||||
new_comm = parent().find_or_create(base_symbol());
|
||||
}
|
||||
|
||||
assert(new_comm);
|
||||
return *new_comm;
|
||||
}
|
||||
|
||||
void annotated_commodity_t::write_annotations(std::ostream& out,
|
||||
const annotation_t& info)
|
||||
{
|
||||
if (info.price)
|
||||
out << " {" << *info.price << '}';
|
||||
|
|
|
|||
|
|
@ -190,10 +190,21 @@ public:
|
|||
optional<amount_t> value(const optional<moment_t>& moment =
|
||||
optional<moment_t>());
|
||||
|
||||
static void parse_symbol(std::istream& in, string& symbol);
|
||||
static string parse_symbol(std::istream& in) {
|
||||
string temp;
|
||||
parse_symbol(in, temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void print(std::ostream& out) const {
|
||||
out << symbol();
|
||||
}
|
||||
|
||||
void read(std::istream& in);
|
||||
void read(char *& data);
|
||||
void write(std::ostream& out) const;
|
||||
|
||||
bool valid() const;
|
||||
};
|
||||
|
||||
|
|
@ -224,6 +235,7 @@ struct annotation_t : public equality_comparable<annotation_t>
|
|||
tag == rhs.tag);
|
||||
}
|
||||
|
||||
void parse(std::istream& in);
|
||||
void print(std::ostream& out) const {
|
||||
out << "price " << (price ? price->to_string() : "NONE") << " "
|
||||
<< "date " << (date ? *date : moment_t()) << " "
|
||||
|
|
@ -273,6 +285,10 @@ public:
|
|||
return *ptr;
|
||||
}
|
||||
|
||||
commodity_t& strip_annotations(const bool _keep_price,
|
||||
const bool _keep_date,
|
||||
const bool _keep_tag);
|
||||
|
||||
void write_annotations(std::ostream& out) const {
|
||||
annotated_commodity_t::write_annotations(out, details);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue