added inclusion specifiers: -z june, -z 2004, -z "monthly in 2003", etc.
This commit is contained in:
parent
5ab3b21396
commit
9d1bdd0989
4 changed files with 129 additions and 59 deletions
10
config.cc
10
config.cc
|
|
@ -160,23 +160,23 @@ OPT_BEGIN(set_price, "p:") {
|
|||
OPT_BEGIN(begin_date, "b:") {
|
||||
if (! config->predicate.empty())
|
||||
config->predicate += "&";
|
||||
config->predicate += "(d>=[";
|
||||
config->predicate += "d>=[";
|
||||
config->predicate += optarg;
|
||||
config->predicate += "])";
|
||||
config->predicate += "]";
|
||||
} OPT_END(begin_date);
|
||||
|
||||
OPT_BEGIN(end_date, "e:") {
|
||||
if (! config->predicate.empty())
|
||||
config->predicate += "&";
|
||||
config->predicate += "(d<[";
|
||||
config->predicate += "d<[";
|
||||
config->predicate += optarg;
|
||||
config->predicate += "])";
|
||||
config->predicate += "]";
|
||||
} OPT_END(end_date);
|
||||
|
||||
OPT_BEGIN(current, "c") {
|
||||
if (! config->predicate.empty())
|
||||
config->predicate += "&";
|
||||
config->predicate += "(d<=N)";
|
||||
config->predicate += "d<=N";
|
||||
} OPT_END(current);
|
||||
|
||||
OPT_BEGIN(cleared, "C") {
|
||||
|
|
|
|||
122
datetime.cc
122
datetime.cc
|
|
@ -1,4 +1,5 @@
|
|||
#include "datetime.h"
|
||||
#include "error.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
|
|
@ -51,56 +52,109 @@ std::time_t interval_t::increment(const std::time_t moment)
|
|||
return then + seconds;
|
||||
}
|
||||
|
||||
interval_t * interval_t::parse(std::istream& in)
|
||||
static void parse_inclusion_specifier(const std::string& word,
|
||||
std::time_t * begin,
|
||||
std::time_t * end)
|
||||
{
|
||||
struct std::tm when;
|
||||
|
||||
if (! parse_date_mask(word.c_str(), &when))
|
||||
throw interval_expr_error("Could not parse 'in' date mask");
|
||||
|
||||
when.tm_hour = 0;
|
||||
when.tm_min = 0;
|
||||
when.tm_sec = 0;
|
||||
|
||||
bool saw_year = true;
|
||||
bool saw_mon = true;
|
||||
|
||||
if (when.tm_year == -1) {
|
||||
when.tm_year = now_tm->tm_year;
|
||||
saw_year = false;
|
||||
}
|
||||
if (when.tm_mon == -1) {
|
||||
when.tm_mon = 0;
|
||||
saw_mon = false;
|
||||
}
|
||||
if (when.tm_mday == -1)
|
||||
when.tm_mday = 1;
|
||||
|
||||
*begin = std::mktime(&when);
|
||||
*end = interval_t(0, saw_mon ? 1 : 0, saw_year ? 1 : 0).increment(*begin);
|
||||
}
|
||||
|
||||
interval_t * interval_t::parse(std::istream& in,
|
||||
std::time_t * begin,
|
||||
std::time_t * end)
|
||||
{
|
||||
unsigned long years = 0;
|
||||
unsigned long months = 0;
|
||||
unsigned long seconds = 0;
|
||||
|
||||
std::string word;
|
||||
in >> word;
|
||||
if (word == "every") {
|
||||
while (! in.eof()) {
|
||||
in >> word;
|
||||
if (std::isdigit(word[0])) {
|
||||
int quantity = std::atol(word.c_str());
|
||||
if (word == "every") {
|
||||
in >> word;
|
||||
if (word == "days")
|
||||
seconds = 86400 * quantity;
|
||||
else if (word == "weeks")
|
||||
seconds = 7 * 86400 * quantity;
|
||||
else if (word == "months")
|
||||
months = quantity;
|
||||
else if (word == "quarters")
|
||||
months = 3 * quantity;
|
||||
else if (word == "years")
|
||||
years = quantity;
|
||||
if (std::isdigit(word[0])) {
|
||||
int quantity = std::atol(word.c_str());
|
||||
in >> word;
|
||||
if (word == "days")
|
||||
seconds = 86400 * quantity;
|
||||
else if (word == "weeks")
|
||||
seconds = 7 * 86400 * quantity;
|
||||
else if (word == "months")
|
||||
months = quantity;
|
||||
else if (word == "quarters")
|
||||
months = 3 * quantity;
|
||||
else if (word == "years")
|
||||
years = quantity;
|
||||
}
|
||||
else if (word == "day")
|
||||
seconds = 86400;
|
||||
else if (word == "week")
|
||||
seconds = 7 * 86400;
|
||||
else if (word == "monthly")
|
||||
months = 1;
|
||||
else if (word == "quarter")
|
||||
months = 3;
|
||||
else if (word == "year")
|
||||
years = 1;
|
||||
}
|
||||
else if (word == "day")
|
||||
else if (word == "daily")
|
||||
seconds = 86400;
|
||||
else if (word == "week")
|
||||
else if (word == "weekly")
|
||||
seconds = 7 * 86400;
|
||||
else if (word == "biweekly")
|
||||
seconds = 14 * 86400;
|
||||
else if (word == "monthly")
|
||||
months = 1;
|
||||
else if (word == "quarter")
|
||||
else if (word == "bimonthly")
|
||||
months = 2;
|
||||
else if (word == "quarterly")
|
||||
months = 3;
|
||||
else if (word == "year")
|
||||
else if (word == "yearly")
|
||||
years = 1;
|
||||
else if (word == "in") {
|
||||
in >> word;
|
||||
parse_inclusion_specifier(word, begin, end);
|
||||
}
|
||||
else if (word == "from") {
|
||||
in >> word;
|
||||
if (! parse_date(word.c_str(), begin))
|
||||
throw interval_expr_error("Could not parse 'from' date");
|
||||
if (! in.eof())
|
||||
in >> word;
|
||||
}
|
||||
else if (word == "to") {
|
||||
in >> word;
|
||||
if (! parse_date(word.c_str(), end))
|
||||
throw interval_expr_error("Could not parse 'to' date");
|
||||
}
|
||||
else {
|
||||
parse_inclusion_specifier(word, begin, end);
|
||||
}
|
||||
}
|
||||
else if (word == "daily")
|
||||
seconds = 86400;
|
||||
else if (word == "weekly")
|
||||
seconds = 7 * 86400;
|
||||
else if (word == "biweekly")
|
||||
seconds = 14 * 86400;
|
||||
else if (word == "monthly")
|
||||
months = 1;
|
||||
else if (word == "bimonthly")
|
||||
months = 2;
|
||||
else if (word == "quarterly")
|
||||
months = 3;
|
||||
else if (word == "yearly")
|
||||
years = 1;
|
||||
|
||||
return new interval_t(seconds, months, years);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ struct interval_t
|
|||
|
||||
std::time_t increment(const std::time_t);
|
||||
|
||||
static interval_t * parse(std::istream& in);
|
||||
static interval_t * parse(std::istream& in, std::time_t * begin,
|
||||
std::time_t * end);
|
||||
};
|
||||
|
||||
extern std::time_t now;
|
||||
|
|
|
|||
53
main.cc
53
main.cc
|
|
@ -295,12 +295,6 @@ int main(int argc, char * argv[], char * envp[])
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
DEBUG_PRINT("ledger.main.predicates", "predicate: " << config->predicate);
|
||||
DEBUG_PRINT("ledger.main.predicates",
|
||||
"disp-pred: " << config->display_predicate);
|
||||
#endif
|
||||
|
||||
// Compile the sorting criteria
|
||||
|
||||
std::auto_ptr<value_expr_t> sort_order;
|
||||
|
|
@ -418,26 +412,47 @@ int main(int argc, char * argv[], char * envp[])
|
|||
#define OUT() (output_stream.get() ? *output_stream : std::cout)
|
||||
|
||||
if (! config->interval_text.empty()) {
|
||||
std::istringstream stream(config->interval_text);
|
||||
report_interval.reset(interval_t::parse(stream));
|
||||
if (! stream.eof()) {
|
||||
std::string word;
|
||||
stream >> word;
|
||||
if (word == "from") {
|
||||
stream >> word;
|
||||
if (! parse_date(word.c_str(), &interval_begin)) {
|
||||
std::cerr << "Error in report interval: "
|
||||
<< "Could not parse 'from' date"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
try {
|
||||
std::istringstream stream(config->interval_text);
|
||||
std::time_t begin = -1, end = -1;
|
||||
report_interval.reset(interval_t::parse(stream, &begin, &end));
|
||||
if (report_interval->seconds == 0 &&
|
||||
report_interval->months == 0 &&
|
||||
report_interval->years == 0)
|
||||
report_interval.release();
|
||||
|
||||
if (begin != -1) {
|
||||
if (! config->predicate.empty())
|
||||
config->predicate += "&";
|
||||
char buf[32];
|
||||
std::sprintf(buf, "d>=%lu", begin);
|
||||
config->predicate += buf;
|
||||
}
|
||||
|
||||
if (end != -1) {
|
||||
if (! config->predicate.empty())
|
||||
config->predicate += "&";
|
||||
char buf[32];
|
||||
std::sprintf(buf, "d<%lu", end);
|
||||
config->predicate += buf;
|
||||
}
|
||||
}
|
||||
catch (const interval_expr_error& err) {
|
||||
std::cerr << "Error in interval (-z) specifier: " << err.what()
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (! config->date_format.empty())
|
||||
format_t::date_format = config->date_format;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
DEBUG_PRINT("ledger.main.predicates", "predicate: " << config->predicate);
|
||||
DEBUG_PRINT("ledger.main.predicates",
|
||||
"disp-pred: " << config->display_predicate);
|
||||
#endif
|
||||
|
||||
// Walk the entries based on the report type and the options
|
||||
|
||||
TIMER_START(report_gen);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue