/* Utility routines for finding and reading Java(TM) .class files.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
- 2006, 2007 Free Software Foundation, Inc.
+ 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>.
Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
#include "toplev.h"
#include "java-tree.h"
#include "hashtab.h"
-#if JCF_USE_SCANDIR
#include <dirent.h>
-#include <fnmatch.h>
-#endif
#include "zlib.h"
JCF_u4 old_read_end = jcf->read_end - jcf->buffer;
JCF_u4 old_size = jcf->buffer_end - jcf->buffer;
JCF_u4 new_size = (old_size == 0 ? 2000 : 2 * old_size) + count;
- unsigned char *new_buffer = jcf->buffer == NULL ? ALLOC (new_size)
- : REALLOC (jcf->buffer, new_size);
+ unsigned char *new_buffer
+ = jcf->buffer == NULL ? XNEWVAR (unsigned char, new_size)
+ : XRESIZEVAR (unsigned char, jcf->buffer, new_size);
jcf->buffer = new_buffer;
jcf->buffer_end = new_buffer + new_size;
jcf->read_ptr = new_buffer + old_read_ptr;
return zipf;
}
- zipf = ALLOC (sizeof (struct ZipFile) + strlen (zipfile) + 1);
+ zipf = XNEWVAR (struct ZipFile, sizeof (struct ZipFile) + strlen (zipfile) + 1);
zipf->next = SeenZipFiles;
zipf->name = (char*)(zipf+1);
strcpy (zipf->name, zipfile);
jcf->read_ptr = jcf->buffer;
jcf->read_end = jcf->buffer_end;
jcf->read_state = NULL;
- jcf->filename = filename;
+ jcf->filename = xstrdup (filename);
if (read (fd, jcf->buffer, stat_buf.st_size) != stat_buf.st_size)
{
perror ("Failed to read .class file");
return open_class (filename, jcf, fd, dep_name);
}
-#if JCF_USE_SCANDIR
-
-/* A comparison function (as for qsort) that compares KEY (a char *
- giving the basename of a file) with the name stored in ENTRY (a
- dirent **). */
-
-static int
-compare_path (const void *key, const void *entry)
-{
- return strcmp ((const char *) key,
- (*((const struct dirent **) entry))->d_name);
-}
-
-/* Returns nonzero if ENTRY names a .java or .class file. */
-
-static int
-java_or_class_file (const struct dirent *entry)
-{
- const char *base = lbasename (entry->d_name);
- return (fnmatch ("*.java", base, 0) == 0 ||
- fnmatch ("*.class", base, 0) == 0);
-}
-
-/* Information about the files present in a particular directory. */
-typedef struct memoized_dirlist_entry
-{
- /* The name of the directory. */
- const char *dir;
- /* The number of .java and .class files present, or -1 if we could
- not, for some reason, obtain the list. */
- int num_files;
- /* The .java and .class files in the directory, in alphabetical
- order. */
- struct dirent **files;
-} memoized_dirlist_entry;
-
-/* A hash function for a memoized_dirlist_entry. */
-static hashval_t
-memoized_dirlist_hash (const void *entry)
-{
- const memoized_dirlist_entry *mde = (const memoized_dirlist_entry *) entry;
- return htab_hash_string (mde->dir);
-}
-
-/* Returns true if ENTRY (a memoized_dirlist_entry *) corresponds to
- the directory given by KEY (a char *) giving the directory
- name. */
-
-static int
-memoized_dirlist_lookup_eq (const void *entry, const void *key)
-{
- return strcmp ((const char *) key,
- ((const memoized_dirlist_entry *) entry)->dir) == 0;
-}
-
-/* A hash table mapping directory names to the lists of .java and
- .class files in that directory. */
-
-static htab_t memoized_dirlists;
-
-#endif
-
-/* Like stat, but avoids actually making the stat system call if we
- know that it cannot succeed. FILENAME and BUF are as for stat. */
-
-static int
-caching_stat (char *filename, struct stat *buf)
-{
-#if JCF_USE_SCANDIR
- char *sep;
- char origsep = 0;
- char *base;
- memoized_dirlist_entry *dent;
- void **slot;
- struct memoized_dirlist_entry temp;
-
- /* If the hashtable has not already been created, create it now. */
- if (!memoized_dirlists)
- memoized_dirlists = htab_create (37,
- memoized_dirlist_hash,
- memoized_dirlist_lookup_eq,
- NULL);
-
- /* Get the name of the directory. */
- sep = strrchr (filename, DIR_SEPARATOR);
-#ifdef DIR_SEPARATOR_2
- if (! sep)
- sep = strrchr (filename, DIR_SEPARATOR_2);
-#endif
- if (sep)
- {
- origsep = *sep;
- *sep = '\0';
- base = sep + 1;
- }
- else
- base = filename;
-
- /* Obtain the entry for this directory from the hash table. This
- approach is ok since we know that the hash function only looks at
- the directory name. */
- temp.dir = filename;
- temp.num_files = 0;
- temp.files = NULL;
- slot = htab_find_slot (memoized_dirlists, &temp, INSERT);
- if (!*slot)
- {
- /* We have not already scanned this directory; scan it now. */
- dent = XNEW (memoized_dirlist_entry);
- dent->dir = xstrdup (filename);
- /* Unfortunately, scandir is not fully standardized. In
- particular, the type of the function pointer passed as the
- third argument sometimes takes a "const struct dirent *"
- parameter, and sometimes just a "struct dirent *". We cast
- to (void *) and use __extension__ so that either way it is
- quietly accepted. FIXME: scandir is not in POSIX. */
- dent->num_files = __extension__ scandir (filename, &dent->files,
- (void *) java_or_class_file,
- alphasort);
- *slot = dent;
- }
- else
- dent = *((memoized_dirlist_entry **) slot);
-
- /* Put the separator back. */
- if (sep)
- *sep = origsep;
-
- /* If the file is not in the list, there is no need to stat it; it
- does not exist. */
- if (dent->num_files != -1
- && !bsearch (base, dent->files, dent->num_files,
- sizeof (struct dirent *), compare_path))
- return -1;
-#endif
-
- return stat (filename, buf);
-}
-
/* Returns 1 if the CLASSNAME (really a char *) matches the name
stored in TABLE_ENTRY (also a char *). */
find_class (const char *classname, int classname_length, JCF *jcf)
{
int fd;
- int i, k, class = -1;
+ int i, k, klass = -1;
struct stat class_buf;
char *dep_file;
void *entry;
/* Allocate and zero out the buffer, since we don't explicitly put a
null pointer when we're copying it below. */
buflen = jcf_path_max_len () + classname_length + 10;
- buffer = ALLOC (buflen);
+ buffer = XNEWVAR (char, buflen);
memset (buffer, 0, buflen);
for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
{
const char *path_name = jcf_path_name (entry);
- if (class != 0)
+ if (klass != 0)
{
int dir_len;
else
continue;
}
- class = caching_stat(buffer, &class_buf);
+ klass = stat (buffer, &class_buf);
}
}
dep_file = buffer;
- if (!class)
+ if (!klass)
{
SOURCE_FRONTEND_DEBUG ((stderr, "[Class selected: %s]\n",
classname+classname_length-
/* Remember that this class could not be found so that we do not
have to look again. */
- *htab_find_slot_with_hash (memoized_class_lookups, classname, hash, INSERT)
- = (void *) classname;
+ *htab_find_slot_with_hash (memoized_class_lookups, classname, hash, INSERT)
+ = (void *) CONST_CAST (char *, classname);
return NULL;
found:
- buffer = (char *) open_class (buffer, jcf, fd, dep_file);
- jcf->classname = xstrdup (classname);
- return buffer;
+ {
+ const char *const tmp = open_class (buffer, jcf, fd, dep_file);
+ jcf->classname = xstrdup (classname);
+ return tmp;
+ }
}
void