Various fixes to allow compiling a compressed .jar/.zip archive.
From-SVN: r39175
This commit is contained in:
parent
b5c4fed92c
commit
a4796c8062
|
@ -1,3 +1,24 @@
|
|||
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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue