Commit fc45c7ef by Tom Tromey Committed by Tom Tromey

jcf-write.c (write_classfile): Add output class file as target.

	* jcf-write.c (write_classfile): Add output class file as target.
	* lang-options.h: Added -MD, -MMD, -M, and -MM.
	* jcf.h: Added declarations for dependency-tracking functions.
	* lang-specs.h: Handle -M, -MM, MD, and -MMD.
	* lang.c (lang_decode_option): Recognize -MD and -MMD.
	(finish_parse): Call jcf_dependency_write.
	(dependency_tracking): New global.
	(DEPEND_SET_FILE): New define.
	(DEPEND_ENABLE): New define.
	(init_parse): Enable dependency tracking if required.
	Include "flags.h".
	* Makefile.in (JAVA_OBJS): Added jcf-depend.o.
	(../jcf-dump$(exeext)): Depend on and link with jcf-depend.o.
	(../gcjh$(exeext)): Likewise.
	(jcf-depend.o): New target.
	* Make-lang.in (JAVA_SRCS): Added jcf-depend.c.
	(GCJH_SOURCES): Likewise.
	* jcf-io.c (open_class): Call jcf_dependency_add_file.  Added
	dep_name argument.
	(find_classfile): Added dep_name argument.
	(find_class): Compute name of dependency.
	(open_in_zip): Call jcf_dependency_add_file.
	* gjavah.c (output_file): No longer global.
	(usage): Don't mention "gjavah".
	(help): Likewise.
	(java_no_argument): Likewise.
	(version): Likewise.
	(main): Recognize and handle -M family of options.
	(print_mangled_classname): Return is void.
	(process_file): Handle case where output is suppressed.
	(HANDLE_END_FIELD): Likewise.
	(HANDLE_METHOD): Likewise.
	* jcf-depend.c: New file.

From-SVN: r23085
parent bf94d1ec
1998-10-14 Tom Tromey <tromey@cygnus.com>
* jcf-write.c (write_classfile): Add output class file as target.
* lang-options.h: Added -MD, -MMD, -M, and -MM.
* jcf.h: Added declarations for dependency-tracking functions.
* lang-specs.h: Handle -M, -MM, MD, and -MMD.
* lang.c (lang_decode_option): Recognize -MD and -MMD.
(finish_parse): Call jcf_dependency_write.
(dependency_tracking): New global.
(DEPEND_SET_FILE): New define.
(DEPEND_ENABLE): New define.
(init_parse): Enable dependency tracking if required.
Include "flags.h".
* Makefile.in (JAVA_OBJS): Added jcf-depend.o.
(../jcf-dump$(exeext)): Depend on and link with jcf-depend.o.
(../gcjh$(exeext)): Likewise.
(jcf-depend.o): New target.
* Make-lang.in (JAVA_SRCS): Added jcf-depend.c.
(GCJH_SOURCES): Likewise.
* jcf-io.c (open_class): Call jcf_dependency_add_file. Added
dep_name argument.
(find_classfile): Added dep_name argument.
(find_class): Compute name of dependency.
(open_in_zip): Call jcf_dependency_add_file.
* gjavah.c (output_file): No longer global.
(usage): Don't mention "gjavah".
(help): Likewise.
(java_no_argument): Likewise.
(version): Likewise.
(main): Recognize and handle -M family of options.
(print_mangled_classname): Return is void.
(process_file): Handle case where output is suppressed.
(HANDLE_END_FIELD): Likewise.
(HANDLE_METHOD): Likewise.
* jcf-depend.c: New file.
Tue Oct 13 23:34:12 1998 Jeffrey A Law (law@cygnus.com)
* java-tree.def: Add missing newline at EOF.
......
......@@ -73,7 +73,8 @@ JAVA_SRCS = $(srcdir)/java/parse.y $(srcdir)/java/class.c \
$(srcdir)/java/lang.c $(srcdir)/java/typeck.c $(srcdir)/java/except.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-write.c $(srcdir)/java/buffer.c \
$(srcdir)/java/jcf-depend.c
jc1$(exeext): $(P) $(JAVA_SRCS) $(LIBDEPS) stamp-objlist
cd java; $(MAKE) $(FLAGS_TO_PASS) $(JAVA_FLAGS_TO_PASS) ../jc1$(exeext)
......@@ -118,7 +119,7 @@ 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/javaop.def $(srcdir)/java/jcf-depend.c
gcjh$(exeext): $(GCJH_SOURCES)
cd java && $(MAKE) $(FLAGS_TO_PASS) $(JAVA_FLAGS_TO_PASS) ../gcjh$(exeext)
......
......@@ -182,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 memmove.o
buffer.o memmove.o jcf-depend.o
JAVA_OBJS_LITE = parse-scan.o jv-scan.o
......@@ -200,15 +200,15 @@ compiler: ../jc1$(exeext) ../jv-scan$(exeext)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
$(JAVA_OBJS_LITE) $(LIBS)
../jcf-dump$(exeext): jcf-dump.o jcf-io.o zextract.o memmove.o
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ jcf-dump.o jcf-io.o zextract.o memmove.o
../jcf-dump$(exeext): jcf-dump.o jcf-io.o jcf-depend.o zextract.o memmove.o
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ jcf-dump.o jcf-io.o jcf-depend.o zextract.o memmove.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 zextract.o memmove.o
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gjavah.o jcf-io.o zextract.o memmove.o
../gcjh$(exeext): gjavah.o jcf-io.o jcf-depend.o zextract.o memmove.o
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gjavah.o jcf-io.o jcf-depend.o zextract.o memmove.o
Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure
cd ..; $(SHELL) config.status
......@@ -287,6 +287,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-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
......
......@@ -40,8 +40,6 @@ static int found_error = 0;
/* Directory to place resulting files in. Set by -d option. */
char *output_directory = "";
char *output_file = NULL;
/* Directory to place temporary file. Set by -td option. Currently unused. */
char *temp_directory = "/tmp";
......@@ -115,14 +113,14 @@ JCF_u2 current_field_flags;
static int field_pass;
#define HANDLE_END_FIELD() \
if (field_pass) print_field_info (out, jcf, current_field_name, \
current_field_signature, \
current_field_flags);
if (out && field_pass) print_field_info (out, jcf, current_field_name, \
current_field_signature, \
current_field_flags);
#define HANDLE_CONSTANTVALUE(VALUEINDEX) current_field_value = (VALUEINDEX)
#define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
print_method_info (out, jcf, NAME, SIGNATURE, ACCESS_FLAGS)
if (out) print_method_info (out, jcf, NAME, SIGNATURE, ACCESS_FLAGS)
#include "jcf-reader.c"
......@@ -175,7 +173,7 @@ print_base_classname (stream, jcf, index)
int index;
{
int name_index = JPOOL_USHORT1 (jcf, index);
int i, len;
int len;
unsigned char *s, *p, *limit;
s = JPOOL_UTF_DATA (jcf, name_index);
......@@ -629,7 +627,7 @@ DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, flags, is_init,
}
}
int
void
DEFUN(print_mangled_classname, (stream, jcf, prefix, index),
FILE *stream AND JCF *jcf AND char *prefix AND int index)
{
......@@ -652,7 +650,7 @@ print_cxx_classname (stream, prefix, jcf, index)
int index;
{
int name_index = JPOOL_USHORT1 (jcf, index);
int i, len, c;
int len, c;
unsigned char *s, *p, *limit;
s = JPOOL_UTF_DATA (jcf, name_index);
......@@ -760,17 +758,20 @@ DEFUN(process_file, (jcf, out),
jcf_parse_class (jcf);
if (written_class_count++ == 0)
if (written_class_count++ == 0 && out)
fputs ("// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-\n\n",
out);
print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
fprintf (out, "__\n");
if (out)
{
print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
fprintf (out, "__\n");
print_mangled_classname (out, jcf, "#define __", jcf->this_class);
fprintf (out, "__\n\n");
print_mangled_classname (out, jcf, "#define __", jcf->this_class);
fprintf (out, "__\n\n");
}
if (jcf->super_class)
if (jcf->super_class && out)
{
int super_length;
unsigned char *supername = super_class_name (jcf, &super_length);
......@@ -789,20 +790,23 @@ DEFUN(process_file, (jcf, out),
fputs ("\n", out);
}
print_class_decls (out, jcf);
if (out)
{
print_class_decls (out, jcf);
for (i = 0; i < prepend_count; ++i)
fprintf (out, "%s\n", prepend_specs[i]);
if (prepend_count > 0)
fputc ('\n', out);
for (i = 0; i < prepend_count; ++i)
fprintf (out, "%s\n", prepend_specs[i]);
if (prepend_count > 0)
fputc ('\n', out);
}
if (! print_cxx_classname (out, "class ", jcf, jcf->this_class))
if (out && ! print_cxx_classname (out, "class ", jcf, jcf->this_class))
{
fprintf (stderr, "class is of array type\n");
found_error = 1;
return;
}
if (jcf->super_class)
if (out && jcf->super_class)
{
if (! print_cxx_classname (out, " : public ", jcf, jcf->super_class))
{
......@@ -811,7 +815,8 @@ DEFUN(process_file, (jcf, out),
return;
}
}
fputs ("\n{\n", out);
if (out)
fputs ("\n{\n", out);
/* We make a single pass over the file, printing methods and fields
as we see them. We have to list the methods in the same order
......@@ -835,38 +840,41 @@ DEFUN(process_file, (jcf, out),
jcf_parse_final_attributes (jcf);
/* Generate friend decl if we still must. */
for (i = 0; i < friend_count; ++i)
fprintf (out, " friend %s\n", friend_specs[i]);
if (out)
{
/* Generate friend decl if we still must. */
for (i = 0; i < friend_count; ++i)
fprintf (out, " friend %s\n", friend_specs[i]);
/* Generate extra declarations. */
if (add_count > 0)
fputc ('\n', out);
for (i = 0; i < add_count; ++i)
fprintf (out, " %s\n", add_specs[i]);
/* Generate extra declarations. */
if (add_count > 0)
fputc ('\n', out);
for (i = 0; i < add_count; ++i)
fprintf (out, " %s\n", add_specs[i]);
fputs ("};\n", out);
fputs ("};\n", out);
if (append_count > 0)
fputc ('\n', out);
for (i = 0; i < append_count; ++i)
fprintf (out, "%s\n", append_specs[i]);
if (append_count > 0)
fputc ('\n', out);
for (i = 0; i < append_count; ++i)
fprintf (out, "%s\n", append_specs[i]);
print_mangled_classname (out, jcf, "\n#endif /* __", jcf->this_class);
fprintf (out, "__ */\n");
print_mangled_classname (out, jcf, "\n#endif /* __", jcf->this_class);
fprintf (out, "__ */\n");
}
}
static void
usage ()
{
fprintf (stderr, "gjavah: no classes specified\n");
fprintf (stderr, "gcjh: no classes specified\n");
exit (1);
}
static void
help ()
{
printf ("Usage: gjavah [OPTION]... CLASS...\n\n");
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 (" -d DIRECTORY Set output directory name\n");
......@@ -883,7 +891,7 @@ static void
java_no_argument (opt)
char *opt;
{
fprintf (stderr, "gjavah: no argument given for option `%s'\n", opt);
fprintf (stderr, "gcjh: no argument given for option `%s'\n", opt);
exit (1);
}
......@@ -891,7 +899,7 @@ static void
version ()
{
/* FIXME: use version.c? */
printf ("gjavah (GNU gcc) 0.0\n\n");
printf ("gcjh (GNU gcc) 0.0\n\n");
printf ("Copyright (C) 1998 Free Software Foundation, Inc.\n");
printf ("This is free software; see the source for copying conditions. There is NO\n");
printf ("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
......@@ -904,6 +912,8 @@ DEFUN(main, (argc, argv),
{
JCF jcf;
int argi;
char *output_file = NULL;
int emit_dependencies = 0, suppress_output = 0;
if (argc <= 1)
usage ();
......@@ -999,6 +1009,33 @@ DEFUN(main, (argc, argv),
help ();
else if (strcmp (arg, "-version") == 0)
version ();
else if (strcmp (arg, "-M") == 0)
{
emit_dependencies = 1;
suppress_output = 1;
jcf_dependency_init (1);
}
else if (strcmp (arg, "-MM") == 0)
{
emit_dependencies = 1;
suppress_output = 1;
jcf_dependency_init (0);
}
else if (strcmp (arg, "-MG") == 0)
{
fprintf (stderr, "gcjh: `%s' option is unimplemented\n", argv[argi]);
exit (1);
}
else if (strcmp (arg, "-MD") == 0)
{
emit_dependencies = 1;
jcf_dependency_init (1);
}
else if (strcmp (arg, "-MMD") == 0)
{
emit_dependencies = 1;
jcf_dependency_init (0);
}
else
{
fprintf (stderr, "%s: illegal argument\n", argv[argi]);
......@@ -1009,6 +1046,12 @@ DEFUN(main, (argc, argv),
if (argi == argc)
usage ();
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");
......@@ -1023,6 +1066,8 @@ DEFUN(main, (argc, argv),
if (verbose)
fprintf (stderr, "Processing %s\n", classname);
if (! output_file)
jcf_dependency_reset ();
classfile_name = find_class (classname, strlen (classname), &jcf, 1);
if (classfile_name == NULL)
{
......@@ -1036,7 +1081,9 @@ DEFUN(main, (argc, argv),
if (strcmp (output_file, "-") == 0)
out = stdout;
else if (out == NULL)
out = fopen (output_file, "w");
{
out = fopen (output_file, "w");
}
if (out == NULL)
{
perror (output_file);
......@@ -1059,18 +1106,38 @@ DEFUN(main, (argc, argv),
ch = '/';
current_output_file[dir_len++] = ch;
}
strcpy (current_output_file+dir_len, ".h");
out = fopen (current_output_file, "w");
if (out == NULL)
if (emit_dependencies)
{
perror (current_output_file);
exit (1);
if (suppress_output)
{
jcf_dependency_set_dep_file ("-");
out = NULL;
}
else
{
/* We use `.hd' and not `.d' to avoid clashes with
dependency tracking from straight compilation. */
strcpy (current_output_file + dir_len, ".hd");
jcf_dependency_set_dep_file (current_output_file);
}
}
strcpy (current_output_file + dir_len, ".h");
jcf_dependency_set_target (current_output_file);
if (! suppress_output)
{
out = fopen (current_output_file, "w");
if (out == NULL)
{
perror (current_output_file);
exit (1);
}
}
}
process_file (&jcf, out);
JCF_FINISH (&jcf);
if (current_output_file != output_file)
free (current_output_file);
jcf_dependency_write ();
}
if (out != NULL && out != stdout)
......
/* Functions for handling dependency tracking when reading .class files.
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 <tromey@cygnus.com>, October 1998. */
#include <config.h>
#include "system.h"
#include <assert.h>
/* We keep a linked list of all the files we've already read. */
struct entry
{
char *file;
struct entry *next;
};
/* List of files. */
static struct entry *dependencies = NULL;
/* Name of targets. We support multiple targets when writing .class
files. */
static struct entry *targets = NULL;
/* Number of columns in output. */
#define MAX_OUTPUT_COLUMNS 72
/* The output file, or NULL if we aren't doing dependency tracking. */
static FILE *dep_out = NULL;
/* Nonzero if system files should be added. */
static int system_files;
/* Helper to free an entry list. */
static void
free_entry (entp)
struct entry **entp;
{
struct entry *ent, *next;
for (ent = *entp; ent != NULL; ent = next)
{
next = ent->next;
free (ent->file);
free (ent);
}
*entp = NULL;
}
/* Helper to add to entry list. */
static void
add_entry (entp, name)
struct entry **entp;
char *name;
{
struct entry *ent;
for (ent = *entp; ent != NULL; ent = ent->next)
if (! strcmp (ent->file, name))
return;
ent = (struct entry *) malloc (sizeof (struct entry));
ent->file = strdup (name);
ent->next = *entp;
*entp = ent;
}
/* Call this to reset the dependency module. This is required if
multiple dependency files are being generated from a single tool
invocation. */
void
jcf_dependency_reset ()
{
struct entry *ent, *next;
free_entry (&dependencies);
free_entry (&targets);
if (dep_out != NULL)
{
if (dep_out != stdout)
fclose (dep_out);
dep_out = NULL;
}
}
void
jcf_dependency_set_target (name)
char *name;
{
free_entry (&targets);
if (name != NULL)
add_entry (&targets, name);
}
void
jcf_dependency_add_target (name)
char *name;
{
add_entry (&targets, name);
}
void
jcf_dependency_set_dep_file (name)
const char *name;
{
assert (dep_out != stdout);
if (dep_out)
fclose (dep_out);
if (! strcmp (name, "-"))
dep_out = stdout;
else
dep_out = fopen (name, "w");
}
void
jcf_dependency_add_file (filename, system_p)
char *filename;
int system_p;
{
struct entry *ent;
/* Just omit system files. */
if (system_p && ! system_files)
return;
add_entry (&dependencies, filename);
}
void
jcf_dependency_init (system_p)
int system_p;
{
system_files = system_p;
}
/* FIXME: this is taken almost directly from cccp.c. Such duplication
is bad. */
static char *
munge (filename)
char *filename;
{
static char *buffer = NULL;
static int buflen = 0;
int len = 2 * strlen (filename) + 1;
char *p, *dst;
if (buflen < len)
{
buflen = len;
if (buffer == NULL)
buffer = malloc (buflen);
else
buffer = realloc (buffer, buflen);
}
dst = buffer;
for (p = filename; *p; ++p)
{
switch (*p)
{
case ' ':
case '\t':
{
/* GNU make uses a weird quoting scheme for white space.
A space or tab preceded by 2N+1 backslashes represents
N backslashes followed by space; a space or tab
preceded by 2N backslashes represents N backslashes at
the end of a file name; and backslashes in other
contexts should not be doubled. */
char *q;
for (q = p - 1; filename < q && q[-1] == '\\'; q--)
*dst++ = '\\';
}
*dst++ = '\\';
goto ordinary_char;
case '$':
*dst++ = '$';
/* Fall through. This can mishandle things like "$(" but
there's no easy fix. */
default:
ordinary_char:
/* This can mishandle characters in the string "\0\n%*?[\\~";
exactly which chars are mishandled depends on the `make' version.
We know of no portable solution for this;
even GNU make 3.76.1 doesn't solve the problem entirely.
(Also, '\0' is mishandled due to our calling conventions.) */
*dst++ = *p;
break;
}
}
*dst++ = '\0';
return buffer;
}
/* Helper to print list of files. */
static int
print_ents (ent, column)
struct entry *ent;
int column;
{
int first = 1;
for (; ent != NULL; ent = ent->next)
{
char *depname = munge (ent->file);
int len = strlen (depname);
if (column + len + 2 > MAX_OUTPUT_COLUMNS)
{
fprintf (dep_out, " \\\n ");
column = 1;
}
if (! first)
fputs (" ", dep_out);
fputs (depname, dep_out);
first = 0;
column += len + 1;
}
return column;
}
void
jcf_dependency_write ()
{
int column = 0;
struct entry *ent;
if (! dep_out)
return;
assert (targets);
column = print_ents (targets, 0);
fputs (" : ", dep_out);
print_ents (dependencies, column);
fputs ("\n", dep_out);
fflush (dep_out);
}
......@@ -793,9 +793,9 @@ DEFUN(main, (argc, argv),
{
fprintf (out, "Reading .class from <standard input>.\n");
#if JCF_USE_STDIO
open_class ("<stdio>", jcf, stdin);
open_class ("<stdio>", jcf, stdin, NULL);
#else
open_class ("<stdio>", jcf, 0);
open_class ("<stdio>", jcf, 0, NULL);
#endif
process_class (jcf);
}
......@@ -806,7 +806,7 @@ DEFUN(main, (argc, argv),
char *arg = argv[argi];
char* class_filename = find_class (arg, strlen (arg), jcf, 1);
if (class_filename == NULL)
class_filename = find_classfile (arg, jcf);
class_filename = find_classfile (arg, jcf, NULL);
if (class_filename == NULL)
{
perror ("Could not find class");
......
/* Utility routines for finding and reading Java(TM) .class files.
Copyright (C) 1996 Free Software Foundation, Inc.
Copyright (C) 1996, 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
......@@ -108,6 +108,7 @@ zipfile, zipmember),
{
char magic [4];
int fd = open (zipfile, O_RDONLY | O_BINARY);
jcf_dependency_add_file (zipfile, 0); /* FIXME: system file? */
if (read (fd, magic, 4) != 4 || GET_u4 (magic) != (JCF_u4)ZIPMAGIC)
return -1;
lseek (fd, 0L, SEEK_SET);
......@@ -168,11 +169,13 @@ zipfile, zipmember),
#if JCF_USE_STDIO
char*
DEFUN(open_class, (filename, jcf, stream),
char *filename AND JCF *jcf AND FILE* stream)
DEFUN(open_class, (filename, jcf, stream, dep_name),
char *filename AND JCF *jcf AND FILE* stream AND char *dep_name)
{
if (jcf)
{
if (dep_name != NULL)
jcf_dependency_add_file (dep_name, 0);
JCF_ZERO (jcf);
jcf->buffer = NULL;
jcf->buffer_end = NULL;
......@@ -187,8 +190,8 @@ DEFUN(open_class, (filename, jcf, stream),
}
#else
char*
DEFUN(open_class, (filename, jcf, fd),
char *filename AND JCF *jcf AND int fd)
DEFUN(open_class, (filename, jcf, fd, dep_name),
char *filename AND JCF *jcf AND int fd AND char *dep_name)
{
if (jcf)
{
......@@ -199,6 +202,8 @@ DEFUN(open_class, (filename, jcf, fd),
perror ("Could not figure length of .class file");
return NULL;
}
if (dep_name != NULL)
jcf_dependency_add_file (dep_name, 0);
JCF_ZERO (jcf);
jcf->buffer = ALLOC (stat_buf.st_size);
jcf->buffer_end = jcf->buffer + stat_buf.st_size;
......@@ -222,19 +227,19 @@ DEFUN(open_class, (filename, jcf, fd),
char *
DEFUN(find_classfile, (filename, jcf),
char *filename AND JCF *jcf)
DEFUN(find_classfile, (filename, jcf, dep_name),
char *filename AND JCF *jcf AND char *dep_name)
{
#if JCF_USE_STDIO
FILE *stream = fopen (filename, "rb");
if (stream == NULL)
return NULL;
return open_class (arg, jcf, stream);
return open_class (arg, jcf, stream, dep_name);
#else
int fd = open (filename, O_RDONLY | O_BINARY);
if (fd < 0)
return NULL;
return open_class (filename, jcf, fd);
return open_class (filename, jcf, fd, dep_name);
#endif
}
......@@ -257,6 +262,12 @@ DEFUN(find_class, (classname, classname_length, jcf, do_class_file),
#endif
int i, j, 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;
/* Allocate and zero out the buffer, since we don't explicitly put a
null pointer when we're copying it below. */
......@@ -264,6 +275,15 @@ DEFUN(find_class, (classname, classname_length, jcf, do_class_file),
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);
}
jcf->java_source = jcf->outofsynch = 0;
for (j = 0; classpath[j] != '\0'; )
{
......@@ -331,13 +351,20 @@ DEFUN(find_class, (classname, classname_length, jcf, do_class_file),
goto found;
}
}
/* 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)
{
......@@ -391,7 +418,7 @@ DEFUN(find_class, (classname, classname_length, jcf, do_class_file),
if (jcf->java_source)
return NULL; /* FIXME */
else
return open_class (buffer, jcf, stream);
return open_class (buffer, jcf, stream, dep_file);
#else
if (jcf->java_source)
{
......@@ -401,7 +428,7 @@ DEFUN(find_class, (classname, classname_length, jcf, do_class_file),
close (fd); /* We use STDIO for source file */
}
else if (do_class_file)
buffer = open_class (buffer, jcf, fd);
buffer = open_class (buffer, jcf, fd, dep_file);
jcf->classname = (char *) ALLOC (classname_length + 1);
strncpy (jcf->classname, classname, classname_length + 1);
jcf->classname = (char *) strdup (classname);
......
......@@ -1870,6 +1870,7 @@ write_classfile (clas)
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);
......
/* Utility macros to read Java(TM) .class files and byte codes.
Copyright (C) 1996 Free Software Foundation, Inc.
Copyright (C) 1996, 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
......@@ -226,7 +226,7 @@ extern char *classpath;
#define DEFAULT_CLASS_PATH "."
extern char *find_class PROTO ((const char *, int, JCF*, int));
extern char *find_classfile PROTO ((char *, JCF*));
extern char *find_classfile PROTO ((char *, JCF*, char *));
extern int jcf_filbuf_from_stdio PROTO ((JCF *jcf, int count));
extern void jcf_out_of_synch PROTO((JCF *));
extern int jcf_unexpected_eof PROTO ((JCF*, int));
......@@ -257,4 +257,13 @@ extern int quiet_flag;
#define SOURCE_FRONTEND_DEBUG(X)
#endif
/* Declarations for dependency code. */
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_add_file PROTO ((const char *, int));
extern void jcf_dependency_write PROTO ((void));
extern void jcf_dependency_init PROTO ((int));
#endif
......@@ -36,3 +36,7 @@ DEFINE_LANG_NAME ("Java")
{ "-fno-assume-compiled", "" },
{ "-femit-class-file", "" },
{ "-femit-class-files", "Dump class files to <name>.class" },
{ "-MD", "Print dependencies to FILE.d" },
{ "-MMD", "Print dependencies to FILE.d" },
{ "-M", "Print dependencies to stdout" },
{ "-MM", "Print dependencies to stdout" },
/* Definitions for specs for the GNU compiler for the Java(TM) language.
Copyright (C) 1996 Free Software Foundation, Inc.
Copyright (C) 1996, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
......@@ -27,12 +27,13 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
{".java", "@java" },
{".class", "@java" },
{"@java",
"%{!M:%{!MM:%{!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*}\
%{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 }}}}"},
"%{!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}\
%{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 }}"},
......@@ -31,6 +31,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "java-tree.h"
#include "jcf.h"
#include "toplev.h"
#include "flags.h"
/* Table indexed by tree code giving a string containing a character
classifying the tree code. Possibilities are
......@@ -104,6 +105,14 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
JCF main_jcf[1];
JCF *current_jcf;
/* Variable controlling how dependency tracking is enabled in
init_parse. */
static int dependency_tracking = 0;
/* Flag values for DEPENDENCY_TRACKING. */
#define DEPEND_SET_FILE 1
#define DEPEND_ENABLE 2
/*
* process java-specific compiler command-line options
*/
......@@ -140,9 +149,35 @@ lang_decode_option (argc, argv)
found = 1;
}
}
return found;
}
if (strcmp (p, "-MD") == 0)
{
jcf_dependency_init (1);
dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
return 1;
}
else if (strcmp (p, "-MMD") == 0)
{
jcf_dependency_init (0);
dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
return 1;
}
else if (strcmp (p, "-M") == 0)
{
jcf_dependency_init (1);
dependency_tracking |= DEPEND_ENABLE;
return 1;
}
else if (strcmp (p, "-MM") == 0)
{
jcf_dependency_init (0);
dependency_tracking |= DEPEND_ENABLE;
return 1;
}
return 0;
}
......@@ -157,9 +192,49 @@ init_parse (filename)
{
finput = stdin;
filename = "stdin";
if (dependency_tracking)
error ("can't do dependency tracking with input from stdin");
}
else
finput = fopen (filename, "r");
{
if (dependency_tracking)
{
char *dot;
dot = strrchr (filename, '.');
if (dot == NULL)
error ("couldn't determine target name for dependency tracking");
else
{
char *buf = (char *) xmalloc (dot - filename + 3);
strncpy (buf, filename, dot - filename);
/* If emitting class files, we might have multiple
targets. The class generation code takes care of
registering them. Otherwise we compute the target
name here. */
if (flag_emit_class_files)
jcf_dependency_set_target (NULL);
else
{
strcpy (buf + (dot - filename), ".o");
jcf_dependency_set_target (buf);
}
if ((dependency_tracking & DEPEND_SET_FILE))
{
strcpy (buf + (dot - filename), ".d");
jcf_dependency_set_dep_file (buf);
}
else
jcf_dependency_set_dep_file ("-");
free (buf);
}
}
finput = fopen (filename, "r");
}
if (finput == 0)
pfatal_with_name (filename);
......@@ -175,6 +250,7 @@ void
finish_parse ()
{
fclose (finput);
jcf_dependency_write ();
}
/* Buffer used by lang_printable_name. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment