Redesigned the format_t class
This commit is contained in:
parent
c3535d06c8
commit
fb8be53edb
6 changed files with 97 additions and 86 deletions
|
|
@ -118,7 +118,8 @@ public:
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
void set_text(const string& txt) {
|
void set_text(const string& txt) {
|
||||||
str = txt;
|
str = txt;
|
||||||
|
compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse(const string& str, const parse_flags_t& flags = PARSE_DEFAULT) {
|
void parse(const string& str, const parse_flags_t& flags = PARSE_DEFAULT) {
|
||||||
|
|
@ -128,9 +129,7 @@ public:
|
||||||
virtual void parse(std::istream&,
|
virtual void parse(std::istream&,
|
||||||
const parse_flags_t& = PARSE_DEFAULT,
|
const parse_flags_t& = PARSE_DEFAULT,
|
||||||
const optional<string>& original_string = none) {
|
const optional<string>& original_string = none) {
|
||||||
str = original_string ? *original_string : "<stream>";
|
set_text(original_string ? *original_string : "<stream>");
|
||||||
context = NULL;
|
|
||||||
compiled = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mark_uncompiled() {
|
void mark_uncompiled() {
|
||||||
|
|
@ -185,7 +184,9 @@ public:
|
||||||
context = scope;
|
context = scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual string context_to_str() const = 0;
|
virtual string context_to_str() const {
|
||||||
|
return empty_string;
|
||||||
|
}
|
||||||
|
|
||||||
string print_to_str() const {
|
string print_to_str() const {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
|
@ -203,8 +204,8 @@ public:
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& out) const = 0;
|
virtual void print(std::ostream&) const {}
|
||||||
virtual void dump(std::ostream& out) const = 0;
|
virtual void dump(std::ostream&) const {}
|
||||||
|
|
||||||
result_type preview(std::ostream& out, scope_t& scope) const {
|
result_type preview(std::ostream& out, scope_t& scope) const {
|
||||||
out << _("--- Input expression ---") << std::endl;
|
out << _("--- Input expression ---") << std::endl;
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,12 @@ void format_t::element_t::dump(std::ostream& out) const
|
||||||
out << std::dec << int(max_width);
|
out << std::dec << int(max_width);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case STRING: out << " str: '" << chars << "'" << std::endl; break;
|
case STRING:
|
||||||
case EXPR: out << " expr: " << expr << std::endl; break;
|
out << " str: '" << boost::get<string>(data) << "'" << std::endl;
|
||||||
|
break;
|
||||||
|
case EXPR:
|
||||||
|
out << " expr: " << boost::get<expr_t>(data) << std::endl;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,7 +121,7 @@ format_t::element_t * format_t::parse_elements(const string& fmt,
|
||||||
|
|
||||||
if (q != buf) {
|
if (q != buf) {
|
||||||
current->type = element_t::STRING;
|
current->type = element_t::STRING;
|
||||||
current->chars = string(buf, q);
|
current->data = string(buf, q);
|
||||||
q = buf;
|
q = buf;
|
||||||
|
|
||||||
current->next.reset(new element_t);
|
current->next.reset(new element_t);
|
||||||
|
|
@ -128,14 +132,14 @@ format_t::element_t * format_t::parse_elements(const string& fmt,
|
||||||
p++;
|
p++;
|
||||||
current->type = element_t::STRING;
|
current->type = element_t::STRING;
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case 'b': current->chars = "\b"; break;
|
case 'b': current->data = string("\b"); break;
|
||||||
case 'f': current->chars = "\f"; break;
|
case 'f': current->data = string("\f"); break;
|
||||||
case 'n': current->chars = "\n"; break;
|
case 'n': current->data = string("\n"); break;
|
||||||
case 'r': current->chars = "\r"; break;
|
case 'r': current->data = string("\r"); break;
|
||||||
case 't': current->chars = "\t"; break;
|
case 't': current->data = string("\t"); break;
|
||||||
case 'v': current->chars = "\v"; break;
|
case 'v': current->data = string("\v"); break;
|
||||||
case '\\': current->chars = "\\"; break;
|
case '\\': current->data = string("\\"); break;
|
||||||
default: current->chars = string(1, *p); break;
|
default: current->data = string(1, *p); break;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -171,8 +175,8 @@ format_t::element_t * format_t::parse_elements(const string& fmt,
|
||||||
|
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '%':
|
case '%':
|
||||||
current->type = element_t::STRING;
|
current->type = element_t::STRING;
|
||||||
current->chars = "%";
|
current->data = string("%");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '$': {
|
case '$': {
|
||||||
|
|
@ -207,7 +211,7 @@ format_t::element_t * format_t::parse_elements(const string& fmt,
|
||||||
if (format_amount) p++;
|
if (format_amount) p++;
|
||||||
|
|
||||||
current->type = element_t::EXPR;
|
current->type = element_t::EXPR;
|
||||||
current->expr = parse_single_expression(p, ! format_amount);
|
current->data = parse_single_expression(p, ! format_amount);
|
||||||
|
|
||||||
// Wrap the subexpression in calls to justify and scrub
|
// Wrap the subexpression in calls to justify and scrub
|
||||||
if (format_amount) {
|
if (format_amount) {
|
||||||
|
|
@ -216,7 +220,7 @@ format_t::element_t * format_t::parse_elements(const string& fmt,
|
||||||
else
|
else
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
expr_t::ptr_op_t op = current->expr.get_op();
|
expr_t::ptr_op_t op = boost::get<expr_t>(current->data).get_op();
|
||||||
|
|
||||||
expr_t::ptr_op_t amount_op;
|
expr_t::ptr_op_t amount_op;
|
||||||
expr_t::ptr_op_t colorize_op;
|
expr_t::ptr_op_t colorize_op;
|
||||||
|
|
@ -238,8 +242,10 @@ format_t::element_t * format_t::parse_elements(const string& fmt,
|
||||||
expr_t::ptr_op_t arg2_node(new expr_t::op_t(expr_t::op_t::VALUE));
|
expr_t::ptr_op_t arg2_node(new expr_t::op_t(expr_t::op_t::VALUE));
|
||||||
expr_t::ptr_op_t arg3_node(new expr_t::op_t(expr_t::op_t::VALUE));
|
expr_t::ptr_op_t arg3_node(new expr_t::op_t(expr_t::op_t::VALUE));
|
||||||
|
|
||||||
arg1_node->set_value(current->min_width > 0 ? long(current->min_width) : -1);
|
arg1_node->set_value(current->min_width > 0 ?
|
||||||
arg2_node->set_value(current->max_width > 0 ? long(current->max_width) : -1);
|
long(current->min_width) : -1);
|
||||||
|
arg2_node->set_value(current->max_width > 0 ?
|
||||||
|
long(current->max_width) : -1);
|
||||||
arg3_node->set_value(! current->has_flags(ELEMENT_ALIGN_LEFT));
|
arg3_node->set_value(! current->has_flags(ELEMENT_ALIGN_LEFT));
|
||||||
|
|
||||||
current->min_width = 0;
|
current->min_width = 0;
|
||||||
|
|
@ -264,7 +270,7 @@ format_t::element_t * format_t::parse_elements(const string& fmt,
|
||||||
call2_node->set_left(justify_node);
|
call2_node->set_left(justify_node);
|
||||||
call2_node->set_right(args3_node);
|
call2_node->set_right(args3_node);
|
||||||
|
|
||||||
string prev_expr = current->expr.text();
|
string prev_expr = boost::get<expr_t>(current->data).text();
|
||||||
|
|
||||||
if (colorize_op) {
|
if (colorize_op) {
|
||||||
expr_t::ptr_op_t ansify_if_node(new expr_t::op_t(expr_t::op_t::IDENT));
|
expr_t::ptr_op_t ansify_if_node(new expr_t::op_t(expr_t::op_t::IDENT));
|
||||||
|
|
@ -278,21 +284,18 @@ format_t::element_t * format_t::parse_elements(const string& fmt,
|
||||||
call3_node->set_left(ansify_if_node);
|
call3_node->set_left(ansify_if_node);
|
||||||
call3_node->set_right(args4_node);
|
call3_node->set_right(args4_node);
|
||||||
|
|
||||||
current->expr = expr_t(call3_node);
|
current->data = expr_t(call3_node);
|
||||||
} else {
|
} else {
|
||||||
current->expr = expr_t(call2_node);
|
current->data = expr_t(call2_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
current->expr.set_text(prev_expr);
|
boost::get<expr_t>(current->data).set_text(prev_expr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
current->type = element_t::EXPR;
|
throw_(format_error, _("Unrecognized formatting character: %1") << *p);
|
||||||
current->chars = string(FMT_PREFIX) + *p;
|
|
||||||
current->expr.parse(current->chars);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -304,15 +307,17 @@ format_t::element_t * format_t::parse_elements(const string& fmt,
|
||||||
current->next.reset(new element_t);
|
current->next.reset(new element_t);
|
||||||
current = current->next.get();
|
current = current->next.get();
|
||||||
}
|
}
|
||||||
current->type = element_t::STRING;
|
current->type = element_t::STRING;
|
||||||
current->chars = string(buf, q);
|
current->data = string(buf, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.release();
|
return result.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void format_t::format(std::ostream& out_str, scope_t& scope)
|
string format_t::real_calc(scope_t& scope)
|
||||||
{
|
{
|
||||||
|
std::ostringstream out_str;
|
||||||
|
|
||||||
for (element_t * elem = elements.get(); elem; elem = elem->next.get()) {
|
for (element_t * elem = elements.get(); elem; elem = elem->next.get()) {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
string name;
|
string name;
|
||||||
|
|
@ -326,20 +331,22 @@ void format_t::format(std::ostream& out_str, scope_t& scope)
|
||||||
case element_t::STRING:
|
case element_t::STRING:
|
||||||
if (elem->min_width > 0)
|
if (elem->min_width > 0)
|
||||||
out.width(elem->min_width);
|
out.width(elem->min_width);
|
||||||
out << elem->chars;
|
out << boost::get<string>(elem->data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case element_t::EXPR:
|
case element_t::EXPR: {
|
||||||
|
expr_t& expr(boost::get<expr_t>(elem->data));
|
||||||
try {
|
try {
|
||||||
elem->expr.compile(scope);
|
|
||||||
|
expr.compile(scope);
|
||||||
|
|
||||||
value_t value;
|
value_t value;
|
||||||
if (elem->expr.is_function()) {
|
if (expr.is_function()) {
|
||||||
call_scope_t args(scope);
|
call_scope_t args(scope);
|
||||||
args.push_back(long(elem->max_width));
|
args.push_back(long(elem->max_width));
|
||||||
value = elem->expr.get_function()(args);
|
value = expr.get_function()(args);
|
||||||
} else {
|
} else {
|
||||||
value = elem->expr.calc(scope);
|
value = expr.calc(scope);
|
||||||
}
|
}
|
||||||
DEBUG("format.expr", "value = (" << value << ")");
|
DEBUG("format.expr", "value = (" << value << ")");
|
||||||
|
|
||||||
|
|
@ -348,10 +355,11 @@ void format_t::format(std::ostream& out_str, scope_t& scope)
|
||||||
}
|
}
|
||||||
catch (const calc_error&) {
|
catch (const calc_error&) {
|
||||||
add_error_context(_("While calculating format expression:"));
|
add_error_context(_("While calculating format expression:"));
|
||||||
add_error_context(elem->expr.context_to_str());
|
add_error_context(expr.context_to_str());
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
@ -375,6 +383,8 @@ void format_t::format(std::ostream& out_str, scope_t& scope)
|
||||||
out_str << out.str();
|
out_str << out.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return out_str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
string format_t::truncate(const unistring& ustr,
|
string format_t::truncate(const unistring& ustr,
|
||||||
|
|
|
||||||
40
src/format.h
40
src/format.h
|
|
@ -50,20 +50,20 @@ class unistring;
|
||||||
|
|
||||||
DECLARE_EXCEPTION(format_error, std::runtime_error);
|
DECLARE_EXCEPTION(format_error, std::runtime_error);
|
||||||
|
|
||||||
class format_t : public noncopyable
|
class format_t : public expr_base_t<string>
|
||||||
{
|
{
|
||||||
|
typedef expr_base_t<string> base_type;
|
||||||
|
|
||||||
struct element_t : public supports_flags<>
|
struct element_t : public supports_flags<>
|
||||||
{
|
{
|
||||||
#define ELEMENT_ALIGN_LEFT 0x01
|
#define ELEMENT_ALIGN_LEFT 0x01
|
||||||
|
|
||||||
enum kind_t { STRING, EXPR };
|
enum kind_t { STRING, EXPR };
|
||||||
|
|
||||||
kind_t type;
|
kind_t type;
|
||||||
std::size_t min_width;
|
std::size_t min_width;
|
||||||
std::size_t max_width;
|
std::size_t max_width;
|
||||||
string chars;
|
variant<string, expr_t> data;
|
||||||
expr_t expr;
|
|
||||||
|
|
||||||
scoped_ptr<struct element_t> next;
|
scoped_ptr<struct element_t> next;
|
||||||
|
|
||||||
element_t() throw()
|
element_t() throw()
|
||||||
|
|
@ -83,8 +83,7 @@ class format_t : public noncopyable
|
||||||
type = elem.type;
|
type = elem.type;
|
||||||
min_width = elem.min_width;
|
min_width = elem.min_width;
|
||||||
max_width = elem.max_width;
|
max_width = elem.max_width;
|
||||||
chars = elem.chars;
|
data = elem.data;
|
||||||
expr = elem.expr;
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -124,25 +123,28 @@ private:
|
||||||
const optional<format_t&>& tmpl);
|
const optional<format_t&>& tmpl);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
format_t() {
|
format_t() : base_type() {
|
||||||
TRACE_CTOR(format_t, "");
|
TRACE_CTOR(format_t, "");
|
||||||
}
|
}
|
||||||
format_t(const string& _format) {
|
format_t(const string& _str, scope_t * context = NULL)
|
||||||
|
: base_type(context) {
|
||||||
TRACE_CTOR(format_t, "const string&");
|
TRACE_CTOR(format_t, "const string&");
|
||||||
parse(_format);
|
if (! _str.empty())
|
||||||
|
parse_format(_str);
|
||||||
}
|
}
|
||||||
~format_t() {
|
~format_t() {
|
||||||
TRACE_DTOR(format_t);
|
TRACE_DTOR(format_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse(const string& _format, const optional<format_t&>& tmpl = none) {
|
void parse_format(const string& _format,
|
||||||
|
const optional<format_t&>& tmpl = none) {
|
||||||
elements.reset(parse_elements(_format, tmpl));
|
elements.reset(parse_elements(_format, tmpl));
|
||||||
format_string = _format;
|
set_text(_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
void format(std::ostream& out, scope_t& scope);
|
virtual result_type real_calc(scope_t& scope);
|
||||||
|
|
||||||
void dump(std::ostream& out) const {
|
virtual void dump(std::ostream& out) const {
|
||||||
for (const element_t * elem = elements.get();
|
for (const element_t * elem = elements.get();
|
||||||
elem;
|
elem;
|
||||||
elem = elem->next.get())
|
elem = elem->next.get())
|
||||||
|
|
@ -154,12 +156,6 @@ public:
|
||||||
const std::size_t account_abbrev_length = 0);
|
const std::size_t account_abbrev_length = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FMT_PREFIX "fmt_"
|
|
||||||
#define FMT_PREFIX_LEN 4
|
|
||||||
|
|
||||||
#define WANT_FMT() \
|
|
||||||
(std::strncmp(p, FMT_PREFIX, FMT_PREFIX_LEN) == 0)
|
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
||||||
#endif // _FORMAT_H
|
#endif // _FORMAT_H
|
||||||
|
|
|
||||||
|
|
@ -51,17 +51,19 @@ format_posts::format_posts(report_t& _report,
|
||||||
const char * f = format.c_str();
|
const char * f = format.c_str();
|
||||||
|
|
||||||
if (const char * p = std::strstr(f, "%/")) {
|
if (const char * p = std::strstr(f, "%/")) {
|
||||||
first_line_format.parse(string(f, 0, p - f));
|
first_line_format.parse_format(string(f, 0, p - f));
|
||||||
const char * n = p + 2;
|
const char * n = p + 2;
|
||||||
if (const char * p = std::strstr(n, "%/")) {
|
if (const char * p = std::strstr(n, "%/")) {
|
||||||
next_lines_format.parse(string(n, 0, p - n), first_line_format);
|
next_lines_format.parse_format(string(n, 0, p - n),
|
||||||
between_format.parse(string(p + 2), first_line_format);
|
first_line_format);
|
||||||
|
between_format.parse_format(string(p + 2),
|
||||||
|
first_line_format);
|
||||||
} else {
|
} else {
|
||||||
next_lines_format.parse(n, first_line_format);
|
next_lines_format.parse_format(string(n), first_line_format);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
first_line_format.parse(format);
|
first_line_format.parse_format(format);
|
||||||
next_lines_format.parse(format);
|
next_lines_format.parse_format(format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +82,7 @@ void format_posts::operator()(post_t& post)
|
||||||
if (last_xact != post.xact) {
|
if (last_xact != post.xact) {
|
||||||
if (last_xact) {
|
if (last_xact) {
|
||||||
bind_scope_t xact_scope(report, *last_xact);
|
bind_scope_t xact_scope(report, *last_xact);
|
||||||
between_format.format(out, xact_scope);
|
out << between_format(xact_scope);
|
||||||
}
|
}
|
||||||
print_item(out, *post.xact);
|
print_item(out, *post.xact);
|
||||||
out << '\n';
|
out << '\n';
|
||||||
|
|
@ -96,16 +98,16 @@ void format_posts::operator()(post_t& post)
|
||||||
if (last_xact != post.xact) {
|
if (last_xact != post.xact) {
|
||||||
if (last_xact) {
|
if (last_xact) {
|
||||||
bind_scope_t xact_scope(report, *last_xact);
|
bind_scope_t xact_scope(report, *last_xact);
|
||||||
between_format.format(out, xact_scope);
|
out << between_format(xact_scope);
|
||||||
}
|
}
|
||||||
first_line_format.format(out, bound_scope);
|
out << first_line_format(bound_scope);
|
||||||
last_xact = post.xact;
|
last_xact = post.xact;
|
||||||
}
|
}
|
||||||
else if (last_post && last_post->date() != post.date()) {
|
else if (last_post && last_post->date() != post.date()) {
|
||||||
first_line_format.format(out, bound_scope);
|
out << first_line_format(bound_scope);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
next_lines_format.format(out, bound_scope);
|
out << next_lines_format(bound_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
post.xdata().add_flags(POST_EXT_DISPLAYED);
|
post.xdata().add_flags(POST_EXT_DISPLAYED);
|
||||||
|
|
@ -122,17 +124,17 @@ format_accounts::format_accounts(report_t& _report,
|
||||||
const char * f = format.c_str();
|
const char * f = format.c_str();
|
||||||
|
|
||||||
if (const char * p = std::strstr(f, "%/")) {
|
if (const char * p = std::strstr(f, "%/")) {
|
||||||
account_line_format.parse(string(f, 0, p - f));
|
account_line_format.parse_format(string(f, 0, p - f));
|
||||||
const char * n = p + 2;
|
const char * n = p + 2;
|
||||||
if (const char * p = std::strstr(n, "%/")) {
|
if (const char * p = std::strstr(n, "%/")) {
|
||||||
total_line_format.parse(string(n, 0, p - n), account_line_format);
|
total_line_format.parse_format(string(n, 0, p - n), account_line_format);
|
||||||
separator_format.parse(string(p + 2), account_line_format);
|
separator_format.parse_format(string(p + 2), account_line_format);
|
||||||
} else {
|
} else {
|
||||||
total_line_format.parse(n, account_line_format);
|
total_line_format.parse_format(n, account_line_format);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
account_line_format.parse(format);
|
account_line_format.parse_format(format);
|
||||||
total_line_format.parse(format, account_line_format);
|
total_line_format.parse_format(format, account_line_format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,7 +150,8 @@ std::size_t format_accounts::post_account(account_t& account, const bool flat)
|
||||||
account.xdata().add_flags(ACCOUNT_EXT_DISPLAYED);
|
account.xdata().add_flags(ACCOUNT_EXT_DISPLAYED);
|
||||||
|
|
||||||
bind_scope_t bound_scope(report, account);
|
bind_scope_t bound_scope(report, account);
|
||||||
account_line_format.format(report.output_stream, bound_scope);
|
static_cast<std::ostream&>(report.output_stream)
|
||||||
|
<< account_line_format(bound_scope);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -213,8 +216,8 @@ void format_accounts::flush()
|
||||||
if (displayed > 1 &&
|
if (displayed > 1 &&
|
||||||
! report.HANDLED(no_total) && ! report.HANDLED(percent)) {
|
! report.HANDLED(no_total) && ! report.HANDLED(percent)) {
|
||||||
bind_scope_t bound_scope(report, *report.session.journal->master);
|
bind_scope_t bound_scope(report, *report.session.journal->master);
|
||||||
separator_format.format(out, bound_scope);
|
out << separator_format(bound_scope);
|
||||||
total_line_format.format(out, bound_scope);
|
out << total_line_format(bound_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.flush();
|
out.flush();
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ value_t format_command(call_scope_t& args)
|
||||||
out << std::endl << _("--- Formatted string ---") << std::endl;
|
out << std::endl << _("--- Formatted string ---") << std::endl;
|
||||||
bind_scope_t bound_scope(args, *post);
|
bind_scope_t bound_scope(args, *post);
|
||||||
out << '"';
|
out << '"';
|
||||||
fmt.format(out, bound_scope);
|
out << fmt(bound_scope);
|
||||||
out << "\"\n";
|
out << "\"\n";
|
||||||
|
|
||||||
return NULL_VALUE;
|
return NULL_VALUE;
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,8 @@ struct symbol_t
|
||||||
OPTION,
|
OPTION,
|
||||||
PRECOMMAND,
|
PRECOMMAND,
|
||||||
COMMAND,
|
COMMAND,
|
||||||
DIRECTIVE
|
DIRECTIVE,
|
||||||
|
FORMAT
|
||||||
};
|
};
|
||||||
|
|
||||||
kind_t kind;
|
kind_t kind;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue