* semantics.c (finish_handler): End the scope of the handler
[official-gcc.git] / gcc / java / jcf-path.c
blob056be31d12cb930c7a7cfd80a918ce8b66e53188
1 /* Handle CLASSPATH, -classpath, and path searching.
3 Copyright (C) 1998, 1999 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNU CC; see the file COPYING. If not, write to
17 the Free Software Foundation, 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
20 Java and all Java-based marks are trademarks or registered trademarks
21 of Sun Microsystems, Inc. in the United States and other countries.
22 The Free Software Foundation is independent of Sun Microsystems, Inc. */
24 /* Written by Tom Tromey <tromey@cygnus.com>, October 1998. */
26 #include "config.h"
27 #include "system.h"
29 #include "jcf.h"
31 /* Some boilerplate that really belongs in a header. */
33 #ifndef GET_ENV_PATH_LIST
34 #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
35 #endif
37 /* By default, colon separates directories in a path. */
38 #ifndef PATH_SEPARATOR
39 #define PATH_SEPARATOR ':'
40 #endif
42 #ifndef DIR_SEPARATOR
43 #define DIR_SEPARATOR '/'
44 #endif
48 /* Possible flag values. */
49 #define FLAG_SYSTEM 1
50 #define FLAG_ZIP 2
52 /* We keep linked lists of directory names. A ``directory'' can be
53 either an ordinary directory or a .zip file. */
54 struct entry
56 char *name;
57 int flags;
58 struct entry *next;
61 static void free_entry PROTO ((struct entry **));
62 static void append_entry PROTO ((struct entry **, struct entry *));
63 static void add_entry PROTO ((struct entry **, const char *, int));
64 static void add_path PROTO ((struct entry **, const char *, int));
66 /* We support several different ways to set the class path.
68 built-in system directory (only libgcj.zip)
69 CLASSPATH environment variable
70 -CLASSPATH overrides CLASSPATH
71 -classpath option - overrides CLASSPATH, -CLASSPATH, and built-in
72 -I prepends path to list
74 We implement this by keeping several path lists, and then simply
75 ignoring the ones which are not relevant. */
77 /* This holds all the -I directories. */
78 static struct entry *include_dirs;
80 /* This holds the CLASSPATH environment variable. */
81 static struct entry *classpath_env;
83 /* This holds the -CLASSPATH command-line option. */
84 static struct entry *classpath_u;
86 /* This holds the -classpath command-line option. */
87 static struct entry *classpath_l;
89 /* This holds the default directories. Some of these will have the
90 "system" flag set. */
91 static struct entry *sys_dirs;
93 /* This is the sealed list. It is just a combination of other lists. */
94 static struct entry *sealed;
96 /* We keep track of the longest path we've seen. */
97 static int longest_path = 0;
101 static void
102 free_entry (entp)
103 struct entry **entp;
105 struct entry *e, *n;
107 for (e = *entp; e; e = n)
109 n = e->next;
110 free (e->name);
111 free (e);
113 *entp = NULL;
116 static void
117 append_entry (entp, ent)
118 struct entry **entp;
119 struct entry *ent;
121 /* It doesn't matter if this is slow, since it is run only at
122 startup, and then infrequently. */
123 struct entry *e;
125 /* Find end of list. */
126 for (e = *entp; e && e->next; e = e->next)
129 if (e)
130 e->next = ent;
131 else
132 *entp = ent;
135 static void
136 add_entry (entp, filename, is_system)
137 struct entry **entp;
138 const char *filename;
139 int is_system;
141 int len;
142 struct entry *n;
144 n = (struct entry *) ALLOC (sizeof (struct entry));
145 n->flags = is_system ? FLAG_SYSTEM : 0;
146 n->next = NULL;
148 len = strlen (filename);
149 if (len > 4 && (strcmp (filename + len - 4, ".zip") == 0
150 || strcmp (filename + len - 4, ".jar") == 0))
152 n->flags |= FLAG_ZIP;
153 /* If the user uses -classpath then he'll have to include
154 libgcj.zip in the value. We check for this in a simplistic
155 way. Symlinks will fool this test. This is only used for
156 -MM and -MMD, so it probably isn't terribly important. */
157 if (! strcmp (filename, LIBGCJ_ZIP_FILE))
158 n->flags |= FLAG_SYSTEM;
161 /* Note that we add a trailing separator to `.zip' names as well.
162 This is a little hack that lets the searching code in jcf-io.c
163 work more easily. Eww. */
164 if (filename[len - 1] != '/' && filename[len - 1] != DIR_SEPARATOR)
166 char *f2 = (char *) alloca (len + 2);
167 strcpy (f2, filename);
168 f2[len] = DIR_SEPARATOR;
169 f2[len + 1] = '\0';
170 n->name = xstrdup (f2);
171 ++len;
173 else
174 n->name = xstrdup (filename);
176 if (len > longest_path)
177 longest_path = len;
179 append_entry (entp, n);
182 static void
183 add_path (entp, cp, is_system)
184 struct entry **entp;
185 const char *cp;
186 int is_system;
188 const char *startp, *endp;
190 if (cp)
192 char *buf = (char *) alloca (strlen (cp) + 3);
193 startp = endp = cp;
194 while (1)
196 if (! *endp || *endp == PATH_SEPARATOR)
198 if (endp == startp)
200 buf[0] = '.';
201 buf[1] = DIR_SEPARATOR;
202 buf[2] = '\0';
204 else
206 strncpy (buf, startp, endp - startp);
207 buf[endp - startp] = '\0';
209 add_entry (entp, buf, is_system);
210 if (! *endp)
211 break;
212 ++endp;
213 startp = endp;
215 else
216 ++endp;
221 /* Initialize the path module. */
222 void
223 jcf_path_init ()
225 char *cp;
227 add_entry (&sys_dirs, ".", 0);
228 add_entry (&sys_dirs, LIBGCJ_ZIP_FILE, 1);
230 GET_ENV_PATH_LIST (cp, "CLASSPATH");
231 add_path (&classpath_env, cp, 0);
234 /* Call this when -classpath is seen on the command line. */
235 void
236 jcf_path_classpath_arg (path)
237 const char *path;
239 free_entry (&classpath_l);
240 add_path (&classpath_l, path, 0);
243 /* Call this when -CLASSPATH is seen on the command line. */
244 void
245 jcf_path_CLASSPATH_arg (path)
246 const char *path;
248 free_entry (&classpath_u);
249 add_path (&classpath_u, path, 0);
252 /* Call this when -I is seen on the command line. */
253 void
254 jcf_path_include_arg (path)
255 const char *path;
257 add_entry (&include_dirs, path, 0);
260 /* We `seal' the path by linking everything into one big list. Then
261 we provide a way to iterate through the sealed list. */
262 void
263 jcf_path_seal ()
265 int do_system = 1;
266 struct entry *secondary;
268 sealed = include_dirs;
269 include_dirs = NULL;
271 if (classpath_l)
273 secondary = classpath_l;
274 classpath_l = NULL;
275 do_system = 0;
277 else if (classpath_u)
279 secondary = classpath_u;
280 classpath_u = NULL;
282 else
284 secondary = classpath_env;
285 classpath_env = NULL;
288 free_entry (&classpath_l);
289 free_entry (&classpath_u);
290 free_entry (&classpath_env);
292 append_entry (&sealed, secondary);
294 if (do_system)
296 append_entry (&sealed, sys_dirs);
297 sys_dirs = NULL;
299 else
300 free_entry (&sys_dirs);
303 void *
304 jcf_path_start ()
306 return (void *) sealed;
309 void *
310 jcf_path_next (x)
311 void *x;
313 struct entry *ent = (struct entry *) x;
314 return (void *) ent->next;
317 /* We guarantee that the return path will either be a zip file, or it
318 will end with a directory separator. */
319 char *
320 jcf_path_name (x)
321 void *x;
323 struct entry *ent = (struct entry *) x;
324 return ent->name;
328 jcf_path_is_zipfile (x)
329 void *x;
331 struct entry *ent = (struct entry *) x;
332 return (ent->flags & FLAG_ZIP);
336 jcf_path_is_system (x)
337 void *x;
339 struct entry *ent = (struct entry *) x;
340 return (ent->flags & FLAG_SYSTEM);
344 jcf_path_max_len ()
346 return longest_path;