File indexing completed on 2025-01-18 09:16:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <stdio.h>
0032 #include <string.h>
0033 #include <unistd.h>
0034 #include <dirent.h>
0035 #include <sys/stat.h>
0036 #include <unistd.h>
0037 #include <errno.h>
0038 #include <stdlib.h>
0039
0040 #define BUFSIZE 1000000
0041 #define TRIGSIZE 1000
0042 #define NLIBMAX 200
0043
0044 extern char *optarg;
0045 extern int optind, opterr, optopt;
0046
0047 char** parsedir(char *directory,int *argc)
0048 {
0049 DIR *actualdir;
0050 FILE *actualfile;
0051 struct dirent *entry;
0052 char *buffer=0;
0053 struct stat status;
0054 char **targv=0,**ptr,**phelp;
0055 int len,targc,s;
0056
0057
0058 actualdir=opendir(directory);
0059
0060 if(!actualdir) return targv;
0061
0062
0063 for(entry=readdir(actualdir);entry!=NULL;entry=readdir(actualdir))
0064 {
0065
0066 if(strcmp(entry->d_name,".")==0 ||
0067 strcmp(entry->d_name,"..")==0) continue;
0068
0069 if(buffer) free(buffer);
0070 buffer=(char*) malloc((strlen(directory)+
0071 strlen(entry->d_name)+2)*sizeof(char));
0072 strcpy(buffer,directory);
0073 strcat(buffer,"/");
0074 strcat(buffer,entry->d_name);
0075 s=stat(buffer,&status);
0076 if(s==0)
0077 {
0078 if(S_ISDIR(status.st_mode))
0079 {
0080
0081 targc=0;
0082 ptr=parsedir(buffer,&targc);
0083 if(targc)
0084 {
0085 phelp=targv;
0086 targv=(char**) malloc((*argc+targc)*sizeof(char*));
0087 memcpy(targv,phelp,*argc*sizeof(char*));
0088 memcpy(&targv[*argc],ptr,targc*sizeof(char*));
0089 *argc+=targc;
0090 free(phelp);
0091 free(ptr);
0092 }
0093 }
0094 else if(S_ISREG(status.st_mode))
0095 {
0096
0097 len=strlen(entry->d_name);
0098 if(entry->d_name[len-2]=='.' && entry->d_name[len-1]=='d')
0099 {
0100 phelp=targv;
0101 targv=(char**) malloc((*argc+1)*sizeof(char*));
0102 memcpy(targv,phelp,*argc*sizeof(char*));
0103 targv[*argc]=strdup(buffer);
0104 (*argc)++;
0105 free(phelp);
0106 }
0107 }
0108 }
0109 else
0110 {
0111 fprintf
0112 (stderr,
0113 " No status - perhaps file %s does not exist.\n",
0114 directory);
0115 exit(1);
0116 }
0117 }
0118
0119 if(buffer) free(buffer);
0120 closedir(actualdir);
0121
0122 return targv;
0123 }
0124
0125
0126 int main (int argc, char** argv) {
0127
0128 char static buffer[BUFSIZE],*bufferPtr,workbuf[256];
0129 char *ptr,*p,**pp,**pp1,**pp2,*directory=0,*libpath=0;
0130 char **rargv;
0131 char *libname=0;
0132 int i,optl=0,optm=0,swapping,c,rargc;
0133 FILE *fp;
0134
0135 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
0136 char *ntg4tmp=0,*ntg4tmp1=0;
0137 int nti;
0138 #endif
0139
0140 struct libmap_
0141 {
0142 char *lib;
0143 char *trigger;
0144 int used;
0145 char **uses;
0146 struct libmap_ *next;
0147 };
0148
0149 struct libmap_ *libmap=0,*libmapPtr=0,*libmapPtr1=0,*libmapPtr2=0,
0150 *prevPtr1,*prevPtr2,*tmpp,*userLibmapPtr;
0151
0152 while((c=getopt(argc,argv,"ld: m:"))!=EOF)
0153 {
0154 switch(c)
0155 {
0156 case 'l':
0157 optl=1;
0158 break;
0159 case 'd':
0160 directory=strdup(optarg);
0161 break;
0162 case 'm':
0163 optm=1;
0164 libpath=strdup(optarg);
0165 break;
0166 }
0167 }
0168
0169
0170
0171 if(optind<argc)
0172 {
0173 rargv=&argv[optind];
0174 rargc=argc-optind;
0175 }
0176 else
0177 {
0178 rargv=0;
0179 rargc=0;
0180 }
0181
0182 if(directory)
0183 {
0184 if(rargc==0)
0185 {
0186 rargv=parsedir(directory,&rargc);
0187 }
0188 else
0189 {
0190 fprintf
0191 (stderr,
0192 " ERROR: If you specify a directory don't also specify files\n");
0193 exit(1);
0194 }
0195 }
0196
0197 if(optl)fprintf(stderr," Reading library name map file...\n");
0198 while (!feof(stdin))
0199 {
0200
0201 fgets(buffer,BUFSIZE,stdin);
0202 if(feof(stdin)) break;
0203 if (strlen(buffer) >= BUFSIZE-1)
0204 {
0205 fprintf(stderr,
0206 " Internal ERROR: BUFSIZE too small to read library name map file\n");
0207 exit(1);
0208 }
0209
0210 if ( buffer[strlen(buffer)-1] == '\n')
0211 { buffer[strlen(buffer)-1]='\0'; }
0212
0213 ptr=strtok(buffer,":\n");
0214
0215
0216 for(libmapPtr1=libmap;libmapPtr1;libmapPtr1=libmapPtr1->next)
0217 {
0218 if(strcmp(libmapPtr1->lib,ptr)==0)
0219 {
0220 fprintf(stderr," ERROR: Duplicate library name: %s\n",ptr);
0221 fprintf(stderr,
0222 " Perhaps a duplicate subdirectory with"
0223 " a GNUmakefile with the same library name.\n"
0224 );
0225 exit(1);
0226 }
0227 }
0228
0229 if(libmap)
0230 {
0231 libmapPtr->next=(struct libmap_*) malloc(sizeof(struct libmap_));
0232 libmapPtr=libmapPtr->next;
0233 }
0234 else
0235 {
0236 libmap=(struct libmap_*) malloc(sizeof(struct libmap_));
0237 libmapPtr=libmap;
0238 }
0239 libmapPtr->next=0;
0240 libmapPtr->lib=strdup(ptr);
0241 libmapPtr->used=0;
0242 libmapPtr->uses=(char**)calloc(NLIBMAX,sizeof(char*));
0243
0244
0245 if(!optl && !optm)
0246 {
0247 pp=libmapPtr->uses;
0248 if(ptr)
0249 {
0250 ptr=strtok(NULL," \n");
0251 while (ptr)
0252 {
0253 *pp=strdup(ptr);
0254 pp++;
0255 ptr=strtok(NULL," \n");
0256 }
0257 }
0258 }
0259
0260 if(!optm)
0261 {
0262
0263 fgets(buffer,BUFSIZE,stdin);
0264 if (strlen(buffer) >= BUFSIZE-1)
0265 {
0266 fprintf(stderr,
0267 " Internal ERROR: BUFSIZE too small to read directory name\n");
0268 exit(1);
0269 }
0270
0271 if ( buffer[strlen(buffer)-1] == '\n')
0272 { buffer[strlen(buffer)-1]='\0'; }
0273
0274 ptr=strtok(buffer,"/");
0275 if(!ptr)
0276 {
0277 fprintf(stderr," ERROR: \"/\" before \"source\" expected.\n");
0278 exit(1);
0279 }
0280 while(ptr&&strcmp (ptr,"source"))ptr=strtok(NULL,"/");
0281 ptr=strtok(NULL,"/");
0282 if(!ptr)
0283 {
0284 fprintf(stderr," ERROR: \"source\" expected.\n");
0285 exit(1);
0286 }
0287 libmapPtr->trigger=(char*)malloc(TRIGSIZE);
0288 if(strlen(ptr)>TRIGSIZE)
0289 {
0290 fprintf(stderr," ERROR: String overflow for: %s\n", ptr);
0291 exit(1);
0292 }
0293 strcpy(libmapPtr->trigger,ptr);
0294 ptr=strtok(NULL,"/");
0295 while(ptr&&strcmp(ptr,"GNUmakefile"))
0296 {
0297 strcat(libmapPtr->trigger,"/");
0298 strcat(libmapPtr->trigger,ptr);
0299 ptr=strtok(NULL,"/");
0300 }
0301 if(!ptr)
0302 {
0303 fprintf
0304 (stderr,
0305 " ERROR: \"source/<unique-sub-path>/GNUmakefile\" expected.\n");
0306 exit(1);
0307 }
0308 }
0309 }
0310
0311 if(optl)fprintf(stderr," Reading dependency files...\n");
0312
0313 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
0314 ntg4tmp=getenv("G4TMP");
0315 if ( ! ntg4tmp )
0316 {
0317 fprintf(stderr," ERROR: Cannot find environment variable G4TMP\n");
0318 exit(1);
0319 }
0320 ntg4tmp1=strdup(ntg4tmp);
0321 #endif
0322
0323 for(i=0;i<rargc;i++)
0324 {
0325 fp=fopen(rargv[i],"r");
0326 fgets(buffer,BUFSIZE,fp);
0327
0328 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
0329 ptr=strchr(ntg4tmp1,':');
0330
0331 while ( ptr=strchr(buffer,'\\') ) *ptr='/';
0332
0333 while (ntg4tmp1!=NULL && (ptr=strstr(buffer,ntg4tmp1))!=NULL )
0334 {
0335 for(nti=0;nti<strlen(ntg4tmp1);nti++) ptr[nti]=' ';
0336 }
0337 #endif
0338
0339
0340 ptr=strtok(buffer,":");
0341
0342
0343 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
0344 {
0345 if(strlen(libmapPtr->lib)>256)
0346 {
0347 fprintf(stderr," ERROR: String overflow for: %s\n", libmapPtr->lib);
0348 exit(1);
0349 }
0350 strcpy(workbuf,libmapPtr->lib);
0351
0352 strcat(workbuf,"/");
0353 if(strstr(ptr,workbuf)) break;
0354 }
0355 if(libmapPtr)
0356 {
0357 userLibmapPtr=libmapPtr;
0358 }
0359 else
0360 {
0361 userLibmapPtr=0;
0362 }
0363
0364 if(!optm)
0365 {
0366
0367 bufferPtr=strtok(NULL,"\n");
0368 if (!bufferPtr)
0369 {
0370 fprintf(stderr," WARNING: It seems there is nothing after \':\' in dependency file %s.\n", rargv[i]);
0371 }
0372 else {
0373 do
0374 {
0375 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
0376 {
0377
0378 if(strlen(libmapPtr->trigger)>256)
0379 {
0380 fprintf(stderr," ERROR: String overflow for: %s\n", libmapPtr->trigger);
0381 exit(1);
0382 }
0383 strcpy(workbuf,libmapPtr->trigger);
0384 strcat(workbuf,"/include");
0385 ptr=strstr(bufferPtr,workbuf);
0386 if(ptr && (userLibmapPtr != libmapPtr))
0387 {
0388 libmapPtr->used=1;
0389 if(userLibmapPtr)
0390 {
0391 for(pp=userLibmapPtr->uses;*pp;pp++)
0392 {
0393 if(strcmp(*pp,libmapPtr->lib)==0)break;
0394 }
0395 if(!*pp)*pp=libmapPtr->lib;
0396 }
0397 }
0398
0399
0400
0401
0402
0403
0404 if(strlen(libmapPtr->lib)>256)
0405 {
0406 fprintf(stderr," ERROR: String overflow for: %s\n", libmapPtr->lib);
0407 exit(1);
0408 }
0409 strcpy(workbuf,libmapPtr->lib);
0410 strcat(workbuf,"/");
0411 ptr=strstr(bufferPtr,workbuf);
0412 if(ptr && (userLibmapPtr != libmapPtr))
0413 {
0414 libmapPtr->used=1;
0415 if(userLibmapPtr)
0416 {
0417 for(pp=userLibmapPtr->uses;*pp;pp++)
0418 {
0419 if(strcmp(*pp,libmapPtr->lib)==0)break;
0420 }
0421 if(!*pp)*pp=libmapPtr->lib;
0422 }
0423 }
0424 }
0425 fgets(buffer,BUFSIZE,fp);
0426 bufferPtr=buffer;
0427
0428 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
0429 while ( ptr=strchr(buffer,'\\') ) *ptr='/';
0430
0431 while (ntg4tmp1 && (ptr=strstr(buffer,ntg4tmp1)) )
0432 {
0433 for(nti=0;nti<strlen(ntg4tmp1);nti++) ptr[nti]=' ';
0434 }
0435 #endif
0436
0437 } while(!feof(fp));
0438 fclose(fp);
0439 }
0440 }
0441 }
0442
0443 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
0444 free(ntg4tmp1);
0445 #endif
0446
0447 if(optl)
0448
0449 {
0450 fprintf(stderr," Checking for circular dependencies...\n");
0451 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
0452 {
0453 for(pp=libmapPtr->uses;*pp;pp++)
0454 {
0455 for(libmapPtr1=libmap;libmapPtr1!=libmapPtr;
0456 libmapPtr1=libmapPtr1->next)
0457 {
0458 if(strcmp(libmapPtr1->lib,*pp)==0)
0459 {
0460 for(pp1=libmapPtr1->uses;*pp1;pp1++)
0461 {
0462 if(strcmp(*pp1,libmapPtr->lib)==0)break;
0463 }
0464 if(*pp1)
0465 {
0466 fprintf
0467 (stderr,
0468 " WARNING: %s and %s use each other.\n",
0469 libmapPtr->lib,
0470 libmapPtr1->lib);
0471 }
0472 }
0473 else
0474 {
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495 }
0496 }
0497 }
0498 }
0499
0500 fprintf(stderr," Reordering according to dependencies...\n");
0501 do
0502 {
0503 swapping=0;
0504 prevPtr2=0;
0505 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
0506 {
0507 for(pp=libmapPtr->uses;*pp;pp++)
0508 {
0509 prevPtr1=0;
0510 for(libmapPtr1=libmap;libmapPtr1!=libmapPtr;
0511 libmapPtr1=libmapPtr1->next)
0512 {
0513 if(strcmp(libmapPtr1->lib,*pp)==0)
0514 {
0515
0516 for(pp1=libmapPtr1->uses;*pp1;pp1++)
0517 {
0518 if(strcmp(*pp1,libmapPtr->lib)==0)break;
0519 }
0520 if(!*pp1)
0521 {
0522 swapping=1;
0523
0524 if(prevPtr1)
0525 {
0526 prevPtr1->next=libmapPtr;
0527 }
0528 else
0529 {
0530 libmap=libmapPtr;
0531 }
0532
0533
0534
0535 tmpp=libmapPtr->next;
0536 if(libmapPtr1->next==libmapPtr)
0537 {
0538 libmapPtr->next=libmapPtr1;
0539 }
0540 else
0541 {
0542 libmapPtr->next=libmapPtr1->next;
0543 }
0544
0545
0546 if(libmapPtr1->next!=libmapPtr)
0547 {
0548 prevPtr2->next=libmapPtr1;
0549 }
0550
0551 libmapPtr1->next=tmpp;
0552 break;
0553 }
0554 }
0555 prevPtr1=libmapPtr1;
0556 }
0557 if(swapping)break;
0558 }
0559 prevPtr2=libmapPtr;
0560 if(swapping)break;
0561 }
0562 }while(swapping);
0563
0564 fprintf(stderr," Writing new library map file...\n");
0565 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
0566 {
0567 printf("%s:",libmapPtr->lib);
0568 for(pp=libmapPtr->uses;*pp;pp++)
0569 {
0570 printf(" %s",*pp);
0571 }
0572 printf("\n");
0573 printf("source/%s/GNUmakefile\n",libmapPtr->trigger);
0574 }
0575 }
0576 else if (optm)
0577 {
0578
0579 int libname_usable_size=24;
0580 if ( ! libname ) libname=malloc(libname_usable_size+16);
0581
0582
0583 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
0584 {
0585 if ( strlen(libpath)+strlen(libmapPtr->lib) > libname_usable_size ) {
0586 libname_usable_size=(strlen(libpath)+strlen(libmapPtr->lib))*2;
0587 free(libname);
0588 libname=malloc(libname_usable_size+16);
0589 }
0590
0591
0592
0593 snprintf(libname, libname_usable_size+16, "%s/lib%s.a", libpath, libmapPtr->lib);
0594 if (access(libname,R_OK))
0595 {
0596 snprintf(libname, libname_usable_size+16, "%s/lib%s.so", libpath, libmapPtr->lib);
0597 if (!access(libname,R_OK))
0598 {
0599 printf("-l%s ",libmapPtr->lib);
0600 }
0601 else
0602 {
0603 snprintf(libname, libname_usable_size+16, "%s/lib%s.dylib", libpath, libmapPtr->lib);
0604 if (!access(libname,R_OK))
0605 {
0606 printf("-l%s ",libmapPtr->lib);
0607 }
0608 }
0609 }
0610 else
0611 {
0612 printf("-l%s ",libmapPtr->lib);
0613 }
0614 libmapPtr=libmapPtr->next;
0615 }
0616 }
0617 else
0618 {
0619
0620 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
0621 {
0622 if(libmapPtr->used)
0623 {
0624 for(pp=libmapPtr->uses;*pp;pp++)
0625 {
0626 for(libmapPtr1=libmap;libmapPtr1;libmapPtr1=libmapPtr1->next)
0627 {
0628 if(strcmp(libmapPtr1->lib,*pp)==0)
0629 {
0630 libmapPtr1->used=1;
0631 }
0632 }
0633 }
0634 }
0635 }
0636
0637
0638 for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
0639 {
0640 if(libmapPtr->used)
0641 {
0642 printf("-l%s ",libmapPtr->lib);
0643 }
0644 }
0645 }
0646
0647 exit(0);
0648
0649 }