00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027 #include "system.h"
00028
00029 #include <dirent.h>
00030
00031 #include "jcf.h"
00032
00033
00034
00035 #ifndef GET_ENV_PATH_LIST
00036 #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
00037 #endif
00038
00039
00040 #ifndef PATH_SEPARATOR
00041 #define PATH_SEPARATOR ':'
00042 #endif
00043
00044 #ifndef DIR_SEPARATOR
00045 #define DIR_SEPARATOR '/'
00046 #endif
00047
00048 #ifndef DIR_UP
00049 #define DIR_UP ".."
00050 #endif
00051
00052
00053
00054
00055 #define FLAG_SYSTEM 1
00056 #define FLAG_ZIP 2
00057
00058
00059
00060 struct entry
00061 {
00062 char *name;
00063 int flags;
00064 struct entry *next;
00065 };
00066
00067 static void free_entry PARAMS ((struct entry **));
00068 static void append_entry PARAMS ((struct entry **, struct entry *));
00069 static void add_entry PARAMS ((struct entry **, const char *, int));
00070 static void add_path PARAMS ((struct entry **, const char *, int));
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 static struct entry *include_dirs;
00087
00088
00089 static struct entry *classpath_env;
00090
00091
00092 static struct entry *classpath_user;
00093
00094
00095
00096 static struct entry *sys_dirs;
00097
00098
00099 static struct entry *extensions;
00100
00101
00102 static struct entry *sealed;
00103
00104
00105 static int longest_path = 0;
00106
00107
00108
00109 static void
00110 free_entry (entp)
00111 struct entry **entp;
00112 {
00113 struct entry *e, *n;
00114
00115 for (e = *entp; e; e = n)
00116 {
00117 n = e->next;
00118 free (e->name);
00119 free (e);
00120 }
00121 *entp = NULL;
00122 }
00123
00124 static void
00125 append_entry (entp, ent)
00126 struct entry **entp;
00127 struct entry *ent;
00128 {
00129
00130
00131 struct entry *e;
00132
00133
00134 for (e = *entp; e && e->next; e = e->next)
00135 ;
00136
00137 if (e)
00138 e->next = ent;
00139 else
00140 *entp = ent;
00141 }
00142
00143 static void
00144 add_entry (entp, filename, is_system)
00145 struct entry **entp;
00146 const char *filename;
00147 int is_system;
00148 {
00149 int len;
00150 struct entry *n;
00151
00152 n = (struct entry *) ALLOC (sizeof (struct entry));
00153 n->flags = is_system ? FLAG_SYSTEM : 0;
00154 n->next = NULL;
00155
00156 len = strlen (filename);
00157 if (len > 4 && (strcmp (filename + len - 4, ".zip") == 0
00158 || strcmp (filename + len - 4, ".jar") == 0))
00159 {
00160 n->flags |= FLAG_ZIP;
00161
00162
00163
00164
00165 if (! strcmp (filename, LIBGCJ_ZIP_FILE))
00166 n->flags |= FLAG_SYSTEM;
00167 }
00168
00169
00170
00171
00172 if (filename[len - 1] != '/' && filename[len - 1] != DIR_SEPARATOR)
00173 {
00174 char *f2 = (char *) alloca (len + 2);
00175 strcpy (f2, filename);
00176 f2[len] = DIR_SEPARATOR;
00177 f2[len + 1] = '\0';
00178 n->name = xstrdup (f2);
00179 ++len;
00180 }
00181 else
00182 n->name = xstrdup (filename);
00183
00184 if (len > longest_path)
00185 longest_path = len;
00186
00187 append_entry (entp, n);
00188 }
00189
00190 static void
00191 add_path (entp, cp, is_system)
00192 struct entry **entp;
00193 const char *cp;
00194 int is_system;
00195 {
00196 const char *startp, *endp;
00197
00198 if (cp)
00199 {
00200 char *buf = (char *) alloca (strlen (cp) + 3);
00201 startp = endp = cp;
00202 while (1)
00203 {
00204 if (! *endp || *endp == PATH_SEPARATOR)
00205 {
00206 if (endp == startp)
00207 {
00208 buf[0] = '.';
00209 buf[1] = DIR_SEPARATOR;
00210 buf[2] = '\0';
00211 }
00212 else
00213 {
00214 strncpy (buf, startp, endp - startp);
00215 buf[endp - startp] = '\0';
00216 }
00217 add_entry (entp, buf, is_system);
00218 if (! *endp)
00219 break;
00220 ++endp;
00221 startp = endp;
00222 }
00223 else
00224 ++endp;
00225 }
00226 }
00227 }
00228
00229 static int init_done = 0;
00230
00231
00232 void
00233 jcf_path_init ()
00234 {
00235 char *cp;
00236 char *try, sep[2];
00237 struct stat stat_b;
00238 int found = 0, len;
00239
00240 if (init_done)
00241 return;
00242 init_done = 1;
00243
00244 sep[0] = DIR_SEPARATOR;
00245 sep[1] = '\0';
00246
00247 GET_ENV_PATH_LIST (cp, "GCC_EXEC_PREFIX");
00248 if (cp)
00249 {
00250 try = alloca (strlen (cp) + 50);
00251
00252
00253
00254
00255
00256 strcpy (try, cp);
00257 strcat (try, DIR_UP);
00258 strcat (try, sep);
00259 strcat (try, DIR_UP);
00260 strcat (try, sep);
00261 len = strlen (try);
00262
00263 strcpy (try + len, "share");
00264 strcat (try, sep);
00265 strcat (try, "java");
00266 strcat (try, sep);
00267 strcat (try, "libgcj-" DEFAULT_TARGET_VERSION ".jar");
00268 if (! stat (try, &stat_b))
00269 {
00270 add_entry (&sys_dirs, try, 1);
00271 found = 1;
00272 strcpy (&try[strlen (try)
00273 - strlen ("libgcj-" DEFAULT_TARGET_VERSION ".jar")],
00274 sep);
00275 strcat (try, "ext");
00276 strcat (try, sep);
00277 if (! stat (try, &stat_b))
00278 jcf_path_extdirs_arg (try);
00279 }
00280 else
00281 {
00282 strcpy (try + len, DIR_UP);
00283 strcat (try, sep);
00284 strcat (try, "share");
00285 strcat (try, sep);
00286 strcat (try, "java");
00287 strcat (try, sep);
00288 strcat (try, "libgcj-" DEFAULT_TARGET_VERSION ".jar");
00289 if (! stat (try, &stat_b))
00290 {
00291 add_entry (&sys_dirs, try, 1);
00292 found = 1;
00293 strcpy (&try[strlen (try)
00294 - strlen ("libgcj-" DEFAULT_TARGET_VERSION ".jar")],
00295 sep);
00296 strcat (try, "ext");
00297 strcat (try, sep);
00298 if (! stat (try, &stat_b))
00299 jcf_path_extdirs_arg (try);
00300 }
00301 }
00302 }
00303 if (! found)
00304 {
00305
00306 char *extdirs;
00307 add_entry (&sys_dirs, LIBGCJ_ZIP_FILE, 1);
00308 extdirs = (char *) alloca (strlen (LIBGCJ_ZIP_FILE) + 1);
00309 strcpy (extdirs, LIBGCJ_ZIP_FILE);
00310 strcpy (&extdirs[strlen (LIBGCJ_ZIP_FILE)
00311 - strlen ("libgcj-" DEFAULT_TARGET_VERSION ".jar")],
00312 "ext");
00313 strcat (extdirs, sep);
00314 if (! stat (extdirs, &stat_b))
00315 jcf_path_extdirs_arg (extdirs);
00316 }
00317
00318 GET_ENV_PATH_LIST (cp, "CLASSPATH");
00319 add_path (&classpath_env, cp, 0);
00320 }
00321
00322
00323
00324
00325 void
00326 jcf_path_classpath_arg (path)
00327 const char *path;
00328 {
00329 free_entry (&classpath_user);
00330 add_path (&classpath_user, path, 0);
00331 }
00332
00333
00334
00335 void
00336 jcf_path_bootclasspath_arg (path)
00337 const char *path;
00338 {
00339 free_entry (&sys_dirs);
00340 add_path (&sys_dirs, path, 1);
00341 }
00342
00343
00344
00345 void
00346 jcf_path_extdirs_arg (cp)
00347 const char *cp;
00348 {
00349 const char *startp, *endp;
00350
00351 free_entry (&extensions);
00352
00353 if (cp)
00354 {
00355 char *buf = (char *) alloca (strlen (cp) + 3);
00356 startp = endp = cp;
00357 while (1)
00358 {
00359 if (! *endp || *endp == PATH_SEPARATOR)
00360 {
00361 if (endp == startp)
00362 return;
00363
00364 strncpy (buf, startp, endp - startp);
00365 buf[endp - startp] = '\0';
00366
00367 {
00368 DIR *dirp = NULL;
00369 int dirname_length = strlen (buf);
00370
00371 dirp = opendir (buf);
00372 if (dirp == NULL)
00373 return;
00374
00375 for (;;)
00376 {
00377 struct dirent *direntp = readdir (dirp);
00378
00379 if (!direntp)
00380 break;
00381
00382 if (direntp->d_name[0] != '.')
00383 {
00384 char *name =
00385 (char *) alloca (dirname_length
00386 + strlen (direntp->d_name) + 2);
00387 strcpy (name, buf);
00388 if (name[dirname_length-1] != DIR_SEPARATOR)
00389 {
00390 name[dirname_length] = DIR_SEPARATOR;
00391 name[dirname_length+1] = 0;
00392 }
00393 strcat (name, direntp->d_name);
00394 add_entry (&extensions, name, 0);
00395 }
00396 }
00397 }
00398
00399 if (! *endp)
00400 break;
00401 ++endp;
00402 startp = endp;
00403 }
00404 else
00405 ++endp;
00406 }
00407 }
00408 }
00409
00410
00411 void
00412 jcf_path_include_arg (path)
00413 const char *path;
00414 {
00415 add_entry (&include_dirs, path, 0);
00416 }
00417
00418
00419
00420
00421 void
00422 jcf_path_seal (print)
00423 int print;
00424 {
00425 struct entry *secondary;
00426
00427 sealed = include_dirs;
00428 include_dirs = NULL;
00429
00430 if (classpath_user)
00431 {
00432 secondary = classpath_user;
00433 classpath_user = NULL;
00434 }
00435 else
00436 {
00437 if (! classpath_env)
00438 add_entry (&classpath_env, ".", 0);
00439
00440 secondary = classpath_env;
00441 classpath_env = NULL;
00442 }
00443
00444
00445 free_entry (&classpath_user);
00446 free_entry (&classpath_env);
00447
00448 append_entry (&sealed, secondary);
00449 append_entry (&sealed, sys_dirs);
00450 append_entry (&sealed, extensions);
00451 sys_dirs = NULL;
00452 extensions = NULL;
00453
00454 if (print)
00455 {
00456 struct entry *ent;
00457 fprintf (stderr, "Class path starts here:\n");
00458 for (ent = sealed; ent; ent = ent->next)
00459 {
00460 fprintf (stderr, " %s", ent->name);
00461 if ((ent->flags & FLAG_SYSTEM))
00462 fprintf (stderr, " (system)");
00463 if ((ent->flags & FLAG_ZIP))
00464 fprintf (stderr, " (zip)");
00465 fprintf (stderr, "\n");
00466 }
00467 }
00468 }
00469
00470 void *
00471 jcf_path_start ()
00472 {
00473 return (void *) sealed;
00474 }
00475
00476 void *
00477 jcf_path_next (x)
00478 void *x;
00479 {
00480 struct entry *ent = (struct entry *) x;
00481 return (void *) ent->next;
00482 }
00483
00484
00485
00486 char *
00487 jcf_path_name (x)
00488 void *x;
00489 {
00490 struct entry *ent = (struct entry *) x;
00491 return ent->name;
00492 }
00493
00494 int
00495 jcf_path_is_zipfile (x)
00496 void *x;
00497 {
00498 struct entry *ent = (struct entry *) x;
00499 return (ent->flags & FLAG_ZIP);
00500 }
00501
00502 int
00503 jcf_path_is_system (x)
00504 void *x;
00505 {
00506 struct entry *ent = (struct entry *) x;
00507 return (ent->flags & FLAG_SYSTEM);
00508 }
00509
00510 int
00511 jcf_path_max_len ()
00512 {
00513 return longest_path;
00514 }