diff options
Diffstat (limited to 'gcc/java/jcf-depend.c')
-rw-r--r-- | gcc/java/jcf-depend.c | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/gcc/java/jcf-depend.c b/gcc/java/jcf-depend.c new file mode 100644 index 0000000..c923a9c --- /dev/null +++ b/gcc/java/jcf-depend.c @@ -0,0 +1,268 @@ +/* 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); +} |