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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [java/] [jcf-path.c] - Blame information for rev 859

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

Line No. Rev Author Line
1 287 jeremybenn
/* Handle CLASSPATH, -classpath, and path searching.
2
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
3
   2007, 2008 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
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3, or (at your option)
10
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
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.
20
 
21
Java and all Java-based marks are trademarks or registered trademarks
22
of Sun Microsystems, Inc. in the United States and other countries.
23
The Free Software Foundation is independent of Sun Microsystems, Inc.  */
24
 
25
/* Written by Tom Tromey <tromey@cygnus.com>, October 1998.  */
26
 
27
#include "config.h"
28
#include "system.h"
29
#include "coretypes.h"
30
#include "tm.h"
31
 
32
#include <dirent.h>
33
 
34
#include "jcf.h"
35
 
36
#ifndef DIR_UP
37
#define DIR_UP ".."
38
#endif
39
 
40
 
41
 
42
/* Possible flag values.  */
43
#define FLAG_SYSTEM 1
44
#define FLAG_ZIP    2
45
 
46
/* We keep linked lists of directory names.  A ``directory'' can be
47
   either an ordinary directory or a .zip file.  */
48
struct entry
49
{
50
  char *name;
51
  int flags;
52
  struct entry *next;
53
};
54
 
55
static void free_entry (struct entry **);
56
static void append_entry (struct entry **, struct entry *);
57
static void add_entry (struct entry **, const char *, int);
58
static void add_path (struct entry **, const char *, int);
59
 
60
/* We support several different ways to set the class path.
61
 
62
   built-in system directory (only libgcj.jar)
63
   CLASSPATH environment variable
64
   -classpath option overrides $CLASSPATH
65
   -CLASSPATH option is a synonym for -classpath (for compatibility)
66
   -bootclasspath overrides built-in
67
   -extdirs sets the extensions directory path (overrides built-in)
68
   -I prepends path to list
69
 
70
   We implement this by keeping several path lists, and then simply
71
   ignoring the ones which are not relevant.  */
72
 
73
/* This holds all the -I directories.  */
74
static struct entry *include_dirs;
75
 
76
/* This holds the CLASSPATH environment variable.  */
77
static struct entry *classpath_env;
78
 
79
/* This holds the -classpath command-line option.  */
80
static struct entry *classpath_user;
81
 
82
/* This holds the default directories.  Some of these will have the
83
   "system" flag set.  */
84
static struct entry *sys_dirs;
85
 
86
/* This holds the extensions path entries.  */
87
static struct entry *extensions;
88
 
89
/* This is the sealed list.  It is just a combination of other lists.  */
90
static struct entry *sealed;
91
 
92
/* We keep track of the longest path we've seen.  */
93
static int longest_path = 0;
94
 
95
 
96
 
97
static void
98
free_entry (struct entry **entp)
99
{
100
  struct entry *e, *n;
101
 
102
  for (e = *entp; e; e = n)
103
    {
104
      n = e->next;
105
      free (e->name);
106
      free (e);
107
    }
108
  *entp = NULL;
109
}
110
 
111
static void
112
append_entry (struct entry **entp, struct entry *ent)
113
{
114
  /* It doesn't matter if this is slow, since it is run only at
115
     startup, and then infrequently.  */
116
  struct entry *e;
117
 
118
  /* Find end of list.  */
119
  for (e = *entp; e && e->next; e = e->next)
120
    ;
121
 
122
  if (e)
123
    e->next = ent;
124
  else
125
    *entp = ent;
126
}
127
 
128
static void
129
add_entry (struct entry **entp, const char *filename, int is_system)
130
{
131
  int len;
132
  struct entry *n;
133
 
134
  n = XNEW (struct entry);
135
  n->flags = is_system ? FLAG_SYSTEM : 0;
136
  n->next = NULL;
137
 
138
  len = strlen (filename);
139
 
140
  if (len > 4 && (FILENAME_CMP (filename + len - 4, ".zip") == 0
141
                  || FILENAME_CMP (filename + len - 4, ".jar") == 0))
142
    {
143
      n->flags |= FLAG_ZIP;
144
      /* If the user uses -classpath then he'll have to include
145
         libgcj.jar in the value.  We check for this in a simplistic
146
         way.  Symlinks will fool this test.  This is only used for
147
         -MM and -MMD, so it probably isn't terribly important.  */
148
      if (! FILENAME_CMP (filename, LIBGCJ_ZIP_FILE))
149
        n->flags |= FLAG_SYSTEM;
150
    }
151
 
152
  /* Note that we add a trailing separator to `.zip' names as well.
153
     This is a little hack that lets the searching code in jcf-io.c
154
     work more easily.  Eww.  */
155
  if (! IS_DIR_SEPARATOR (filename[len - 1]))
156
    {
157
      char *f2 = (char *) alloca (len + 2);
158
      strcpy (f2, filename);
159
      f2[len] = DIR_SEPARATOR;
160
      f2[len + 1] = '\0';
161
      n->name = xstrdup (f2);
162
      ++len;
163
    }
164
  else
165
    n->name = xstrdup (filename);
166
 
167
  if (len > longest_path)
168
    longest_path = len;
169
 
170
  append_entry (entp, n);
171
}
172
 
173
static void
174
add_path (struct entry **entp, const char *cp, int is_system)
175
{
176
  const char *startp, *endp;
177
 
178
  if (cp)
179
    {
180
      char *buf = (char *) alloca (strlen (cp) + 3);
181
      startp = endp = cp;
182
      while (1)
183
        {
184
          if (! *endp || *endp == PATH_SEPARATOR)
185
            {
186
              if (endp == startp)
187
                {
188
                  buf[0] = '.';
189
                  buf[1] = DIR_SEPARATOR;
190
                  buf[2] = '\0';
191
                }
192
              else
193
                {
194
                  strncpy (buf, startp, endp - startp);
195
                  buf[endp - startp] = '\0';
196
                }
197
              add_entry (entp, buf, is_system);
198
              if (! *endp)
199
                break;
200
              ++endp;
201
              startp = endp;
202
            }
203
          else
204
            ++endp;
205
        }
206
    }
207
}
208
 
209
static int init_done = 0;
210
 
211
/* Initialize the path module.  */
212
void
213
jcf_path_init (void)
214
{
215
  char *cp;
216
  char *attempt, sep[2];
217
  struct stat stat_b;
218
  int found = 0, len;
219
 
220
  if (init_done)
221
    return;
222
  init_done = 1;
223
 
224
  sep[0] = DIR_SEPARATOR;
225
  sep[1] = '\0';
226
 
227
  GET_ENVIRONMENT (cp, "GCC_EXEC_PREFIX");
228
  if (cp)
229
    {
230
      attempt = (char *) alloca (strlen (cp) + 50);
231
      /* The exec prefix can be something like
232
         /usr/local/bin/../lib/gcc-lib/.  We want to change this
233
         into a pointer to the share/java directory.  We support two
234
         configurations: one where prefix and exec-prefix are the
235
         same, and one where exec-prefix is `prefix/SOMETHING'.  */
236
      strcpy (attempt, cp);
237
      strcat (attempt, DIR_UP);
238
      strcat (attempt, sep);
239
      strcat (attempt, DIR_UP);
240
      strcat (attempt, sep);
241
      len = strlen (attempt);
242
 
243
      strcpy (attempt + len, "share");
244
      strcat (attempt, sep);
245
      strcat (attempt, "java");
246
      strcat (attempt, sep);
247
      strcat (attempt, "libgcj-" DEFAULT_TARGET_VERSION ".jar");
248
      if (! stat (attempt, &stat_b))
249
        {
250
          add_entry (&sys_dirs, attempt, 1);
251
          found = 1;
252
          strcpy (&attempt[strlen (attempt)
253
                           - strlen ("libgcj-" DEFAULT_TARGET_VERSION ".jar")],
254
                  sep);
255
          strcat (attempt, "ext");
256
          strcat (attempt, sep);
257
          if (! stat (attempt, &stat_b))
258
            jcf_path_extdirs_arg (attempt);
259
        }
260
      else
261
        {
262
          strcpy (attempt + len, DIR_UP);
263
          strcat (attempt, sep);
264
          strcat (attempt, "share");
265
          strcat (attempt, sep);
266
          strcat (attempt, "java");
267
          strcat (attempt, sep);
268
          strcat (attempt, "libgcj-" DEFAULT_TARGET_VERSION ".jar");
269
          if (! stat (attempt, &stat_b))
270
            {
271
              add_entry (&sys_dirs, attempt, 1);
272
              found = 1;
273
              strcpy (&attempt[strlen (attempt)
274
                               - strlen ("libgcj-" DEFAULT_TARGET_VERSION ".jar")],
275
                      sep);
276
              strcat (attempt, "ext");
277
              strcat (attempt, sep);
278
              if (! stat (attempt, &stat_b))
279
                jcf_path_extdirs_arg (attempt);
280
            }
281
        }
282
    }
283
  if (! found)
284
    {
285
      /* Desperation: use the installed one.  */
286
      char *extdirs;
287
      add_entry (&sys_dirs, LIBGCJ_ZIP_FILE, 1);
288
      extdirs = (char *) alloca (strlen (LIBGCJ_ZIP_FILE) + 1);
289
      strcpy (extdirs, LIBGCJ_ZIP_FILE);
290
      strcpy (&extdirs[strlen (LIBGCJ_ZIP_FILE)
291
                      - strlen ("libgcj-" DEFAULT_TARGET_VERSION ".jar")],
292
              "ext");
293
      strcat (extdirs, sep);
294
      if (! stat (extdirs, &stat_b))
295
        jcf_path_extdirs_arg (extdirs);
296
    }
297
 
298
  GET_ENVIRONMENT (cp, "CLASSPATH");
299
  add_path (&classpath_env, cp, 0);
300
}
301
 
302
/* Call this when -classpath is seen on the command line.
303
   This overrides only the $CLASSPATH environment variable.
304
 */
305
void
306
jcf_path_classpath_arg (const char *path)
307
{
308
  free_entry (&classpath_user);
309
  add_path (&classpath_user, path, 0);
310
}
311
 
312
/* Call this when -bootclasspath is seen on the command line.
313
 */
314
void
315
jcf_path_bootclasspath_arg (const char *path)
316
{
317
  free_entry (&sys_dirs);
318
  add_path (&sys_dirs, path, 1);
319
}
320
 
321
/* Call this when -extdirs is seen on the command line.
322
 */
323
void
324
jcf_path_extdirs_arg (const char *cp)
325
{
326
  const char *startp, *endp;
327
 
328
  free_entry (&extensions);
329
 
330
  if (cp)
331
    {
332
      char *buf = (char *) alloca (strlen (cp) + 3);
333
      startp = endp = cp;
334
      while (1)
335
        {
336
          if (! *endp || *endp == PATH_SEPARATOR)
337
            {
338
              if (endp == startp)
339
                return;
340
 
341
              strncpy (buf, startp, endp - startp);
342
              buf[endp - startp] = '\0';
343
 
344
              {
345
                DIR *dirp = NULL;
346
                int dirname_length = strlen (buf);
347
 
348
                dirp = opendir (buf);
349
                if (dirp == NULL)
350
                  return;
351
 
352
                for (;;)
353
                  {
354
                    struct dirent *direntp = readdir (dirp);
355
 
356
                    if (!direntp)
357
                      break;
358
 
359
                    if (direntp->d_name[0] != '.')
360
                      {
361
                        char *name = (char *) alloca (dirname_length
362
                                             + strlen (direntp->d_name) + 2);
363
                        strcpy (name, buf);
364
                        if (! IS_DIR_SEPARATOR (name[dirname_length-1]))
365
                          {
366
                            name[dirname_length] = DIR_SEPARATOR;
367
                            name[dirname_length+1] = 0;
368
                          }
369
                        strcat (name, direntp->d_name);
370
                        add_entry (&extensions, name, 0);
371
                      }
372
                  }
373
                if (dirp)
374
                  closedir (dirp);
375
              }
376
 
377
              if (! *endp)
378
                break;
379
              ++endp;
380
              startp = endp;
381
            }
382
          else
383
            ++endp;
384
        }
385
    }
386
}
387
 
388
/* Call this when -I is seen on the command line.  */
389
void
390
jcf_path_include_arg (const char *path)
391
{
392
  add_entry (&include_dirs, path, 0);
393
}
394
 
395
/* We `seal' the path by linking everything into one big list.  Then
396
   we provide a way to iterate through the sealed list.  If PRINT is
397
   true then we print the final class path to stderr.  */
398
void
399
jcf_path_seal (int print)
400
{
401
  struct entry *secondary;
402
 
403
  sealed = include_dirs;
404
  include_dirs = NULL;
405
 
406
  if (classpath_user)
407
    {
408
      secondary = classpath_user;
409
      classpath_user = NULL;
410
    }
411
  else
412
    {
413
      if (! classpath_env)
414
        add_entry (&classpath_env, ".", 0);
415
 
416
      secondary = classpath_env;
417
      classpath_env = NULL;
418
    }
419
 
420
 
421
  free_entry (&classpath_user);
422
  free_entry (&classpath_env);
423
 
424
  append_entry (&sealed, secondary);
425
  append_entry (&sealed, sys_dirs);
426
  append_entry (&sealed, extensions);
427
  sys_dirs = NULL;
428
  extensions = NULL;
429
 
430
  if (print)
431
    {
432
      struct entry *ent;
433
      fprintf (stderr, "Class path starts here:\n");
434
      for (ent = sealed; ent; ent = ent->next)
435
        {
436
          fprintf (stderr, "    %s", ent->name);
437
          if ((ent->flags & FLAG_SYSTEM))
438
            fprintf (stderr, " (system)");
439
          if ((ent->flags & FLAG_ZIP))
440
            fprintf (stderr, " (zip)");
441
          fprintf (stderr, "\n");
442
        }
443
    }
444
}
445
 
446
void *
447
jcf_path_start (void)
448
{
449
  return (void *) sealed;
450
}
451
 
452
void *
453
jcf_path_next (void *x)
454
{
455
  struct entry *ent = (struct entry *) x;
456
  return (void *) ent->next;
457
}
458
 
459
static const char
460
PATH_SEPARATOR_STR[] = {PATH_SEPARATOR, '\0'};
461
 
462
char *
463
jcf_path_compute (const char *prefix)
464
{
465
  struct entry *iter;
466
  char *result;
467
  int length = strlen (prefix) + 1;
468
  int first;
469
 
470
  for (iter = sealed; iter != NULL; iter = iter->next)
471
    length += strlen (iter->name) + 1;
472
 
473
  result = (char *) xmalloc (length);
474
  strcpy (result, prefix);
475
  first = 1;
476
  for (iter = sealed; iter != NULL; iter = iter->next)
477
    {
478
      if (! first)
479
        strcat (result, PATH_SEPARATOR_STR);
480
      first = 0;
481
      strcat (result, iter->name);
482
      /* Ugly: we want to strip the '/' from zip entries when
483
         computing a string classpath.  */
484
      if ((iter->flags & FLAG_ZIP) != 0)
485
        result[strlen (result) - 1] = '\0';
486
    }
487
 
488
  return result;
489
}
490
 
491
/* We guarantee that the return path will either be a zip file, or it
492
   will end with a directory separator.  */
493
char *
494
jcf_path_name (void *x)
495
{
496
  struct entry *ent = (struct entry *) x;
497
  return ent->name;
498
}
499
 
500
int
501
jcf_path_is_zipfile (void *x)
502
{
503
  struct entry *ent = (struct entry *) x;
504
  return (ent->flags & FLAG_ZIP);
505
}
506
 
507
int
508
jcf_path_is_system (void *x)
509
{
510
  struct entry *ent = (struct entry *) x;
511
  return (ent->flags & FLAG_SYSTEM);
512
}
513
 
514
int
515
jcf_path_max_len (void)
516
{
517
  return longest_path;
518
}

powered by: WebSVN 2.1.0

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