Commit a4796c80 by Per Bothner Committed by Per Bothner

Various fixes to allow compiling a compressed .jar/.zip archive.

From-SVN: r39175
parent b5c4fed9
2001-01-21 Per Bothner <per@bothner.com> 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. Minor optimization of static ggc roots.
* jcf-parse.c (parse_roots): New static field. * jcf-parse.c (parse_roots): New static field.
(current_field, current_method, current_file_list): Replace by macros (current_field, current_method, current_file_list): Replace by macros
......
...@@ -90,7 +90,7 @@ DEFUN(jcf_filbuf_from_stdio, (jcf, count), ...@@ -90,7 +90,7 @@ DEFUN(jcf_filbuf_from_stdio, (jcf, count),
#include "zipfile.h" #include "zipfile.h"
struct ZipFileCache *SeenZipFiles = NULL; struct ZipFile *SeenZipFiles = NULL;
/* Open a zip file with the given name, and cache directory and file /* 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. descriptor. If the file is missing, treat it as an empty archive.
...@@ -101,29 +101,29 @@ ZipFile * ...@@ -101,29 +101,29 @@ ZipFile *
DEFUN(opendir_in_zip, (zipfile, is_system), DEFUN(opendir_in_zip, (zipfile, is_system),
const char *zipfile AND int is_system) const char *zipfile AND int is_system)
{ {
struct ZipFileCache* zipf; struct ZipFile* zipf;
char magic [4]; char magic [4];
int fd; int fd;
for (zipf = SeenZipFiles; zipf != NULL; zipf = zipf->next) for (zipf = SeenZipFiles; zipf != NULL; zipf = zipf->next)
{ {
if (strcmp (zipf->name, zipfile) == 0) 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->next = SeenZipFiles;
zipf->name = (char*)(zipf+1); zipf->name = (char*)(zipf+1);
strcpy (zipf->name, zipfile); strcpy (zipf->name, zipfile);
SeenZipFiles = zipf; SeenZipFiles = zipf;
fd = open (zipfile, O_RDONLY | O_BINARY); fd = open (zipfile, O_RDONLY | O_BINARY);
zipf->z.fd = fd; zipf->fd = fd;
if (fd < 0) if (fd < 0)
{ {
/* A missing zip file is not considered an error. /* A missing zip file is not considered an error.
We may want to re-consider that. FIXME. */ We may want to re-consider that. FIXME. */
zipf->z.count = 0; zipf->count = 0;
zipf->z.dir_size = 0; zipf->dir_size = 0;
zipf->z.central_directory = NULL; zipf->central_directory = NULL;
} }
else else
{ {
...@@ -131,10 +131,10 @@ DEFUN(opendir_in_zip, (zipfile, is_system), ...@@ -131,10 +131,10 @@ DEFUN(opendir_in_zip, (zipfile, is_system),
if (read (fd, magic, 4) != 4 || GET_u4 (magic) != (JCF_u4)ZIPMAGIC) if (read (fd, magic, 4) != 4 || GET_u4 (magic) != (JCF_u4)ZIPMAGIC)
return NULL; return NULL;
lseek (fd, 0L, SEEK_SET); lseek (fd, 0L, SEEK_SET);
if (read_zip_archive (&zipf->z) != 0) if (read_zip_archive (zipf) != 0)
return NULL; return NULL;
} }
return &zipf->z; return zipf;
} }
/* Returns: /* Returns:
...@@ -151,7 +151,6 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system), ...@@ -151,7 +151,6 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system),
ZipDirectory *zipd; ZipDirectory *zipd;
int i, len; int i, len;
ZipFile *zipf = opendir_in_zip (zipfile, is_system); ZipFile *zipf = opendir_in_zip (zipfile, is_system);
z_stream d_stream; /* decompression stream */
if (zipf == NULL) if (zipf == NULL)
return -2; return -2;
...@@ -159,10 +158,6 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system), ...@@ -159,10 +158,6 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system),
if (!zipmember) if (!zipmember)
return 0; return 0;
d_stream.zalloc = (alloc_func) 0;
d_stream.zfree = (free_func) 0;
d_stream.opaque = (voidpf) 0;
len = strlen (zipmember); len = strlen (zipmember);
zipd = (struct ZipDirectory*) zipf->central_directory; zipd = (struct ZipDirectory*) zipf->central_directory;
...@@ -173,9 +168,21 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system), ...@@ -173,9 +168,21 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system),
{ {
JCF_ZERO (jcf); JCF_ZERO (jcf);
jcf->filbuf = jcf_unexpected_eof;
jcf->filename = xstrdup (zipfile); jcf->filename = xstrdup (zipfile);
jcf->classname = xstrdup (zipmember); 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; jcf->zipd = (void *)zipd;
if (zipd->compression_method == Z_NO_COMPRESSION) if (zipd->compression_method == Z_NO_COMPRESSION)
...@@ -191,6 +198,11 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system), ...@@ -191,6 +198,11 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system),
else else
{ {
char *buffer; 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); jcf->buffer = ALLOC (zipd->uncompressed_size);
d_stream.next_out = jcf->buffer; d_stream.next_out = jcf->buffer;
d_stream.avail_out = zipd->uncompressed_size; d_stream.avail_out = zipd->uncompressed_size;
...@@ -212,9 +224,6 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system), ...@@ -212,9 +224,6 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmember, is_system),
} }
return 0; return 0;
}
}
return -1;
} }
#if JCF_USE_STDIO #if JCF_USE_STDIO
......
...@@ -91,7 +91,6 @@ static void process_zip_dir PARAMS ((FILE *)); ...@@ -91,7 +91,6 @@ static void process_zip_dir PARAMS ((FILE *));
static void parse_source_file PARAMS ((tree, FILE *)); static void parse_source_file PARAMS ((tree, FILE *));
static void jcf_parse_source PARAMS ((void)); static void jcf_parse_source PARAMS ((void));
static int jcf_figure_file_type PARAMS ((JCF *)); 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 parse_class_file PARAMS ((void));
static void set_source_filename PARAMS ((JCF *, int)); static void set_source_filename PARAMS ((JCF *, int));
static int predefined_filename_p PARAMS ((tree)); static int predefined_filename_p PARAMS ((tree));
...@@ -509,27 +508,29 @@ read_class (name) ...@@ -509,27 +508,29 @@ read_class (name)
tree name; tree name;
{ {
JCF this_jcf, *jcf; JCF this_jcf, *jcf;
tree icv, class;
tree save_current_class = current_class; tree save_current_class = current_class;
const char *save_input_filename = input_filename; const char *save_input_filename = input_filename;
JCF *save_current_jcf = current_jcf; 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 ((icv = IDENTIFIER_CLASS_VALUE (name)) != NULL_TREE)
if (find_in_current_zip (IDENTIFIER_POINTER (name), &jcf) == 0)
{ {
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), if (find_class (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name),
&this_jcf, 1) == 0) &this_jcf, 1) == 0)
return 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) if (current_jcf->java_source)
jcf_parse_source (); jcf_parse_source ();
...@@ -537,19 +538,19 @@ read_class (name) ...@@ -537,19 +538,19 @@ read_class (name)
java_parser_context_save_global (); java_parser_context_save_global ();
java_push_parser_context (); java_push_parser_context ();
input_filename = current_jcf->filename; 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); jcf_parse (current_jcf);
java_pop_parser_context (0); java_pop_parser_context (0);
java_parser_context_restore_global (); java_parser_context_restore_global ();
} }
if (!current_jcf->seen_in_zip) if (! JCF_SEEN_IN_ZIP (current_jcf))
JCF_FINISH (current_jcf); JCF_FINISH (current_jcf);
current_class = save_current_class; current_class = save_current_class;
input_filename = save_input_filename; input_filename = save_input_filename;
current_jcf = save_current_jcf; current_jcf = save_current_jcf;
if (current_jcf->read_state)
fseek (current_jcf->read_state, saved_pos, SEEK_SET);
return 1; return 1;
} }
...@@ -673,7 +674,7 @@ jcf_parse (jcf) ...@@ -673,7 +674,7 @@ jcf_parse (jcf)
all_class_list = tree_cons (NULL_TREE, all_class_list = tree_cons (NULL_TREE,
TYPE_NAME (current_class), all_class_list ); 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; for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (current_class)); current;
current = TREE_CHAIN (current)) current = TREE_CHAIN (current))
load_class (DECL_NAME (TREE_PURPOSE (current)), 1); load_class (DECL_NAME (TREE_PURPOSE (current)), 1);
...@@ -957,7 +958,7 @@ yyparse () ...@@ -957,7 +958,7 @@ yyparse ()
return 0; return 0;
} }
static struct ZipFileCache *localToFile; static struct ZipFile *localToFile;
/* Process all class entries found in the zip file. */ /* Process all class entries found in the zip file. */
static void static void
...@@ -966,8 +967,8 @@ parse_zip_file_entries (void) ...@@ -966,8 +967,8 @@ parse_zip_file_entries (void)
struct ZipDirectory *zdir; struct ZipDirectory *zdir;
int i; int i;
for (i = 0, zdir = (ZipDirectory *)localToFile->z.central_directory; for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
i < localToFile->z.count; i++, zdir = ZIPDIR_NEXT (zdir)) i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
{ {
tree class; tree class;
...@@ -981,7 +982,7 @@ parse_zip_file_entries (void) ...@@ -981,7 +982,7 @@ parse_zip_file_entries (void)
if ( !CLASS_LOADED_P (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); jcf_parse (current_jcf);
} }
...@@ -1007,8 +1008,8 @@ process_zip_dir (FILE *finput) ...@@ -1007,8 +1008,8 @@ process_zip_dir (FILE *finput)
int i; int i;
ZipDirectory *zdir; ZipDirectory *zdir;
for (i = 0, zdir = (ZipDirectory *)localToFile->z.central_directory; for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
i < localToFile->z.count; i++, zdir = ZIPDIR_NEXT (zdir)) i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
{ {
char *class_name, *file_name, *class_name_in_zip_dir; char *class_name, *file_name, *class_name_in_zip_dir;
tree class; tree class;
...@@ -1048,42 +1049,15 @@ process_zip_dir (FILE *finput) ...@@ -1048,42 +1049,15 @@ process_zip_dir (FILE *finput)
jcf->read_state = finput; jcf->read_state = finput;
jcf->filbuf = jcf_filbuf_from_stdio; jcf->filbuf = jcf_filbuf_from_stdio;
jcf->seen_in_zip = 1;
jcf->java_source = 0; jcf->java_source = 0;
jcf->zip_offset = zdir->filestart;
jcf->classname = class_name; jcf->classname = class_name;
jcf->filename = file_name; jcf->filename = file_name;
jcf->zipd = zdir;
TYPE_JCF (class) = jcf; 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 */ /* Figure what kind of file we're dealing with */
static int static int
DEFUN(jcf_figure_file_type, (jcf), DEFUN(jcf_figure_file_type, (jcf),
...@@ -1105,8 +1079,7 @@ DEFUN(jcf_figure_file_type, (jcf), ...@@ -1105,8 +1079,7 @@ DEFUN(jcf_figure_file_type, (jcf),
if (magic == (JCF_u4)ZIPMAGIC if (magic == (JCF_u4)ZIPMAGIC
&& !open_in_zip (jcf, input_filename, NULL, 0)) && !open_in_zip (jcf, input_filename, NULL, 0))
{ {
localToFile = ALLOC (sizeof (struct ZipFileCache)); localToFile = SeenZipFiles;
memcpy (localToFile, SeenZipFiles, sizeof (struct ZipFileCache));
/* Register all the class defined there. */ /* Register all the class defined there. */
process_zip_dir (jcf->read_state); process_zip_dir (jcf->read_state);
return JCF_ZIP; return JCF_ZIP;
......
...@@ -83,6 +83,8 @@ typedef struct CPool { ...@@ -83,6 +83,8 @@ typedef struct CPool {
jword* data; jword* data;
} CPool; } CPool;
struct ZipDirectory;
/* JCF encapsulates the state of reading a Java Class File. */ /* JCF encapsulates the state of reading a Java Class File. */
typedef struct JCF { typedef struct JCF {
...@@ -90,19 +92,19 @@ typedef struct JCF { ...@@ -90,19 +92,19 @@ typedef struct JCF {
unsigned char *buffer_end; unsigned char *buffer_end;
unsigned char *read_ptr; unsigned char *read_ptr;
unsigned char *read_end; unsigned char *read_end;
int seen_in_zip;
int java_source; int java_source;
long zip_offset;
jcf_filbuf_t filbuf; jcf_filbuf_t filbuf;
void *read_state; void *read_state;
const char *filename; const char *filename;
const char *classname; 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; JCF_u2 access_flags, this_class, super_class;
CPool cpool; CPool cpool;
} JCF; } JCF;
/*typedef JCF* JCF_FILE;*/ /*typedef JCF* JCF_FILE;*/
#define JCF_SEEN_IN_ZIP(JCF) ((JCF)->zipd != NULL)
/* The CPOOL macros take a (pointer to a) CPool. /* The CPOOL macros take a (pointer to a) CPool.
The JPOOL macros take a (pointer to a) JCF. The JPOOL macros take a (pointer to a) JCF.
Some of the latter should perhaps be deprecated or removed. */ Some of the latter should perhaps be deprecated or removed. */
......
...@@ -331,6 +331,7 @@ read_zip_archive (zipf) ...@@ -331,6 +331,7 @@ read_zip_archive (zipf)
zipd->compression_method = compression_method; zipd->compression_method = compression_method;
zipd->size = size; zipd->size = size;
zipd->uncompressed_size = uncompressed_size; zipd->uncompressed_size = uncompressed_size;
zipd->zipf = zipf;
#ifdef __GNUC__ #ifdef __GNUC__
#define DIR_ALIGN __alignof__(ZipDirectory) #define DIR_ALIGN __alignof__(ZipDirectory)
#else #else
......
...@@ -22,11 +22,15 @@ of Sun Microsystems, Inc. in the United States and other countries. ...@@ -22,11 +22,15 @@ of Sun Microsystems, Inc. in the United States and other countries.
The Free Software Foundation is independent of Sun Microsystems, Inc. */ The Free Software Foundation is independent of Sun Microsystems, Inc. */
struct ZipFile { struct ZipFile {
char *name;
int fd; int fd;
long size; long size;
long count; long count;
long dir_size; long dir_size;
char *central_directory; char *central_directory;
/* Chain together in SeenZipFiles. */
struct ZipFile *next;
}; };
typedef struct ZipFile ZipFile; typedef struct ZipFile ZipFile;
...@@ -38,6 +42,7 @@ struct ZipDirectory { ...@@ -38,6 +42,7 @@ struct ZipDirectory {
unsigned size; /* length of file */ unsigned size; /* length of file */
unsigned uncompressed_size; /* length of uncompressed data */ unsigned uncompressed_size; /* length of uncompressed data */
unsigned filestart; /* start of file in archive */ unsigned filestart; /* start of file in archive */
ZipFile *zipf;
int filename_length; int filename_length;
/* char mid_padding[...]; */ /* char mid_padding[...]; */
/* char filename[filename_length]; */ /* char filename[filename_length]; */
...@@ -46,13 +51,7 @@ struct ZipDirectory { ...@@ -46,13 +51,7 @@ struct ZipDirectory {
typedef struct ZipDirectory ZipDirectory; typedef struct ZipDirectory ZipDirectory;
struct ZipFileCache { extern struct ZipFile *SeenZipFiles;
struct ZipFile z;
struct ZipFileCache *next;
char *name;
};
extern struct ZipFileCache *SeenZipFiles;
#define ZIPDIR_FILENAME(ZIPD) ((char*)(ZIPD)+(ZIPD)->filename_offset) #define ZIPDIR_FILENAME(ZIPD) ((char*)(ZIPD)+(ZIPD)->filename_offset)
#define ZIPDIR_NEXT(ZIPD) \ #define ZIPDIR_NEXT(ZIPD) \
...@@ -62,6 +61,7 @@ extern struct ZipFileCache *SeenZipFiles; ...@@ -62,6 +61,7 @@ extern struct ZipFileCache *SeenZipFiles;
extern ZipFile * opendir_in_zip PARAMS ((const char *, int)); extern ZipFile * opendir_in_zip PARAMS ((const char *, int));
extern int read_zip_archive PARAMS ((ZipFile *)); extern int read_zip_archive PARAMS ((ZipFile *));
#ifdef JCF_ZIP #ifdef JCF_ZIP
extern int read_zip_member PARAMS ((JCF*, ZipDirectory*, ZipFile *));
extern int open_in_zip PARAMS ((struct JCF *, const char *, extern int open_in_zip PARAMS ((struct JCF *, const char *,
const char *, int)); const char *, int));
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment