00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include "system.h"
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #include <stdarg.h>
00067 #include "debug.h"
00068
00069
00070
00071
00072
00073
00074
00075 typedef struct {
00076 short poolSize;
00077 char **stringList;
00078 short *classRef;
00079 short *typeRef;
00080 } symbolTable_t;
00081
00082
00083
00084
00085
00086 char *PROGRAM_NAME=0;
00087
00088
00089 char *FILE_NAME=0;
00090
00091
00092 char *CLASS_NAME=0;
00093
00094
00095 int ARG_PROVIDES=0;
00096 int ARG_REQUIRES=0;
00097 int ARG_RPMFORMAT=0;
00098 int ARG_KEYWORDS=0;
00099 int ARG_STARPROV=0;
00100
00101
00102 char *KEYWORD_VERSION=0;
00103 char *KEYWORD_REVISION=0;
00104 char *KEYWORD_EPOCH=0;
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 #define MAX_PRINT_TABLE 10000
00128 char *PRINT_TABLE[MAX_PRINT_TABLE];
00129 int SIZE_PRINT_TABLE;
00130
00131
00132
00133 void usage (void);
00134 void outofmemory(void);
00135 void die(char *format, ...);
00136 size_t my_fread(void *ptr, size_t size, size_t nitems, FILE *stream);
00137 void check_range(short value, short poolSize);
00138 char *is_lower_equal (char *string, char *pattern);
00139 int findJavaMagic (FILE *fileHandle);
00140 int my_strcmp (const void *a, const void *b);
00141 void print_table_flush(void);
00142 void print_table_add(char *str);
00143 char *formatClassName(char *pSomeString, char terminator, char print_star);
00144 void dumpRefType(char *pSomeString);
00145 void dumpRequires(symbolTable_t *symbolTable);
00146 void genSymbolTable (FILE *fileHandle, symbolTable_t *symbolTable);
00147 void findClassName (FILE *fileHandle, symbolTable_t *symbolTable);
00148 void freeSymbolTable (symbolTable_t *symbolTable);
00149 void processJavaFile (FILE *fileHandle);
00150
00151
00152
00153 void
00154 usage (void)
00155 {
00156 printf("NAME:\n\tjavadeps - Examine Java class files and\n"
00157 "\t\t\treturn information about their dependencies.\n\n");
00158 printf("USAGE:\n");
00159 printf("\t javadeps { --provides | --requires } \n"
00160 "\t\t [--rpmformat] [--keywords] \n"
00161 "\t\t [--] classfile-name ... \n\n"
00162 "\t javadeps [--help]\n\n");
00163 printf("\n\n");
00164 printf("DESCRIPTION:\n\n");
00165 printf("List the dependencies or the fully qualified class names, of the \n"
00166 "classfiles listed on the command line. \n\n");
00167 printf("OPTIONS:\n\n");
00168 printf("--requires For each class files listed in the arguments,\n"
00169 " -r print the list of class files that would be\n"
00170 " required to run these java programs. This does not \n"
00171 " include anyting instantiated by reflection.\n\n");
00172 printf("--provides For each class files listed in the arguments, \n"
00173 " -p Print the fully qualified java classes,\n"
00174 " that they provide.\n\n");
00175 printf("--rpmformat format the output to match that used by RPM's \n"
00176 " -F (Red Hat Package Manager) dependency analysis \n"
00177 " database. The default is not --rpmformat.\n\n");
00178 printf("--keywords Make use of any keywords embeded in the classfile.\n"
00179 " -k The default is not --keyword.\n\n");
00180 printf("--starprov Add the star notation provides to the provides list.\n"
00181 " -s The default is not --starprov. This is only for use\n"
00182 " with (Sun) jhtml dependencies, and since jhtml is \n"
00183 " deprecated so is this option.\n\n");
00184 printf("--help Display this page and exit.\n\n");
00185 printf("-- This stops the processing of arguments, making it \n"
00186 " easier for users to have filenames like '--keywords',\n"
00187 " without the command line parser getting confused.\n\n");
00188 printf("\n\n");
00189 printf("If any of the class file names in the argument list is '-' then\n"
00190 "<stdin> will be read instead of reading from a file. The\n"
00191 "contents of <stdin> should be the contents of a class file and \n"
00192 "not a list of class files to read. It is assumed that when run \n"
00193 "with '-', this program is in a pipeline preceeded by the \n"
00194 "command 'unzip -p filename.jar' so that <stdin> may contain\n"
00195 "the contents of several classfiles concatenated together.\n");
00196 printf("\n\n");
00197 printf("If --keywords is specified then the following strings are \n"
00198 "searched for (case insensitive) in the class file string table\n"
00199 "and, if a string is found with a prefix matching the keyword then \n"
00200 "the dependencies are changed accordingly. There may be multiple \n"
00201 "string tables entries prefixed with RPM_Provides and RPM_Requires. \n"
00202 "This would indicate that the dependency is the union\n"
00203 "of all entries.\n"
00204 "\n\n"
00205 "Keyword List:\n\n"
00206 "'$Revision: ' This RCS/CVS compatible keyword is assumed to \n"
00207 " contain the version number of the class file \n"
00208 " it is found in. Care should be taken with this\n"
00209 " option as RPM's notion of which version is later\n"
00210 " may not corrispond with your own, especially\n"
00211 " if you use branches. This keyword\n"
00212 " only effects the output of --provides and only\n"
00213 " when RPM_Version is not defined.\n\n"
00214 "'RPM_Version: ' This is an alternative method of specifing the\n"
00215 " version number of the class. It will override\n"
00216 " $Revision if set. This keyword only effects\n"
00217 " the output of --provides \n\n"
00218 "'RPM_Epoch: ' This string contains the epoch to use with the \n"
00219 " version number stored in Revision. If not \n"
00220 " specified, the epoch is assumed to be zero.\n"
00221 " This keyword only effects the output of\n "
00222 " --provides and only when $Revision number is\n"
00223 " used.\n\n"
00224 "'RPM_Provides: ' This string lists additional capabilites\n"
00225 " provided by the java class. The string should\n"
00226 " be a white space ([\\t\\v\\n\\r\\f\\ ])\n"
00227 " separated list of dependency strings. Each\n"
00228 " dependency string must be of the same format as\n"
00229 " would be valid in the Requires or Provides line\n"
00230 " of the specfile. This keyword only effects the\n"
00231 " output of --provides.\n\n"
00232 "'RPM_Requires: ' This string lists additional requirements of\n"
00233 " the java class. The string should be a white \n"
00234 " space ([\\t\v\\n\\r\\f\\ ]) separated list of \n"
00235 " dependency strings. Each dependency string must\n"
00236 " be of the same format as would be valid in the \n"
00237 " Requires or Provides line of the specfile. This\n"
00238 " keyword only effects the output of --requires.\n "
00239 " \n\n"
00240 "Note that there is no means of setting the release number. This\n"
00241 "is necessary because release numbers are incremented when the\n"
00242 "source does not change but the package needs to be rebuilt. So\n"
00243 "relase numbers can not be stored in the source. The release is\n"
00244 "assumed to be zero. \n\n"
00245 "");
00246 printf("EXAMPLES (Java Keywords): \n\n"
00247 "\t public static final String REVISION = \"$Revision: 2.6.8.3 $\";\n"
00248 "\t public static final String EPOCH = \"4\";\n"
00249 "\t public static final String REQUIRES = \"RPM_Requires: "
00250 "java(gnu.regexp.RE) java(com.ibm.site.util.Options)>=1.5\";\n"
00251 "");
00252 printf("\n\n");
00253 printf("EXAMPLES (Arguments): \n\n"
00254 "\tjavadeps --requires -- filename.class\n\n"
00255 "\tjavadeps --provides -- filename.class\n\n"
00256 "\tjavadeps --help\n\n"
00257 "\n"
00258 "\tjavadeps --requires --rpmformat --keywords -- filename.class\n\n"
00259 "\tjavadeps --requires -- filename1.class filename2.class\n\n"
00260 "\tcat filename2.class | javadeps --requires -- filename1.class -\n\n"
00261 "\tunzip -p filename.jar | javadeps --requires -- - \n\n"
00262 "");
00263 printf("This program is distributed with RPM the Redhat Package \n"
00264 "Managment system. Further information about RPM can be found at \n"
00265 "\thttp://www.rpm.org/\n\n");
00266 printf("\n\n");
00267 exit(-1);
00268 }
00269
00270
00271 void outofmemory(void) {
00272
00273
00274
00275
00276 fprintf(stderr, "Could not allocate memory");
00277 exit(-1);
00278 }
00279
00280
00281 void die(char *format, ...) {
00282
00283
00284
00285
00286 char *newformat = NULL, *newmsg = NULL;
00287 va_list ap;
00288
00289 if ( !(newformat = malloc(1024)) || !(newmsg = malloc(1024)) )
00290 outofmemory();
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 va_start(ap, format);
00303
00304 if ( (!FILE_NAME) ) {
00305
00306 sprintf (newformat, "\n%s: %s",
00307 PROGRAM_NAME, format);
00308
00309 } else if ( (FILE_NAME) && (!CLASS_NAME) ) {
00310
00311 sprintf (newformat, "\n%s: Java classfile: %s, %s",
00312 PROGRAM_NAME, FILE_NAME, format);
00313
00314 } else if (CLASS_NAME) {
00315 sprintf (newformat, "\n%s: Java classfile: %s, classname: %s, %s",
00316 PROGRAM_NAME, FILE_NAME, CLASS_NAME, format);
00317 }
00318
00319 vsprintf (newmsg, newformat, ap);
00320
00321
00322
00323
00324
00325 fprintf(stderr, newmsg);
00326
00327 free(newformat);
00328 free(newmsg);
00329
00330 exit(-1);
00331 }
00332
00333
00334
00335
00336
00337 size_t my_fread(void *ptr, size_t size, size_t nitems, FILE *stream) {
00338 size_t rc=0;
00339
00340 int eof=0;
00341 int error=0;
00342
00343
00344 rc = fread(ptr, size, nitems, stream);
00345 if ( (size!=0) && (rc == 0) ) {
00346 eof = feof(stream);
00347 error = ferror(stream);
00348 die("Error reading from file, or unexpected EOF\n");
00349 }
00350 return rc;
00351 }
00352
00353
00354 void check_range(short value, short poolSize) {
00355
00356 if (value > poolSize) {
00357 die("Value: %d, is out of range of the constant pool\n",
00358 value);
00359 }
00360 return ;
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 char
00374 *is_lower_equal (char *string, char *pattern)
00375 {
00376
00377 while ( (tolower(*string) == *pattern) &&
00378 *string && *pattern ) {
00379 string++;
00380 pattern++;
00381 }
00382
00383 if ( *pattern == 0 ) {
00384 return string;
00385 }
00386
00387 return NULL;
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 #define mod4(num) ( (num) & 3 )
00401
00402
00403 int findJavaMagic (FILE *fileHandle)
00404 {
00405 int offset=0;
00406 int foundMagic = 0;
00407 size_t rc;
00408
00409
00410 unsigned char magicInt[4] = {0xCA, 0xFE, 0xBA, 0xBE};
00411
00412
00413
00414 unsigned char buffer[4] = {0};
00415
00416 foundMagic = 0;
00417 while( !foundMagic ) {
00418
00419 rc = fread(&buffer[offset], 1, 1, fileHandle);
00420 if ( !rc ) {
00421
00422
00423
00424
00425 if ( feof(fileHandle) ) {
00426 return 0;
00427 }
00428
00429 if ( ferror(fileHandle) ) {
00430 die ("Error reading character from file.\n");
00431 };
00432
00433 }
00434
00435
00436
00437
00438 foundMagic = (
00439 (magicInt[0] == buffer[mod4(offset+1)]) &&
00440 (magicInt[1] == buffer[mod4(offset+2)]) &&
00441 (magicInt[2] == buffer[mod4(offset+3)]) &&
00442 (magicInt[3] == buffer[mod4(offset+0)]) &&
00443 1
00444 );
00445
00446 offset = mod4(offset+1);
00447
00448 }
00449
00450 return foundMagic;
00451 }
00452
00453 #undef mod4
00454
00455
00456 int
00457 my_strcmp (const void *a, const void *b) {
00458 char **a1; char **b1;
00459 int ret;
00460
00461 a1 = (char **)a;
00462 b1 = (char **)b;
00463 ret = strcmp(*a1,*b1);
00464 return ret;
00465 }
00466
00467
00468
00469 void
00470 print_table_flush(void) {
00471 int i;
00472 char *last_string;
00473
00474 if (!SIZE_PRINT_TABLE) {
00475 return ;
00476 }
00477
00478
00479
00480
00481
00482 qsort( (void *) PRINT_TABLE, (size_t) SIZE_PRINT_TABLE,
00483 sizeof(char *), &my_strcmp);
00484
00485 printf("%s",PRINT_TABLE[0]);
00486 last_string = PRINT_TABLE[0];
00487 PRINT_TABLE[0] = NULL;
00488
00489 for (i = 1; i < SIZE_PRINT_TABLE; i++) {
00490 if ( strcmp(last_string, PRINT_TABLE[i]) ){
00491 printf("%s",PRINT_TABLE[i]);
00492 free(last_string);
00493 last_string = PRINT_TABLE[i];
00494 } else {
00495 free(PRINT_TABLE[i]);
00496 }
00497 PRINT_TABLE[i] = NULL;
00498 }
00499
00500 free(last_string);
00501 SIZE_PRINT_TABLE = 0;
00502 return ;
00503 }
00504
00505
00506
00507
00508
00509
00510
00511
00512 void
00513 print_table_add(char *str) {
00514
00515 if (SIZE_PRINT_TABLE == MAX_PRINT_TABLE) {
00516 print_table_flush();
00517 }
00518
00519 PRINT_TABLE[SIZE_PRINT_TABLE] = str;
00520 SIZE_PRINT_TABLE++;
00521 return ;
00522 }
00523
00524
00525 void
00526 print_list(char *in_string) {
00527
00528
00529
00530
00531
00532 if (in_string) {
00533 printf("%s\n", in_string);
00534 }
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 return ;
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 char
00598 *formatClassName(char *in_string, char terminator,
00599 char print_star)
00600 {
00601 char *leaf_class=0, *out_string=0;
00602 char *ClassName_Break_Set=0;
00603
00604
00605 out_string = malloc(strlen(in_string) + 10);
00606 if ( !out_string ) {
00607 outofmemory();
00608 }
00609 out_string[0]= '\0';
00610
00611
00612
00613
00614 ClassName_Break_Set = malloc(3);
00615 if ( !ClassName_Break_Set ) {
00616 outofmemory();
00617 }
00618 ClassName_Break_Set[0] = '/';
00619
00620 ClassName_Break_Set[1] = terminator;
00621 ClassName_Break_Set[2] = '\0';
00622
00623 if(ARG_RPMFORMAT) {
00624 strcat(out_string, "java(");
00625 }
00626 if (print_star) {
00627
00628
00629 leaf_class = strrchr(in_string, '/');
00630 if (leaf_class) {
00631 leaf_class[0] = terminator;
00632 }
00633 }
00634
00635 while (*in_string != terminator) {
00636 char *newEnd=0;
00637 int copy_len;
00638
00639
00640
00641 if (in_string[0] == '\0' ) {
00642 die("Classname does not terminate with: '%c', '%s'\n",
00643 terminator, in_string);
00644 } else {
00645 if (in_string[0] == '/' ) {
00646
00647 strcat(out_string, ".");
00648 in_string++;
00649 }
00650 }
00651
00652 newEnd = strpbrk(in_string, ClassName_Break_Set);
00653
00654 if (newEnd) {
00655 copy_len = newEnd-in_string;
00656 } else {
00657 if (terminator == '\0') {
00658 copy_len = strlen(in_string);
00659 } else {
00660 copy_len = 0;
00661 }
00662 }
00663
00664
00665 if (copy_len) {
00666 strncat(out_string, in_string, copy_len);
00667 in_string+=copy_len;
00668 }
00669
00670 }
00671
00672 if (leaf_class) {
00673
00674 strcat(out_string, ".*");
00675 leaf_class[0] = '/';
00676 }
00677 if(ARG_RPMFORMAT) {
00678 strcat(out_string, ")");
00679 }
00680
00681 strcat(out_string, "\n");
00682 free(ClassName_Break_Set);
00683 return out_string;
00684 }
00685
00686
00687
00688
00689
00690 void
00691 dumpRefType(char *string)
00692 {
00693
00694
00695
00696
00697 string = strchr(string, 'L');
00698 while (string) {
00699 string++;
00700 print_table_add(formatClassName(string, ';', 0));
00701 string = strchr(string, ';');
00702 string = strchr(string, 'L');
00703 }
00704
00705 return ;
00706 }
00707
00708
00709
00710
00711 void
00712 dumpRequires(symbolTable_t *symbolTable) {
00713 int tem;
00714 int ref = 0;
00715
00716 for(tem=1; tem < symbolTable->poolSize; tem++ ) {
00717
00718
00719 ref = symbolTable->classRef[tem];
00720 if(ref) {
00721 char *string = symbolTable->stringList[ref];
00722 if( !*string ) {
00723 die("class num: %d, referenced string num: %d, "
00724 "which is null.\n",
00725 tem, ref);
00726 }
00727 if ( string[0] == '[' ) {
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739 string = strchr(string, 'L');
00740 if (string) {
00741 dumpRefType(string);
00742 }
00743 } else {
00744 print_table_add(formatClassName(string, '\0', 0));
00745 }
00746 }
00747
00748
00749 ref = symbolTable->typeRef[tem];
00750 if (ref) {
00751 char *string = symbolTable->stringList[ref];
00752 if ( !*string ) {
00753 die("type num: %d, referenced string num: %d, "
00754 "which is null.\n",
00755 tem, ref);
00756 }
00757
00758 dumpRefType(string);
00759 }
00760
00761 }
00762
00763 return ;
00764 }
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 void genSymbolTable (FILE *fileHandle, symbolTable_t *symbolTable)
00775 {
00776 char ignore[10];
00777 int i=0;
00778
00779
00780
00781
00782
00783 my_fread(&ignore, 4, 1, fileHandle);
00784
00785 my_fread(&(symbolTable->poolSize), 2, 1, fileHandle);
00786
00787
00788
00789 symbolTable->stringList = (char**) calloc(symbolTable->poolSize,
00790 sizeof(char*));
00791 if(!symbolTable->stringList){
00792 outofmemory();
00793 }
00794
00795 symbolTable->classRef = (short*) calloc(symbolTable->poolSize,
00796 sizeof(short*));
00797 if(!symbolTable->classRef){
00798 outofmemory();
00799 }
00800
00801 symbolTable->typeRef = (short*) calloc(symbolTable->poolSize,
00802 sizeof(short*));
00803 if(!symbolTable->typeRef){
00804 outofmemory();
00805 }
00806
00807
00808 for(i=0; i < symbolTable->poolSize; i++) {
00809 symbolTable->stringList[i] = NULL;
00810 symbolTable->classRef[i] = 0;
00811 symbolTable->typeRef[i] = 0;
00812 }
00813
00814
00815
00816
00817
00818
00819 for(i=1; i < symbolTable->poolSize; i++) {
00820 unsigned short type = 0;
00821 unsigned short value = 0;
00822 unsigned char tag = 0;
00823
00824
00825
00826 my_fread(&tag, 1, 1, fileHandle);
00827 switch(tag) {
00828 case 1:
00829 {
00830
00831 char *someString;
00832 unsigned short length = 0;
00833
00834
00835
00836
00837 my_fread(&length, 2, 1, fileHandle);
00838 someString = (char*) malloc(length+1);
00839 if(!someString){
00840 outofmemory();
00841 }
00842 my_fread(someString, length, 1, fileHandle);
00843 someString[length]=0;
00844 symbolTable->stringList[i] = someString;
00845
00846 if (ARG_KEYWORDS) {
00847 char *ptr=0;
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857 if (ARG_REQUIRES) {
00858 ptr = is_lower_equal(someString, "rpm_requires: ");
00859 if(ptr){
00860 print_list(ptr);
00861 }
00862 }
00863 if (ARG_PROVIDES) {
00864 ptr = is_lower_equal(someString, "rpm_provides: ");
00865 if(ptr){
00866 print_list(ptr);
00867 }
00868 }
00869
00870
00871
00872 ptr = is_lower_equal(someString, "$revision: ");
00873 if(ptr){
00874 KEYWORD_REVISION=ptr;
00875
00876 ptr = strchr(KEYWORD_REVISION, ' ');
00877 if (ptr) {
00878 *ptr = 0;
00879 }
00880 }
00881 ptr = is_lower_equal(someString, "rpm_version: ");
00882 if(ptr){
00883 KEYWORD_VERSION=ptr;
00884
00885 ptr = strchr(KEYWORD_VERSION, ' ');
00886 if (ptr) {
00887 *ptr = 0;
00888 }
00889 }
00890 ptr = is_lower_equal(someString, "rpm_epoch: ");
00891 if(ptr){
00892 KEYWORD_EPOCH=ptr;
00893
00894 ptr = strchr(KEYWORD_EPOCH, ' ');
00895 if (ptr) {
00896 *ptr = 0;
00897 }
00898 }
00899 }
00900 break;
00901 }
00902 case 2:
00903 die("Unknown type in constant table. "
00904 "Entry: %d. \n", i);
00905 break;
00906 case 3:
00907 my_fread(&ignore, 4, 1, fileHandle);
00908 break;
00909 case 4:
00910 my_fread(&ignore, 4, 1, fileHandle);
00911 break;
00912 case 5:
00913 my_fread(&ignore, 8, 1, fileHandle);
00914 i++;
00915 break;
00916 case 6:
00917 my_fread(&ignore, 8, 1, fileHandle);
00918 i++;
00919 break;
00920 case 7:
00921 my_fread(&value, 2, 1, fileHandle);
00922
00923 check_range(value, symbolTable->poolSize);
00924 symbolTable->classRef[i]=value;
00925 break;
00926 case 8:
00927 my_fread(&ignore, 2, 1, fileHandle);
00928 break;
00929 case 9:
00930 my_fread(&ignore, 4, 1, fileHandle);
00931 break;
00932 case 10:
00933 my_fread(&ignore, 4, 1, fileHandle);
00934 break;
00935 case 11:
00936 my_fread(&ignore, 4, 1, fileHandle);
00937 break;
00938 case 12:
00939 my_fread(&ignore, 2, 1, fileHandle);
00940 my_fread(&type, 2, 1, fileHandle);
00941
00942 check_range(type, symbolTable->poolSize);
00943 symbolTable->typeRef[i]=type;
00944 break;
00945 default:
00946 die("Unknown tag type: %d.\n",
00947 "Entry: %d. \n", tag, i);
00948 break;
00949 }
00950 }
00951
00952 return ;
00953 }
00954
00955
00956
00957
00958
00959
00960
00961 void
00962 findClassName (FILE *fileHandle, symbolTable_t *symbolTable) {
00963 char ignore[10];
00964 unsigned short type = 0;
00965 unsigned short class = 0;
00966 char *out_string;
00967 char *newline;
00968
00969
00970
00971 my_fread(&ignore, 2, 1, fileHandle);
00972
00973
00974
00975 my_fread(&type, 2, 1, fileHandle);
00976 class = symbolTable->classRef[type];
00977 if( !class ||
00978 !symbolTable->stringList[class] ) {
00979 die("Couln't find class: %d, provided by file.\n", class);
00980 }
00981 CLASS_NAME=symbolTable->stringList[class];
00982
00983 out_string = formatClassName(symbolTable->stringList[class], '\0', 0);
00984
00985 {
00986 int len = 10;
00987
00988 if (out_string) {
00989 len += strlen(out_string);
00990 }
00991 if (KEYWORD_EPOCH) {
00992 len += strlen(KEYWORD_EPOCH);
00993 }
00994 if (KEYWORD_VERSION) {
00995 len += strlen(KEYWORD_VERSION);
00996 }
00997 if (KEYWORD_REVISION) {
00998 len += strlen(KEYWORD_REVISION);
00999 }
01000
01001 out_string = realloc(out_string, len );
01002 }
01003
01004 if (!out_string){
01005 outofmemory();
01006 }
01007
01008 if( KEYWORD_VERSION || KEYWORD_REVISION ){
01009
01010
01011
01012 char *newline;
01013
01014
01015
01016
01017
01018 {
01019 char *copy_string;
01020 copy_string = (char*) malloc(strlen(out_string));
01021 if (!copy_string){
01022 outofmemory();
01023 }
01024 copy_string = strcpy(copy_string, out_string);
01025 print_table_add(copy_string);
01026 }
01027
01028 newline = strrchr(out_string, '\n');
01029 if (newline) {
01030 newline[0] = '\0';
01031 }
01032 strcat(out_string, " = ");
01033 if(KEYWORD_EPOCH){
01034 strcat(out_string, KEYWORD_EPOCH);
01035 strcat(out_string, ":");
01036 }
01037 if(KEYWORD_VERSION){
01038 strcat(out_string, KEYWORD_VERSION);
01039 } else {
01040 strcat(out_string, KEYWORD_REVISION);
01041 }
01042 strcat(out_string, "\n");
01043 }
01044
01045 print_table_add(out_string);
01046 out_string=NULL;
01047
01048
01049
01050
01051
01052 if (ARG_STARPROV) {
01053 out_string = formatClassName(symbolTable->stringList[class], '\0', 1);
01054 print_table_add(out_string);
01055 }
01056
01057 return ;
01058 }
01059
01060
01061
01062
01063
01064 void freeSymbolTable (symbolTable_t *symbolTable)
01065 {
01066 int i=0;
01067
01068 for(i=1; i < symbolTable->poolSize; i++) {
01069 if( symbolTable->stringList[i] ) {
01070 free(symbolTable->stringList[i]);
01071 symbolTable->stringList[i] = 0;
01072 }
01073 }
01074
01075 free(symbolTable->stringList);
01076 symbolTable->stringList=0;
01077
01078 free(symbolTable->classRef);
01079 symbolTable->classRef=0;
01080
01081 free(symbolTable->typeRef);
01082 symbolTable->typeRef=0;
01083
01084 free(symbolTable);
01085 symbolTable=0;
01086
01087 return ;
01088 }
01089
01090
01091
01092
01093
01094
01095
01096 void processJavaFile (FILE *fileHandle) {
01097 symbolTable_t symbolTable= {0};
01098
01099 genSymbolTable(fileHandle, &symbolTable);
01100 findClassName(fileHandle, &symbolTable);
01101
01102 if(ARG_REQUIRES) {
01103 dumpRequires(&symbolTable);
01104 }
01105
01106 freeSymbolTable(&symbolTable);
01107
01108 return ;
01109
01110 }
01111
01112
01113 int
01114 main(int argc, char **argv)
01115 {
01116 FILE *fileHandle;
01117 int i = 0;
01118 int rc = 0;
01119 int foundMagic=0;
01120
01121 PROGRAM_NAME=argv[0];
01122
01123 if(argv[1] == NULL) {
01124 usage();
01125 }
01126
01127
01128
01129 for (i = 1; argv[i] != NULL; i++) {
01130
01131 if (0) {
01132
01133
01134
01135
01136 ;
01137 } else if ( !strcmp("-p",argv[i]) || !strcmp("--provides",argv[i]) ) {
01138 ARG_PROVIDES = 1;
01139 } else if ( !strcmp("-r",argv[i]) || !strcmp("--requires",argv[i]) ) {
01140 ARG_REQUIRES = 1;
01141 } else if ( !strcmp("-h",argv[i]) || !strcmp("--help",argv[i]) ||
01142 !strcmp("-?",argv[i]) ) {
01143
01144 usage();
01145 } else if ( !strcmp("-F",argv[i]) || !strcmp("--rpmformat",argv[i]) ) {
01146 ARG_RPMFORMAT=1;
01147 } else if ( !strcmp("-k",argv[i]) || !strcmp("--keywords",argv[i]) ) {
01148 ARG_KEYWORDS=1;
01149 } else if ( !strcmp("-s",argv[i]) || !strcmp("--starprov",argv[i]) ) {
01150 ARG_STARPROV=1;
01151 } else if ( !strcmp("--",argv[i]) ) {
01152 i++;
01153 break;
01154 } else {
01155
01156 break;
01157 }
01158 }
01159
01160
01161
01162 if ( !ARG_PROVIDES && !ARG_REQUIRES ) {
01163 die ("Must specify either --provides or --requires.\n");
01164 }
01165
01166 if ( ARG_PROVIDES && ARG_REQUIRES ) {
01167 die ("Can not specify both --provides and --requires.\n");
01168 }
01169
01170 if ( ARG_REQUIRES && ARG_STARPROV) {
01171 die ("Can not specify both --requires and --starpov.\n");
01172 }
01173
01174 if(argv[i] == NULL) {
01175 die ("Must specify Java class files.\n");
01176 }
01177
01178
01179
01180 for ( ; argv[i] != NULL; i++) {
01181
01182
01183
01184 if ( !strcmp("-", argv[i]) ) {
01185
01186 fileHandle = stdin;
01187 FILE_NAME = "<stdin>";
01188
01189 foundMagic = findJavaMagic(fileHandle);
01190 while (foundMagic) {
01191 processJavaFile(fileHandle);
01192 foundMagic = findJavaMagic(fileHandle);
01193 }
01194 } else {
01195
01196 fileHandle = fopen(argv[i], "r");
01197 if( fileHandle == 0 ) {
01198 die ("Could not open file: %s.\n", argv[i]);
01199 }
01200 fileHandle = fileHandle;
01201 FILE_NAME = argv[i];
01202
01203 foundMagic = findJavaMagic(fileHandle);
01204 if (foundMagic) {
01205 processJavaFile(fileHandle);
01206 }
01207 }
01208
01209 rc = fclose(fileHandle);
01210 if( rc ) {
01211 die ("Could not close file: %s.\n", FILE_NAME);
01212 }
01213 CLASS_NAME=0;
01214 }
01215
01216 print_table_flush();
01217 return 0;
01218 }