diff options
author | neil <neil@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-08-20 06:14:53 +0000 |
---|---|---|
committer | neil <neil@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-08-20 06:14:53 +0000 |
commit | 17b80c08ecff239bdb1ab5b10ad6d98819d67791 (patch) | |
tree | a03bfc505ec1118b3947c2fbbf52975e90cc2d08 /gcc/prefix.c | |
parent | 312866af43c7d34fa7b50f97f20058108888e844 (diff) | |
download | gcc-17b80c08ecff239bdb1ab5b10ad6d98819d67791.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45043 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/prefix.c')
-rw-r--r-- | gcc/prefix.c | 145 |
1 files changed, 82 insertions, 63 deletions
diff --git a/gcc/prefix.c b/gcc/prefix.c index 5fa47e75a63..1ad88cfe8ec 100644 --- a/gcc/prefix.c +++ b/gcc/prefix.c @@ -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 */ |