summaryrefslogtreecommitdiff
path: root/soltools/javadep
diff options
context:
space:
mode:
authorNils Fuhrmann <nf@openoffice.org>2001-04-18 08:52:08 +0000
committerNils Fuhrmann <nf@openoffice.org>2001-04-18 08:52:08 +0000
commit9a1f016b0bae0d2f70184115a617e3790c48d0ef (patch)
tree30853242e9650a20347a027196f325cdeab8cc58 /soltools/javadep
parentb8288b60ef4ed490f28aa6110bc9df5548438b83 (diff)
Moved to soltools
Diffstat (limited to 'soltools/javadep')
-rw-r--r--soltools/javadep/javadep.c930
-rw-r--r--soltools/javadep/makefile.mk89
2 files changed, 1019 insertions, 0 deletions
diff --git a/soltools/javadep/javadep.c b/soltools/javadep/javadep.c
new file mode 100644
index 000000000000..30fc267fa4f3
--- /dev/null
+++ b/soltools/javadep/javadep.c
@@ -0,0 +1,930 @@
+/*************************************************************************
+ *
+ * $RCSfile: javadep.c,v $
+ *
+ * $Revision: 1.1 $
+ *
+ * last change: $Author: nf $ $Date: 2001-04-18 09:50:15 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+/* All Java Virtual Machine Specs are from
+ * "The Java Virtual Machine Specification", T. Lindholm, F. Yellin
+ * (JVMS)
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+
+#if defined(UNX)
+#include <unistd.h>
+#include <netinet/in.h> /* ntohl(), ntohs() */
+#elif defined(WNT)
+#include <io.h>
+#define access _access
+#define vsnprintf _vsnprintf
+#define CDECL _cdecl
+#define F_OK 00
+#define PATH_MAX _MAX_PATH
+#define ntohl(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
+ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+
+#define ntohs(x) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+#endif
+
+#ifdef BOOTSTRAPPER
+#include <glibc/posix/getopt.h>
+#else
+#include <glibc/getopt.h>
+#endif
+
+/* max. length of line in response file */
+#define RES_FILE_BUF 65536
+
+struct file {
+ char *pname;
+ FILE *pfs;
+};
+
+struct growable {
+ int ncur;
+ int nmax;
+ char **parray;
+};
+
+typedef struct file file_t;
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+
+struct utf8 {
+ uint16 nlen;
+ void *pdata;
+};
+
+typedef struct utf8 utf8_t;
+
+/* The contents of the Constant_pool is described in JVMS p. 93
+ */
+enum {
+ CONSTANT_Class = 7,
+ CONSTANT_Fieldref = 9,
+ CONSTANT_Methodref = 10,
+ CONSTANT_InterfaceMethodref = 11,
+ CONSTANT_String = 8,
+ CONSTANT_Integer = 3,
+ CONSTANT_Float = 4,
+ CONSTANT_Long = 5,
+ CONSTANT_Double = 6,
+ CONSTANT_NameAndType = 12,
+ CONSTANT_Utf8 = 1
+};
+
+enum { NGROW_INIT = 1, NGROW = 2 };
+
+static char *pprogname = "javadep";
+static char csep = ';';
+#if defined (UNX)
+#define CDECL
+static char cpathsep = '/';
+#elif defined (WNT)
+static char cpathsep = '\\';
+#endif
+static int bnl = 0;
+static FILE *pfsout = NULL;
+static char *pout_file = NULL;
+
+
+/* prototypes */
+uint8 read_uint8(const file_t *pfile);
+uint16 read_uint16(const file_t *pfile);
+uint32 read_uint32(const file_t *pfile);
+void skip_bytes(const file_t *pfile, const size_t nnum);
+char *escape_slash(const char *pstr);
+char *get_stripped_class(const char *pclass);
+int is_inner(const char *pstr);
+void print_dependencies(const struct growable *pdep,
+ const char* pclass_file);
+void process_class_file(const char *pfilenamem,
+ const struct growable *pfilt);
+char *utf8tolatin1(const utf8_t a_utf8);
+void *xmalloc(size_t size);
+void *xcalloc(size_t nmemb, size_t size);
+void *xrealloc(void *ptr, size_t size);
+void grow_if_needed (struct growable *pgrow);
+int append_to_growable(struct growable *, char *);
+struct growable *allocate_growable(void);
+void free_growable(struct growable *pgrowvoid);
+void create_filters(struct growable *pfilt, const struct growable *pinc);
+void usage(void);
+void err_quit(const char *, ...);
+void silent_quit(void);
+
+uint8
+read_uint8(const file_t *pfile)
+{
+ /* read a byte from classfile */
+ int nread;
+ uint8 ndata;
+ nread = fread(&ndata, sizeof(uint8), 1, pfile->pfs);
+ if ( !nread ) {
+ fclose(pfile->pfs);
+ err_quit("%s: truncated class file", pfile->pname);
+ }
+ return ndata;
+}
+
+uint16
+read_uint16(const file_t *pfile)
+{
+ /* read a short from classfile and convert it to host format */
+ int nread;
+ uint16 ndata;
+ nread = fread(&ndata, sizeof(uint16), 1, pfile->pfs);
+ if ( !nread ) {
+ fclose(pfile->pfs);
+ err_quit("%s: truncated class file", pfile->pname);
+ }
+ ndata = ntohs(ndata);
+ return ndata;
+}
+
+uint32
+read_uint32(const file_t *pfile)
+{
+ /* read an int from classfile and convert it to host format */
+ int nread;
+ uint32 ndata;
+ nread = fread(&ndata, sizeof(uint32), 1, pfile->pfs);
+ if ( !nread ) {
+ fclose(pfile->pfs);
+ err_quit("%s: truncated class file", pfile->pname);
+ }
+ ndata = ntohl(ndata);
+ return ndata;
+}
+
+utf8_t
+read_utf8(const file_t *pfile)
+{
+ /* Read a java utf-8-string with uint16 length prependend
+ * from class file. Returns utf8 struct
+ * with fresh allocated datablock,
+ * caller is responsible for freeing.
+ * Data is still in network byteorder
+ */
+
+ utf8_t a_utf8;
+ int nread;
+
+ a_utf8.pdata = NULL;
+
+ a_utf8.nlen = read_uint16(pfile);
+ if (a_utf8.nlen > 0) {
+ a_utf8.pdata = xmalloc(a_utf8.nlen*sizeof(char));
+ nread = fread(a_utf8.pdata, a_utf8.nlen*sizeof(char), 1, pfile->pfs);
+ if ( !nread ) {
+ fclose(pfile->pfs);
+ err_quit("%s: truncated class file", pfile->pname);
+ }
+ }
+
+ return a_utf8;
+}
+
+char *utf8tolatin1(const utf8_t a_utf8)
+{
+ /* function returns fresh allocated zero terminated string,
+ * caller is responsible for freeing
+ */
+
+ /* JVMS p. 101: the null byte is encoded using a two byte format,
+ * Java Virtual Machine Utf8 strings differ in this respect from
+ * standard UTF-8 strings
+ */
+
+ /* Multibyte data is in network byte order */
+
+ char *p;
+ char *pp;
+ char *pstr;
+
+ pstr = pp = xmalloc((a_utf8.nlen+1) * sizeof(char));
+
+ for ( p = (char*)a_utf8.pdata;
+ p < (char*)a_utf8.pdata+a_utf8.nlen;
+ p++ ) {
+ if ( *p & 0x80 ) {
+ err_quit("sorry, real UTF8 decoding not yet implemented\n");
+ } else {
+ *pp++ = *p;
+ }
+ }
+ *pp = '\0';
+
+ return pstr;
+}
+
+
+void
+skip_bytes(const file_t *pfile, const size_t nnumber)
+{
+ /* skip a nnumber of bytes in classfile */
+ if ( fseek(pfile->pfs, nnumber, SEEK_CUR) == -1 )
+ err_quit("%s: %s", pfile->pname, strerror(errno));
+}
+
+void
+add_to_dependencies(struct growable *pdep,
+ const struct growable *pfilt,
+ char *pdepstr,
+ const char *pclass_file)
+{
+ /* create dependencies */
+ int i;
+ int nlen_filt, nlen_str;
+ char *pstr, *ptrunc;
+ char path[PATH_MAX+1];
+ char cnp_class_file[PATH_MAX+1];
+ char cnp_str[PATH_MAX+1];
+
+ pstr = xmalloc((strlen(pdepstr)+6+1)*sizeof(char));
+ strcpy(pstr, pdepstr);
+ strcat(pstr, ".class");
+
+ if ( pfilt->ncur == 0 ) { /* no filters */
+ if ( access(pstr, F_OK) == 0 ) {
+ append_to_growable(pdep, strdup(pstr));
+ }
+ } else {
+ nlen_str = strlen(pstr);
+ for ( i = 0; i < pfilt->ncur; i++ ) {
+ nlen_filt = strlen(pfilt->parray[i]);
+ if ( nlen_filt + 1 + nlen_str > PATH_MAX )
+ err_quit("path to long");
+ memcpy(path, pfilt->parray[i], nlen_filt);
+ path[nlen_filt] = '/';
+ memcpy( path+nlen_filt+1, pstr, nlen_str+1);
+
+ if ( access(path, F_OK) != 0 )
+ return; /* path doesn't represent a real file, don't bother */
+
+ /* get the canonical path */
+#if defined (UNX)
+ if ( !(realpath(pclass_file, cnp_class_file)
+ && realpath(path, cnp_str) ) ) {
+ err_quit("can't get the canonical path");
+ }
+#else
+ if ( !(_fullpath(cnp_class_file, pclass_file, sizeof(cnp_class_file))
+ && _fullpath(cnp_str, path, sizeof(cnp_str)) ) ) {
+ err_quit("can't get the canonical path");
+ }
+#endif
+
+ /* truncate so that only the package prefix remains */
+ ptrunc = strrchr(cnp_str, cpathsep);
+ *ptrunc = '\0';
+ ptrunc = strrchr(cnp_class_file, cpathsep);
+ *ptrunc = '\0';
+
+ if ( !strcmp(cnp_str, cnp_class_file) )
+ return; /* identical, don't bother with this one */
+
+ append_to_growable(pdep, strdup(path));
+ }
+ }
+ free(pstr);
+ return;
+}
+
+char *get_stripped_class(const char *pclass)
+{
+ /* returns fresh allocated string with the simple unadorned
+ * class name from a full qualified class name.
+ *
+ * caller is resposible for freeing
+ */
+ char *pstr, *ptmpstr;
+
+ pstr = ptmpstr = strdup(pclass);
+
+ /* '\\' might be possible on WIN32 plattforms */
+ while ( (ptmpstr = strchr(ptmpstr, '\\')) != NULL )
+ *ptmpstr = '/';
+
+ /* remove any trailing .class */
+ ptmpstr = strchr(pstr, '.');
+ if ( ptmpstr )
+ *ptmpstr = '\0';
+
+ /* remove leading package descriptors */
+ ptmpstr = strrchr(pstr, '/');
+ if ( !ptmpstr ) {
+ return pstr;
+ }
+ else {
+ ptmpstr = strdup(ptmpstr);
+ free(pstr);
+ return ptmpstr;
+ }
+}
+
+char *
+escape_slash(const char *pstr)
+{
+ /* returns a fresh allocated string with all cpathsep escaped exchanged
+ * with "$/"
+ *
+ * caller is responsible for freeing
+ */
+
+ const char *pp = pstr;
+ char *p, *pnp;
+ char *pnew_str;
+ int i = 0;
+
+ while ( (p=strchr(pp, cpathsep)) != NULL ) {
+ ++i;
+ pp = ++p;
+ }
+ pnp = pnew_str = xmalloc((strlen(pstr) + i + 1) * sizeof(char));
+
+ pp = pstr;
+
+ if ( i > 0 ) {
+ while ( (p=strchr(pp, cpathsep)) != NULL ) {
+ strncpy(pnp, pp, p-pp);
+ pnp += p-pp;
+ *pnp++ = '$';
+ *pnp++ = '/';
+ pp = ++p;
+ }
+ }
+ strcpy(pnp, pp);
+
+ return pnew_str;
+}
+
+
+void
+print_dependencies(const struct growable *pdep, const char* pclass_file)
+{
+ char *pstr;
+ int i;
+
+ pstr = escape_slash(pclass_file);
+ fprintf(pfsout, "%s:", pstr);
+ free(pstr);
+
+ for( i=0; i<pdep->ncur; ++i) {
+ fprintf(pfsout, " \\\n");
+ pstr=escape_slash(pdep->parray[i]);
+ fprintf(pfsout, "\t%s", pstr);
+ free(pstr);
+ }
+
+ fprintf(pfsout,"\n\n");
+ return;
+}
+
+int
+is_inner(const char *pstr)
+{
+ /* return true if character '$' is found in classname */
+
+ /*
+ * note that a '$' in a classname is not an exact indicator
+ * for an inner class. Java identifier may legally contain
+ * this chararcter, and so may classnames. In the context
+ * of javadep this doesn't matter since the makefile system
+ * can't cope with classfiles with '$'s in the filename
+ * anyway.
+ *
+ */
+
+ if ( strchr(pstr, '$') != NULL )
+ return 1;
+
+ return 0;
+}
+
+void
+process_class_file(const char *pfilename, const struct growable *pfilt)
+{
+ /* read class file and extract object information
+ * java class files are in bigendian data format
+ * (JVMS, p. 83)
+ */
+ int i;
+ uint32 nmagic;
+ uint16 nminor, nmajor;
+ uint16 ncnt;
+ uint16 nclass_cnt;
+ utf8_t* pc_pool;
+ uint16* pc_class;
+ file_t file;
+
+ struct growable *pdepen;
+
+ file.pname = (char*)pfilename;
+
+ if ( !(file.pfs = fopen(file.pname,"rb")) )
+ silent_quit();
+
+ nmagic = read_uint32(&file);
+
+ if ( nmagic != 0xCAFEBABE ) {
+ fclose(file.pfs);
+ err_quit("%s: invalid magic", file.pname);
+ }
+
+ nminor = read_uint16(&file);
+ nmajor = read_uint16(&file);
+
+ /* get number of entries in constant pool */
+ ncnt = read_uint16(&file);
+
+#ifdef DEBUG
+ printf("Magic: %p\n", (void*)nmagic);
+ printf("Major %d, Minor %d\n", nmajor, nminor);
+ printf("Const_pool_count %d\n", ncnt);
+#endif
+
+ /* There can be ncount entries in the constant_pool table
+ * so at most ncount-1 of them can be of type CONSTANT_Class
+ * (at leat one CONSTANT_Utf8 entry must exist).
+ * Usually way less CONSTANT_Class entries exists, of course
+ */
+
+ pc_pool = xcalloc(ncnt,sizeof(utf8_t));
+ pc_class = xmalloc((ncnt-1)*sizeof(uint16));
+
+ /* pc_pool[0] is reserved to the java virtual machine and does
+ * not exist in the class file
+ */
+
+ nclass_cnt = 0;
+
+ for (i = 1; i < ncnt; i++) {
+ uint8 ntag;
+ uint16 nindex;
+ utf8_t a_utf8;
+
+ ntag = read_uint8(&file);
+
+ /* we are only interested in CONSTANT_Class entries and
+ * Utf8 string entries, because they might belong to
+ * CONSTANT_Class entries
+ */
+ switch(ntag) {
+ case CONSTANT_Class:
+ nindex = read_uint16(&file);
+ pc_class[nclass_cnt++] = nindex;
+ break;
+ case CONSTANT_Fieldref:
+ case CONSTANT_Methodref:
+ case CONSTANT_InterfaceMethodref:
+ skip_bytes(&file, 4L);
+ break;
+ case CONSTANT_String:
+ skip_bytes(&file, 2L);
+ break;
+ case CONSTANT_Integer:
+ case CONSTANT_Float:
+ skip_bytes(&file, 4L);
+ break;
+ case CONSTANT_Long:
+ case CONSTANT_Double:
+ skip_bytes(&file, 8L);
+ /* Long and Doubles take 2(!)
+ * entries in constant_pool_table
+ */
+ i++;
+ break;
+ case CONSTANT_NameAndType:
+ skip_bytes(&file, 4L);
+ break;
+ case CONSTANT_Utf8:
+ a_utf8 = read_utf8(&file);
+ pc_pool[i] = a_utf8;
+ break;
+ default:
+ /* Unknown Constant_pool entry, this means we are
+ * in trouble
+ */
+ err_quit("corrupted class file\n");
+ break;
+
+ }
+ }
+
+ fclose(file.pfs);
+
+ pdepen = allocate_growable();
+
+ for (i = 0; i < nclass_cnt; i++) {
+ char *pstr, *ptmpstr;
+ pstr = ptmpstr = utf8tolatin1(pc_pool[pc_class[i]]);
+ /* we are not interested in inner classes */
+ if ( is_inner(pstr) ) {
+ free(pstr);
+ pstr = NULL;
+ }
+ /* strip off evt. array indicators */
+ if ( *ptmpstr == '[' ) {
+ while ( *ptmpstr == '[' )
+ ptmpstr++;
+ /* we only interested in obj. arrays, which are marked with 'L' */
+ if ( *ptmpstr == 'L' ) {
+ char *p = pstr;
+ pstr = strdup(++ptmpstr);
+ /* remove final ';' from object array name */
+ pstr[strlen(pstr)-1] = '\0';
+ free(p);
+ } else {
+ free(pstr);
+ pstr = NULL;
+ }
+ }
+
+ if (pstr) {
+ add_to_dependencies(pdepen, pfilt, pstr, file.pname);
+ free(pstr);
+ }
+ }
+
+ print_dependencies(pdepen, file.pname);
+ free_growable(pdepen);
+ pdepen = NULL;
+
+ for (i = 0; i < ncnt; i++)
+ free(pc_pool[i].pdata);
+
+ free(pc_class);
+ free(pc_pool);
+}
+
+void *
+xmalloc(size_t size)
+{
+ void *ptr;
+
+ ptr = malloc(size);
+
+ if ( !ptr )
+ err_quit("out of memory");
+
+ return ptr;
+}
+
+
+void *
+xcalloc(size_t nmemb, size_t size)
+{
+ void *ptr;
+
+ ptr = calloc(nmemb, size);
+
+ if ( !ptr )
+ err_quit("out of memory");
+
+ return ptr;
+}
+
+void *
+xrealloc(void *ptr, size_t size)
+{
+ ptr = realloc(ptr, size);
+
+ if ( !ptr )
+ err_quit("out of memory");
+
+ return ptr;
+}
+
+void
+err_quit(const char* fmt, ...)
+{
+ /* No dependency file must be generated for any error condition,
+ * just print message and exit.
+ */
+ va_list args;
+ char buffer[PATH_MAX];
+
+ if ( bnl )
+ printf("\n");
+
+ va_start(args, fmt);
+
+ if ( pprogname )
+ fprintf(stderr, "%s: ", pprogname);
+ vsnprintf(buffer, sizeof(buffer), fmt, args);
+ fputs(buffer, stderr);
+ fputc('\n', stderr);
+
+ va_end(args);
+
+ /* clean up */
+ if ( pfsout && pfsout != stdout ) {
+ fclose(pfsout);
+ unlink(pout_file);
+ }
+ exit(1);
+}
+
+void
+silent_quit()
+{
+ /* In some cases we should just do a silent exit */
+
+ /* clean up */
+ if ( pfsout && pfsout != stdout ) {
+ fclose(pfsout);
+ unlink(pout_file);
+ }
+ if ( bnl )
+ printf("\n");
+ exit(0);
+}
+
+int append_to_growable(struct growable *pgrow, char *pstr)
+{
+ /* append an element pstr to pgrow,
+ * return new number of elements
+ */
+ grow_if_needed(pgrow);
+ pgrow->parray[pgrow->ncur++] = pstr;
+ return pgrow->ncur;
+}
+
+void
+grow_if_needed(struct growable *pgrow)
+{
+ /* grow growable arrays */
+
+ if ( pgrow->ncur >= pgrow->nmax ) {
+ pgrow->parray = xrealloc(pgrow->parray,
+ (NGROW*pgrow->nmax)*sizeof(char*));
+ pgrow->nmax *= NGROW;
+ }
+ return;
+}
+
+struct growable *allocate_growable(void)
+{
+ /* allocate an growable array,
+ * initialize with NGROW_INIT elements
+ */
+
+ struct growable *pgrow;
+
+ pgrow = xmalloc(sizeof(struct growable));
+ pgrow->parray = xmalloc(NGROW_INIT*sizeof(char *));
+ pgrow->nmax = NGROW_INIT;
+ pgrow->ncur = 0;
+ return pgrow;
+}
+
+void
+free_growable(struct growable *pgrow)
+{
+ int i;
+ for( i = 0; i < pgrow->ncur; i++ )
+ free(pgrow->parray[i]);
+ free(pgrow->parray);
+ free(pgrow);
+}
+
+void
+create_filters(struct growable *pfilt, const struct growable *pinc)
+{
+ char *p, *pp, *pstr;
+ int i, nlen;
+ /* break up includes into filter list */
+ for ( i = 0; i < pinc->ncur; i++ ) {
+ pp = pinc->parray[i];
+
+ while ( (p = strchr(pp, csep)) != NULL) {
+ nlen = p - pp;
+ pstr = xmalloc((nlen+1)*sizeof(char*));
+ strncpy(pstr, pp, nlen);
+ pstr[nlen] = '\0';
+ append_to_growable(pfilt, pstr);
+ pp = p + 1;
+ }
+ pstr = xmalloc((strlen(pp)+1)*sizeof(char*));
+ strcpy(pstr, pp);
+ append_to_growable(pfilt, pstr);
+ }
+
+}
+
+void
+usage()
+{
+ fprintf(stderr,
+ "usage: %s [-i|-I includepath ... -s|-S seperator "
+ "-o|-O outpath -v|-V -h|-H] <file> ....\n",
+ pprogname);
+}
+
+int CDECL
+main(int argc, char *argv[])
+{
+ int bv_flag = 0;
+ struct growable *presp, *pincs, *pfilters;
+ int c, i, nall_argc;
+ char **pall_argv;
+
+ presp = allocate_growable();
+
+ /* FIXME: cleanup the option parsing */
+ /* search for response file, read it */
+ for ( i = 1; i < argc; i++ ) {
+ char *parg = argv[i];
+ char buffer[RES_FILE_BUF];
+
+ if ( *parg == '@' ) {
+ FILE *pfile;
+ if ( !(pfile = fopen(++parg, "r")) )
+ err_quit("%s: %s", parg, strerror(errno));
+ while ( !feof(pfile) ) {
+ char *p, *token;
+
+ if ( fgets(buffer, RES_FILE_BUF, pfile) ) {;
+ p = buffer;
+ while ( (token = strtok(p, " \t\n")) != NULL ) {
+ p = NULL;
+ append_to_growable(presp, strdup(token));
+ }
+ }
+ }
+ fclose(pfile);
+ }
+ }
+
+ /* copy all arguments incl. response file in one array
+ * for parsing with getopt
+ */
+ /* note: this doesn't seem to work with SOLARIS getopt,
+ * use GNU getopt instead
+ */
+ nall_argc = argc + presp->ncur;
+ pall_argv = xmalloc((nall_argc+1)*sizeof(char *));
+ memcpy(pall_argv, argv, argc*sizeof(char *));
+ memcpy(pall_argv+argc, presp->parray, presp->ncur*sizeof(char *));
+ *(pall_argv+argc+presp->ncur) = '\0'; /* terminate */
+
+ opterr = 0;
+ pincs = allocate_growable();
+
+ while( (c = getopt(nall_argc, pall_argv, ":i:I:s:S:o:OhHvV")) != -1 ) {
+ switch(c) {
+ case 'i':
+ case 'I':
+ append_to_growable(pincs, strdup(optarg));
+ break;
+ case 's':
+ case 'S':
+ csep = optarg[0];
+ break;
+ case 'o':
+ case 'O':
+ pout_file = optarg;
+ break;
+ case 'h':
+ case 'H':
+ usage();
+ return 0;
+ break;
+ case 'v':
+ case 'V':
+ bv_flag = 1;
+ break;
+ case '?':
+ if (isprint (optopt))
+ fprintf (stderr,
+ "Unknown option `-%c'.\n", optopt);
+ else
+ fprintf (stderr,
+ "Unknown option character `\\x%x'.\n",
+ optopt);
+ usage();
+ return 1;
+ break;
+ case ':':
+ fprintf(stderr, "Missing parameter.\n");
+ usage();
+ return 1;
+ break;
+ default:
+ usage();
+ return 1;
+ break;
+ }
+ }
+
+ pfilters = allocate_growable();
+ create_filters(pfilters, pincs);
+ free_growable(pincs);
+ pincs = NULL;
+
+ if ( pout_file ) {
+ if ( !(pfsout = fopen(pout_file, "w")) )
+ err_quit("%s: %s", pout_file, strerror(errno));
+ } else {
+ pfsout = stdout;
+ }
+
+ /* the remaining arguments are either class file
+ * names or response files, ignore response file
+ * since they have already been included
+ */
+ for ( i = optind; i < nall_argc; i++ ) {
+ char *parg = pall_argv[i];
+ if ( *parg != '@' ) {
+ process_class_file(parg, pfilters);
+ if ( pfsout != stdout ) {
+ if ( bv_flag )
+ printf("Processed %s ...\n", parg);
+ else {
+ printf(".");
+ fflush(stdout);
+ if ( !bnl )
+ bnl++;
+ }
+ }
+ }
+ }
+ if ( bnl )
+ printf("\n");
+
+
+ free_growable(pfilters);
+ pfilters = NULL;
+ free(pall_argv);
+ pall_argv = NULL;
+ free_growable(presp);
+ presp = NULL;
+
+ fclose(pfsout);
+ exit(0);
+}
+
diff --git a/soltools/javadep/makefile.mk b/soltools/javadep/makefile.mk
new file mode 100644
index 000000000000..a0d691ab30e0
--- /dev/null
+++ b/soltools/javadep/makefile.mk
@@ -0,0 +1,89 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1 $
+#
+# last change: $Author: nf $ $Date: 2001-04-18 09:50:15 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..
+
+PRJNAME=soltools
+TARGET=javadep
+TARGETTYPE=CUI
+TARGETTHREAD=MT
+NO_DEFAULT_STL=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+APP1TARGET = javadep
+APP1OBJS = $(OBJ)$/javadep.obj
+.IF "$(GUI)"=="WNT"
+APP1STDLIBS = gnu_getopt.lib
+.ELSE # "$(GUI)"=="WNT"
+APP1STDLIBS = -lgnu_getopt
+.ENDIF # "$(GUI)"=="WNT"
+DEPOBJFILES = $(APP1OBJS)
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk