summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--amount.cc38
-rw-r--r--config.cc2
-rw-r--r--format.cc59
-rw-r--r--option.cc21
-rw-r--r--textual.cc5
-rw-r--r--valexpr.cc71
-rw-r--r--valexpr.h2
8 files changed, 86 insertions, 118 deletions
diff --git a/Makefile b/Makefile
index 2f5eaa65..0b7ea490 100644
--- a/Makefile
+++ b/Makefile
@@ -42,12 +42,6 @@ all: make.deps ledger
docs: ledger.info ledger.pdf
-install:
- make clean
- make DFLAGS="-O3 -fomit-frame-pointer"
- cp ledger $(HOME)/bin
- strip $(HOME)/bin/ledger
-
libledger.a: $(OBJS)
ar rv $@ $?
ranlib $@
diff --git a/amount.cc b/amount.cc
index 9f8c78f2..8aaab7d9 100644
--- a/amount.cc
+++ b/amount.cc
@@ -1,6 +1,5 @@
-#include "amount.h"
-
-#include <list>
+#include "ledger.h"
+#include "util.h"
#include "gmp.h"
@@ -585,43 +584,30 @@ static inline char peek_next_nonws(std::istream& in)
void parse_quantity(std::istream& in, std::string& value)
{
+ static char buf[256];
char c = peek_next_nonws(in);
- while (std::isdigit(c) || c == '-' || c == '.' || c == ',') {
- in.get(c);
- if (in.eof())
- break;
- value += c;
- c = in.peek();
- }
+ READ_INTO(in, buf, 256, c,
+ std::isdigit(c) || c == '-' || c == '.' || c == ',');
+ value = buf;
}
void parse_commodity(std::istream& in, std::string& symbol)
{
+ static char buf[256];
+
char c = peek_next_nonws(in);
if (c == '"') {
in.get(c);
- c = in.peek();
- while (! in.eof() && c != '"') {
- in.get(c);
- if (c == '\\')
- in.get(c);
- symbol += c;
- c = in.peek();
- }
-
+ READ_INTO(in, buf, 256, c, c != '"');
if (c == '"')
in.get(c);
else
assert(0);
} else {
- while (! std::isspace(c) && ! std::isdigit(c) && c != '-' && c != '.') {
- in.get(c);
- if (in.eof())
- break;
- symbol += c;
- c = in.peek();
- }
+ READ_INTO(in, buf, 256, c, ! std::isspace(c) && ! std::isdigit(c) &&
+ c != '-' && c != '.');
}
+ symbol = buf;
}
void amount_t::parse(std::istream& in)
diff --git a/config.cc b/config.cc
index 06e6f4a7..99c4d4b4 100644
--- a/config.cc
+++ b/config.cc
@@ -20,8 +20,6 @@ config_t::config_t()
{
if (const char * p = std::getenv("HOME"))
init_file = cache_file = price_db = p;
- else
- init_file = cache_file = price_db = "";
init_file += "/.ledgerrc";
cache_file += "/.ledger";
diff --git a/format.cc b/format.cc
index ec259a19..12acc03e 100644
--- a/format.cc
+++ b/format.cc
@@ -47,7 +47,9 @@ element_t * format_t::parse_elements(const std::string& fmt)
{
element_t * result = NULL;
element_t * current = NULL;
- std::string str;
+
+ static char buf[1024];
+ char * q = buf;
for (const char * p = fmt.c_str(); *p; p++) {
if (*p == '%') {
@@ -58,10 +60,10 @@ element_t * format_t::parse_elements(const std::string& fmt)
current = current->next;
}
- if (! str.empty()) {
+ if (q != buf) {
current->type = element_t::STRING;
- current->chars = str;
- str = "";
+ current->chars = std::string(buf, q);
+ q = buf;
current->next = new element_t;
current = current->next;
@@ -73,22 +75,23 @@ element_t * format_t::parse_elements(const std::string& fmt)
++p;
}
- std::string num;
- while (*p && std::isdigit(*p))
- num += *p++;
- if (! num.empty())
- current->min_width = std::atol(num.c_str());
+ int num = 0;
+ while (*p && std::isdigit(*p)) {
+ num *= 10;
+ num += *p++ - '0';
+ }
+ current->min_width = num;
if (*p == '.') {
++p;
- num = "";
- while (*p && std::isdigit(*p))
- num += *p++;
- if (! num.empty()) {
- current->max_width = std::atol(num.c_str());
- if (current->min_width == 0)
- current->min_width = current->max_width;
+ num = 0;
+ while (*p && std::isdigit(*p)) {
+ num *= 10;
+ num += *p++ - '0';
}
+ current->max_width = num;
+ if (current->min_width == 0)
+ current->min_width = current->max_width;
}
switch (*p) {
@@ -97,29 +100,31 @@ element_t * format_t::parse_elements(const std::string& fmt)
current->chars = "%";
break;
- case '(':
+ case '(': {
++p;
- num = "";
+ const char * b = p;
while (*p && *p != ')')
- num += *p++;
+ p++;
if (*p != ')')
throw format_error("Missing ')'");
current->type = element_t::VALUE_EXPR;
- current->val_expr = parse_value_expr(num);
+ current->val_expr = parse_value_expr(std::string(b, p));
break;
+ }
- case '[':
+ case '[': {
++p;
- num = "";
+ const char * b = p;
while (*p && *p != ']')
- num += *p++;
+ p++;
if (*p != ']')
throw format_error("Missing ']'");
current->type = element_t::DATE_STRING;
- current->chars = num;
+ current->chars = std::string(b, p);
break;
+ }
case 'D':
current->type = element_t::DATE_STRING;
@@ -137,11 +142,11 @@ element_t * format_t::parse_elements(const std::string& fmt)
case '_': current->type = element_t::SPACER; break;
}
} else {
- str += *p;
+ *q++ = *p;
}
}
- if (! str.empty()) {
+ if (q != buf) {
if (! result) {
current = result = new element_t;
} else {
@@ -149,7 +154,7 @@ element_t * format_t::parse_elements(const std::string& fmt)
current = current->next;
}
current->type = element_t::STRING;
- current->chars = str;
+ current->chars = std::string(buf, q);
}
return result;
diff --git a/option.cc b/option.cc
index ec55d41e..46cfbebe 100644
--- a/option.cc
+++ b/option.cc
@@ -1,4 +1,5 @@
#include "option.h"
+#include "util.h"
#include <iostream>
#include <cstdarg>
@@ -9,11 +10,16 @@ option_handler::option_handler(const std::string& label,
{
option_t opt;
+ static char buf[128];
+ char * p = buf;
for (const char * q = label.c_str(); *q; q++)
if (*q == '_')
- opt.long_opt += '-';
+ *p++ = '-';
else
- opt.long_opt += *q;
+ *p++ = *q;
+ assert(p < buf + 127);
+ *p = '\0';
+ opt.long_opt = buf;
handlers.insert(option_handler_pair(opt.long_opt, this));
@@ -130,15 +136,18 @@ void process_environment(char ** envp, const std::string& tag)
{
for (char ** p = envp; *p; p++)
if (std::strncmp(*p, tag.c_str(), 7) == 0) {
- std::string opt;
char * q;
+ static char buf[128];
+ char * r = buf;
for (q = *p + 7; *q && *q != '='; q++)
if (*q == '_')
- opt += '-';
+ *r++ += '-';
else
- opt += std::tolower(*q);
+ *r++ += std::tolower(*q);
+ assert(r < buf + 127);
+ *r = '\0';
if (*q == '=')
- process_option(opt, q + 1);
+ process_option(buf, q + 1);
}
}
diff --git a/textual.cc b/textual.cc
index 03953141..15aa33e0 100644
--- a/textual.cc
+++ b/textual.cc
@@ -385,13 +385,12 @@ unsigned int parse_textual_journal(std::istream& in, journal_t * journal,
in >> c;
in >> date;
in >> time;
+ date += " ";
+ date += time;
in.getline(line, MAX_LINE);
linenum++;
- date += " ";
- date += time;
-
struct std::tm when;
if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) {
entry_t * curr = new entry_t;
diff --git a/valexpr.cc b/valexpr.cc
index cd6664b1..74d4587b 100644
--- a/valexpr.cc
+++ b/valexpr.cc
@@ -1,6 +1,8 @@
#include "valexpr.h"
#include "error.h"
#include "datetime.h"
+#include "debug.h"
+#include "util.h"
#include <vector>
@@ -344,32 +346,20 @@ value_expr_t * parse_value_term(std::istream& in)
char c = peek_next_nonws(in);
if (std::isdigit(c) || c == '.' || c == '{') {
- std::string ident;
-
+ static char buf[2048];
if (c == '{') {
in.get(c);
- c = in.peek();
- while (! in.eof() && c != '}') {
- in.get(c);
- ident += c;
- c = in.peek();
- }
+ READ_INTO(in, buf, 2048, c, c != '}');
if (c == '}')
in.get(c);
else
throw value_expr_error("Missing '}'");
} else {
- while (! in.eof() && std::isdigit(c) || c == '.') {
- in.get(c);
- ident += c;
- c = in.peek();
- }
+ READ_INTO(in, buf, 2048, c, std::isdigit(c) || c == '.');
}
- if (! ident.empty()) {
- node = new value_expr_t(value_expr_t::CONSTANT_A);
- node->constant_a.parse(ident);
- }
+ node = new value_expr_t(value_expr_t::CONSTANT_A);
+ node->constant_a.parse(buf);
return node;
}
@@ -443,7 +433,6 @@ value_expr_t * parse_value_term(std::istream& in)
// Other
case '/': {
- std::string ident;
bool payee_mask = false;
c = peek_next_nonws(in);
@@ -453,22 +442,15 @@ value_expr_t * parse_value_term(std::istream& in)
c = in.peek();
}
- while (! in.eof() && c != '/') {
- in.get(c);
- if (c == '\\')
- in.get(c);
- ident += c;
- c = in.peek();
- }
-
- if (c == '/') {
- in.get(c);
- node = new value_expr_t(payee_mask ?
- value_expr_t::F_PAYEE_MASK : value_expr_t::F_ACCOUNT_MASK);
- node->mask = new mask_t(ident);
- } else {
+ static char buf[4096];
+ READ_INTO(in, buf, 4096, c, c != '/');
+ if (c != '/')
throw value_expr_error("Missing closing '/'");
- }
+
+ in.get(c);
+ node = new value_expr_t(payee_mask ? value_expr_t::F_PAYEE_MASK :
+ value_expr_t::F_ACCOUNT_MASK);
+ node->mask = new mask_t(buf);
break;
}
@@ -481,22 +463,15 @@ value_expr_t * parse_value_term(std::istream& in)
break;
case '[': {
- std::string ident;
-
- c = in.peek();
- while (! in.eof() && c != ']') {
- in.get(c);
- ident += c;
- c = in.peek();
- }
- if (c == ']') {
- in.get(c);
- node = new value_expr_t(value_expr_t::CONSTANT_T);
- if (! parse_date(ident.c_str(), &node->constant_t))
- throw value_expr_error("Failed to parse date");
- } else {
+ static char buf[1024];
+ READ_INTO(in, buf, 1024, c, c != ']');
+ if (c != ']')
throw value_expr_error("Missing ']'");
- }
+
+ in.get(c);
+ node = new value_expr_t(value_expr_t::CONSTANT_T);
+ if (! parse_date(buf, &node->constant_t))
+ throw value_expr_error("Failed to parse date");
break;
}
diff --git a/valexpr.h b/valexpr.h
index d5a73e32..81b20495 100644
--- a/valexpr.h
+++ b/valexpr.h
@@ -133,9 +133,11 @@ class item_predicate
predicate = NULL;
if (! _predicate.empty()) {
try {
+#ifdef DEBUG_ENABLED
DEBUG_CLASS("valexpr.predicate.parse");
DEBUG_PRINT_("parsing: '" << _predicate << "'");
+#endif
predicate = parse_value_expr(_predicate);
#ifdef DEBUG_ENABLED