201 struct dirent* dirp = readdir(it->dir);
202 return dirp ? dirp->d_name : NULL;
203 }
204
205 static void
206 WildcardIterator_close(WildcardIterator it)
207 {
208 if (it) {
209 closedir(it->dir);
210 JLI_MemFree(it);
211 }
212 }
213 #endif /* Unix */
214
215 static int
216 equal(const char *s1, const char *s2)
217 {
218 return JLI_StrCmp(s1, s2) == 0;
219 }
220
221 /*
222 * FileList ADT - a dynamic list of C filenames
223 */
224 struct FileList_
225 {
226 char **files;
227 int size;
228 int capacity;
229 };
230 typedef struct FileList_ *FileList;
231
232 static FileList
233 FileList_new(int capacity)
234 {
235 FileList fl = NEW_(FileList);
236 fl->capacity = capacity;
237 fl->files = (char **) JLI_MemAlloc(capacity * sizeof(fl->files[0]));
238 fl->size = 0;
239 return fl;
240 }
241
242
243
244 static void
245 FileList_free(FileList fl)
246 {
247 if (fl) {
248 if (fl->files) {
249 int i;
250 for (i = 0; i < fl->size; i++)
251 JLI_MemFree(fl->files[i]);
252 JLI_MemFree(fl->files);
253 }
254 JLI_MemFree(fl);
255 }
256 }
257
258 static void
259 FileList_ensureCapacity(FileList fl, int capacity)
260 {
261 if (fl->capacity < capacity) {
262 while (fl->capacity < capacity)
263 fl->capacity *= 2;
264 fl->files = JLI_MemRealloc(fl->files,
265 fl->capacity * sizeof(fl->files[0]));
266 }
267 }
268
269 static void
270 FileList_add(FileList fl, char *file)
271 {
272 FileList_ensureCapacity(fl, fl->size+1);
273 fl->files[fl->size++] = file;
274 }
275
276 static void
277 FileList_addSubstring(FileList fl, const char *beg, size_t len)
278 {
279 char *filename = (char *) JLI_MemAlloc(len+1);
280 memcpy(filename, beg, len);
281 filename[len] = '\0';
282 FileList_ensureCapacity(fl, fl->size+1);
283 fl->files[fl->size++] = filename;
284 }
285
286 static char *
287 FileList_join(FileList fl, char sep)
288 {
289 int i;
290 int size;
291 char *path;
292 char *p;
293 for (i = 0, size = 1; i < fl->size; i++)
294 size += (int)JLI_StrLen(fl->files[i]) + 1;
295
296 path = JLI_MemAlloc(size);
297
298 for (i = 0, p = path; i < fl->size; i++) {
299 int len = (int)JLI_StrLen(fl->files[i]);
300 if (i > 0) *p++ = sep;
301 memcpy(p, fl->files[i], len);
302 p += len;
303 }
304 *p = '\0';
305
306 return path;
307 }
308
309 static FileList
310 FileList_split(const char *path, char sep)
311 {
312 const char *p, *q;
313 size_t len = JLI_StrLen(path);
314 int count;
315 FileList fl;
316 for (count = 1, p = path; p < path + len; p++)
317 count += (*p == sep);
318 fl = FileList_new(count);
319 for (p = path;;) {
320 for (q = p; q <= path + len; q++) {
321 if (*q == sep || *q == '\0') {
322 FileList_addSubstring(fl, p, q - p);
323 if (*q == '\0')
324 return fl;
325 p = q + 1;
326 }
327 }
328 }
329 }
330
331 static int
332 isJarFileName(const char *filename)
333 {
334 int len = (int)JLI_StrLen(filename);
335 return (len >= 4) &&
336 (filename[len - 4] == '.') &&
337 (equal(filename + len - 3, "jar") ||
338 equal(filename + len - 3, "JAR")) &&
339 /* Paranoia: Maybe filename is "DIR:foo.jar" */
340 (JLI_StrChr(filename, PATH_SEPARATOR) == NULL);
341 }
342
343 static char *
344 wildcardConcat(const char *wildcard, const char *basename)
345 {
346 int wildlen = (int)JLI_StrLen(wildcard);
347 int baselen = (int)JLI_StrLen(basename);
348 char *filename = (char *) JLI_MemAlloc(wildlen + baselen);
349 /* Replace the trailing '*' with basename */
350 memcpy(filename, wildcard, wildlen-1);
351 memcpy(filename+wildlen-1, basename, baselen+1);
352 return filename;
353 }
354
355 static FileList
356 wildcardFileList(const char *wildcard)
357 {
358 const char *basename;
359 FileList fl = FileList_new(16);
360 WildcardIterator it = WildcardIterator_for(wildcard);
361
362 if (it == NULL)
363 {
364 FileList_free(fl);
365 return NULL;
366 }
367
368 while ((basename = WildcardIterator_next(it)) != NULL)
369 if (isJarFileName(basename))
370 FileList_add(fl, wildcardConcat(wildcard, basename));
371 WildcardIterator_close(it);
372 return fl;
373 }
374
375 static int
376 isWildcard(const char *filename)
377 {
378 int len = (int)JLI_StrLen(filename);
379 return (len > 0) &&
380 (filename[len - 1] == '*') &&
381 (len == 1 || IS_FILE_SEPARATOR(filename[len - 2])) &&
382 (! exists(filename));
383 }
384
385 static void
386 FileList_expandWildcards(FileList fl)
387 {
388 int i, j;
389 for (i = 0; i < fl->size; i++) {
390 if (isWildcard(fl->files[i])) {
391 FileList expanded = wildcardFileList(fl->files[i]);
392 if (expanded != NULL && expanded->size > 0) {
393 JLI_MemFree(fl->files[i]);
394 FileList_ensureCapacity(fl, fl->size + expanded->size);
395 for (j = fl->size - 1; j >= i+1; j--)
396 fl->files[j+expanded->size-1] = fl->files[j];
397 for (j = 0; j < expanded->size; j++)
398 fl->files[i+j] = expanded->files[j];
399 i += expanded->size - 1;
400 fl->size += expanded->size - 1;
401 /* fl expropriates expanded's elements. */
402 expanded->size = 0;
403 }
404 FileList_free(expanded);
405 }
406 }
407 }
408
409 const char *
410 JLI_WildcardExpandClasspath(const char *classpath)
411 {
412 char *expanded;
413 FileList fl;
414
415 if (JLI_StrChr(classpath, '*') == NULL)
416 return classpath;
417 fl = FileList_split(classpath, PATH_SEPARATOR);
418 FileList_expandWildcards(fl);
419 expanded = FileList_join(fl, PATH_SEPARATOR);
420 FileList_free(fl);
421 if (getenv(JLDEBUG_ENV_ENTRY) != 0)
422 printf("Expanded wildcards:\n"
423 " before: \"%s\"\n"
424 " after : \"%s\"\n",
425 classpath, expanded);
426 return expanded;
427 }
428
429 #ifdef DEBUG_WILDCARD
430 static void
431 FileList_print(FileList fl)
432 {
433 int i;
434 putchar('[');
435 for (i = 0; i < fl->size; i++) {
436 if (i > 0) printf(", ");
437 printf("\"%s\"",fl->files[i]);
438 }
439 putchar(']');
440 }
441
442 static void
443 wildcardExpandArgv(const char ***argv)
444 {
445 int i;
446 for (i = 0; (*argv)[i]; i++) {
447 if (equal((*argv)[i], "-cp") ||
448 equal((*argv)[i], "-classpath")) {
449 i++;
450 (*argv)[i] = wildcardExpandClasspath((*argv)[i]);
451 }
452 }
453 }
454
455 static void
456 debugPrintArgv(char *argv[])
457 {
|
201 struct dirent* dirp = readdir(it->dir);
202 return dirp ? dirp->d_name : NULL;
203 }
204
205 static void
206 WildcardIterator_close(WildcardIterator it)
207 {
208 if (it) {
209 closedir(it->dir);
210 JLI_MemFree(it);
211 }
212 }
213 #endif /* Unix */
214
215 static int
216 equal(const char *s1, const char *s2)
217 {
218 return JLI_StrCmp(s1, s2) == 0;
219 }
220
221 static int
222 isJarFileName(const char *filename)
223 {
224 int len = (int)JLI_StrLen(filename);
225 return (len >= 4) &&
226 (filename[len - 4] == '.') &&
227 (equal(filename + len - 3, "jar") ||
228 equal(filename + len - 3, "JAR")) &&
229 /* Paranoia: Maybe filename is "DIR:foo.jar" */
230 (JLI_StrChr(filename, PATH_SEPARATOR) == NULL);
231 }
232
233 static char *
234 wildcardConcat(const char *wildcard, const char *basename)
235 {
236 int wildlen = (int)JLI_StrLen(wildcard);
237 int baselen = (int)JLI_StrLen(basename);
238 char *filename = (char *) JLI_MemAlloc(wildlen + baselen);
239 /* Replace the trailing '*' with basename */
240 memcpy(filename, wildcard, wildlen-1);
241 memcpy(filename+wildlen-1, basename, baselen+1);
242 return filename;
243 }
244
245 static JLI_List
246 wildcardFileList(const char *wildcard)
247 {
248 const char *basename;
249 JLI_List fl = JLI_List_new(16);
250 WildcardIterator it = WildcardIterator_for(wildcard);
251
252 if (it == NULL)
253 {
254 JLI_List_free(fl);
255 return NULL;
256 }
257
258 while ((basename = WildcardIterator_next(it)) != NULL)
259 if (isJarFileName(basename))
260 JLI_List_add(fl, wildcardConcat(wildcard, basename));
261 WildcardIterator_close(it);
262 return fl;
263 }
264
265 static int
266 isWildcard(const char *filename)
267 {
268 int len = (int)JLI_StrLen(filename);
269 return (len > 0) &&
270 (filename[len - 1] == '*') &&
271 (len == 1 || IS_FILE_SEPARATOR(filename[len - 2])) &&
272 (! exists(filename));
273 }
274
275 static void
276 FileList_expandWildcards(JLI_List fl)
277 {
278 int i, j;
279 for (i = 0; i < fl->size; i++) {
280 if (isWildcard(fl->elements[i])) {
281 JLI_List expanded = wildcardFileList(fl->elements[i]);
282 if (expanded != NULL && expanded->size > 0) {
283 JLI_MemFree(fl->elements[i]);
284 JLI_List_ensureCapacity(fl, fl->size + expanded->size);
285 for (j = fl->size - 1; j >= i+1; j--)
286 fl->elements[j+expanded->size-1] = fl->elements[j];
287 for (j = 0; j < expanded->size; j++)
288 fl->elements[i+j] = expanded->elements[j];
289 i += expanded->size - 1;
290 fl->size += expanded->size - 1;
291 /* fl expropriates expanded's elements. */
292 expanded->size = 0;
293 }
294 JLI_List_free(expanded);
295 }
296 }
297 }
298
299 const char *
300 JLI_WildcardExpandClasspath(const char *classpath)
301 {
302 char *expanded;
303 JLI_List fl;
304
305 if (JLI_StrChr(classpath, '*') == NULL)
306 return classpath;
307 fl = JLI_List_split(classpath, PATH_SEPARATOR);
308 FileList_expandWildcards(fl);
309 expanded = JLI_List_join(fl, PATH_SEPARATOR);
310 JLI_List_free(fl);
311 if (getenv(JLDEBUG_ENV_ENTRY) != 0)
312 printf("Expanded wildcards:\n"
313 " before: \"%s\"\n"
314 " after : \"%s\"\n",
315 classpath, expanded);
316 return expanded;
317 }
318
319 #ifdef DEBUG_WILDCARD
320 static void
321 FileList_print(JLI_List fl)
322 {
323 int i;
324 putchar('[');
325 for (i = 0; i < fl->size; i++) {
326 if (i > 0) printf(", ");
327 printf("\"%s\"",fl->elements[i]);
328 }
329 putchar(']');
330 }
331
332 static void
333 wildcardExpandArgv(const char ***argv)
334 {
335 int i;
336 for (i = 0; (*argv)[i]; i++) {
337 if (equal((*argv)[i], "-cp") ||
338 equal((*argv)[i], "-classpath")) {
339 i++;
340 (*argv)[i] = wildcardExpandClasspath((*argv)[i]);
341 }
342 }
343 }
344
345 static void
346 debugPrintArgv(char *argv[])
347 {
|