X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fjava%2Fjcf-parse.c;h=4e49b1ffcb1fd7ed5da084f2172cb5bc31786274;hp=5ecac053dd70e0cfe0da774045521d7cf353f653;hb=8e452f9c0c8f40aeee57cd573a9d638e53872aea;hpb=2883a3edf742fdc13c2730a16cc47649d6353251 diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index 5ecac053dd7..4e49b1ffcb1 100644 --- a/gcc/java/jcf-parse.c +++ b/gcc/java/jcf-parse.c @@ -1,5 +1,5 @@ /* Parser for Java(TM) .class files. - Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003 + Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GCC. @@ -41,12 +41,14 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "ggc.h" #include "debug.h" #include "assert.h" +#include "tm_p.h" +#include "cgraph.h" #ifdef HAVE_LOCALE_H #include #endif -#ifdef HAVE_NL_LANGINFO +#ifdef HAVE_LANGINFO_CODESET #include #endif @@ -62,7 +64,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ text = (JCF)->read_ptr; \ save = text[LENGTH]; \ text[LENGTH] = 0; \ - (JCF)->cpool.data[INDEX].t = get_identifier (text); \ + (JCF)->cpool.data[INDEX].t = get_identifier ((const char *) text); \ text[LENGTH] = save; \ JCF_SKIP (JCF, LENGTH); } while (0) @@ -70,10 +72,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ extern struct obstack temporary_obstack; -/* Set to nonzero value in order to emit class initilization code - before static field references. */ -extern int always_initialize_class_p; - static GTY(()) tree parse_roots[3]; /* The FIELD_DECL for the current field. */ @@ -93,16 +91,36 @@ static struct ZipFile *localToFile; /* Declarations of some functions used here. */ static void handle_innerclass_attribute (int count, JCF *); static tree give_name_to_class (JCF *jcf, int index); +static char *compute_class_name (struct ZipDirectory *zdir); +static int classify_zip_file (struct ZipDirectory *zdir); static void parse_zip_file_entries (void); static void process_zip_dir (FILE *); static void parse_source_file_1 (tree, FILE *); static void parse_source_file_2 (void); static void parse_source_file_3 (void); static void parse_class_file (void); +static void handle_deprecated (void); static void set_source_filename (JCF *, int); static void jcf_parse (struct JCF*); static void load_inner_classes (tree); +/* Handle "Deprecated" attribute. */ +static void +handle_deprecated (void) +{ + if (current_field != NULL_TREE) + FIELD_DEPRECATED (current_field) = 1; + else if (current_method != NULL_TREE) + METHOD_DEPRECATED (current_method) = 1; + else if (current_class != NULL_TREE) + CLASS_DEPRECATED (TYPE_NAME (current_class)) = 1; + else + { + /* Shouldn't happen. */ + abort (); + } +} + /* Handle "SourceFile" attribute. */ static void @@ -131,7 +149,7 @@ set_source_filename (JCF *jcf, int index) #define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \ { tree super_class = SUPER==0 ? NULL_TREE : get_class_constant (jcf, SUPER); \ - current_class = give_name_to_class (jcf, THIS); \ + output_class = current_class = give_name_to_class (jcf, THIS); \ set_super_info (ACCESS_FLAGS, current_class, super_class, INTERFACES_COUNT);} #define HANDLE_CLASS_INTERFACE(INDEX) \ @@ -197,6 +215,8 @@ set_source_filename (JCF *jcf, int index) DECL_FUNCTION_THROWS (current_method) = nreverse (list); \ } +#define HANDLE_DEPRECATED_ATTRIBUTE() handle_deprecated () + /* Link seen inner classes to their outer context and register the inner class to its outer context. They will be later loaded. */ #define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \ @@ -253,7 +273,8 @@ get_constant (JCF *jcf, int index) case CONSTANT_Long: { unsigned HOST_WIDE_INT num = JPOOL_UINT (jcf, index); - HOST_WIDE_INT lo, hi; + unsigned HOST_WIDE_INT lo; + HOST_WIDE_INT hi; lshift_double (num, 0, 32, 64, &lo, &hi, 0); num = JPOOL_UINT (jcf, index+1); add_double (lo, hi, num, 0, &lo, &hi); @@ -356,7 +377,7 @@ handle_innerclass_attribute (int count, JCF *jcf) entry isn't a member (like an inner class) the value is 0. */ int ocii = JCF_readu2 (jcf); /* Read inner_name_index. If the class we're dealing with is - an annonymous class, it must be 0. */ + an anonymous class, it must be 0. */ int ini = JCF_readu2 (jcf); /* Read the access flag. */ int acc = JCF_readu2 (jcf); @@ -391,11 +412,11 @@ give_name_to_class (JCF *jcf, int i) tree this_class; int j = JPOOL_USHORT1 (jcf, i); /* verify_constant_pool confirmed that j is a CONSTANT_Utf8. */ - tree class_name = unmangle_classname (JPOOL_UTF_DATA (jcf, j), + tree class_name = unmangle_classname ((const char *) JPOOL_UTF_DATA (jcf, j), JPOOL_UTF_LENGTH (jcf, j)); this_class = lookup_class (class_name); input_filename = DECL_SOURCE_FILE (TYPE_NAME (this_class)); - lineno = 0; + input_line = 0; if (main_input_filename == NULL && jcf == main_jcf) main_input_filename = input_filename; @@ -419,11 +440,11 @@ get_class_constant (JCF *jcf, int i) { int name_index = JPOOL_USHORT1 (jcf, i); /* verify_constant_pool confirmed that name_index is a CONSTANT_Utf8. */ - const char *name = JPOOL_UTF_DATA (jcf, name_index); + const char *name = (const char *) JPOOL_UTF_DATA (jcf, name_index); int nlength = JPOOL_UTF_LENGTH (jcf, name_index); if (name[0] == '[') /* Handle array "classes". */ - type = TREE_TYPE (parse_signature_string (name, nlength)); + type = TREE_TYPE (parse_signature_string ((const unsigned char *) name, nlength)); else { tree cname = unmangle_classname (name, nlength); @@ -448,7 +469,8 @@ read_class (tree name) JCF this_jcf, *jcf; tree icv, class = NULL_TREE; tree save_current_class = current_class; - const char *save_input_filename = input_filename; + tree save_output_class = output_class; + location_t save_location = input_location; JCF *save_current_jcf = current_jcf; if ((icv = IDENTIFIER_CLASS_VALUE (name)) != NULL_TREE) @@ -473,29 +495,35 @@ read_class (tree name) if (current_jcf->java_source) { const char *filename = current_jcf->filename; - tree file; + tree given_file, real_file; FILE *finput; int generate; java_parser_context_save_global (); java_push_parser_context (); - BUILD_FILENAME_IDENTIFIER_NODE (file, filename); - generate = IS_A_COMMAND_LINE_FILENAME_P (file); + + given_file = get_identifier (filename); + real_file = get_identifier (lrealpath (filename)); + + generate = IS_A_COMMAND_LINE_FILENAME_P (given_file); if (wfl_operator == NULL_TREE) wfl_operator = build_expr_wfl (NULL_TREE, NULL, 0, 0); - EXPR_WFL_FILENAME_NODE (wfl_operator) = file; + EXPR_WFL_FILENAME_NODE (wfl_operator) = given_file; input_filename = ggc_strdup (filename); - current_class = NULL_TREE; + output_class = current_class = NULL_TREE; current_function_decl = NULL_TREE; - if (!HAS_BEEN_ALREADY_PARSED_P (file)) + + if (! HAS_BEEN_ALREADY_PARSED_P (real_file)) { - if (!(finput = fopen (input_filename, "r"))) - fatal_io_error ("can't reopen %s", input_filename); - parse_source_file_1 (file, finput); + if (! (finput = fopen (input_filename, "r"))) + fatal_error ("can't reopen %s: %m", input_filename); + + parse_source_file_1 (real_file, finput); parse_source_file_2 (); parse_source_file_3 (); + if (fclose (finput)) - fatal_io_error ("can't close %s", input_filename); + fatal_error ("can't close %s: %m", input_filename); } JCF_FINISH (current_jcf); java_pop_parser_context (generate); @@ -507,12 +535,16 @@ read_class (tree name) { java_parser_context_save_global (); java_push_parser_context (); - current_class = class; + output_class = current_class = class; 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); + /* Parsing might change the class, in which case we have to + put it back where we found it. */ + if (current_class != class && icv != NULL_TREE) + TREE_TYPE (icv) = current_class; class = current_class; java_pop_parser_context (0); java_parser_context_restore_global (); @@ -521,8 +553,9 @@ read_class (tree name) load_inner_classes (class); } + output_class = save_output_class; current_class = save_current_class; - input_filename = save_input_filename; + input_location = save_location; current_jcf = save_current_jcf; return 1; } @@ -530,10 +563,6 @@ read_class (tree name) /* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if called from the parser, otherwise it's a RECORD_TYPE node. If VERBOSE is 1, print error message on failure to load a class. */ - -/* Replace calls to load_class by having callers call read_class directly - - and then perhaps rename read_class to load_class. FIXME */ - void load_class (tree class_or_name, int verbose) { @@ -549,7 +578,12 @@ load_class (tree class_or_name, int verbose) name = TYPE_NAME (TREE_PURPOSE (class_or_name)); /* Or it's a type in the making */ else - name = DECL_NAME (TYPE_NAME (class_or_name)); + { + /* If the class is from source code, then it must already be loaded. */ + if (CLASS_FROM_SOURCE_P (class_or_name)) + return; + name = DECL_NAME (TYPE_NAME (class_or_name)); + } saved = name; while (1) @@ -580,7 +614,7 @@ load_class (tree class_or_name, int verbose) /* Parse the .class file JCF. */ -void +static void jcf_parse (JCF* jcf) { int i, code; @@ -665,34 +699,25 @@ load_inner_classes (tree cur_class) } } -void -init_outgoing_cpool (void) -{ - outgoing_cpool = ggc_alloc_cleared (sizeof (struct CPool)); -} - static void parse_class_file (void) { - tree method, field; - const char *save_input_filename = input_filename; - int save_lineno = lineno; + tree method; + location_t save_location = input_location; java_layout_seen_class_methods (); input_filename = DECL_SOURCE_FILE (TYPE_NAME (current_class)); - lineno = 0; - (*debug_hooks->start_source_file) (lineno, input_filename); - init_outgoing_cpool (); + input_line = 0; + (*debug_hooks->start_source_file) (input_line, input_filename); /* Currently we always have to emit calls to _Jv_InitClass when compiling from class files. */ always_initialize_class_p = 1; - for (field = TYPE_FIELDS (current_class); - field != NULL_TREE; field = TREE_CHAIN (field)) - if (FIELD_STATIC (field)) - DECL_EXTERNAL (field) = 0; + gen_indirect_dispatch_tables (current_class); + + java_mark_class_local (current_class); for (method = TYPE_METHODS (current_class); method != NULL_TREE; method = TREE_CHAIN (method)) @@ -721,7 +746,7 @@ parse_class_file (void) DECL_MAX_LOCALS (method) = decl_max_locals; start_java_method (method); give_name_to_locals (jcf); - expand_expr_stmt (build_jni_stub (method)); + *get_stmts () = build_jni_stub (method); end_java_method (); continue; } @@ -733,11 +758,11 @@ parse_class_file (void) continue; } - lineno = 0; + input_line = 0; if (DECL_LINENUMBERS_OFFSET (method)) { - register int i; - register unsigned char *ptr; + int i; + unsigned char *ptr; JCF_SEEK (jcf, DECL_LINENUMBERS_OFFSET (method)); linenumber_count = i = JCF_readu2 (jcf); linenumber_table = ptr = jcf->read_ptr; @@ -745,10 +770,10 @@ parse_class_file (void) for (ptr += 2; --i >= 0; ptr += 4) { int line = GET_u2 (ptr); - /* Set initial lineno lineno to smallest linenumber. + /* Set initial input_line to smallest linenumber. * Needs to be set before init_function_start. */ - if (lineno == 0 || line < lineno) - lineno = line; + if (input_line == 0 || line < input_line) + input_line = line; } } else @@ -763,7 +788,7 @@ parse_class_file (void) give_name_to_locals (jcf); - /* Actually generate code. */ + /* Convert bytecode to trees. */ expand_byte_code (jcf, method); end_java_method (); @@ -774,19 +799,19 @@ parse_class_file (void) finish_class (); - (*debug_hooks->end_source_file) (save_lineno); - input_filename = save_input_filename; - lineno = save_lineno; + (*debug_hooks->end_source_file) (save_location.line); + input_location = save_location; } /* Parse a source file, as pointed by the current value of INPUT_FILENAME. */ static void -parse_source_file_1 (tree file, FILE *finput) +parse_source_file_1 (tree real_file, FILE *finput) { int save_error_count = java_error_count; - /* Mark the file as parsed */ - HAS_BEEN_ALREADY_PARSED_P (file) = 1; + + /* Mark the file as parsed. */ + HAS_BEEN_ALREADY_PARSED_P (real_file) = 1; jcf_dependency_add_file (input_filename, 0); @@ -795,7 +820,7 @@ parse_source_file_1 (tree file, FILE *finput) /* There's no point in trying to find the current encoding unless we are going to do something intelligent with it -- hence the test for iconv. */ -#if defined (HAVE_LOCALE_H) && defined (HAVE_ICONV) && defined (HAVE_NL_LANGINFO) +#if defined (HAVE_LOCALE_H) && defined (HAVE_ICONV) && defined (HAVE_LANGINFO_CODESET) setlocale (LC_CTYPE, ""); if (current_encoding == NULL) current_encoding = nl_langinfo (CODESET); @@ -851,6 +876,21 @@ predefined_filename_p (tree node) return 0; } +/* Generate a function that does all static initialization for this + translation unit. */ + +static void +java_emit_static_constructor (void) +{ + tree body = NULL; + + emit_register_classes (&body); + write_resource_constructor (&body); + + if (body) + cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY); +} + void java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) { @@ -864,7 +904,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) int avail = 2000; finput = fopen (input_filename, "r"); if (finput == NULL) - fatal_io_error ("can't open %s", input_filename); + fatal_error ("can't open %s: %m", input_filename); list = xmalloc(avail); next = list; for (;;) @@ -883,7 +923,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) if (count == 0) { if (! feof (finput)) - fatal_io_error ("error closing %s", input_filename); + fatal_error ("error closing %s: %m", input_filename); *next = '\0'; break; } @@ -894,9 +934,9 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) finput = NULL; } else - list = xstrdup (input_filename); + list = input_filename ? xstrdup (input_filename) : 0; - do + while (list) { for (next = list; ; ) { @@ -959,14 +999,15 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) if (twice) { - const char *saved_input_filename = input_filename; - input_filename = value; - warning ("source file seen twice on command line and will be compiled only once"); - input_filename = saved_input_filename; + location_t warn_loc; + warn_loc.file = value; + warn_loc.line = 0; + warning ("%Hsource file seen twice on command line and " + "will be compiled only once", &warn_loc); } else { - BUILD_FILENAME_IDENTIFIER_NODE (node, value); + node = get_identifier (value); IS_A_COMMAND_LINE_FILENAME_P (node) = 1; current_file_list = tree_cons (NULL_TREE, node, current_file_list); @@ -974,7 +1015,6 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) } list = next; } - while (next); if (filename_count == 0) warning ("no input file specified"); @@ -989,7 +1029,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) resource_filename = IDENTIFIER_POINTER (TREE_VALUE (current_file_list)); compile_resource_file (resource_name, resource_filename); - return; + goto finish; } current_jcf = main_jcf; @@ -999,19 +1039,21 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) unsigned char magic_string[4]; uint32 magic = 0; tree name = TREE_VALUE (node); + tree real_file; /* Skip already parsed files */ - if (HAS_BEEN_ALREADY_PARSED_P (name)) + real_file = get_identifier (lrealpath (IDENTIFIER_POINTER (name))); + if (HAS_BEEN_ALREADY_PARSED_P (real_file)) continue; /* Close previous descriptor, if any */ if (finput && fclose (finput)) - fatal_io_error ("can't close input file %s", main_input_filename); + fatal_error ("can't close input file %s: %m", main_input_filename); finput = fopen (IDENTIFIER_POINTER (name), "rb"); if (finput == NULL) - fatal_io_error ("can't open %s", IDENTIFIER_POINTER (name)); - + fatal_error ("can't open %s: %m", IDENTIFIER_POINTER (name)); + #ifdef IO_BUFFER_SIZE setvbuf (finput, xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE); @@ -1046,7 +1088,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) if (open_in_zip (main_jcf, input_filename, NULL, 0) < 0) fatal_error ("bad zip/jar file %s", IDENTIFIER_POINTER (name)); localToFile = SeenZipFiles; - /* Register all the class defined there. */ + /* Register all the classes defined there. */ process_zip_dir (main_jcf->read_state); parse_zip_file_entries (); /* @@ -1059,7 +1101,8 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) JAVA_FILE_P (node) = 1; java_push_parser_context (); java_parser_context_save_global (); - parse_source_file_1 (name, finput); + + parse_source_file_1 (real_file, finput); java_parser_context_restore_global (); java_pop_parser_context (1); } @@ -1082,7 +1125,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) input_filename = IDENTIFIER_POINTER (TREE_VALUE (node)); if (CLASS_FILE_P (node)) { - current_class = TREE_PURPOSE (node); + output_class = current_class = TREE_PURPOSE (node); current_jcf = TYPE_JCF (current_class); layout_class (current_class); load_inner_classes (current_class); @@ -1093,12 +1136,63 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED) input_filename = main_input_filename; java_expand_classes (); - if (!java_report_errors () && !flag_syntax_only) - { - emit_register_classes (); - if (flag_indirect_dispatch) - emit_offset_symbol_table (); - } + if (java_report_errors () || flag_syntax_only) + return; + + /* Expand all classes compiled from source. */ + java_finish_classes (); + + finish: + /* Arrange for any necessary initialization to happen. */ + java_emit_static_constructor (); + + /* Only finalize the compilation unit after we've told cgraph which + functions have their addresses stored. */ + cgraph_finalize_compilation_unit (); + cgraph_optimize (); +} + + +/* Return the name of the class corresponding to the name of the file + in this zip entry. The result is newly allocated using ALLOC. */ +static char * +compute_class_name (struct ZipDirectory *zdir) +{ + char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir); + char *class_name; + int j; + + class_name = ALLOC (zdir->filename_length + 1 - 6); + strncpy (class_name, class_name_in_zip_dir, zdir->filename_length - 6); + class_name [zdir->filename_length - 6] = '\0'; + for (j = 0; class_name[j]; ++j) + class_name[j] = class_name[j] == '/' ? '.' : class_name[j]; + return class_name; +} + +/* Return 0 if we should skip this entry, 1 if it is a .class file, 2 + if it is a property file of some sort. */ +static int +classify_zip_file (struct ZipDirectory *zdir) +{ + char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir); + + if (zdir->filename_length > 6 + && !strncmp (&class_name_in_zip_dir[zdir->filename_length - 6], + ".class", 6)) + return 1; + + /* For now we drop the manifest, but not other information. */ + if (zdir->filename_length == 20 + && !strncmp (class_name_in_zip_dir, "META-INF/MANIFEST.MF", 20)) + return 0; + + /* Drop directory entries. */ + if (zdir->filename_length > 0 + && class_name_in_zip_dir[zdir->filename_length - 1] == '/') + return 0; + + return 2; } /* Process all class entries found in the zip file. */ @@ -1112,35 +1206,82 @@ parse_zip_file_entries (void) i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir)) { tree class; - - /* We don't need to consider those files. */ - if (!zdir->size || !zdir->filename_offset) - continue; - - class = lookup_class (get_identifier (ZIPDIR_FILENAME (zdir))); - current_jcf = TYPE_JCF (class); - current_class = class; - if ( !CLASS_LOADED_P (class)) + switch (classify_zip_file (zdir)) { - if (! CLASS_PARSED_P (class)) - { - read_zip_member(current_jcf, zdir, localToFile); - jcf_parse (current_jcf); - } - layout_class (current_class); - load_inner_classes (current_class); - } + case 0: + continue; - if (TYPE_SIZE (current_class) != error_mark_node) - { - input_filename = current_jcf->filename; - parse_class_file (); - FREE (current_jcf->buffer); /* No longer necessary */ - /* Note: there is a way to free this buffer right after a - class seen in a zip file has been parsed. The idea is the - set its jcf in such a way that buffer will be reallocated - the time the code for the class will be generated. FIXME. */ + case 1: + { + char *class_name = compute_class_name (zdir); + class = lookup_class (get_identifier (class_name)); + FREE (class_name); + current_jcf = TYPE_JCF (class); + output_class = current_class = class; + + if (! CLASS_LOADED_P (class)) + { + if (! CLASS_PARSED_P (class)) + { + read_zip_member (current_jcf, zdir, localToFile); + jcf_parse (current_jcf); + } + layout_class (current_class); + load_inner_classes (current_class); + } + + if (TYPE_SIZE (current_class) != error_mark_node) + { + input_filename = current_jcf->filename; + parse_class_file (); + FREE (current_jcf->buffer); /* No longer necessary */ + /* Note: there is a way to free this buffer right after a + class seen in a zip file has been parsed. The idea is the + set its jcf in such a way that buffer will be reallocated + the time the code for the class will be generated. FIXME. */ + } + } + break; + + case 2: + { + char *file_name, *class_name_in_zip_dir, *buffer; + JCF *jcf; + file_name = ALLOC (zdir->filename_length + 1); + class_name_in_zip_dir = ZIPDIR_FILENAME (zdir); + strncpy (file_name, class_name_in_zip_dir, zdir->filename_length); + file_name[zdir->filename_length] = '\0'; + jcf = ALLOC (sizeof (JCF)); + JCF_ZERO (jcf); + jcf->read_state = finput; + jcf->filbuf = jcf_filbuf_from_stdio; + jcf->java_source = 0; + jcf->classname = NULL; + jcf->filename = file_name; + jcf->zipd = zdir; + + if (read_zip_member (jcf, zdir, localToFile) < 0) + fatal_error ("error while reading %s from zip file", file_name); + + buffer = ALLOC (zdir->filename_length + 1 + + (jcf->buffer_end - jcf->buffer)); + strcpy (buffer, file_name); + /* This is not a typo: we overwrite the trailing \0 of the + file name; this is just how the data is laid out. */ + memcpy (buffer + zdir->filename_length, + jcf->buffer, jcf->buffer_end - jcf->buffer); + + compile_resource_data (file_name, buffer, + jcf->buffer_end - jcf->buffer); + JCF_FINISH (jcf); + FREE (jcf); + FREE (buffer); + } + break; + + default: + abort (); } } } @@ -1160,37 +1301,21 @@ process_zip_dir (FILE *finput) char *class_name, *file_name, *class_name_in_zip_dir; tree class; JCF *jcf; - int j; class_name_in_zip_dir = ZIPDIR_FILENAME (zdir); - /* We choose to not to process entries with a zero size or entries - not bearing the .class extension. */ - if (!zdir->size || !zdir->filename_offset || - strncmp (&class_name_in_zip_dir[zdir->filename_length-6], - ".class", 6)) - { - /* So it will be skipped in parse_zip_file_entries */ - zdir->size = 0; - continue; - } + /* Here we skip non-class files; we handle them later. */ + if (classify_zip_file (zdir) != 1) + continue; - class_name = ALLOC (zdir->filename_length+1-6); + class_name = compute_class_name (zdir); file_name = ALLOC (zdir->filename_length+1); jcf = ggc_alloc (sizeof (JCF)); JCF_ZERO (jcf); - strncpy (class_name, class_name_in_zip_dir, zdir->filename_length-6); - class_name [zdir->filename_length-6] = '\0'; strncpy (file_name, class_name_in_zip_dir, zdir->filename_length); file_name [zdir->filename_length] = '\0'; - for (j=0; class_name[j]; j++) - class_name [j] = (class_name [j] == '/' ? '.' : class_name [j]); - - /* Yes, we write back the true class name into the zip directory. */ - strcpy (class_name_in_zip_dir, class_name); - zdir->filename_length = j; class = lookup_class (get_identifier (class_name)); jcf->read_state = finput;