summaryrefslogtreecommitdiffstats
path: root/parse.cxx
diff options
context:
space:
mode:
authorjistone <jistone>2007-08-17 01:54:28 +0000
committerjistone <jistone>2007-08-17 01:54:28 +0000
commit3cb170588c9b180fb4d28af04e44ac87481560a7 (patch)
tree8cf0c1f2f065c640052d6f8b90ee6f0300f12a85 /parse.cxx
parentbf49da0383481795d0a8d608beee27f6b1a251dc (diff)
downloadsystemtap-steved-3cb170588c9b180fb4d28af04e44ac87481560a7.tar.gz
systemtap-steved-3cb170588c9b180fb4d28af04e44ac87481560a7.tar.xz
systemtap-steved-3cb170588c9b180fb4d28af04e44ac87481560a7.zip
2007-08-16 Josh Stone <joshua.i.stone@intel.com>
PR 4591 * parse.cxx (parser::parse_symbol): Tweak 'print' matching to allow all the new variants with printd and println. * staptree.h (struct print_format): Add fields for the new print variants, and parse_print() to help matching. * staptree.cxx (print_format::parse_print): New static method to match the print variants and determine their properties. (print_format::print): Handle the new print types. (deep_copy_visitor::visit_print_format): Copy the new fields. * translate.cxx (c_unparser::visit_print_format): Insert delims and newlines where appropriate for new print functions. * stap1.in: Document the new print functions. testsuite/ * lib/stap_run.exp: Make sure to match the entire output, in case there are multiple pass/fail messages. * buildok/printf.stp: Add lines for new print variants. * parseko/printd01.stp: Make sure that bad printd calls are handled. * parseko/printd02.stp: Ditto. * parseko/printd03.stp: Ditto. * parseko/printd04.stp: Ditto. * systemtap.base/print.stp: Try a bunch of different print calls. * systemtap.base/print.exp: Driver for above.
Diffstat (limited to 'parse.cxx')
-rw-r--r--parse.cxx75
1 files changed, 46 insertions, 29 deletions
diff --git a/parse.cxx b/parse.cxx
index 61d0352a..e22c58ea 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -2226,6 +2226,8 @@ parser::parse_symbol ()
// now scrutinize this identifier for the various magic forms of identifier
// (printf, @stat_op, and $var...)
+ bool pf_stream, pf_format, pf_delim, pf_newline;
+
if (name.size() > 0 && name[0] == '@')
{
stat_op *sop = new stat_op;
@@ -2248,36 +2250,19 @@ parser::parse_symbol ()
return sop;
}
- else if (name.size() > 0 && (name == "print"
- || name == "sprint"
- || name == "printf"
- || name == "sprintf"))
+ else if (print_format::parse_print(name,
+ pf_stream, pf_format, pf_delim, pf_newline))
{
print_format *fmt = new print_format;
fmt->tok = t;
- fmt->print_with_format = (name[name.size() - 1] == 'f');
- fmt->print_to_stream = (name[0] == 'p');
+ fmt->print_to_stream = pf_stream;
+ fmt->print_with_format = pf_format;
+ fmt->print_with_delim = pf_delim;
+ fmt->print_with_newline = pf_newline;
expect_op("(");
- if (fmt->print_with_format)
- {
- // Consume and convert a format string, and any subsequent
- // arguments. Agreement between the format string and the
- // arguments is postponed to the typechecking phase.
- string tmp;
- expect_unknown (tok_string, tmp);
- fmt->raw_components = tmp;
- fmt->components = print_format::string_to_components (tmp);
- while (!peek_op (")"))
- {
- expect_op(",");
- expression *e = parse_expression ();
- fmt->args.push_back(e);
- }
- }
- else if (name == "print" &&
- (peek_kw("@hist_linear") ||
- peek_kw("@hist_log")))
+ if (name == "print" &&
+ (peek_kw("@hist_linear") || peek_kw("@hist_log")))
{
// We have a special case where we recognize
// print(@hist_foo(bar)) as a magic print-the-histogram
@@ -2312,10 +2297,42 @@ parser::parse_symbol ()
}
else
{
- // If we are not printing with a format string, we permit
- // exactly one argument (of any type).
- expression *e = parse_expression ();
- fmt->args.push_back(e);
+ int min_args = 0;
+ if (fmt->print_with_format)
+ {
+ // Consume and convert a format string. Agreement between the
+ // format string and the arguments is postponed to the
+ // typechecking phase.
+ string tmp;
+ expect_unknown (tok_string, tmp);
+ fmt->raw_components = tmp;
+ fmt->components = print_format::string_to_components (tmp);
+ }
+ else if (fmt->print_with_delim)
+ {
+ // Consume a delimiter to separate arguments.
+ fmt->delimiter.clear();
+ fmt->delimiter.type = print_format::conv_literal;
+ expect_unknown (tok_string, fmt->delimiter.literal_string);
+ min_args = 2;
+ }
+ else
+ {
+ // If we are not printing with a format string, we must have
+ // at least one argument (of any type).
+ expression *e = parse_expression ();
+ fmt->args.push_back(e);
+ }
+
+ // Consume any subsequent arguments.
+ while (min_args || !peek_op (")"))
+ {
+ expect_op(",");
+ expression *e = parse_expression ();
+ fmt->args.push_back(e);
+ if (min_args)
+ --min_args;
+ }
}
expect_op(")");
return fmt;