Weird problems compiling bytecode

Per Bothner per@bothner.com
Fri Jan 19 22:23:00 GMT 2001


Edgar Villanueva <edgarvil@home.com> writes:
> I have been trying to compile the java antlr library in both source and
> bytecode format.
> I have been successful compiling the .java files but not the .class
> files.
> ...
> antlr/CppCodeGenerator.java: In class `antlr.CppCodeGenerator':
> antlr/CppCodeGenerator.java: In method
> `antlr.CppCodeGenerator(antlr.AlternativeBlock,boolean)':
> antlr/CppCodeGenerator.java:1585: Tree check: expected integer_cst, have
> instance_initializers_expr

I ran into something similar. I concluded it was a garbage collection
error. Note this is the garbage collector in the compiler, used to
manage the data structures in the compiler, not the run-time garbage
collector that is linked into libgcj. The problem is that the
constant pool is not registred as a "root".
If you're adventurous, please try this patch. The patch is
bigger than needed, because it also tries to fix a problem
in how compressed .jar/.zip files are handled. (The existing
code does not handle compiling a .jar/.zip file specified on
the command line if the archive is compressed.)
Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/class.c,v
retrieving revision 1.84
diff -u -p -r1.84 class.c
--- class.c	2001年01月15日 08:01:21	1.84
+++ class.c	2001年01月20日 06:11:53
@@ -83,6 +83,12 @@ static assume_compiled_node *find_assume
 
 static assume_compiled_node *assume_compiled_tree;
 
+static tree class_roots[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
+#define registered_class class_roots[0]
+#define fields_ident class_roots[1] /* get_identifier ("fields") */
+#define info_ident class_roots[2] /* get_identifier ("info") */
+#define class_list class_roots[3]
+
 /* Return the node that most closely represents the class whose name
 is IDENT. Start the search from NODE. Return NULL if an
 appropriate node does not exist. */
@@ -978,22 +984,10 @@ build_static_field_ref (fdecl)
 {
 /* Compile as:
 * *(FTYPE*)build_class_ref(FCLASS)->fields[INDEX].info.addr */
- static tree fields_ident = NULL_TREE;
- static tree info_ident = NULL_TREE;
 tree ref = build_class_ref (fclass);
 tree fld;
 int field_index = 0;
 ref = build1 (INDIRECT_REF, class_type_node, ref);
- if (fields_ident == NULL_TREE)
-	{
-	 fields_ident = get_identifier ("fields");
-	 ggc_add_tree_root (&fields_ident, 1);
-	}
- if (info_ident == NULL_TREE)
-	{
-	 info_ident = get_identifier ("info");
-	 ggc_add_tree_root (&info_ident, 1);
-	}
 ref = build (COMPONENT_REF, field_ptr_type_node, ref,
 		 lookup_field (&class_type_node, fields_ident));
 
@@ -1508,7 +1502,7 @@ is_compiled_class (class)
 if (class == current_class)
 return 2;
 
- seen_in_zip = (TYPE_JCF (class) && TYPE_JCF (class)->seen_in_zip);
+ seen_in_zip = (TYPE_JCF (class) && JCF_SEEN_IN_ZIP (TYPE_JCF (class)));
 if (CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (class) || seen_in_zip)
 {
 /* The class was seen in the current ZIP file and will be
@@ -1628,19 +1622,10 @@ void
 layout_class (this_class)
 tree this_class;
 {
- static tree list = NULL_TREE;
- static int initialized_p;
 tree super_class = CLASSTYPE_SUPER (this_class);
 tree field;
 
- /* Register LIST with the garbage collector. */
- if (!initialized_p)
- {
- ggc_add_tree_root (&list, 1);
- initialized_p = 1;
- }
-
- list = tree_cons (this_class, NULL_TREE, list);
+ class_list = tree_cons (this_class, NULL_TREE, class_list);
 if (CLASS_BEING_LAIDOUT (this_class))
 {
 char buffer [1024];
@@ -1651,7 +1636,7 @@ layout_class (this_class)
 	 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))));
 obstack_grow (&temporary_obstack, buffer, strlen (buffer));
 
- for (current = TREE_CHAIN (list); current; 
+ for (current = TREE_CHAIN (class_list); current; 
 	 current = TREE_CHAIN (current))
 	{
 	 tree decl = TYPE_NAME (TREE_PURPOSE (current));
@@ -1679,7 +1664,7 @@ layout_class (this_class)
 	{
 	 TYPE_SIZE (this_class) = error_mark_node;
 	 CLASS_BEING_LAIDOUT (this_class) = 0;
-	 list = TREE_CHAIN (list);
+	 class_list = TREE_CHAIN (class_list);
 	 return;
 	}
 if (TYPE_SIZE (this_class) == NULL_TREE)
@@ -1721,7 +1706,7 @@ layout_class (this_class)
 		{
 		 TYPE_SIZE (this_class) = error_mark_node;
 		 CLASS_BEING_LAIDOUT (this_class) = 0;
-		 list = TREE_CHAIN (list);
+		 class_list = TREE_CHAIN (class_list);
 		 return;
 		}
 	 }
@@ -1733,7 +1718,7 @@ layout_class (this_class)
 fold (convert (int_type_node, TYPE_SIZE_UNIT (this_class)));
 
 CLASS_BEING_LAIDOUT (this_class) = 0;
- list = TREE_CHAIN (list);
+ class_list = TREE_CHAIN (class_list);
 }
 
 void
@@ -1845,8 +1830,6 @@ layout_class_method (this_class, super_c
 return dtable_count;
 }
 
-static tree registered_class = NULL_TREE;
-
 void
 register_class ()
 {
@@ -1911,7 +1894,9 @@ void
 init_class_processing ()
 {
 registerClass_libfunc = gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterClass");
- ggc_add_tree_root (&registered_class, 1);
+ ggc_add_tree_root (class_roots, sizeof (class_roots) / sizeof (tree));
+ fields_ident = get_identifier ("fields");
+ info_ident = get_identifier ("info");
 ggc_add_rtx_root (&registerClass_libfunc, 1);
 gcc_obstack_init (&temporary_obstack);
 }
Index: expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/expr.c,v
retrieving revision 1.96
diff -u -p -r1.96 expr.c
--- expr.c	2001年01月17日 00:39:09	1.96
+++ expr.c	2001年01月20日 06:11:55
@@ -352,8 +352,8 @@ pop_type_0 (type, messagep)
 /* This is a kludge, but matches what Sun's verifier does.
 	 It can be tricked, but is safe as long as type errors
 	 (i.e. interface method calls) are caught at run-time. */
- /* FIXME: this is worse than a kludge, probably. */
- return object_ptr_type_node;
+ else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type))))
+	return object_ptr_type_node;
 }
 {
 const char *str1 = "expected type '";
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月20日 06:11:56
@@ -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;
@@ -171,11 +166,21 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmem
 if (len == zipd->filename_length &&
 	 strncmp (ZIPDIR_FILENAME (zipd), zipmember, len) == 0)
 	{
-	 JCF_ZERO (jcf);
+ 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;
+}
+
+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)
@@ -190,7 +195,12 @@ DEFUN(open_in_zip, (jcf, zipfile, zipmem
 	 }
 	 else
 	 {
+ z_stream d_stream; /* decompression stream */
 	 char *buffer;
+ 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 +222,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.69
diff -u -p -r1.69 jcf-parse.c
--- jcf-parse.c	2001年01月15日 08:01:21	1.69
+++ jcf-parse.c	2001年01月20日 06:11:56
@@ -70,14 +70,16 @@ extern struct obstack permanent_obstack;
 before static field references. */
 extern int always_initialize_class_p;
 
+static tree parse_roots[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
+
 /* The FIELD_DECL for the current field. */
-static tree current_field = NULL_TREE;
+#define current_field parse_roots[0]
 
 /* The METHOD_DECL for the current method. */
-static tree current_method = NULL_TREE;
+#define current_method parse_roots[1]
 
 /* A list of file names. */
-static tree current_file_list = NULL_TREE;
+#define current_file_list parse_roots[2]
 
 /* The Java .class file that provides main_class; the main input file. */
 static struct JCF main_jcf[1];
@@ -89,11 +91,30 @@ 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));
+static void ggc_mark_jcf PARAMS ((void**));
 
+static void
+ggc_mark_jcf (elt)
+ void **elt;
+{
+ JCF *jcf = *(JCF**) elt;
+ if (jcf != NULL)
+ {
+ CPool *cpool = &jcf->cpool;
+ int size = CPOOL_COUNT(cpool);
+ int index;
+ for (index = 1; index < size; index++)
+	{
+	 int tag = JPOOL_TAG (jcf, index);
+	 if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
+	 ggc_mark_tree ((tree) cpool->data[index]);
+	}
+ }
+}
+
 /* Handle "SourceFile" attribute. */
 
 static void
@@ -484,47 +505,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;
 }
 
@@ -648,7 +671,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);
@@ -932,7 +955,7 @@ yyparse ()
 return 0;
 }
 
-static struct ZipFileCache *localToFile;
+static struct ZipFile *localToFile;
 
 /* Process all class entries found in the zip file. */
 static void
@@ -941,8 +964,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;
 
@@ -956,7 +979,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);
 	}
 
@@ -982,8 +1005,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;
@@ -1023,42 +1046,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),
@@ -1080,8 +1076,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;
@@ -1096,7 +1091,7 @@ void
 init_jcf_parse ()
 {
 /* Register roots with the garbage collector. */
- ggc_add_tree_root (&current_field, 1);
- ggc_add_tree_root (&current_method, 1);
- ggc_add_tree_root (&current_file_list, 1);
+ ggc_add_tree_root (parse_roots, sizeof (parse_roots) / sizeof(tree));
+
+ ggc_add_root (&current_jcf, 1, sizeof (JCF), ggc_mark_jcf);
 }
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月20日 06:11:57
@@ -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: verify.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/verify.c,v
retrieving revision 1.35
diff -u -p -r1.35 verify.c
--- verify.c	2001年01月14日 21:48:10	1.35
+++ verify.c	2001年01月20日 06:12:06
@@ -232,7 +232,7 @@ merge_type_state (label)
 int cur_length = stack_pointer + nlocals;
 tree vec = LABEL_TYPE_STATE (label);
 tree return_map;
- if (vec == NULL_TREE || !LABEL_VERIFIED (label))
+ if (vec == NULL_TREE)
 {
 if (!vec)
 	{
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月20日 06:12:07
@@ -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: 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月20日 06:12:07
@@ -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
-- 
	--Per Bothner
per@bothner.com http://www.bothner.com/~per/


More information about the Java mailing list

AltStyle によって変換されたページ (->オリジナル) /