OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [prefix.c] - Blame information for rev 745

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 684 jeremybenn
/* Utility to update paths from internal to external forms.
2
   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3
   2007, 2011  Free Software Foundation, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify it under
8
the terms of the GNU Library General Public License as published by
9
the Free Software Foundation; either version 3 of the License, or (at
10
your option) any later version.
11
 
12
GCC is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
Library General Public License for more details.
16
 
17
You should have received a copy of the GNU Library General Public
18
License along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
20
 
21
/* This file contains routines to update a path, both to canonicalize
22
   the directory format and to handle any prefix translation.
23
 
24
   This file must be compiled with -DPREFIX= to specify the "prefix"
25
   value used by configure.  If a filename does not begin with this
26
   prefix, it will not be affected other than by directory canonicalization.
27
 
28
   Each caller of 'update_path' may specify both a filename and
29
   a translation prefix and consist of the name of the package that contains
30
   the file ("@GCC", "@BINUTIL", "@GNU", etc).
31
 
32
   If the prefix is not specified, the filename will only undergo
33
   directory canonicalization.
34
 
35
   If it is specified, the string given by PREFIX will be replaced
36
   by the specified prefix (with a '@' in front unless the prefix begins
37
   with a '$') and further translation will be done as follows
38
   until none of the two conditions below are met:
39
 
40
   1) If the filename begins with '@', the string between the '@' and
41
   the end of the name or the first '/' or directory separator will
42
   be considered a "key" and looked up as follows:
43
 
44
   -- If this is a Win32 OS, then the Registry will be examined for
45
      an entry of "key" in
46
 
47
      HKEY_LOCAL_MACHINE\SOFTWARE\Free Software Foundation\<KEY>
48
 
49
      if found, that value will be used. <KEY> defaults to GCC version
50
      string, but can be overridden at configuration time.
51
 
52
   -- If not found (or not a Win32 OS), the environment variable
53
      key_ROOT (the value of "key" concatenated with the constant "_ROOT")
54
      is tried.  If that fails, then PREFIX (see above) is used.
55
 
56
   2) If the filename begins with a '$', the rest of the string up
57
   to the end or the first '/' or directory separator will be used
58
   as an environment variable, whose value will be returned.
59
 
60
   Once all this is done, any '/' will be converted to DIR_SEPARATOR,
61
   if they are different.
62
 
63
   NOTE:  using resolve_keyed_path under Win32 requires linking with
64
   advapi32.dll.  */
65
 
66
 
67
#include "config.h"
68
#include "system.h"
69
#include "coretypes.h"
70
#if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
71
#include <windows.h>
72
#endif
73
#include "prefix.h"
74
#include "common/common-target.h"
75
 
76
static const char *std_prefix = PREFIX;
77
 
78
static const char *get_key_value (char *);
79
static char *translate_name (char *);
80
static char *save_string (const char *, int);
81
static void tr (char *, int, int);
82
 
83
#if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
84
static char *lookup_key (char *);
85
static HKEY reg_key = (HKEY) INVALID_HANDLE_VALUE;
86
#endif
87
 
88
/* Given KEY, as above, return its value.  */
89
 
90
static const char *
91
get_key_value (char *key)
92
{
93
  const char *prefix = 0;
94
  char *temp = 0;
95
 
96
#if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
97
  prefix = lookup_key (key);
98
#endif
99
 
100
  if (prefix == 0)
101
    prefix = getenv (temp = concat (key, "_ROOT", NULL));
102
 
103
  if (prefix == 0)
104
    prefix = std_prefix;
105
 
106
  free (temp);
107
 
108
  return prefix;
109
}
110
 
111
/* Return a copy of a string that has been placed in the heap.  */
112
 
113
static char *
114
save_string (const char *s, int len)
115
{
116
  char *result = XNEWVEC (char, len + 1);
117
 
118
  memcpy (result, s, len);
119
  result[len] = 0;
120
  return result;
121
}
122
 
123
#if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
124
 
125
#ifndef WIN32_REGISTRY_KEY
126
# define WIN32_REGISTRY_KEY BASEVER
127
#endif
128
 
129
/* Look up "key" in the registry, as above.  */
130
 
131
static char *
132
lookup_key (char *key)
133
{
134
  char *dst;
135
  DWORD size;
136
  DWORD type;
137
  LONG res;
138
 
139
  if (reg_key == (HKEY) INVALID_HANDLE_VALUE)
140
    {
141
      res = RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE", 0,
142
                           KEY_READ, &reg_key);
143
 
144
      if (res == ERROR_SUCCESS)
145
        res = RegOpenKeyExA (reg_key, "Free Software Foundation", 0,
146
                             KEY_READ, &reg_key);
147
 
148
      if (res == ERROR_SUCCESS)
149
        res = RegOpenKeyExA (reg_key, WIN32_REGISTRY_KEY, 0,
150
                             KEY_READ, &reg_key);
151
 
152
      if (res != ERROR_SUCCESS)
153
        {
154
          reg_key = (HKEY) INVALID_HANDLE_VALUE;
155
          return 0;
156
        }
157
    }
158
 
159
  size = 32;
160
  dst = xmalloc (size);
161
 
162
  res = RegQueryValueExA (reg_key, key, 0, &type, (LPBYTE) dst, &size);
163
  if (res == ERROR_MORE_DATA && type == REG_SZ)
164
    {
165
      dst = xrealloc (dst, size);
166
      res = RegQueryValueExA (reg_key, key, 0, &type, (LPBYTE) dst, &size);
167
    }
168
 
169
  if (type != REG_SZ || res != ERROR_SUCCESS)
170
    {
171
      free (dst);
172
      dst = 0;
173
    }
174
 
175
  return dst;
176
}
177
#endif
178
 
179
/* If NAME, a malloc-ed string, starts with a '@' or '$', apply the
180
   translation rules above and return a newly malloc-ed name.
181
   Otherwise, return the given name.  */
182
 
183
static char *
184
translate_name (char *name)
185
{
186
  char code;
187
  char *key, *old_name;
188
  const char *prefix;
189
  int keylen;
190
 
191
  for (;;)
192
    {
193
      code = name[0];
194
      if (code != '@' && code != '$')
195
        break;
196
 
197
      for (keylen = 0;
198
           (name[keylen + 1] != 0 && !IS_DIR_SEPARATOR (name[keylen + 1]));
199
           keylen++)
200
        ;
201
 
202
      key = (char *) alloca (keylen + 1);
203
      strncpy (key, &name[1], keylen);
204
      key[keylen] = 0;
205
 
206
      if (code == '@')
207
        {
208
          prefix = get_key_value (key);
209
          if (prefix == 0)
210
            prefix = std_prefix;
211
        }
212
      else
213
        prefix = getenv (key);
214
 
215
      if (prefix == 0)
216
        prefix = PREFIX;
217
 
218
      /* We used to strip trailing DIR_SEPARATORs here, but that can
219
         sometimes yield a result with no separator when one was coded
220
         and intended by the user, causing two path components to run
221
         together.  */
222
 
223
      old_name = name;
224
      name = concat (prefix, &name[keylen + 1], NULL);
225
      free (old_name);
226
    }
227
 
228
  return name;
229
}
230
 
231
/* In a NUL-terminated STRING, replace character C1 with C2 in-place.  */
232
static void
233
tr (char *string, int c1, int c2)
234
{
235
  do
236
    {
237
      if (*string == c1)
238
        *string = c2;
239
    }
240
  while (*string++);
241
}
242
 
243
/* Update PATH using KEY if PATH starts with PREFIX as a directory.
244
   The returned string is always malloc-ed, and the caller is
245
   responsible for freeing it.  */
246
 
247
char *
248
update_path (const char *path, const char *key)
249
{
250
  char *result, *p;
251
  const int len = strlen (std_prefix);
252
 
253
  if (! filename_ncmp (path, std_prefix, len)
254
      && (IS_DIR_SEPARATOR(path[len])
255
          || path[len] == '\0')
256
      && key != 0)
257
    {
258
      bool free_key = false;
259
 
260
      if (key[0] != '$')
261
        {
262
          key = concat ("@", key, NULL);
263
          free_key = true;
264
        }
265
 
266
      result = concat (key, &path[len], NULL);
267
      if (free_key)
268
        free (CONST_CAST (char *, key));
269
      result = translate_name (result);
270
    }
271
  else
272
    result = xstrdup (path);
273
 
274
  p = result;
275
  while (1)
276
    {
277
      char *src, *dest;
278
 
279
      p = strchr (p, '.');
280
      if (p == NULL)
281
        break;
282
      /* Look for `/../'  */
283
      if (p[1] == '.'
284
          && IS_DIR_SEPARATOR (p[2])
285
          && (p != result && IS_DIR_SEPARATOR (p[-1])))
286
        {
287
          *p = 0;
288
          if (!targetm_common.always_strip_dotdot
289
              && access (result, X_OK) == 0)
290
            {
291
              *p = '.';
292
              break;
293
            }
294
          else
295
            {
296
              /* We can't access the dir, so we won't be able to
297
                 access dir/.. either.  Strip out `dir/../'.  If `dir'
298
                 turns out to be `.', strip one more path component.  */
299
              dest = p;
300
              do
301
                {
302
                  --dest;
303
                  while (dest != result && IS_DIR_SEPARATOR (*dest))
304
                    --dest;
305
                  while (dest != result && !IS_DIR_SEPARATOR (dest[-1]))
306
                    --dest;
307
                }
308
              while (dest != result && *dest == '.');
309
              /* If we have something like `./..' or `/..', don't
310
                 strip anything more.  */
311
              if (*dest == '.' || IS_DIR_SEPARATOR (*dest))
312
                {
313
                  *p = '.';
314
                  break;
315
                }
316
              src = p + 3;
317
              while (IS_DIR_SEPARATOR (*src))
318
                ++src;
319
              p = dest;
320
              while ((*dest++ = *src++) != 0)
321
                ;
322
            }
323
        }
324
      else
325
        ++p;
326
    }
327
 
328
#ifdef UPDATE_PATH_HOST_CANONICALIZE
329
  /* Perform host dependent canonicalization when needed.  */
330
  UPDATE_PATH_HOST_CANONICALIZE (result);
331
#endif
332
 
333
#ifdef DIR_SEPARATOR_2
334
  /* Convert DIR_SEPARATOR_2 to DIR_SEPARATOR.  */
335
  if (DIR_SEPARATOR_2 != DIR_SEPARATOR)
336
    tr (result, DIR_SEPARATOR_2, DIR_SEPARATOR);
337
#endif
338
 
339
#if defined (DIR_SEPARATOR) && !defined (DIR_SEPARATOR_2)
340
  if (DIR_SEPARATOR != '/')
341
    tr (result, '/', DIR_SEPARATOR);
342
#endif
343
 
344
  return result;
345
}
346
 
347
/* Reset the standard prefix.  */
348
void
349
set_std_prefix (const char *prefix, int len)
350
{
351
  std_prefix = save_string (prefix, len);
352
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.