From a4796c80627e34e3fa2828225c70dfc3b65c62e6 Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Sun, 21 Jan 2001 13:50:37 -0800 Subject: [PATCH] Various fixes to allow compiling a compressed .jar/.zip archive. From-SVN: r39175 --- gcc/java/ChangeLog | 21 ++++++++++++ gcc/java/jcf-io.c | 47 +++++++++++++++----------- gcc/java/jcf-parse.c | 79 +++++++++++++++----------------------------- gcc/java/jcf.h | 8 +++-- gcc/java/zextract.c | 1 + gcc/java/zipfile.h | 14 ++++---- 6 files changed, 88 insertions(+), 82 deletions(-) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index f045363d32b..cc768eadc2d 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,24 @@ +2001-01-21 Per Bothner + + 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 Minor optimization of static ggc roots. diff --git a/gcc/java/jcf-io.c b/gcc/java/jcf-io.c index 71b893cb199..655e3812006 100644 --- a/gcc/java/jcf-io.c +++ b/gcc/java/jcf-io.c @@ -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_system), 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, zipmember, is_system), 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, zipmember, is_system), 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, zipmember, is_system), { 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, zipmember, is_system), 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, zipmember, is_system), } return 0; - } - } - return -1; } #if JCF_USE_STDIO diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index 61c3c1509c1..a4178c016d7 100644 --- a/gcc/java/jcf-parse.c +++ b/gcc/java/jcf-parse.c @@ -91,7 +91,6 @@ static void process_zip_dir PARAMS ((FILE *)); 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,27 +508,29 @@ 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 (); @@ -537,19 +538,19 @@ read_class (name) 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; diff --git a/gcc/java/jcf.h b/gcc/java/jcf.h index eaeb9054719..5bb53b05c46 100644 --- a/gcc/java/jcf.h +++ b/gcc/java/jcf.h @@ -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,19 +92,19 @@ 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. */ diff --git a/gcc/java/zextract.c b/gcc/java/zextract.c index f381f92c57f..2226eeac619 100644 --- a/gcc/java/zextract.c +++ b/gcc/java/zextract.c @@ -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 diff --git a/gcc/java/zipfile.h b/gcc/java/zipfile.h index bf76a2ad687..f0be3cca4ec 100644 --- a/gcc/java/zipfile.h +++ b/gcc/java/zipfile.h @@ -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. */ 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]; */ @@ -46,13 +51,7 @@ 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 -- 2.30.2