gdb/
authorJan Kratochvil <jan.kratochvil@redhat.com>
Tue, 17 Apr 2012 15:47:09 +0000 (15:47 +0000)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Tue, 17 Apr 2012 15:47:09 +0000 (15:47 +0000)
Code cleanup.
* charset.c (find_charset_names): Remove variables ix and elt.
Use free_char_ptr_vec.
* elfread.c (build_id_to_debug_filename): New variables debugdir_vec,
back_to and ix.  Use dirnames_to_char_ptr_vec.  Remove variable
debugdir_end.  New variable debugdir_len.
* gdb_vecs.h (free_char_ptr_vec, make_cleanup_free_char_ptr_vec)
(dirnames_to_char_ptr_vec_append, dirnames_to_char_ptr_vec): New
declarations.
* progspace.c (clear_program_space_solib_cache): Remove variables ix
and elt.  Use free_char_ptr_vec.
* source.c (add_path): Remove variables argv, arg and argv_index.
New variables dir_vec, back_to, ix and name.
Use dirnames_to_char_ptr_vec_append.  Use freeargv instead of
make_cleanup_freeargv.  Remove variable separator.  Simplify the code
no longer expecting DIRNAME_SEPARATOR.
(openp): Remove variable p, p1 and len.  New variables dir_vec,
back_to, ix and dir.  Use dirnames_to_char_ptr_vec.  Simplify the code
no longer expecting DIRNAME_SEPARATOR.
* symfile.c (find_separate_debug_file): New variables debugdir_vec,
back_to and ix.  Use dirnames_to_char_ptr_vec.  Remove variable
debugdir_end.
* utils.c (free_char_ptr_vec, do_free_char_ptr_vec)
(make_cleanup_free_char_ptr_vec, dirnames_to_char_ptr_vec_append)
(dirnames_to_char_ptr_vec): New functions.

gdb/ChangeLog
gdb/charset.c
gdb/elfread.c
gdb/gdb_vecs.h
gdb/progspace.c
gdb/source.c
gdb/symfile.c
gdb/utils.c

index 4e6aef02fed3c5834da078b508b7cf829440b948..6f9608a5f4c465a8d2bd48af160af6bea5a3790b 100644 (file)
@@ -1,3 +1,31 @@
+2012-04-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Code cleanup.
+       * charset.c (find_charset_names): Remove variables ix and elt.
+       Use free_char_ptr_vec.
+       * elfread.c (build_id_to_debug_filename): New variables debugdir_vec,
+       back_to and ix.  Use dirnames_to_char_ptr_vec.  Remove variable
+       debugdir_end.  New variable debugdir_len.
+       * gdb_vecs.h (free_char_ptr_vec, make_cleanup_free_char_ptr_vec)
+       (dirnames_to_char_ptr_vec_append, dirnames_to_char_ptr_vec): New
+       declarations.
+       * progspace.c (clear_program_space_solib_cache): Remove variables ix
+       and elt.  Use free_char_ptr_vec.
+       * source.c (add_path): Remove variables argv, arg and argv_index.
+       New variables dir_vec, back_to, ix and name.
+       Use dirnames_to_char_ptr_vec_append.  Use freeargv instead of
+       make_cleanup_freeargv.  Remove variable separator.  Simplify the code
+       no longer expecting DIRNAME_SEPARATOR.
+       (openp): Remove variable p, p1 and len.  New variables dir_vec,
+       back_to, ix and dir.  Use dirnames_to_char_ptr_vec.  Simplify the code
+       no longer expecting DIRNAME_SEPARATOR.
+       * symfile.c (find_separate_debug_file): New variables debugdir_vec,
+       back_to and ix.  Use dirnames_to_char_ptr_vec.  Remove variable
+       debugdir_end.
+       * utils.c (free_char_ptr_vec, do_free_char_ptr_vec)
+       (make_cleanup_free_char_ptr_vec, dirnames_to_char_ptr_vec_append)
+       (dirnames_to_char_ptr_vec): New functions.
+
 2012-04-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        Code cleanup.
index 4a209a553cb3a1fcbf2fb117848f6a83175fbeb1..89baf461f4a0b684efae74f6533e2717362af90c 100644 (file)
@@ -909,11 +909,8 @@ find_charset_names (void)
   if (fail)
     {
       /* Some error occurred, so drop the vector.  */
-      int ix;
-      char *elt;
-      for (ix = 0; VEC_iterate (char_ptr, charsets, ix, elt); ++ix)
-       xfree (elt);
-      VEC_truncate (char_ptr, charsets, 0);
+      free_char_ptr_vec (charsets);
+      charsets = NULL;
     }
   else
     VEC_safe_push (char_ptr, charsets, NULL);
index 9f8a7e8bf0f1b81d973cce5458c3f2faaf6d5548..117e674e3cfb7415d52911812597f82273019c2a 100644 (file)
@@ -1123,6 +1123,9 @@ static char *
 build_id_to_debug_filename (struct build_id *build_id)
 {
   char *link, *debugdir, *retval = NULL;
+  VEC (char_ptr) *debugdir_vec;
+  struct cleanup *back_to;
+  int ix;
 
   /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */
   link = alloca (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
@@ -1131,22 +1134,18 @@ build_id_to_debug_filename (struct build_id *build_id)
   /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
      cause "/.build-id/..." lookups.  */
 
-  debugdir = debug_file_directory;
-  do
+  debugdir_vec = dirnames_to_char_ptr_vec (debug_file_directory);
+  back_to = make_cleanup_free_char_ptr_vec (debugdir_vec);
+
+  for (ix = 0; VEC_iterate (char_ptr, debugdir_vec, ix, debugdir); ++ix)
     {
-      char *s, *debugdir_end;
+      size_t debugdir_len = strlen (debugdir);
       gdb_byte *data = build_id->data;
       size_t size = build_id->size;
+      char *s;
 
-      while (*debugdir == DIRNAME_SEPARATOR)
-       debugdir++;
-
-      debugdir_end = strchr (debugdir, DIRNAME_SEPARATOR);
-      if (debugdir_end == NULL)
-       debugdir_end = &debugdir[strlen (debugdir)];
-
-      memcpy (link, debugdir, debugdir_end - debugdir);
-      s = &link[debugdir_end - debugdir];
+      memcpy (link, debugdir, debugdir_len);
+      s = &link[debugdir_len];
       s += sprintf (s, "/.build-id/");
       if (size > 0)
        {
@@ -1171,11 +1170,9 @@ build_id_to_debug_filename (struct build_id *build_id)
 
       if (retval != NULL)
        break;
-
-      debugdir = debugdir_end;
     }
-  while (*debugdir != 0);
 
+  do_cleanups (back_to);
   return retval;
 }
 
index 04bd711f6907d3bedd7448eba064f6a41cb84e01..b9e0b14dd52fe56c2d07c4b5c30205512d7e205e 100644 (file)
 
 DEF_VEC_P (char_ptr);
 
+/* From utils.c: */
+
+extern void free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec);
+
+extern struct cleanup *
+  make_cleanup_free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec);
+
+extern void dirnames_to_char_ptr_vec_append (VEC (char_ptr) **vecp,
+                                            const char *dirnames);
+
+extern VEC (char_ptr) *dirnames_to_char_ptr_vec (const char *dirnames);
+
 #endif /* GDB_VECS_H */
index 54531d9b1fb20b014dae90b95b7e1ed0a2448712..1065c277b9207c09b897a80f40fa6a5713e8b348 100644 (file)
@@ -509,13 +509,10 @@ switch_to_program_space_and_thread (struct program_space *pspace)
 void
 clear_program_space_solib_cache (struct program_space *pspace)
 {
-  int ix;
-  char *name;
-
   VEC_free (so_list_ptr, pspace->added_solibs);
-  for (ix = 0; VEC_iterate (char_ptr, pspace->deleted_solibs, ix, name); ++ix)
-    xfree (name);
-  VEC_free (char_ptr, pspace->deleted_solibs);
+
+  free_char_ptr_vec (pspace->deleted_solibs);
+  pspace->deleted_solibs = NULL;
 }
 
 \f
index 8e7acf8f0b1df711dca8dc2f7cd7c7e3f103b8b7..27c5b0e00b52d780f4c5106b6beb75d03292d6d6 100644 (file)
@@ -440,62 +440,40 @@ add_path (char *dirname, char **which_path, int parse_separators)
 {
   char *old = *which_path;
   int prefix = 0;
-  char **argv = NULL;
-  char *arg;
-  int argv_index = 0;
+  VEC (char_ptr) *dir_vec = NULL;
+  struct cleanup *back_to;
+  int ix;
+  char *name;
 
   if (dirname == 0)
     return;
 
   if (parse_separators)
     {
+      char **argv, **argvp;
+
       /* This will properly parse the space and tab separators
-        and any quotes that may exist.  DIRNAME_SEPARATOR will
-        be dealt with later.  */
+        and any quotes that may exist.  */
       argv = gdb_buildargv (dirname);
-      make_cleanup_freeargv (argv);
 
-      arg = argv[0];
+      for (argvp = argv; *argvp; argvp++)
+       dirnames_to_char_ptr_vec_append (&dir_vec, *argvp);
+
+      freeargv (argv);
     }
   else
-    {
-      arg = xstrdup (dirname);
-      make_cleanup (xfree, arg);
-    }
+    VEC_safe_push (char_ptr, dir_vec, xstrdup (dirname));
+  back_to = make_cleanup_free_char_ptr_vec (dir_vec);
 
-  do
+  for (ix = 0; VEC_iterate (char_ptr, dir_vec, ix, name); ++ix)
     {
-      char *name = arg;
       char *p;
       struct stat st;
 
-      {
-       char *separator = NULL;
-
-       /* Spaces and tabs will have been removed by buildargv().
-          The directories will there be split into a list but
-          each entry may still contain DIRNAME_SEPARATOR.  */
-       if (parse_separators)
-         separator = strchr (name, DIRNAME_SEPARATOR);
-
-       if (separator == 0)
-         p = arg = name + strlen (name);
-       else
-         {
-           p = separator;
-           arg = p + 1;
-           while (*arg == DIRNAME_SEPARATOR)
-             ++arg;
-         }
-
-       /* If there are no more directories in this argument then start
-          on the next argument next time round the loop (if any).  */
-       if (*arg == '\0')
-         arg = parse_separators ? argv[++argv_index] : NULL;
-      }
-
-      /* name is the start of the directory.
-        p is the separator (or null) following the end.  */
+      /* Spaces and tabs will have been removed by buildargv().
+         NAME is the start of the directory.
+        P is the '\0' following the end.  */
+      p = name + strlen (name);
 
       while (!(IS_DIR_SEPARATOR (*name) && p <= name + 1)      /* "/" */
 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
@@ -576,26 +554,17 @@ add_path (char *dirname, char **which_path, int parse_separators)
        char tinybuf[2];
 
        p = *which_path;
-       while (1)
+       /* FIXME: we should use realpath() or its work-alike
+          before comparing.  Then all the code above which
+          removes excess slashes and dots could simply go away.  */
+       if (!filename_cmp (p, name))
          {
-           /* FIXME: we should use realpath() or its work-alike
-              before comparing.  Then all the code above which
-              removes excess slashes and dots could simply go away.  */
-           if (!filename_ncmp (p, name, len)
-               && (p[len] == '\0' || p[len] == DIRNAME_SEPARATOR))
-             {
-               /* Found it in the search path, remove old copy.  */
-               if (p > *which_path)
-                 p--;          /* Back over leading separator.  */
-               if (prefix > p - *which_path)
-                 goto skip_dup;        /* Same dir twice in one cmd.  */
-               memmove (p, &p[len + 1], strlen (&p[len + 1]) + 1);     /* Copy from next \0 or  : */
-             }
-           p = strchr (p, DIRNAME_SEPARATOR);
-           if (p != 0)
-             ++p;
-           else
-             break;
+           /* Found it in the search path, remove old copy.  */
+           if (p > *which_path)
+             p--;              /* Back over leading separator.  */
+           if (prefix > p - *which_path)
+             goto skip_dup;    /* Same dir twice in one cmd.  */
+           memmove (p, &p[len + 1], strlen (&p[len + 1]) + 1); /* Copy from next \0 or  : */
          }
 
        tinybuf[0] = DIRNAME_SEPARATOR;
@@ -628,7 +597,8 @@ add_path (char *dirname, char **which_path, int parse_separators)
     skip_dup:
       ;
     }
-  while (arg != NULL);
+
+  do_cleanups (back_to);
 }
 
 
@@ -709,10 +679,11 @@ openp (const char *path, int opts, const char *string,
 {
   int fd;
   char *filename;
-  const char *p;
-  const char *p1;
-  int len;
   int alloclen;
+  VEC (char_ptr) *dir_vec;
+  struct cleanup *back_to;
+  int ix;
+  char *dir;
 
   /* The open syscall MODE parameter is not specified.  */
   gdb_assert ((mode & O_CREAT) == 0);
@@ -775,16 +746,15 @@ openp (const char *path, int opts, const char *string,
   alloclen = strlen (path) + strlen (string) + 2;
   filename = alloca (alloclen);
   fd = -1;
-  for (p = path; p; p = p1 ? p1 + 1 : 0)
+
+  dir_vec = dirnames_to_char_ptr_vec (path);
+  back_to = make_cleanup_free_char_ptr_vec (dir_vec);
+
+  for (ix = 0; VEC_iterate (char_ptr, dir_vec, ix, dir); ++ix)
     {
-      p1 = strchr (p, DIRNAME_SEPARATOR);
-      if (p1)
-       len = p1 - p;
-      else
-       len = strlen (p);
+      size_t len = strlen (dir);
 
-      if (len == 4 && p[0] == '$' && p[1] == 'c'
-         && p[2] == 'w' && p[3] == 'd')
+      if (strcmp (dir, "$cwd") == 0)
        {
          /* Name is $cwd -- insert current directory name instead.  */
          int newlen;
@@ -802,8 +772,7 @@ openp (const char *path, int opts, const char *string,
       else
        {
          /* Normal file name in path -- just use it.  */
-         strncpy (filename, p, len);
-         filename[len] = 0;
+         strcpy (filename, dir);
 
          /* Don't search $cdir.  It's also a magic path like $cwd, but we
             don't have enough information to expand it.  The user *could*
@@ -812,7 +781,7 @@ openp (const char *path, int opts, const char *string,
             contexts.  If the user really has '$cdir' one can use './$cdir'.
             We can get $cdir when loading scripts.  When loading source files
             $cdir must have already been expanded to the correct value.  */
-         if (strcmp (filename, "$cdir") == 0)
+         if (strcmp (dir, "$cdir") == 0)
            continue;
        }
 
@@ -831,6 +800,8 @@ openp (const char *path, int opts, const char *string,
        }
     }
 
+  do_cleanups (back_to);
+
 done:
   if (filename_opened)
     {
index 816b574adfa1316220229e31a8b27fcad90e8414..cbdaa25dcc55507435bc5dad88c4ca1e39450927 100644 (file)
@@ -1441,6 +1441,9 @@ find_separate_debug_file (const char *dir,
   char *debugdir;
   char *debugfile;
   int i;
+  VEC (char_ptr) *debugdir_vec;
+  struct cleanup *back_to;
+  int ix;
 
   /* Set I to max (strlen (canon_dir), strlen (dir)).  */
   i = strlen (dir);
@@ -1475,20 +1478,12 @@ find_separate_debug_file (const char *dir,
      Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
      cause "/..." lookups.  */
 
-  debugdir = debug_file_directory;
-  do
-    {
-      char *debugdir_end;
-
-      while (*debugdir == DIRNAME_SEPARATOR)
-       debugdir++;
-
-      debugdir_end = strchr (debugdir, DIRNAME_SEPARATOR);
-      if (debugdir_end == NULL)
-       debugdir_end = &debugdir[strlen (debugdir)];
+  debugdir_vec = dirnames_to_char_ptr_vec (debug_file_directory);
+  back_to = make_cleanup_free_char_ptr_vec (debugdir_vec);
 
-      memcpy (debugfile, debugdir, debugdir_end - debugdir);
-      debugfile[debugdir_end - debugdir] = 0;
+  for (ix = 0; VEC_iterate (char_ptr, debugdir_vec, ix, debugdir); ++ix)
+    {
+      strcpy (debugfile, debugdir);
       strcat (debugfile, "/");
       strcat (debugfile, dir);
       strcat (debugfile, debuglink);
@@ -1503,8 +1498,7 @@ find_separate_debug_file (const char *dir,
                            strlen (gdb_sysroot)) == 0
          && IS_DIR_SEPARATOR (canon_dir[strlen (gdb_sysroot)]))
        {
-         memcpy (debugfile, debugdir, debugdir_end - debugdir);
-         debugfile[debugdir_end - debugdir] = 0;
+         strcpy (debugfile, debugdir);
          strcat (debugfile, canon_dir + strlen (gdb_sysroot));
          strcat (debugfile, "/");
          strcat (debugfile, debuglink);
@@ -1512,11 +1506,9 @@ find_separate_debug_file (const char *dir,
          if (separate_debug_file_exists (debugfile, crc32, objfile))
            return debugfile;
        }
-
-      debugdir = debugdir_end;
     }
-  while (*debugdir != 0);
 
+  do_cleanups (back_to);
   xfree (debugfile);
   return NULL;
 }
index 1096b3ad12eb18dc46cb3aa00eed65ca7423a739..104c5aa0a0a2020b3283399ec8e71d56f150297d 100644 (file)
@@ -3802,6 +3802,95 @@ producer_is_gcc_ge_4 (const char *producer)
   return minor;
 }
 
+/* Call xfree for each element of CHAR_PTR_VEC and final VEC_free for
+   CHAR_PTR_VEC itself.
+
+   You must not modify CHAR_PTR_VEC after it got registered with this function
+   by make_cleanup as the CHAR_PTR_VEC base address may change on its updates.
+   Contrary to VEC_free this function does not (cannot) clear the pointer.  */
+
+void
+free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec)
+{
+  int ix;
+  char *name;
+
+  for (ix = 0; VEC_iterate (char_ptr, char_ptr_vec, ix, name); ++ix)
+    xfree (name);
+  VEC_free (char_ptr, char_ptr_vec);
+}
+
+/* Helper for make_cleanup_free_char_ptr_vec.  */
+
+static void
+do_free_char_ptr_vec (void *arg)
+{
+  VEC (char_ptr) *char_ptr_vec = arg;
+
+  free_char_ptr_vec (char_ptr_vec);
+}
+
+/* Make cleanup handler calling xfree for each element of CHAR_PTR_VEC and
+   final VEC_free for CHAR_PTR_VEC itself.
+
+   You must not modify CHAR_PTR_VEC after this cleanup registration as the
+   CHAR_PTR_VEC base address may change on its updates.  Contrary to VEC_free
+   this function does not (cannot) clear the pointer.  */
+
+struct cleanup *
+make_cleanup_free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec)
+{
+  return make_cleanup (do_free_char_ptr_vec, char_ptr_vec);
+}
+
+/* Extended version of dirnames_to_char_ptr_vec - additionally if *VECP is
+   non-NULL the new list elements from DIRNAMES are appended to the existing
+   *VECP list of entries.  *VECP address will be updated by this call.  */
+
+void
+dirnames_to_char_ptr_vec_append (VEC (char_ptr) **vecp, const char *dirnames)
+{
+  do
+    {
+      size_t this_len;
+      char *next_dir, *this_dir;
+
+      next_dir = strchr (dirnames, DIRNAME_SEPARATOR);
+      if (next_dir == NULL)
+       this_len = strlen (dirnames);
+      else
+       {
+         this_len = next_dir - dirnames;
+         next_dir++;
+       }
+
+      this_dir = xmalloc (this_len + 1);
+      memcpy (this_dir, dirnames, this_len);
+      this_dir[this_len] = '\0';
+      VEC_safe_push (char_ptr, *vecp, this_dir);
+
+      dirnames = next_dir;
+    }
+  while (dirnames != NULL);
+}
+
+/* Split DIRNAMES by DIRNAME_SEPARATOR delimiter and return a list of all the
+   elements in their original order.  For empty string ("") DIRNAMES return
+   list of one empty string ("") element.
+   
+   You may modify the returned strings.
+   Read free_char_ptr_vec for its cleanup.  */
+
+VEC (char_ptr) *
+dirnames_to_char_ptr_vec (const char *dirnames)
+{
+  VEC (char_ptr) *retval = NULL;
+  
+  dirnames_to_char_ptr_vec_append (&retval, dirnames);
+
+  return retval;
+}
+
 #ifdef HAVE_WAITPID
 
 #ifdef SIGALRM