From: Tom Tromey Date: Fri, 13 Nov 1998 14:09:53 +0000 (+0000) Subject: gjavah.c (main): Handle --output-class-directory argument. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=df66b5660c1dc2f388b54d3d8d14951ead739edb;p=gcc.git gjavah.c (main): Handle --output-class-directory argument. * gjavah.c (main): Handle --output-class-directory argument. * jvspec.c (lang_specific_driver): Translate `-d' into -foutput-class-dir. * jcf.h (jcf_write_base_directory): Declare. * lang.c (lang_decode_option): Recognize -foutput-class-dir. * lang-options.h: Mention -foutput-class-dir. * jcf-write.c (jcf_write_base_directory): New global. (make_class_file_name): Put generated .class file into `-d' directory, or into source directory if -d not given. Function now static. (write_classfile): Free class file name. Handle case where class file name is NULL. (DIR_SEPARATOR): New macro. Include From-SVN: r23640 --- diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 4de1cc918d5..21c7db24fe6 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,5 +1,20 @@ 1998-11-13 Tom Tromey + * gjavah.c (main): Handle --output-class-directory argument. + * jvspec.c (lang_specific_driver): Translate `-d' into + -foutput-class-dir. + * jcf.h (jcf_write_base_directory): Declare. + * lang.c (lang_decode_option): Recognize -foutput-class-dir. + * lang-options.h: Mention -foutput-class-dir. + * jcf-write.c (jcf_write_base_directory): New global. + (make_class_file_name): Put generated .class file into `-d' + directory, or into source directory if -d not given. Function now + static. + (write_classfile): Free class file name. Handle case where class + file name is NULL. + (DIR_SEPARATOR): New macro. + Include + * Makefile.in (prefix): New macro. Thu Nov 12 14:15:07 1998 Per Bothner diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c index c88463c1686..5e76337ef95 100644 --- a/gcc/java/jcf-write.c +++ b/gcc/java/jcf-write.c @@ -34,8 +34,19 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "parse.h" /* for BLOCK_EXPR_BODY */ #include "buffer.h" +#include + +#ifndef DIR_SEPARATOR +#define DIR_SEPARATOR '/' +#endif + extern struct obstack temporary_obstack; +/* Base directory in which `.class' files should be written. + NULL means to put the file into the same directory as the + corresponding .java file. */ +char *jcf_write_base_directory = NULL; + /* Make sure bytecode.data is big enough for at least N more bytes. */ #define RESERVE(N) \ @@ -2498,13 +2509,73 @@ generate_classfile (clas, state) return state->first; } -char* +static char * make_class_file_name (clas) tree clas; { - /* Should prepend an output directly, but need an option to specify it. */ - return IDENTIFIER_POINTER (identifier_subst (DECL_NAME (TYPE_NAME (clas)), - "", '.', '/', ".class")); + char *cname, *dname, *slash, *r; + struct stat sb; + + cname = IDENTIFIER_POINTER (identifier_subst (DECL_NAME (TYPE_NAME (clas)), + "", '.', DIR_SEPARATOR, + ".class")); + if (jcf_write_base_directory == NULL) + { + /* Make sure we put the class file into the .java file's + directory, and not into some subdirectory thereof. */ + char *t; + dname = DECL_SOURCE_FILE (TYPE_NAME (clas)); + slash = strrchr (dname, DIR_SEPARATOR); + if (! slash) + { + dname = "."; + slash = dname + 1; + } + t = strrchr (cname, DIR_SEPARATOR); + if (t) + cname = t + 1; + } + else + { + dname = jcf_write_base_directory; + slash = dname + strlen (dname); + } + + r = xmalloc (slash - dname + strlen (cname) + 2); + strncpy (r, dname, slash - dname); + r[slash - dname] = DIR_SEPARATOR; + strcpy (&r[slash - dname + 1], cname); + + /* We try to make new directories when we need them. We only do + this for directories which "might not" exist. For instance, we + assume the `-d' directory exists, but we don't assume that any + subdirectory below it exists. It might be worthwhile to keep + track of which directories we've created to avoid gratuitous + stat()s. */ + dname = r + (slash - dname) + 1; + while (1) + { + cname = strchr (dname, DIR_SEPARATOR); + if (cname == NULL) + break; + *cname = '\0'; + if (stat (r, &sb) == -1) + { + /* Try to make it. */ + if (mkdir (r, 0755) == -1) + { + fatal ("failed to create directory `%s'", r); + free (r); + return NULL; + } + } + *cname = DIR_SEPARATOR; + /* Skip consecutive separators. */ + for (dname = cname + 1; *dname && *dname == DIR_SEPARATOR; ++dname) + ; + } + + return r; } /* Write out the contens of a class (RECORD_TYPE) CLAS, as a .class file. @@ -2518,15 +2589,20 @@ write_classfile (clas) struct jcf_partial state[1]; char *class_file_name = make_class_file_name (clas); struct chunk *chunks; - FILE* stream = fopen (class_file_name, "wb"); - if (stream == NULL) - fatal ("failed to open `%s' for writing", class_file_name); - jcf_dependency_add_target (class_file_name); - init_jcf_state (state, work); - chunks = generate_classfile (clas, state); - write_chunks (stream, chunks); - if (fclose (stream)) - fatal ("failed to close after writing `%s'", class_file_name); + + if (class_file_name != NULL) + { + FILE* stream = fopen (class_file_name, "wb"); + if (stream == NULL) + fatal ("failed to open `%s' for writing", class_file_name); + jcf_dependency_add_target (class_file_name); + init_jcf_state (state, work); + chunks = generate_classfile (clas, state); + write_chunks (stream, chunks); + if (fclose (stream)) + fatal ("failed to close after writing `%s'", class_file_name); + free (class_file_name); + } release_jcf_state (state); } diff --git a/gcc/java/jcf.h b/gcc/java/jcf.h index 1b8aff2dac6..8f748b3617f 100644 --- a/gcc/java/jcf.h +++ b/gcc/java/jcf.h @@ -245,6 +245,8 @@ extern int jcf_unexpected_eof PROTO ((JCF*, int)); ? (((PTR)[-3]&0x1F) << 12) + (((PTR)[-2]&0x3F) << 6) + ((PTR)[-1]&0x3F) \ : ((PTR)++, -1)) +extern char *jcf_write_base_directory; + /* Debug macros, for the front end */ extern int quiet_flag; diff --git a/gcc/java/jvspec.c b/gcc/java/jvspec.c index ba17d092918..325254d2c68 100644 --- a/gcc/java/jvspec.c +++ b/gcc/java/jvspec.c @@ -302,6 +302,12 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) /* Remember this so we can confirm -fmain option. */ will_link = 0; } + else if (strcmp (argv[i], "-d") == 0) + { + /* `-d' option is for javac compatibility. */ + quote = argv[i]; + added -= 1; + } else /* Pass other options through. */ continue; @@ -404,6 +410,16 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) continue; } + if (strcmp (argv[i], "-d") == 0) + { + char *patharg = (char *) xmalloc (sizeof ("-foutput-class-dir=") + + strlen (argv[i + 1]) + 1); + sprintf (patharg, "-foutput-class-dir=%s", argv[i + 1]); + arglist[j] = patharg; + ++i; + continue; + } + if (strncmp (argv[i], "-fmain=", 7) == 0) { if (! will_link) diff --git a/gcc/java/lang-options.h b/gcc/java/lang-options.h index 46101931e60..56d023cdd93 100644 --- a/gcc/java/lang-options.h +++ b/gcc/java/lang-options.h @@ -25,11 +25,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ /* This is the contribution to the `lang_options' array in gcc.c for java. */ -/* CYGNUS LOCAL - the format of this file has been changed to - allow cc1 to implement --help. nickc/--help */ - DEFINE_LANG_NAME ("Java") - + { "-fbounds-check", "" }, { "-fno-bounds-check", "Disable automatic array bounds checking" }, { "-fassume-compiled", "Make is_compiled_class return 1"}, @@ -43,3 +40,4 @@ DEFINE_LANG_NAME ("Java") { "-fclasspath", "Set class path and suppress system path" }, { "-fCLASSPATH", "Set class path" }, { "-I", "Add directory to class path" }, + { "-foutput-class-dir", "Directory where class files should be written" }, diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 14c0ed3787d..3bc001d5e3b 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -147,6 +147,14 @@ lang_decode_option (argc, argv) return 1; } +#define ARG "-foutput-class-dir=" + if (strncmp (p, ARG, sizeof (ARG) - 1) == 0) + { + jcf_write_base_directory = p + sizeof (ARG) - 1; + return 1; + } +#undef ARG + if (p[0] == '-' && p[1] == 'f') { /* Some kind of -f option.