public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-sergiodj-stap: fix doc string for "catch marker"
@ 2011-01-17 20:35 tromey
  0 siblings, 0 replies; only message in thread
From: tromey @ 2011-01-17 20:35 UTC (permalink / raw)
  To: archer-commits

The branch, archer-sergiodj-stap has been updated
       via  b7a9daaf3f56a2a426b89b08923e20ba9371132f (commit)
       via  4d180e2357532a8339d3cb92ad0ed2e40b5095de (commit)
       via  20abd115b000cba8be265799ee7b1cf9eaab4858 (commit)
       via  e5daf4d3c44d71768a5c79c497610aea936ae748 (commit)
      from  4d3d0d2e6cd2850ef38c65d9751e3917ba6bfc83 (commit)

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

- Log -----------------------------------------------------------------
commit b7a9daaf3f56a2a426b89b08923e20ba9371132f
Author: Tom Tromey <tromey@redhat.com>
Date:   Mon Jan 17 13:34:20 2011 -0700

    fix doc string for "catch marker"

commit 4d180e2357532a8339d3cb92ad0ed2e40b5095de
Author: Tom Tromey <tromey@redhat.com>
Date:   Mon Jan 17 13:31:17 2011 -0700

    use regcomp and regexec -- cleaner and more efficient

commit 20abd115b000cba8be265799ee7b1cf9eaab4858
Author: Tom Tromey <tromey@redhat.com>
Date:   Mon Jan 17 13:16:53 2011 -0700

    Add completion support for catch marker

commit e5daf4d3c44d71768a5c79c497610aea936ae748
Author: Tom Tromey <tromey@redhat.com>
Date:   Mon Jan 17 10:41:58 2011 -0700

    Pull in regcomp / regfree code from gdb master

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

Summary of changes:
 gdb/breakpoint.c   |  193 ++++++++++++++++++++++++++++++++++++++--------------
 gdb/cli/cli-cmds.c |   26 ++++----
 gdb/gdb_regex.h    |    5 ++
 gdb/utils.c        |   56 +++++++++++++++
 4 files changed, 217 insertions(+), 63 deletions(-)

First 500 lines of diff:
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index f197641..1bce17d 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -9344,34 +9344,31 @@ static struct breakpoint_ops marker_catchpoint_ops = {
   print_recreate_marker_catchpoint
 };
 
-/* Completion function used by "catch marker".  */
-
-static char **complete_markers (struct cmd_list_element *cmd,
-				char *text, char *word)
-{
-  return NULL;			/* FIXME */
-}
-
 /* 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.  */
+   argument was found, or an xmalloc'd string.  If TERMINUS is NULL,
+   then the entire input string is considered; otherwise, the search
+   stops at TERMINUS, which must point into *ARG.  */
 
 static char *
-extract_arg (char **arg)
+extract_arg (char **arg, char *terminus)
 {
   char *result, *copy;
 
   if (!*arg)
     return NULL;
 
+  if (!terminus)
+    terminus = *arg + strlen (*arg);
+
   /* Find the start of the argument.  */
   ep_skip_leading_whitespace (arg);
-  if (! **arg)
+  if (! **arg || *arg >= terminus)
     return NULL;
   result = *arg;
 
   /* Find the end of the argument.  */
-  for (++*arg; **arg && ! isspace (**arg); ++*arg)
+  for (++*arg; *arg < terminus && **arg && ! isspace (**arg); ++*arg)
     ;
 
   if (result == *arg)
@@ -9401,17 +9398,17 @@ catch_marker_command (char *arg, int from_tty,
 
   cleanup = make_cleanup (VEC_cleanup (symtab_and_line_s), &salvec);
 
-  provider = extract_arg (&arg);
+  provider = extract_arg (&arg, NULL);
   if (!provider)
     error (_("provider name required"));
   make_cleanup (xfree, provider);
 
-  marker = extract_arg (&arg);
+  marker = extract_arg (&arg, NULL);
   if (!marker)
     error (_("marker name required"));
   make_cleanup (xfree, marker);
 
-  objname = extract_arg (&arg);
+  objname = extract_arg (&arg, NULL);
   if (objname)
     make_cleanup (xfree, objname);
 
@@ -9483,6 +9480,30 @@ struct stap_marker_and_objfile
 typedef struct stap_marker_and_objfile stap_entry;
 DEF_VEC_O (stap_entry);
 
+/* A helper function for collect_markers that compiles a regexp and
+   throws an exception on error.  This installs a cleanup to free the
+   resulting pattern on success.  If RX is NULL, this does nothing.  */
+
+static void
+compile_rx_or_error (regex_t *pattern, const char *rx, const char *message)
+{
+  int code;
+
+  if (!rx)
+    return;
+
+  code = regcomp (pattern, rx, REG_NOSUB);
+  if (code == 0)
+    make_regfree_cleanup (pattern);
+  else
+    {
+      char *err = get_regcomp_error (code, pattern);
+
+      make_cleanup (xfree, err);
+      error (_("%s: %s"), message, err);
+    }
+}
+
 /* Make a vector of markers matching OBJNAME, PROVIDER, and MARKER.
    Each argument is a regexp, or NULL, which matches anything.  */
 
@@ -9490,63 +9511,43 @@ static VEC (stap_entry) *
 collect_markers (char *objname, char *provider, char *marker)
 {
   struct objfile *objfile;
-  int need_compile = 1;
   VEC (stap_entry) *result = NULL;
   struct cleanup *cleanup;
+  regex_t obj_pat, prov_pat, mark_pat;
 
   cleanup = make_cleanup (VEC_cleanup (stap_entry), &result);
 
+  compile_rx_or_error (&prov_pat, provider, _("Invalid provider regexp"));
+  compile_rx_or_error (&mark_pat, marker, _("Invalid marker regexp"));
+  compile_rx_or_error (&obj_pat, objname, _("Invalid object file regexp"));
+
   ALL_OBJFILES (objfile)
   {
     const struct stap_marker *markers;
     int i, num_markers;
     stap_entry entry;
 
+    if (! objfile->sf || ! objfile->sf->sym_get_markers)
+      continue;
+
     if (objname)
       {
-	if (need_compile)
-	  {
-	    char *err = re_comp (objname);
-
-	    if (err)
-	      error (_("Invalid object file regexp: %s"), err);
-
-	    need_compile = 0;
-	  }
-
-	if (re_exec (objfile->name) == 0)
+	if (regexec (&obj_pat, objfile->name, 0, NULL, 0) != 0)
 	  continue;
       }
 
-    if (! objfile->sf || ! objfile->sf->sym_get_markers)
-      continue;
-
     markers = objfile->sf->sym_get_markers (objfile, &num_markers);
     for (i = 0; i < num_markers; ++i)
       {
 	if (provider)
 	  {
-	    char *err = re_comp (provider);
-
-	    if (err)
-	      error (_("Invalid provider regexp: %s"), err);
-
-	    need_compile = 1;
-
-	    if (re_exec (markers[i].provider) == 0)
+	    if (regexec (&prov_pat, markers[i].provider, 0, NULL, 0) != 0)
 	      continue;
 	  }
 
 	if (marker)
 	  {
-	    char *err = re_comp (marker);
-
-	    if (err)
-	      error (_("Invalid marker regexp: %s"), err);
-
-	    need_compile = 1;
-
-	    if (re_exec (markers[i].name) == 0)
+	    if (regexec (&mark_pat, markers[i].name, 0, NULL, 0) != 0)
 	      continue;
 	  }
 
@@ -9560,6 +9561,97 @@ collect_markers (char *objname, char *provider, char *marker)
   return result;
 }
 
+/* A helper function that calls extract_arg.  TEXT_PTR and WORD are
+   passed verbatim to extract_arg; *TEXT_PTR is updated.  If the
+   extracted argument ends before WORD, then this returns 1 and sets
+   *OUT to a regexp-quoted copy of the argument.  In this case this
+   function also makes a cleanup to free *OUT.  Otherwise, this does
+   not touch *OUT and returns 0.  */
+
+static int
+extract_arg_and_quote (char **text_ptr, char *word, char **out)
+{
+  char *result;
+
+  result = extract_arg (text_ptr, word);
+  if (!result)
+    return 1;
+
+  if (*text_ptr == word)
+    {
+      xfree (result);
+      return 1;
+    }
+
+  *out = regexp_quote (result);
+  xfree (result);
+  make_cleanup (xfree, *out);
+  return 0;
+}
+
+/* Completion function used by "catch marker".  */
+
+static char **complete_markers (struct cmd_list_element *cmd,
+				char *text, char *word)
+{
+  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
+  char *provider = NULL, *marker = NULL, *objname = NULL;
+  int complete_what, i;
+  VEC (char_ptr) *completions = NULL;
+  stap_entry *entry;
+  char **result;
+  VEC (stap_entry) *items;
+
+  /* Extract each argument as a regular expression that just matches
+     the argument.  Stop when we reach WORD and note which word we are
+     in.  */
+  if (extract_arg_and_quote (&text, word, &provider))
+    complete_what = 0;
+  else if (extract_arg_and_quote (&text, word, &marker))
+    complete_what = 1;
+  else if (extract_arg_and_quote (&text, word, &objname))
+    complete_what = 2;
+  else
+    {
+      /* WORD is past the end of the 3rd word in TEXT.  This is an
+	 invalid command, so just stop.  */
+      do_cleanups (cleanup);
+      return NULL;
+    }
+
+  items = collect_markers (objname, provider, marker);
+  make_cleanup (VEC_cleanup (stap_entry), &items);
+
+  make_cleanup (VEC_cleanup (char_ptr), &completions);
+  for (i = 0; VEC_iterate (stap_entry, items, i, entry); ++i)
+    {
+      char *value;
+
+      switch (complete_what)
+	{
+	case 0:
+	  value = entry->marker->provider;
+	  break;
+	case 1:
+	  value = entry->marker->name;
+	  break;
+	case 2:
+	  value = entry->objfile->name;
+	  break;
+	}
+
+      VEC_safe_push (char_ptr, completions, value);
+    }
+
+  VEC_safe_push (char_ptr, completions, NULL);
+  result = complete_on_enum ((const char **) VEC_address (char_ptr,
+							  completions),
+			     text, word);
+
+  do_cleanups (cleanup);
+  return result;
+}
+
 /* A qsort comparison function for stap_entry objects.  */
 
 static int
@@ -9596,17 +9688,17 @@ info_markers_command (char *arg, int from_tty)
   int i, addr_width, any_found;
   stap_entry *entry;
 
-  provider = extract_arg (&arg);
+  provider = extract_arg (&arg, NULL);
   if (provider)
     {
       make_cleanup (xfree, provider);
 
-      marker = extract_arg (&arg);
+      marker = extract_arg (&arg, NULL);
       if (marker)
 	{
 	  make_cleanup (xfree, marker);
 
-	  objname = extract_arg (&arg);
+	  objname = extract_arg (&arg, NULL);
 	  if (objname)
 	    make_cleanup (xfree, objname);
 	}
@@ -12620,7 +12712,8 @@ With an argument, catch only exceptions with the given name."),
 		     CATCH_TEMPORARY);
   add_catch_command ("marker", _("\
 Stop at a SystemTap static marker.\n\
-Arguments are the provider name and marker name."),
+Arguments are the provider name, the marker name, and an optional\n\
+object (executable or shared library) file name."),
 		     catch_marker_command,
 		     complete_markers,
 		     CATCH_PERMANENT,
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index ae02031..c11b257 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -1253,28 +1253,28 @@ show_user (char *args, int from_tty)
 void 
 apropos_command (char *searchstr, int from_tty)
 {
-  extern struct cmd_list_element *cmdlist; /* This is the main command
-					      list.  */
   regex_t pattern;
-  char *pattern_fastmap;
-  char errorbuffer[512];
+  int code;
 
-  pattern_fastmap = xcalloc (256, sizeof (char));
   if (searchstr == NULL)
-      error (_("REGEXP string is empty"));
+    error (_("REGEXP string is empty"));
 
-  if (regcomp(&pattern,searchstr,REG_ICASE) == 0)
+  code = regcomp (&pattern, searchstr, REG_ICASE);
+  if (code == 0)
     {
-      pattern.fastmap=pattern_fastmap;
-      re_compile_fastmap(&pattern);
-      apropos_cmd (gdb_stdout,cmdlist,&pattern,"");
+      struct cleanup *cleanups;
+
+      cleanups = make_regfree_cleanup (&pattern);
+      apropos_cmd (gdb_stdout, cmdlist, &pattern, "");
+      do_cleanups (cleanups);
     }
   else
     {
-      regerror(regcomp(&pattern,searchstr,REG_ICASE),NULL,errorbuffer,512);
-      error (_("Error in regular expression:%s"),errorbuffer);
+      char *err = get_regcomp_error (code, &pattern);
+
+      make_cleanup (xfree, err);
+      error (_("Error in regular expression: %s"), err);
     }
-  xfree (pattern_fastmap);
 }
 \f
 /* Print a list of files and line numbers which a user may choose from
diff --git a/gdb/gdb_regex.h b/gdb/gdb_regex.h
index ccdf9c3..a38aaca 100644
--- a/gdb/gdb_regex.h
+++ b/gdb/gdb_regex.h
@@ -28,4 +28,9 @@
 # include <regex.h>
 #endif
 
+/* From utils.c.  */
+struct cleanup *make_regfree_cleanup (regex_t *);
+char *get_regcomp_error (int, regex_t *);
+char *regexp_quote (const char *);
+
 #endif /* not GDB_REGEX_H */
diff --git a/gdb/utils.c b/gdb/utils.c
index 985f219..c8b315a 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -73,6 +73,7 @@
 
 #include "gdb_usleep.h"
 #include "interps.h"
+#include "gdb_regex.h"
 
 #if !HAVE_DECL_MALLOC
 extern PTR malloc ();		/* ARI: PTR */
@@ -1643,6 +1644,61 @@ gdb_print_host_address (const void *addr, struct ui_file *stream)
 }
 \f
 
+/* A cleanup function that calls regfree.  */
+
+static void
+do_regfree_cleanup (void *r)
+{
+  regfree (r);
+}
+
+/* Create a new cleanup that frees the compiled regular expression R.  */
+
+struct cleanup *
+make_regfree_cleanup (regex_t *r)
+{
+  return make_cleanup (do_regfree_cleanup, r);
+}
+
+/* Return an xmalloc'd error message resulting from a regular
+   expression compilation failure.  */
+
+char *
+get_regcomp_error (int code, regex_t *rx)
+{
+  size_t length = regerror (code, rx, NULL, 0);
+  char *result = xmalloc (length);
+
+  regerror (code, rx, result, length);
+  return result;
+}
+
+/* Return an xmalloc'd copy of STRING which is suitable for use as a
+   regular expression which will match just that string.  */
+
+char *
+regexp_quote (const char *string)
+{
+  char *result = xmalloc (3 + 2 * strlen (string));
+  char *out = result;
+
+  *out++ = '^';
+  while (*string)
+    {
+      if (*string == '[' || *string == ']' || *string == '\\'
+	  || *string == '.' || *string == '?' || *string == '+'
+	  || *string == '^' || *string == '$')
+	*out++ = '\\';
+      *out++ = *string++;
+    }
+  *out++ = '$';
+  *out = '\0';
+
+  return result;
+}
+
+\f
+
 /* This function supports the query, nquery, and yquery functions.
    Ask user a y-or-n question and return 0 if answer is no, 1 if
    answer is yes, or default the answer to the specified default


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


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

only message in thread, other threads:[~2011-01-17 20:35 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-17 20:35 [SCM] archer-sergiodj-stap: fix doc string for "catch marker" tromey

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).