1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir /* All Java Virtual Machine Specs are from 29*cdf0e10cSrcweir * "The Java Virtual Machine Specification", T. Lindholm, F. Yellin 30*cdf0e10cSrcweir * (JVMS) 31*cdf0e10cSrcweir */ 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include <stdlib.h> 34*cdf0e10cSrcweir #include <stdio.h> 35*cdf0e10cSrcweir #include <stdarg.h> 36*cdf0e10cSrcweir #include <string.h> 37*cdf0e10cSrcweir #include <errno.h> 38*cdf0e10cSrcweir #include <ctype.h> 39*cdf0e10cSrcweir #include <limits.h> 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #if defined(UNX) || defined(OS2) 42*cdf0e10cSrcweir #include <unistd.h> 43*cdf0e10cSrcweir #include <netinet/in.h> /* ntohl(), ntohs() */ 44*cdf0e10cSrcweir #elif defined(WNT) 45*cdf0e10cSrcweir #include <io.h> 46*cdf0e10cSrcweir #define access _access 47*cdf0e10cSrcweir #define vsnprintf _vsnprintf 48*cdf0e10cSrcweir #define CDECL _cdecl 49*cdf0e10cSrcweir #define F_OK 00 50*cdf0e10cSrcweir #define PATH_MAX _MAX_PATH 51*cdf0e10cSrcweir #define ntohl(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ 52*cdf0e10cSrcweir (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir #define ntohs(x) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) 55*cdf0e10cSrcweir #endif 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir #if defined(OS2) 58*cdf0e10cSrcweir #define CDECL 59*cdf0e10cSrcweir #endif 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir /* max. length of line in response file */ 62*cdf0e10cSrcweir #define RES_FILE_BUF 65536 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir struct file { 65*cdf0e10cSrcweir char *pname; 66*cdf0e10cSrcweir FILE *pfs; 67*cdf0e10cSrcweir }; 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir struct growable { 70*cdf0e10cSrcweir int ncur; 71*cdf0e10cSrcweir int nmax; 72*cdf0e10cSrcweir char **parray; 73*cdf0e10cSrcweir }; 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir typedef struct file file_t; 76*cdf0e10cSrcweir typedef unsigned char uint8; 77*cdf0e10cSrcweir typedef unsigned short uint16; 78*cdf0e10cSrcweir typedef unsigned int uint32; 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir struct utf8 { 81*cdf0e10cSrcweir uint16 nlen; 82*cdf0e10cSrcweir void *pdata; 83*cdf0e10cSrcweir }; 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir typedef struct utf8 utf8_t; 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir /* The contents of the Constant_pool is described in JVMS p. 93 88*cdf0e10cSrcweir */ 89*cdf0e10cSrcweir enum { 90*cdf0e10cSrcweir CONSTANT_Class = 7, 91*cdf0e10cSrcweir CONSTANT_Fieldref = 9, 92*cdf0e10cSrcweir CONSTANT_Methodref = 10, 93*cdf0e10cSrcweir CONSTANT_InterfaceMethodref = 11, 94*cdf0e10cSrcweir CONSTANT_String = 8, 95*cdf0e10cSrcweir CONSTANT_Integer = 3, 96*cdf0e10cSrcweir CONSTANT_Float = 4, 97*cdf0e10cSrcweir CONSTANT_Long = 5, 98*cdf0e10cSrcweir CONSTANT_Double = 6, 99*cdf0e10cSrcweir CONSTANT_NameAndType = 12, 100*cdf0e10cSrcweir CONSTANT_Utf8 = 1 101*cdf0e10cSrcweir }; 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir enum { NGROW_INIT = 10, NGROW = 2 }; 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir static char *pprogname = "javadep"; 106*cdf0e10cSrcweir static char csep = ';'; 107*cdf0e10cSrcweir #if defined (UNX) || defined(OS2) 108*cdf0e10cSrcweir #define CDECL 109*cdf0e10cSrcweir static char cpathsep = '/'; 110*cdf0e10cSrcweir #elif defined (WNT) || defined(OS2) 111*cdf0e10cSrcweir static char cpathsep = '\\'; 112*cdf0e10cSrcweir #endif 113*cdf0e10cSrcweir static FILE *pfsout = NULL; 114*cdf0e10cSrcweir static char *pout_file = NULL; 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir /* prototypes */ 118*cdf0e10cSrcweir uint8 read_uint8(const file_t *pfile); 119*cdf0e10cSrcweir uint16 read_uint16(const file_t *pfile); 120*cdf0e10cSrcweir uint32 read_uint32(const file_t *pfile); 121*cdf0e10cSrcweir void skip_bytes(const file_t *pfile, const size_t nnum); 122*cdf0e10cSrcweir char *escape_slash(const char *pstr); 123*cdf0e10cSrcweir int is_inner(const char *pstr); 124*cdf0e10cSrcweir void print_dependencies(const struct growable *pdep, 125*cdf0e10cSrcweir const char* pclass_file); 126*cdf0e10cSrcweir void process_class_file(const char *pfilenamem, 127*cdf0e10cSrcweir const struct growable *pfilt); 128*cdf0e10cSrcweir char *utf8tolatin1(const utf8_t a_utf8); 129*cdf0e10cSrcweir void *xmalloc(size_t size); 130*cdf0e10cSrcweir void *xcalloc(size_t nmemb, size_t size); 131*cdf0e10cSrcweir void *xrealloc(void *ptr, size_t size); 132*cdf0e10cSrcweir void grow_if_needed (struct growable *pgrow); 133*cdf0e10cSrcweir int append_to_growable(struct growable *, char *); 134*cdf0e10cSrcweir struct growable *allocate_growable(void); 135*cdf0e10cSrcweir void free_growable(struct growable *pgrowvoid); 136*cdf0e10cSrcweir void create_filters(struct growable *pfilt, const struct growable *pinc); 137*cdf0e10cSrcweir void usage(void); 138*cdf0e10cSrcweir void err_quit(const char *, ...); 139*cdf0e10cSrcweir void silent_quit(void); 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir #ifdef WNT 142*cdf0e10cSrcweir /* poor man's getopt() */ 143*cdf0e10cSrcweir int simple_getopt(char *pargv[], const char *poptstring); 144*cdf0e10cSrcweir char *optarg = NULL; 145*cdf0e10cSrcweir int optind = 1; 146*cdf0e10cSrcweir int optopt = 0; 147*cdf0e10cSrcweir int opterr = 0; 148*cdf0e10cSrcweir #endif 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir uint8 151*cdf0e10cSrcweir read_uint8(const file_t *pfile) 152*cdf0e10cSrcweir { 153*cdf0e10cSrcweir /* read a byte from classfile */ 154*cdf0e10cSrcweir int nread; 155*cdf0e10cSrcweir uint8 ndata; 156*cdf0e10cSrcweir nread = fread(&ndata, sizeof(uint8), 1, pfile->pfs); 157*cdf0e10cSrcweir if ( !nread ) { 158*cdf0e10cSrcweir fclose(pfile->pfs); 159*cdf0e10cSrcweir err_quit("%s: truncated class file", pfile->pname); 160*cdf0e10cSrcweir } 161*cdf0e10cSrcweir return ndata; 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir uint16 165*cdf0e10cSrcweir read_uint16(const file_t *pfile) 166*cdf0e10cSrcweir { 167*cdf0e10cSrcweir /* read a short from classfile and convert it to host format */ 168*cdf0e10cSrcweir int nread; 169*cdf0e10cSrcweir uint16 ndata; 170*cdf0e10cSrcweir nread = fread(&ndata, sizeof(uint16), 1, pfile->pfs); 171*cdf0e10cSrcweir if ( !nread ) { 172*cdf0e10cSrcweir fclose(pfile->pfs); 173*cdf0e10cSrcweir err_quit("%s: truncated class file", pfile->pname); 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir ndata = ntohs(ndata); 176*cdf0e10cSrcweir return ndata; 177*cdf0e10cSrcweir } 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir uint32 180*cdf0e10cSrcweir read_uint32(const file_t *pfile) 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir /* read an int from classfile and convert it to host format */ 183*cdf0e10cSrcweir int nread; 184*cdf0e10cSrcweir uint32 ndata; 185*cdf0e10cSrcweir nread = fread(&ndata, sizeof(uint32), 1, pfile->pfs); 186*cdf0e10cSrcweir if ( !nread ) { 187*cdf0e10cSrcweir fclose(pfile->pfs); 188*cdf0e10cSrcweir err_quit("%s: truncated class file", pfile->pname); 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir ndata = ntohl(ndata); 191*cdf0e10cSrcweir return ndata; 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir utf8_t 195*cdf0e10cSrcweir read_utf8(const file_t *pfile) 196*cdf0e10cSrcweir { 197*cdf0e10cSrcweir /* Read a java utf-8-string with uint16 length prependend 198*cdf0e10cSrcweir * from class file. Returns utf8 struct 199*cdf0e10cSrcweir * with fresh allocated datablock, 200*cdf0e10cSrcweir * caller is responsible for freeing. 201*cdf0e10cSrcweir * Data is still in network byteorder 202*cdf0e10cSrcweir */ 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir utf8_t a_utf8; 205*cdf0e10cSrcweir int nread; 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir a_utf8.pdata = NULL; 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir a_utf8.nlen = read_uint16(pfile); 210*cdf0e10cSrcweir if (a_utf8.nlen > 0) { 211*cdf0e10cSrcweir a_utf8.pdata = xmalloc(a_utf8.nlen*sizeof(char)); 212*cdf0e10cSrcweir nread = fread(a_utf8.pdata, a_utf8.nlen*sizeof(char), 1, pfile->pfs); 213*cdf0e10cSrcweir if ( !nread ) { 214*cdf0e10cSrcweir fclose(pfile->pfs); 215*cdf0e10cSrcweir err_quit("%s: truncated class file", pfile->pname); 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir } 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir return a_utf8; 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir char *utf8tolatin1(const utf8_t a_utf8) 223*cdf0e10cSrcweir { 224*cdf0e10cSrcweir /* function returns fresh allocated zero terminated string, 225*cdf0e10cSrcweir * caller is responsible for freeing 226*cdf0e10cSrcweir */ 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir /* JVMS p. 101: the null byte is encoded using a two byte format, 229*cdf0e10cSrcweir * Java Virtual Machine Utf8 strings differ in this respect from 230*cdf0e10cSrcweir * standard UTF-8 strings 231*cdf0e10cSrcweir */ 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir /* Multibyte data is in network byte order */ 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir char *p; 236*cdf0e10cSrcweir char *pp; 237*cdf0e10cSrcweir char *pstr; 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir pstr = pp = xmalloc((a_utf8.nlen+1) * sizeof(char)); 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir for ( p = (char*)a_utf8.pdata; 242*cdf0e10cSrcweir p < (char*)a_utf8.pdata+a_utf8.nlen; 243*cdf0e10cSrcweir p++ ) { 244*cdf0e10cSrcweir if ( *p & 0x80 ) { 245*cdf0e10cSrcweir err_quit("sorry, real UTF8 decoding not yet implemented\n"); 246*cdf0e10cSrcweir } else { 247*cdf0e10cSrcweir *pp++ = *p; 248*cdf0e10cSrcweir } 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir *pp = '\0'; 251*cdf0e10cSrcweir 252*cdf0e10cSrcweir return pstr; 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir void 257*cdf0e10cSrcweir skip_bytes(const file_t *pfile, const size_t nnumber) 258*cdf0e10cSrcweir { 259*cdf0e10cSrcweir /* skip a nnumber of bytes in classfile */ 260*cdf0e10cSrcweir if ( fseek(pfile->pfs, nnumber, SEEK_CUR) == -1 ) 261*cdf0e10cSrcweir err_quit("%s: %s", pfile->pname, strerror(errno)); 262*cdf0e10cSrcweir } 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir void 265*cdf0e10cSrcweir add_to_dependencies(struct growable *pdep, 266*cdf0e10cSrcweir const struct growable *pfilt, 267*cdf0e10cSrcweir char *pdepstr, 268*cdf0e10cSrcweir const char *pclass_file) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir /* create dependencies */ 271*cdf0e10cSrcweir int i; 272*cdf0e10cSrcweir int nlen_filt, nlen_str, nlen_pdepstr; 273*cdf0e10cSrcweir char *pstr, *ptrunc; 274*cdf0e10cSrcweir char path[PATH_MAX+1]; 275*cdf0e10cSrcweir char cnp_class_file[PATH_MAX+1]; 276*cdf0e10cSrcweir char cnp_str[PATH_MAX+1]; 277*cdf0e10cSrcweir 278*cdf0e10cSrcweir nlen_pdepstr = strlen(pdepstr); 279*cdf0e10cSrcweir pstr = xmalloc((nlen_pdepstr+6+1)*sizeof(char)); 280*cdf0e10cSrcweir memcpy(pstr, pdepstr, nlen_pdepstr+1); 281*cdf0e10cSrcweir strncat(pstr, ".class", 6); 282*cdf0e10cSrcweir 283*cdf0e10cSrcweir if ( pfilt->ncur == 0 ) { /* no filters */ 284*cdf0e10cSrcweir if ( access(pstr, F_OK) == 0 ) { 285*cdf0e10cSrcweir append_to_growable(pdep, strdup(pstr)); 286*cdf0e10cSrcweir } 287*cdf0e10cSrcweir } else { 288*cdf0e10cSrcweir nlen_str = strlen(pstr); 289*cdf0e10cSrcweir for ( i = 0; i < pfilt->ncur; i++ ) { 290*cdf0e10cSrcweir nlen_filt = strlen(pfilt->parray[i]); 291*cdf0e10cSrcweir if ( nlen_filt + 1 + nlen_str > PATH_MAX ) 292*cdf0e10cSrcweir err_quit("path to long"); 293*cdf0e10cSrcweir memcpy(path, pfilt->parray[i], nlen_filt); 294*cdf0e10cSrcweir path[nlen_filt] = '/'; 295*cdf0e10cSrcweir memcpy( path+nlen_filt+1, pstr, nlen_str+1); 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir if ( access(path, F_OK) != 0 ) { 298*cdf0e10cSrcweir free(pstr); 299*cdf0e10cSrcweir pstr = NULL; 300*cdf0e10cSrcweir return; /* path doesn't represent a real file, don't bother */ 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir /* get the canonical path */ 304*cdf0e10cSrcweir #if defined (UNX) || defined(OS2) 305*cdf0e10cSrcweir if ( !(realpath(pclass_file, cnp_class_file) 306*cdf0e10cSrcweir && realpath(path, cnp_str) ) ) { 307*cdf0e10cSrcweir err_quit("can't get the canonical path"); 308*cdf0e10cSrcweir } 309*cdf0e10cSrcweir #else 310*cdf0e10cSrcweir if ( !(_fullpath(cnp_class_file, pclass_file, sizeof(cnp_class_file)) 311*cdf0e10cSrcweir && _fullpath(cnp_str, path, sizeof(cnp_str)) ) ) { 312*cdf0e10cSrcweir err_quit("can't get the canonical path"); 313*cdf0e10cSrcweir } 314*cdf0e10cSrcweir #endif 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir /* truncate so that only the package prefix remains */ 317*cdf0e10cSrcweir ptrunc = strrchr(cnp_str, cpathsep); 318*cdf0e10cSrcweir *ptrunc = '\0'; 319*cdf0e10cSrcweir ptrunc = strrchr(cnp_class_file, cpathsep); 320*cdf0e10cSrcweir *ptrunc = '\0'; 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir if ( !strcmp(cnp_str, cnp_class_file) ) { 323*cdf0e10cSrcweir free(pstr); 324*cdf0e10cSrcweir pstr = NULL; 325*cdf0e10cSrcweir return; /* identical, don't bother with this one */ 326*cdf0e10cSrcweir } 327*cdf0e10cSrcweir 328*cdf0e10cSrcweir append_to_growable(pdep, strdup(path)); 329*cdf0e10cSrcweir } 330*cdf0e10cSrcweir } 331*cdf0e10cSrcweir free(pstr); 332*cdf0e10cSrcweir return; 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir 335*cdf0e10cSrcweir char * 336*cdf0e10cSrcweir escape_slash(const char *pstr) 337*cdf0e10cSrcweir { 338*cdf0e10cSrcweir /* returns a fresh allocated string with all cpathsep escaped exchanged 339*cdf0e10cSrcweir * with "$/" 340*cdf0e10cSrcweir * 341*cdf0e10cSrcweir * caller is responsible for freeing 342*cdf0e10cSrcweir */ 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir const char *pp = pstr; 345*cdf0e10cSrcweir char *p, *pnp; 346*cdf0e10cSrcweir char *pnew_str; 347*cdf0e10cSrcweir int nlen_pnp, nlen_pp; 348*cdf0e10cSrcweir int i = 0; 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir while ( (p=strchr(pp, cpathsep)) != NULL ) { 351*cdf0e10cSrcweir ++i; 352*cdf0e10cSrcweir pp = ++p; 353*cdf0e10cSrcweir } 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir nlen_pnp = strlen(pstr) + i; 356*cdf0e10cSrcweir pnp = pnew_str = xmalloc((nlen_pnp+1) * sizeof(char)); 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir pp = pstr; 359*cdf0e10cSrcweir 360*cdf0e10cSrcweir if ( i > 0 ) { 361*cdf0e10cSrcweir while ( (p=strchr(pp, cpathsep)) != NULL ) { 362*cdf0e10cSrcweir memcpy(pnp, pp, p-pp); 363*cdf0e10cSrcweir pnp += p-pp; 364*cdf0e10cSrcweir *pnp++ = '$'; 365*cdf0e10cSrcweir *pnp++ = '/'; 366*cdf0e10cSrcweir pp = ++p; 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir } 369*cdf0e10cSrcweir nlen_pp = strlen(pp); 370*cdf0e10cSrcweir memcpy(pnp, pp, nlen_pp+1); 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir return pnew_str; 373*cdf0e10cSrcweir } 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir void 377*cdf0e10cSrcweir print_dependencies(const struct growable *pdep, const char* pclass_file) 378*cdf0e10cSrcweir { 379*cdf0e10cSrcweir char *pstr; 380*cdf0e10cSrcweir int i; 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir pstr = escape_slash(pclass_file); 383*cdf0e10cSrcweir fprintf(pfsout, "%s:", pstr); 384*cdf0e10cSrcweir free(pstr); 385*cdf0e10cSrcweir 386*cdf0e10cSrcweir for( i=0; i<pdep->ncur; ++i) { 387*cdf0e10cSrcweir fprintf(pfsout, " \\\n"); 388*cdf0e10cSrcweir pstr=escape_slash(pdep->parray[i]); 389*cdf0e10cSrcweir fprintf(pfsout, "\t%s", pstr); 390*cdf0e10cSrcweir free(pstr); 391*cdf0e10cSrcweir } 392*cdf0e10cSrcweir 393*cdf0e10cSrcweir fprintf(pfsout,"\n\n"); 394*cdf0e10cSrcweir return; 395*cdf0e10cSrcweir } 396*cdf0e10cSrcweir 397*cdf0e10cSrcweir int 398*cdf0e10cSrcweir is_inner(const char *pstr) 399*cdf0e10cSrcweir { 400*cdf0e10cSrcweir /* return true if character '$' is found in classname */ 401*cdf0e10cSrcweir 402*cdf0e10cSrcweir /* 403*cdf0e10cSrcweir * note that a '$' in a classname is not an exact indicator 404*cdf0e10cSrcweir * for an inner class. Java identifier may legally contain 405*cdf0e10cSrcweir * this chararcter, and so may classnames. In the context 406*cdf0e10cSrcweir * of javadep this doesn't matter since the makefile system 407*cdf0e10cSrcweir * can't cope with classfiles with '$'s in the filename 408*cdf0e10cSrcweir * anyway. 409*cdf0e10cSrcweir * 410*cdf0e10cSrcweir */ 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir if ( strchr(pstr, '$') != NULL ) 413*cdf0e10cSrcweir return 1; 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir return 0; 416*cdf0e10cSrcweir } 417*cdf0e10cSrcweir 418*cdf0e10cSrcweir void 419*cdf0e10cSrcweir process_class_file(const char *pfilename, const struct growable *pfilt) 420*cdf0e10cSrcweir { 421*cdf0e10cSrcweir /* read class file and extract object information 422*cdf0e10cSrcweir * java class files are in bigendian data format 423*cdf0e10cSrcweir * (JVMS, p. 83) 424*cdf0e10cSrcweir */ 425*cdf0e10cSrcweir int i; 426*cdf0e10cSrcweir uint32 nmagic; 427*cdf0e10cSrcweir uint16 nminor, nmajor; 428*cdf0e10cSrcweir uint16 ncnt; 429*cdf0e10cSrcweir uint16 nclass_cnt; 430*cdf0e10cSrcweir utf8_t* pc_pool; 431*cdf0e10cSrcweir uint16* pc_class; 432*cdf0e10cSrcweir file_t file; 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir struct growable *pdepen; 435*cdf0e10cSrcweir 436*cdf0e10cSrcweir file.pname = (char*)pfilename; 437*cdf0e10cSrcweir 438*cdf0e10cSrcweir file.pfs = fopen(file.pname,"rb"); 439*cdf0e10cSrcweir if ( !file.pfs ) 440*cdf0e10cSrcweir silent_quit(); 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir nmagic = read_uint32(&file); 443*cdf0e10cSrcweir 444*cdf0e10cSrcweir if ( nmagic != 0xCAFEBABE ) { 445*cdf0e10cSrcweir fclose(file.pfs); 446*cdf0e10cSrcweir err_quit("%s: invalid magic", file.pname); 447*cdf0e10cSrcweir } 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir nminor = read_uint16(&file); 450*cdf0e10cSrcweir nmajor = read_uint16(&file); 451*cdf0e10cSrcweir 452*cdf0e10cSrcweir /* get number of entries in constant pool */ 453*cdf0e10cSrcweir ncnt = read_uint16(&file); 454*cdf0e10cSrcweir 455*cdf0e10cSrcweir #ifdef DEBUG 456*cdf0e10cSrcweir printf("Magic: %p\n", (void*)nmagic); 457*cdf0e10cSrcweir printf("Major %d, Minor %d\n", nmajor, nminor); 458*cdf0e10cSrcweir printf("Const_pool_count %d\n", ncnt); 459*cdf0e10cSrcweir #endif 460*cdf0e10cSrcweir 461*cdf0e10cSrcweir /* There can be ncount entries in the constant_pool table 462*cdf0e10cSrcweir * so at most ncount-1 of them can be of type CONSTANT_Class 463*cdf0e10cSrcweir * (at leat one CONSTANT_Utf8 entry must exist). 464*cdf0e10cSrcweir * Usually way less CONSTANT_Class entries exists, of course 465*cdf0e10cSrcweir */ 466*cdf0e10cSrcweir 467*cdf0e10cSrcweir pc_pool = xcalloc(ncnt,sizeof(utf8_t)); 468*cdf0e10cSrcweir pc_class = xmalloc((ncnt-1)*sizeof(uint16)); 469*cdf0e10cSrcweir 470*cdf0e10cSrcweir /* pc_pool[0] is reserved to the java virtual machine and does 471*cdf0e10cSrcweir * not exist in the class file 472*cdf0e10cSrcweir */ 473*cdf0e10cSrcweir 474*cdf0e10cSrcweir nclass_cnt = 0; 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir for (i = 1; i < ncnt; i++) { 477*cdf0e10cSrcweir uint8 ntag; 478*cdf0e10cSrcweir uint16 nindex; 479*cdf0e10cSrcweir utf8_t a_utf8; 480*cdf0e10cSrcweir 481*cdf0e10cSrcweir ntag = read_uint8(&file); 482*cdf0e10cSrcweir 483*cdf0e10cSrcweir /* we are only interested in CONSTANT_Class entries and 484*cdf0e10cSrcweir * Utf8 string entries, because they might belong to 485*cdf0e10cSrcweir * CONSTANT_Class entries 486*cdf0e10cSrcweir */ 487*cdf0e10cSrcweir switch(ntag) { 488*cdf0e10cSrcweir case CONSTANT_Class: 489*cdf0e10cSrcweir nindex = read_uint16(&file); 490*cdf0e10cSrcweir pc_class[nclass_cnt++] = nindex; 491*cdf0e10cSrcweir break; 492*cdf0e10cSrcweir case CONSTANT_Fieldref: 493*cdf0e10cSrcweir case CONSTANT_Methodref: 494*cdf0e10cSrcweir case CONSTANT_InterfaceMethodref: 495*cdf0e10cSrcweir skip_bytes(&file, 4L); 496*cdf0e10cSrcweir break; 497*cdf0e10cSrcweir case CONSTANT_String: 498*cdf0e10cSrcweir skip_bytes(&file, 2L); 499*cdf0e10cSrcweir break; 500*cdf0e10cSrcweir case CONSTANT_Integer: 501*cdf0e10cSrcweir case CONSTANT_Float: 502*cdf0e10cSrcweir skip_bytes(&file, 4L); 503*cdf0e10cSrcweir break; 504*cdf0e10cSrcweir case CONSTANT_Long: 505*cdf0e10cSrcweir case CONSTANT_Double: 506*cdf0e10cSrcweir skip_bytes(&file, 8L); 507*cdf0e10cSrcweir /* Long and Doubles take 2(!) 508*cdf0e10cSrcweir * entries in constant_pool_table 509*cdf0e10cSrcweir */ 510*cdf0e10cSrcweir i++; 511*cdf0e10cSrcweir break; 512*cdf0e10cSrcweir case CONSTANT_NameAndType: 513*cdf0e10cSrcweir skip_bytes(&file, 4L); 514*cdf0e10cSrcweir break; 515*cdf0e10cSrcweir case CONSTANT_Utf8: 516*cdf0e10cSrcweir a_utf8 = read_utf8(&file); 517*cdf0e10cSrcweir pc_pool[i] = a_utf8; 518*cdf0e10cSrcweir break; 519*cdf0e10cSrcweir default: 520*cdf0e10cSrcweir /* Unknown Constant_pool entry, this means we are 521*cdf0e10cSrcweir * in trouble 522*cdf0e10cSrcweir */ 523*cdf0e10cSrcweir err_quit("corrupted class file\n"); 524*cdf0e10cSrcweir break; 525*cdf0e10cSrcweir 526*cdf0e10cSrcweir } 527*cdf0e10cSrcweir } 528*cdf0e10cSrcweir 529*cdf0e10cSrcweir fclose(file.pfs); 530*cdf0e10cSrcweir 531*cdf0e10cSrcweir pdepen = allocate_growable(); 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir for (i = 0; i < nclass_cnt; i++) { 534*cdf0e10cSrcweir char *pstr, *ptmpstr; 535*cdf0e10cSrcweir pstr = ptmpstr = utf8tolatin1(pc_pool[pc_class[i]]); 536*cdf0e10cSrcweir /* we are not interested in inner classes */ 537*cdf0e10cSrcweir if ( is_inner(pstr) ) { 538*cdf0e10cSrcweir free(pstr); 539*cdf0e10cSrcweir pstr = NULL; 540*cdf0e10cSrcweir continue; 541*cdf0e10cSrcweir } 542*cdf0e10cSrcweir /* strip off evt. array indicators */ 543*cdf0e10cSrcweir if ( *ptmpstr == '[' ) { 544*cdf0e10cSrcweir while ( *ptmpstr == '[' ) 545*cdf0e10cSrcweir ptmpstr++; 546*cdf0e10cSrcweir /* we only interested in obj. arrays, which are marked with 'L' */ 547*cdf0e10cSrcweir if ( *ptmpstr == 'L' ) { 548*cdf0e10cSrcweir char *p = pstr; 549*cdf0e10cSrcweir pstr = strdup(++ptmpstr); 550*cdf0e10cSrcweir /* remove final ';' from object array name */ 551*cdf0e10cSrcweir pstr[strlen(pstr)-1] = '\0'; 552*cdf0e10cSrcweir free(p); 553*cdf0e10cSrcweir } else { 554*cdf0e10cSrcweir free(pstr); 555*cdf0e10cSrcweir pstr = NULL; 556*cdf0e10cSrcweir } 557*cdf0e10cSrcweir } 558*cdf0e10cSrcweir 559*cdf0e10cSrcweir if (pstr) { 560*cdf0e10cSrcweir add_to_dependencies(pdepen, pfilt, pstr, file.pname); 561*cdf0e10cSrcweir free(pstr); 562*cdf0e10cSrcweir } 563*cdf0e10cSrcweir } 564*cdf0e10cSrcweir 565*cdf0e10cSrcweir print_dependencies(pdepen, file.pname); 566*cdf0e10cSrcweir free_growable(pdepen); 567*cdf0e10cSrcweir pdepen = NULL; 568*cdf0e10cSrcweir 569*cdf0e10cSrcweir for (i = 0; i < ncnt; i++) 570*cdf0e10cSrcweir free(pc_pool[i].pdata); 571*cdf0e10cSrcweir 572*cdf0e10cSrcweir free(pc_class); 573*cdf0e10cSrcweir free(pc_pool); 574*cdf0e10cSrcweir } 575*cdf0e10cSrcweir 576*cdf0e10cSrcweir void * 577*cdf0e10cSrcweir xmalloc(size_t size) 578*cdf0e10cSrcweir { 579*cdf0e10cSrcweir void *ptr; 580*cdf0e10cSrcweir 581*cdf0e10cSrcweir ptr = malloc(size); 582*cdf0e10cSrcweir 583*cdf0e10cSrcweir if ( !ptr ) 584*cdf0e10cSrcweir err_quit("out of memory"); 585*cdf0e10cSrcweir 586*cdf0e10cSrcweir return ptr; 587*cdf0e10cSrcweir } 588*cdf0e10cSrcweir 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir void * 591*cdf0e10cSrcweir xcalloc(size_t nmemb, size_t size) 592*cdf0e10cSrcweir { 593*cdf0e10cSrcweir void *ptr; 594*cdf0e10cSrcweir 595*cdf0e10cSrcweir ptr = calloc(nmemb, size); 596*cdf0e10cSrcweir 597*cdf0e10cSrcweir if ( !ptr ) 598*cdf0e10cSrcweir err_quit("out of memory"); 599*cdf0e10cSrcweir 600*cdf0e10cSrcweir return ptr; 601*cdf0e10cSrcweir } 602*cdf0e10cSrcweir 603*cdf0e10cSrcweir void * 604*cdf0e10cSrcweir xrealloc(void *ptr, size_t size) 605*cdf0e10cSrcweir { 606*cdf0e10cSrcweir ptr = realloc(ptr, size); 607*cdf0e10cSrcweir 608*cdf0e10cSrcweir if ( !ptr ) 609*cdf0e10cSrcweir err_quit("out of memory"); 610*cdf0e10cSrcweir 611*cdf0e10cSrcweir return ptr; 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir 614*cdf0e10cSrcweir void 615*cdf0e10cSrcweir err_quit(const char* fmt, ...) 616*cdf0e10cSrcweir { 617*cdf0e10cSrcweir /* No dependency file must be generated for any error condition, 618*cdf0e10cSrcweir * just print message and exit. 619*cdf0e10cSrcweir */ 620*cdf0e10cSrcweir va_list args; 621*cdf0e10cSrcweir char buffer[PATH_MAX]; 622*cdf0e10cSrcweir 623*cdf0e10cSrcweir va_start(args, fmt); 624*cdf0e10cSrcweir 625*cdf0e10cSrcweir if ( pprogname ) 626*cdf0e10cSrcweir fprintf(stderr, "%s: ", pprogname); 627*cdf0e10cSrcweir vsnprintf(buffer, sizeof(buffer), fmt, args); 628*cdf0e10cSrcweir fputs(buffer, stderr); 629*cdf0e10cSrcweir fputc('\n', stderr); 630*cdf0e10cSrcweir 631*cdf0e10cSrcweir va_end(args); 632*cdf0e10cSrcweir 633*cdf0e10cSrcweir /* clean up */ 634*cdf0e10cSrcweir if ( pfsout && pfsout != stdout ) { 635*cdf0e10cSrcweir fclose(pfsout); 636*cdf0e10cSrcweir unlink(pout_file); 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir exit(1); 639*cdf0e10cSrcweir } 640*cdf0e10cSrcweir 641*cdf0e10cSrcweir void 642*cdf0e10cSrcweir silent_quit() 643*cdf0e10cSrcweir { 644*cdf0e10cSrcweir /* In some cases we should just do a silent exit */ 645*cdf0e10cSrcweir 646*cdf0e10cSrcweir /* clean up */ 647*cdf0e10cSrcweir if ( pfsout && pfsout != stdout ) { 648*cdf0e10cSrcweir fclose(pfsout); 649*cdf0e10cSrcweir unlink(pout_file); 650*cdf0e10cSrcweir } 651*cdf0e10cSrcweir exit(0); 652*cdf0e10cSrcweir } 653*cdf0e10cSrcweir 654*cdf0e10cSrcweir int append_to_growable(struct growable *pgrow, char *pstr) 655*cdf0e10cSrcweir { 656*cdf0e10cSrcweir /* append an element pstr to pgrow, 657*cdf0e10cSrcweir * return new number of elements 658*cdf0e10cSrcweir */ 659*cdf0e10cSrcweir grow_if_needed(pgrow); 660*cdf0e10cSrcweir pgrow->parray[pgrow->ncur++] = pstr; 661*cdf0e10cSrcweir return pgrow->ncur; 662*cdf0e10cSrcweir } 663*cdf0e10cSrcweir 664*cdf0e10cSrcweir void 665*cdf0e10cSrcweir grow_if_needed(struct growable *pgrow) 666*cdf0e10cSrcweir { 667*cdf0e10cSrcweir /* grow growable arrays */ 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir if ( pgrow->ncur >= pgrow->nmax ) { 670*cdf0e10cSrcweir pgrow->parray = xrealloc(pgrow->parray, 671*cdf0e10cSrcweir (NGROW*pgrow->nmax)*sizeof(char*)); 672*cdf0e10cSrcweir pgrow->nmax *= NGROW; 673*cdf0e10cSrcweir } 674*cdf0e10cSrcweir return; 675*cdf0e10cSrcweir } 676*cdf0e10cSrcweir 677*cdf0e10cSrcweir struct growable *allocate_growable(void) 678*cdf0e10cSrcweir { 679*cdf0e10cSrcweir /* allocate an growable array, 680*cdf0e10cSrcweir * initialize with NGROW_INIT elements 681*cdf0e10cSrcweir */ 682*cdf0e10cSrcweir 683*cdf0e10cSrcweir struct growable *pgrow; 684*cdf0e10cSrcweir 685*cdf0e10cSrcweir pgrow = xmalloc(sizeof(struct growable)); 686*cdf0e10cSrcweir pgrow->parray = xmalloc(NGROW_INIT*sizeof(char *)); 687*cdf0e10cSrcweir pgrow->nmax = NGROW_INIT; 688*cdf0e10cSrcweir pgrow->ncur = 0; 689*cdf0e10cSrcweir return pgrow; 690*cdf0e10cSrcweir } 691*cdf0e10cSrcweir 692*cdf0e10cSrcweir void 693*cdf0e10cSrcweir free_growable(struct growable *pgrow) 694*cdf0e10cSrcweir { 695*cdf0e10cSrcweir int i; 696*cdf0e10cSrcweir for( i = 0; i < pgrow->ncur; i++ ) 697*cdf0e10cSrcweir free(pgrow->parray[i]); 698*cdf0e10cSrcweir free(pgrow->parray); 699*cdf0e10cSrcweir free(pgrow); 700*cdf0e10cSrcweir } 701*cdf0e10cSrcweir 702*cdf0e10cSrcweir void 703*cdf0e10cSrcweir create_filters(struct growable *pfilt, const struct growable *pinc) 704*cdf0e10cSrcweir { 705*cdf0e10cSrcweir char *p, *pp, *pstr; 706*cdf0e10cSrcweir int i, nlen, nlen_pstr; 707*cdf0e10cSrcweir /* break up includes into filter list */ 708*cdf0e10cSrcweir for ( i = 0; i < pinc->ncur; i++ ) { 709*cdf0e10cSrcweir pp = pinc->parray[i]; 710*cdf0e10cSrcweir 711*cdf0e10cSrcweir while ( (p = strchr(pp, csep)) != NULL) { 712*cdf0e10cSrcweir nlen = p - pp; 713*cdf0e10cSrcweir pstr = xmalloc((nlen+1)*sizeof(char*)); 714*cdf0e10cSrcweir memcpy(pstr, pp, nlen); 715*cdf0e10cSrcweir pstr[nlen] = '\0'; 716*cdf0e10cSrcweir append_to_growable(pfilt, pstr); 717*cdf0e10cSrcweir pp = p + 1; 718*cdf0e10cSrcweir } 719*cdf0e10cSrcweir nlen_pstr = strlen(pp); 720*cdf0e10cSrcweir pstr = xmalloc((nlen_pstr+1)*sizeof(char*)); 721*cdf0e10cSrcweir memcpy(pstr, pp, nlen_pstr+1); 722*cdf0e10cSrcweir append_to_growable(pfilt, pstr); 723*cdf0e10cSrcweir } 724*cdf0e10cSrcweir 725*cdf0e10cSrcweir } 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir void 728*cdf0e10cSrcweir usage() 729*cdf0e10cSrcweir { 730*cdf0e10cSrcweir fprintf(stderr, 731*cdf0e10cSrcweir "usage: %s [-i|-I includepath ... -s|-S seperator " 732*cdf0e10cSrcweir "-o|-O outpath -v|-V -h|-H] <file> ....\n", 733*cdf0e10cSrcweir pprogname); 734*cdf0e10cSrcweir } 735*cdf0e10cSrcweir 736*cdf0e10cSrcweir #ifdef WNT 737*cdf0e10cSrcweir /* my very simple minded implementation of getopt() 738*cdf0e10cSrcweir * it's to sad that getopt() is not available everywhere 739*cdf0e10cSrcweir * note: this is not a full POSIX conforming getopt() 740*cdf0e10cSrcweir */ 741*cdf0e10cSrcweir int simple_getopt(char *pargv[], const char *poptstring) 742*cdf0e10cSrcweir { 743*cdf0e10cSrcweir char *parg = pargv[optind]; 744*cdf0e10cSrcweir 745*cdf0e10cSrcweir /* skip all response file arguments */ 746*cdf0e10cSrcweir if ( parg ) { 747*cdf0e10cSrcweir while ( *parg == '@' ) 748*cdf0e10cSrcweir parg = pargv[++optind]; 749*cdf0e10cSrcweir 750*cdf0e10cSrcweir if ( parg[0] == '-' && parg[1] != '\0' ) { 751*cdf0e10cSrcweir char *popt; 752*cdf0e10cSrcweir int c = parg[1]; 753*cdf0e10cSrcweir if ( (popt = strchr(poptstring, c)) == NULL ) { 754*cdf0e10cSrcweir optopt = c; 755*cdf0e10cSrcweir if ( opterr ) 756*cdf0e10cSrcweir fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); 757*cdf0e10cSrcweir return '?'; 758*cdf0e10cSrcweir } 759*cdf0e10cSrcweir if ( *(++popt) == ':') { 760*cdf0e10cSrcweir if ( parg[2] != '\0' ) { 761*cdf0e10cSrcweir optarg = ++parg; 762*cdf0e10cSrcweir } else { 763*cdf0e10cSrcweir optarg = pargv[++optind]; 764*cdf0e10cSrcweir } 765*cdf0e10cSrcweir } else { 766*cdf0e10cSrcweir optarg = NULL; 767*cdf0e10cSrcweir } 768*cdf0e10cSrcweir ++optind; 769*cdf0e10cSrcweir return c; 770*cdf0e10cSrcweir } 771*cdf0e10cSrcweir } 772*cdf0e10cSrcweir return -1; 773*cdf0e10cSrcweir } 774*cdf0e10cSrcweir #endif 775*cdf0e10cSrcweir 776*cdf0e10cSrcweir int CDECL 777*cdf0e10cSrcweir main(int argc, char *argv[]) 778*cdf0e10cSrcweir { 779*cdf0e10cSrcweir int bv_flag = 0; 780*cdf0e10cSrcweir struct growable *presp, *pincs, *pfilters; 781*cdf0e10cSrcweir int c, i, nall_argc; 782*cdf0e10cSrcweir char **pall_argv; 783*cdf0e10cSrcweir 784*cdf0e10cSrcweir presp = allocate_growable(); 785*cdf0e10cSrcweir 786*cdf0e10cSrcweir /* FIXME: cleanup the option parsing */ 787*cdf0e10cSrcweir /* search for response file, read it */ 788*cdf0e10cSrcweir for ( i = 1; i < argc; i++ ) { 789*cdf0e10cSrcweir char *parg = argv[i]; 790*cdf0e10cSrcweir char buffer[RES_FILE_BUF]; 791*cdf0e10cSrcweir 792*cdf0e10cSrcweir if ( *parg == '@' ) { 793*cdf0e10cSrcweir FILE *pfile = fopen(++parg, "r"); 794*cdf0e10cSrcweir if ( !pfile ) 795*cdf0e10cSrcweir err_quit("%s: %s", parg, strerror(errno)); 796*cdf0e10cSrcweir while ( !feof(pfile) ) { 797*cdf0e10cSrcweir char *p, *token; 798*cdf0e10cSrcweir 799*cdf0e10cSrcweir if ( fgets(buffer, RES_FILE_BUF, pfile) ) {; 800*cdf0e10cSrcweir p = buffer; 801*cdf0e10cSrcweir while ( (token = strtok(p, " \t\n")) != NULL ) { 802*cdf0e10cSrcweir p = NULL; 803*cdf0e10cSrcweir append_to_growable(presp, strdup(token)); 804*cdf0e10cSrcweir } 805*cdf0e10cSrcweir } 806*cdf0e10cSrcweir } 807*cdf0e10cSrcweir fclose(pfile); 808*cdf0e10cSrcweir } 809*cdf0e10cSrcweir } 810*cdf0e10cSrcweir 811*cdf0e10cSrcweir /* copy all arguments incl. response file in one array 812*cdf0e10cSrcweir * for parsing with getopt 813*cdf0e10cSrcweir */ 814*cdf0e10cSrcweir nall_argc = argc + presp->ncur; 815*cdf0e10cSrcweir pall_argv = xmalloc((nall_argc+1)*sizeof(char *)); 816*cdf0e10cSrcweir memcpy(pall_argv, argv, argc*sizeof(char *)); 817*cdf0e10cSrcweir memcpy(pall_argv+argc, presp->parray, presp->ncur*sizeof(char *)); 818*cdf0e10cSrcweir *(pall_argv+argc+presp->ncur) = '\0'; /* terminate */ 819*cdf0e10cSrcweir 820*cdf0e10cSrcweir opterr = 0; 821*cdf0e10cSrcweir pincs = allocate_growable(); 822*cdf0e10cSrcweir 823*cdf0e10cSrcweir #ifdef WNT 824*cdf0e10cSrcweir while( (c = simple_getopt(pall_argv, ":i:I:s:S:o:OhHvV")) != -1 ) { 825*cdf0e10cSrcweir #else 826*cdf0e10cSrcweir while( (c = getopt(nall_argc, pall_argv, ":i:I:s:S:o:OhHvV")) != -1 ) { 827*cdf0e10cSrcweir #endif 828*cdf0e10cSrcweir switch(c) { 829*cdf0e10cSrcweir case 'i': 830*cdf0e10cSrcweir case 'I': 831*cdf0e10cSrcweir append_to_growable(pincs, strdup(optarg)); 832*cdf0e10cSrcweir break; 833*cdf0e10cSrcweir case 's': 834*cdf0e10cSrcweir case 'S': 835*cdf0e10cSrcweir csep = optarg[0]; 836*cdf0e10cSrcweir break; 837*cdf0e10cSrcweir case 'o': 838*cdf0e10cSrcweir case 'O': 839*cdf0e10cSrcweir pout_file = optarg; 840*cdf0e10cSrcweir break; 841*cdf0e10cSrcweir case 'h': 842*cdf0e10cSrcweir case 'H': 843*cdf0e10cSrcweir usage(); 844*cdf0e10cSrcweir return 0; 845*cdf0e10cSrcweir break; 846*cdf0e10cSrcweir case 'v': 847*cdf0e10cSrcweir case 'V': 848*cdf0e10cSrcweir bv_flag = 1; 849*cdf0e10cSrcweir break; 850*cdf0e10cSrcweir case '?': 851*cdf0e10cSrcweir if (isprint (optopt)) 852*cdf0e10cSrcweir fprintf (stderr, 853*cdf0e10cSrcweir "Unknown option `-%c'.\n", optopt); 854*cdf0e10cSrcweir else 855*cdf0e10cSrcweir fprintf (stderr, 856*cdf0e10cSrcweir "Unknown option character `\\x%x'.\n", 857*cdf0e10cSrcweir optopt); 858*cdf0e10cSrcweir usage(); 859*cdf0e10cSrcweir return 1; 860*cdf0e10cSrcweir break; 861*cdf0e10cSrcweir case ':': 862*cdf0e10cSrcweir fprintf(stderr, "Missing parameter.\n"); 863*cdf0e10cSrcweir usage(); 864*cdf0e10cSrcweir return 1; 865*cdf0e10cSrcweir break; 866*cdf0e10cSrcweir default: 867*cdf0e10cSrcweir usage(); 868*cdf0e10cSrcweir return 1; 869*cdf0e10cSrcweir break; 870*cdf0e10cSrcweir } 871*cdf0e10cSrcweir } 872*cdf0e10cSrcweir 873*cdf0e10cSrcweir pfilters = allocate_growable(); 874*cdf0e10cSrcweir create_filters(pfilters, pincs); 875*cdf0e10cSrcweir free_growable(pincs); 876*cdf0e10cSrcweir pincs = NULL; 877*cdf0e10cSrcweir 878*cdf0e10cSrcweir if ( pout_file ) { 879*cdf0e10cSrcweir pfsout = fopen(pout_file, "w"); 880*cdf0e10cSrcweir if ( !pfsout ) 881*cdf0e10cSrcweir err_quit("%s: %s", pout_file, strerror(errno)); 882*cdf0e10cSrcweir } else { 883*cdf0e10cSrcweir pfsout = stdout; 884*cdf0e10cSrcweir } 885*cdf0e10cSrcweir 886*cdf0e10cSrcweir /* the remaining arguments are either class file 887*cdf0e10cSrcweir * names or response files, ignore response file 888*cdf0e10cSrcweir * since they have already been included 889*cdf0e10cSrcweir */ 890*cdf0e10cSrcweir for ( i = optind; i < nall_argc; i++ ) { 891*cdf0e10cSrcweir char *parg = pall_argv[i]; 892*cdf0e10cSrcweir if ( *parg != '@' ) { 893*cdf0e10cSrcweir process_class_file(parg, pfilters); 894*cdf0e10cSrcweir if ( pfsout != stdout ) { 895*cdf0e10cSrcweir if ( bv_flag ) 896*cdf0e10cSrcweir printf("Processed %s ...\n", parg); 897*cdf0e10cSrcweir } 898*cdf0e10cSrcweir } 899*cdf0e10cSrcweir } 900*cdf0e10cSrcweir 901*cdf0e10cSrcweir free_growable(pfilters); 902*cdf0e10cSrcweir pfilters = NULL; 903*cdf0e10cSrcweir free(pall_argv); 904*cdf0e10cSrcweir pall_argv = NULL; 905*cdf0e10cSrcweir free_growable(presp); 906*cdf0e10cSrcweir presp = NULL; 907*cdf0e10cSrcweir 908*cdf0e10cSrcweir fclose(pfsout); 909*cdf0e10cSrcweir exit(0); 910*cdf0e10cSrcweir } 911*cdf0e10cSrcweir 912