OSDN Git Service

2007-04-06 Colin Walters <walters@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / java / jcf-io.c
index 534c45b..10de9d2 100644 (file)
@@ -1,6 +1,6 @@
 /* Utility routines for finding and reading Java(TM) .class files.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+   2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -16,8 +16,8 @@ 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, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  
 
 Java and all Java-based marks are trademarks or registered trademarks
 of Sun Microsystems, Inc. in the United States and other countries.
@@ -134,10 +134,18 @@ opendir_in_zip (const char *zipfile, int is_system)
     {
       jcf_dependency_add_file (zipfile, is_system);
       if (read (fd, magic, 4) != 4 || GET_u4 (magic) != (JCF_u4)ZIPMAGIC)
-       return NULL;
+       {
+         free (zipf);
+         close (fd);
+         return NULL;
+       }
       lseek (fd, 0L, SEEK_SET);
       if (read_zip_archive (zipf) != 0)
-       return NULL;
+       {
+         free (zipf);
+         close (fd);
+         return NULL;
+       }
     }
 
   SeenZipFiles = zipf;  
@@ -188,11 +196,11 @@ int
 read_zip_member (JCF *jcf,  ZipDirectory *zipd, ZipFile *zipf)
 {
   jcf->filbuf = jcf_unexpected_eof;
-  jcf->zipd = (void *)zipd;
+  jcf->zipd = zipd;
 
   if (zipd->compression_method == Z_NO_COMPRESSION)
     {
-      jcf->buffer = ALLOC (zipd->size);
+      jcf->buffer = XNEWVEC (unsigned char, zipd->size);
       jcf->buffer_end = jcf->buffer + zipd->size;
       jcf->read_ptr = jcf->buffer;
       jcf->read_end = jcf->buffer_end;
@@ -208,13 +216,13 @@ read_zip_member (JCF *jcf,  ZipDirectory *zipd, ZipFile *zipf)
       d_stream.zfree = (free_func) 0;
       d_stream.opaque = (voidpf) 0;
 
-      jcf->buffer = ALLOC (zipd->uncompressed_size);
+      jcf->buffer = XNEWVEC (unsigned char, zipd->uncompressed_size);
       d_stream.next_out = jcf->buffer;
       d_stream.avail_out = zipd->uncompressed_size;
       jcf->buffer_end = jcf->buffer + zipd->uncompressed_size;
       jcf->read_ptr = jcf->buffer;
       jcf->read_end = jcf->buffer_end;
-      buffer = ALLOC (zipd->size);
+      buffer = XNEWVEC (char, zipd->size);
       d_stream.next_in = (unsigned char *) buffer;
       d_stream.avail_in = zipd->size;
       if (lseek (zipf->fd, zipd->filestart, 0) < 0
@@ -225,7 +233,7 @@ read_zip_member (JCF *jcf,  ZipDirectory *zipd, ZipFile *zipf)
       inflateInit2 (&d_stream, -MAX_WBITS);
       inflate (&d_stream, Z_NO_FLUSH);
       inflateEnd (&d_stream);
-      FREE (buffer);
+      free (buffer);
     }
 
   return 0;
@@ -246,12 +254,12 @@ open_class (const char *filename, JCF *jcf, int fd, const char *dep_name)
       if (dep_name != NULL)
        jcf_dependency_add_file (dep_name, 0);
       JCF_ZERO (jcf);
-      jcf->buffer = ALLOC (stat_buf.st_size);
+      jcf->buffer = XNEWVEC (unsigned char, stat_buf.st_size);
       jcf->buffer_end = jcf->buffer + stat_buf.st_size;
       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");
@@ -311,6 +319,14 @@ typedef struct memoized_dirlist_entry
   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.  */
@@ -341,11 +357,12 @@ caching_stat (char *filename, struct stat *buf)
   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,
-                                    htab_hash_string,
+                                    memoized_dirlist_hash,
                                     memoized_dirlist_lookup_eq,
                                     NULL);
 
@@ -364,13 +381,17 @@ caching_stat (char *filename, struct stat *buf)
   else
     base = filename;
 
-  /* Obtain the entry for this directory from the hash table.  */
-  slot = htab_find_slot (memoized_dirlists, filename, INSERT);
+  /* 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 = ((memoized_dirlist_entry *) 
-             ALLOC (sizeof (memoized_dirlist_entry)));
+      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
@@ -424,15 +445,13 @@ static htab_t memoized_class_lookups;
    file. */
 
 const char *
-find_class (const char *classname, int classname_length, JCF *jcf,
-           int source_ok)
+find_class (const char *classname, int classname_length, JCF *jcf)
 {
   int fd;
-  int i, k, java = -1, class = -1;
-  struct stat java_buf, class_buf;
+  int i, k, class = -1;
+  struct stat class_buf;
   char *dep_file;
   void *entry;
-  char *java_buffer;
   int buflen;
   char *buffer;
   hashval_t hash;
@@ -456,10 +475,6 @@ find_class (const char *classname, int classname_length, JCF *jcf,
   buffer = ALLOC (buflen);
   memset (buffer, 0, buflen);
 
-  java_buffer = alloca (buflen);
-
-  jcf->java_source = 0;
-
   for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry))
     {
       const char *path_name = jcf_path_name (entry);
@@ -508,39 +523,9 @@ find_class (const char *classname, int classname_length, JCF *jcf,
            }
          class = caching_stat(buffer, &class_buf);
        }
-
-      if (source_ok)
-       {
-         /* Compute name of .java file.  */
-         int l, m;
-         strcpy (java_buffer, path_name);
-         l = strlen (java_buffer);
-         for (m = 0; m < classname_length; ++m)
-           java_buffer[m + l] = (classname[m] == '.'
-                                 ? DIR_SEPARATOR : classname[m]);
-         strcpy (java_buffer + m + l, ".java");
-         java = caching_stat (java_buffer, &java_buf);
-         if (java == 0)
-           break;
-       }
     }
 
-  /* We preferably pick a class file if we have a chance. If the source
-     file is newer than the class file, we issue a warning and parse the
-     source file instead.
-     There should be a flag to allow people have the class file picked
-     up no matter what. FIXME. */
-  if (! java && ! class && java_buf.st_mtime > class_buf.st_mtime)
-    {
-      if (flag_newer)
-       warning ("source file for class %qs is newer than its matching class file.  Source file %qs used instead", classname, java_buffer);
-      class = -1;
-    }
-
-  if (! java)
-    dep_file = java_buffer;
-  else
-    dep_file = buffer;
+  dep_file = buffer;
   if (!class)
     {
       SOURCE_FRONTEND_DEBUG ((stderr, "[Class selected: %s]\n",
@@ -551,21 +536,6 @@ find_class (const char *classname, int classname_length, JCF *jcf,
       if (fd >= 0)
        goto found;
     }
-  /* Give .java a try, if necessary */
-  if (!java)
-    {
-      strcpy (buffer, java_buffer);
-      SOURCE_FRONTEND_DEBUG ((stderr, "[Source selected: %s]\n",
-                             classname+classname_length-
-                             (classname_length <= 30 ? 
-                              classname_length : 30)));
-      fd = JCF_OPEN_EXACT_CASE (buffer, O_RDONLY);
-      if (fd >= 0)
-       {
-         jcf->java_source = 1;
-         goto found;
-       }
-    }
 
   free (buffer);
 
@@ -576,15 +546,7 @@ find_class (const char *classname, int classname_length, JCF *jcf,
 
   return NULL;
  found:
-  if (jcf->java_source)
-    {
-      JCF_ZERO (jcf);          /* JCF_FINISH relies on this */
-      jcf->java_source = 1;
-      jcf->filename = xstrdup (buffer);
-      close (fd);              /* We use STDIO for source file */
-    }
-  else
-    buffer = (char *) open_class (buffer, jcf, fd, dep_file);
+  buffer = (char *) open_class (buffer, jcf, fd, dep_file);
   jcf->classname = xstrdup (classname);
   return buffer;
 }