summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfche <fche>2005-12-12 17:39:53 +0000
committerfche <fche>2005-12-12 17:39:53 +0000
commita9c62ac9b339211d80b013eac75ba47f8a39d478 (patch)
tree235ad14256204134f14b55080f8c2b40a2186ea7
parent9cb3a339871fa02385f16d896471ac8b7941e580 (diff)
downloadsystemtap-steved-a9c62ac9b339211d80b013eac75ba47f8a39d478.tar.gz
systemtap-steved-a9c62ac9b339211d80b013eac75ba47f8a39d478.tar.xz
systemtap-steved-a9c62ac9b339211d80b013eac75ba47f8a39d478.zip
2005-12-12 Frank Ch. Eigler <fche@redhat.com>
Fix parse tree pretty-printer. * staptree.h (print_format): Add raw_components field. * parse.cxx (parse_symbol): Set it. * staptree.cxx (lex_cast_qstring): Copy it here too. (binary_expression::print): Add a space around operator, due to lexical ambiguity (expr % paren-expr) vs %( preprocessor op. (array_in:: foreach_loop:: arrayindex::print): Print base as indexable. (print_format::string_to_components): Use parse_error, not semantic. (print_format::print): Properly quote formatting string. Print histogram argument. * translate.cxx (visit_print_format): Properly quote formatting string. (varlock): Reword lock timeout error message. * testsuite/buildok/printf.stp: Add some quoting troublemakers. * testsuite/parseok/unparser.stp: New file.
-rw-r--r--ChangeLog17
-rw-r--r--parse.cxx1
-rw-r--r--staptree.cxx44
-rw-r--r--staptree.h1
-rwxr-xr-xtestsuite/buildok/printf.stp1
-rwxr-xr-xtestsuite/parseok/unparser.stp21
-rw-r--r--translate.cxx4
7 files changed, 78 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 7c1f777d..9b242df2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2005-12-12 Frank Ch. Eigler <fche@redhat.com>
+
+ Fix parse tree pretty-printer.
+ * staptree.h (print_format): Add raw_components field.
+ * parse.cxx (parse_symbol): Set it.
+ * staptree.cxx (lex_cast_qstring): Copy it here too.
+ (binary_expression::print): Add a space around operator, due to
+ lexical ambiguity (expr % paren-expr) vs %( preprocessor op.
+ (array_in:: foreach_loop:: arrayindex::print): Print base as indexable.
+ (print_format::string_to_components): Use parse_error, not semantic.
+ (print_format::print): Properly quote formatting string. Print
+ histogram argument.
+ * translate.cxx (visit_print_format): Properly quote formatting string.
+ (varlock): Reword lock timeout error message.
+ * testsuite/buildok/printf.stp: Add some quoting troublemakers.
+ * testsuite/parseok/unparser.stp: New file.
+
2005-12-11 Roland McGrath <roland@redhat.com>
* configure.ac: Bump version to 0.5.1 for test builds.
diff --git a/parse.cxx b/parse.cxx
index 04123a4d..56495a56 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -1981,6 +1981,7 @@ parser::parse_symbol ()
// 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 (")"))
{
diff --git a/staptree.cxx b/staptree.cxx
index 87c9b383..0eb898ac 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -17,6 +17,27 @@
using namespace std;
+// return as quoted string, with at least '"' backslash-escaped
+template <typename IN> inline string
+lex_cast_qstring(IN const & in)
+{
+ stringstream ss;
+ string out, out2;
+ if (!(ss << in))
+ throw runtime_error("bad lexical cast");
+ out = ss.str();
+ out2 += '"';
+ for (unsigned i=0; i<out.length(); i++)
+ {
+ if (out[i] == '"') // XXX others?
+ out2 += '\\';
+ out2 += out[i];
+ }
+ out2 += '"';
+ return out2;
+}
+
+
expression::expression ():
type (pe_unknown), tok (0)
{
@@ -196,9 +217,9 @@ void literal_number::print (ostream& o) const
void binary_expression::print (ostream& o) const
{
- o << '(' << *left << ")"
+ o << "(" << *left << ") "
<< op
- << '(' << *right << ")";
+ << " (" << *right << ")";
}
@@ -215,7 +236,8 @@ void array_in::print (ostream& o) const
if (i > 0) o << ", ";
operand->indexes[i]->print (o);
}
- o << "] in " << operand->base;
+ o << "] in ";
+ operand->base->print_indexable (o);
}
void post_crement::print (ostream& o) const
@@ -301,7 +323,8 @@ void functiondecl::printsig (ostream& o) const
void arrayindex::print (ostream& o) const
{
- o << base << "[";
+ base->print_indexable (o);
+ o << "[";
for (unsigned i=0; i<indexes.size(); i++)
o << (i>0 ? ", " : "") << *indexes[i];
o << "]";
@@ -541,7 +564,7 @@ print_format::string_to_components(string const & str)
}
if (curr.type == conv_unspecified)
- throw semantic_error("invalid or missing conversion specifier");
+ throw parse_error("invalid or missing conversion specifier");
++i;
res.push_back(curr);
@@ -554,7 +577,7 @@ print_format::string_to_components(string const & str)
if (curr.type == conv_literal)
res.push_back(curr);
else
- throw semantic_error("trailing incomplete print format conversion");
+ throw parse_error("trailing incomplete print format conversion");
}
return res;
@@ -569,12 +592,14 @@ void print_format::print (ostream& o) const
o << name << "(";
if (print_with_format)
{
- o << '"' << components_to_string(components) << "\", ";
+ o << lex_cast_qstring (raw_components);
}
+ if (hist)
+ hist->print(o);
for (vector<expression*>::const_iterator i = args.begin();
i != args.end(); ++i)
{
- if (i != args.begin())
+ if (i != args.begin() || print_with_format)
o << ", ";
(*i)->print(o);
}
@@ -686,7 +711,8 @@ void foreach_loop::print (ostream& o) const
if (sort_direction != 0 && sort_column == i+1)
o << (sort_direction > 0 ? "+" : "-");
}
- o << "] in " << base;
+ o << "] in ";
+ base->print_indexable (o);
if (sort_direction != 0 && sort_column == 0)
o << (sort_direction > 0 ? "+" : "-");
o << ") ";
diff --git a/staptree.h b/staptree.h
index b5420693..44f7de7c 100644
--- a/staptree.h
+++ b/staptree.h
@@ -310,6 +310,7 @@ struct print_format: public expression
: hist(NULL)
{}
+ std::string raw_components;
std::vector<format_component> components;
std::vector<expression*> args;
hist_op *hist;
diff --git a/testsuite/buildok/printf.stp b/testsuite/buildok/printf.stp
index 4fd14ad6..2a76a0e9 100755
--- a/testsuite/buildok/printf.stp
+++ b/testsuite/buildok/printf.stp
@@ -26,4 +26,5 @@ probe begin
sprintf("%s before %s",
sprint(1), sprint(3)),
sprint("C"))
+ printf("\"quote\\this\"")
}
diff --git a/testsuite/parseok/unparser.stp b/testsuite/parseok/unparser.stp
new file mode 100755
index 00000000..710c4636
--- /dev/null
+++ b/testsuite/parseok/unparser.stp
@@ -0,0 +1,21 @@
+#! /bin/sh
+
+set -e
+
+for dir in ${SRCDIR}/testsuite/parseok \
+${SRCDIR}/testsuite/semok \
+${SRCDIR}/testsuite/semko \
+${SRCDIR}/testsuite/transok \
+${SRCDIR}/testsuite/transko \
+${SRCDIR}/testsuite/buildok \
+${SRCDIR}/testsuite/buildko
+do
+ for file in $dir/*.stp
+ do
+ if head -1 $file | grep -q stap
+ then
+ echo $file
+ ./stap -p1 $file | ./stap -p1 - > /dev/null
+ fi
+ done
+done
diff --git a/translate.cxx b/translate.cxx
index f2a848f3..fa95966c 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -449,7 +449,7 @@ struct varlock
<< "(trylock_count++ < MAXTRYLOCK)"
<< ") ; /* spin */";
c.o->newline() << "if (unlikely (trylock_count >= MAXTRYLOCK)) {";
- c.o->newline(1) << "c->last_error = \"deadlock over variable "
+ c.o->newline(1) << "c->last_error = \"locking timeout over variable "
<< v << "\";";
c.o->newline() << "goto " << post_unlock_label << ";";
c.o->newline(-1) << "}";
@@ -3218,7 +3218,7 @@ c_unparser::visit_print_format (print_format* e)
else
o->newline() << "snprintf (" << res.qname() << ", MAXSTRINGLEN, ";
- o->line() << "\"" << print_format::components_to_string(components) << "\"";
+ o->line() << lex_cast_qstring(print_format::components_to_string(components));
for (unsigned i = 0; i < tmp.size(); ++i)
{