Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Macros | Functions | Variables
liblist.c File Reference
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>

Go to the source code of this file.

Macros

#define BUFSIZE   1000000
 
#define TRIGSIZE   1000
 
#define NLIBMAX   200
 

Functions

char ** parsedir (char *directory, int *argc)
 
int main (int argc, char **argv)
 

Variables

char * optarg
 
int optind
 
int opterr
 
int optopt
 

Macro Definition Documentation

#define BUFSIZE   1000000

Definition at line 41 of file liblist.c.

Referenced by G4UItcsh::G4UItcsh(), main(), and G4MPIbatch::ReadCommand().

#define NLIBMAX   200

Definition at line 43 of file liblist.c.

Referenced by main().

#define TRIGSIZE   1000

Definition at line 42 of file liblist.c.

Referenced by main().

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 127 of file liblist.c.

References buffer, bufferPtr, BUFSIZE, test::c, calloc(), free(), malloc(), NLIBMAX, optarg, optind, parsedir(), G4InuclParticleNames::pp, and TRIGSIZE.

127  {
128 
129  char static buffer[BUFSIZE],*bufferPtr,workbuf[256];
130  char *ptr,*p,**pp,**pp1,**pp2,*directory=0,*libpath=0;
131  char **rargv;
132  char *libname=0;
133  int i,optl=0,optm=0,swapping,c,rargc;
134  FILE *fp;
135 
136 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
137  char *ntg4tmp=0,*ntg4tmp1=0;
138  int nti;
139 #endif
140 
141  struct libmap_
142  {
143  char *lib; /* Library name, e.g., G4run. */
144  char *trigger; /* Source directory, e.g., source/run/. */
145  int used; /* True if used by these dependency files. */
146  char **uses; /* List of library names which this library uses. */
147  struct libmap_ *next;
148  };
149 
150  struct libmap_ *libmap=0,*libmapPtr=0,*libmapPtr1=0,*libmapPtr2=0,
151  *prevPtr1,*prevPtr2,*tmpp,*userLibmapPtr;
152 
153  while((c=getopt(argc,argv,"ld: m:"))!=EOF)
154  {
155  switch(c)
156  {
157  case 'l':
158  optl=1;
159  break;
160  case 'd':
161  directory=strdup(optarg);
162  break;
163  case 'm':
164  optm=1;
165  libpath=strdup(optarg);
166  break;
167  }
168  }
169 
170  /*Adjust parameters after parsing options */
171 
172  if(optind<argc)
173  {
174  rargv=&argv[optind];
175  rargc=argc-optind;
176  }
177  else
178  {
179  rargv=0;
180  rargc=0;
181  }
182 
183  if(directory)
184  {
185  if(rargc==0)
186  {
187  rargv=parsedir(directory,&rargc);
188  }
189  else
190  {
191  fprintf
192  (stderr,
193  " ERROR: If you specify a directory don't also specify files\n");
194  exit(1);
195  }
196  }
197 
198  if(optl)fprintf(stderr," Reading library name map file...\n");
199  while (!feof(stdin))
200  {
201  /* Get library name... */
202  fgets(buffer,BUFSIZE,stdin);
203  if(feof(stdin)) break;
204  if (strlen(buffer) >= BUFSIZE-1)
205  {
206  fprintf(stderr,
207  " Internal ERROR: BUFSIZE too small to read library name map file\n");
208  exit(1);
209  }
210  /* discarded trailing \n, as gets() was doing */
211  if ( buffer[strlen(buffer)-1] == '\n')
212  { buffer[strlen(buffer)-1]='\0'; }
213 
214  ptr=strtok(buffer,":\n");
215 
216  /* Check for duplicate names... */
217  for(libmapPtr1=libmap;libmapPtr1;libmapPtr1=libmapPtr1->next)
218  {
219  if(strcmp(libmapPtr1->lib,ptr)==0)
220  {
221  fprintf(stderr," ERROR: Duplicate library name: %s\n",ptr);
222  fprintf(stderr,
223  " Perhaps a duplicate subdirectory with"
224  " a GNUmakefile with the same library name.\n"
225  );
226  exit(1);
227  }
228  }
229 
230  if(libmap)
231  {
232  libmapPtr->next=(struct libmap_*) malloc(sizeof(struct libmap_));
233  libmapPtr=libmapPtr->next;
234  }
235  else /* First time through anchor libmapPtr to libmap. */
236  {
237  libmap=(struct libmap_*) malloc(sizeof(struct libmap_));
238  libmapPtr=libmap;
239  }
240  libmapPtr->next=0;
241  libmapPtr->lib=strdup(ptr);
242  libmapPtr->used=0;
243  libmapPtr->uses=(char**)calloc(NLIBMAX,sizeof(char*));
244 
245  /* If option -l not specified, fill uses list... */
246  if(!optl && !optm)
247  {
248  pp=libmapPtr->uses;
249  if(ptr)
250  {
251  ptr=strtok(NULL," \n");
252  while (ptr)
253  {
254  *pp=strdup(ptr);
255  pp++;
256  ptr=strtok(NULL," \n");
257  }
258  }
259  }
260 
261  if(!optm)
262  {
263  /* Get directory name... */
264  fgets(buffer,BUFSIZE,stdin);
265  if (strlen(buffer) >= BUFSIZE-1)
266  {
267  fprintf(stderr,
268  " Internal ERROR: BUFSIZE too small to read directory name\n");
269  exit(1);
270  }
271  /* discarded trailing \n, as gets() was doing */
272  if ( buffer[strlen(buffer)-1] == '\n')
273  { buffer[strlen(buffer)-1]='\0'; }
274 
275  ptr=strtok(buffer,"/");
276  if(!ptr)
277  {
278  fprintf(stderr," ERROR: \"/\" before \"source\" expected.\n");
279  exit(1);
280  }
281  while(ptr&&strcmp (ptr,"source"))ptr=strtok(NULL,"/");
282  ptr=strtok(NULL,"/");
283  if(!ptr)
284  {
285  fprintf(stderr," ERROR: \"source\" expected.\n");
286  exit(1);
287  }
288  libmapPtr->trigger=(char*)malloc(TRIGSIZE);
289  if(strlen(ptr)>TRIGSIZE)
290  {
291  fprintf(stderr," ERROR: String overflow for: %s\n", ptr);
292  exit(1);
293  }
294  strcpy(libmapPtr->trigger,ptr);
295  ptr=strtok(NULL,"/");
296  while(ptr&&strcmp(ptr,"GNUmakefile"))
297  {
298  strncat(libmapPtr->trigger,"/",1);
299  strncat(libmapPtr->trigger,ptr,strlen(ptr));
300  ptr=strtok(NULL,"/");
301  }
302  if(!ptr)
303  {
304  fprintf
305  (stderr,
306  " ERROR: \"source/<unique-sub-path>/GNUmakefile\" expected.\n");
307  exit(1);
308  }
309  }
310  }
311 
312  if(optl)fprintf(stderr," Reading dependency files...\n");
313 
314 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
315  ntg4tmp=getenv("G4TMP");
316  if ( ! ntg4tmp )
317  {
318  fprintf(stderr," ERROR: Cannot find environment variable G4TMP\n");
319  exit(1);
320  }
321  ntg4tmp1=strdup(ntg4tmp);
322 #endif
323 
324  for(i=0;i<rargc;i++)
325  {
326  fp=fopen(rargv[i],"r");
327  fgets(buffer,BUFSIZE,fp);
328 
329 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
330  ptr=strchr(ntg4tmp1,':');
331 
332  while ( ptr=strchr(buffer,'\\') ) *ptr='/';
333 
334  while (ntg4tmp1!=NULL && (ptr=strstr(buffer,ntg4tmp1))!=NULL )
335  {
336  for(nti=0;nti<strlen(ntg4tmp1);nti++) ptr[nti]=' ';
337  }
338 #endif
339 
340  /* Clip target out of dependency file... */
341  ptr=strtok(buffer,":");
342 
343  /* Look for a "user" library... */
344  for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
345  {
346  if(strlen(libmapPtr->lib)>256)
347  {
348  fprintf(stderr," ERROR: String overflow for: %s\n", libmapPtr->lib);
349  exit(1);
350  }
351  strcpy(workbuf,libmapPtr->lib);
352  /* Add trailing "/" to distinguish track/ and tracking/, etc. */
353  strncat(workbuf,"/",1);
354  if(strstr(ptr,workbuf)) break;
355  }
356  if(libmapPtr)
357  {
358  userLibmapPtr=libmapPtr;
359  }
360  else
361  {
362  userLibmapPtr=0;
363  }
364 
365  if(!optm)
366  {
367  /* Look for a "used" library and add it to the "user" uses list... */
368  bufferPtr=strtok(NULL,"\n"); /* Start *after* ":". */
369  if (!bufferPtr)
370  {
371  fprintf(stderr," WARNING: It seems there is nothing after \':\' in dependency file %s.\n", rargv[i]);
372  }
373  else {
374  do
375  {
376  for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
377  {
378  /* Look for trigger string. */
379  if(strlen(libmapPtr->trigger)>256)
380  {
381  fprintf(stderr," ERROR: String overflow for: %s\n", libmapPtr->trigger);
382  exit(1);
383  }
384  strcpy(workbuf,libmapPtr->trigger);
385  strncat(workbuf,"/include",8);
386  ptr=strstr(bufferPtr,workbuf);
387  if(ptr && (userLibmapPtr != libmapPtr))
388  {
389  libmapPtr->used=1;
390  if(userLibmapPtr)
391  {
392  for(pp=userLibmapPtr->uses;*pp;pp++)
393  {
394  if(strcmp(*pp,libmapPtr->lib)==0)break;
395  }
396  if(!*pp)*pp=libmapPtr->lib;
397  }
398  }
399  /* Also look for library name in case header files are
400  placed in temporary directories under a subdirectory
401  with the same name as the library name. This can
402  happen with Objectivity which makes header files
403  from .ddl files and places them in a temporary
404  directory. */
405  if(strlen(libmapPtr->lib)>256)
406  {
407  fprintf(stderr," ERROR: String overflow for: %s\n", libmapPtr->lib);
408  exit(1);
409  }
410  strcpy(workbuf,libmapPtr->lib);
411  strncat(workbuf,"/",1);
412  ptr=strstr(bufferPtr,workbuf);
413  if(ptr && (userLibmapPtr != libmapPtr))
414  {
415  libmapPtr->used=1;
416  if(userLibmapPtr)
417  {
418  for(pp=userLibmapPtr->uses;*pp;pp++)
419  {
420  if(strcmp(*pp,libmapPtr->lib)==0)break;
421  }
422  if(!*pp)*pp=libmapPtr->lib;
423  }
424  }
425  }
426  fgets(buffer,BUFSIZE,fp);
427  bufferPtr=buffer;
428 
429 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
430  while ( ptr=strchr(buffer,'\\') ) *ptr='/';
431 
432  while (ntg4tmp1 && (ptr=strstr(buffer,ntg4tmp1)) )
433  {
434  for(nti=0;nti<strlen(ntg4tmp1);nti++) ptr[nti]=' ';
435  }
436 #endif
437 
438  } while(!feof(fp));
439  fclose(fp);
440  }
441  }
442  }
443 
444 #if defined ( _WIN32 ) || defined ( __CYGWIN__ ) || defined ( __CYGWIN32__ )
445  free(ntg4tmp1);
446 #endif
447 
448  if(optl) /* This option is used for compiling the file libname.map
449  from all the dependencies. */
450  {
451  fprintf(stderr," Checking for circular dependencies...\n");
452  for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
453  {
454  for(pp=libmapPtr->uses;*pp;pp++)
455  {
456  for(libmapPtr1=libmap;libmapPtr1!=libmapPtr;
457  libmapPtr1=libmapPtr1->next)
458  {
459  if(strcmp(libmapPtr1->lib,*pp)==0)
460  {
461  for(pp1=libmapPtr1->uses;*pp1;pp1++)
462  {
463  if(strcmp(*pp1,libmapPtr->lib)==0)break;
464  }
465  if(*pp1)
466  {
467  fprintf
468  (stderr,
469  " WARNING: %s and %s use each other.\n",
470  libmapPtr->lib,
471  libmapPtr1->lib);
472  }
473  }
474  else
475  {
476  /* Not right yet...
477  for(pp1=libmapPtr1->uses;*pp1;pp1++)
478  {
479  for(libmapPtr0=libmap;libmapPtr0!=libmapPtr1;
480  libmapPtr0=libmapPtr0->next)
481  {
482  if(libmapPtr0==*pp)
483  {
484  fprintf
485  (stderr,
486  " WARNING: triangular dependecy:\n"
487  " %s uses %s uses %s uses %s.\n",
488  libmapPtr->lib,
489  libmapPtr1->lib,
490  libmapPtr0->lib,
491  libmapPtr->lib);
492  }
493  }
494  }
495  */
496  }
497  }
498  }
499  }
500 
501  fprintf(stderr," Reordering according to dependencies...\n");
502  do
503  {
504  swapping=0;
505  prevPtr2=0;
506  for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
507  {
508  for(pp=libmapPtr->uses;*pp;pp++)
509  {
510  prevPtr1=0;
511  for(libmapPtr1=libmap;libmapPtr1!=libmapPtr;
512  libmapPtr1=libmapPtr1->next)
513  {
514  if(strcmp(libmapPtr1->lib,*pp)==0)
515  {
516  /* Check that 1st doesn't use 2nd... */
517  for(pp1=libmapPtr1->uses;*pp1;pp1++)
518  {
519  if(strcmp(*pp1,libmapPtr->lib)==0)break;
520  }
521  if(!*pp1) /* If not... */
522  {
523  swapping=1;
524  /* Make previous of 1st now point to 2nd... */
525  if(prevPtr1)
526  {
527  prevPtr1->next=libmapPtr;
528  }
529  else
530  {
531  libmap=libmapPtr;
532  }
533  /* Make 2nd now point to what 1st did, unless
534  it's adjacent, in which case make it point
535  to 1st itself... */
536  tmpp=libmapPtr->next;
537  if(libmapPtr1->next==libmapPtr)
538  {
539  libmapPtr->next=libmapPtr1;
540  }
541  else
542  {
543  libmapPtr->next=libmapPtr1->next;
544  }
545  /* Make previous of 2nd point to 1st, unless
546  it's adjacent, in which case leave it... */
547  if(libmapPtr1->next!=libmapPtr)
548  {
549  prevPtr2->next=libmapPtr1;
550  }
551  /* Make 1st now point to what 2nd did... */
552  libmapPtr1->next=tmpp;
553  break;
554  }
555  }
556  prevPtr1=libmapPtr1;
557  }
558  if(swapping)break;
559  }
560  prevPtr2=libmapPtr;
561  if(swapping)break;
562  }
563  }while(swapping);
564 
565  fprintf(stderr," Writing new library map file...\n");
566  for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
567  {
568  printf("%s:",libmapPtr->lib);
569  for(pp=libmapPtr->uses;*pp;pp++)
570  {
571  printf(" %s",*pp);
572  }
573  printf("\n");
574  printf("source/%s/GNUmakefile\n",libmapPtr->trigger);
575  }
576  }
577  else if (optm)
578  {
579  /* create tmp. string libname */
580  int libname_usable_size=24;
581  if ( ! libname ) libname=malloc(libname_usable_size+16);
582 
583  /* Write out full library list... */
584  for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
585  {
586  if ( strlen(libpath)+strlen(libmapPtr->lib) > libname_usable_size ) {
587  libname_usable_size=(strlen(libpath)+strlen(libmapPtr->lib))*2;
588  free(libname);
589  libname=malloc(libname_usable_size+16);
590  }
591  /* Check existance of libraries and print out only installed ones */
592 
593 
594  sprintf(libname, "%s/lib%s.a", libpath, libmapPtr->lib);
595  if (access(libname,R_OK))
596  {
597  sprintf(libname, "%s/lib%s.so", libpath, libmapPtr->lib);
598  if (!access(libname,R_OK))
599  {
600  printf("-l%s ",libmapPtr->lib);
601  }
602  else /* case MacOS .dylib */
603  {
604  sprintf(libname, "%s/lib%s.dylib", libpath, libmapPtr->lib);
605  if (!access(libname,R_OK))
606  {
607  printf("-l%s ",libmapPtr->lib);
608  }
609  }
610  }
611  else
612  {
613  printf("-l%s ",libmapPtr->lib);
614  }
615  libmapPtr=libmapPtr->next;
616  }
617  }
618  else
619  {
620  /* Add dependent libraries... */
621  for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
622  {
623  if(libmapPtr->used)
624  {
625  for(pp=libmapPtr->uses;*pp;pp++)
626  {
627  for(libmapPtr1=libmap;libmapPtr1;libmapPtr1=libmapPtr1->next)
628  {
629  if(strcmp(libmapPtr1->lib,*pp)==0)
630  {
631  libmapPtr1->used=1;
632  }
633  }
634  }
635  }
636  }
637 
638  /* Write out library list... */
639  for(libmapPtr=libmap;libmapPtr;libmapPtr=libmapPtr->next)
640  {
641  if(libmapPtr->used)
642  {
643  printf("-l%s ",libmapPtr->lib);
644  }
645  }
646  }
647 
648  exit(0);
649 
650 }
int optind
void * calloc(size_t __nmemb, size_t __size)
Definition: hjmalloc.cc:67
void free(void *__ptr)
Definition: hjmalloc.cc:140
const char * p
Definition: xmltok.h:285
#define buffer
Definition: xmlparse.cc:611
#define TRIGSIZE
Definition: liblist.c:42
#define NLIBMAX
Definition: liblist.c:43
#define bufferPtr
Definition: xmlparse.cc:612
char * optarg
char ** parsedir(char *directory, int *argc)
Definition: liblist.c:48
void * malloc(size_t __size)
Definition: hjmalloc.cc:30
#define BUFSIZE
Definition: liblist.c:41
char** parsedir ( char *  directory,
int argc 
)

Definition at line 48 of file liblist.c.

References buffer, free(), and malloc().

Referenced by main().

49 {
50  DIR *actualdir;
51  FILE *actualfile;
52  struct dirent *entry;
53  char *buffer=0;
54  struct stat status;
55  char **targv=0,**ptr,**phelp;
56  int len,targc,s;
57 
58  /*Open the actual directory*/
59  actualdir=opendir(directory);
60 
61  if(!actualdir) return targv;
62 
63  /*Loop over all entries */
64  for(entry=readdir(actualdir);entry!=NULL;entry=readdir(actualdir))
65  {
66  /* Throw away . and .. */
67  if(strcmp(entry->d_name,".")==0 ||
68  strcmp(entry->d_name,"..")==0) continue;
69  /* Obtain the status information of that entry */
70  if(buffer) free(buffer);
71  buffer=(char*) malloc((strlen(directory)+
72  strlen(entry->d_name)+2)*sizeof(char));
73  strcpy(buffer,directory);
74  strncat(buffer,"/",1);
75  strncat(buffer,entry->d_name,strlen(entry->d_name));
76  s=stat(buffer,&status);
77  if(s==0)
78  {
79  if(S_ISDIR(status.st_mode))
80  {
81  /* a directory, so we are going recursive*/
82  targc=0;
83  ptr=parsedir(buffer,&targc);
84  if(targc)
85  {
86  phelp=targv;
87  targv=(char**) malloc((*argc+targc)*sizeof(char*));
88  memcpy(targv,phelp,*argc*sizeof(char*));
89  memcpy(&targv[*argc],ptr,targc*sizeof(char*));
90  *argc+=targc;
91  free(phelp);
92  free(ptr);
93  }
94  }
95  else if(S_ISREG(status.st_mode))
96  {
97  /* a regular file is it .d? */
98  len=strlen(entry->d_name);
99  if(entry->d_name[len-2]=='.' && entry->d_name[len-1]=='d')
100  {
101  phelp=targv;
102  targv=(char**) malloc((*argc+1)*sizeof(char*));
103  memcpy(targv,phelp,*argc*sizeof(char*));
104  targv[*argc]=strdup(buffer);
105  (*argc)++;
106  free(phelp);
107  }
108  }
109  }
110  else
111  {
112  fprintf
113  (stderr,
114  " No status - perhaps file %s does not exist.\n",
115  directory);
116  exit(1);
117  }
118  }
119 
120  if(buffer) free(buffer);
121  closedir(actualdir);
122 
123  return targv;
124 }
const XML_Char * s
void free(void *__ptr)
Definition: hjmalloc.cc:140
#define buffer
Definition: xmlparse.cc:611
int status
Definition: tracer.cxx:24
const XML_Char int len
char ** parsedir(char *directory, int *argc)
Definition: liblist.c:48
void * malloc(size_t __size)
Definition: hjmalloc.cc:30

Variable Documentation

char* optarg

Referenced by main().

int opterr
int optind

Referenced by main().

int optopt

Referenced by main().