From bb9b756cf81ed964550ca8ec0b165271e80ab3fe Mon Sep 17 00:00:00 2001 From: tromey Date: Thu, 22 Oct 1998 12:06:05 +0000 Subject: [PATCH] * jcf-io.c (find_class): Use saw_java_source to determine when to look for `.java' file. * jcf-parse.c (saw_java_source): New global. (yyparse): Set it if `.java' file seen. * Make-lang.in (JAVA_SRCS): Added jcf-path.c. (GCJH_SOURCES): Likewise. * Makefile.in (datadir): New macro. (libjava_zip): Likewise. (JAVA_OBJS): Added jcf-path.o. (../jcf-dump$(exeext)): Depend on and link with jcf-depend.o. (../gcjh$(exeext)): Likewise. (jcf-path.o): New target. * java-tree.h (fix_classpath): Removed decl. * jcf-parse.c (fix_classpath): Removed. (load_class): Don't call fix_classpath. * parse.y (read_import_dir): Don't call fix_classpath. * lex.h: Don't mention classpath. * lex.c (java_init_lex): Don't initialize classpath. * jcf-io.c (classpath): Removed global. (find_class): Use jcf_path iteration functions. Correctly search class path for .java file. (open_in_zip): New argument `is_system'. * jcf-dump.c (main): Call jcf_path_init. Recognize all new classpath-related options. * lang.c (lang_decode_option): Handle -fclasspath, -fCLASSPATH, and -I. (lang_init): Call jcf_path_init. * lang-options.h: Mention -I, -fclasspath, and -fCLASSPATH. * lang-specs.h: Handle -I. Minor cleanup to -M options. Correctly put braces around second string in each entry. * gjavah.c (main): Call jcf_path_init. Recognize all the new classpath-related options. (help): Updated for new options. * jcf.h: Declare functions from jcf-path.c. Don't mention `classpath' global. * jcf-path.c: New file. * jcf-depend.c: Include jcf.h. * jcf-write.c (localvar_alloc): Returns `void'. (localvar_free): Removed unused variable. * lang.c (OBJECT_SUFFIX): Define if not already defined. (init_parse): Use OBJECT_SUFFIX, not ".o". git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@23219 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/java/ChangeLog | 48 +++++++ gcc/java/Make-lang.in | 5 +- gcc/java/Makefile.in | 24 +++- gcc/java/gjavah.c | 26 ++-- gcc/java/java-tree.h | 1 - gcc/java/jcf-depend.c | 9 +- gcc/java/jcf-dump.c | 52 +++----- gcc/java/jcf-io.c | 275 +++++++++++++++++++------------------- gcc/java/jcf-parse.c | 43 +++--- gcc/java/jcf-path.c | 341 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/java/jcf-write.c | 3 +- gcc/java/jcf.h | 16 ++- gcc/java/lang-options.h | 3 + gcc/java/lang-specs.h | 11 +- gcc/java/lang.c | 32 ++++- gcc/java/lex.c | 1 - gcc/java/lex.h | 1 - gcc/java/parse.c | 8 +- gcc/java/parse.y | 2 - 19 files changed, 672 insertions(+), 229 deletions(-) create mode 100644 gcc/java/jcf-path.c diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 9a0c08f10f8..0d1665f0cf6 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,51 @@ +1998-10-22 Tom Tromey + + * jcf-io.c (find_class): Use saw_java_source to determine when to + look for `.java' file. + * jcf-parse.c (saw_java_source): New global. + (yyparse): Set it if `.java' file seen. + + * Make-lang.in (JAVA_SRCS): Added jcf-path.c. + (GCJH_SOURCES): Likewise. + * Makefile.in (datadir): New macro. + (libjava_zip): Likewise. + (JAVA_OBJS): Added jcf-path.o. + (../jcf-dump$(exeext)): Depend on and link with jcf-depend.o. + (../gcjh$(exeext)): Likewise. + (jcf-path.o): New target. + * java-tree.h (fix_classpath): Removed decl. + * jcf-parse.c (fix_classpath): Removed. + (load_class): Don't call fix_classpath. + * parse.y (read_import_dir): Don't call fix_classpath. + * lex.h: Don't mention classpath. + * lex.c (java_init_lex): Don't initialize classpath. + * jcf-io.c (classpath): Removed global. + (find_class): Use jcf_path iteration functions. Correctly search + class path for .java file. + (open_in_zip): New argument `is_system'. + * jcf-dump.c (main): Call jcf_path_init. Recognize all new + classpath-related options. + * lang.c (lang_decode_option): Handle -fclasspath, -fCLASSPATH, + and -I. + (lang_init): Call jcf_path_init. + * lang-options.h: Mention -I, -fclasspath, and -fCLASSPATH. + * lang-specs.h: Handle -I. Minor cleanup to -M options. + Correctly put braces around second string in each entry. + * gjavah.c (main): Call jcf_path_init. Recognize all the new + classpath-related options. + (help): Updated for new options. + * jcf.h: Declare functions from jcf-path.c. Don't mention + `classpath' global. + * jcf-path.c: New file. + + * jcf-depend.c: Include jcf.h. + + * jcf-write.c (localvar_alloc): Returns `void'. + (localvar_free): Removed unused variable. + + * lang.c (OBJECT_SUFFIX): Define if not already defined. + (init_parse): Use OBJECT_SUFFIX, not ".o". + Wed Oct 21 07:54:11 1998 Alexandre Petit-Bianco * class.c (emit_register_classes): Renamed from diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in index a7526afb0f1..0ec63d54144 100644 --- a/gcc/java/Make-lang.in +++ b/gcc/java/Make-lang.in @@ -74,7 +74,7 @@ JAVA_SRCS = $(srcdir)/java/parse.y $(srcdir)/java/class.c \ $(srcdir)/java/verify.c $(srcdir)/java/zextract.c $(srcdir)/java/jcf-io.c \ $(srcdir)/java/jcf-parse.c $(srcdir)/java/mangle.c \ $(srcdir)/java/jcf-write.c $(srcdir)/java/buffer.c \ - $(srcdir)/java/jcf-depend.c + $(srcdir)/java/jcf-depend.c $(srcdir)/java/jcf-path.c jc1$(exeext): $(P) $(JAVA_SRCS) $(LIBDEPS) stamp-objlist cd java; $(MAKE) $(FLAGS_TO_PASS) $(JAVA_FLAGS_TO_PASS) ../jc1$(exeext) @@ -119,7 +119,8 @@ jvgenmain$(exeext): $(srcdir)/java/jvgenmain.c $(srcdir)/java/mangle.c \ GCJH_SOURCES = $(srcdir)/java/gjavah.c $(srcdir)/java/jcf-io.c \ $(srcdir)/java/zextract.c $(srcdir)/java/jcf-reader.c \ $(srcdir)/java/jcf.h $(srcdir)/java/javaop.h \ - $(srcdir)/java/javaop.def $(srcdir)/java/jcf-depend.c + $(srcdir)/java/javaop.def $(srcdir)/java/jcf-depend.c \ + $(srcdir)/java/jcf-path.c gcjh$(exeext): $(GCJH_SOURCES) cd java && $(MAKE) $(FLAGS_TO_PASS) $(JAVA_FLAGS_TO_PASS) ../gcjh$(exeext) diff --git a/gcc/java/Makefile.in b/gcc/java/Makefile.in index 25eedf552b7..217a5bea4d5 100644 --- a/gcc/java/Makefile.in +++ b/gcc/java/Makefile.in @@ -104,6 +104,10 @@ objdir = . srcdir = @srcdir@ VPATH = @srcdir@ +# Directory holding libjava.zip. +datadir = @datadir@ +libjava_zip = $(datadir)/libjava.zip + # Additional system libraries to link with. CLIB= @@ -178,7 +182,7 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config -I$(srcdir) # JAVA_OBJS = parse.o class.o decl.o expr.o constants.o lang.o typeck.o \ except.o verify.o zextract.o jcf-io.o jcf-parse.o mangle.o jcf-write.o \ - buffer.o jcf-depend.o + buffer.o jcf-depend.o jcf-path.o JAVA_OBJS_LITE = parse-scan.o jv-scan.o @@ -198,15 +202,19 @@ compiler: ../jc1$(exeext) ../jv-scan$(exeext) $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \ $(JAVA_OBJS_LITE) $(LIBS) -../jcf-dump$(exeext): jcf-dump.o jcf-io.o jcf-depend.o zextract.o - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ jcf-dump.o jcf-io.o jcf-depend.o zextract.o $(LIBS) +../jcf-dump$(exeext): jcf-dump.o jcf-io.o jcf-depend.o jcf-path.o \ + zextract.o + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ jcf-dump.o jcf-io.o \ + jcf-depend.o jcf-path.o zextract.o # Dependencies here must be kept in sync with dependencies in Make-lang.in. ../jvgenmain$(exeext): jvgenmain.o mangle.o $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ jvgenmain.o mangle.o ../obstack.o -../gcjh$(exeext): gjavah.o jcf-io.o jcf-depend.o zextract.o - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gjavah.o jcf-io.o jcf-depend.o zextract.o $(LIBS) +../gcjh$(exeext): gjavah.o jcf-io.o jcf-depend.o jcf-path.o \ + zextract.o + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gjavah.o jcf-io.o \ + jcf-depend.o jcf-path.o zextract.o Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure cd ..; $(SHELL) config.status @@ -240,6 +248,10 @@ keyword.h: keyword.gperf gperf -L KR-C -F ', 0' -p -t -j1 -i 1 -g -o -N java_keyword -k1,3,$$ \ keyword.gperf > keyword.h +jcf-path.o: jcf-path.c $(CONFIG_H) $(srcdir)/../system.h jcf.h + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + -DLIBJAVA_ZIP_FILE='"$(libjava_zip)"' $(srcdir)/jcf-path.c + # These exist for maintenance purposes. # Update the tags table. @@ -277,7 +289,7 @@ expr.o : expr.c $(CONFIG_H) $(JAVA_TREE_H) jcf.h $(srcdir)/../real.h \ $(RTL_H) $(EXPR_H) javaop.h java-opcodes.h $(srcdir)/../except.h \ java-except.h java-except.h parse.h $(srcdir)/../toplev.h \ $(srcdir)/../system.h -jcf-depend.o: jcf-depend.c $(CONFIG_H) $(srcdir)/../system.h +jcf-depend.o: jcf-depend.c $(CONFIG_H) $(srcdir)/../system.h jcf.h jcf-io.o: jcf-io.c $(CONFIG_H) $(srcdir)/../system.h jcf-parse.o : jcf-parse.c $(CONFIG_H) $(JAVA_TREE_H) $(srcdir)/../flags.h \ $(srcdir)/../input.h java-except.h $(srcdir)/../system.h diff --git a/gcc/java/gjavah.c b/gcc/java/gjavah.c index 4ad28db46a8..c8a9facb19c 100644 --- a/gcc/java/gjavah.c +++ b/gcc/java/gjavah.c @@ -31,6 +31,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #endif #include +#include + /* The output file. */ FILE *out = NULL; @@ -877,6 +879,8 @@ help () printf ("Usage: gcjh [OPTION]... CLASS...\n\n"); printf ("Generate C++ header files from .class files\n\n"); printf (" --classpath PATH Set path to find .class files\n"); + printf (" --CLASSPATH PATH Set path to find .class files\n"); + printf (" -IDIR Append directory to class path\n"); printf (" -d DIRECTORY Set output directory name\n"); printf (" --help Print this help, then exit\n"); printf (" -o FILE Set output file name\n"); @@ -918,6 +922,8 @@ DEFUN(main, (argc, argv), if (argc <= 1) usage (); + jcf_path_init (); + for (argi = 1; argi < argc; argi++) { char *arg = argv[argi]; @@ -997,10 +1003,19 @@ DEFUN(main, (argc, argv), else if (strcmp (arg, "-classpath") == 0) { if (argi + 1 < argc) - classpath = argv[++argi]; + jcf_path_classpath_arg (argv[++argi]); else java_no_argument (argv[argi]); } + else if (strcmp (arg, "-CLASSPATH") == 0) + { + if (argi + 1 < argc) + jcf_path_CLASSPATH_arg (argv[++argi]); + else + java_no_argument (argv[argi]); + } + else if (strncmp (arg, "-I", 2) == 0) + jcf_path_include_arg (arg + 2); else if (strcmp (arg, "-verbose") == 0 || strcmp (arg, "-v") == 0) verbose++; else if (strcmp (arg, "-stubs") == 0) @@ -1046,19 +1061,14 @@ DEFUN(main, (argc, argv), if (argi == argc) usage (); + jcf_path_seal (); + if (output_file && emit_dependencies) { fprintf (stderr, "gcjh: can't specify both -o and -MD\n"); exit (1); } - if (classpath == NULL) - { - classpath = (char *) getenv ("CLASSPATH"); - if (classpath == NULL) - classpath = ""; - } - for (; argi < argc; argi++) { char *classname = argv[argi]; diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index aef477be4a2..666862fce2e 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -517,7 +517,6 @@ extern void set_super_info PROTO ((int, tree, tree, int)); extern int get_access_flags_from_decl PROTO ((tree)); extern int interface_of_p PROTO ((tree, tree)); extern int inherits_from_p PROTO ((tree, tree)); -extern void fix_classpath PROTO (()); extern void complete_start_java_method PROTO ((tree)); extern void emit_handlers PROTO (()); extern void init_outgoing_cpool PROTO (()); diff --git a/gcc/java/jcf-depend.c b/gcc/java/jcf-depend.c index c923a9c806a..9adbdb4eec0 100644 --- a/gcc/java/jcf-depend.c +++ b/gcc/java/jcf-depend.c @@ -28,6 +28,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include +#include "jcf.h" + /* We keep a linked list of all the files we've already read. */ @@ -95,8 +97,6 @@ add_entry (entp, name) void jcf_dependency_reset () { - struct entry *ent, *next; - free_entry (&dependencies); free_entry (&targets); @@ -139,11 +139,9 @@ jcf_dependency_set_dep_file (name) void jcf_dependency_add_file (filename, system_p) - char *filename; + const char *filename; int system_p; { - struct entry *ent; - /* Just omit system files. */ if (system_p && ! system_files) return; @@ -253,7 +251,6 @@ void jcf_dependency_write () { int column = 0; - struct entry *ent; if (! dep_out) return; diff --git a/gcc/java/jcf-dump.c b/gcc/java/jcf-dump.c index 25243228bff..7ccb97cc6d9 100644 --- a/gcc/java/jcf-dump.c +++ b/gcc/java/jcf-dump.c @@ -712,44 +712,37 @@ DEFUN(main, (argc, argv), if (argc <= 1) usage (); + jcf_path_init (); + for (argi = 1; argi < argc; argi++) { char *arg = argv[argi]; + + /* Just let all arguments be given in either "-" or "--" form. */ + if (arg[0] != '-' || ! strcmp (arg, "--")) + break; + if (arg[0] == '-') { if (strcmp (arg, "-o") == 0 && argi + 1 < argc) output_file = argv[++argi]; - else if (arg[1] == '-') - { - arg++; - if (strcmp (arg, "-classpath") == 0 && argi + 1 < argc) - classpath = argv[++argi]; - else if (strcmp (arg, "-verbose") == 0) - verbose++; - else if (strcmp (arg, "-print-main") == 0) - flag_print_main++; - else if (strcmp (arg, "-javap") == 0) - { - flag_javap_compatible++; - flag_print_constant_pool = 0; - } - else if (arg[2] == '\0') - break; - else - { - fprintf (stderr, "%s: illegal argument\n", argv[argi]); - exit (FATAL_EXIT_CODE); - } - - } else if (strcmp (arg, "-classpath") == 0 && argi + 1 < argc) - classpath = argv[++argi]; + jcf_path_classpath_arg (argv[++argi]); + else if (strcmp (arg, "-CLASSPATH") == 0 && argi + 1 < argc) + jcf_path_CLASSPATH_arg (argv[++argi]); + else if (strncmp (arg, "-I", 2) == 0) + jcf_path_include_arg (arg + 2); else if (strcmp (arg, "-verbose") == 0) verbose++; else if (strcmp (arg, "-print-main") == 0) flag_print_main++; else if (strcmp (arg, "-c") == 0) flag_disassemble_methods++; + else if (strcmp (arg, "-javap") == 0) + { + flag_javap_compatible++; + flag_print_constant_pool = 0; + } else { fprintf (stderr, "%s: illegal argument\n", argv[argi]); @@ -759,8 +752,12 @@ DEFUN(main, (argc, argv), else break; } + if (argi == argc) usage (); + + jcf_path_seal (); + if (flag_print_main) { flag_print_fields = 0; @@ -770,13 +767,6 @@ DEFUN(main, (argc, argv), flag_print_class_info = 0; } - if (classpath == NULL) - { - classpath = (char *) getenv ("CLASSPATH"); - if (classpath == NULL) - classpath = ""; - } - if (output_file) { out = fopen (output_file, "w"); diff --git a/gcc/java/jcf-io.c b/gcc/java/jcf-io.c index 95ddd0d066d..666cda7bdaa 100644 --- a/gcc/java/jcf-io.c +++ b/gcc/java/jcf-io.c @@ -25,8 +25,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "config.h" #include "system.h" -#define ENABLE_UNZIP 1 - #include "jcf.h" #include #include @@ -36,8 +34,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #define O_BINARY 0 /* MS-DOS brain-damage */ #endif -char *classpath; - int DEFUN(jcf_unexpected_eof, (jcf, count), JCF *jcf AND int count) @@ -89,15 +85,14 @@ DEFUN(jcf_filbuf_from_stdio, (jcf, count), return 0; } -#if ENABLE_UNZIP #include "zipfile.h" struct ZipFileCache *SeenZipFiles = NULL; int -DEFUN(open_in_zip, (jcf, -zipfile, zipmember), - JCF *jcf AND const char *zipfile AND const char *zipmember) +DEFUN(open_in_zip, (jcf, zipfile, zipmember), + JCF *jcf AND const char *zipfile AND const char *zipmember + AND int is_system) { struct ZipFileCache* zipf; ZipDirectory *zipd; @@ -108,7 +103,7 @@ zipfile, zipmember), { char magic [4]; int fd = open (zipfile, O_RDONLY | O_BINARY); - jcf_dependency_add_file (zipfile, 0); /* FIXME: system file? */ + jcf_dependency_add_file (zipfile, is_system); if (read (fd, magic, 4) != 4 || GET_u4 (magic) != (JCF_u4)ZIPMAGIC) return -1; lseek (fd, 0L, SEEK_SET); @@ -165,7 +160,6 @@ zipfile, zipmember), } return -1; } -#endif /* ENABLE_UNZIP */ #if JCF_USE_STDIO char* @@ -260,156 +254,175 @@ DEFUN(find_class, (classname, classname_length, jcf, do_class_file), #else int fd; #endif - int i, j, k, java, class; + int i, k, java, class; struct stat java_buf, class_buf; char *dep_file; - - /* A temporary buffer that we grow to be large enough to hold - whatever class name we're working on. */ - static int temp_len = 0; - static char *temp_buffer = NULL; + void *entry, *java_entry; + char *java_buffer; /* Allocate and zero out the buffer, since we don't explicitly put a null pointer when we're copying it below. */ - int buflen = strlen (classpath) + classname_length + 10; + int buflen = jcf_path_max_len () + classname_length + 10; char *buffer = (char *) ALLOC (buflen); bzero (buffer, buflen); - if (buflen > temp_len) - { - temp_len = buflen; - if (temp_buffer == NULL) - temp_buffer = (char *) ALLOC (temp_len); - else - temp_buffer = (char *) REALLOC (temp_buffer, temp_len); - } + java_buffer = (char *) alloca (buflen); jcf->java_source = jcf->outofsynch = 0; - for (j = 0; classpath[j] != '\0'; ) + + for (entry = jcf_path_start (); entry != NULL; entry = jcf_path_next (entry)) { - for (i = 0; classpath[j] != ':' && classpath[j] != '\0'; i++, j++) - buffer[i] = classpath[j]; - if (classpath[j] == ':') - j++; - if (i > 0) /* Empty directory is redundant */ + int dir_len; + + strcpy (buffer, jcf_path_name (entry)); + i = strlen (buffer); + + dir_len = i - 1; + + for (k = 0; k < classname_length; k++, i++) { - int dir_len; - if (buffer[i-1] != '/') - buffer[i++] = '/'; - dir_len = i-1; - for (k = 0; k < classname_length; k++, i++) - { - char ch = classname[k]; - buffer[i] = ch == '.' ? '/' : ch; - } + char ch = classname[k]; + buffer[i] = ch == '.' ? '/' : ch; + } + if (do_class_file) + strcpy (buffer+i, ".class"); + + if (jcf_path_is_zipfile (entry)) + { + int err_code; + JCF _jcf; + if (!do_class_file) + strcpy (buffer+i, "/"); + buffer[dir_len] = '\0'; if (do_class_file) - strcpy (buffer+i, ".class"); -#if ENABLE_UNZIP - if (dir_len > 4 - && buffer[dir_len-4] == '.' && buffer[dir_len-3] == 'z' - && buffer[dir_len-2] == 'i' && buffer[dir_len-1] == 'p') + SOURCE_FRONTEND_DEBUG + (("Trying [...%s]:%s", + &buffer[dir_len-(dir_len > 15 ? 15 : dir_len)], + buffer+dir_len+1)); + if (jcf == NULL) + jcf = &_jcf; + err_code = open_in_zip (jcf, buffer, buffer+dir_len+1, + jcf_path_is_system (entry)); + if (err_code == 0) { - int err_code; - JCF _jcf; if (!do_class_file) - strcpy (buffer+i, "/"); - buffer[dir_len] = '\0'; - if (do_class_file) - SOURCE_FRONTEND_DEBUG - (("Trying [...%s]:%s", - &buffer[dir_len-(dir_len > 15 ? 15 : dir_len)], - buffer+dir_len+1)); - if (jcf == NULL) - jcf = &_jcf; - err_code = open_in_zip (jcf, buffer, buffer+dir_len+1); - if (err_code == 0) - { - if (!do_class_file) - jcf->seen_in_zip = 1; - else - { - buffer[dir_len] = '('; - strcpy (buffer+i, ".class)"); - } - if (jcf == &_jcf) - JCF_FINISH (jcf); - return buffer; - } + jcf->seen_in_zip = 1; else - continue; - } -#endif - /* If we do directories, do them here */ - if (!do_class_file) - { - struct stat dir_buff; - int dir; - buffer[i] = '\0'; /* Was previously unterminated here. */ - if (!(dir = stat (buffer, &dir_buff))) { - jcf->seen_in_zip = 0; - goto found; + buffer[dir_len] = '('; + strcpy (buffer+i, ".class)"); } + if (jcf == &_jcf) + JCF_FINISH (jcf); + return buffer; } - - /* Check for out of synch .class/.java files */ - class = stat (buffer, &class_buf); - strcpy (buffer+i, ".java"); - /* Stash the name of the .java file in the temp buffer. */ - strcpy (temp_buffer, buffer); - java = stat (buffer, &java_buf); - if ((!java && !class) && java_buf.st_mtime >= class_buf.st_mtime) - jcf->outofsynch = 1; - - if (! java) - dep_file = temp_buffer; else - dep_file = buffer; -#if JCF_USE_STDIO - if (!class) + continue; + } + + /* If we do directories, do them here */ + if (!do_class_file) + { + struct stat dir_buff; + int dir; + buffer[i] = '\0'; /* Was previously unterminated here. */ + if (!(dir = stat (buffer, &dir_buff))) { - strcpy (buffer+i, ".class"); - SOURCE_FRONTEND_DEBUG (("Trying %s", buffer)); - stream = fopen (buffer, "rb"); - if (stream) - goto found; + jcf->seen_in_zip = 0; + goto found; } - /* Give .java a try, if necessary */ - if (!java) + } + + class = stat (buffer, &class_buf); + /* This is a little odd: if we didn't find the class file, we + can just skip to the next iteration. However, if this is the + last iteration, then we want to search for the .java file as + well. It was a little easier to implement this with two + loops, as opposed to checking for each type of file each time + through the loop. */ + if (class && jcf_path_next (entry)) + continue; + + /* Check for out of synch .class/.java files. */ + java = 1; + for (java_entry = jcf_path_start (); + java && java_entry != NULL; + java_entry = jcf_path_next (java_entry)) + { + int m, l; + extern int saw_java_source; /* FIXME: temporary. */ + + if (jcf_path_is_zipfile (java_entry)) + continue; + + /* Compute name of .java file. */ + strcpy (java_buffer, jcf_path_name (java_entry)); + l = strlen (java_buffer); + for (m = 0; m < classname_length; ++m) { - strcpy (buffer+i, ".java"); - SOURCE_FRONTEND_DEBUG (("Trying %s", buffer)); - stream = fopen (buffer, "r"); - if (stream) - { - jcf->java_source = 1; - goto found; - } + java_buffer[m + l] = (classname[m] == '.' + ? '/' + : classname[m]); } -#else - if (!class) + strcpy (java_buffer + m + l, ".java"); + + /* FIXME: until the `.java' parser is fully working, we only + look for a .java file when one was mentioned on the + command line. This lets us test the .java parser fairly + easily, without compromising our ability to use the + .class parser without fear. */ + if (saw_java_source) + java = stat (java_buffer, &java_buf); + } + + if (! java && ! class && java_buf.st_mtime >= class_buf.st_mtime) + jcf->outofsynch = 1; + + if (! java) + dep_file = java_buffer; + else + dep_file = buffer; +#if JCF_USE_STDIO + if (!class) + { + SOURCE_FRONTEND_DEBUG (("Trying %s", buffer)); + stream = fopen (buffer, "rb"); + if (stream) + goto found; + } + /* Give .java a try, if necessary */ + if (!java) + { + strcpy (buffer, java_buffer); + SOURCE_FRONTEND_DEBUG (("Trying %s", buffer)); + stream = fopen (buffer, "r"); + if (stream) { - strcpy (buffer+i, ".class"); - SOURCE_FRONTEND_DEBUG (("Trying %s", buffer)); - fd = open (buffer, O_RDONLY | O_BINARY); - if (fd >= 0) - goto found; + jcf->java_source = 1; + goto found; } - /* Give .java a try, if necessary */ - if (!java) + } +#else + if (!class) + { + SOURCE_FRONTEND_DEBUG (("Trying %s", buffer)); + fd = open (buffer, O_RDONLY | O_BINARY); + if (fd >= 0) + goto found; + } + /* Give .java a try, if necessary */ + if (!java) + { + strcpy (buffer, java_buffer); + SOURCE_FRONTEND_DEBUG (("Trying %s", buffer)); + fd = open (buffer, O_RDONLY); + if (fd >= 0) { - if (do_class_file) - strcpy (buffer+i, ".java"); - SOURCE_FRONTEND_DEBUG (("Trying %s", buffer)); - fd = open (buffer, O_RDONLY | O_BINARY); - if (fd >= 0) - { - jcf->java_source = 1; - goto found; - } + jcf->java_source = 1; + goto found; } -#endif } +#endif } free (buffer); return NULL; diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index 3df187fa347..81a1528e750 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 Free Software Foundation, Inc. + Copyright (C) 1996, 1998 Free Software Foundation, Inc. This file is part of GNU CC. @@ -61,6 +61,11 @@ tree current_class = NULL_TREE; /* The class we started with. */ tree main_class = NULL_TREE; +/* This is true if the user specified a `.java' file on the command + line. Otherwise it is 0. FIXME: this is temporary, until our + .java parser is fully working. */ +int saw_java_source = 0; + /* The FIELD_DECL for the current field. */ static tree current_field = NULL_TREE; @@ -413,22 +418,6 @@ get_class_constant (JCF *jcf , int i) } void -fix_classpath () -{ - static char default_path[] = DEFAULT_CLASS_PATH; - - if (classpath == NULL) - { - classpath = (char *) getenv ("CLASSPATH"); - if (classpath == NULL) - { - warning ("CLASSPATH not set"); - classpath = default_path; - } - } -} - -void DEFUN(jcf_out_of_synch, (jcf), JCF *jcf) { @@ -465,8 +454,6 @@ load_class (class_or_name, verbose) push_obstacks (&permanent_obstack, &permanent_obstack); - if (!classpath) - fix_classpath (); /* Search in current zip first. */ if (find_in_current_zip (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name), &jcf) == 0) @@ -475,11 +462,14 @@ load_class (class_or_name, verbose) { if (verbose) { - error ("Cannot find class file class %s.", + error ("Cannot find class file for class %s.", IDENTIFIER_POINTER (name)); TYPE_SIZE (class_or_name) = error_mark_node; +#if 0 + /* FIXME: what to do here? */ if (!strcmp (classpath, DEFAULT_CLASS_PATH)) fatal ("giving up"); +#endif pop_obstacks (); /* FIXME: one pop_obstack() per function */ } return; @@ -730,12 +720,16 @@ yyparse () if (list[0]) { - char *value; + char *value, len; + + len = strlen (list); + if (len > 5 && ! strcmp (&list[len - 5], ".java")) + saw_java_source = 1; if (*list != '/' && several_files) obstack_grow (&temporary_obstack, "./", 2); - - obstack_grow0 (&temporary_obstack, list, strlen (list)); + + obstack_grow0 (&temporary_obstack, list, len); value = obstack_finish (&temporary_obstack); node = get_identifier (value); IS_A_COMMAND_LINE_FILENAME_P (node) = 1; @@ -936,7 +930,8 @@ DEFUN(jcf_figure_file_type, (jcf), if (magic == 0xcafebabe) return JCF_CLASS; - if (!open_in_zip (jcf, input_filename, NULL)) + /* FIXME: is it a system file? */ + if (!open_in_zip (jcf, input_filename, NULL, 0)) { localToFile = ALLOC (sizeof (struct ZipFileCache)); bcopy (SeenZipFiles, localToFile, sizeof (struct ZipFileCache)); diff --git a/gcc/java/jcf-path.c b/gcc/java/jcf-path.c new file mode 100644 index 00000000000..6e88496b549 --- /dev/null +++ b/gcc/java/jcf-path.c @@ -0,0 +1,341 @@ +/* Handle CLASSPATH, -classpath, and path searching. + + Copyright (C) 1998 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. + +Java and all Java-based marks are trademarks or registered trademarks +of Sun Microsystems, Inc. in the United States and other countries. +The Free Software Foundation is independent of Sun Microsystems, Inc. */ + +/* Written by Tom Tromey , October 1998. */ + +#include +#include "system.h" + +#include "jcf.h" + +/* Some boilerplate that really belongs in a header. */ + +#ifndef GET_ENV_PATH_LIST +#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0) +#endif + +/* By default, colon separates directories in a path. */ +#ifndef PATH_SEPARATOR +#define PATH_SEPARATOR ':' +#endif + +#ifndef DIR_SEPARATOR +#define DIR_SEPARATOR '/' +#endif + + + +/* Possible flag values. */ +#define FLAG_SYSTEM 1 +#define FLAG_ZIP 2 + +/* We keep linked lists of directory names. A ``directory'' can be + either an ordinary directory or a .zip file. */ +struct entry +{ + char *name; + int flags; + struct entry *next; +}; + +/* We support several different ways to set the class path. + + built-in system directory (only libjava.zip) + CLASSPATH environment variable + -CLASSPATH overrides CLASSPATH + -classpath option - overrides CLASSPATH, -CLASSPATH, and built-in + -I prepends path to list + + We implement this by keeping several path lists, and then simply + ignoring the ones which are not relevant. */ + +/* This holds all the -I directories. */ +static struct entry *include_dirs; + +/* This holds the CLASSPATH environment variable. */ +static struct entry *classpath_env; + +/* This holds the -CLASSPATH command-line option. */ +static struct entry *classpath_u; + +/* This holds the -classpath command-line option. */ +static struct entry *classpath_l; + +/* This holds the default directories. Some of these will have the + "system" flag set. */ +static struct entry *sys_dirs; + +/* This is the sealed list. It is just a combination of other lists. */ +static struct entry *sealed; + +/* We keep track of the longest path we've seen. */ +static int longest_path = 0; + + + +static void +free_entry (entp) + struct entry **entp; +{ + struct entry *e, *n; + + for (e = *entp; e; e = n) + { + n = e->next; + free (e->name); + free (e); + } + *entp = NULL; +} + +static void +append_entry (entp, ent) + struct entry **entp; + struct entry *ent; +{ + /* It doesn't matter if this is slow, since it is run only at + startup, and then infrequently. */ + struct entry *e; + + /* Find end of list. */ + for (e = *entp; e && e->next; e = e->next) + ; + + if (e) + e->next = ent; + else + *entp = ent; +} + +static void +add_entry (entp, filename, is_system) + struct entry **entp; + char *filename; + int is_system; +{ + int len; + struct entry *n; + + n = (struct entry *) ALLOC (sizeof (struct entry)); + n->flags = is_system ? FLAG_SYSTEM : 0; + n->next = NULL; + + len = strlen (filename); + if (len > 4 && ! strcmp (filename - 4, ".zip")) + { + n->flags |= FLAG_ZIP; + /* If the user uses -classpath then he'll have to include + libjava.zip in the value. We check for this in a simplistic + way. Symlinks will fool this test. This is only used for + -MM and -MMD, so it probably isn't terribly important. */ + if (! strcmp (filename, LIBJAVA_ZIP_FILE)) + n->flags |= FLAG_SYSTEM; + } + + if (filename[len - 1] != '/' && filename[len - 1] != DIR_SEPARATOR) + { + char *f2 = (char *) alloca (len + 1); + strcpy (f2, filename); + f2[len] = DIR_SEPARATOR; + f2[len + 1] = '\0'; + n->name = strdup (f2); + ++len; + } + else + n->name = strdup (filename); + + if (len > longest_path) + longest_path = len; + + append_entry (entp, n); +} + +static void +add_path (entp, cp, is_system) + struct entry **entp; + char *cp; + int is_system; +{ + char *startp, *endp; + + if (cp) + { + char *buf = (char *) alloca (strlen (cp) + 3); + startp = endp = cp; + while (1) + { + if (! *endp || *endp == PATH_SEPARATOR) + { + strncpy (buf, startp, endp - startp); + if (endp == startp) + { + buf[0] = '.'; + buf[1] = DIR_SEPARATOR; + buf[2] = '\0'; + } + else if (endp[-1] != '/' && endp[1] != DIR_SEPARATOR) + { + buf[endp - startp] = DIR_SEPARATOR; + buf[endp - startp + 1] = '\0'; + } + else + buf[endp - startp] = '\0'; + add_entry (entp, buf, is_system); + if (! *endp) + break; + ++endp; + startp = endp; + } + else + ++endp; + } + } +} + +/* Initialize the path module. */ +void +jcf_path_init () +{ + char *cp; + + add_entry (&sys_dirs, ".", 0); + add_entry (&sys_dirs, LIBJAVA_ZIP_FILE, 1); + + GET_ENV_PATH_LIST (cp, "CLASSPATH"); + add_path (&classpath_env, cp, 0); +} + +/* Call this when -classpath is seen on the command line. */ +void +jcf_path_classpath_arg (path) + char *path; +{ + free_entry (&classpath_l); + add_path (&classpath_l, path, 0); +} + +/* Call this when -CLASSPATH is seen on the command line. */ +void +jcf_path_CLASSPATH_arg (path) + char *path; +{ + free_entry (&classpath_u); + add_path (&classpath_u, path, 0); +} + +/* Call this when -I is seen on the command line. */ +void +jcf_path_include_arg (path) + char *path; +{ + add_entry (&include_dirs, path, 0); +} + +/* We `seal' the path by linking everything into one big list. Then + we provide a way to iterate through the sealed list. */ +void +jcf_path_seal () +{ + int do_system = 1; + struct entry *secondary; + + sealed = include_dirs; + include_dirs = NULL; + + if (classpath_l) + { + secondary = classpath_l; + classpath_l = NULL; + do_system = 0; + } + else if (classpath_u) + { + secondary = classpath_u; + classpath_u = NULL; + } + else + { + secondary = classpath_env; + classpath_env = NULL; + } + + free_entry (&classpath_l); + free_entry (&classpath_u); + free_entry (&classpath_env); + + append_entry (&sealed, secondary); + + if (do_system) + { + append_entry (&sealed, sys_dirs); + sys_dirs = NULL; + } + else + free_entry (&sys_dirs); +} + +void * +jcf_path_start () +{ + return (void *) sealed; +} + +void * +jcf_path_next (x) + void *x; +{ + struct entry *ent = (struct entry *) x; + return (void *) ent->next; +} + +/* We guarantee that the return path will either be a zip file, or it + will end with a directory separator. */ +char * +jcf_path_name (x) + void *x; +{ + struct entry *ent = (struct entry *) x; + return ent->name; +} + +int +jcf_path_is_zipfile (x) + void *x; +{ + struct entry *ent = (struct entry *) x; + return (ent->flags & FLAG_ZIP); +} + +int +jcf_path_is_system (x) + void *x; +{ + struct entry *ent = (struct entry *) x; + return (ent->flags & FLAG_SYSTEM); +} + +int +jcf_path_max_len () +{ + return longest_path; +} diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c index 2fb1008fa08..5d092c6ec3a 100644 --- a/gcc/java/jcf-write.c +++ b/gcc/java/jcf-write.c @@ -347,7 +347,7 @@ struct localvar_info #define localvar_max \ ((struct localvar_info**) state->localvars.ptr - localvar_buffer) -int +void localvar_alloc (decl, state) tree decl; struct jcf_partial *state; @@ -403,7 +403,6 @@ localvar_free (decl, state) register struct localvar_info **ptr = &localvar_buffer [index]; register struct localvar_info *info = *ptr; int wide = TYPE_IS_WIDE (TREE_TYPE (decl)); - int i; info->end_label = end_label; diff --git a/gcc/java/jcf.h b/gcc/java/jcf.h index f88ff1041c7..3f98814ea5a 100644 --- a/gcc/java/jcf.h +++ b/gcc/java/jcf.h @@ -222,7 +222,6 @@ typedef struct JCF { #define CONSTANT_Utf8 1 #define CONSTANT_Unicode 2 -extern char *classpath; #define DEFAULT_CLASS_PATH "." extern char *find_class PROTO ((const char *, int, JCF*, int)); @@ -261,9 +260,22 @@ extern int quiet_flag; extern void jcf_dependency_reset PROTO ((void)); extern void jcf_dependency_set_target PROTO ((char *)); extern void jcf_dependency_add_target PROTO ((char *)); -extern void jcf_dependency_set_dep_file PROTO ((char *)); +extern void jcf_dependency_set_dep_file PROTO ((const char *)); extern void jcf_dependency_add_file PROTO ((const char *, int)); extern void jcf_dependency_write PROTO ((void)); extern void jcf_dependency_init PROTO ((int)); +/* Declarations for path handling code. */ +extern void jcf_path_init PROTO ((void)); +extern void jcf_path_classpath_arg PROTO ((char *)); +extern void jcf_path_CLASSPATH_arg PROTO ((char *)); +extern void jcf_path_include_arg PROTO ((char *)); +extern void jcf_path_seal PROTO ((void)); +extern void *jcf_path_start PROTO ((void)); +extern void *jcf_path_next PROTO ((void *)); +extern char *jcf_path_name PROTO ((void *)); +extern int jcf_path_is_zipfile PROTO ((void *)); +extern int jcf_path_is_system PROTO ((void *)); +extern int jcf_path_max_len PROTO ((void)); + #endif diff --git a/gcc/java/lang-options.h b/gcc/java/lang-options.h index 4ea735caab5..0f0f74b581c 100644 --- a/gcc/java/lang-options.h +++ b/gcc/java/lang-options.h @@ -37,3 +37,6 @@ DEFINE_LANG_NAME ("Java") { "-MMD", "Print dependencies to FILE.d" }, { "-M", "Print dependencies to stdout" }, { "-MM", "Print dependencies to stdout" }, + { "-fclasspath", "Set class path and suppress system path" }, + { "-fCLASSPATH", "Set class path" }, + { "-I", "Add directory to class path" }, diff --git a/gcc/java/lang-specs.h b/gcc/java/lang-specs.h index 6a455dbc903..190a44ceedd 100644 --- a/gcc/java/lang-specs.h +++ b/gcc/java/lang-specs.h @@ -24,16 +24,17 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ /* This is the contribution to the `default_compilers' array in gcc.c for Java. */ - {".java", "@java" }, - {".class", "@java" }, + {".java", {"@java"} }, + {".class", {"@java"} }, {"@java", - "%{!E:jc1 %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\ + {"%{!E:jc1 %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\ %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\ %{traditional} %{v:-version} %{pg:-p} %{p}\ %{f*} %{+e*} %{aux-info*}\ - %{MD:-MD} %{MMD:-MMD} %{M:-M} %{MM:-MM}\ + %{I*}\ + %{MD} %{MMD} %{M} %{MM}\ %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ %{!S:as %a %Y\ %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}"}, + %{!pipe:%g.s} %A\n }}"}}, diff --git a/gcc/java/lang.c b/gcc/java/lang.c index df6c50d0c27..b425b8b97c7 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -33,6 +33,10 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "toplev.h" #include "flags.h" +#ifndef OBJECT_SUFFIX +# define OBJECT_SUFFIX ".o" +#endif + /* Table indexed by tree code giving a string containing a character classifying the tree code. Possibilities are t, d, s, c, r, <, 1 and 2. See java/java-tree.def for details. */ @@ -179,6 +183,26 @@ lang_decode_option (argc, argv) return 1; } +#define CLARG "-fclasspath=" + if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0) + { + jcf_path_classpath_arg (p + sizeof (CLARG)); + return 1; + } +#undef CLARG +#define CLARG "-fCLASSPATH=" + else if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0) + { + jcf_path_CLASSPATH_arg (p + sizeof (CLARG)); + return 1; + } +#undef CLARG + else if (strncmp (p, "-I", 2) == 0) + { + jcf_path_include_arg (p + 2); + return 1; + } + return 0; } @@ -207,7 +231,8 @@ init_parse (filename) error ("couldn't determine target name for dependency tracking"); else { - char *buf = (char *) xmalloc (dot - filename + 3); + char *buf = (char *) xmalloc (dot - filename + + 3 + sizeof (OBJECT_SUFFIX)); strncpy (buf, filename, dot - filename); /* If emitting class files, we might have multiple @@ -218,7 +243,7 @@ init_parse (filename) jcf_dependency_set_target (NULL); else { - strcpy (buf + (dot - filename), ".o"); + strcpy (buf + (dot - filename), OBJECT_SUFFIX); jcf_dependency_set_target (buf); } @@ -421,6 +446,9 @@ lang_init () flag_minimal_debug = 0; #endif + jcf_path_init (); + jcf_path_seal (); + decl_printable_name = lang_printable_name; print_error_function = lang_print_error; lang_expand_expr = java_lang_expand_expr; diff --git a/gcc/java/lex.c b/gcc/java/lex.c index 1c103e131cd..504c8414b31 100644 --- a/gcc/java/lex.c +++ b/gcc/java/lex.c @@ -87,7 +87,6 @@ java_init_lex () ctxp->incomplete_class = NULL_TREE; bzero (ctxp->modifier_ctx, 11*sizeof (ctxp->modifier_ctx[0])); - classpath = NULL; bzero (current_jcf, sizeof (JCF)); ctxp->current_parsed_class = NULL; ctxp->package = NULL_TREE; diff --git a/gcc/java/lex.h b/gcc/java/lex.h index fdee404c0a9..b8dc5c2bebb 100644 --- a/gcc/java/lex.h +++ b/gcc/java/lex.h @@ -31,7 +31,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ /* Extern global variables declarations */ extern FILE *finput; extern int lineno; -extern char *classpath; /* A Unicode character, as read from the input file */ typedef unsigned short unicode_t; diff --git a/gcc/java/parse.c b/gcc/java/parse.c index cd66dd01b2a..0d0f964714d 100644 --- a/gcc/java/parse.c +++ b/gcc/java/parse.c @@ -2068,7 +2068,7 @@ static const short yycheck[] = { 3, #define YYPURE 1 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "bison.simple" +#line 3 "/x1/java-install/share/bison.simple" /* Skeleton output parser for bison, Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. @@ -2261,7 +2261,7 @@ __yy_memcpy (char *to, char *from, int count) #endif #endif -#line 196 "bison.simple" +#line 196 "/x1/java-install/share/bison.simple" /* The user can define YYPARSE_PARAM as the name of an argument to be passed into yyparse. The argument should have type void *. @@ -4462,7 +4462,7 @@ case 492: break;} } /* the action file gets copied in in place of this dollarsign */ -#line 498 "bison.simple" +#line 498 "/x1/java-install/share/bison.simple" yyvsp -= yylen; yyssp -= yylen; @@ -6928,8 +6928,6 @@ read_import_dir (wfl) char *founddirname, *d_name; jcf = &jcfr; - if (!classpath) - fix_classpath (); if (!(founddirname = find_class (name, name_len, jcf, 0))) fatal ("Can't import `%s'", name); if (jcf->outofsynch) diff --git a/gcc/java/parse.y b/gcc/java/parse.y index fd0c4b5cc92..84de8f71b94 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -4322,8 +4322,6 @@ read_import_dir (wfl) char *founddirname, *d_name; jcf = &jcfr; - if (!classpath) - fix_classpath (); if (!(founddirname = find_class (name, name_len, jcf, 0))) fatal ("Can't import `%s'", name); if (jcf->outofsynch) -- 2.11.4.GIT