+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.
+
2001-01-21 Per Bothner <per@bothner.com>
Minor optimization of static ggc roots.
#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.
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
{
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:
ZipDirectory *zipd;
int i, len;
ZipFile *zipf = opendir_in_zip (zipfile, is_system);
- z_stream d_stream; /* decompression stream */
if (zipf == NULL)
return -2;
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;
{
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)
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;
}
return 0;
- }
- }
- return -1;
}
#if JCF_USE_STDIO
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));
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 ();
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;
}
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);
return 0;
}
-static struct ZipFileCache *localToFile;
+static struct ZipFile *localToFile;
/* Process all class entries found in the zip file. */
static 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;
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);
}
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;
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),
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;
jword* data;
} CPool;
+struct ZipDirectory;
+
/* JCF encapsulates the state of reading a Java Class File. */
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.
Some of the latter should perhaps be deprecated or removed. */
zipd->compression_method = compression_method;
zipd->size = size;
zipd->uncompressed_size = uncompressed_size;
+ zipd->zipf = zipf;
#ifdef __GNUC__
#define DIR_ALIGN __alignof__(ZipDirectory)
#else
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;
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]; */
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) \
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