From 3cb170588c9b180fb4d28af04e44ac87481560a7 Mon Sep 17 00:00:00 2001 From: jistone Date: Fri, 17 Aug 2007 01:54:28 +0000 Subject: 2007-08-16 Josh Stone 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. --- parse.cxx | 75 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 29 deletions(-) (limited to 'parse.cxx') 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; -- cgit