[PATCH] Java - allow compiling a compressed .jar/.zip archive

Per Bothner per@bothner.com
Sun Jan 21 13:52:00 GMT 2001


I checked in the following.  It should allow compiling a compressed
.jar or .zip archive.

This is the last of the changes I had lined up.

2001-01-21  Per Bothner  <per@bothner.com>

	Various fixes to allow compiling a compressed .jar/.zip archive.
	* zipfile.h (struct ZipFileCache):  Replace by struct ZipFile.
	(struct ZipFile):  Add fields name and next (from  ZipFileCache).
	(struct ZipDirectory):  New field zipf points to owning ZipFile.
	* jcf.h (struct ZipDirectory):  Add forward declaration.
	(struct JCF):   Declare zipd field to have type struct ZipDirectory.
	Remove seen_in_zip and zip_offset fields.
	(JCF_SEEN_IN_ZIP):  New macro.
	* zextract.c (read_zip_archive):  Set ZipDirectory's zipf field.
	* jcf-io.c:  Change all ZipFileCache to ZipFile.
	(read_zip_member):  New function.
	(open_in_zip):  Call read_zip_member.
	* jcf-parse.c (find_in_current_zip):  Remove function.
	(read_class):  Merge in find_in_current_zip functionality.
	Call read_zip_member if needed.
	(parse_zip_file_entries):  Use read_zip_member.
	(process_zip_dir):  Update for removed and added JCF fields.
	(jcf_figure_file_type):  Re-use, don't copy initial ZipFile struct.

Index: zipfile.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/zipfile.h,v
retrieving revision 1.10
diff -u -p -r1.10 zipfile.h
--- zipfile.h	2000/12/10 03:53:33	1.10
+++ zipfile.h	2001/01/21 21:47:47
@@ -22,11 +22,15 @@ of Sun Microsystems, Inc. in the United 
 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 
 struct ZipFile {
+  char *name;
   int fd;
   long size;
   long count;
   long dir_size;
   char *central_directory;
+
+  /* Chain together in SeenZipFiles. */
+  struct ZipFile *next;
 };
 
 typedef struct ZipFile ZipFile;
@@ -38,6 +42,7 @@ struct ZipDirectory {
   unsigned size; /* length of file */
   unsigned uncompressed_size; /* length of uncompressed data */
   unsigned filestart;  /* start of file in archive */
+  ZipFile *zipf;
   int filename_length;
   /* char mid_padding[...]; */
   /* char filename[filename_length]; */
@@ -45,14 +50,8 @@ struct ZipDirectory {
 };
 
 typedef struct ZipDirectory ZipDirectory;
-
-struct ZipFileCache {
-  struct ZipFile z;
-  struct ZipFileCache *next;
-  char *name;
-};
 
-extern struct ZipFileCache *SeenZipFiles;
+extern struct ZipFile *SeenZipFiles;
 
 #define ZIPDIR_FILENAME(ZIPD) ((char*)(ZIPD)+(ZIPD)->filename_offset)
 #define ZIPDIR_NEXT(ZIPD) \
@@ -62,6 +61,7 @@ extern struct ZipFileCache *SeenZipFiles
 extern ZipFile * opendir_in_zip PARAMS ((const char *, int));
 extern int read_zip_archive PARAMS ((ZipFile *));
 #ifdef JCF_ZIP
+extern int read_zip_member PARAMS ((JCF*, ZipDirectory*, ZipFile *));
 extern int open_in_zip PARAMS ((struct JCF *, const char *,
 			       const char *, int));
 #endif
Index: jcf.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/jcf.h,v
retrieving revision 1.19
diff -u -p -r1.19 jcf.h
--- jcf.h	2000/10/20 21:19:29	1.19
+++ jcf.h	2001/01/21 21:47:47
@@ -83,6 +83,8 @@ typedef struct CPool {
   jword*	data;
 } CPool;
 
+struct ZipDirectory;
+
 /* JCF encapsulates the state of reading a Java Class File. */
 
 typedef struct JCF {
@@ -90,18 +92,18 @@ typedef struct JCF {
   unsigned char *buffer_end;
   unsigned char *read_ptr;
   unsigned char *read_end;
-  int seen_in_zip;
   int java_source;
-  long zip_offset;    
   jcf_filbuf_t filbuf;
   void *read_state;
   const char *filename;
   const char *classname;
-  void *zipd;			/* Directory entry where it was found */
+  struct ZipDirectory *zipd;	/* Directory entry where it was found */
   JCF_u2 access_flags, this_class, super_class;
   CPool cpool;
 } JCF;
 /*typedef JCF*  JCF_FILE;*/
+
+#define JCF_SEEN_IN_ZIP(JCF) ((JCF)->zipd != NULL)
 
 /* The CPOOL macros take a (pointer to a) CPool.
    The JPOOL macros take a (pointer to a) JCF.
Index: zextract.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/zextract.c,v
retrieving revision 1.10
diff -u -p -r1.10 zextract.c
--- zextract.c	2000/09/06 02:13:28	1.10
+++ zextract.c	2001/01/21 21:47:47
@@ -331,6 +331,7 @@ read_zip_archive (zipf)
       zipd->compression_method = compression_method;
       zipd->size = size;
       zipd->uncompressed_size = uncompressed_size;
+      zipd->zipf = zipf;
 #ifdef __GNUC__
 #define DIR_ALIGN __alignof__(ZipDirectory)
 #else
Index: jcf-io.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/jcf-io.c,v
retrieving revision 1.27
diff -u -p -r1.27 jcf-io.c
--- jcf-io.c	2000/12/10 20:18:23	1.27
+++ jcf-io.c	2001/01/21 21:47:48
@@ -90,7 +90,7 @@ DEFUN(jcf_filbuf_from_stdio, (jcf, count
 
 #include "zipfile.h"
 
-struct ZipFileCache *SeenZipFiles = NULL;
+struct ZipFile *SeenZipFiles = NULL;
 
 /* Open a zip file with the given name, and cache directory and file
    descriptor.  If the file is missing, treat it as an empty archive.
@@ -101,29 +101,29 @@ ZipFile *
 DEFUN(opendir_in_zip, (zipfile, is_system),
       const char *zipfile AND int is_system)
 {
-  struct ZipFileCache* zipf;
+  struct ZipFile* zipf;
   char magic [4];
   int fd;
   for (zipf = SeenZipFiles;  zipf != NULL;  zipf = zipf->next)
     {
       if (strcmp (zipf->name, zipfile) == 0)
-	return &zipf->z;
+	return zipf;
     }
 
-  zipf = ALLOC (sizeof (struct ZipFileCache) + strlen (zipfile) + 1);
+  zipf = ALLOC (sizeof (struct ZipFile) + strlen (zipfile) + 1);
   zipf->next = SeenZipFiles;
   zipf->name = (char*)(zipf+1);
   strcpy (zipf->name, zipfile);
   SeenZipFiles = zipf;
   fd = open (zipfile, O_RDONLY | O_BINARY);
-  zipf->z.fd = fd;
+  zipf->fd = fd;
   if (fd < 0)
     {
       /* A missing zip file is not considered an error.
        We may want to re-consider that.  FIXME. */
-      zipf->z.count = 0;
-      zipf->z.dir_size = 0;
-      zipf->z.central_directory = NULL;
+      zipf->count = 0;
+      zipf->dir_size = 0;
+      zipf->central_directory = NULL;
     }
   else
     {
@@ -131,10 +131,10 @@ DEFUN(opendir_in_zip, (zipfile, is_syste
       if (read (fd, magic, 4) != 4 || GET_u4 (magic) != (JCF_u4)ZIPMAGIC)
 	return NULL;
       lseek (fd, 0L, SEEK_SET);
-      if (read_zip_archive (&zipf->z) != 0)
+      if (read_zip_archive (zipf) != 0)
 	return NULL;
     }
-  return &zipf->z;
+  return zipf;
 }
 
 /* Returns:
@@ -151,7 +151,6 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmem
   ZipDirectory *zipd;
   int i, len;
   ZipFile *zipf = opendir_in_zip (zipfile, is_system);
-  z_stream d_stream; /* decompression stream */
 
   if (zipf == NULL)
     return -2;
@@ -159,10 +158,6 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmem
   if (!zipmember)
     return 0;
 
-  d_stream.zalloc = (alloc_func) 0;
-  d_stream.zfree = (free_func) 0;
-  d_stream.opaque = (voidpf) 0;
-
   len = strlen (zipmember);
   
   zipd = (struct ZipDirectory*) zipf->central_directory;
@@ -173,9 +168,21 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmem
 	{
 	  JCF_ZERO (jcf);
 
-	  jcf->filbuf = jcf_unexpected_eof;
 	  jcf->filename = xstrdup (zipfile);
 	  jcf->classname = xstrdup (zipmember);
+	  return read_zip_member(jcf, zipd, zipf);
+	}
+    }
+  return -1;
+}
+
+/* Read data from zip archive member. */
+
+int
+DEFUN(read_zip_member, (jcf, zipd, zipf),
+      JCF *jcf AND  ZipDirectory *zipd AND ZipFile *zipf)
+{
+	  jcf->filbuf = jcf_unexpected_eof;
 	  jcf->zipd = (void *)zipd;
 
 	  if (zipd->compression_method == Z_NO_COMPRESSION)
@@ -191,6 +198,11 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmem
 	  else
 	    {
 	      char *buffer;
+	      z_stream d_stream; /* decompression stream */
+	      d_stream.zalloc = (alloc_func) 0;
+	      d_stream.zfree = (free_func) 0;
+	      d_stream.opaque = (voidpf) 0;
+
 	      jcf->buffer = ALLOC (zipd->uncompressed_size);
 	      d_stream.next_out = jcf->buffer;
 	      d_stream.avail_out = zipd->uncompressed_size;
@@ -212,9 +224,6 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmem
 	    }
 
 	  return 0;
-	}
-    }
-  return -1;
 }
 
 #if JCF_USE_STDIO
Index: jcf-parse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/jcf-parse.c,v
retrieving revision 1.71
diff -u -p -r1.71 jcf-parse.c
--- jcf-parse.c	2001/01/21 21:24:30	1.71
+++ jcf-parse.c	2001/01/21 21:47:48
@@ -91,7 +91,6 @@ static void process_zip_dir PARAMS ((FIL
 static void parse_source_file PARAMS ((tree, FILE *));
 static void jcf_parse_source PARAMS ((void));
 static int jcf_figure_file_type PARAMS ((JCF *));
-static int find_in_current_zip PARAMS ((const char *, struct JCF **));
 static void parse_class_file PARAMS ((void));
 static void set_source_filename PARAMS ((JCF *, int));
 static int predefined_filename_p PARAMS ((tree));
@@ -509,47 +508,49 @@ read_class (name)
      tree name;
 {
   JCF this_jcf, *jcf;
+  tree icv, class;
   tree save_current_class = current_class;
   const char *save_input_filename = input_filename;
   JCF *save_current_jcf = current_jcf;
-  long saved_pos = 0;
-  if (current_jcf->read_state)
-    saved_pos = ftell (current_jcf->read_state);
 
-  /* Search in current zip first.  */
-  if (find_in_current_zip (IDENTIFIER_POINTER (name), &jcf) == 0)
+  if ((icv = IDENTIFIER_CLASS_VALUE (name)) != NULL_TREE)
     {
+      class = TREE_TYPE (icv);
+      jcf = TYPE_JCF (class);
+    }
+  else
+    jcf = NULL;
+
+  if (jcf == NULL)
+    {
+      this_jcf.zipd = NULL;
+      jcf = &this_jcf;
       if (find_class (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name),
 		      &this_jcf, 1) == 0)
 	return 0;
-      else
-	{
-	  this_jcf.seen_in_zip = 0;
-	  current_jcf = &this_jcf;
-	}
     }
-  else
-    current_jcf = jcf;
 
+  current_jcf = jcf;
+
   if (current_jcf->java_source)
     jcf_parse_source ();
   else {
     java_parser_context_save_global ();
     java_push_parser_context ();
     input_filename = current_jcf->filename;
+    if (JCF_SEEN_IN_ZIP (current_jcf))
+      read_zip_member(current_jcf, current_jcf->zipd, current_jcf->zipd->zipf);
     jcf_parse (current_jcf);
     java_pop_parser_context (0);
     java_parser_context_restore_global ();
   }
 
-  if (!current_jcf->seen_in_zip)
+  if (! JCF_SEEN_IN_ZIP (current_jcf))
     JCF_FINISH (current_jcf);
 
   current_class = save_current_class;
   input_filename = save_input_filename;
   current_jcf = save_current_jcf;
-  if (current_jcf->read_state)
-    fseek (current_jcf->read_state, saved_pos, SEEK_SET);
   return 1;
 }
 
@@ -673,7 +674,7 @@ jcf_parse (jcf)
     all_class_list = tree_cons (NULL_TREE, 
 				TYPE_NAME (current_class), all_class_list );
 
-  /* And if we came accross inner classes, load them now. */
+  /* And if we came across inner classes, load them now. */
   for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (current_class)); current;
        current = TREE_CHAIN (current))
     load_class (DECL_NAME (TREE_PURPOSE (current)), 1);
@@ -957,7 +958,7 @@ yyparse ()
   return 0;
 }
 
-static struct ZipFileCache *localToFile;
+static struct ZipFile *localToFile;
 
 /* Process all class entries found in the zip file.  */
 static void
@@ -966,8 +967,8 @@ parse_zip_file_entries (void)
   struct ZipDirectory *zdir;
   int i;
 
-  for (i = 0, zdir = (ZipDirectory *)localToFile->z.central_directory;
-       i < localToFile->z.count; i++, zdir = ZIPDIR_NEXT (zdir))
+  for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
+       i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
     {
       tree class;
       
@@ -981,7 +982,7 @@ parse_zip_file_entries (void)
 
       if ( !CLASS_LOADED_P (class))
 	{
-          fseek (current_jcf->read_state, current_jcf->zip_offset, SEEK_SET);
+	  read_zip_member(current_jcf, zdir, localToFile);
 	  jcf_parse (current_jcf);
 	}
 
@@ -1007,8 +1008,8 @@ process_zip_dir (FILE *finput)
   int i;
   ZipDirectory *zdir;
 
-  for (i = 0, zdir = (ZipDirectory *)localToFile->z.central_directory;
-       i < localToFile->z.count; i++, zdir = ZIPDIR_NEXT (zdir))
+  for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
+       i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
     {
       char *class_name, *file_name, *class_name_in_zip_dir;
       tree class;
@@ -1048,42 +1049,15 @@ process_zip_dir (FILE *finput)
 
       jcf->read_state  = finput;
       jcf->filbuf      = jcf_filbuf_from_stdio;
-      jcf->seen_in_zip = 1;
       jcf->java_source = 0;
-      jcf->zip_offset  = zdir->filestart;
       jcf->classname   = class_name;
       jcf->filename    = file_name;
+      jcf->zipd        = zdir;
 
       TYPE_JCF (class) = jcf;
     }
 }
 
-/* Lookup class NAME and figure whether is a class already found in the current
-   zip file.  */
-static int
-DEFUN(find_in_current_zip, (name, length, jcf),
-      const char *name AND JCF **jcf)
-{
-  JCF *local_jcf;
-  tree class_name = maybe_get_identifier (name), class, icv;
-
-  if (!class_name)
-    return 0;
-
-  if (!(icv = IDENTIFIER_CLASS_VALUE (class_name)))
-    return 0;
-
-  class = TREE_TYPE (icv);
-
-  /* Doesn't have jcf specific info ? It's not ours */
-  if (!TYPE_JCF (class))
-    return 0;
-
-  *jcf = local_jcf = TYPE_JCF (class);
-  fseek (local_jcf->read_state, local_jcf->zip_offset, SEEK_SET);
-  return 1;
-}
-
 /* Figure what kind of file we're dealing with */
 static int
 DEFUN(jcf_figure_file_type, (jcf),
@@ -1105,8 +1079,7 @@ DEFUN(jcf_figure_file_type, (jcf),
   if (magic ==  (JCF_u4)ZIPMAGIC
       && !open_in_zip (jcf, input_filename, NULL, 0))
     {
-      localToFile = ALLOC (sizeof (struct ZipFileCache));
-      memcpy (localToFile, SeenZipFiles, sizeof (struct ZipFileCache));
+      localToFile = SeenZipFiles;
       /* Register all the class defined there.  */
       process_zip_dir (jcf->read_state);
       return JCF_ZIP;

-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/


More information about the Gcc-patches mailing list