cppinit.c (init_standard_includes): The returned buffer is already malloc-ed.
authorNeil Booth <neil@daikokuya.demon.co.uk>
Mon, 20 Aug 2001 06:14:53 +0000 (06:14 +0000)
committerNeil Booth <neil@gcc.gnu.org>
Mon, 20 Aug 2001 06:14:53 +0000 (06:14 +0000)
* cppinit.c (init_standard_includes): The returned buffer
is already malloc-ed.
* gcc.c (add_prefix): Similarly.
* prefix.c (translate_name): Update to support clear buffer
ownership rules.
(update_path): Similarly.  Be sure to free any newly allocated
key.  UPDATE_PATH_HOST_CANONICALIZE takes only one argument.
(tr): New function.
* prefix.h (update_path): Update prototype and document.
* config/i386/xm-djgpp.h (UPDATE_PATH_HOST_CANONICALIZE): Clean
up and update to new buffer ownership rules.
* doc/gcc.texi (UPDATE_PATH_HOST_CANONICALIZE): Update.

From-SVN: r45043

gcc/ChangeLog
gcc/config/i386/xm-djgpp.h
gcc/cppinit.c
gcc/doc/gcc.texi
gcc/gcc.c
gcc/prefix.c
gcc/prefix.h

index d37e8f4d98ddc1ec9d6d0f2c99540102dade48cb..c7c501e37577710ed269f8c1d2590c388d48d35a 100644 (file)
@@ -1,3 +1,18 @@
+2001-08-20  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * cppinit.c (init_standard_includes): The returned buffer
+       is already malloc-ed.
+       * gcc.c (add_prefix): Similarly.
+       * prefix.c (translate_name): Update to support clear buffer
+       ownership rules.
+       (update_path): Similarly.  Be sure to free any newly allocated
+       key.  UPDATE_PATH_HOST_CANONICALIZE takes only one argument.
+       (tr): New function.
+       * prefix.h (update_path): Update prototype and document.
+       * config/i386/xm-djgpp.h (UPDATE_PATH_HOST_CANONICALIZE): Clean
+       up and update to new buffer ownership rules.
+       * doc/gcc.texi (UPDATE_PATH_HOST_CANONICALIZE): Update.
+
 Mon Aug 20 01:44:50 CEST 2001  Jan Hubicka  <jh@suse.cz>
 
        * final.c (compute_alignments): New function.
index c26a5cf7bc86e8c436e5e7a37b9be04f1d16a95f..cad1abf64c1c9a2c3353d70bcc99670cb35df804 100644 (file)
@@ -82,27 +82,17 @@ Boston, MA 02111-1307, USA.  */
     md_exec_prefix = update_path (md_exec_prefix, NULL); \
   } while (0)
 
-/* Canonicalize paths containing '/dev/env/', especially those in
-   prefix.c.  */
-#define UPDATE_PATH_HOST_CANONICALIZE(PATH, KEY) \
-  do { \
-    if (strncmp (PATH, "/dev/env/", sizeof("/dev/env/") - 1) == 0) \
-      { \
-        static char *djdir; \
-        static int djdir_len; \
-        static char fixed_path[FILENAME_MAX + 1]; \
-        char *new_path; \
-        /* The default prefixes all use '/dev/env/DJDIR', so optimize \
-           for this. All other uses of '/dev/env/' go through \
-           libc's canonicalization function.  */ \
-        _fixpath (PATH, fixed_path); \
-        /* _fixpath removes any trailing '/', so add it back.  */ \
-        strcat (fixed_path, "/"); \
-        new_path = xstrdup (fixed_path); \
-        PATH = new_path; \
-        return PATH; \
-      } \
-    /* If DIR_SEPARATOR_2 isn't in PATH, nothing more need be done.  */ \
-    if (strchr (PATH, DIR_SEPARATOR_2) == NULL) \
-      return PATH; \
-  } while (0)
+/* Canonicalize paths containing '/dev/env/'; used in prefix.c.
+   _fixpath is a djgpp-specific function to canonicalize a path.
+   "/dev/env/DJDIR" evaluates to "c:/djgpp" if DJDIR is "c:/djgpp" for
+   example.  It removes any trailing '/', so add it back.  */
+#define UPDATE_PATH_HOST_CANONICALIZE(PATH) \
+  if (memcmp ((PATH), "/dev/env/", sizeof("/dev/env/") - 1) == 0) \
+    {                                          \
+      static char fixed_path[FILENAME_MAX + 1];        \
+                                               \
+      _fixpath ((PATH), fixed_path);           \
+      strcat (fixed_path, "/");                        \
+      free (PATH);                             \
+      (PATH) = xstrdup (fixed_path);           \
+    } 
index 0b47abea185c2c57e8e8ad9ec2a71e7b359e35cc..4a78a938987ea89a352dc470a7dd868e6889cd8e 100644 (file)
@@ -861,7 +861,7 @@ init_standard_includes (pfile)
          || (CPP_OPTION (pfile, cplusplus)
              && !CPP_OPTION (pfile, no_standard_cplusplus_includes)))
        {
-         char *str = xstrdup (update_path (p->fname, p->component));
+         char *str = update_path (p->fname, p->component);
          append_include_chain (pfile, str, SYSTEM, p->cxx_aware);
        }
     }
index 862d2fe29db77a5d2f32519280ca1219a3c08bba..befee3643bbb4d01066ca188ac260968c80afc59 100644 (file)
@@ -4059,12 +4059,13 @@ If defined, a C statement (sans semicolon) that performs host-dependent
 initialization when a compilation driver is being initialized.
 
 @findex UPDATE_PATH_HOST_CANONICALIZE
-@item UPDATE_PATH_HOST_CANONICALIZE (@var{path}, @var{key})
+@item UPDATE_PATH_HOST_CANONICALIZE (@var{path})
 If defined, a C statement (sans semicolon) that performs host-dependent
-canonicalization when a path used in a compilation driver or preprocessor is
-canonicalized.  @var{path} is the path to be canonicalized, and @var{key} is
-a translation prefix when its value isn't @code{NULL}.  If the C statement
-does canonicalize @var{path}, the new path should be returned.
+canonicalization when a path used in a compilation driver or
+preprocessor is canonicalized.  @var{path} is a malloc-ed path to be
+canonicalized.  If the C statement does canonicalize @var{path} into a
+different buffer, the old path should be freed and the new buffer should
+have been allocated with malloc.
 @end table
 
 @findex bzero
index 5d1806323adf4f4a47a0df6b6efe99fc1bced08c..47cfa2e95ff33f1d2c77042b2757b1ba71fff817 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -2607,7 +2607,7 @@ add_prefix (pprefix, prefix, component, priority, require_machine_suffix, warn)
     pprefix->max_len = len;
 
   pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
-  pl->prefix = save_string (prefix, len);
+  pl->prefix = prefix;
   pl->require_machine_suffix = require_machine_suffix;
   pl->used_flag_ptr = warn;
   pl->priority = priority;
index 5fa47e75a634c6e083c5b8e64939671062aa3fd4..1ad88cfe8ec1abb7254d887f77cf6681b10e7e67 100644 (file)
@@ -74,8 +74,9 @@ Boston, MA 02111-1307, USA.  */
 static const char *std_prefix = PREFIX;
 
 static const char *get_key_value       PARAMS ((char *));
-static const char *translate_name      PARAMS ((const char *));
+static char *translate_name            PARAMS ((char *));
 static char *save_string               PARAMS ((const char *, int));
+static void tr                         PARAMS ((char *, int, int));
 
 #if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
 static char *lookup_key                PARAMS ((char *));
@@ -230,101 +231,119 @@ lookup_key (key)
 }
 #endif
 
-/* If NAME starts with a '@' or '$', apply the translation rules above
-   and return a new name.  Otherwise, return the given name.  */
+/* If NAME, a malloc-ed string, starts with a '@' or '$', apply the
+   translation rules above and return a newly malloc-ed name.
+   Otherwise, return the given name.  */
 
-static const char *
+static char *
 translate_name (name)
-  const char *name;
+     char *name;
 {
-  char code = name[0];
-  char *key;
-  const char *prefix = 0;
+  char code;
+  char *key, *old_name;
+  const char *prefix;
   int keylen;
 
-  if (code != '@' && code != '$')
-    return name;
-
-  for (keylen = 0;
-       (name[keylen + 1] != 0 && !IS_DIR_SEPARATOR (name[keylen + 1]));
-       keylen++)
-    ;
+  for (;;)
+    {
+      code = name[0];
+      if (code != '@' && code != '$')
+       break;
+
+      for (keylen = 0;
+          (name[keylen + 1] != 0 && !IS_DIR_SEPARATOR (name[keylen + 1]));
+          keylen++)
+       ;
+
+      key = (char *) alloca (keylen + 1);
+      strncpy (key, &name[1], keylen);
+      key[keylen] = 0;
+
+      if (code == '@')
+       {
+         prefix = get_key_value (key);
+         if (prefix == 0)
+           prefix = std_prefix;
+       }
+      else
+       prefix = getenv (key);
 
-  key = (char *) alloca (keylen + 1);
-  strncpy (key, &name[1], keylen);
-  key[keylen] = 0;
+      if (prefix == 0)
+       prefix = PREFIX;
 
-  name = &name[keylen + 1];
+      /* We used to strip trailing DIR_SEPARATORs here, but that can
+        sometimes yield a result with no separator when one was coded
+        and intended by the user, causing two path components to run
+        together.  */
 
-  if (code == '@')
-    {
-      prefix = get_key_value (key);
-      if (prefix == 0)
-       prefix = std_prefix;
+      old_name = name;
+      name = concat (prefix, &name[keylen + 1], NULL);
+      free (old_name);
     }
-  else
-    prefix = getenv (key);
 
-  if (prefix == 0)
-    prefix = PREFIX;
-
-  /* We used to strip trailing DIR_SEPARATORs here, but that can
-     sometimes yield a result with no separator when one was coded
-     and intended by the user, causing two path components to run
-     together.  */
+  return name;
+}
 
-  return concat (prefix, name, NULL);
+/* In a NUL-terminated STRING, replace character C1 with C2 in-place.  */
+static void
+tr (string, c1, c2)
+     char *string;
+     int c1, c2;
+{
+  do
+    {
+      if (*string == c1)
+       *string = c2;
+    }
+  while (*string++);
 }
 
-/* Update PATH using KEY if PATH starts with PREFIX.  */
+/* Update PATH using KEY if PATH starts with PREFIX.  The returned
+   string is always malloc-ed, and the caller is responsible for
+   freeing it.  */
 
-const char *
+char *
 update_path (path, key)
   const char *path;
   const char *key;
 {
+  char *result;
+
   if (! strncmp (path, std_prefix, strlen (std_prefix)) && key != 0)
     {
-      if (key[0] != '$')
-       key = concat ("@", key, NULL);
-
-      path = concat (key, &path[strlen (std_prefix)], NULL);
+      bool free_key = false;
 
-      while (path[0] == '@' || path[0] == '$')
-       path = translate_name (path);
+      if (key[0] != '$')
+       {
+         key = concat ("@", key, NULL);
+         free_key = true;
+       }
+
+      result = concat (key, &path[strlen (std_prefix)], NULL);
+      if (free_key)
+       free ((char *) key);
+      result = translate_name (result);
     }
+  else
+    result = xstrdup (path);
 
 #ifdef UPDATE_PATH_HOST_CANONICALIZE
-/* Perform host dependant canonicalization when needed.  */
-UPDATE_PATH_HOST_CANONICALIZE (path, key);
+  /* Perform host dependent canonicalization when needed.  */
+  UPDATE_PATH_HOST_CANONICALIZE (path);
 #endif
 
 #ifdef DIR_SEPARATOR_2
   /* Convert DIR_SEPARATOR_2 to DIR_SEPARATOR.  */
-  if (DIR_SEPARATOR != DIR_SEPARATOR_2)
-    {
-      char *new_path = xstrdup (path);
-      path = new_path;
-      do {
-       if (*new_path == DIR_SEPARATOR_2)
-         *new_path = DIR_SEPARATOR;
-      } while (*new_path++);
-    }
+  if (DIR_SEPARATOR_2 != DIR_SEPARATOR)
+    tr (result, DIR_SEPARATOR_2, DIR_SEPARATOR);
 #endif
-      
+
 #if defined (DIR_SEPARATOR) && !defined (DIR_SEPARATOR_2)
   if (DIR_SEPARATOR != '/')
-    {
-      char *new_path = xstrdup (path);
-      path = new_path;
-      do {
-       if (*new_path == '/')
-         *new_path = DIR_SEPARATOR;
-      } while (*new_path++);
-    }
+    tr (result, '/', DIR_SEPARATOR);
 #endif
 
-  return path;
+  return result;
 }
 
 /* Reset the standard prefix */
index 03c0d191fc25e04691672ba550852d9cfaf6e82c..b712900cd829fb8a263e0288bcc86750f7cef3fa 100644 (file)
@@ -22,7 +22,10 @@ Boston, MA 02111-1307, USA.  */
 #ifndef GCC_PREFIX_H
 #define GCC_PREFIX_H
 
-extern const char *update_path PARAMS ((const char *, const char *));
+/* Update PATH using KEY if PATH starts with PREFIX.  The returned
+   string is always malloc-ed, and the caller is responsible for
+   freeing it.  */
+extern char *update_path PARAMS ((const char *path, const char *key));
 extern void set_std_prefix PARAMS ((const char *, int));
 
 #endif /* ! GCC_PREFIX_H */