Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/config/liblist.c

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 
  2 /*
  3 Given a "libname.map" file on standard input and a list or directory
  4 of .d dependency files liblist produces:
  5   a) without -l option, a library list ordered according to the libname.map,
  6      giving a warning if conflicting dependencies are found in the .d files.
  7   b) with -l option, another libname.map, ordered according firstly to the
  8      original libname.map file, then reordered according to the dependencies
  9      found in the .d files.  This option is used for compiling the file
 10      libname.map from all the dependencies.
 11   c) with -m <lpath> option, the whole existing libraries list ordered
 12      according to the libname.map, where libraries are placed in <lpath>.
 13 The .d files are specified in the argument(s).
 14 The libname.map is on standard input.
 15 
 16 Usage:
 17   liblist *.d < libname.map
 18   liblist -d <ddir> < libname.map
 19   liblist -l *.d < libname.map
 20   liblist -ld <ddir> < libname.map
 21   liblist -l -d <ddir> < libname.map
 22   liblist -m <lpath> < libname.map
 23 where:
 24   <ddir>  is a directory name of a directory which is recursively
 25           searched for dependency files
 26   <lpath> is the path where libraries are located
 27 
 28 Frank Behner, John Allison 13th February 1999.
 29 */
 30 
 31 #include <stdio.h>
 32 #include <string.h>
 33 #include <unistd.h>
 34 #include <dirent.h>
 35 #include <sys/stat.h>
 36 #include <unistd.h>
 37 #include <errno.h>
 38 #include <stdlib.h>
 39 
 40 #define BUFSIZE 1000000
 41 #define TRIGSIZE 1000
 42 #define NLIBMAX 200
 43 
 44 extern char *optarg;
 45 extern int optind, opterr, optopt;
 46 
 47 char** parsedir(char *directory,int *argc)
 48 {
 49   DIR *actualdir;
 50   FILE *actualfile;
 51   struct dirent *entry; 
 52   char *buffer=0;
 53   struct stat status;
 54   char **targv=0,**ptr,**phelp;
 55   int len,targc,s;
 56 
 57   /*Open the actual directory*/
 58   actualdir=opendir(directory);
 59 
 60   if(!actualdir) return targv;
 61 
 62   /*Loop over all entries */
 63   for(entry=readdir(actualdir);entry!=NULL;entry=readdir(actualdir))
 64     {
 65       /* Throw away . and .. */
 66       if(strcmp(entry->d_name,".")==0 ||
 67    strcmp(entry->d_name,"..")==0) continue;
 68       /* Obtain the status information of that entry */
 69       if(buffer) free(buffer);
 70       buffer=(char*) malloc((strlen(directory)+
 71            strlen(entry->d_name)+2)*sizeof(char));
 72       strcpy(buffer,directory);
 73       strcat(buffer,"/");
 74       strcat(buffer,entry->d_name);
 75       s=stat(buffer,&status);
 76       if(s==0)
 77   {
 78     if(S_ISDIR(status.st_mode))
 79       {
 80         /* a directory, so we are going recursive*/
 81         targc=0;
 82         ptr=parsedir(buffer,&targc);
 83         if(targc)
 84     {
 85       phelp=targv;
 86       targv=(char**) malloc((*argc+targc)*sizeof(char*));
 87       memcpy(targv,phelp,*argc*sizeof(char*));
 88       memcpy(&targv[*argc],ptr,targc*sizeof(char*));
 89       *argc+=targc;
 90       free(phelp);
 91       free(ptr);
 92     }
 93       }
 94     else if(S_ISREG(status.st_mode))
 95       {
 96         /* a regular file is it .d? */
 97         len=strlen(entry->d_name);
 98         if(entry->d_name[len-2]=='.' && entry->d_name[len-1]=='d')
 99     {
100       phelp=targv;
101       targv=(char**) malloc((*argc+1)*sizeof(char*));
102       memcpy(targv,phelp,*argc*sizeof(char*));
103       targv[*argc]=strdup(buffer);
104       (*argc)++;
105       free(phelp);
106     }
107       }
108   }
109       else
110   {
111     fprintf
112       (stderr,
113        "  No status - perhaps file %s does not exist.\n",
114        directory);
115     exit(1);
116   }
117     }
118 
119   if(buffer) free(buffer);
120   closedir(actualdir);
121 
122   return targv;
123 }
124     
125  
126 int main (int argc, char** argv) {
127 
128   char static buffer[BUFSIZE],*bufferPtr,workbuf[256];
129   char *ptr,*p,**pp,**pp1,**pp2,*directory=0,*libpath=0;
130   char **rargv;
131   char *libname=0;
132   int i,optl=0,optm=0,swapping,c,rargc;
133   FILE *fp;
134 
135 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
136   char *ntg4tmp=0,*ntg4tmp1=0;
137   int nti; 
138 #endif
139 
140   struct libmap_
141     {
142       char *lib;      /* Library name, e.g., G4run. */
143       char *trigger;  /* Source directory, e.g., source/run/.  */
144       int used;       /* True if used by these dependency files.  */
145       char **uses;    /* List of library names which this library uses.  */
146       struct libmap_ *next;
147   };
148 
149   struct libmap_ *libmap=0,*libmapPtr=0,*libmapPtr1=0,*libmapPtr2=0,
150     *prevPtr1,*prevPtr2,*tmpp,*userLibmapPtr;
151 
152   while((c=getopt(argc,argv,"ld: m:"))!=EOF)
153     {
154       switch(c)
155   {
156   case 'l':
157     optl=1;
158     break;
159   case 'd':
160     directory=strdup(optarg);
161     break;
162         case 'm':
163           optm=1;
164     libpath=strdup(optarg);
165           break;
166   }
167     }
168     
169   /*Adjust parameters after parsing options */
170 
171   if(optind<argc)
172     {
173       rargv=&argv[optind];
174       rargc=argc-optind;
175     }
176   else
177     {
178       rargv=0;
179       rargc=0;
180     }
181 
182   if(directory)
183     {
184       if(rargc==0)
185   {
186     rargv=parsedir(directory,&rargc);
187   }
188       else
189   {
190     fprintf
191       (stderr,
192        "  ERROR: If you specify a directory don't also specify files\n");
193     exit(1);
194   }
195     }
196 
197   if(optl)fprintf(stderr,"  Reading library name map file...\n");
198   while (!feof(stdin))
199     {
200       /* Get library name... */
201       fgets(buffer,BUFSIZE,stdin);
202       if(feof(stdin)) break;
203       if (strlen(buffer) >= BUFSIZE-1)
204       {
205          fprintf(stderr,
206      " Internal ERROR: BUFSIZE too small to read library name map file\n");
207    exit(1);
208       }
209          /* discarded trailing \n, as gets() was doing */
210       if ( buffer[strlen(buffer)-1] == '\n') 
211         {   buffer[strlen(buffer)-1]='\0'; }  
212 
213       ptr=strtok(buffer,":\n");
214 
215       /* Check for duplicate names... */
216       for(libmapPtr1=libmap;libmapPtr1;libmapPtr1=libmapPtr1->next)
217   {
218     if(strcmp(libmapPtr1->lib,ptr)==0)
219       {
220         fprintf(stderr,"  ERROR: Duplicate library name: %s\n",ptr);
221         fprintf(stderr,
222           "  Perhaps a duplicate subdirectory with"
223           " a GNUmakefile with the same library name.\n"
224           );
225         exit(1);
226       }
227   }
228 
229       if(libmap)
230   {
231     libmapPtr->next=(struct libmap_*) malloc(sizeof(struct libmap_));
232     libmapPtr=libmapPtr->next;
233   }
234       else /* First time through anchor libmapPtr to libmap. */
235   {
236     libmap=(struct libmap_*) malloc(sizeof(struct libmap_));
237     libmapPtr=libmap;
238   }
239       libmapPtr->next=0;      
240       libmapPtr->lib=strdup(ptr);
241       libmapPtr->used=0;
242       libmapPtr->uses=(char**)calloc(NLIBMAX,sizeof(char*));
243 
244       /* If option -l not specified, fill uses list... */
245       if(!optl && !optm)
246   {
247     pp=libmapPtr->uses;
248     if(ptr)
249       {
250         ptr=strtok(NULL," \n");
251         while (ptr)
252     {
253       *pp=strdup(ptr);
254       pp++;
255       ptr=strtok(NULL," \n");
256     }
257       }
258   }
259 
260       if(!optm)
261         {
262           /* Get directory name... */
263           fgets(buffer,BUFSIZE,stdin);
264     if (strlen(buffer) >= BUFSIZE-1)
265     {
266              fprintf(stderr,
267          " Internal ERROR: BUFSIZE too small to read directory name\n");
268        exit(1);
269     }
270          /* discarded trailing \n, as gets() was doing */
271           if ( buffer[strlen(buffer)-1] == '\n') 
272              {   buffer[strlen(buffer)-1]='\0'; }  
273 
274           ptr=strtok(buffer,"/");
275           if(!ptr)
276       {
277         fprintf(stderr,"  ERROR: \"/\" before \"source\" expected.\n");
278         exit(1);
279       }
280           while(ptr&&strcmp (ptr,"source"))ptr=strtok(NULL,"/");
281           ptr=strtok(NULL,"/");
282           if(!ptr)
283       {
284         fprintf(stderr,"  ERROR: \"source\" expected.\n");
285         exit(1);
286       }
287           libmapPtr->trigger=(char*)malloc(TRIGSIZE);
288     if(strlen(ptr)>TRIGSIZE)
289           {
290             fprintf(stderr,"  ERROR: String overflow for: %s\n", ptr);
291             exit(1);
292           }
293           strcpy(libmapPtr->trigger,ptr);
294           ptr=strtok(NULL,"/");
295           while(ptr&&strcmp(ptr,"GNUmakefile"))
296       {
297         strcat(libmapPtr->trigger,"/");
298         strcat(libmapPtr->trigger,ptr);
299         ptr=strtok(NULL,"/");
300       }
301           if(!ptr)
302       {
303         fprintf
304           (stderr,
305            "  ERROR: \"source/<unique-sub-path>/GNUmakefile\" expected.\n");
306         exit(1);
307       }
308   }
309     }
310 
311   if(optl)fprintf(stderr,"  Reading dependency files...\n");
312 
313 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
314       ntg4tmp=getenv("G4TMP");
315       if ( ! ntg4tmp ) 
316         {
317            fprintf(stderr,"  ERROR: Cannot find environment variable G4TMP\n");
318            exit(1);
319         }
320       ntg4tmp1=strdup(ntg4tmp);
321 #endif
322 
323   for(i=0;i<rargc;i++)
324     {
325       fp=fopen(rargv[i],"r");
326       fgets(buffer,BUFSIZE,fp);
327 
328 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
329       ptr=strchr(ntg4tmp1,':');
330 
331       while ( ptr=strchr(buffer,'\\') ) *ptr='/';
332  
333       while (ntg4tmp1!=NULL &&  (ptr=strstr(buffer,ntg4tmp1))!=NULL )
334         {
335           for(nti=0;nti<strlen(ntg4tmp1);nti++) ptr[nti]=' ';
336         }
337 #endif
338      
339       /* Clip target out of dependency file... */
340       ptr=strtok(buffer,":");
341       
342       /* Look for a "user" library... */
343       for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
344   {
345     if(strlen(libmapPtr->lib)>256)
346           {
347             fprintf(stderr,"  ERROR: String overflow for: %s\n", libmapPtr->lib);
348             exit(1);
349           }
350           strcpy(workbuf,libmapPtr->lib);
351     /* Add trailing "/" to distinguish track/ and tracking/, etc. */
352     strcat(workbuf,"/");
353     if(strstr(ptr,workbuf)) break;
354   }
355       if(libmapPtr)
356   {
357     userLibmapPtr=libmapPtr;
358   }
359       else
360   {
361     userLibmapPtr=0;
362   }
363 
364       if(!optm)
365   {
366     /* Look for a "used" library and add it to the "user" uses list... */
367     bufferPtr=strtok(NULL,"\n");  /* Start *after* ":". */
368     if (!bufferPtr) 
369       {
370         fprintf(stderr,"  WARNING: It seems there is nothing after \':\' in dependency file %s.\n", rargv[i]);
371       }
372     else {
373     do
374       {
375         for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
376           {
377       /* Look for trigger string. */
378             if(strlen(libmapPtr->trigger)>256)
379                   {
380                     fprintf(stderr,"  ERROR: String overflow for: %s\n", libmapPtr->trigger);
381                     exit(1);
382                   }
383                   strcpy(workbuf,libmapPtr->trigger);
384       strcat(workbuf,"/include");
385       ptr=strstr(bufferPtr,workbuf);
386       if(ptr && (userLibmapPtr != libmapPtr))
387         {
388           libmapPtr->used=1;
389           if(userLibmapPtr)
390             {
391         for(pp=userLibmapPtr->uses;*pp;pp++)
392           {
393             if(strcmp(*pp,libmapPtr->lib)==0)break;
394           }
395         if(!*pp)*pp=libmapPtr->lib;
396             }
397         }
398       /* Also look for library name in case header files are
399          placed in temporary directories under a subdirectory
400          with the same name as the library name.  This can
401          happen with Objectivity which makes header files
402          from .ddl files and places them in a temporary
403          directory. */
404             if(strlen(libmapPtr->lib)>256)
405                   {
406                     fprintf(stderr,"  ERROR: String overflow for: %s\n", libmapPtr->lib);
407                     exit(1);
408                   }
409       strcpy(workbuf,libmapPtr->lib);
410       strcat(workbuf,"/");
411       ptr=strstr(bufferPtr,workbuf);
412       if(ptr && (userLibmapPtr != libmapPtr))
413         {
414           libmapPtr->used=1;
415           if(userLibmapPtr)
416             {
417         for(pp=userLibmapPtr->uses;*pp;pp++)
418           {
419             if(strcmp(*pp,libmapPtr->lib)==0)break;
420           }
421         if(!*pp)*pp=libmapPtr->lib;
422             }
423         }
424           }
425         fgets(buffer,BUFSIZE,fp);
426         bufferPtr=buffer;
427 
428 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
429         while ( ptr=strchr(buffer,'\\') ) *ptr='/';
430 
431         while (ntg4tmp1 &&  (ptr=strstr(buffer,ntg4tmp1)) )
432           {
433       for(nti=0;nti<strlen(ntg4tmp1);nti++) ptr[nti]=' ';
434           }
435 #endif
436 
437       } while(!feof(fp));
438     fclose(fp);
439         }
440       }
441     }
442 
443 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
444       free(ntg4tmp1);
445 #endif
446 
447   if(optl) /* This option is used for compiling the file libname.map
448         from all the dependencies. */
449     {
450       fprintf(stderr,"  Checking for circular dependencies...\n");
451       for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
452   {
453     for(pp=libmapPtr->uses;*pp;pp++)
454       {
455         for(libmapPtr1=libmap;libmapPtr1!=libmapPtr;
456       libmapPtr1=libmapPtr1->next)
457     {
458       if(strcmp(libmapPtr1->lib,*pp)==0)
459         {
460           for(pp1=libmapPtr1->uses;*pp1;pp1++)
461       {
462         if(strcmp(*pp1,libmapPtr->lib)==0)break;
463       }
464           if(*pp1)
465       {
466         fprintf
467           (stderr,
468            "  WARNING: %s and %s use each other.\n",
469            libmapPtr->lib,
470            libmapPtr1->lib);
471       }
472         }
473       else 
474         {
475           /* Not right yet...
476           for(pp1=libmapPtr1->uses;*pp1;pp1++)
477       {
478         for(libmapPtr0=libmap;libmapPtr0!=libmapPtr1;
479             libmapPtr0=libmapPtr0->next)
480           {
481             if(libmapPtr0==*pp)
482         {
483           fprintf
484             (stderr,
485              "  WARNING: triangular dependecy:\n"
486              "  %s uses %s uses %s uses %s.\n",
487              libmapPtr->lib,
488              libmapPtr1->lib,
489              libmapPtr0->lib,
490              libmapPtr->lib);
491         }
492           }
493       }
494           */
495         }
496     }
497       }
498   }
499 
500       fprintf(stderr,"  Reordering according to dependencies...\n");
501       do
502   {
503     swapping=0;
504     prevPtr2=0;
505     for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
506       {
507         for(pp=libmapPtr->uses;*pp;pp++)
508     {
509       prevPtr1=0;
510       for(libmapPtr1=libmap;libmapPtr1!=libmapPtr;
511           libmapPtr1=libmapPtr1->next)
512         {
513           if(strcmp(libmapPtr1->lib,*pp)==0)
514       {
515         /* Check that 1st doesn't use 2nd... */
516         for(pp1=libmapPtr1->uses;*pp1;pp1++)
517           {
518             if(strcmp(*pp1,libmapPtr->lib)==0)break;
519           }
520         if(!*pp1) /* If not... */
521           {
522             swapping=1;
523             /* Make previous of 1st now point to 2nd... */
524             if(prevPtr1)
525         {
526           prevPtr1->next=libmapPtr;
527         }
528             else
529         {
530           libmap=libmapPtr;
531         }
532             /* Make 2nd now point to what 1st did, unless
533          it's adjacent, in which case make it point
534          to 1st itself... */
535             tmpp=libmapPtr->next;
536             if(libmapPtr1->next==libmapPtr)
537         {
538           libmapPtr->next=libmapPtr1;
539         }
540             else
541         {
542           libmapPtr->next=libmapPtr1->next;
543         }
544             /* Make previous of 2nd point to 1st, unless
545          it's adjacent, in which case leave it... */
546             if(libmapPtr1->next!=libmapPtr)
547         {
548           prevPtr2->next=libmapPtr1;
549         }
550             /* Make 1st now point to what 2nd did... */
551             libmapPtr1->next=tmpp;
552             break;
553           }
554       }
555           prevPtr1=libmapPtr1;
556         }
557       if(swapping)break;
558     }
559         prevPtr2=libmapPtr;
560         if(swapping)break;
561       }
562   }while(swapping);
563 
564       fprintf(stderr,"  Writing new library map file...\n");
565       for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
566   {
567     printf("%s:",libmapPtr->lib);
568     for(pp=libmapPtr->uses;*pp;pp++)
569       {
570         printf(" %s",*pp);
571       }
572     printf("\n");
573     printf("source/%s/GNUmakefile\n",libmapPtr->trigger);
574   }
575     }
576   else if (optm)
577     {
578       /* create tmp. string libname */ 
579       int libname_usable_size=24;
580       if ( ! libname ) libname=malloc(libname_usable_size+16);
581 
582       /* Write out full library list... */      
583       for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
584       {
585   if ( strlen(libpath)+strlen(libmapPtr->lib) > libname_usable_size ) {
586     libname_usable_size=(strlen(libpath)+strlen(libmapPtr->lib))*2;
587     free(libname);
588     libname=malloc(libname_usable_size+16);
589   }
590         /* Check existance of libraries and print out only installed ones */
591     
592   
593   snprintf(libname, libname_usable_size+16, "%s/lib%s.a", libpath, libmapPtr->lib);
594         if (access(libname,R_OK))
595   {
596     snprintf(libname, libname_usable_size+16, "%s/lib%s.so", libpath, libmapPtr->lib);
597           if (!access(libname,R_OK))
598     {
599             printf("-l%s ",libmapPtr->lib);
600     }
601           else  /* case MacOS .dylib */
602           {
603       snprintf(libname, libname_usable_size+16, "%s/lib%s.dylib", libpath, libmapPtr->lib);
604             if (!access(libname,R_OK))
605       {
606               printf("-l%s ",libmapPtr->lib);
607       }
608           }
609   }
610         else
611   {
612           printf("-l%s ",libmapPtr->lib);
613   }
614   libmapPtr=libmapPtr->next;
615       }
616     }
617   else
618     {
619       /* Add dependent libraries... */
620       for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
621   {
622     if(libmapPtr->used)
623       {
624         for(pp=libmapPtr->uses;*pp;pp++)
625     {
626       for(libmapPtr1=libmap;libmapPtr1;libmapPtr1=libmapPtr1->next)
627         {
628           if(strcmp(libmapPtr1->lib,*pp)==0)
629       {
630         libmapPtr1->used=1;
631       }
632         }
633     }       
634       }
635   }
636 
637       /* Write out library list... */
638       for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
639   {
640     if(libmapPtr->used)
641       {
642         printf("-l%s ",libmapPtr->lib);
643       }
644   }
645     }
646       
647   exit(0);
648   
649 }
650