public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-sergiodj-stap: First version of the parser for the arguments.
@ 2011-03-02 19:36 sergiodj
  0 siblings, 0 replies; only message in thread
From: sergiodj @ 2011-03-02 19:36 UTC (permalink / raw)
  To: archer-commits

The branch, archer-sergiodj-stap has been updated
       via  18d8eb5f1c053ec00eef50f80beed020f96c9aae (commit)
      from  aabc4832abf2d0f52a9015d274deb71c44f5981a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 18d8eb5f1c053ec00eef50f80beed020f96c9aae
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date:   Wed Mar 2 16:35:39 2011 -0300

    First version of the parser for the arguments.
    
    This first version is not ready yet, but it already works for some
    simple expressions.

-----------------------------------------------------------------------

Summary of changes:
 gdb/stap-probe.c |  282 ++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 244 insertions(+), 38 deletions(-)

First 500 lines of diff:
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index 56b48f6..c23cb96 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -33,19 +33,22 @@
 
 #include <ctype.h>
 
-enum stap_arg_offset
+enum stap_arg_bitness
 {
-  STAP_ARG_OFFSET_UNDEFINED,
-  STAP_ARG_OFFSET_32BIT_UNSIGNED,
-  STAP_ARG_OFFSET_32BIT_SIGNED,
-  STAP_ARG_OFFSET_64BIT_UNSIGNED,
-  STAP_ARG_OFFSET_64BIT_SIGNED,
+  STAP_ARG_BITNESS_UNDEFINED,
+  STAP_ARG_BITNESS_32BIT_UNSIGNED,
+  STAP_ARG_BITNESS_32BIT_SIGNED,
+  STAP_ARG_BITNESS_64BIT_UNSIGNED,
+  STAP_ARG_BITNESS_64BIT_SIGNED,
 };
 
 struct stap_probe_arg
 {
-  enum stap_arg_offset offset;
-  /* FIXME Add more fields to this struct.  */
+  /* The bitness of this argument.  */
+  enum stap_arg_bitness bitness;
+
+  /* The string representing this argument.  */
+  char *arg_str;
 };
 
 #define STAP_MAX_ARGS 10
@@ -66,18 +69,206 @@ struct stap_args_info
    In this case, the number of arguments for this probe is zero, so that's
    why this variable is useful.  */
 static struct stap_args_info dummy_stap_args_info =
-  { 0, NULL };
+  { 0, NULL, NULL };
+
+static void
+ep_skip_leading_whitespace (char **s)
+{
+  if ((s == NULL) || (*s == NULL))
+    return;
+  while (isspace (**s))
+    *s += 1;
+}
+
+static void
+stap_skip_whitespace_cond (char **s, int inside_paren)
+{
+  if (inside_paren)
+    ep_skip_leading_whitespace (s);
+}
+
+static int
+stap_parse_arg (const char **p)
+{
+  char *cur = (char *) *p;
+  int done = 0;
+  int paren_open = 0;
+
+  while (!done)
+    {
+      switch (*cur)
+	{
+	case ' ': case 0:
+	  /* If we're here, then we have already parsed everything
+	     from this argument.  */
+	  if (paren_open)
+	    return 0;
+	  done = 1;
+	  break;
+
+	case '(':
+	  ++paren_open;
+	  ++cur;
+	  stap_skip_whitespace_cond (&cur, paren_open);
+	  break;
+
+	case ')':
+	  if (!paren_open)
+	    return 0;
+
+	  --paren_open;
+	  ++cur;
+	  if (paren_open)
+	    ep_skip_leading_whitespace (&cur);
+	  break;
+
+	case '+': case '-':
+//	  break;
+	
+	case '*': case '/':
+	case '>': case '<': case '|': case '&':
+	case '^': case '!':
+	    {
+	      char c = *cur;
+
+	      ++cur;
+	      switch (*cur)
+		{
+		case '>':
+		  if (c != '<' && c != '>')
+		    return 0;
+
+		  ++cur;
+		  break;
+
+		case '<':
+		  if (c != '<')
+		    return 0;
+
+		  ++cur;
+		  break;
+
+		case '=':
+		  if (c != '=' && c != '<' && c != '>' && c != '!')
+		    return 0;
+
+		  ++cur;
+		  break;
+
+		case '|':
+		  if (c != '|')
+		    return 0;
+
+		  ++cur;
+		  break;
+
+		case '&':
+		  if (c != '&')
+		    return 0;
+
+		  ++cur;
+		  break;
+		}
+	      /* Infix operators take two arguments, one on either
+		 side.  Skipping the whitespaces that may happen on the
+		 right side.  */
+	      stap_skip_whitespace_cond (&cur, paren_open);
+	    }
+	  break;
+
+	case '%':
+	    {
+	      ++cur;
+	      stap_skip_whitespace_cond (&cur, paren_open);
+	      if (*cur >= 'a' && *cur <= 'z')
+		{
+		  /* We're dealing with a register name.  */
+		  while ((*cur >= 'a' && *cur <= 'z')
+			 || (*cur >= '0' && *cur <= '9'))
+		    ++cur;
+
+		  stap_skip_whitespace_cond (&cur, paren_open);
+
+		  /* Some registers (e.g. floating-point register stack
+		     registers on Intel i386) have the following syntax:
+
+		     `%st(0)', `%st(1)', and so on.
+
+		     So it's ok to expect parenthesis here.  */
+		  if (*cur == '(')
+		    {
+		      ++cur;
+		      stap_skip_whitespace_cond (&cur, paren_open);
+		      if (*cur < '0' || *cur > '9')
+			/* This is an error, since we only expect numbers
+			   inside this parenthesis.  */
+			return 0;
+		      ++cur;
+		      stap_skip_whitespace_cond (&cur, paren_open);
+		      if (*cur != ')')
+			/* We only expect one number.  */
+			return 0;
+		      ++cur;
+		      stap_skip_whitespace_cond (&cur, paren_open);
+		    }
+		}
+	    }
+	  break;
+
+	case '$':
+	    {
+	      /* This is an integer constant.  */
+	      ++cur;
+	      stap_skip_whitespace_cond (&cur, paren_open);
+
+	      while (isdigit (*cur))
+		++cur;
+	    }
+	  break;
+
+	case '0': case '1': case '2': case '3': case '4':
+	case '5': case '6': case '7': case '8': case '9':
+	    {
+	      /* Number.  */
+	      while (isdigit (*cur))
+		++cur;
+
+	      stap_skip_whitespace_cond (&cur, paren_open);
+	    }
+	  break;
+	}
+    }
+
+  *p = cur;
+
+  return 1;
+}
+
+static void
+stap_free_args_info (void *args_info_ptr)
+{
+  struct stap_args_info *a = (struct stap_args_info *) args_info_ptr;
+  int i;
+
+  for (i = 0; i < STAP_MAX_ARGS; i++)
+    if (a->arg->arg_str)
+      xfree (a->arg->arg_str);
+
+  xfree (a->arg);
+  xfree (a);
+}
 
 void
 stap_parse_probe_arguments (struct stap_probe *probe)
 {
   struct stap_args_info *args_info;
+  struct cleanup *back_to;
   const char *cur = probe->args;
   int current_arg = -1;
   enum
     {
       NEW_ARG,
-      OFFSET,
+      BITNESS,
       PARSE_ARG,
     } current_state;
 
@@ -88,7 +279,8 @@ stap_parse_probe_arguments (struct stap_probe *probe)
     return;
 
   args_info = xmalloc (sizeof (struct stap_args_info));
-  args_info->arg = xmalloc (STAP_MAX_ARGS * sizeof (struct stap_probe_arg));
+  back_to = make_cleanup (stap_free_args_info, args_info);
+  args_info->arg = xcalloc (STAP_MAX_ARGS, sizeof (struct stap_probe_arg));
 
   /* Ok, let's start.  */
   current_state = NEW_ARG;
@@ -103,17 +295,16 @@ stap_parse_probe_arguments (struct stap_probe *probe)
 	  if (current_arg >= STAP_MAX_ARGS)
 	    {
 	      /*complaint*/
-	      xfree (args_info->arg);
-	      xfree (args_info);
+	      do_cleanups (back_to);
 	      return;
 	    }
 
-	  current_state = OFFSET;
+	  current_state = BITNESS;
 	  break;
 
-	case OFFSET:
+	case BITNESS:
 	    {
-	      enum stap_arg_offset o;
+	      enum stap_arg_bitness b;
 	      int got_minus = 0;
 
 	      /* We expect to find something like:
@@ -127,8 +318,8 @@ stap_parse_probe_arguments (struct stap_probe *probe)
 		  && cur[1] != '@')
 		{
 		  current_state = PARSE_ARG;
-		  args_info->arg[current_arg].offset
-		    = STAP_ARG_OFFSET_UNDEFINED;
+		  args_info->arg[current_arg].bitness
+		    = STAP_ARG_BITNESS_UNDEFINED;
 		  break;
 		}
 
@@ -140,23 +331,22 @@ stap_parse_probe_arguments (struct stap_probe *probe)
 		}
 
 	      if (*cur == '4')
-		o = got_minus ? STAP_ARG_OFFSET_32BIT_SIGNED
-		  : STAP_ARG_OFFSET_32BIT_UNSIGNED;
+		b = got_minus ? STAP_ARG_BITNESS_32BIT_SIGNED
+		  : STAP_ARG_BITNESS_32BIT_UNSIGNED;
 	      else if (*cur == '8')
-		o = got_minus ? STAP_ARG_OFFSET_64BIT_SIGNED
-		  : STAP_ARG_OFFSET_64BIT_UNSIGNED;
+		b = got_minus ? STAP_ARG_BITNESS_64BIT_SIGNED
+		  : STAP_ARG_BITNESS_64BIT_UNSIGNED;
 	      else
 		{
 		  /*FIXME complaint*/
 
 		  /* We have an error, because we don't expect anything
 		     except 4 and 8.  */
-		  xfree (args_info->arg);
-		  xfree (args_info);
+		  do_cleanups (back_to);
 		  return;
 		}
 
-	      args_info->arg[current_arg].offset = o;
+	      args_info->arg[current_arg].bitness = b;
 	      /* Discard the number and the `@' sign.  */
 	      cur += 2;
 	      /* Move on.  */
@@ -165,12 +355,35 @@ stap_parse_probe_arguments (struct stap_probe *probe)
 	  break;
 
 	case PARSE_ARG:
-	  /* FIXME THIS IS JUST FOR TESTING  */
-	  while (*cur++ != ' ');
-	  /* Start it over again.  */
-	  current_state = NEW_ARG;
+	    {
+	      const char *start = cur;
+
+	      if (!stap_parse_arg (&cur))
+		{
+		  /* We have tried to parse this argument, but it's
+		     malformed.  This is an error.  */
+		  do_cleanups (back_to);
+		  return;
+		}
+
+	      args_info->arg[current_arg].arg_str
+		= savestring (start, cur - start);
+	      /* Start it over again.  */
+	      ep_skip_leading_whitespace ((char **) &cur);
+	      current_state = NEW_ARG;
+	    }
 	  break;
 	}
+
+      if (!*cur && current_state != NEW_ARG)
+	{
+	  /* We reached the end of the argument string, but we're
+	     still in the middle of the process of parsing an argument.
+	     It means the argument string is malformed.  */
+	  /* complaint*/
+	  do_cleanups (back_to);
+	  return;
+	}
     }
 
   args_info->n_args = current_arg + 1;
@@ -180,6 +393,8 @@ stap_parse_probe_arguments (struct stap_probe *probe)
   args_info->probe = probe;
 
   probe->parsed_args = args_info;
+
+  discard_cleanups (back_to);
 }
 
 int
@@ -203,15 +418,6 @@ stap_free_parsed_args (struct stap_args_info *parsed_args)
   xfree (parsed_args);
 }
 
-static void
-ep_skip_leading_whitespace (char **s)
-{
-  if ((s == NULL) || (*s == NULL))
-    return;
-  while (isspace (**s))
-    *s += 1;
-}
-
 /* A helper function to extract an argument from *ARG.  An argument is
    delimited by whitespace.  The return value is either NULL if no
    argument was found, or an xmalloc'd string.  */


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-03-02 19:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-02 19:36 [SCM] archer-sergiodj-stap: First version of the parser for the arguments sergiodj

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).