diff options
author | fche <fche> | 2005-03-15 22:38:27 +0000 |
---|---|---|
committer | fche <fche> | 2005-03-15 22:38:27 +0000 |
commit | 9c0c0e4652824a0bf8f4da2175278b129fac6809 (patch) | |
tree | c560854f3933fa4cfcf397c9fd040da913bd98bb /parse.cxx | |
parent | 204b456c7c08bc40ffe1f21575461d92a544e92b (diff) | |
download | systemtap-steved-9c0c0e4652824a0bf8f4da2175278b129fac6809.tar.gz systemtap-steved-9c0c0e4652824a0bf8f4da2175278b129fac6809.tar.xz systemtap-steved-9c0c0e4652824a0bf8f4da2175278b129fac6809.zip |
2005-03-15 Frank Ch. Eigler <fche@redhat.com>
* TODO: New file. Include some probe-point-provider syntax examples.
* parse.cxx (lexer::scan, parser::parse_literal): Support hex, octal
numbers via strtol.
(parse_probe, parse_probe_point): Modify for dotted syntax.
* staptree.cxx: Ditto.
* parsetest.cxx, semtest.cxx: Print parse/sem results even if
.stp files were given on command line.
* parse.h, staptree.h: Rename probe_point_spec -> probe_point.
* runtest.sh: New test-runner front-end script.
* Makefile.am: Use it for TESTS_ENVIRONMENT.
* testsuite/*: Update probe point syntax. Add a bunch of new tests.
Diffstat (limited to 'parse.cxx')
-rw-r--r-- | parse.cxx | 95 |
1 files changed, 70 insertions, 25 deletions
@@ -6,7 +6,10 @@ #include "staptree.h" #include "parse.h" #include <cctype> +#include <cstdlib> #include <fstream> +#include <cerrno> +#include <climits> using namespace std; @@ -179,17 +182,22 @@ lexer::scan () else if (isdigit (c)) { - // XXX: support 0xHEX etc. n->type = tok_number; - n->content = c; + n->content = (char) c; + while (1) { int c2 = input.peek (); if (! input) break; - if (isdigit(c2)) + + // NB: isalnum is very permissive. We rely on strtol, called in + // parser::parse_literal below, to confirm that the number string + // is correctly formatted and in range. + + if (isalnum (c2)) { - n->content.push_back(c2); + n->content.push_back (c2); input_get (); } else @@ -344,10 +352,10 @@ parser::parse_probe () if (t && t->type == tok_identifier) { p->tok = t; - p->location.push_back (parse_probe_point_spec ()); + p->locations.push_back (parse_probe_point ()); t = peek (); - if (t && t->type == tok_operator && t->content == ":") + if (t && t->type == tok_operator && t->content == ",") { next (); continue; @@ -355,11 +363,11 @@ parser::parse_probe () else if (t && t->type == tok_operator && t->content == "{") break; else - throw parse_error ("expected ':' or '{'"); + throw parse_error ("expected ',' or '{'"); // XXX: unify logic with that in parse_symbol() } else - throw parse_error ("expected probe location specifier"); + throw parse_error ("expected probe point specifier"); } p->body = parse_stmt_block (); @@ -524,25 +532,49 @@ parser::parse_functiondecl () } -probe_point_spec* -parser::parse_probe_point_spec () +probe_point* +parser::parse_probe_point () { - probe_point_spec* pl = new probe_point_spec; + probe_point* pl = new probe_point; - const token* t = next (); - if (t->type != tok_identifier) - throw parse_error ("expected identifier"); - pl->functor = t->content; - pl->tok = t; - - t = peek (); - if (t && t->type == tok_operator && t->content == "(") + while (1) { - next (); // consume "(" - pl->arg = parse_literal (); - const token* tt = next (); - if (! (tt->type == tok_operator && tt->content == ")")) - throw parse_error ("expected ')'"); + const token* t = next (); + if (t->type != tok_identifier) + throw parse_error ("expected identifier"); + + if (pl->tok == 0) pl->tok = t; + + probe_point::component* c = new probe_point::component; + c->functor = t->content; + pl->components.push_back (c); + // NB though we still may add c->arg soon + + t = peek (); + if (t && t->type == tok_operator + && (t->content == "{" || t->content == ",")) + break; + + if (t && t->type == tok_operator && t->content == "(") + { + next (); // consume "(" + c->arg = parse_literal (); + + t = next (); + if (! (t->type == tok_operator && t->content == ")")) + throw parse_error ("expected ')'"); + + t = peek (); + if (t && t->type == tok_operator + && (t->content == "{" || t->content == ",")) + break; + } + // fall through + + if (t && t->type == tok_operator && t->content == ".") + next (); + else + throw parse_error ("expected '.'"); } return pl; @@ -557,7 +589,20 @@ parser::parse_literal () if (t->type == tok_string) l = new literal_string (t->content); else if (t->type == tok_number) - l = new literal_number (atol (t->content.c_str ())); + { + const char* startp = t->content.c_str (); + char* endp = (char*) startp; + + // NB: we allow controlled overflow from LONG_MIN .. ULONG_MAX + errno = 0; + long long value = strtoll (startp, & endp, 0); + if (errno == ERANGE || errno == EINVAL || *endp != '\0' + || value > ULONG_MAX || value < LONG_MIN) + throw parse_error ("number invalid or out of range"); + + long value2 = (long) value; + l = new literal_number (value2); + } else throw parse_error ("expected literal string or number"); |