new version of tcoffee 8.99 not yet compiled for ia32 linux (currently compiled for...
[jabaws.git] / binaries / src / tcoffee / t_coffee_source / util.c
1 // DIR_4_TCOFFEE [def: ~/.t_coffee]: UNIQUE_DIR_4_TCOFFEE -> DIR_4_TCOFFEE ->HOME/.t_coffee
2 //TMP_4_TCOFFEE [def: ~/.t_coffee/tmp]:: UNIQUE_DIR_4_TCOFFEE -> TMP_4_TCOFFEE ->DIR_4_TCOFFEE/tmp
3
4 #define FILE_CHECK 1
5 #include <stddef.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <ctype.h>
9 #include <string.h>
10 #include <limits.h>
11 #include <float.h>
12 #include <math.h>
13 #include <stdarg.h>
14 #include <fcntl.h>
15 #include <sys/file.h>
16
17
18 #include "io_lib_header.h"
19 #include "util_lib_header.h"
20 #include "define_header.h"
21 #include "perl_header_lib.h"
22
23 //defined this way because all compilers cannot pas ap
24 //safe printf: it declares buf to the proper size
25 #define cvsprintf(buf,string)\
26 if(1)\
27   {                                             \
28     va_list ap;                                 \
29     int n;                                      \
30     char buf2[2];                               \
31     va_start (ap,string);                       \
32     n=vsnprintf (buf2,1, string, ap)+3;         \
33     va_end (ap);                                \
34     va_start (ap, string);                      \
35     buf=vcalloc (n, sizeof (char));             \
36     vsnprintf (buf, n,string, ap);              \
37     va_end(ap);}
38
39 int my_vsscanf(char *buf, char *fmt, va_list parms);
40 static int get_vtmpnam2_root();
41
42
43
44
45 static int global_exit_signal;
46 static int no_error_report;
47 static int clean_exit_started;
48 static int debug_lock;
49 static char *in_cl;
50 static char *logfile;
51 /*********************************************************************/
52 /*                                                                   */
53 /*                                  DICHOTOMY                        */
54 /*                                                                   */
55 /*                                                                   */
56 /*********************************************************************/
57 double dichotomy (double value, double target_value, double middle, double *bottom,double *top)
58 {
59   if ( value> target_value)top[0]=middle;
60   else if ( value<target_value)bottom[0]=middle;
61   return (top[0]-bottom[0])/2+bottom[0];
62 }
63
64
65 /*********************************************************************/
66 /*                                                                   */
67 /*                                   QSORT                           */
68 /*                                                                   */
69 /*                                                                   */
70 /*********************************************************************/
71
72 #define MAXSTACK (sizeof(size_t) * CHAR_BIT)
73 static void exchange(void *a, void *b, size_t size) {
74     size_t i;
75     int *ia;
76     int *ib;
77     char *ca;
78     char *cb;
79     
80     /******************
81      *  exchange a,b  *
82      ******************/
83     ia=(int*)a;
84     ib=(int*)b;
85     for (i = sizeof(int); i <= size; i += sizeof(int)) {
86         int t =ia[0];
87         ia[0]=ib[0];
88         ib[0]=t;
89         ia++; ib++;
90     
91     }
92     ca=(char*)ia;
93     cb=(char*)ib;
94     for (i = i - sizeof(int) + 1; i <= size; i++) {
95         
96         char t=ca[0];
97         ca[0]=cb[0];
98         cb[0]=t;
99         ca++;cb++;
100
101     }
102 }
103
104 #ifdef USE_QSORT
105 void qsort(void *base, size_t nmemb, size_t size,
106         int (*compar)(const void *, const void *)) {
107     void *lbStack[MAXSTACK], *ubStack[MAXSTACK];
108     int sp;
109     unsigned int offset;
110
111     /********************
112      *  ANSI-C qsort()  *
113      ********************/
114
115     lbStack[0] = (char *)base;
116     ubStack[0] = (char *)base + (nmemb-1)*size;
117     for (sp = 0; sp >= 0; sp--) {
118         char *lb, *ub, *m;
119         char *P, *i, *j;
120
121         lb = lbStack[sp];
122         ub = ubStack[sp];
123
124         while (lb < ub) {
125
126             /* select pivot and exchange with 1st element */
127             offset = (ub - lb) >> 1;
128             P = lb + offset - offset % size;
129             exchange (lb, P, size);
130
131             /* partition into two segments */
132             i = lb + size;
133             j = ub;
134             while (1) {
135                 while (i < j && compar(lb, i) > 0) i += size;
136                 while (j >= i && compar(j, lb) > 0) j -= size;
137                 if (i >= j) break;
138                 exchange (i, j, size);
139                 j -= size;
140                 i += size;
141             }
142
143             /* pivot belongs in A[j] */
144             exchange (lb, j, size);
145             m = j;
146
147             /* keep processing smallest segment, and stack largest */
148             if (m - lb <= ub - m) {
149                 if (m + size < ub) {
150                     lbStack[sp] = m + size;
151                     ubStack[sp++] = ub;
152                 }
153                 ub = m - size;
154             } else {
155                 if (m - size > lb) {
156                     lbStack[sp] = lb; 
157                     ubStack[sp++] = m - size;
158                 }
159                 lb = m + size;
160             }
161         }
162     }
163 }
164 #endif
165 int pstrcmp(char *p1, char *p2);
166
167
168
169 /*********************************************************************/
170 /*                                                                   */
171 /*                                   HEAPSORT                           */
172 /*                                                                   */
173 /*                                                                   */
174 /*********************************************************************/
175 FILE * hsort_file ( FILE *fp,int n,int len, size_t size,int first_comp_field, int n_comp_fields,int (*compare)(const void *, const void*,int, int, size_t),void * (*copy)(void *,void*, size_t))
176      {
177      unsigned long i, ir, j, l;
178      void *rra, *rrb, *ra_j, *ra_j_1;
179      void *tp;
180      long  start;
181      int FE=1;
182      
183     
184     
185      start=ftell(fp);
186      rra   =vcalloc ( len, size);
187      rrb   =vcalloc ( len, size);
188      ra_j  =vcalloc ( len, size);
189      ra_j_1=vcalloc ( len, size);
190
191      if ( n<2)return fp;
192      l=(n >>1)+1;
193      ir=n;
194
195      for (;;)
196          {
197          if ( l>FE)
198             {
199             l--;
200             fseek( fp, start+(((l-1)*len)*size), SEEK_SET);
201             fread( rra, size, len,fp); /*rra=ra[--l]*/
202             }
203          else
204             {
205             fseek( fp, start+((ir-1)*len*size), SEEK_SET);
206             fread( rra, size, len,fp); /*rra=ra[ir]*/
207             
208             fseek( fp, start, SEEK_SET);
209             fread( rrb, size, len,fp); /*rrb=ra[0]*/
210             
211             fseek( fp, start+((ir-1)*len*size), SEEK_SET);
212             fwrite(rrb,size, len, fp); /*ra[ir]=rrb=ra[0]*/ 
213
214             if (--ir ==FE)
215                {
216                fseek ( fp,start, SEEK_SET);
217                fwrite(rra,size, len, fp); /*ra[0]=rra*/ 
218                break;
219                }
220             }         
221          i=l;
222          j=l+l;
223          while ( j<=ir)
224                {
225                fseek ( fp, start+((j-1)*len*size), SEEK_SET);
226                fread (ra_j, size, len, fp);
227                
228                if ( j<ir)
229                   {
230                   fseek ( fp, start+(((j-1)+1)*len*size), SEEK_SET);
231                   fread (ra_j_1, size, len, fp);
232                   }
233
234                if ( j<ir && compare( ra_j, ra_j_1,first_comp_field,n_comp_fields, size )<0)
235                    {
236                    SWAPP(ra_j, ra_j_1, tp);
237                    j++;
238                    }
239
240                if (compare(rra, ra_j, first_comp_field,n_comp_fields, size)<0)
241                        {
242                        fseek ( fp, start+((i-1)*len*size), SEEK_SET);
243                        fwrite(ra_j,size, len, fp);
244                        i=j;
245                        j<<= 1;
246                        }
247                else
248                        j=ir+1;
249                
250                }
251          fseek ( fp, start+((i-1)*len*size), SEEK_SET);
252          fwrite(rra,size, len, fp);     
253          }
254      vfree (  rra);
255      vfree ( rrb);
256
257      vfree (  ra_j);
258      vfree (  ra_j_1);
259      return fp;
260      }
261 void ** hsort_array ( void **ra,int n,int len, size_t size,int first_comp_field, int n_comp_fields,int (*compare)(const void *, const void*,int, int, size_t),void * (*copy)(void *,void*, size_t))
262      {
263      unsigned long i, ir, j, l;
264      void *rra;
265      int FE=1;
266      
267      if ( FE==1){ra--;}
268      else
269      {
270      n--;
271      }
272
273      
274      rra   =vcalloc ( len, size);
275     
276      
277      if ( n<2)return ra;
278      l=(n >>1)+1;
279      ir=n;
280
281      for (;;)
282          {
283          if ( l>FE)
284             {
285             copy ( rra, ra[--l],len);
286             }
287          else
288             {      
289             copy ( rra, ra[ir],len);
290             copy ( ra[ir], ra[FE], len);
291             if (--ir ==FE)
292                {
293                copy ( ra[FE],rra,len);
294                break;
295                }
296             }
297          i=l;
298          j=l+l;
299          while ( j<=ir)
300                {               
301                if ( j<ir && compare( ra[j], ra[j+1],first_comp_field,n_comp_fields, size )<0)j++;
302                if (compare(rra, ra[j], first_comp_field,n_comp_fields, size)<0)
303                        {copy(ra[i], ra[j],len);i=j;j<<= 1;}
304                else
305                        j=ir+1;         
306                }
307          copy( ra[i], rra,len);  
308          }
309      vfree (rra);
310      ra+=FE;
311      
312      return ra;
313      }
314 /*********************************************************************/
315 /*                                                                   */
316 /*                         CEDRIC BSEARCH                            */
317 /*                                                                   */
318 /*                                                                   */
319 /*********************************************************************/
320 void * bsearch_file ( const void *key,int *p,int comp_first,int comp_len, FILE *fp,int len, int entry_len,size_t el_size, int (*compare)(const void *, const void*,int, int, size_t))
321        {
322        int upper, lower, c, i;
323        static void *key2;
324        long start;
325        static long key2_size;
326
327
328        start=ftell(fp);
329
330        upper=-1;
331        lower=len;
332        if ( key2==NULL){key2=vcalloc (entry_len, el_size);key2_size=entry_len* el_size;}
333        else if (key2_size<  (entry_len* el_size)){vfree(key2);key2=vcalloc (entry_len, el_size);key2_size=entry_len* el_size;} 
334
335        while ((lower-upper)>1)
336              {
337              i=(lower+upper) >> 1;
338
339              fseek ( fp,start+(i*el_size*entry_len), SEEK_SET); 
340              fread ( key2, el_size, entry_len,fp);           
341              c=compare(key2,key, comp_first, comp_len,el_size);
342              
343              if      ( c==0){p[0]=i;return key2;}
344              else if ( c< 0)upper=i;
345              else if ( c> 0)lower=i;
346              }
347        return NULL;
348        }
349
350 void * bsearch_array ( const void *key,int *p,int comp_first, int comp_len,void**list,int len, int entry_len,size_t el_size, int (*compare)(const void *, const void*,int, int, size_t))
351        {
352        int upper, lower, c, i;
353        void *key2;
354        
355        upper=-1;
356        lower=len;
357        while ((lower-upper)>1)
358              {
359              i=(lower+upper) >>1;
360              key2=list[i];           
361              c=compare(key2,key, comp_first,comp_len,el_size);
362              
363              if      ( c==0){p[0]=i;return key2;}
364              else if ( c< 0)upper=i;
365              else if ( c> 0)lower=i;
366              }
367        return NULL;
368        }                     
369                      
370 /**********************************************************************/
371 /*                                                                    */
372 /*                         HSORT/BSEARCH WRAPPERS                             */
373 /*                                                                    */
374 /*                                                                    */
375 /**********************************************************************/
376 void **search_in_list_file ( void *key, int *p,int comp_len,FILE *fp, int len, size_t size, int entry_len)  
377       {
378       static void **l;  
379       
380
381       if ( l==NULL)l=vcalloc ( 1, sizeof (int*));
382         
383       l[0]=bsearch_file (key,p,0,comp_len,fp,len,entry_len,size,hsort_cmp);  
384       if (l[0]==NULL)return NULL;
385       else return l;
386       }
387 void **search_in_list_array ( void *key,int *p, int comp_len,void **L, int len, size_t size, int entry_len)  
388       {
389       static void **l;
390  
391       if ( l==NULL)l=vcalloc ( 1, sizeof (int*));       
392       
393       l[0]=bsearch_array (key,p,0,comp_len,L,len,entry_len,size,hsort_cmp);  
394       if (l[0]==NULL)return NULL;
395       else return l;
396       }
397 void **hsort_list_array ( void **L, int len, size_t size, int entry_len, int first_comp_field, int n_comp_fields)  
398        {
399          return hsort_array (L, len,entry_len, size,first_comp_field, n_comp_fields,hsort_cmp , hsort_cpy);
400        }
401 FILE  *hsort_list_file ( FILE*fp  , int len, size_t size, int entry_len, int first_comp_field, int n_comp_fields)  
402        {
403
404        return hsort_file (fp, len,entry_len, size,first_comp_field, n_comp_fields,hsort_cmp , hsort_cpy);
405        }
406
407 int hsort_cmp ( const void *a, const void *b, int first, int clen, size_t size)
408        {
409        int*ax;
410        int*bx;
411        int p;
412        
413        ax=(int*)a;
414        bx=(int*)b;
415        for ( p=first; p<clen+first; p++)
416            {
417            if ( ax[p]<bx[p])return -1;
418            else if ( ax[p]==bx[p]);
419            else return 1;
420            }
421        return 0;
422        }
423 void *hsort_cpy(void*to, void *from, size_t size)
424        {
425        
426        int *ax;
427        int *bx;
428        int p;
429        ax=(int*)to;
430        bx=(int*)from;
431        for (p=0; p<(int)size; p++)
432            ax[p]=bx[p];
433        
434        
435        return to;
436       
437        }
438        
439        
440 void test_hsort_list_array()
441       {
442       int **array;
443       int a;
444       int n=100;
445
446       array=declare_int(n, 3);
447       for ( a=0; a<n; a++)array[a][0]=a;
448       
449       hsort_list_array( (void**)array,n, sizeof (int), 3, 0, 1);
450       for ( a=0; a<n; a++)fprintf ( stderr, "\n%d %d", array[a][0],a);
451       myexit(EXIT_FAILURE);
452       }
453       
454
455 /*********************************************************************/
456 /*                                                                   */
457 /*                         B_SEARCH_FILE FUNCTIONS                   */
458 /*                                                                   */
459 /*                                                                   */
460 /*********************************************************************/          
461
462 /*********************************************************************/
463 /*                                                                   */
464 /*                         SORT/COMPARE/SEARCH FUNCTIONS             */
465 /*                                                                   */
466 /*                                                                   */
467 /*********************************************************************/
468 static int sort_field;
469 int **search_in_list_int ( int *key, int k_len, int **list, int ne)
470         {
471         int **l;                
472         sort_field=k_len;       
473         l=bsearch (&key,list, ne, sizeof(int**),(int(*)(const void*,const void*))(cmp_list_int));  
474         return l;
475         }
476 void sort_float ( float **V,int N_F, int F, int left, int right)
477         {
478         sort_field=F;
479         qsort ( V, right+1, sizeof(int**),(int(*)(const void*,const void*))(cmp_int));
480         }
481 int cmp_float ( const float **a, const float **b)
482         {
483         if ( a[0][sort_field]< b[0][sort_field])return-1;
484         else if ( a[0][sort_field]==b[0][sort_field])return 0;
485         else return 1;
486         }
487
488 void sort_int_1D ( int *L, int n)
489         {
490         int **array;
491         int a;
492         
493         array=declare_int ( n, 1);
494         for ( a=0; a< n; a++)
495                 array[a][0]=L[a];
496         sort_int ( array, 1, 0, 0, n-1);
497         for ( a=0; a< n; a++)
498                 L[a]=array[a][0];
499         free_int ( array, n);
500         }
501
502 char** sort_string_array (char **V, int n)     
503 {
504   
505   
506   qsort ( V,n,sizeof (char*),(int(*)(const void*,const void*))(pstrcmp));
507   return V;
508
509  
510 }
511
512 int pstrcmp(char *p1, char *p2)
513 {
514   return strcmp(*(char **)p1, *(char **)p2);
515 }
516 void sort_int ( int **V,int N_F, int F, int left, int right)
517         {
518           if (!V)return;
519         sort_field=F;
520         qsort ( V, (right-left)+1, sizeof(int**),(int(*)(const void*,const void*))(cmp_int));
521         }
522 void sort_list_int ( int **V,int N_F, int F, int left, int right)
523         {
524         if (!V)return;
525         sort_field=F;
526         qsort ( V, (right-left)+1, sizeof(int**),(int(*)(const void*,const void*))(cmp_list_int));
527         }
528 static int *order;
529 void sort_list_int2 ( int **V,int *list,int N_F, int left, int right)
530         {
531           // just like sort_int_list, but uses list to to order the comparison of the keys
532           if (!V)return;
533         order=list;
534         
535         qsort ( V, (right-left)+1, sizeof(int**),(int(*)(const void*,const void*))(cmp_list_int2));
536         }
537 int cmp_list_int2 (const int**a, const int**b)
538         {
539           int p=0;;
540           int c,d;
541           
542           
543
544           while ((c=order[p])!=-1)
545           {
546             
547             if ( a[0][c]>b[0][c])return   1;
548             else if ( a[0][c]<b[0][c])return  -1;
549             p++;
550           }
551         return 0;
552         }
553 void sort_int_inv ( int **V,int N_F, int F, int left, int right)
554         {
555         int a,b;
556         int **list;
557         if (!V)return;
558         sort_field=F;
559         qsort ( V, (right-left)+1, sizeof(int**),(int(*)(const void*,const void*))(cmp_int));
560         
561         list=declare_int ((right-left)+1, N_F);
562         for ( a=left; a< (right-left)+1; a++)
563                 {
564                 for ( b=0; b< N_F; b++)
565                         {
566                         list[a-left][b]=V[a][b];
567                         }
568                 }
569         for ( a=left; a< (right-left)+1; a++)
570                 {
571                 for ( b=0; b< N_F; b++)
572                         V[a][b]=list[(right-left)-a][b];
573                 }
574         free_int (list, -1);
575         }
576         
577 void sort_list_int_inv ( int **V,int N_F, int F, int left, int right)
578         {
579         int a,b;
580         int **list;
581         if (!V)return;
582         sort_field=F;
583         qsort ( V, (right-left)+1, sizeof(int**),(int(*)(const void*,const void*))(cmp_list_int));
584         
585         list=declare_int ((right-left)+1, N_F); 
586         for ( a=left; a< (right-left)+1; a++)
587                 {
588                 for ( b=0; b< N_F; b++)
589                         {
590                         list[a-left][b]=V[a][b];
591                         }
592                 }
593         for ( a=left; a< (right-left)+1; a++)
594                 {
595                 for ( b=0; b< N_F; b++)
596                         V[a][b]=list[(right-left)-a][b];
597                 }
598         free_int (list, -1);
599         }       
600         
601
602
603 int cmp_int ( const int**a, const int**b)
604         {
605         if ( a[0][sort_field]< b[0][sort_field])return-1;
606         else if ( a[0][sort_field]==b[0][sort_field])return 0;
607         else return 1;
608         }
609 int cmp_list_int (const int**a, const int**b)
610         {
611         int c;
612         int undef=0;
613         int ret;
614         
615         for ( c=0; c<=sort_field; c++)
616                 {
617                 if ( a[0][c]==UNDEFINED|| b[0][c]==UNDEFINED)ret=0;
618                 else if ( a[0][c]>b[0][c])return   1;
619                 else if ( a[0][c]<b[0][c])return  -1;
620                 }
621         if (undef==sort_field)
622                 {
623                   if (a[0][0]==b[0][0])return 0;
624                 }
625         return 0;
626         }
627
628
629 int name_is_in_list ( char *name, char **name_list, int n_name, int len)
630         {
631         int a;
632         int pos=-1;
633         /*Note: RETURNS THE Offset of the LAST Occurence of name in name_list*/
634         
635         if ( name_list==NULL || name ==NULL)return -1;
636         
637
638         for ( a=0; a< n_name; a++)
639           {
640             if ( name_list[a]==NULL);
641             else if ( len!=-1)
642               {
643                 if (strncmp ( name, name_list[a], len)==0)pos=a;        
644               }
645             else if ( strm ( name, name_list[a]))pos=a;
646           }
647         return pos;
648         }
649 char * check_list_for_dup ( char **list, int ne)
650         {
651         int a, b;
652         
653         for ( a=0; a< ne-1; a++)
654             for ( b=a+1; b< ne; b++)if (strm ( list[a], list[b]))return list[a];
655         return NULL;
656         }
657 FILE *get_number_list_in_file ( FILE *fp, int *list, int *n, int *max_len)
658         {
659         
660         int c;
661         
662         while ( isspace((c=fgetc (fp))));
663         ungetc(c, fp);
664         while ( c!='\n')
665                 {
666                 while ( isspace((c=fgetc (fp))) && c!='\n');
667                 
668                 if ( c!='\n')
669                         {
670                         ungetc(c, fp);
671                         if ( n[0]>=max_len[0])
672                                 list=vrealloc ( list, (n[0]+100)*sizeof (int));
673                                 max_len[0]=(n[0]+100);
674                         
675                         fscanf ( fp, "%d",&list[n[0]++]);
676                         }
677                 }
678         return fp;
679         }
680 /*********************************************************************/
681 /*                                                                   */
682 /*                         QUANTILE                                  */
683 /*                                                                   */
684 /*                                                                   */
685 /*********************************************************************/
686 int quantile (int argc, char *argv[])
687 {
688   FILE *fp;
689   int a,n,c, t;
690   int **list; 
691   char ***  string_list;
692   char *name, s1[1000], s2[1000];
693
694
695   if ( argc<2)
696     {
697
698       fprintf (stderr, "\nquantile <fname> <quant: 0.00-1.00> [<top | bottom>]");
699       fprintf (stderr, "\nSplits your data in two according to the quantile");
700       fprintf (stderr, "\nReturns the top quantile or the bottom quantile");
701       fprintf (stderr, "\nData must be in <fname> with two fields/line: Field1=index, Field2=value\n");
702       fprintf (stderr, "\n1 27\n2 46\n3 5\n...\n");
703       fprintf (stderr, "\nValue can either be integer or float");
704       
705       
706       myexit (EXIT_FAILURE);
707     }
708   
709   if (strm (argv[1], "stdin"))
710     {
711       name=vtmpnam(NULL);
712       fp=vfopen (name, "w");
713       while ( (c=fgetc(stdin))!=EOF)
714         {
715           fprintf ( fp, "%c", c);
716         }
717       vfclose (fp);
718     }
719   else
720     name=argv[1];
721   
722   
723
724
725   n=count_n_line_in_file (name);
726   list=declare_int (n, 2);
727   string_list=declare_arrayN(3,sizeof (char), n, 2, 10);
728   
729   fp=vfopen (name, "r");
730   n=0;
731   while ( (c=fgetc (fp))!=EOF)
732     {
733       ungetc(c,fp);
734       fscanf ( fp, "%s %s\n", s1, s2);
735       list[n][0]=(int)(atof(s1)*1000);
736       list[n][1]=(int)(atof(s2)*1000);
737       list[n][2]=n;
738       
739       sprintf (string_list[n][0],"%s",s1);
740       sprintf (string_list[n][1],"%s",s2);
741
742       
743       n++;
744     }
745   sort_int_inv ( list,3, 1, 0, n-1);
746   t=quantile_rank ( list,1,n, atof (argv[2]));
747   if ( argc!=4 || (argc==4 && strm (argv[3], "bottom")))
748     {
749       for (a=t; a<n; a++)
750         fprintf ( stdout, "%s %s\n", string_list[list[a][2]][0], string_list[list[a][2]][1]); 
751     }
752   else
753     {
754       for ( a=0; a<t; a++)
755         fprintf ( stdout, "%s %s\n", string_list[list[a][2]][0], string_list[list[a][2]][1]);
756     }
757   
758   fprintf (stderr, "\nQuantile %.2f T= %d Out of N= %d entries\n", atof (argv[2]), t, n), 
759   free_int (list, -1);
760   return n;
761
762 }
763   
764 int quantile_rank (int **list,int field, int n, float p)
765 {
766   int nr;
767   
768   
769   if ( p==1) nr=0;
770   else if ( p==0) nr=n;
771   else
772     {
773       int a, b,j, *l;
774       double g, q, np, i_part;
775       l=vcalloc ( n, sizeof (int));
776       for (a=n-1, b=0; b<n; a--, b++)
777         l[b]=list[a][field];
778             
779       np=(double)n*(double)p;
780       g=modf (np, &i_part);
781       j=(int)i_part;
782       j--;
783       
784       q=(float)l[j]+g*((float)l[j+1]-(float)l[j]);
785       
786       nr=0;
787       while (nr<n && list[nr][field]>=q)nr++;
788       vfree(l);
789     }
790   return nr;
791 }
792 /*********************************************************************/
793 /*                                                                   */
794 /*                         DUPLICATION                               */
795 /*                                                                   */
796 /*                                                                   */
797 /*********************************************************************/
798 short* ga_memcpy_short ( short *array1, short *array2, int n)
799         {
800         int a;
801         
802         for ( a=0; a< n; a++)
803                 array2[a]=array1[a];
804         
805         return array2;
806         }
807 int * ga_memcpy_int ( int *array1, int *array2, int n)
808         {
809         int a;
810         
811         for ( a=0; a< n; a++)
812                 array2[a]=array1[a];
813         
814         return array2;
815         }                       
816                         
817 float* ga_memcpy_float ( float *array1, float *array2, int n)
818         {
819         int a;
820         
821         for ( a=0; a< n; a++)
822                 array2[a]=array1[a];
823         
824         return array2;
825         }
826 double*  ga_memcpy_double (double *array1, double*array2, int n)
827         {
828         int a;
829         
830         for ( a=0; a< n; a++)
831                 array2[a]=array1[a];
832         
833         return array2;
834         }
835
836
837
838 /*recycle: get the bottom pointer on the top of the heap*/
839
840 void ** recycle (void **A, int l, int cycle)
841 {
842   void **B;
843   int a,b,c;
844   B=vcalloc (l, sizeof (void*));
845  
846   for ( c=0; c< cycle; c++)
847     {
848       for ( a=1, b=0; a<l; a++, b++) B[b]=A[a];
849       B[l-1]=A[0];
850       for ( a=0; a<l; a++)A[a]=B[a];
851     }
852   vfree (B);
853   return A;
854
855
856 /* Old READ/WRITE ARRAY SIZE*/
857 /*
858 #define WRITE_SIZE(type,function)\
859 void function ( int x, type *array, int os)\
860      {\
861      int a,l;\
862      char buf[SIZE_OF_INT+1];\
863      array+=os*SIZE_OF_INT;\
864      for ( a=0;a<SIZE_OF_INT; a++)array[a]=0;\
865      sprintf ( buf, "%d", x);\
866      l=strlen (buf);\
867      array+=SIZE_OF_INT-l;\
868      for (a=0; a<l; a++)array[a]=(type)buf[a];\
869      }
870 WRITE_SIZE(short,write_size_short)
871 WRITE_SIZE(char,write_size_char)
872 WRITE_SIZE(int,write_size_int)
873 WRITE_SIZE(float,write_size_float)
874 WRITE_SIZE(double,write_size_double)
875
876 #define READ_ARRAY_SIZE(type, function)\
877 int function (type *array, int os)\
878     {\
879     int a, b;\
880     char buf[SIZE_OF_INT+1];\
881     a=b=0;\
882     array+=os*SIZE_OF_INT;\
883     while ( a!=SIZE_OF_INT && array[a]==0)a++;\
884     while ( a!=SIZE_OF_INT)buf[b++]=(char)array[a++];\
885     buf[b]='\0';\
886     return atoi(buf);\
887     }
888 READ_ARRAY_SIZE(short,read_size_short)
889 READ_ARRAY_SIZE(char,read_size_char)
890 READ_ARRAY_SIZE(int,read_size_int)
891 READ_ARRAY_SIZE(float,read_size_float)
892 READ_ARRAY_SIZE(double,read_size_double)
893 */
894 /*********************************************************************/
895 /*                                                                   */
896 /*                          DUPLICATION                              */
897 /*                                                                   */
898 /*                                                                   */
899 /*********************************************************************/
900
901 #define SET_NUMBERS(type,function)\
902 type * function(type *list,int n, ...)\
903      {\
904      type *buf;\
905      int  *index,i;\
906      va_list ap;\
907      int max;\
908 \
909      va_start(ap, n);\
910      buf=vcalloc(n, sizeof(type));\
911      index=vcalloc(n, sizeof(int));\
912      max=0;\
913      for ( i=0; i< n; i++)\
914          {\
915          buf[i]  =va_arg(ap,type);\
916          index[i]=va_arg(ap, int);\
917          if (index[i]>max)max=index[i];\
918          }\
919      va_end(ap);\
920      if (list==NULL)list=vcalloc ( max+1, sizeof (type));\
921      for ( i=0; i<n; i++)list[index[i]]=buf[i];\
922      vfree(buf);\
923      vfree(index);\
924      return list;\
925      }
926      /*SET_NUMBERS(short ,set_short)*/
927      /*SET_NUMBERS(char  ,set_char)*/
928 SET_NUMBERS(int   ,set_int)
929      /*SET_NUMBERS(float ,set_float)*/
930 SET_NUMBERS(double,set_double)
931
932 short ** duplicate_short ( short **array , int len, int field)
933     {
934     return copy_short (array ,declare_short ( len, field),  len, field);
935     }
936 int ** duplicate_int ( int **array , int len, int field)
937     {
938     return copy_int (array ,declare_int ( len, field),  len, field);
939     }
940 char ** duplicate_char ( char **array , int len, int field)
941     {
942     return copy_char (array ,declare_char ( len, field),  len, field);
943     }
944 char * duplicate_string ( char *string)
945     {
946       int l;
947       char *buf=NULL;
948       
949       l=strlen (string);
950       
951       if ( !l);
952       else
953         {
954           buf=vcalloc ( l+1, sizeof(char));
955           sprintf ( buf, "%s", string);
956         }
957       return buf;
958     }
959 float ** duplicate_float ( float **array , int len, int field)
960     {
961     return copy_float (array ,declare_float ( len, field),  len, field);
962     }
963 double ** duplicate_double ( double **array , int len, int field)
964     {
965     return copy_double (array ,declare_double ( len, field),  len, field);
966     }
967
968
969
970 /*********************************************************************/
971 /*                                                                   */
972 /*                           COPY OF 2D ARRAY                        */
973 /*                                                                   */
974 /*                                                                   */
975 /*********************************************************************/
976 short ** copy_short( short **array1, short  **array2, int len, int number_field)
977     {
978     int a;
979     
980     if ( len==-1)len=read_array_size (array1,sizeof (short*));
981     if ( number_field==-1)number_field=read_array_size (array1[0],sizeof (short));
982     if ( array2)free_short ( array2, -1);
983     array2=declare_short ( len, number_field);
984
985     for ( a=0; a< len; a++)
986         ga_memcpy_short( array1[a],array2[a],number_field);
987     
988     return array2;
989     }
990 char ** copy_char ( char **array1, char **array2, int len, int number_field)
991     {
992     int a;
993     
994     if ( array1==NULL)return NULL;
995     if ( len==-1)len=read_size_char (array1,sizeof (char*));
996     if ( number_field==-1)
997         {
998         number_field=read_size_char (array1[0],sizeof(char));
999         for ( a=0; a< len; a++)
1000             number_field=MAX(number_field, strlen ( array1[a]))+1;
1001         }
1002     
1003     if ( array2)free_char (array2, -1);
1004     array2=declare_char(len, number_field);
1005     
1006     for ( a=0; a< len; a++)
1007       sprintf ( array2[a], "%s", array1[a]);
1008
1009     return array2;
1010     } 
1011 int ** copy_int ( int **array1, int **array2, int len, int number_field)
1012     {
1013     int a;
1014     
1015     if ( array1==NULL) return NULL;
1016     if ( len==-1)len=read_size_int (array1, sizeof (int*));
1017     if ( number_field==-1)number_field=read_size_int (array1[0],sizeof (int));
1018     
1019     
1020     
1021     if (array2)free_int (array2, -1);
1022     array2=declare_int ( len, number_field);
1023
1024     for ( a=0; a< len; a++)
1025         ga_memcpy_int( array1[a],array2[a],number_field);
1026     
1027     return array2;
1028     }
1029
1030 float ** copy_float ( float **array1, float **array2, int len, int number_field)
1031     {
1032     int a;
1033     
1034     if ( array1==NULL) return NULL;
1035     if ( len==-1)len=read_size_float (array1,sizeof (float*));
1036     if ( number_field==-1)number_field=read_size_float (array1[0],sizeof (float));
1037
1038     if ( array2)free_float (array2, -1);
1039     array2=declare_float ( len, number_field);
1040     
1041     for ( a=0; a< len; a++)
1042         ga_memcpy_float( array1[a],array2[a],number_field);
1043     return array2;
1044     }
1045 double ** copy_double (double **array1, double **array2, int len, int number_field)
1046     {
1047     int a;
1048
1049     if ( array1==NULL) return NULL;
1050     if ( len==-1)len=read_size_double (array1,sizeof (double*));
1051     if ( number_field==-1)number_field=read_size_double (array1[0], sizeof (double));
1052     if ( array2)free_double (array2, -1);
1053     array2=declare_double ( len, number_field);
1054
1055     for ( a=0; a< len; a++)
1056         ga_memcpy_double( array1[a],array2[a],number_field);
1057     return array2;
1058     }
1059 /*********************************************************************/
1060 /*                                                                   */
1061 /*                        CONCATENATION                              */
1062 /*                                                                   */
1063 /*                                                                   */
1064 /*********************************************************************/
1065
1066
1067
1068
1069
1070 Alignment ** cat_aln_list ( Alignment **list_to_cat,int first, int end, Alignment **rec_list)
1071     {
1072     int rec_list_start;
1073     int a, b;
1074
1075     if ( list_to_cat==NULL)return rec_list;
1076     else
1077        {
1078        rec_list_start=(rec_list[-1])->nseq;       
1079        rec_list=realloc_aln_array ( rec_list, end-first);      
1080        for ( a=first, b=rec_list_start; a<end; a++, b++)copy_aln (list_to_cat[a], rec_list[b]);      
1081        free_aln_array ( list_to_cat);      
1082        return rec_list;
1083        }
1084     }
1085            
1086 /*********************************************************************/
1087 /*                                                                   */
1088 /*                         NUMBER ARRAY ANALYSE                      */
1089 /*                                                                   */
1090 /*                                                                   */
1091 /*********************************************************************/
1092
1093 int output_array_int (char* fname, int  **array)
1094      {
1095      int a, b;
1096      int len,nf;
1097      FILE *fp;
1098
1099      fp=vfopen (fname, "w");
1100      len=read_array_size_new (array);
1101      fprintf (fp, "%d\n",len);
1102      for ( a=0; a<len; a++)
1103        {
1104          nf=read_array_size_new(array[a]);
1105          fprintf (fp, "%d ",nf);
1106          for (b=0; b<nf; b++)fprintf (fp, "%5d ", array[a][b]);
1107          fprintf (fp, "\n");
1108        }
1109      fprintf ( fp, "\n");
1110      vfclose (fp);
1111      return EXIT_SUCCESS;
1112      }
1113
1114 int **input_array_int (char *fname)
1115 {
1116   FILE *fp;
1117   int **array;
1118   int len,len2,a,b;
1119
1120   fp=vfopen (fname, "r");
1121   fscanf (fp, "%d\n", &len);
1122   array=vcalloc (len, sizeof (int*));
1123   for (a=0; a<len; a++)
1124     {
1125       fscanf(fp, "%d ", &len2);
1126       array[a]=vcalloc (len2, sizeof (int));
1127       for (b=0; b<len2; b++)
1128         fscanf(fp, "%d ", &array[a][b]);
1129       fscanf (fp, "\n");
1130     }
1131   vfclose (fp);
1132   return array;
1133 }
1134
1135
1136 #define RETURN_MAX_COOR(type,wf,rf,function,comparison,undef)\
1137 type function ( type ** array, int len_array, int field, int *coor)\
1138     {\
1139     type max;\
1140     int a;\
1141 \
1142     if (array==NULL || len_array==0)return 0;\
1143     else\
1144         {\
1145         len_array=rf(array,sizeof (type*));\
1146         max=array[0][field];\
1147         coor[0]=0;\
1148         for ( a=1; a< len_array; a++)\
1149               if ( max==undef)max=array[a][field];\
1150               else if ( array[a][field]!=undef)\
1151                    if (array[a][field] comparison max)\
1152                        {max=array[a][field];\
1153                         coor[0]=a;\
1154                         }\
1155          }\
1156     return max;\
1157     }
1158
1159 RETURN_MAX_COOR(short,write_size_short,read_size_short,return_max_coor_short,>, UNDEFINED_SHORT)
1160 RETURN_MAX_COOR(char,write_size_char,read_size_char,return_max_coor_char,>, UNDEFINED_CHAR)
1161 RETURN_MAX_COOR(int,write_size_int,read_size_int,return_max_coor_int,>, UNDEFINED_INT)
1162 RETURN_MAX_COOR(float,write_size_float,read_size_float,return_max_coor_float,>, UNDEFINED_FLOAT)
1163 RETURN_MAX_COOR(double,write_size_double,read_size_double,return_max_coor_double,>, UNDEFINED_DOUBLE)
1164 RETURN_MAX_COOR(short,write_size_short,read_size_short,return_min_coor_short,<, UNDEFINED_SHORT)
1165 RETURN_MAX_COOR(char,write_size_char,read_size_char,return_min_coor_char,<, UNDEFINED_CHAR)
1166 RETURN_MAX_COOR(int,write_size_int,read_size_int,return_min_coor_int,<, UNDEFINED_INT)
1167 RETURN_MAX_COOR(float,write_size_float,read_size_float,return_min_coor_float,<, UNDEFINED_FLOAT)
1168 RETURN_MAX_COOR(double,write_size_double,read_size_double,return_min_coor_double,<, UNDEFINED_DOUBLE)
1169 #define RETURN_MAX(type,wf,rf,function,comparison,undef)\
1170 type function ( type ** array, int len_array, int field)\
1171     {\
1172     type max;\
1173     int a;\
1174 \
1175     if (array==NULL || len_array==0)return 0;\
1176     else\
1177         {\
1178         if (len_array==-1)len_array=rf(array,sizeof (type*));\
1179         max=array[0][field];\
1180         for ( a=1; a< len_array; a++)\
1181             if ( max==undef)max=array[a][field];\
1182             else if ( array[a][field]!=undef)max=( array[a][field] comparison max)?array[a][field]:max;\
1183         }\
1184     return (max==undef)?0:max;\
1185     }
1186
1187 RETURN_MAX(short,write_size_short,read_size_short,return_max_short,>,UNDEFINED_SHORT)
1188 RETURN_MAX(char,write_size_char,read_size_char,return_max_char,>,UNDEFINED_CHAR)
1189 RETURN_MAX(int,write_size_int,read_size_int,return_max_int,>,UNDEFINED_INT)
1190 RETURN_MAX(float,write_size_float,read_size_float,return_max_float,>,UNDEFINED_FLOAT)
1191 RETURN_MAX(double,write_size_double,read_size_double,return_max_double,>,UNDEFINED_DOUBLE)
1192 RETURN_MAX(short,write_size_short,read_size_short,return_min_short,<,UNDEFINED_SHORT)
1193 RETURN_MAX(char,write_size_char,read_size_char,return_min_char,<,UNDEFINED_CHAR)
1194 RETURN_MAX(int,write_size_int,read_size_int,return_min_int,<,UNDEFINED_INT)
1195 RETURN_MAX(float,write_size_float,read_size_float,return_min_float,<,UNDEFINED_FLOAT)
1196 RETURN_MAX(double,write_size_double,read_size_double,return_min_double,<,UNDEFINED_DOUBLE)
1197
1198
1199
1200 #define RETURN_2DMAX(type,wf,rf,function,comparison,undef)\
1201 type function ( type ** array, int start, int len_array, int first_field, int number_field)\
1202     {\
1203     type max;\
1204     int a,b;\
1205     if (array==NULL || len_array==0 || first_field<0 || number_field==0)return 0;\
1206     else\
1207          {max=array[start][first_field];\
1208           for ( a=start; a< start+len_array; a++)\
1209               for (b=first_field; b< first_field+number_field; b++)\
1210                      if (array[a][b]!=undef)max=( array[a][b] comparison max)?array[a][b]:max;\
1211          }\
1212     return max;\
1213     }
1214 RETURN_2DMAX(short,write_size_short,read_size_short,return_2Dmax_short,>, UNDEFINED_SHORT)
1215 RETURN_2DMAX(char,write_size_char,read_size_char,return_2Dmax_char,>,UNDEFINED_CHAR)
1216 RETURN_2DMAX(int,write_size_int,read_size_int,return_2Dmax_int,>,UNDEFINED_INT)
1217 RETURN_2DMAX(float,write_size_float,read_size_float,return_2Dmax_float,>,UNDEFINED_FLOAT)
1218 RETURN_2DMAX(double,write_size_double,read_size_double,return_2Dmax_double,>,UNDEFINED_DOUBLE)
1219 RETURN_2DMAX(short,write_size_short,read_size_short,return_2Dmin_short,<,UNDEFINED_SHORT)
1220 RETURN_2DMAX(char,write_size_char,read_size_char,return_2Dmin_char,<,UNDEFINED_CHAR)
1221 RETURN_2DMAX(int,write_size_int,read_size_int,return_2Dmin_int,<,UNDEFINED_INT)
1222 RETURN_2DMAX(float,write_size_float,read_size_float,return_2Dmin_float,<,UNDEFINED_FLOAT)
1223 RETURN_2DMAX(double,write_size_double,read_size_double,return_2Dmin_double,<,UNDEFINED_DOUBLE)
1224
1225 #define RETURN_2DMAX_COOR(type,wf,rf,function,compare,undef)\
1226 type function ( type **array, int start1 , int end1, int start2, int end2,int *i, int *j)\
1227     {\
1228     int a, b;\
1229     double max=undef;\
1230     if ( start1==-1)start1=0;\
1231     if ( start2==-1)start2=0;\
1232     if ( end1==-1)end1=rf(array,sizeof (type*));\
1233     if ( end2==-1)end2=rf(array[0],sizeof (type));\
1234     if ( array==NULL || (end1-start1)==0 || (end1-start1)>rf ( array,sizeof (type*)) || (end2-start2)==0)\
1235         {\
1236         return 0;\
1237         i[0]=0;\
1238         j[0]=0;\
1239         }\
1240     i[0]=0;\
1241     j[0]=0;\
1242     for ( a=start1; a<end1; a++)\
1243         for ( b=start2; b<end2; b++)\
1244             {\
1245             if ( max==undef && array[a][b]!=undef)max=array[a][b];\
1246             else if ( array[a][b]!=undef && (array[a][b] compare max))\
1247                {\
1248                max=array[a][b];\
1249                i[0]=a;\
1250                j[0]=b;\
1251                }\
1252             }\
1253     return (type)max;\
1254     }
1255 RETURN_2DMAX_COOR(short,write_size_short,read_size_short,return_2Dmax_coor_short,>,UNDEFINED_SHORT)
1256 RETURN_2DMAX_COOR(char,write_size_char,read_size_char,return_2Dmax_coor_char,>,UNDEFINED_CHAR)
1257 RETURN_2DMAX_COOR(int,write_size_int,read_size_int,return_2Dmax_coor_int,>,UNDEFINED_INT)
1258 RETURN_2DMAX_COOR(float,write_size_float,read_size_float,return_2Dmax_coor_float,>,UNDEFINED_FLOAT)
1259 RETURN_2DMAX_COOR(double,write_size_double,read_size_double,return_2Dmax_coor_double,>,UNDEFINED_DOUBLE)
1260 RETURN_2DMAX_COOR(short,write_size_short,read_size_short,return_2Dmin_coor_short,<,UNDEFINED_SHORT)
1261 RETURN_2DMAX_COOR(char,write_size_char,read_size_char,return_2Dmin_coor_char,<,UNDEFINED_CHAR)
1262 RETURN_2DMAX_COOR(int,write_size_int,read_size_int,return_2Dmin_coor_int,<,UNDEFINED_INT)
1263 RETURN_2DMAX_COOR(float,write_size_float,read_size_float,return_2Dmin_coor_float,<,UNDEFINED_FLOAT)
1264 RETURN_2DMAX_COOR(double,write_size_double,read_size_double,return_2Dmin_coor_double,<,UNDEFINED_DOUBLE)
1265
1266 #define RETURN_WMEAN(type,wf,rf,function,sum_function,undef)\
1267 double function ( type **array, int len, int wfield,int sfield)\
1268     {\
1269     double b;\
1270     int a, c;\
1271     if ( len==0 ||array==NULL || len>rf ( array,sizeof (type*)))return 0;\
1272     else\
1273          {\
1274          if ( len==-1)len=rf(array,sizeof (type*));\
1275          for ( b=0, c=0,a=0; a< len; a++)\
1276              {\
1277              if (array[a][sfield]!=undef && array[a][wfield]!=undef )\
1278                 {\
1279                 b+=array[a][sfield];\
1280                 c+=array[a][wfield];\
1281                 }\
1282              }\
1283          }\
1284     return (c==0)?0:(b/c);\
1285     }
1286 RETURN_WMEAN(short,write_size_short,read_size_short,return_wmean_short, return_sum_short,UNDEFINED_SHORT)
1287 RETURN_WMEAN(char,write_size_char,read_size_char, return_wmean_char,return_sum_char,UNDEFINED_CHAR)
1288 RETURN_WMEAN(int,write_size_int,read_size_int,return_wmean_int,return_sum_int,UNDEFINED_INT)
1289 RETURN_WMEAN(float,write_size_float,read_size_float,return_wmean_float,return_sum_float,UNDEFINED_FLOAT)
1290 RETURN_WMEAN(double,write_size_double,read_size_double,return_wmean_double,return_sum_double,UNDEFINED_DOUBLE)
1291
1292                      
1293 #define RETURN_MEAN(type,wf,rf,function,sum_function,undef)\
1294 double function ( type **array, int len, int field)\
1295     {\
1296     double b;\
1297     int a, c;\
1298     if ( len==0 ||array==NULL || len>rf ( array,sizeof(type*)))return 0;\
1299     else\
1300          {\
1301          for ( b=0, c=0,a=0; a< len; a++)\
1302              {\
1303              if (array[a][field]!=undef)\
1304                 {\
1305                 b+=array[a][field];\
1306                 c++;\
1307                 }\
1308              }\
1309          }\
1310     return (c==0)?0:(b/c);\
1311     }
1312 RETURN_MEAN(short,write_size_short,read_size_short,return_mean_short, return_sum_short,UNDEFINED_SHORT)
1313 RETURN_MEAN(char,write_size_char,read_size_char, return_mean_char,return_sum_char,UNDEFINED_CHAR)
1314 RETURN_MEAN(int,write_size_int,read_size_int,return_mean_int,return_sum_int,UNDEFINED_INT)
1315 RETURN_MEAN(float,write_size_float,read_size_float,return_mean_float,return_sum_float,UNDEFINED_FLOAT)
1316 RETURN_MEAN(double,write_size_double,read_size_double,return_mean_double,return_sum_double,UNDEFINED_DOUBLE)
1317
1318 #define RETURN_SUM(type,wf,rf,function,undef)\
1319 type function(type **array, int len, int field)\
1320 {\
1321  int a;\
1322  type b=0;\
1323  if ( len==0 ||array==NULL)return 0;\
1324  else\
1325      {\
1326      if ( len==-1)len=rf ( array,sizeof (type*));\
1327      for ( a=0; a< len; a++)\
1328           if ( array[a][field]!=undef)b+=array[a][field];\
1329      }\
1330   return b;\
1331   }
1332 RETURN_SUM(short,write_size_short,read_size_short, return_sum_short,UNDEFINED_SHORT)
1333 RETURN_SUM(char,write_size_char,read_size_char,return_sum_char,UNDEFINED_CHAR)
1334 RETURN_SUM(int,write_size_int,read_size_int,return_sum_int,UNDEFINED_INT)
1335 RETURN_SUM(float,write_size_float,read_size_float,return_sum_float,UNDEFINED_FLOAT)
1336 RETURN_SUM(double,write_size_double,read_size_double,return_sum_double,UNDEFINED_DOUBLE)    
1337
1338 #define RETURN_SD(type,wf,rf,function,undef)\
1339   type function ( type **array, int len, int field,type mean)   \
1340     {\
1341     int a;\
1342     double c=0;\
1343     if ( len==0 ||array==NULL || len>rf ( array,sizeof(type*)))return 0;\
1344     else\
1345         {\
1346         for ( a=0; a< len; a++)\
1347             {\
1348             if ((array[a][field]!=undef) && (mean-array[a][field])!=0)\
1349              c+=((double)mean-array[a][field])*((double)mean-array[a][field]);\
1350             }\
1351         c=sqrt(c)/(double)len;\
1352         return (type)MAX(c,1);\
1353         }\
1354     }
1355 RETURN_SD(short,write_size_short,read_size_short, return_sd_short,UNDEFINED_SHORT)
1356 RETURN_SD(char,write_size_char,read_size_char,return_sd_char,UNDEFINED_CHAR)
1357 RETURN_SD(int,write_size_int,read_size_int,return_sd_int,UNDEFINED_INT)
1358 RETURN_SD(float,write_size_float,read_size_float,return_sd_float,UNDEFINED_FLOAT)
1359 RETURN_SD(double,write_size_double,read_size_double,return_sd_double,UNDEFINED_DOUBLE) 
1360 double return_z_score( double x,double sum, double sum2, double n)
1361     {
1362     double sd;
1363     double avg;
1364     double z;
1365     
1366    
1367     sd=(n==0)?0:sqrt(sum2*n -sum*sum)/n;
1368     avg=(n==0)?0:(sum/n);
1369     z=(sd==0)?0:(x-avg)/sd;
1370     return z;
1371     }
1372
1373 double* return_r (double **list, int n)
1374 {
1375    double Sy, Sx, Sxy, Sx2, Sy2,r_up, r_low, x, y;
1376    double *r;
1377    int a;
1378    
1379    r=vcalloc ( 3, sizeof (double));
1380    Sy=Sx=Sxy=Sx2=Sy2=0;
1381    
1382    for ( a=0; a<n; a++)
1383      {
1384        x=list[a][0];
1385        y=list[a][1];
1386        Sy+=y;
1387        Sx+=x;
1388        Sy2+=y*y;
1389        Sx2+=x*x;
1390        Sxy+=x*y;
1391      }
1392    r_up=n*Sxy-(Sx*Sy);
1393    r_low=(n*Sx2-(Sx*Sx))*(n*Sy2-(Sy*Sy));
1394    r_low=sqrt(r_low);
1395    r[0]=(r_low==0)?0:r_up/r_low;
1396    
1397    x=Sx/(double)n;
1398    y=Sy/(double)n;
1399    r_up=Sxy-(n*x*y);
1400    r_up*=r_up;
1401    r_low=(Sx2-n*x*x)*(Sy2-n*y*y);
1402    r[1]=(r_low==0)?0:r_up/r_low;
1403    r[2]=n;
1404    return r;
1405   }
1406
1407 #define INVERT_LIST(type,wf,rf,function,swap_function)\
1408 type* function (type *list, int len)\
1409     {\
1410     int a, b;\
1411     for ( a=0, b=len-1; a<b; a++, b--)swap_function ( &list[a], &list[b], 1);\
1412     return list;\
1413     }
1414 INVERT_LIST(short,write_size_short,read_size_short, invert_list_short,swap_short)
1415 INVERT_LIST(char,write_size_char,read_size_char,invert_list_char,swap_char)
1416 INVERT_LIST(int,write_size_int,read_size_int,invert_list_int,swap_int)
1417 INVERT_LIST(float,write_size_float,read_size_float,invert_list_float,swap_float)
1418 INVERT_LIST(double,write_size_double,read_size_double,invert_list_double,swap_double) 
1419
1420 #define SWAP_FUNCTION(type,wf,rf,function)\
1421 void function(type *a, type *b, int n)\
1422     {\
1423     type t;\
1424     int c;\
1425     for ( c=0;c<n;c++)\
1426         {t=a[c];\
1427          a[c]=b[c];\
1428          b[c]=t;\
1429         }\
1430     }
1431 SWAP_FUNCTION(short,write_size_short,read_size_short,swap_short)
1432 SWAP_FUNCTION(char,write_size_char,read_size_char,swap_char)
1433 SWAP_FUNCTION(int,write_size_int,read_size_int,swap_int)
1434 SWAP_FUNCTION(float,write_size_float,read_size_float,swap_float)
1435 SWAP_FUNCTION(double,write_size_double,read_size_double,swap_double) 
1436
1437 #define RETURN_MAX_HORIZ(type,wf,rf,function,comparison,undef)\
1438 type function  (type ** array, int len_array, int field)\
1439     {\
1440     type max;\
1441     int a;\
1442     if ( len_array==0)return 0;\
1443     else\
1444         {\
1445         max=array[field][0];\
1446         for ( a=1; a< len_array; a++)\
1447             if ( array[field][a]!=undef) max=( array[field][a] comparison max)?array[field][a]:max;\
1448         return (int)max;\
1449         }\
1450     }
1451 RETURN_MAX_HORIZ(short,write_size_short,read_size_short,return_max_short_hor,>,UNDEFINED_SHORT)
1452 RETURN_MAX_HORIZ(char,write_size_char,read_size_char,return_max_char_hor,>,UNDEFINED_CHAR)
1453 RETURN_MAX_HORIZ(int,write_size_int,read_size_int,return_max_int_hor,>,UNDEFINED_INT)
1454 RETURN_MAX_HORIZ(float,write_size_float,read_size_float,return_max_float_hor,>,UNDEFINED_FLOAT)
1455 RETURN_MAX_HORIZ(double,write_size_double,read_size_double,return_max_double_hor,>,UNDEFINED_DOUBLE) 
1456
1457 RETURN_MAX_HORIZ(short,write_size_short,read_size_short,return_min_short_hor,<,UNDEFINED_SHORT)
1458 RETURN_MAX_HORIZ(char,write_size_char,read_size_char,return_min_char_hor,<,UNDEFINED_CHAR)
1459 RETURN_MAX_HORIZ(int,write_size_int,read_size_int,return_min_int_hor,<,UNDEFINED_INT)
1460 RETURN_MAX_HORIZ(float,write_size_float,read_size_float,return_min_float_hor,<,UNDEFINED_FLOAT)
1461 RETURN_MAX_HORIZ(double,write_size_double,read_size_double,return_min_double_hor,<,UNDEFINED_DOUBLE) 
1462
1463   
1464
1465 #define BEST_OF_MANY(type,wf,rf,function,undef)\
1466 type function (int n, ...)\
1467         {\
1468         va_list ap;\
1469         int *fop,a;\
1470         type v, best;\
1471         int maximise;\
1472         /*first Arg: number of values\
1473           2nd   Arg: maximise(1)/minimise(0)\
1474           3rd   Arg: *int contains the indice of the best value\
1475           ...   Arg: n type values\
1476         */\
1477         va_start (ap, n);\
1478         maximise=va_arg (ap, int);\
1479         fop=va_arg (ap, int*);\
1480         best=va_arg (ap, type);\
1481         fop[0]=0;\
1482         for ( a=1; a<n; a++)\
1483                 {\
1484                 v=va_arg (ap, type);\
1485                 if (best==undef)\
1486                         {\
1487                         best=v;\
1488                         fop[0]=a;\
1489                         }\
1490                 if ( best==undef || v==undef);\
1491                 else if ( maximise==1 && v>best)\
1492                         {\
1493                         fop[0]=a;\
1494                         best=v;\
1495                         }\
1496                 else if ( maximise==0 && v<best)\
1497                         {\
1498                         fop[0]=a;\
1499                         best=v;\
1500                         }\
1501                 }\
1502         va_end (ap);\
1503         return best;\
1504         }
1505      /*BEST_OF_MANY(short,write_size_short,read_size_short, best_short,UNDEFINED_SHORT)*/
1506      /*BEST_OF_MANY(char,write_size_char,read_size_char,best_char,UNDEFINED_CHAR)*/
1507 BEST_OF_MANY(int,write_size_int,read_size_int,best_int,UNDEFINED_INT)
1508      /*BEST_OF_MANY(float,write_size_float,read_size_float,best_float,UNDEFINED_FLOAT)*/
1509 BEST_OF_MANY(double,write_size_double,read_size_double,best_double,UNDEFINED_DOUBLE)
1510 #define IS_DEFINED(type,function,undef)\
1511 int function(int n, ...)\
1512      {\
1513      int i;\
1514      va_list ap;\
1515 \
1516      va_start(ap, n);\
1517      for ( i=0; i< n; i++)\
1518          {\
1519          if(va_arg(ap,type)==undef)\
1520               {\
1521                 va_end(ap);\
1522                 return 0;\
1523               }\
1524          }\
1525      va_end(ap);\
1526      return 1;\
1527      }  
1528      /*IS_DEFINED(short,is_defined_short,UNDEFINED_SHORT)*/
1529      /*IS_DEFINED(char,is_defined_char,  UNDEFINED_CHAR)*/
1530 IS_DEFINED(int,is_defined_int,   UNDEFINED_INT)
1531      /*IS_DEFINED(float,is_defined_float, UNDEFINED_FLOAT)*/
1532 IS_DEFINED(double,is_defined_double,UNDEFINED_DOUBLE)
1533   
1534   int return_maxlen ( char ** array, int number)
1535     {
1536     int a;
1537     int max=0;
1538     for ( a=0; a< number; a++)
1539         max=( strlen ( array[a])>max)?strlen ( array[a]):max;
1540
1541     return max;
1542     }
1543
1544
1545 int return_minlen ( char ** array, int number)
1546     {
1547     int a;
1548     int min;
1549
1550     min=strlen( array[0]);
1551     for ( a=1; a< number; a++)
1552         min=( strlen ( array[a])>min)?strlen ( array[a]):min;
1553
1554     return min;
1555     }
1556  
1557
1558
1559 float return_mean_diff_float ( float **array, int len, int field,float mean)
1560     {
1561     int a;
1562     float b=0;
1563     
1564     for ( a=0; a< len; a++)
1565         {
1566         if ( (mean-array[a][field])!=0) 
1567                 b+=sqrt((double)((float) ( mean-array[a][field])*(float)(mean-array[a][field])));
1568         }
1569         
1570     return ((float)b/(float)len);
1571     }
1572
1573
1574
1575 void inverse_int ( int**array, int len, int field, int max, int min)
1576     {
1577     int a;
1578     for ( a=0; a< len; a++)
1579         array[a][field]=max-array[a][field]+min;
1580     }
1581 void inverse_float ( float**array, int len, int field, int max, int min)
1582     {
1583     int a;
1584     for ( a=0; a< len; a++)
1585         array[a][field]=max-array[a][field]+min;
1586     }
1587 void inverse_2D_float ( float **array, int start, int len, int start_field, int number_field, float max,float min)
1588     {
1589     int a, b;
1590     for ( a=0; a< start+len; a++)
1591         for ( b=start_field; b< start_field+ number_field; b++)
1592             array[a][b]=max-array[a][b]+min;
1593     }
1594
1595 int max_int (int*i, ...)
1596
1597   va_list ap;                                   \
1598   int index, best_value=0, value;
1599   int a=0;
1600  //  expects n values : n, &index, i1, v1, i2, v2...., -1
1601      va_start(ap, i);
1602      while ((index=va_arg(ap,int))!=-1)
1603        {
1604          value=va_arg(ap, int);
1605          if ( a==0 || value>best_value)
1606            {
1607              i[0]=index;
1608              best_value=value;
1609              a=1;
1610            }
1611        }
1612      va_end (ap);
1613      return best_value;
1614 }
1615   
1616 /*********************************************************************/
1617 /*                                                                   */
1618 /*                         SHELL INTERFACES                          */
1619 /*                                                                   */
1620 /*                                                                   */
1621 /*********************************************************************/
1622 char* getenv4debug (const char * val)
1623 {
1624   /*efficient mean of getting an environment variable: checks only if one DEBUG is on*/
1625   static int check;
1626   
1627   if ( !check)
1628     {
1629       
1630       if (getenv       ("DEBUG_BLAST"))check=1;      
1631       else if ( getenv ("DEBUG_TREE_COMPARE"))check=1;
1632       else if ( getenv ("DEBUG_MALN"))check=1;
1633       else if ( getenv ("DEBUG_EXTRACT_FROM_PDB"))check=1;
1634       else if ( getenv ("DEBUG_LIBRARY"))check=1;
1635       else if ( getenv ("DEBUG_FUGUE"))check=1;
1636       
1637       else if ( getenv ("DEBUG_REFORMAT"))check=1;
1638       else if ( getenv ("DEBUG_RECONCILIATION"))check=1;
1639       else if ( getenv ("DEBUG_TMP_FILE"))check=1;
1640       else if ( getenv ("DEBUG_TREE"))check=1;
1641       
1642      else if ( getenv ("DEBUG_SEQ_REFORMAT") && strm (PROGRAM, "SEQ_REFORMAT"))check=2;
1643       else if ( getenv ("DEBUG_TCOFFEE") && strm (PROGRAM, "T-COFFEE"))check=2;
1644       else check=-1;      
1645     }
1646
1647   if ( check>0 && strm ( val, "DEBUG_TMP_FILE"))
1648     {
1649       return "1";
1650     }
1651   
1652   else if ( check==1)
1653     {
1654       return getenv (val);
1655     }
1656   else if ( check==2)
1657     {
1658       return "1";
1659     }
1660   else
1661     return NULL;
1662 }
1663
1664 int   atoigetenv (const char*var)
1665 {
1666   char *v;
1667   if (!var) return 0;
1668   else if (!(v=getenv(var)))return 0;
1669   else if ( is_number(v))return atoi(v);
1670   else return 1;
1671 }
1672 char* get_env_variable ( const char *var, int mode)
1673         {
1674             /*mode 0: return NULL if variable not set*/
1675             /*mode 1: crash if variable not set*/
1676             if ( !getenv (var))
1677                {
1678                    if (mode==NO_REPORT)return NULL;
1679                    else if ( mode ==IS_NOT_FATAL)
1680                      {
1681                        myexit(fprintf_error ( stderr, "\nYou must set the variable %s [FATAL]\n", var));
1682                        return NULL;
1683                       }
1684                    else
1685                       {
1686                           myexit(fprintf_error ( stderr, "\nYou must set the variable %s [FATAL]\n", var));
1687                           myexit (EXIT_FAILURE);
1688                           return NULL;
1689                       }
1690                }
1691             else return getenv (var);
1692         }
1693                 
1694 void get_pwd ( char *name)
1695         {
1696         char *string;
1697         FILE *fp;
1698          
1699
1700         string=vtmpnam(NULL);
1701         printf_system_direct ("pwd > %s", string);
1702         
1703         fp=vfopen ( string, "r");
1704         fscanf ( fp, "%s",name);
1705         vfclose (fp);
1706         printf_system_direct ("rm %s", string);
1707         }
1708 int pg_is_installed ( char *pg)
1709         {
1710         char *fname;
1711         FILE *fp;
1712         int r=0;
1713
1714         return 1;
1715
1716         fname= vtmpnam(NULL);
1717         
1718         printf_system_direct("which %s > %s", pg, fname);
1719         
1720         if ((fp=find_token_in_file ( fname, NULL, "Command"))){r=1;vfclose(fp);}
1721          
1722
1723         return r;
1724         
1725         }
1726
1727             
1728 /*********************************************************************/
1729 /*                                                                   */
1730 /*                           MISC                                    */  
1731 /*                                                                   */
1732 /*********************************************************************/
1733 char *num2plot (int value, int max, int line_len)
1734         {
1735                int   len;
1736                int   value_len;
1737                char *buf;
1738         static char *string;
1739
1740         if ( string==NULL)string=vcalloc (1000, sizeof(char));
1741  
1742         if ( line_len==-1)len=30;
1743         else len=line_len;
1744         
1745         value_len=((float)value/(float)max)*(float)len;
1746         if ( value==0)
1747             sprintf ( string, "|");
1748         else
1749             {
1750             buf=generate_string(value_len, '*');
1751             sprintf ( string,"%s", buf);
1752             vfree(buf);
1753             }
1754         return string;
1755         }
1756         
1757 int   perl_strstr ( char *string, char *pattern)
1758 {
1759   char *tmp;
1760   FILE *fp;
1761   int r;
1762   
1763   char *string2;
1764
1765   if (!string)  return 0;
1766   if (!pattern) return 0;
1767   
1768   
1769   
1770   string2=vcalloc ( strlen (string)+1, sizeof (char));
1771   sprintf ( string2,"%s", string);
1772   string2=substitute (string2, "(", " ");
1773   string2=substitute (string2, ")", " ");
1774   string2=substitute (string2, "'", " ");
1775   tmp=vtmpnam(NULL);
1776   printf_system_direct("perl -e '$s=\"%s\";$x=($s=~/%s/);$x=($x==1)?1:0;print $x;'>%s", string2, pattern,tmp);
1777   
1778   if (check_file_exists(tmp))
1779     {
1780       fp=vfopen (tmp, "r");
1781       fscanf (fp, "%d", &r);
1782       vfclose (fp);
1783     }
1784   else
1785     {
1786       fprintf ( stderr, "COM: %s\n", string);
1787       r=0;
1788     }
1789   vfree (string2);
1790   return r;
1791 }
1792
1793 void crash_if ( int val, char *s)
1794     {
1795     if ( val==0)crash(s);
1796     }
1797 void crash ( char *s)
1798         {
1799         int *a;
1800
1801         
1802
1803         fprintf ( stderr, "%s",s);
1804         a=vcalloc ( 10, sizeof (int));
1805         a[20]=1;
1806         error_exit();
1807         }
1808
1809 static int *local_table;
1810 int ** make_recursive_combination_table ( int tot_n_param, int *n_param, int *nc, int**table, int field)
1811     {
1812     int a, b, c;
1813     
1814     /* makes a table of all possible combinations*/
1815
1816     if ( tot_n_param==0)
1817         {
1818             nc[0]=1;
1819             fprintf ( stderr, "\nNULL RETURNED");
1820             return NULL;
1821         }
1822     if (table==NULL)
1823         {
1824         if ( local_table!=NULL)vfree (local_table);
1825         local_table=vcalloc ( tot_n_param, sizeof (int));
1826         field=0;
1827         for ( a=0; a< tot_n_param; a++)local_table[a]=-1;
1828         for ( a=0; a< tot_n_param; a++)nc[0]=nc[0]*n_param[a];
1829         
1830
1831         table=declare_int ( nc[0],tot_n_param);
1832         nc[0]=0;
1833         }
1834     
1835     for ( b=0; b<n_param[field]; b++)
1836                {
1837                
1838                local_table[field]=b;
1839                if ( field<tot_n_param-1)
1840                   {
1841                   table=make_recursive_combination_table ( tot_n_param, n_param, nc, table, field+1);
1842                   }
1843                else
1844                   {
1845                   for ( c=0; c< tot_n_param; c++)table[nc[0]][c]=local_table[c];
1846                   nc[0]++;
1847                   }
1848                }
1849     return table;
1850     }
1851                   
1852 /*********************************************************************/
1853 /*                                                                   */
1854 /*                         STRING PROCESSING                         */
1855 /*                                                                   */
1856 /*                                                                   */
1857 /*********************************************************************/
1858 char *strnrchr ( char *s,char x, int n)
1859 {
1860   int a;
1861   for (a=0; a< n; a++)if (s[a]=='x')return s+a;
1862   return NULL;
1863 }
1864 int intlen (int n)
1865 {
1866   char buf [100];
1867   sprintf ( buf, "%d", n);
1868   return strlen (buf)+1;
1869 }
1870 char * update_string (char string1[], char string2[])
1871 {
1872   if ( string1==string2);
1873   else if ( string2==NULL)
1874     {
1875       if ( string1==NULL)string1=vcalloc ( 1, sizeof(char));
1876       string1[0]='\0';
1877     }
1878   else
1879     {
1880       int l1, l2;
1881       l1=read_array_size_new (string1);
1882       l2=strlen (string2)+1;
1883       if (l1<l2)
1884         string1=vrealloc (string1, (l2)*sizeof (char));
1885       sprintf ( string1, "%s", string2);
1886     }
1887   return string1;
1888 }
1889   
1890 char* strcatf  (char *string1,char *string2, ...)
1891 {
1892   
1893   va_list ap;
1894   char *buf;
1895   
1896   buf=vcalloc ( read_array_size_new (string1)+1, sizeof (char));
1897   va_start (ap, string2);
1898   vsprintf (buf, string2, ap);
1899   va_end (ap);
1900   string1=vcat (string1, buf);
1901   vfree (buf);
1902   return string1;
1903 }
1904
1905 char *vcat ( char *st1, char *st2)
1906 {
1907   int l=0;
1908   char *ns;
1909   
1910   if ( !st1 && !st2)return NULL;
1911   if ( st1) l+=strlen (st1);
1912   if ( st2) l+=strlen (st2);
1913   l++;
1914   
1915   ns=vcalloc ( l, sizeof (char));
1916   sprintf ( ns, "%s%s", (st1)?st1:"", (st2)?st2:"");
1917   return ns;
1918 }
1919 int print_param ( char *param, FILE *fp);
1920 int print_param ( char *param, FILE *fp)
1921 {
1922   static char **p;
1923   static int np;
1924   int a;
1925   
1926   if (!p)p=vcalloc (1000, sizeof (char*));
1927   
1928   for ( a=0; a<np; a++)if (p[a]==param) return 0;
1929   
1930   p[np++]=param;
1931   
1932   fprintf ( fp, "\nPARAMETERS: %s\n", param);
1933   return 1;
1934 }
1935   
1936 int strget_param ( char *string, char *token1, char *token2, char *format, ...)
1937 {
1938   /*string: command line
1939     token1: parameter
1940     token2: default value (in a string)
1941     format: standard scanf format
1942     ... arguments for scanf
1943   */
1944   char *buf;
1945   char *buf2;
1946   int n;
1947   va_list ap;
1948   
1949   if (!string) return 0;
1950   //print_param (string, stdout);
1951   //print_param (string, stderr);
1952   va_start (ap, format);
1953   buf=after_strstr ( string, token1);
1954   
1955   
1956   if (buf)
1957     {
1958       buf2=vcalloc (strlen (buf)+1, sizeof (char));
1959       sprintf ( buf2, "%s", buf);
1960       buf2=substitute (buf2, "__", " ");
1961       n=my_vsscanf (buf2, format, ap);
1962       vfree (buf2);
1963     }
1964   else     {n=my_vsscanf (token2, format, ap);}
1965   va_end (ap);
1966   
1967   return n;
1968 }
1969
1970 char* estrstr (char *string,char *token,...)
1971 {
1972   char *etoken;
1973   char *ret;
1974   
1975   if (!token) return NULL;
1976   if (!string) return NULL;
1977
1978   cvsprintf (etoken,token);
1979   ret=strstr(string,etoken);
1980   vfree (etoken);
1981   return ret;
1982 }
1983
1984 char* festrstr (char *file,char *token,...)
1985 {
1986   char *string;
1987   char *etoken;
1988   char *ret;
1989   
1990   if (!token || !file || !file_exists(NULL,file))return NULL;
1991   if ((string=file2string(string)))
1992     {
1993       cvsprintf (etoken,token);
1994       ret=strstr(string,etoken);
1995       vfree (string);
1996       vfree (etoken);
1997       if (ret)return token;
1998     }
1999   return NULL;
2000 }
2001
2002  
2003 int strscanf (char *string1,char *token, char *format,...)
2004 {
2005   char *buf;
2006   va_list ap;
2007   int n;
2008   
2009   va_start (ap,format);
2010   buf=after_strstr ( string1, token);
2011   if ( buf){n=my_vsscanf (buf, format, ap);}
2012   else n=0;
2013   
2014   va_end (ap);
2015   return n;
2016 }
2017
2018 int match_motif ( char *string, char **motif)//crude string matching, the motif and the string have the same length
2019   {
2020   int l, a;
2021   if (!motif) return 0;
2022   l=strlen (string);
2023   for ( a=0; a<l; a++)
2024       {
2025         if ( motif[a][0]!='*' && !strchr (motif[a], string[a]))return 0;
2026       }
2027   return 1;
2028
2029
2030 char *after_strstr ( char *string, char *token)
2031 {
2032   char *p;
2033   if ( (p=vstrstr (string, token)))return p+strlen (token);
2034   else return NULL;
2035 }
2036 char* lstrstr ( char *in, char *token)//return strstr if matches on the left
2037 {
2038   char *s;
2039   if ((s=vstrstr(in, token))&&s==in)return s;
2040   else return NULL;
2041   
2042 }
2043
2044 char *vstrstr ( char *in, char *token)
2045 {
2046   if (!in || !token) return NULL;
2047   else return strstr (in, token);
2048 }
2049 char ** push_string (char *val, char **stack, int *nval, int position)
2050 {
2051   char **new_stack;
2052   int a;
2053   
2054   
2055   if (!val || nval[0]<=position)return stack;
2056   nval[0]++;
2057   new_stack=vcalloc ( nval[0], sizeof (char*));  
2058   new_stack[position]=val;
2059   for (a=0; a< position; a++)new_stack[a]=stack[a];
2060   for (a=position+1; a<nval[0]; a++)new_stack[a]=stack[a-1];
2061   vfree (stack);
2062   
2063   return new_stack;
2064 }
2065
2066 int vsrand (int val)
2067 {
2068   static int initialized;
2069   
2070   if (initialized) return 0;
2071   else if (   getenv ("DEBUG_SRAND"))
2072     {
2073       srand (10);
2074       initialized=1;
2075     }
2076   else
2077     {
2078       
2079       /*Make sure two processes in a row do not get the same time value*/
2080       srand ((val==0)?time(NULL):val);
2081       initialized=1;
2082     }
2083   return 1;
2084 }
2085 int  *randomize_list (int *list, int len, int ncycle)
2086 {
2087   int p1, p2, a, buf;
2088   
2089   vsrand (0);
2090   if ( ncycle==0)ncycle=len;
2091   for ( a=0; a<ncycle; a++)
2092     {
2093       p1=rand()%len;
2094       p2=rand()%len;
2095       buf=list[p1];
2096       list[p1]=list[p2];
2097       list[p2]=buf;
2098     }
2099   return list;
2100 }
2101 /*Replace by a gap the parts of the two strings that do not OVERLAP*/
2102 /*returns the length of the overlap*/
2103 int vstrcmp (const char *s1, const char *s2)
2104 {
2105   if ( !s1 && !s2)return 0;
2106   else if ( !s1 || !s2)return 1;
2107   else return strcmp ( s1, s2);
2108 }
2109 int vstrncmp (const char *s1, const char *s2, int n)
2110 {
2111   if ( !s1 && !s2)return 0;
2112   else if ( !s1 || !s2)return 1;
2113   else return strncmp ( s1, s2, n);
2114 }
2115 FILE *print_array_char (FILE *out, char **array, int n, char *sep)
2116         {
2117         int a;
2118         if ( array==NULL || read_size_char (array,sizeof (char*))<n)
2119            {
2120            myexit(fprintf_error ( stderr, "\nORB in print_array_char [FATAL]\n"));
2121            crash("");
2122            }
2123         for ( a=0; a< n; a++)fprintf ( out, "%s%s", array[a],sep);
2124         return out;
2125         }
2126 char * path2filename ( char *array)
2127 {
2128   Fname *F;
2129   char *name;
2130
2131   name=vcalloc ( strlen (array)+2, sizeof (char));
2132   F=parse_fname (array);
2133   if ( F->suffix)sprintf ( name, "%s.%s", F->name, F->suffix);
2134   else sprintf (name, "%s", F->name);
2135   free_fname (F);
2136   return name;
2137 }
2138 Fname* parse_fname ( char *array)
2139          {
2140          int l;
2141          Fname *F;
2142
2143
2144
2145          F=declare_fname (sizeof (array));
2146          
2147          sprintf ( F->full, "%s", array);
2148          sprintf ( F->path, "%s", array);       
2149          l=strlen (array);
2150          while (l!=-1 && (F->path)[l]!='/')(F->path)[l--]='\0';
2151          
2152          sprintf ( F->name, "%s", array+l+1);
2153          l=strlen (F->name);
2154          while (l!=-1)
2155            {
2156             if((F->name)[l]=='.')
2157               {
2158               F->name[l]='\0';
2159               sprintf ( F->suffix, "%s", F->name+l+1);
2160               break;
2161               }
2162             else l--;
2163             }
2164
2165         return F;
2166         }
2167 char *filename2path (char *name)
2168 {
2169   char *nname;
2170   int x;
2171   if (isdir (name))return name;
2172   
2173   x=strlen (name)-1;
2174   nname=vcalloc (x+2, sizeof (char));
2175   sprintf ( nname, "%s", name);
2176   while ( x >=0 && nname[x]!='/')nname[x--]='\0';
2177   
2178   if ( !isdir (nname) || !nname[0]){vfree (nname); return NULL;}
2179   return nname;
2180 }
2181   
2182   
2183
2184   
2185     
2186 char *extract_suffixe ( char *array)
2187         {
2188         int l;
2189         char *new_string;
2190         char *x;
2191         l=strlen (array);
2192         new_string=vcalloc ( l+1, sizeof (char));
2193         sprintf (new_string, "%s",array);
2194         
2195         x=new_string+l;
2196         while (x!=new_string && x[0]!='.' && x[0]!='/' )x--;
2197         if ( x[0]=='.')x[0]='\0';
2198         else if (x[0]=='/')return x+1;
2199  
2200         while ( x!=new_string && x[0]!='/')x--;
2201         
2202         return (x[0]=='/')?x+1:x;
2203         }
2204 void string_array_upper ( char **string, int n)
2205      {
2206      int a;
2207      for ( a=0; a< n; a++)upper_string (string[a]);
2208      }
2209 void string_array_lower ( char **string, int n)
2210      {
2211      int a;
2212      for ( a=0; a< n; a++)lower_string (string[a]);
2213      }
2214
2215 char *upper_string ( char *string)
2216         {
2217         int len, a;
2218         
2219         len=strlen ( string);
2220         for ( a=0; a< len; a++)string[a]=toupper ( string[a]);
2221         return string;
2222         }       
2223 char *lower_string ( char *string)
2224         {
2225         int len, a;
2226         
2227         len=strlen ( string);
2228         for ( a=0; a< len; a++)string[a]=tolower ( string[a]);
2229         return string;
2230         }       
2231 void string_array_convert ( char **array, int n_strings, int ns, char **sl)
2232         {
2233         int a;
2234
2235         for ( a=0; a< n_strings; a++)string_convert ( array[a], ns, sl);
2236         }
2237 void string_convert( char *string, int ns, char **sl)
2238         {
2239         int a, l;
2240         l=strlen ( string);
2241         for ( a=0; a< l; a++)
2242             string[a]=convert(string[a], ns, sl);
2243         }
2244 int convert ( char c, int ns, char **sl)
2245         {
2246         int a;
2247         int return_char;
2248
2249         for ( a=0; a< ns; a++)
2250             {
2251             if ((return_char=convert2 ( c, sl[a]))!=-1)
2252                 return return_char;
2253             }
2254         return c;
2255         
2256
2257         }
2258 int convert2 ( char c, char *list)
2259     {
2260     int a;
2261     int l1;
2262     int return_char;
2263
2264     l1=strlen ( list);
2265     
2266     return_char=(list[l1-1]=='#')?c:list[l1-1];
2267
2268     for ( a=0; a< l1; a++)
2269            if (list[a]=='#')return return_char;
2270            else if ( list[a]==c)return return_char;
2271     
2272     return -1;
2273     }
2274 char* substitute_old ( char *string_in, char *t, char *r)
2275 {
2276   char *string_out;
2277   char *p, *heap_in;
2278   int delta, l;
2279   /*REplaces every occurence of token t with token r in string_in*/
2280
2281   if ( string_in==NULL || t==NULL || r==NULL) return string_in;
2282   
2283   heap_in=string_in;
2284
2285   l=read_array_size_new ((void*)string_in)+1;
2286
2287   string_out=vcalloc (l, sizeof (char));
2288   delta=strlen(r)-strlen (t);
2289   delta=(delta<0)?0:delta;
2290          
2291   while ( (p=strstr ( string_in, t))!=NULL)
2292     {
2293
2294       p[0]='\0';
2295       if ( delta)
2296         {
2297           l+=delta; 
2298           string_out=vrealloc(string_out, sizeof (char)*l);
2299         }
2300       
2301       strcat ( string_out, string_in);
2302       strcat ( string_out, r);
2303       string_in=p+strlen (t);
2304     }
2305   strcat ( string_out, string_in);
2306   if (l<strlen (string_out))
2307     {
2308       heap_in=vrealloc (heap_in, sizeof(char)*(strlen (string_out)+1));
2309     }
2310   sprintf ( heap_in, "%s", string_out);  
2311   vfree (string_out);
2312   return heap_in;
2313 }
2314 //Makes sure substitutions of the tild only occur on valid UNIX pathnames
2315 char* tild_substitute ( char *string_in, char *t, char *r)
2316 {
2317   char *p;
2318  
2319   p=strstr ( string_in, "~");
2320   if ( p==NULL)return string_in;
2321   else if (p && p!=string_in && p[-1]!='/')return string_in;
2322   
2323   else
2324     {
2325       return substituteN (string_in, t, r,1);
2326     }
2327   
2328 }
2329
2330 char* substitute_char_set (char *s, char *set, char r)
2331 {
2332   int l,a;
2333
2334   if ( !s || !set || !r) return s;
2335   l=strlen (set);
2336   for (a=0; a<l; a++)
2337     s=substitute_char (s, set[a], r);
2338   return s;
2339 }
2340     
2341
2342 char* substitute_char ( char *string_in, char t, char r)
2343 {
2344   int n=0;
2345   while ( string_in && string_in[n]!='\0')
2346     {
2347       if ( string_in[n] == t)string_in[n]=r;
2348       n++;
2349     }
2350   return string_in;
2351 }
2352 char* substitute ( char *string_in, char *t, char *r)
2353 {
2354   /*REplaces every occurence of token t with token r in string_in*/
2355   return substituteN(string_in, t, r,0);
2356 }
2357 char* substituteN ( char *string_in, char *t, char *r, int N)
2358 {
2359   char *string_out;
2360   char *p, *heap_in, n=0;
2361   int delta, l, lsi,lso,lr,lt,nt;
2362  
2363   /*REplaces the first N Occurences*/
2364   if ( string_in==NULL || t==NULL || r==NULL) return string_in;
2365   
2366   heap_in=string_in;
2367
2368   l=read_array_size_new ((void*)string_in)+1;
2369   lr=strlen(r);
2370   lt=strlen(t);
2371   lsi=strlen (string_in);
2372   
2373   delta=((lr-lt)>0)?(lr-lt):0;
2374   nt=0;
2375   while ( (p=strstr (string_in, t))!=NULL)
2376     {
2377       string_in=p+lt;
2378       nt++;
2379     }
2380   string_in=heap_in;
2381   
2382   lso=nt*delta+lsi;
2383   string_out=vcalloc (lso+1, sizeof (char));
2384   
2385   while ((N==0 ||n<N) && (p=strstr ( string_in, t))!=NULL)
2386     {
2387       p[0]='\0';
2388       strcat ( string_out, string_in);
2389       strcat ( string_out, r);
2390       string_in=p+lt;
2391       if (N!=0)n++;
2392     }
2393   strcat ( string_out, string_in);
2394   if (l<(lso+1)){HERE ("Realloc %s %s delta=%d %d %d", t, r,delta, lsi, lso);heap_in=vrealloc (heap_in, sizeof (char)*(lso +1));}
2395   sprintf ( heap_in, "%s", string_out);  
2396   vfree (string_out);
2397   return heap_in;
2398 }
2399
2400   
2401 char **clean_string (int n, char **string)
2402 {
2403   int a,b,c,l;
2404   if ( !string) return string;
2405   for (a=0; a< n; a++)
2406     {
2407       if (!string[a]) continue;
2408       l=strlen (string[a]);
2409       for (b=0; b<l; b++)
2410         {
2411           c=string[a][b];
2412           if (!isgraph(c) && c!='\n' && c!='\t' && c!=' ')string[a][b]=' ';
2413         }
2414     }
2415   return string;
2416 }
2417                
2418
2419
2420
2421 int str_overlap ( char *string1, char *string2, char x)
2422         {       
2423         int a, b;
2424         int l1, l2;
2425         int **array;
2426         int max1=0, max2=0;
2427         int score;
2428         int max_val=-1;
2429         int end1, end2;
2430         int start1, start2;
2431
2432         if ( strm ( string1, string2))return 0;
2433         else
2434             {
2435             l1=strlen ( string1);
2436             l2=strlen ( string2);
2437             array=declare_int ( strlen ( string1), strlen ( string2));
2438             for ( a=0; a< l1; a++)
2439                 for ( b=0; b< l2; b++)
2440                     {
2441                         if ( a==0 || b==0)array[a][b]=(string1[a]==string2[b])?1:0;
2442                         else
2443                             if (string1[a]==string2[b])
2444                                {
2445                                score=array[a][b]=array[a-1][b-1]+1;
2446                                if ( max_val<score)
2447                                   {
2448                                   max_val=score;
2449                                   max1=a;
2450                                   max2=b;
2451                                   }
2452                                }
2453                     }
2454             start1=(max1+1)-max_val;
2455             end1=  max1;
2456             
2457             start2=(max2+1)-max_val;
2458             end2=  max2;
2459             
2460             for ( a=0; a< l1; a++)if ( a<start1 || a> end1)string1[a]=x;
2461             for ( a=0; a< l2; a++)if ( a<start2 || a> end2)string2[a]=x;
2462             
2463             free_int ( array, l1);
2464             
2465             return max_val;
2466             }
2467         }
2468
2469 int get_string_line ( int start, int n_lines, char *in, char *out)
2470         {
2471         int nl=0;
2472         int a=0;
2473         int c=0;
2474         
2475         while ( nl<n_lines)
2476                 {
2477                 while ( (c=in[start++])!='\n' && c!='\0')
2478                         {
2479                         out[a++]=c;
2480                         }
2481                 out[a++]='\n';
2482                 nl++;
2483                 }
2484         out[a]='\0';
2485         return (c=='\0')?-1:start;
2486         }
2487         
2488
2489 FILE * output_string_wrap ( int wrap,char *string, FILE *fp)
2490         {
2491
2492          int a, b,l;
2493          
2494          l=strlen ( string);
2495          
2496          for ( a=0, b=1; a< l; a++, b++)
2497                 {
2498                 fprintf ( fp, "%c", string[a]);
2499                 if ( b==wrap)
2500                         {
2501                         fprintf ( fp, "\n");
2502                         b=0;
2503                         }
2504                 }
2505          return fp;
2506          }
2507
2508 char * extract_char ( char * array, int first, int len)
2509     {
2510     char *array2;
2511     int a;
2512
2513     len= ( len<0)?0:len;    
2514
2515     array2=vcalloc ((len+1), sizeof (char));
2516     
2517     for ( a=0; a<len; a++)
2518         array2[a]=array[first++];
2519
2520     array2[a]='\0';
2521
2522     return array2;
2523     }    
2524
2525 int check_cl4t_coffee (int argc, char **argv)
2526 {
2527   char *name;
2528   if ( name_is_in_list ("-other_pg", argv, argc, 100)!=-1)return 1;
2529   else if (name_is_in_list ( "tcoffee_test_seq.pep", argv, argc, 100)!=-1)return 1;
2530   else
2531     {
2532       int a,  inseq, result;
2533       FILE *fp;
2534       char command[10000];
2535       command[0]='\0';
2536
2537       for ( inseq=0,a=0; a<argc; a++)
2538         {
2539           if ( inseq && argv[a][0]=='-')
2540             {
2541               inseq=0;
2542             }
2543           else if (strm ( argv[a], "-seq"))inseq=1;
2544
2545           if ( inseq==0)
2546             {
2547               strcat ( command, " ");
2548               strcat ( command, argv[a]);
2549             }
2550         }
2551       name=vcalloc ( 100, sizeof (char));
2552       sprintf ( name, "TCIT_%d", (int)rand()%10000);
2553       strcat ( command, " -seq tcoffee_test_seq.pep -quiet -no_error_report");
2554       fp=vfopen ( name, "w");
2555       fprintf ( fp, ">A\nthecat\n>B\nthecat\n");
2556       vfclose (fp);
2557       result=safe_system (command);
2558       printf_system ( "rm %s.*", name);
2559       vfree (name);
2560       if (result) {myexit (EXIT_FAILURE);return 0;}
2561       else return 1;
2562     }
2563 }
2564       
2565 char** merge_list ( char **argv, int *argc)
2566        {
2567        int a, b;
2568        int n_in;
2569        char **out;
2570        char current [STRING];
2571
2572        out=declare_char (argc[0], STRING);
2573        n_in=argc[0];
2574        argc[0]=0;
2575        
2576        a=0;
2577        while (a< n_in && !is_parameter ( argv[a]))
2578          {
2579            sprintf (out[argc[0]++], "%s",  argv[a]);
2580            argv[a][0]='\0';
2581            a++;
2582          }
2583      
2584        
2585        for ( a=0; a< n_in; a++)
2586          {
2587            if ( is_parameter (argv[a]))
2588              {
2589                sprintf ( out[argc[0]++], "%s", argv[a]);
2590                sprintf ( current, "%s", argv[a]);
2591                
2592                for ( b=0; b< n_in;)
2593                  {
2594                    if ( is_parameter (argv[b]) && strm (current, argv[b]))
2595                         {
2596                           argv[b][0]='\0';
2597                           b++;
2598                           while ( b<n_in && !is_parameter ( argv[b]) )
2599                             {
2600                               if (argv[b][0])
2601                                {
2602                                  sprintf ( out[argc[0]++], "%s", argv[b]); 
2603                                  argv[b][0]='\0';
2604                                }
2605                              b++;
2606                             }
2607                         }
2608
2609                    else b++;
2610                      
2611                      
2612                    
2613                  }
2614              }
2615          }
2616                           
2617        free_char (argv, -1);
2618        return out;
2619        }
2620
2621
2622 int *  string2num_list_old ( char *string)
2623 {
2624   /*Breaks down a list of numbers separated by any legal separator and put them in an array of the right size*/
2625   /*Returns list a list of integer*/
2626   /*Skips non numbers*/
2627   
2628   char *buf, *s;
2629   int  *list, n;
2630   
2631
2632   buf=vcalloc ( strlen (string)+1, sizeof (char));
2633   
2634   n=0;
2635   sprintf ( buf, "%s", string);
2636   s=strtok (buf, SEPARATORS);
2637   while (s!=NULL)
2638           {
2639             n++;
2640             s=strtok (NULL, SEPARATORS);
2641           }
2642   list=vcalloc (n+1, sizeof (int));
2643   
2644   n=0;
2645   sprintf ( buf, "%s", string);
2646   s=strtok (buf, SEPARATORS);
2647   while (s!=NULL)
2648           {
2649             if (is_number(s))list[n++]=atoi(s);
2650             s=strtok (NULL, SEPARATORS);
2651           }
2652   vfree (buf);
2653  
2654   return list;
2655 }
2656
2657
2658
2659 int *name_array2index_array ( char **list1, int n1, char **list2, int n2)
2660 {
2661   int *list,a, max;
2662   /*returns an indexed list of the position of list1 in list2*/
2663   list=vcalloc ( n1, sizeof (int));
2664   for ( a=0, max=0; a< n1; a++)max=MAX(max, strlen (list1[a]));
2665   for ( a=0       ; a< n2; a++)max=MAX(max, strlen (list2[a]));
2666   
2667   for ( a=0; a< n1; a++)
2668     {
2669       list[a]=name_is_in_list (list1[a],list2,n2,max);
2670     }
2671   return list;
2672 }
2673
2674 int * string2num_list ( char *string)
2675 {
2676   return string2num_list2(string, SEPARATORS);
2677 }
2678 int * string2num_list2 ( char *string, char *separators)
2679 {
2680    /*Breaks down a list of numbers separated by any legal separator and put them in an array of the right size*/
2681   /*Returns list a list of integer*/
2682   /*Skips non numbers*/
2683   
2684   char **nlist;
2685   int *list;
2686   int a, m, n;
2687   
2688   nlist=string2list2 (string, separators);
2689   
2690   if (nlist==NULL) return NULL;
2691   
2692   n=atoi(nlist[0]);
2693   list=vcalloc ( n, sizeof (int));
2694   
2695   for (m=1, a=1; a< n; a++)
2696     {
2697       if (is_number(nlist[a]))list[m++]=atoi(nlist[a]);
2698     }
2699   
2700   list[0]=m;
2701   free_char (nlist, -1);
2702   if ( m==0){vfree(list); return NULL;}
2703   else
2704     {
2705       return list;
2706     }
2707   
2708   return NULL;
2709   
2710 }
2711 char * list2string  ( char **list, int n)
2712 {
2713   return list2string2 ( list, n, " ");
2714 }
2715 char * list2string2 ( char **list,int n, char* sep)
2716 {
2717   int l, a;
2718   char *string;
2719   
2720   for ( l=0,a=0; a<n; a++)l+=strlen ( list[a])+1;
2721   string=vcalloc (l+1, sizeof (char));
2722   for ( a=0; a< n; a++)
2723       {
2724         strcat ( string, list[a]);
2725         strcat ( string, sep);
2726       }
2727     return string;
2728   }
2729
2730 char **  string2list ( char *string)
2731   {
2732     return string2list2(string, SEPARATORS);
2733   }
2734 char **  string2list2 ( char *string, char *separators)
2735   {
2736   /*Breaks down a list of words separated by any legal separator and put them in an array of the right size*/
2737   /*Returns list a list of char with the size written in list[0]*/
2738   
2739   
2740   char *buf, *s;
2741   char  **list;
2742   int n, max_len;
2743   
2744   if ( string==NULL)return NULL;
2745   buf=vcalloc ( strlen (string)+2, sizeof (char));
2746   
2747
2748   n=max_len=0;
2749   sprintf ( buf, "%s", string);
2750   s=strtok (buf, separators);
2751   
2752   while (s!=NULL)
2753           { 
2754             n++;
2755             max_len=MAX(max_len,(strlen (s)));
2756             s=strtok (NULL, separators);
2757             
2758           }
2759   
2760   if ( n==0){vfree(buf); return NULL;}
2761   
2762   list=declare_arrayN (2, sizeof (char), n+2, max_len+1);
2763     
2764   n=1;
2765   sprintf ( buf, "%s", string);
2766   s=strtok (buf, separators);
2767   while (s!=NULL)
2768           {
2769             sprintf (list[n++], "%s",s);
2770             s=strtok (NULL, separators);
2771           }
2772   
2773   sprintf (list[0], "%d", n);
2774   
2775   vfree (buf); 
2776   
2777   return list;
2778 }
2779
2780 char** break_list ( char **argv, int *argc, char *separators)
2781        {
2782        int a, b;
2783        int n_in;
2784        char **out;
2785        char **ar=NULL;
2786        int n_ar;
2787        int cont=1;
2788
2789        /*Breaks down the argv command line in smaller units, breaking at every separator*/
2790        out=vcalloc (MAX_N_PARAM, sizeof (char*));
2791        n_in=argc[0];
2792        argc[0]=0;
2793        
2794        if ( n_in>=MAX_N_PARAM)
2795          {
2796            myexit(fprintf_error ( stderr, "\nERROR: too many parameters, recompile with MAX_N_PARAM set at a higher velue [FATAL:%s]\n", PROGRAM));\
2797            myexit (EXIT_FAILURE);
2798          }
2799        
2800        for ( a=0; a< n_in; a++)
2801            {
2802              
2803
2804              
2805              if (cont)ar=get_list_of_tokens( argv[a], separators,&n_ar);
2806              else ar=get_list_of_tokens( argv[a],"",&n_ar);
2807
2808
2809              for ( b=0; b< n_ar; b++)
2810                {
2811                  out[argc[0]]=vcalloc( strlen (ar[b])+1, sizeof (char));
2812                  sprintf (out[argc[0]++], "%s", ar[b]);
2813                }
2814              free_char (ar, -1);
2815              ar=NULL;
2816              if ( strstr (argv[a], "-other_pg"))cont=0;
2817            }
2818        free_char (ar, -1);
2819        return out;
2820        }
2821     
2822 char *invert_string2 (char *string)
2823 {
2824   char *buf;
2825   int a, b, l;
2826   
2827   l=strlen (string);
2828   buf=vcalloc ( l+1, sizeof (char));
2829   for ( a=l-1, b=0; a>=0; a--, b++)
2830     buf[b]=string[a];
2831   sprintf (string, "%s", buf);
2832   vfree (buf);
2833   return string;
2834 }
2835 char *invert_string (char *string)
2836 {
2837   return string2inverted_string(string);
2838 }
2839 char* string2inverted_string(char *string)
2840 {
2841   char *buf;
2842   int a, b, l;
2843   
2844   l=strlen (string);
2845   buf=vcalloc ( l+1, sizeof (char));
2846   for ( a=l-1, b=0; a>=0; a--, b++)
2847     buf[b]=string[a];
2848   return buf;
2849 }
2850
2851 char ** get_list_of_tokens ( char *in_string, char *separators, int *n_tokens)
2852 {
2853     char **list=NULL;
2854     char *p=NULL;
2855     char *string;
2856     
2857     
2858     n_tokens[0]=0;
2859     if ( in_string==NULL || strm(in_string, ""));
2860     else if ( in_string[0]=='[')
2861       {
2862         list=declare_char (1, strlen ( in_string)+1);
2863         sprintf ( list[n_tokens[0]], "%s",in_string);
2864         n_tokens[0]++;
2865       }
2866     else
2867       {
2868         list=declare_char (strlen ( in_string)+1, 1);   
2869         string=vcalloc ( strlen(in_string)+1, sizeof (char));
2870         sprintf ( string, "%s", in_string);     
2871         
2872         while ( (p=strtok ((p==NULL)?string:NULL, ((separators==NULL)?SEPARATORS:separators)))!=NULL)
2873            {
2874            list[n_tokens[0]]=vrealloc ( list[n_tokens[0]], sizeof (char) *strlen (p)+1);
2875            sprintf ( list[n_tokens[0]], "%s", p);
2876            n_tokens[0]++;
2877            }
2878
2879         vfree (string);
2880         }
2881    return list;
2882    }
2883
2884 char **ungap_array ( char **array, int n)
2885         {
2886         int a;
2887         for ( a=0; a< n; a++)ungap(array[a]);
2888         return array;
2889         }
2890
2891 void ungap ( char *seq)
2892 {
2893   remove_charset ( seq, "ungap");
2894 }
2895 int seq2len (char *seq, char *pset,char *nset)
2896 {
2897   int a, l, t=0;
2898   //count all the residues in pset and NOT in nset
2899   if ( !seq) return 0;
2900   
2901   l=strlen (seq);
2902   //returns the len of the string 
2903   for (a=0; a< l; a++)
2904     {
2905       char c=seq[a];
2906       if ( pset && nset && strchr (pset, c) && !strchr (nset, c))t++;
2907       else if ( pset && strchr  (pset, c))t++;
2908       else if ( nset && !strchr (nset, c))t++;
2909     }
2910   return t;
2911 }
2912 int seq2res_len (char *seq)
2913 {
2914   return seq2len (seq, NULL, GAP_LIST);
2915 }
2916 char* remove_charset_from_file (char *fname, char *set)
2917 {
2918   char *tmp;
2919   char c;
2920   FILE *fp1;
2921   FILE *fp2;
2922   
2923   fp1=vfopen (fname, "r");
2924   fp2=vfopen (tmp=vtmpnam (NULL), "w");
2925   while ( (c=fgetc(fp1))!=EOF)
2926     {
2927     if (!strchr ( set,c))fprintf ( fp2, "%c", c);
2928     }
2929   vfclose (fp1);
2930   vfclose (fp2);
2931   return tmp;
2932 }
2933   
2934 void remove_charset ( char *seq, char *set)
2935         {
2936         int a, b, l;
2937         char *set2;
2938
2939         set2=vcalloc (256, sizeof (char));
2940         if ( strm (set, "!alnum"))
2941           {
2942             for ( b=0,a=1;a< 256; a++)if ( !isalnum (a))set2[b++]=a;
2943           }
2944         else if ( strm ( set, "ungap"))
2945           {
2946             sprintf ( set2, "%s", GAP_LIST);
2947           }
2948         else
2949           {
2950             sprintf ( set2, "%s", set);
2951           }
2952         
2953         l=strlen ( seq);
2954         for (b=0, a=0; a<=l; a++)
2955           {
2956             if ( strchr ( set2, seq[a]));
2957             else seq[b++]=seq[a];
2958           }
2959         seq[b]='\0';
2960         vfree (set2);
2961         }
2962
2963   
2964 char **char_array2number ( char ** array, int n)
2965        {
2966        int a;
2967        for ( a=0; a< n; a++)array[a]=char2number(array[a]);
2968        return array;
2969        }
2970 char *char2number ( char * array)
2971        {
2972        int a, l;
2973        
2974        
2975        l=strlen ( array);
2976        for ( a=0; a< l; a++)
2977            {
2978              if ( isdigit(array[a]) && array[a]!=NO_COLOR_RESIDUE && array[a]!=NO_COLOR_GAP )array[a]-='0';
2979              else if ( array[a]<9);
2980              else if ( array[a]==NO_COLOR_RESIDUE || array[a]==NO_COLOR_GAP)array[a]=NO_COLOR_RESIDUE;
2981            }
2982        return array;
2983        }
2984 long atop (char*p)
2985 {
2986   /*turns a char into a pointer*/
2987   if ( p==NULL) return 0;
2988   else return atol(p);
2989 }
2990
2991 char *mark_internal_gaps(char *seq, char symbol)
2992 {
2993   int l, a, gap;
2994   int in_seq;
2995   char *cache_seq;
2996   
2997   l=strlen(seq);
2998   cache_seq=vcalloc ( l+1, sizeof (char));
2999   sprintf ( cache_seq, "%s", seq);
3000   
3001   for ( gap=0, in_seq=0,a=0; a< l; a++)
3002     {
3003       gap=is_gap(seq[a]);
3004       if ( !gap && !in_seq)in_seq=1;
3005       if (gap && in_seq)seq[a]=symbol;      
3006     }
3007   
3008   for (gap=0, in_seq=0,a=l-1; a>=0; a--)
3009     {
3010       gap=is_gap(seq[a]);
3011       if ( !gap && !in_seq)break;
3012       if (gap && !in_seq)seq[a]=cache_seq[a];
3013     }
3014   vfree(cache_seq);
3015   return seq;
3016 }
3017
3018 void splice_out ( char *seq, char x)
3019     
3020         {
3021         int a, b, l;
3022
3023         l=strlen ( seq);
3024         for (b=0, a=0; a<=l; a++)
3025                 if ( seq[a]==x);
3026                 else seq[b++]=seq[a];   
3027         seq[b]='\0';
3028         }
3029 char *splice_out_seg ( char *seq, int pos, int len)
3030 {
3031   int l, a;
3032   
3033   if (seq==NULL || pos<0) return seq;
3034   l=strlen (seq);
3035   if ( l<(pos+len))
3036     printf_exit ( EXIT_FAILURE, stderr, "Splice_out_seg out of bound: Length %d seg: [%d %d] [splice_out_seg::util.c][FATAL:%s]\n", l, pos, pos+len, PROGRAM);
3037   l-=len;
3038   for (a=pos; a< l; a++)
3039     seq[a]=seq[a+len];
3040   seq[a]='\0';
3041   return seq;
3042 }
3043   
3044 int isblanc ( char *buf)
3045    {
3046    int a, l;
3047    
3048    if ( buf==NULL)return 0;
3049    l=strlen (buf);
3050    for ( a=0; a< l; a++)
3051         if (isalnum (buf[a]))return 0;
3052    return 1;
3053    }
3054
3055
3056
3057 int is_number  ( char *num)
3058    {
3059      int a, l;
3060      l=strlen (num);
3061      
3062      for (a=0;a<l; a++)
3063        if ( !strchr ("0123456789.-+", num[a]))return 0;
3064      return 1;
3065    }
3066
3067 int is_alnum_line ( char *buf)
3068    {
3069    int a, l;
3070    l=strlen (buf);
3071    for ( a=0; a< l; a++)
3072         if (isalnum (buf[a]))return 1;
3073    return 0;
3074    } 
3075 int is_alpha_line ( char *buf)
3076    {
3077    int a, l;
3078    l=strlen (buf);
3079    for ( a=0; a< l; a++)
3080         if (isalpha (buf[a]))return 1;
3081    return 0;
3082    }
3083 int case_insensitive_strcmp ( char *string1, char *string2)
3084 {
3085   int a;
3086   int l;
3087   
3088   if ( !string1 && !string2) return 1;
3089   else if ( !string1 && !string2) return 0;
3090   else
3091     {
3092       l=strlen (string1);
3093       for ( a=0; a< l; a++)
3094         {
3095           if (tolower(string1[a])!=tolower(string2[a]))return 0;
3096         }
3097     }
3098   return 1;
3099 }       
3100 int get_string_sim ( char *string1, char *string2, char *ignore)
3101         {
3102         int len1;
3103         int len2;
3104         int a;
3105         int pos=0;
3106         int sim=0;
3107         char r1, r2;
3108         
3109         
3110         len1=strlen (string1);
3111         len2=strlen (string2);
3112         
3113         if ( len1!=len2)return 0;
3114         
3115         for ( a=0; a< len1; a++)
3116                 {
3117                 r1=string1[a];
3118                 r2=string2[a];
3119                 if ( !is_in_set (r1, ignore) && !is_in_set (r2, ignore))
3120                         {
3121                         pos++;
3122                         if (r1==r2)
3123                                 {
3124                                 sim++;
3125                                 }
3126                         }
3127                 }
3128         
3129         if (pos==0)
3130                  return 0;
3131         else    
3132                 return (int) (sim*100)/pos;
3133         
3134         }
3135 int haslower (char *s)
3136 {
3137   if (!s) return 0;
3138   else
3139     {
3140       int l,a;
3141       l=strlen (s);
3142       for (a=0; a<l; a++)if (islower(s[a]))return 1;
3143       return 0;
3144     }
3145 }
3146 int hasupper (char *s)
3147 {
3148   if (!s) return 0;
3149   else
3150     {
3151       int l,a;
3152       l=strlen (s);
3153       for (a=0; a<l; a++)if (isupper(s[a]))return 1;
3154       return 0;
3155     }
3156 }
3157
3158 int is_aa  ( char x)
3159          {
3160          return (is_in_set (x, AA_ALPHABET) && !is_in_set (x, GAP_LIST));
3161          }
3162 int is_rna ( char x)
3163          {
3164          return (is_in_set (x, RNAONLY_ALPHABET)&& !is_in_set (x, GAP_LIST));
3165          }
3166 int is_dna ( char x)
3167          {
3168          return (is_in_set (x, DNA_ALPHABET)&& !is_in_set (x, GAP_LIST));
3169          }
3170 int is_gap ( char x)
3171          {
3172          return ( is_in_set ( x, GAP_LIST));
3173          }
3174 int is_gop ( int p, char *s)
3175 {
3176   if (!s) return 0;
3177   else if (p<=0)return 0;
3178   else if (s[p]!='-' && s[p+1]=='-')return 1;
3179   else return 0;
3180 }
3181     
3182 char* get_alphabet   ( char *seq, char *alphabet)
3183 /*This function builds an alphabet from the string seq*/
3184 /*Alphabet does not need to be emppty. The total number of unique symbols is returned*/
3185 /*Gaps, as defined in the GAP_LIST are ignored*/
3186     {
3187         int a;
3188         int len;
3189         
3190         if ( !alphabet) alphabet=vcalloc ( 200, sizeof (char));
3191
3192         len=strlen (seq);
3193         
3194         for ( a=0; a<len; a++)
3195           if ( !is_gap ( seq[a]) && !is_in_set ( seq[a], alphabet+1)){alphabet[(int)++alphabet[0]]=seq[a];}
3196         return alphabet;
3197     }
3198
3199 int array_is_in_set ( char *x, char *set )
3200          {
3201          int len;
3202          int a;
3203          
3204          len=strlen (x);
3205          for ( a=0; a< len; a++)
3206              if ( !is_in_set ( x[a], set))return 0;
3207          return 1;
3208          }
3209
3210
3211 int is_in_set ( char r, char *list)
3212         {
3213         static char s[2];
3214         
3215         s[0]=r;
3216
3217         
3218         if ( strstr ( list,s)!=NULL)return 1;
3219         
3220         return 0;
3221         }
3222 char * generate_void ( int x)
3223     {
3224     return generate_string (x, ' ');
3225     }
3226    
3227 char * generate_null ( int x)
3228     {
3229     return generate_string ( x, '-');
3230     }
3231                 
3232 char * generate_string ( int x, char y)
3233     {
3234          int a;
3235     char *string;
3236     
3237     string = vcalloc ( x+1, sizeof ( char));
3238
3239     for ( a=0; a< x; a++)
3240         string[a]=y;
3241
3242     string[a]='\0';
3243     return string;
3244     }
3245 char * translate_string (char *string, char *in, char*out)
3246 {
3247   int l1, l2;
3248   int a, b;
3249
3250   l1=strlen(string);
3251   l2=strlen (in);
3252
3253   if ( l2!=strlen (out))
3254     {
3255       myexit(fprintf_error ( stderr, "\nERROR: translate_string function: IN alphabet (%s) must have the same size as OUT alphabet (%s) [FATAL:%s]\n", in, out, PROGRAM));
3256       myexit (EXIT_FAILURE);
3257     }
3258   
3259   for ( a=0; a< l1; a++)
3260     {
3261       for ( b=0; b< l2; b++)
3262         {
3263           if ( string[a]==in[b])
3264             {
3265               string[a]=out[b];
3266               b=l2;
3267             }
3268         }
3269     }
3270   return string;
3271 }
3272   
3273
3274 int get_longest_string (char **array,int n, int *len, int *index)
3275      {
3276      int a, l;
3277      int max_len=0, max_index=0;
3278
3279      if ( n==0 || array==NULL )return 0;     
3280      if ( n==-1)n=read_size_char(array,sizeof (char*));
3281      
3282
3283      if (read_size_char ( array,sizeof (char*))<n)
3284          {
3285          myexit(fprintf_error ( stderr, "\nBAD REQUEST: Number of strings=%d, expected number=%d", read_size_char ( array,sizeof (char*)),n));
3286          crash ("[FATAL/util.c]");
3287          }
3288      else
3289          {
3290          max_len=strlen(array[0]);
3291          max_index=0;
3292          for ( a=1; a< n; a++)
3293              {
3294              l=strlen ( array[a]);
3295              if ( l>max_len)
3296                 {
3297                 max_len=l;
3298                 max_index=a;
3299                 }
3300              }
3301          if (index!=NULL)index[0]=max_index;
3302          if (len!=NULL)len[0]=max_len;
3303          }
3304      
3305      return max_len;
3306      }
3307
3308 int get_shortest_string (char **array,int n, int *len, int *index)
3309      {
3310      int a, l;
3311      int min_len;
3312
3313      if ( n==0|| array==NULL || read_size_char ( array,sizeof (char*))<n)return 0;
3314      else
3315          {
3316          min_len=strlen(array[0]);
3317
3318          for ( a=1; a< n; a++)
3319              {
3320              l=strlen ( array[a]);
3321              if ( l<min_len)
3322                 {
3323                 min_len=l;
3324
3325                 }
3326              }
3327          if (index!=NULL)index[0]=a;
3328          if (len!=NULL)len[0]=min_len;
3329          }
3330      return min_len;
3331      }
3332
3333 char **pad_string_array ( char **array, int n, int len, char pad)
3334      {
3335      int a, b, l;
3336      for ( a=0; a< n; a++)
3337          {
3338          l= strlen ( array[a]);
3339          for (b=l; b<len; b++)array[a][b]=pad;
3340          array[a][len]='\0';
3341          }
3342      return array;
3343      }
3344 char **right_pad_string_array ( char **array, int n, int len, char pad)
3345      {
3346      return pad_string_array(array, n, len, pad);
3347      }
3348 char **left_pad_string_array ( char **array, int n, int len, char pad)
3349      {
3350      int a, b, c, l;
3351      char *buf;
3352
3353      buf=vcalloc ( len+1, sizeof (char));
3354      for ( a=0; a< n; a++)
3355          {
3356          l= strlen ( array[a]);
3357          for (b=0; b<(len-l); b++)buf[b]=pad;
3358          for (c=0,b=(len-l); b<=len; c++,b++)buf[b]=array[a][c];         
3359          sprintf (array[a], "%s", buf);
3360
3361          }
3362      vfree(buf);
3363      return array;
3364      }
3365 char * crop_string (char *string, int start, int end)
3366      {
3367      static char *buf;
3368      /*Extract [start-end[*/
3369
3370      if ( strlen (string)<end)
3371              {
3372              myexit(fprintf_error ( stderr, "\nString=%s, start=%d end=%d", string, start, end));
3373              crash ( "Wrong End in crop String [FATAL]");
3374              }
3375      else
3376          {
3377          buf=vcalloc (strlen (string)+1, sizeof (char));
3378          string[end]='\0';
3379          sprintf ( buf, "%s", string+start);
3380          sprintf ( string,"%s", buf);
3381          vfree (buf);
3382          }
3383
3384      return string;
3385      }
3386                   
3387 int get_distance2char ( char *x, char*list)
3388     {
3389
3390     char *y;
3391     y=x;
3392     if (x==NULL) return 0;
3393     while (!is_in_set (y[0], list) && y[0]!='\0')y++;
3394     return y-x;
3395     }
3396 /*********************************************************************/
3397 /*                                                                   */
3398 /*                         TIME        FUNCTIONS                     */
3399 /*                                                                   */
3400 /*                                                                   */
3401 /*********************************************************************/
3402 static long ref;
3403 static int child;
3404 static long ticks;
3405 static long milli_sec_conv=1000;
3406
3407
3408 FILE *print_program_information (FILE *fp, char *comment)
3409 {
3410    fprintf ( fp, "# Results Produced with %s (%s)\n",PROGRAM, VERSION);
3411    fprintf ( fp, "# %s is available from %s\n",PROGRAM,URL);
3412    fprintf ( fp, "# Register on: https://groups.google.com/group/tcoffee/\n");
3413    if (comment)fprintf ( fp, "# %s\n", comment);
3414    return fp;
3415 }
3416 FILE* print_cpu_usage (FILE *fp, char *comment)
3417 {
3418   fprintf ( fp, "# %s CPU Usage: %d millisec\n", comment, get_time());
3419   return fp;
3420 }
3421 void print_exit_success_message ()
3422 {
3423   return;
3424   fprintf ( stderr, "\n# TERMINATION STATUS: SUCCESS [PROGRAM: %s pid %d ppid %d]\n#CL: %s\n", PROGRAM, getpid(), getppid(),in_cl);
3425 }
3426 void print_exit_failure_message ()
3427 {
3428   fprintf ( stderr, "\n# TERMINATION STATUS: FAILURE [PROGRAM: %s pid %d ppid %d\n#CL: %s\n", PROGRAM, getpid(), getppid(), in_cl);
3429 }
3430
3431
3432
3433
3434 int get_time ()
3435         {
3436         static long time;
3437         struct tms time_buf[1];
3438         long tms_stime, tms_utime;
3439
3440         if ( child==1)return get_ctime();
3441           
3442         if ( ticks==0)ticks = sysconf(_SC_CLK_TCK);
3443         times ( time_buf);
3444
3445         tms_stime=(long)time_buf->tms_stime*milli_sec_conv;
3446         tms_utime=(long)time_buf->tms_utime*milli_sec_conv;
3447         
3448
3449
3450         
3451         if ( ref==0)
3452                 {
3453                 ref=(tms_stime+tms_utime);
3454                 return 0;
3455                 }
3456         else
3457                 {
3458                 time=(tms_utime+tms_stime)-ref;
3459                 return (int) ((time)/ticks);
3460                 }
3461         }
3462 int get_ctime ()
3463         {
3464         static long time;
3465         struct tms time_buf[1];
3466         long   tms_cutime, tms_cstime; 
3467         
3468         if ( ticks==0)ticks = sysconf(_SC_CLK_TCK);
3469         times ( time_buf);
3470
3471
3472
3473         tms_cstime=(long)time_buf->tms_cstime*milli_sec_conv;
3474         tms_cutime=(long)time_buf->tms_cutime*milli_sec_conv;
3475
3476         if ( ref==0)
3477                 {
3478                 child=1;
3479                 ref=tms_cstime+tms_cutime;
3480                 return 0;
3481                 }
3482         else
3483                 {
3484                 time=(tms_cutime+tms_cstime)-ref;
3485                 return (int)((time)/ticks);
3486                 }
3487         }
3488 int reset_time()
3489         {
3490         ref=0;
3491         return (int)get_time();
3492         }
3493 int increase_ref_time(int increase)
3494         {
3495         if ( ref==0)get_time();
3496         
3497         ref-=(long)ticks*(long)increase;
3498         if (ref==0)ref++;
3499         return (int)ref;
3500         }
3501
3502 /*********************************************************************/
3503 /*                                                                   */
3504 /*                         SYSTEM CALLS                              */
3505 /*                                                                   */
3506 /*                                                                   */
3507 /*********************************************************************/ 
3508 int evaluate_sys_call_io ( char *out_file, char *com, char *fonc)
3509      {
3510        if ( file_exists (NULL,out_file))return 1;
3511        else 
3512          {
3513            add_warning (stderr, "COMMAND FAILED: %s",com); 
3514            return 0;
3515          }
3516      }
3517 void HERE (char *string, ...)
3518 {
3519   va_list ap;
3520   
3521   va_start (ap, string);
3522   fprintf ( stderr, "HERE: ");
3523   vfprintf (stderr, string, ap);
3524   fprintf ( stderr, "\n");
3525   va_end (ap);
3526   
3527 }
3528
3529     
3530 int fprintf_fork  (FILE *fp, char *string, ...)
3531 {
3532   static char *openF;
3533   static char *closeF;
3534   
3535   
3536   FILE *flag;
3537   
3538   
3539
3540   char *buf;
3541  
3542   if (!openF)
3543     {
3544       openF=vcalloc (100, sizeof (char));
3545       sprintf (openF, "cedric1");
3546       closeF=vcalloc (100, sizeof (char));
3547       sprintf (closeF, "cedric2");
3548       
3549       //openF =vtmpnam (NULL);
3550       //closeF=vtmpnam (NULL);
3551       vfclose(vfopen (openF,"w"));
3552     }
3553   while ((rename (openF,closeF))==-1);
3554     
3555   cvsprintf (buf,string);
3556   fprintf ( fp, "%s", buf);
3557   fflush (fp);
3558   rename (closeF, openF);
3559   vfree (buf);
3560   return 0;
3561 }
3562 int fprintf_fork2  (FILE *fp, char *string, ...)
3563 {
3564
3565  
3566  
3567   char* buf;
3568  
3569   cvsprintf (buf, string);
3570   fprintf ( fp, "%s", buf);
3571   vfree (buf);
3572   fflush (fp);
3573   return 0;
3574 }
3575
3576 int printf_file  (char *file,char *mode, char *string,...)
3577 {
3578   FILE *fp;
3579   va_list ap;
3580   
3581   if (!(fp=vfopen (file, mode)))return 0;
3582   va_start (ap, string);
3583   vfprintf (fp, string, ap);
3584   va_end (ap);
3585   vfclose (fp);
3586   return 1;
3587   }
3588 int printf_system_direct  (char *string, ...)
3589 {
3590   char *buf;
3591   int r;
3592   
3593   cvsprintf (buf, string);
3594
3595
3596   r=system (buf);
3597   vfree(buf);
3598   return r;
3599 }
3600
3601 int printf_system  (char *string, ...)
3602 {
3603   char *buf;
3604   int r;
3605   
3606   cvsprintf (buf, string);
3607   r=my_system (buf);
3608   vfree(buf);
3609   return r;
3610 }
3611
3612 int my_system_cl (int argc, char *argv[])
3613 {
3614   int a,l;
3615   char *command;
3616   
3617   for ( a=0, l=0; a< argc; a++)l+=(strlen(argv[a])+2);
3618   command=vcalloc (l+1, sizeof(char));
3619   for ( a=0; a< argc; a++)
3620     {
3621       command=strcat (command, argv[a]);
3622       command=strcat (command, " ");
3623     }
3624   a=my_system ( command);
3625   vfree (command);
3626   return a;
3627 }
3628
3629 int my_system ( char *command0)
3630 {
3631   static char ***unpacked_list;
3632   static int n_unpacked;
3633     
3634   if (!unpacked_list)
3635     {
3636       unpacked_list=declare_arrayN(3, sizeof (char), 3, 200,300);
3637     }
3638
3639   if ( getenv ("DEBUG_PERL"))return safe_system (command0);
3640   else
3641     {
3642       char **list;
3643       int is_command;
3644       int a, c=0;
3645       char *command1;
3646       char *command2;
3647       int return_val;
3648       
3649       command1=vcalloc ( 3*strlen (command0)+1, sizeof (char));
3650       command2=vcalloc ( 100000, sizeof (char));      
3651       sprintf ( command1, "%s", command0);
3652       
3653       command1=substitute (command1, "|", " | ");
3654       command1=substitute (command1, ";", " ; ");
3655       
3656       list=string2list (command1);
3657
3658       if ( !list) return EXIT_SUCCESS;
3659       is_command=1;
3660
3661       //Identify T-Coffee self threads and install threads
3662             
3663       for ( a=1; a< atoi(list[0]); a++)
3664         {
3665           if ( is_command)
3666             {
3667               if ( strstr ( list[a], "unpack_"))
3668                 {
3669                   unpack_all_perl_script (list[a]+strlen ("unpack_"));
3670                   myexit (EXIT_SUCCESS);
3671                 }
3672               else if ((c=name_is_in_list (list[a], unpacked_list[0], n_unpacked, 100))!=-1);
3673               else
3674                 {
3675
3676                   n_unpacked=unpack_perl_script (list[a], unpacked_list, n_unpacked);c=n_unpacked-1;
3677                   
3678                 }
3679               //if non unpacked script check pg is installed:
3680                       
3681               if ( strm (unpacked_list[2][c], "shell"))
3682                 {
3683                   check_program_is_installed (list[a], NULL, NULL, NULL, INSTALL_OR_DIE);
3684                 }
3685               strcat (command2, ((c!=-1)?unpacked_list[1][c]:list[a]));
3686               strcat (command2, " ");
3687               is_command=0;
3688               
3689             }
3690           else
3691             {
3692               strcat (command2, list[a]);
3693               strcat (command2, " ");
3694               if ( strm (list[a], ",") ||strm (list[a], "|")) is_command=1;
3695             }
3696         }
3697       
3698       free_char (list,-1);
3699       vfree ( command1);
3700       command2=substitute ( command2, "//", "/");
3701       
3702       return_val=safe_system (command2);
3703       
3704       vfree ( command2);
3705       return return_val;
3706     }
3707 }
3708 int has_warning_lock()
3709 {
3710   if (lock(getpid(), LWARNING, LCHECK,NULL))return 1;
3711   else return 0;
3712 }
3713 int has_error_lock()
3714 {
3715   if (lock(getpid(), LERROR, LCHECK,NULL))return 1;
3716   else return 0;
3717 }
3718 int is_shellpid(int pid)
3719 {
3720   if ( lock(pid, LLOCK, LCHECK, NULL) && strstr (lock(pid,LLOCK, LREAD, NULL), "-SHELL-"))return 1;
3721   else return 0;
3722 }
3723 int is_rootpid()
3724 {
3725
3726   if (debug_lock)
3727     {
3728       char *f;
3729       fprintf ( stderr,"\n\t------ check if %d isrootpid (util): %s->%d", getpid(),f=lock2name (getppid(),LLOCK), (lock(getppid(), LLOCK, LCHECK, NULL))?1:0);
3730       vfree (f);
3731     }
3732                 
3733   
3734   if(lock (getppid(), LLOCK, LCHECK, NULL)!=NULL)return 0;
3735   else return 1;
3736 }
3737
3738 int shift_lock ( int from, int to, int from_type,int to_type, int action)
3739 {
3740   //action: SET (concatenate) or RESET (replace parent with child content)
3741   char *e;
3742   if (!lock (from,from_type, LCHECK, NULL))return 0;
3743   e=lock (from,from_type, LREAD, NULL);
3744   lock (from,from_type, LRELEASE, NULL);
3745   
3746   if ( action==LSET || action==LRESET)lock (to, to_type,action, e);
3747   else 
3748     {
3749       myexit(fprintf_error (stderr, "Unsupported type for shift_lock"));
3750     }
3751   vfree (e);
3752   return 1;
3753 }
3754
3755 char*lock2name (int pid, int type)
3756 {
3757   char *fname;
3758   char host[1024];
3759   gethostname(host, 1023);
3760   
3761   fname=vcalloc (strlen(host)+strlen (get_lockdir_4_tcoffee())+1000, sizeof (char));
3762   if (type == LLOCK)sprintf (fname, "%s/.%d.%s.lock4tcoffee",get_lockdir_4_tcoffee(), pid,host);
3763   else if ( type == LERROR) sprintf (fname, "%s/.%d.%s.error4tcoffee", get_lockdir_4_tcoffee(),pid,host); 
3764   else if ( type == LWARNING) sprintf (fname, "%s/.%d.%s.warning4tcoffee",get_lockdir_4_tcoffee(),pid,host); 
3765   else myexit(fprintf_error ( stderr, "ERROR: Unknown type for lock"));
3766   return fname;
3767 }
3768
3769 int release_all_locks (int pid)
3770 {
3771   lock (pid, LLOCK, LRELEASE, NULL);
3772   lock (pid, LERROR, LRELEASE, NULL);
3773   lock (pid, LWARNING, LRELEASE, NULL);
3774   return 1;
3775 }
3776 char* lock(int pid,int type, int action,char *string, ...)
3777 {
3778   char *fname;
3779   char *r;
3780
3781
3782   
3783   fname=lock2name (pid, type);
3784   
3785   if (debug_lock)
3786     {
3787       fprintf (stderr,"\n\t\t---loc4tc(util.h) %d =>%s [RD: %s]\n", action, fname, getcwd(NULL, 0));
3788     }
3789   
3790   if (action == LREAD)
3791     {
3792       r=file2string (fname);
3793     }
3794   else if ( action == LCHECK)
3795     {
3796       r=(file_exists (NULL,fname))?"x":NULL;
3797     }
3798   else if (action== LRELEASE) 
3799     {
3800       
3801       if (debug_lock)
3802         {
3803           printf_system_direct ("mv %s %s.released", fname, fname);
3804         }
3805       else if (file_exists (NULL, fname))
3806         {
3807           vremove (fname);
3808         //safe_remove (fname);return NULL;
3809         }
3810       r=" ";
3811     }
3812   else if ( clean_exit_started) return NULL; //NO MORE LOCK SETTING during EXIT Phase
3813   else if (action== LSET || action == LRESET)    
3814     {
3815       char *value;
3816  
3817       if (string)
3818         {
3819           cvsprintf (value,string);
3820         }
3821       else
3822         {
3823           value=vcalloc (2, sizeof(char));
3824           sprintf (value, " ");
3825         }
3826       string2file (fname, (action==LSET)?"a":"w", value);
3827       vfree (value);
3828       r= " ";
3829       
3830     }
3831   else myexit(fprintf_error ( stderr, "ERROR: Unknown action for LOCK"));
3832   vfree (fname);
3833   return r;
3834     
3835 }
3836 int check_process (const char *com,int pid,int r, int failure_handling)
3837 {
3838
3839   //If the child process has an error lock, copy that lock into the parent'lock
3840   //The error stack trace of the child gets passed to the parent
3841   if (debug_lock)fprintf (stderr, "\nEVAL_CALL ----- %d ->%s\n",pid, (r==EXIT_FAILURE)?"FAIL":"SUCCESS");
3842   
3843   if ( failure_handling == IGNORE_FAILURE) return r;
3844   if ( lock(pid, LWARNING, LCHECK, NULL))
3845     {
3846       shift_lock (pid, getpid(), LWARNING, LWARNING,LSET);
3847     }
3848
3849   
3850   if ( lock(pid, LERROR, LCHECK, NULL))
3851     {
3852       shift_lock (pid, getpid(), LERROR,LERROR, LSET);
3853     }
3854   else if (r==EXIT_FAILURE)
3855     {
3856       //Reconstruct missing errorlock
3857       lock (getpid(), LERROR,LSET,"%d -- ERROR: UNSPECIFIED UNSPECIFIED\n",pid);
3858       lock (getpid(), LERROR,LSET,"%d -- COM: %s\n",pid,com);
3859       lock (getpid(), LERROR, LSET,"%d -- STACK: %d -> %d\n",pid,getpid(), pid);
3860     }
3861   //lock is now ready. Shall we use it?
3862
3863   if (lock(getpid(), LERROR, LCHECK, NULL))
3864     {
3865       if (failure_handling==RETURN_ON_FAILURE)
3866         {
3867           shift_lock(getpid(),getpid(),LERROR, LWARNING,LSET);
3868         }
3869       else
3870         {
3871           myexit (EXIT_FAILURE);
3872         }
3873     }
3874   return r;
3875 }
3876   
3877
3878 int safe_system (const char * com_in)
3879 {
3880     pid_t pid;
3881     int   status;
3882
3883     int failure_handling;
3884     char *p;
3885     char command[1000];
3886     
3887     static char *com;
3888
3889     if ( clean_exit_started) return system (com_in);
3890     if ( com)vfree (com);
3891     if ( strstr ( com_in, "SCRATCH_FILE"))
3892       {
3893         com=vcalloc ( strlen ( com_in)+1, sizeof (char));
3894         sprintf ( com, "%s", com_in);
3895         while (strstr ( com, "SCRATCH_FILE"))
3896           {
3897             char *t;
3898             t=vtmpnam(NULL);
3899             com=vrealloc (com, (strlen (com)+strlen (t)+1)*sizeof (char));
3900             
3901             
3902             com=substitute (com,"SCRATCH_FILE", t);
3903           }
3904       }
3905     else
3906       {
3907         com=vcalloc (strlen (com_in)+1, sizeof (char));
3908         sprintf ( com, "%s", com_in);
3909       }
3910     
3911
3912     if (com == NULL)
3913         return (1);
3914     else if ( (p=strstr (com, "::IGNORE_FAILURE::")))
3915       {
3916         p[0]='\0';
3917         failure_handling=IGNORE_FAILURE;
3918       }
3919     else if ( (p=strstr (com, "::RETURN_ON_FAILURE::")))
3920       {
3921         p[0]='\0';
3922         failure_handling=RETURN_ON_FAILURE;
3923       }
3924     else
3925       {
3926         failure_handling=EXIT_ON_FAILURE;
3927       }
3928     
3929               
3930     sprintf ( command, " -SHELL-%s (tc)", com_in);
3931     if ((pid = vvfork (command)) < 0)
3932         return (-1);
3933     
3934     if (pid == 0) 
3935       {
3936         char * argv [4];
3937         
3938         argv [0] = "sh";
3939
3940
3941         argv [1] = "-c";
3942         argv [2] =(char*) com;
3943         argv [3] = 0;
3944         
3945         if ( debug_lock)fprintf (stderr,"\n--- safe_system (util.h): %s (%d)\n", com, getpid());
3946         execvp ("/bin/sh", argv);
3947       }
3948     else
3949       {
3950         set_pid(pid);
3951       }
3952     
3953     
3954     while (1) 
3955       {
3956         int r;
3957         r=vwaitpid (pid, &status, 0);
3958         
3959         
3960         if (errno ==EINTR)r=EXIT_SUCCESS;
3961         else if (r==-1 || status != EXIT_SUCCESS)r=EXIT_FAILURE;
3962         else r=EXIT_SUCCESS;
3963         if ( debug_lock)
3964           fprintf ( stderr, "\n--- safe system return (util.c): p:%d c:%d r:%d (wait for %d", getppid(), getpid(), r, pid);  
3965         return check_process (com_in,pid,r, failure_handling);
3966       }
3967
3968
3969
3970
3971
3972
3973 static int **pidtable;
3974 int assert_pid (pid_t p)
3975 {
3976   if ( p>= MAX_N_PID || p<0)
3977     {
3978       printf_exit (EXIT_FAILURE, stderr, "MAX_N_PID exceded -- Recompile changing the value of MAX_N_PID (current: %d Requested: %d)", MAX_N_PID, p);
3979     }
3980   return 1;
3981 }
3982 pid_t **declare_pidtable ()
3983 {
3984   int a;
3985   
3986   pidtable=vcalloc (MAX_N_PID, sizeof (pid_t*));
3987   for (a=0; a<MAX_N_PID; a++)
3988     {
3989       pidtable[a]=vcalloc (2, sizeof (pid_t));
3990     }
3991   return pidtable;
3992 }
3993 pid_t set_pid (pid_t p)
3994 {
3995
3996   assert_pid (p);
3997   if (!pidtable)declare_pidtable();
3998   if ( p<=0) return (pid_t)0;
3999   pidtable[(int)p][0]=getpid();
4000   pidtable[(int)p][1]=1;
4001   return p;}
4002 pid_t vvfork (char *type)
4003 {
4004   pid_t p;
4005   static int attempt;
4006     
4007   p=fork();
4008   if (p==-1)
4009     {
4010       attempt++;
4011       if ( attempt==1000) 
4012         {
4013           myexit(fprintf_error (stderr,"FORK_ERROR fork returned -1"));
4014           return -1;
4015         }
4016       else 
4017         add_warning (stderr, "Could Not Fork %s [%d/%d tries]", PROGRAM, attempt, 1000);
4018       wait((pid_t*)-1);
4019       return vvfork(type);
4020     }
4021   else
4022     {
4023       attempt=0;
4024       if (p!=0)
4025         {
4026           lock (getpid(), LLOCK, LSET, "%d\n",p);//Update the parent lock
4027           set_pid(p);
4028           return p;
4029         }
4030       else
4031         {
4032           release_all_locks (getpid());
4033           lock (getpid(), LLOCK, LSET, "%d%s\n", getppid(), (type)?type:"");//Create lock for the fork
4034           if (debug_lock)fprintf ( stderr, "\nFORKED (util): p=%d child=%d\n", getppid(), getpid());
4035           
4036           return 0;
4037         }
4038     }
4039 }
4040 int    vwait_npid (int sub, int max, int min)
4041 {
4042   if (max==0)
4043     {
4044       while (sub>0)
4045         {
4046           vwait (NULL);
4047           sub--;
4048         }
4049     }
4050   else if ( sub>=max)
4051     {
4052       while (sub>=min)
4053         {
4054           vwait (NULL);
4055           sub--;
4056         }
4057     }
4058   else{;}
4059   return sub;
4060 }
4061
4062       
4063 pid_t  vwaitpid (pid_t p, int *status, int options)
4064 {
4065
4066   
4067   p=waitpid (p, status, options);
4068     
4069   if (pidtable)
4070     {
4071       assert_pid (p);
4072       pidtable[(int)p][0]=pidtable[(int)p][1]=0;
4073     }
4074   return p;
4075 }
4076 pid_t vwait (pid_t *p)
4077 {
4078   pid_t p2;
4079   int rv=0;
4080   int handle_failure;
4081   
4082   if (atoigetenv("RETURN_ON_FAILURE"))handle_failure=RETURN_ON_FAILURE;
4083   else handle_failure=EXIT_ON_FAILURE;
4084     
4085   
4086   p2=wait (&rv);
4087   if (p2!=-1)rv=check_process("forked::T-Coffee", p2, rv,handle_failure);
4088   if ( p) p[0]=rv;
4089   
4090   return p2;
4091 }
4092
4093
4094 int get_child_list (int pid,int *clist);
4095 int kill_child_list (int *list);
4096 int kill_child_pid(int pid)
4097 {
4098   int *list;
4099   int n,a, cpid;
4100   
4101   cpid=getpid();
4102   list=vcalloc (MAX_N_PID, sizeof (int));
4103   
4104   while ((n=get_child_list (pid,list)))
4105     {
4106       kill_child_list (list);
4107     }
4108   
4109   for (a=0; a<MAX_N_PID; a++)
4110     {
4111       if ( list [a] && a!=cpid)
4112         {
4113           shift_lock (a,cpid, LERROR, LERROR, LSET);
4114           shift_lock (a,cpid, LWARNING, LWARNING, LSET);
4115           lock  (a, LLOCK, LRELEASE, " ");
4116           lock  (a, LERROR,LRELEASE, " ");
4117           lock  (a, LWARNING,LRELEASE, " ");
4118         }
4119     }
4120   return 1;
4121 }
4122
4123 int kill_child_list (int *list)
4124 {
4125   int a;
4126   int cpid=getpid();
4127   for (a=0; a<MAX_N_PID; a++)
4128     {
4129       if (list[a]==1 && a!=cpid)
4130         {
4131           kill (a, SIGTERM);
4132           list[a]=-1;
4133         }
4134     }
4135 }
4136           
4137 int get_child_list (int pid,int *clist)
4138 {
4139   char ***list;
4140   char *lockf;
4141   int a;
4142   int n=0;
4143   
4144   assert_pid (pid);
4145   clist[pid]++;
4146   if (clist[pid]>1)
4147     {
4148           add_information ( stderr, "Corrupted Lock System" );
4149           for (a=0; a<MAX_N_PID; a++)release_all_locks (a);
4150           return 0;
4151
4152     }
4153         
4154   lockf=lock2name (pid, LLOCK);
4155   if ( lockf && file_exists (NULL,lockf)) 
4156     {
4157       list=file2list (lockf, "\n");
4158       
4159       a=1;
4160       while (list && list[a])
4161         {
4162           n+=get_child_list (atoi(list[a++][1]), clist);
4163         }
4164       free_arrayN ((void **)list, 3);
4165     }
4166   vfree (lockf);
4167   
4168   if (!clist[pid]){clist[pid]=1; n++;}
4169   return n;
4170 }
4171
4172
4173 int kill_child_pid_pld()
4174 {
4175   int n;
4176   string2file (logfile, "a","\n----TC: %d kill ALL CHILDREN", getpid());
4177   
4178   //  kill (0, SIGTERM); //send a sigterm to ALL children processes
4179   //return 1;
4180   
4181   if ( !pidtable)return 0;
4182   else
4183     {
4184       int a;
4185       pid_t cpid;
4186       cpid=getpid();
4187       for (a=0; a<MAX_N_PID; a++)
4188         {
4189           if (pidtable[a][1] && pidtable[a][0]==cpid )
4190             {
4191               if (debug_lock)fprintf ( stderr, "\n--- KILL %d from TC (%d)\n", a, getpid());
4192               
4193               pidtable[a][1]=pidtable[a][0]=0;
4194               kill((pid_t)a, SIGTERM);
4195               //lock (a, LLOCK, LRELEASE, "");
4196               shift_lock(a,getpid(),LERROR,LERROR, LSET);
4197               shift_lock(a,getpid(),LWARNING,LWARNING, LSET);
4198               
4199               n++;
4200             }
4201         }
4202     }
4203   return n;
4204 }
4205           
4206
4207
4208
4209 void unpack_all_perl_script (char *script)
4210 {
4211   int a=0;
4212   FILE *fp;
4213   char command[1000];
4214   
4215   while ( !strm(PerlScriptName[a], "EndList"))
4216     {
4217       if (script==NULL || strm (script, "all") ||strm (script, "perl_script")|| strm (script,PerlScriptName[a]))
4218         {
4219           fprintf ( stderr, "\nUnpack Script %s\n", PerlScriptName[a]);
4220           fp=vfopen ( PerlScriptName[a], "w");
4221           fprintf (fp, "%s\n%s\n", PERL_HEADER,PerlScriptFile[a]);
4222           vfclose (fp);
4223           sprintf ( command, "chmod u+x %s",PerlScriptName[a] );
4224           safe_system (command);
4225         }
4226       a++;
4227     }
4228   myexit (EXIT_SUCCESS);
4229 }
4230 int satoi (char *);
4231 int satoi (char *c)
4232 {
4233   if ( !c)return 0;
4234   else return atoi (c);
4235 }
4236   
4237 int unpack_perl_script (char *name, char ***unpacked, int n)
4238 {
4239   int a=0;
4240   
4241
4242   set_file2remove_extension(".pl", SET);
4243   
4244   
4245   if ( name==NULL) unpack_all_perl_script (NULL);
4246   while ( !strm(PerlScriptName[a], "EndList") && !strm ( name, PerlScriptName[a]))
4247     {
4248       a++;
4249     }
4250   
4251   if ( strm(PerlScriptName[a], "EndList")|| (check_file_exists (name) && isexec(name) && satoi(getenv("RUN_LOCAL_SCRIPT"))) || (pg_is_installed (name) &&(satoi(getenv("RUN_LOCAL_SCRIPT"))) ))
4252        {
4253          if ( check_file_exists (name) && ! strstr (name, "/") && isexec(name) && satoi(getenv ("RUN_LOCAL_SCRIPT")))
4254            {
4255              add_warning ( stderr, "Local Copy of %s detected [Debug mode]. DELETE this file", name);
4256              sprintf ( unpacked[0][n], "%s", name);
4257              sprintf ( unpacked[1][n], "./%s", name);
4258              sprintf ( unpacked[2][n], "shell");
4259            }
4260          else if ( pg_is_installed (name) &&satoi(getenv("RUN_LOCAL_SCRIPT")) )
4261            {
4262              add_warning ( stderr, "Running external copy of %s [Debug mode].", name);
4263              sprintf ( unpacked[0][n], "%s", name);
4264              sprintf ( unpacked[1][n], "%s", name);
4265              sprintf ( unpacked[2][n], "local");
4266            }
4267          else if ( strstr (name, "t_coffee"))
4268            {
4269              /*Cygwin pb: t_coffee cannot call itself: making a local copy for recursion*/
4270              char buf[1000];
4271              char *b2;
4272              b2=vtmpnam (NULL);
4273              sprintf (buf, "cp `which %s` %s; chmod u+x %s",name, b2, b2);
4274              safe_system (buf);
4275              sprintf ( unpacked[0][n], "%s", name);
4276              sprintf ( unpacked[1][n], "%s", b2);
4277              sprintf ( unpacked[2][n], "shell");
4278              
4279            }
4280          else
4281            {
4282              sprintf ( unpacked[0][n], "%s", name);
4283              sprintf ( unpacked[1][n], "%s", name);
4284              sprintf ( unpacked[2][n], "shell");
4285            }
4286        }
4287   else
4288     {
4289       FILE *fp;
4290       sprintf ( unpacked[0][n], "%s", name);
4291       sprintf ( unpacked[1][n], "%s", vtmpnam(NULL));
4292       sprintf ( unpacked[2][n], "unpack");
4293       fp=vfopen (unpacked[1][n], "w");
4294       fprintf (fp, "%s\n%s\n", PERL_HEADER,PerlScriptFile[a]);            
4295       vfclose (fp);
4296       printf_system_direct ("chmod u+x %s", unpacked[1][n]);
4297       
4298     }
4299   
4300   set_file2remove_extension(".pl", UNSET);
4301   return ++n;
4302 }
4303         
4304 /*********************************************************************/
4305 /*                                                                   */
4306 /*                         IO FUNCTIONS                              */
4307 /*                                                                   */
4308 /*                                                                   */
4309 /*********************************************************************/
4310 char *program_name;
4311 char *error_file;
4312 void   set_command_line (char *cl)
4313 {
4314   in_cl=vcalloc ( strlen (cl)+1, sizeof (char));
4315   sprintf (in_cl, "%s", cl);
4316 }
4317 FILE * print_command_line (FILE *fp )
4318 {
4319   fprintf ( fp, "# Command Line: %s [PROGRAM:%s]\n",in_cl, PROGRAM);
4320   return fp;
4321 }
4322 int check_dir_getenv ( char *string);
4323 char *get_plugins_4_tcoffee_old ( char *mode)
4324 {
4325   static char *plugins_4_tcoffee;
4326   
4327   if ( !plugins_4_tcoffee)plugins_4_tcoffee=vcalloc ( 1000, sizeof (char));
4328   
4329   if (mode)plugins_4_tcoffee[0]='\0';
4330
4331   
4332   if ( plugins_4_tcoffee[0])return plugins_4_tcoffee;
4333   else if ( mode) sprintf (plugins_4_tcoffee, "%s", mode);
4334   else if ( check_dir_getenv ("PLUGINS_4_TCOFFEE"))
4335     {
4336       sprintf (plugins_4_tcoffee, "%s", getenv ("PLUGINS_4_TCOFFEE"));
4337     }
4338   else
4339     {
4340       sprintf (plugins_4_tcoffee, "%s/plugins/%s/", get_dir_4_tcoffee(), get_os());
4341     }
4342   //if (!isdir (plugins_4_tcoffee)){printf_exit (EXIT_FAILURE, stderr, "ERROR: The declared plugin directory for T-Coffee is invalid: [%s] [FATAL:%s %s]", plugins_4_tcoffee, PROGRAM, VERSION); }
4343   return plugins_4_tcoffee;
4344 }
4345 char *get_home_4_tcoffee ()
4346 {
4347   static char *home_4_tcoffee;
4348   static char home[1000];
4349   
4350
4351   if ( !home_4_tcoffee)
4352     home_4_tcoffee=vcalloc ( 1000, sizeof (char));
4353   
4354   if ( home_4_tcoffee[0])return home_4_tcoffee;
4355   else if ( check_dir_getenv ("HOME_4_TCOFFEE"))
4356     {
4357       sprintf (home_4_tcoffee, "%s/", getenv ("HOME_4_TCOFFEE"));
4358     }
4359   else if ( check_dir_getenv ("HOME"))
4360     {
4361       sprintf (home_4_tcoffee, "%s/", getenv ("HOME"));
4362       sprintf (home, "%s/", home_4_tcoffee);
4363     }
4364   else if ( check_dir_getenv ("TMP"))
4365     {
4366       sprintf (home_4_tcoffee, "%s/", getenv ("TMP"));
4367     }
4368   else if (check_dir_getenv ("TEMP"))
4369     {
4370       sprintf (home_4_tcoffee, "%s/", getenv ("TEMP"));
4371     }
4372   else 
4373     {
4374       printf_exit (EXIT_FAILURE, stderr, "ERROR: Could not set a HOME directory.\nSet any of the following environement variables to some suitable location: HOME, HOME_4_TCOFFEE, TMP or TEMP [FATAL:%s]\n", PROGRAM);
4375     }
4376   
4377  
4378   return home_4_tcoffee;
4379 }
4380 char *get_dir_4_tcoffee()
4381 {
4382   static char dir_4_tcoffee[1000];
4383    
4384   if (dir_4_tcoffee[0])return dir_4_tcoffee;
4385   else
4386     {
4387       if ( getenv ("UNIQUE_DIR_4_TCOFFEE"))sprintf (dir_4_tcoffee, "%s/", getenv("UNIQUE_DIR_4_TCOFFEE"));
4388       else if ( getenv ("DIR_4_TCOFFEE"))sprintf (dir_4_tcoffee, "%s/", getenv("DIR_4_TCOFFEE"));
4389       else sprintf ( dir_4_tcoffee, "%s/.t_coffee/",get_home_4_tcoffee());
4390       my_mkdir (dir_4_tcoffee);
4391     }
4392   return dir_4_tcoffee;
4393 }
4394 char *get_tmp_4_tcoffee ()
4395 {
4396   static char tmp_4_tcoffee [1000];
4397   
4398   if ( tmp_4_tcoffee[0])return tmp_4_tcoffee;
4399   else
4400     {
4401       char *v=getenv("TMP_4_TCOFFEE");
4402       char buf[1000];
4403       char host[1024];
4404       gethostname(host, 1023);
4405       if (getenv ("UNIQUE_DIR_4_TCOFFEE"))sprintf (tmp_4_tcoffee, "%s/", getenv("UNIQUE_DIR_4_TCOFFEE"));
4406       else if (v && strstr (v, "TMP"))sprintf (tmp_4_tcoffee, "%s/", getenv("TMP_4_TCOFFEE"));
4407       else if (v && strstr (v, "LOCAL"))sprintf (tmp_4_tcoffee, "%s/", getcwd(NULL,0));
4408       else if (v && strstr (v, "."))sprintf (tmp_4_tcoffee, "%s/", getcwd(NULL,0));
4409       else if (v)sprintf (tmp_4_tcoffee, "%s", v);
4410       else if (isdir("/var/tmp"))sprintf (tmp_4_tcoffee, "/var/tmp/");
4411       else sprintf (tmp_4_tcoffee, "%s/", getcwd(NULL,0));
4412       
4413       //now that rough location is decided, create the subdir structure
4414        if (is_rootpid())
4415         {
4416           sprintf (buf, "%s/t_coffee.tmp.%s/tmp.%d/", tmp_4_tcoffee, host,getpid());
4417           sprintf (tmp_4_tcoffee, "%s", buf);
4418           my_mkdir(tmp_4_tcoffee);
4419           my_rmdir(tmp_4_tcoffee);
4420           my_mkdir(tmp_4_tcoffee);
4421         }
4422     }
4423
4424   return tmp_4_tcoffee;
4425 }
4426 char *get_cache_4_tcoffee ()
4427 {
4428
4429   static char cache_4_tcoffee [1000];
4430   if ( cache_4_tcoffee[0])return cache_4_tcoffee;
4431   else
4432     {
4433       if (getenv ("UNIQUE_DIR_4_TCOFFEE"))sprintf (cache_4_tcoffee, "%s/", getenv("UNIQUE_DIR_4_TCOFFEE"));
4434       else if ( getenv ("CACHE_4_TCOFFEE"))sprintf (cache_4_tcoffee, "%s/", getenv("CACHE_4_TCOFFEE"));
4435       else sprintf ( cache_4_tcoffee, "%s/cache/", get_dir_4_tcoffee());
4436       
4437       my_mkdir(cache_4_tcoffee); /*Do not use mkdir: not yet initialized*/
4438     }
4439   return cache_4_tcoffee;
4440 }
4441
4442 char *get_mcoffee_4_tcoffee ()
4443 {
4444   static char mcoffee_4_tcoffee [1000];
4445   if ( mcoffee_4_tcoffee[0])return mcoffee_4_tcoffee;
4446   else
4447     {
4448       if (getenv ("UNIQUE_DIR_4_TCOFFEE"))sprintf (mcoffee_4_tcoffee, "%s/", getenv("UNIQUE_DIR_4_TCOFFEE"));
4449       else if ( getenv ("MCOFFEE_4_TCOFFEE"))sprintf (mcoffee_4_tcoffee, "%s/", getenv("MCOFFEE_4_TCOFFEE"));
4450       else sprintf ( mcoffee_4_tcoffee, "%s/mcoffee/", get_dir_4_tcoffee());
4451       my_mkdir (mcoffee_4_tcoffee);
4452     }
4453   return mcoffee_4_tcoffee;
4454 }
4455 char *get_methods_4_tcoffee ()
4456 {
4457   static char methods_4_tcoffee [1000];
4458   if ( methods_4_tcoffee[0])return methods_4_tcoffee;
4459   else
4460     {
4461       if (getenv ("UNIQUE_DIR_4_TCOFFEE"))sprintf (methods_4_tcoffee, "%s/", getenv("UNIQUE_DIR_4_TCOFFEE"));
4462       else if ( getenv ("METHODS_4_TCOFFEE"))sprintf (methods_4_tcoffee, "%s/", getenv("METHODS_4_TCOFFEE"));
4463       else sprintf ( methods_4_tcoffee, "%s/methods/", get_dir_4_tcoffee());
4464       my_mkdir (methods_4_tcoffee);
4465     }
4466   return methods_4_tcoffee;
4467 }
4468
4469 char *get_plugins_4_tcoffee ()
4470 {
4471   static char plugins_4_tcoffee [1000];
4472   if ( plugins_4_tcoffee[0])return plugins_4_tcoffee;
4473   else
4474     {
4475       if (getenv ("UNIQUE_DIR_4_TCOFFEE"))sprintf (plugins_4_tcoffee, "%s/", getenv("UNIQUE_DIR_4_TCOFFEE"));
4476       else if (isdir4path (getenv("PLUGINS_4_TCOFFEE")))sprintf (plugins_4_tcoffee, "%s/", getenv("PLUGINS_4_TCOFFEE"));
4477       else sprintf (plugins_4_tcoffee, "%s/plugins/%s/", get_dir_4_tcoffee(), get_os());
4478       my_mkdir(plugins_4_tcoffee);
4479     }
4480   return plugins_4_tcoffee;
4481 }
4482 char *get_lockdir_4_tcoffee ()
4483 {
4484   static char lockdir_4_tcoffee [1000];
4485   char *v;
4486   
4487   if ( lockdir_4_tcoffee[0])return lockdir_4_tcoffee;
4488   else
4489     {
4490       char buf[1000];
4491       v=getenv ("LOCKDIR_4_TCOFFEE");
4492       if (getenv ("UNIQUE_DIR_4_TCOFFEE"))sprintf (lockdir_4_tcoffee, "%s/", get_tmp_4_tcoffee());
4493       else if (v)sprintf (lockdir_4_tcoffee, "%s/", v);
4494       else sprintf (lockdir_4_tcoffee, "%s/", get_tmp_4_tcoffee());
4495     }
4496   
4497   
4498   return lockdir_4_tcoffee;
4499 }
4500
4501
4502 int get_nproc ()
4503 {
4504   static int nproc;
4505
4506   if (nproc);
4507   else if ( get_int_variable ("n_core"))
4508     {
4509       nproc=get_int_variable ("n_core");
4510     }
4511   else if ( getenv ("NUMBER_OF_PROCESSORS_4_TCOFFEE"))
4512     {
4513       nproc=atoi(getenv ("NUMBER_OF_PROCESSORS_4_TCOFFEE"));
4514     }
4515   else if ( getenv ("NUMBER_OF_PROCESSORS"))
4516     {
4517       nproc=atoi(getenv ("NUMBER_OF_PROCESSORS"));
4518     }
4519   else if ( file_exists (NULL,"/proc/cpuinfo"))
4520     {
4521       char *tmp;
4522       char string[100];
4523       tmp=vtmpnam (NULL);
4524       printf_system_direct ("grep \"^processor\" /proc/cpuinfo | wc -l>%s", tmp);
4525       sprintf ( string, "%s", file2string (tmp));
4526       chomp (string);
4527       nproc=atoi (string);
4528     }
4529   else  
4530     nproc=1;
4531     
4532   return nproc;
4533 }
4534
4535   
4536
4537
4538
4539 char * get_os()
4540 {
4541   static char os[100];
4542   char *file;
4543   
4544   if ( os[0])return os;
4545   else
4546     {
4547       char *s;
4548
4549       file=tmpnam (NULL);
4550       printf_system_direct ("uname > %s", file);
4551
4552       s=file2string (file);
4553       lower_string (s);
4554       
4555       if (strstr (s, "cygwin"))sprintf ( os, "windows");
4556       else if ( strstr (s, "linux"))sprintf ( os, "linux");
4557       else if ( strstr (s, "osx"))sprintf ( os, "macosx");
4558       else if ( strstr (s, "darwin"))sprintf ( os, "macosx");
4559       else sprintf (os, "linux");
4560       vfree (s);
4561       vremove (file);
4562     }
4563   return os;
4564 }
4565
4566
4567
4568
4569   
4570 int cputenv (char *string, ...) 
4571 {
4572   
4573
4574
4575
4576
4577   char *s;
4578   char *s2;
4579   int r;
4580   
4581
4582   if (!string)return 0;
4583   
4584   cvsprintf (s, string);
4585   
4586   s2=vcalloc (strlen (s)+1, sizeof (char));
4587   sprintf ( s2, "%s", s);
4588   
4589   r=putenv (s2);
4590   //vfree (s); //Potential leak
4591   return r;
4592 }
4593
4594
4595 int fcputenv   (char *file, char *mode,char * string, ...)
4596 {
4597   va_list ap;
4598   FILE *fp;
4599   if (!string)return 0;
4600   
4601   if (!(fp=vfopen (file, mode)))return 0;
4602   
4603   va_start (ap, string);
4604   vfprintf (fp, string, ap);
4605   vfclose (fp);
4606   va_end (ap);
4607   return 1;
4608 }
4609 int isdir4path (char *p)
4610 {
4611    if ( !p) return 0;
4612    if ( !p || access (p, F_OK)==-1 || access (p, W_OK)==-1 || access(p, R_OK)==-1 || access (p, X_OK)==-1)return 0;
4613    
4614    return 1;
4615 }
4616 int check_dir_getenv ( char *string)
4617 {
4618   char *p;
4619   return (isdir4path(p=getenv ( string)));
4620
4621 }
4622
4623
4624
4625
4626 int  set_unique_dir_4_tcoffee (char *dir);
4627 int  set_unique_dir_4_tcoffee (char *dir)
4628 {
4629   static char **string;
4630   int m, n;
4631   m=n=0;
4632   if ( !dir || !isdir(dir) || strm (dir, "no"))return 0;
4633   string=declare_char (10, 100);
4634   sprintf ( string[m++], "DIR_4_TCOFFEE=%s", dir);putenv (string[n++]);
4635   sprintf ( string[m++], "CACHE_4_TCOFFEE=%s", dir);putenv (string[n++]);
4636   sprintf ( string[m++], "TMP_4_TCOFFEE=%s", dir);putenv (string[n++]);
4637   sprintf ( string[m++], "PLUGINS_4_TCOFFEE=%s", dir);putenv (string[n++]);
4638   sprintf ( string[m++], "MCOFFEE_4_TCOFFEE=%s", dir);putenv (string[n++]);
4639   sprintf ( string[m++], "METHODS_4_TCOFFEE=%s", dir);putenv (string[n++]);
4640   
4641   return 1;
4642 }
4643
4644
4645
4646   
4647
4648 void myexit (int signal)
4649 {
4650     
4651   if (clean_exit_started==1)return; //protects processes while they are doing a clean exit
4652   global_exit_signal=signal;
4653   exit (global_exit_signal); //ONLY BARE EXIT!!!!!!!!!!!!!!
4654 }
4655
4656
4657 static int n_warning;
4658 static char **warning_list;
4659
4660 FILE *fatal_exit (FILE *fp,int exit_mode, char *string, ...)
4661 {
4662   va_list ap;
4663   va_start (ap, string);
4664   vfprintf (fp, string, ap);
4665   va_end (ap);
4666   myexit (exit_mode);
4667   return fp;
4668 }
4669 static int warning_mode;
4670 int set_warning_mode ( int mode)
4671 {
4672   warning_mode=mode;
4673   return mode;
4674 }
4675
4676 int  fprintf_error( FILE *fp, char *string, ...)
4677 {
4678   char *msg;
4679   
4680   cvsprintf (msg, string);
4681   msg=substitute ( msg, "\n", "");
4682   msg=substitute ( msg, "ERROR", " ");
4683   if (fp)fprintf ( fp, "\n--ERROR: %s\n", msg);
4684   if ( clean_exit_started) return EXIT_FAILURE;
4685   
4686   lock (getpid(), LERROR,LSET,"%d -- ERROR: %s\n",getpid(),msg);
4687   lock (getpid(), LERROR,LSET,"%d -- COM: %s\n",getpid(),in_cl);
4688   lock (getpid(), LERROR, LSET,"%d -- STACK: %d -> %d\n",getpid(), getppid(),getpid());
4689   
4690   vfree (msg);
4691   return EXIT_FAILURE;
4692 }
4693 void printf_exit  (int exit_code, FILE *fp, char *string, ...)
4694 {
4695   char *msg;
4696   
4697   cvsprintf (msg, string);
4698   myexit(fprintf_error (fp,msg));
4699   myexit (exit_code);
4700 }
4701
4702
4703 FILE *add_warning (FILE *fp, char *string, ...)
4704 {
4705   char *buf;
4706     
4707   if ( warning_mode==NO || getenv("NO_WARNING_4_TCOFFEE"))return fp;
4708   else
4709     {
4710       
4711       cvsprintf (buf, string);
4712       if (fp)fprintf (fp, "\npid %d -- %s\n",getpid(), buf);
4713       if ( clean_exit_started)return fp;
4714       
4715       
4716       lock(getpid(),LWARNING, LSET, "%d -- WARNING: %s\n", getpid(),buf);
4717       vfree (buf);
4718     }
4719   return fp;
4720 }
4721 FILE *add_information (FILE *fp, char *string, ...)
4722 {
4723   char *buf;
4724     
4725   if ( warning_mode==NO || getenv("NO_INFORMATION_4_TCOFFEE"))return fp;
4726   else
4727     {
4728       
4729       cvsprintf (buf, string);
4730       if (fp)fprintf (fp, "\npid %d -- %s\n",getpid(), buf);
4731       if ( clean_exit_started)return fp;
4732       
4733       
4734       lock(getpid(),LWARNING, LSET, "%d -- INFORMATION: %s\n", getpid(),buf);
4735       vfree (buf);
4736     }
4737   return fp;
4738 }
4739
4740     
4741  
4742 int   count_n_res_in_array  (char *array, int len)
4743       {
4744         return count_n_symbol_in_array(array, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", len);
4745       }
4746 int   count_n_gap_in_array  (char *array, int len)
4747       {
4748         int l;
4749         if ( len<=0 ||len>strlen(array) )l=strlen(array);
4750         else l=len;
4751         
4752         return l- count_n_res_in_array (array,len);
4753       }
4754 int count_n_symbol_in_array ( char *array, char *array_list, int len)
4755       {
4756         int a=0, t=0;
4757         int l;
4758         
4759         if ( len<=0 ||len>strlen(array) )l=strlen(array);
4760         else l=len;
4761
4762         for ( a=0; a< l; a++)t+=is_in_set (array[a], array_list);
4763         return t;
4764       }
4765
4766 char* count_strings_in_file ( char *in, char *out)
4767 {
4768   FILE *fp;
4769   int n,c;
4770   char **list, **result;
4771
4772   
4773   if (!out) out=vtmpnam (NULL);
4774   list=declare_char (count_n_line_in_file(in)+1, measure_longest_line_in_file (in)+1);
4775   
4776   n=0;
4777   fp=vfopen (in, "r");
4778   while ((c=fgetc (fp))!=EOF)
4779     {
4780       ungetc (c, fp);
4781       fscanf (fp, "%s\n",list[n]);
4782       n++;
4783     }
4784   vfclose (fp);
4785   
4786   result=count_strings (list, n);
4787   
4788   
4789   n=0;
4790   fp=vfopen (out, "w");
4791   while (result[n])fprintf ( fp,"%s\n", result[n++]);
4792   vfclose (fp);
4793   
4794   free_char (list, -1);
4795   free_char (result, -1);
4796   
4797   return out;
4798 }
4799
4800 int ** count_int_strings (int **array, int len, int s)
4801 {
4802   int **result;
4803   int a,n;
4804   
4805   sort_list_int (array,s, s,0, len-1);
4806   result=vcalloc (len, sizeof (int*));
4807   for (n=-1,a=0; a<len; a++)
4808     {
4809       if (n==-1 || memcmp (array[a], result[n], sizeof (int)*s)!=0)
4810         {
4811           n++;
4812           result[n]=vcalloc (s+1, sizeof (int));
4813           memcpy (result[n],array[a], sizeof (int)*s);
4814           fprintf ( stdout, "*");
4815         }
4816       result[n][s]++;
4817     }
4818   sort_int (result, s+1, s, 0, n);
4819   result=vrealloc ( result, sizeof (int*)*n);
4820   return result;
4821 }
4822   
4823 char** count_strings ( char **array, int len)
4824 {
4825   int a, c, n;
4826   char *cs;
4827   char **result;
4828   
4829   result=vcalloc (len+1, sizeof (char*));
4830   array=sort_string_array (array, len);
4831
4832   for (c=0, a=0, n=0, cs=NULL; a< len; a++)
4833     {
4834       if (cs == NULL || !strm (cs, array[a]))
4835         {
4836           if (cs)
4837             {
4838               result[c]=vcalloc (strlen (cs)+20, sizeof (char));
4839               sprintf ( result[c], "%s %d", cs, n);
4840               c++;
4841             }
4842           
4843           n=1;
4844           cs=array[a];
4845         }
4846       else n++;
4847     }
4848   
4849   result[c]=vcalloc (strlen (cs)+20, sizeof (char));
4850   sprintf ( result[c], "%s %d", cs, n);
4851  
4852   return result;
4853 }
4854           
4855 int   get_first_non_white_char (char *name)
4856 {
4857   if ( !name) return 0;
4858   else if ( !file_exists (NULL,name))return 0;
4859   else
4860     {
4861       FILE *fp;
4862       char c;
4863       
4864       fp=vfopen (name, "r");
4865       while (isspace ((c=fgetc (fp)))&& c!=EOF);
4866       vfclose (fp);
4867       return c;
4868     }
4869 }
4870 int   count_n_char_x_in_file(char *name, char x)
4871       {
4872       FILE *fp;
4873       int n, c;
4874
4875       n=0;
4876       fp=vfopen(name, "r");
4877       while ( (c=fgetc(fp))!=EOF)n+=(c==x);
4878       vfclose (fp);
4879       return n;
4880       }
4881 int   count_n_char_in_file(char *name)
4882       {
4883       int  c, n;
4884       FILE *fp;
4885
4886       n=0;
4887       fp=vfopen(name, "r");
4888       while ( (c=fgetc(fp))!=EOF){n++;}
4889       vfclose (fp);
4890       return n;
4891       }
4892 int count_n_line_in_file ( char *name )
4893      {
4894       int  c, n;
4895       FILE *fp;
4896
4897       n=0;
4898       fp=vfopen(name, "r");
4899       while ( (c=fgetc(fp))!=EOF)n+=(c=='\n');
4900       vfclose (fp);
4901       return n;
4902       }
4903 int measure_longest_line_in_file ( char *name )
4904      {
4905       int  c;
4906       FILE *fp;
4907       int longest=0;
4908       int current=0;
4909
4910
4911       fp=vfopen(name, "r");
4912       while ( (c=fgetc(fp))!=EOF)
4913           {
4914               if ( c=='\n'){longest=MAX(longest, current+1);current=0;}
4915               else current++;
4916           }
4917       longest=MAX(longest, current+1);
4918
4919       vfclose (fp);
4920       return longest;
4921       }
4922 char *input_name ()
4923         {
4924         char *string;
4925         int a;
4926         char ch;
4927         
4928         string= vcalloc ( 500, sizeof ( char));
4929         
4930         a=0;
4931         while ( ( ch=getchar())!='\n' && a<500)
4932                         string[a++]=ch;
4933         string[a]='\0'; 
4934         
4935         if ( string[0]=='\0')
4936                 {
4937                 vfree (string);
4938                 return NULL;
4939                 }
4940         else
4941                 return string;
4942         }
4943
4944 FILE * vtmpfile()
4945     {
4946         return tmpfile();
4947     }
4948 int string_variable_isset (char *name)
4949 {
4950   if (store_string_variable (name,NULL, ISSET)==NULL)return 0;
4951   else return 1;
4952 }
4953 char* set_string_variable (char *name, char * v)
4954 {
4955   return store_string_variable (name, v, SET);
4956 }
4957 char * get_string_variable (char *name)
4958 {
4959   return store_string_variable (name,NULL, GET);
4960 }
4961 char* unset_string_variable (char *name)
4962 {
4963   return store_string_variable (name,0, UNSET);
4964 }
4965
4966 char* store_string_variable (char *name, char* v, int mode)
4967 {
4968   static char **name_array, **val_array;
4969   static int n;
4970   int a;
4971   
4972   if ( mode == SET)
4973     {
4974       
4975       for (a=0; a<n; a++)
4976         {
4977           if ( strm (name,name_array[a]))
4978             {
4979               if (v)
4980                 {
4981                   val_array[a]=vrealloc (val_array[a], strlen (v)+1);
4982                   sprintf (val_array[a],"%s",v);
4983                 }
4984               else val_array[a]='\0';
4985               return v;
4986             }
4987         }
4988       if (!name_array)
4989         {
4990           name_array=vcalloc (1, sizeof (char*));
4991           val_array=vcalloc  (1, sizeof (char*));
4992         }
4993       else
4994         {
4995           name_array=vrealloc (name_array, (n+1)*sizeof (char*));
4996           val_array=vrealloc (val_array, (n+1)*sizeof (char*));
4997         }
4998       name_array[n]=vcalloc ( strlen (name)+1, sizeof (char));
4999       val_array[n]=vcalloc ( strlen (v)+1, sizeof (char));
5000       
5001       sprintf ( name_array[n], "%s", name);
5002       sprintf ( val_array[n], "%s", v);
5003       n++;
5004       
5005       return v;
5006       
5007     }
5008   else if ( mode == ISSET)
5009     {
5010        for (a=0; a<n; a++) 
5011          if ( strm (name_array[a], name))return (char *)1;
5012     }
5013   else if ( mode == UNSET)
5014     {
5015       for (a=0; a<n; a++) 
5016         if ( strm (name_array[a], name))
5017           {
5018             name_array[a][0]='\0';
5019             val_array[a][0]='\0';
5020             return 0;
5021           }
5022       add_warning (stdout, "Could not UNSET the value of %s. You must SET the value before it is used", name);
5023     }
5024   else if (mode==GET)
5025     {
5026       for (a=0; a<n; a++) 
5027         {
5028           if ( strm (name_array[a], name))
5029             return val_array[a];
5030         }
5031     }
5032   return NULL;
5033 }
5034 int int_variable_isset (char *name)
5035 {
5036   return store_int_variable (name,0, ISSET);
5037 }
5038 int set_int_variable (char *name, int v)
5039 {
5040   return store_int_variable (name, v, SET);
5041 }
5042 int get_int_variable (char *name)
5043 {
5044   return store_int_variable (name, 0, GET);
5045 }
5046 int unset_int_variable (char *name)
5047 {
5048   return store_int_variable (name,0, UNSET);
5049 }
5050
5051 int store_int_variable (char *name, int v, int mode)
5052 {
5053   static char **name_array; 
5054   static int *val_array;
5055   static int n;
5056   int a;
5057   
5058   if ( mode == SET)
5059     {
5060       for (a=0; a<n; a++)
5061         {
5062           if ( strm (name,name_array[a]))
5063             {
5064               val_array[a]=v;
5065               return v;
5066             }
5067         }
5068       if (!name_array)
5069         {
5070           name_array=vcalloc (1, sizeof (char*));
5071           val_array=vcalloc  (1, sizeof (int));
5072         }
5073       else
5074         {
5075           name_array=vrealloc (name_array, (n+1)*sizeof (char*));
5076           val_array=vrealloc (val_array, (n+1)*sizeof (int));
5077         }
5078       name_array[n]=vcalloc ( strlen (name)+1, sizeof (char));
5079       sprintf ( name_array[n], "%s", name);
5080       val_array[n]=v;
5081       n++;
5082       
5083       return v;
5084       
5085     }
5086   else if ( mode == ISSET)
5087     {
5088        for (a=0; a<n; a++) 
5089          if ( strm (name_array[a], name))return 1;
5090     }
5091   else if ( mode == UNSET)
5092     {
5093       for (a=0; a<n; a++) 
5094         if ( strm (name_array[a], name))
5095           {
5096             name_array[a][0]='\0';
5097             val_array[a]=0;
5098             return 0;
5099           }
5100       add_warning (stdout, "Could not UNSET the value of %s. You must SET the value before it is used", name);
5101     }
5102   else if (mode==GET)
5103     {
5104       for (a=0; a<n; a++) 
5105         {
5106           if ( strm (name_array[a], name))
5107             return val_array[a];
5108         }
5109     }
5110   return 0;
5111 }
5112
5113       
5114 char * get_proxy_from_env ()
5115 {
5116   char *proxy=NULL;
5117   
5118   if ((proxy=get_string_variable ("cl_proxy"))){;}//Command line proxy always wins
5119   else if ((proxy=getenv ("http_proxy_4_TCOFFEE"))); 
5120   else if ((proxy=get_string_variable ("proxy")));//use default T-Coffee proxy
5121   else if ( getenv ("HTTP_proxy") && getenv ("http_proxy")){return getenv ("HTTP_proxy");}//get environement proxy
5122   else if ((proxy=getenv ("HTTP_proxy")));//id 
5123   else if ((proxy=getenv ("http_proxy")));//id
5124   else if ((proxy=getenv ("HTTP_PROXY")));//id
5125   else if ((proxy=getenv ("ALL_proxy")));//id
5126   else if ((proxy=getenv ("all_proxy")));//id
5127   else if ((proxy=getenv ("ALL_PROXY")));//id
5128   
5129   if (proxy)set_proxy(proxy);
5130   else
5131     {proxy=vcalloc (1, sizeof(char));}
5132       
5133   return proxy;
5134 }
5135 char *get_proxy ()
5136 {
5137   return get_proxy_from_env ();
5138 }
5139 int set_proxy (char *proxy)
5140 {
5141
5142   if (!proxy) return 0;
5143   
5144   cputenv ("HTTP_proxy_4_TCOFFEE=%s", proxy);
5145   cputenv ("HTTP_proxy=%s", proxy);
5146   cputenv ("http_proxy=%s", proxy);
5147   cputenv ("HTTP_PROXY=%s", proxy);
5148   cputenv ("ALL_proxy=%s", proxy);
5149   cputenv ("ALL_PROXY=%s", proxy);
5150   cputenv ("all_proxy=%s", proxy);
5151   
5152   return 1;
5153 }
5154
5155 FILE* warning_msg(FILE*fp)
5156 {
5157   char *msg;
5158
5159   msg=lock ( getpid(),LWARNING, LREAD,NULL);
5160   if (!msg) return fp;
5161   fprintf ( fp, "\n\n");
5162   fprintf ( fp, "*************************************************************************************************\n");
5163   fprintf ( fp, "*                        MESSAGES RECAPITULATION                                    \n");
5164   fprintf ( fp, "%s",msg);
5165   fprintf ( fp, "*************************************************************************************************\n");
5166   return fp;
5167 }
5168 FILE* stack_msg(FILE*fp)
5169 {
5170   char *error;
5171
5172   error=lock ( getpid(),LERROR, LREAD,NULL);
5173   if (!error)return fp;
5174   fprintf ( fp, "\n\n");
5175   fprintf ( fp, "*************************************************************************************************\n");
5176   fprintf ( fp, "*                        FULL TRACE BACK PID: %d                                    \n", getpid());
5177   fprintf ( fp, "%s", error);
5178   fprintf ( fp, "*************************************************************************************************\n");
5179   return fp;
5180 }
5181 FILE * install_msg(FILE *fp)
5182 {
5183   fprintf ( fp, "\n\n");
5184   fprintf ( fp, "*************************************************************************************************\n");
5185   fprintf ( fp, "*                        CONFIGURATION: Missing Package                                     \n");
5186   fprintf ( fp, "*                                                                                               \n");
5187   fprintf ( fp, "*                                                                                               \n");
5188   fprintf ( fp, "* It looks like a package is either not installed or not on your PATH\n (see trace)\n"); 
5189   fprintf ( fp, "* If it is on your path, declare its location:\n");
5190   fprintf ( fp, "*                  export PATH=<executable directory>:$PATH\n");
5191   fprintf ( fp, "* Make this permanent by adding this line to the file\n");
5192   fprintf ( fp, "*                  ~/.bashrc\n");
5193   fprintf ( fp, "* If this package is not installed but supported you can try to install it via t_coffee:\n");
5194   fprintf ( fp, "*                  t_coffee -other_pg install <pakage name>\n");
5195   fprintf ( fp, "* Otherwise you must install it yourself\n");
5196   fprintf ( fp, "*************************************************************************************************\n");
5197   
5198   return fp;
5199 }
5200 FILE* proxy_msg(FILE*fp)
5201   {
5202   fprintf ( fp, "\n\n");
5203   fprintf ( fp, "*************************************************************************************************\n");
5204   fprintf ( fp, "*                        CONFIGURATION: Faulty Network OR Missing Proxy                                        \n");
5205   fprintf ( fp, "*                                                                                               \n");
5206   fprintf ( fp, "*                                                                                               \n");
5207   fprintf ( fp, "* It looks like you cannot access the network\n");    
5208   fprintf ( fp, "* Check that your network is up and running...\n");    
5209   fprintf ( fp, "* If you are behind a firewall, you must enter your proxy address to use webservices\n");
5210   fprintf ( fp, "* This address is usualy something like: http://some.place.here:8080\n");           
5211   fprintf ( fp, "* Todo this via the command line:\n");
5212   fprintf ( fp, "*                                                                                               \n");
5213   fprintf ( fp, "*                  -proxy=<youremail>  \n");
5214   fprintf ( fp, "*                                                                                               \n");
5215   fprintf ( fp, "*To make it permanent:\n");
5216   fprintf ( fp, "*                   export PROXY_4_TCOFFEE=<your email>\n");
5217   fprintf ( fp, "*Add this line to either:\n");
5218   fprintf ( fp, "*             <yourhome>/.bashrc\n");
5219   fprintf ( fp, "*         OR  %s/.t_coffee_env\n", get_dir_4_tcoffee());
5220   fprintf ( fp, "*************************************************************************************************\n");
5221   
5222   return fp;
5223 }
5224 FILE* email_msg(FILE*fp)
5225 {
5226   fprintf ( fp, "\n\n");
5227   fprintf ( fp, "*************************************************************************************************\n");
5228   fprintf ( fp, "*                        CONFIGURATION: Missing Email                                        \n");
5229   fprintf ( fp, "*                                                                                               \n");
5230   
5231   fprintf ( fp, "* This mode of T-Coffee uses the  EBI BLAST webservices. The EBI requires a valid E-mail     \n");
5232   fprintf ( fp, "* address for this service to be used (check: www.ebi.ac.uk/Tools/webservices/).                \n");            
5233   
5234   fprintf ( fp, "*                                                                                               \n");
5235   fprintf ( fp, "* To provide the email, add to the command line:*\n");
5236   fprintf ( fp, "*                                                                                               \n");
5237   fprintf ( fp, "*                  -email=<youremail>  *\n");
5238   fprintf ( fp, "*To make it permanent:\n");
5239   fprintf ( fp, "*                   export EMAIL_4_TCOFFEE=<your email>\n");
5240   fprintf ( fp, "*Add this line to either:\n");
5241   fprintf ( fp, "*             ~/.bashrc\n");
5242   fprintf ( fp, "*         OR  %s/.t_coffee_env\n", get_dir_4_tcoffee());
5243   fprintf ( fp, "*************************************************************************************************\n");
5244   
5245   return fp;
5246 }           
5247
5248 void update_error_dir()
5249 {
5250
5251
5252   ;
5253
5254   
5255   
5256 }
5257 void dump_tcoffee(char *target, char *nature)
5258 {
5259   char **list, *s;
5260   int a=0;
5261   FILE *fp;
5262   char *f;
5263   char *out_list;
5264   
5265   if ((fp=fopen (target, "w")))
5266     {
5267       fprintf (fp, "<T-CoffeeApplicationDump>\n<nature>%s</nature>\n", nature);
5268       fprintf (fp, "<program>%s</program>\n", PROGRAM);
5269       fprintf (fp, "<version>%s</version>\n",VERSION);
5270       if ((f=strstr (in_cl, "-dump")))f[0]='\0';
5271       fprintf (fp, "<cl>%s</cl>\n",in_cl);
5272       fprintf (fp, "<stack>\n");
5273       stack_msg(fp);
5274       fprintf (fp, "</stack>\n<warning>\n");
5275       warning_msg (fp);
5276       fprintf (fp, "</warning>\n");
5277       
5278       //dump input
5279       list=string2list (in_cl);
5280       out_list=file2string (get_string_variable ("dump_output_file_list"));
5281       
5282       for (a=1; a<atoi (list[0]); a++)
5283         {
5284           FILE *fp2;
5285           char c;
5286           s=list[a];
5287           if (out_list && estrstr(out_list, "#%s#",s))continue;
5288           if (file_exists (NULL,s))
5289             {
5290               fp2=fopen (s, "r");
5291               fprintf (fp, "<file>\n<stream>input</stream>\n");
5292               fprintf (fp, "<name>%s</name>\n",s);
5293               fprintf (fp, "<content>\n");
5294               while ((c=fgetc(fp2))!=EOF)fprintf ( fp, "%c", c);
5295               fclose (fp2);
5296               fprintf (fp, "</content>\n</file>\n");
5297             }
5298         }
5299       //dump output
5300       if ((f=get_string_variable ("dump_output_file")))
5301         {
5302           FILE *fp2;
5303           char c;
5304           
5305           if ((fp2=fopen (f, "r"))!=NULL)
5306             {
5307               while ((c=fgetc (fp2))!=EOF)fprintf (fp, "%c",c);
5308               fclose (fp2);
5309             }
5310           
5311         }
5312       
5313       fprintf (fp, "<environement>\n");
5314       fclose (fp);
5315       printf_system_direct("printenv >> %s", target);
5316       fp=fopen (target, "a");
5317       fprintf (fp, "</environement>\n</T-CoffeeApplicationDump>");
5318       fclose (fp);
5319       
5320       fprintf ( stderr, "\n#----- Dumped File: %s\n",target);
5321     }
5322   else fprintf ( stderr, "\n#----- Could NOT Produce Dump File: %s -- Sorry \n", target);
5323   
5324
5325 }
5326 void dump_error_file()
5327 {
5328   char target[1000];
5329
5330
5331
5332   char **list, *s;
5333   int a=0;
5334   FILE *fp;
5335
5336   
5337   sprintf ( target, "%s",getenv("ERRORFILE_4_TCOFFEE"));
5338   dump_tcoffee (target, "error");
5339   return;
5340   
5341   if ((fp=fopen (target, "w")))
5342     {
5343       
5344       fprintf ( fp, "\n######### RUN_REPORT      START  ######");
5345       fprintf ( fp, "\n######### PROGRAM_VERSION START  ######"); 
5346       fprintf ( fp, "\n          %s, %s", PROGRAM, VERSION);
5347       fprintf ( fp, "\n######### PROGRAM_VERSION END    ######");
5348       
5349       fprintf ( fp, "\n######### COMMAND_LINE    START  ######");
5350       fprintf ( fp, "\n%s", in_cl);
5351       fprintf ( fp, "\n######### COMMAND_LINE    END    ######\n"); 
5352       fprintf ( fp, "\n######### MESSAGES START    ######\n"); 
5353       
5354       stack_msg(fp);
5355       warning_msg (fp);
5356       
5357       fprintf ( fp, "\n######### MESSAGES END    ######\n"); 
5358       fprintf ( fp, "\n######### FILES START     ######\n"); 
5359       
5360       list=string2list (in_cl);
5361       for (a=1; a<atoi (list[0]); a++)
5362         {
5363           FILE *fp2;
5364           char c;
5365           s=list[a];
5366           if (file_exists (NULL,s))
5367             {
5368               fp2=fopen (s, "r");
5369               fprintf ( fp, "\n************* Start_Input_File: %s  *************\n", s);
5370               while ((c=fgetc(fp2))!=EOF)fprintf ( fp, "%c", c);
5371               fclose (fp2);
5372               fprintf ( fp, "\n************* End_Input_File: %s  *************", s);
5373               
5374             }
5375         }
5376       fprintf ( fp, "\n######### FILES END  ######\n"); 
5377       fprintf ( fp, "\n######### ENVIRONEMENT  ######\n"); 
5378       fclose (fp);
5379       printf_system_direct("printenv >> %s", target);
5380             
5381       fprintf ( stderr, "\n#----- Dumped ErrorFile: %s\n",target);
5382     }
5383   else fprintf ( stderr, "\n#----- Could NOT Dumpe ErrorFile: %s -- Sorry \n", target);
5384
5385 }
5386
5387    
5388
5389 FILE* error_msg(FILE*fp )
5390      {
5391        if ( no_error_report)return fp;
5392
5393        fprintf( fp,"\n\t******************************************************************");
5394        fprintf( fp, "\n\t* Abnormal Termination");
5395        fprintf( fp, "\n\t* Job NOT Completed:[%s, %s]",PROGRAM, VERSION);
5396        fprintf( fp, "\n\t* Please CHECK:                                       ");
5397        fprintf( fp, "\n\t* \t-1 The format of your Input Files                 ");
5398        fprintf( fp, "\n\t* \t-2 The parameters                                 ");
5399        fprintf( fp, "\n\t* \t-3 The use of special characters in sequence names:");
5400        fprintf( fp, "\n\t* \t\t (@, |, %%...)");
5401        
5402        fprintf( fp, "\n\t* \t-4 The Online Doc (%s)                   ", URL);
5403        fprintf( fp, "\n\t* \t-5 Send the file:");
5404        fprintf (fp, "\n\t*");
5405        fprintf (fp, "\n\t*\t    %s ", getenv("ERRORFILE_4_TCOFFEE"));
5406        fprintf (fp,  "\n\t* to:");
5407        fprintf( fp, "\n\t* \t\t%s",EMAIL);
5408        
5409        fprintf( fp, "\n\t* If you run T-Coffee over the WEB:");
5410        fprintf( fp, "\n\t* \tWindows Cut and Paste is sometimes erratic and");
5411        fprintf( fp, "\n\t* \tit can loose carriage returns. If you suspect this,");
5412        fprintf( fp, "\n\t* \ttry to cut and paste through an intermediate application");
5413        fprintf( fp, "\n\t* \t(word pad) and inspect the results\n\n");
5414        fprintf( fp, "\n\t* CONFIDENTIALITY:");
5415        fprintf( fp, "\n\t* \tThe File %s may contain your personnal DATA", getenv("ERRORFILE_4_TCOFFEE"));
5416        fprintf( fp, "\n\t* \tRemove ALL confidential DATA from this file BEFORE sending it");
5417        fprintf( fp, "\n\t******************************************************************\n");
5418        print_command_line(fp);
5419        return fp;
5420      }
5421       
5422
5423 char *get_email_from_env ()
5424 {
5425   char *email=NULL;
5426   if ( (email=get_string_variable ("cl_email")));
5427   else if ( (email=get_string_variable ("email")));
5428   else if ( (email=getenv ("EMAIL_4_TCOFFEE")));
5429   else if ( (email=getenv ("EMAIL")));
5430   else email=vcalloc ( 1, sizeof (char));
5431   return email;
5432 }
5433
5434 int set_email (char *email)
5435 {
5436   if (!email) return 0;
5437   
5438   cputenv ("EMAIL_4_TCOFFEE=%s", email);
5439   cputenv ("EMAIL=%s",email);
5440   
5441   return 1;
5442 }
5443 char *chomp (char *name)
5444 {
5445   int a=0;
5446   while ( name[a]!='\n' && name[a]!='\0')a++;
5447   name[a]='\0';
5448   return name;
5449 }
5450 static Tmpname *tmpname;
5451 static Tmpname *ntmpname;
5452
5453 static int n_tmpname;
5454 static int file2remove_flag;
5455
5456 char *set_file2remove_extension (char *extension, int mode)
5457 {
5458   static char ext[100];
5459   if (mode==SET)sprintf (ext, "%s", extension);
5460   else if ( mode==UNSET) ext[0]='\0';
5461   else if ( mode==GET);
5462   return ext;
5463 }
5464 int flag_file2remove_is_on ()
5465
5466   return file2remove_flag;
5467 }
5468 void set_file2remove_on()
5469 {
5470   file2remove_flag=1;
5471 }
5472 void set_file2remove_off()
5473 {
5474   file2remove_flag=0;
5475 }
5476
5477 char *add2file2remove_list (char *name)
5478 {
5479
5480   
5481   if ( !tmpname || !name)ntmpname=tmpname=vcalloc ( 1, sizeof (Tmpname));
5482   else if (!ntmpname->name);
5483   else ntmpname=ntmpname->next=vcalloc ( 1, sizeof (Tmpname));
5484   
5485   if (!name) return NULL;
5486   
5487   ntmpname->name=vcalloc(strlen(name)+1, sizeof (char));
5488   
5489   sprintf (ntmpname->name, "%s", name);
5490   return ntmpname->name;
5491 }
5492 //char *short_tmpnam_2(char *s);//used to generate very compact tmp names
5493 void  initiate_vtmpnam (char *file)
5494 {
5495   add2file2remove_list (NULL);
5496   tmpnam_2(NULL);
5497 }
5498 char *vtmpnam ( char *s1)
5499 {
5500   char *s,*s2;
5501
5502   n_tmpname++;
5503   
5504   standard_initialisation(NULL, NULL);
5505   
5506   s=vcalloc ( VERY_LONG_STRING, sizeof (char));
5507   s[0]='\0';
5508   
5509   s=tmpnam_2 (s);
5510   
5511   s2=add2file2remove_list (s);
5512   if (s!=s2)vfree (s);
5513   if (s1){sprintf (s1, "%s",s2);return s1;}
5514   else return s2;
5515 }
5516      
5517
5518
5519 int get_vtmpnam2_root()
5520 {
5521   int MAX_TMPNAM_ROOT=10000;
5522   static int v;
5523
5524   if (v) ;
5525   else
5526     {
5527       vsrand(0);
5528       v=rand()%MAX_TMPNAM_ROOT;
5529     }
5530   return v;
5531 }
5532 char *tmpnam_2 (char *s)
5533
5534         static int root;   
5535         static int file;
5536         char buf[VERY_LONG_STRING];
5537         static char root2[VERY_LONG_STRING]; 
5538         static char *tmpdir;
5539         static int name_size;
5540         
5541         if ( !root || !s)
5542         {
5543                 char *vtmpnam_prefixe;
5544                 
5545                 name_size=MAX( 2*L_tmpnam, MAXNAMES*2)+1;
5546                 root=get_vtmpnam2_root();
5547                 sprintf ( root2, "%d%d_", root, (int)getpid());
5548                 
5549                 vtmpnam_prefixe=vcalloc (strlen (root2)+strlen (get_tmp_4_tcoffee())+2, sizeof (char));
5550                 sprintf (vtmpnam_prefixe, "%s/%s", get_tmp_4_tcoffee(), root2);
5551                 set_string_variable ("vtmpnam_prefixe1", vtmpnam_prefixe);
5552                 set_string_variable ("vtmpnam_prefixe2", root2);
5553                 vfree (vtmpnam_prefixe);
5554         }
5555         
5556         if (!s)return NULL;
5557         tmpdir=get_tmp_4_tcoffee();
5558                                         
5559         sprintf (buf, "%s/%s%d_TCtmp%s",tmpdir,root2, file++,set_file2remove_extension (NULL, GET));
5560         if ( strlen(buf)>=name_size)s=vrealloc (s,(strlen(buf)+1)*sizeof (char));
5561         sprintf (s, "%s", buf);
5562         return s;
5563 }
5564 char *short_tmpnam_2(char *s)
5565 {
5566   static int root;   
5567   static int file;
5568   char buf[VERY_LONG_STRING];
5569   static char root2[VERY_LONG_STRING]; 
5570
5571   static int name_size;
5572   
5573   if ( !root || !s)
5574     {
5575       char *vtmpnam_prefixe;
5576       
5577       name_size=MAX( 2*L_tmpnam, MAXNAMES*2)+1;
5578       root=get_vtmpnam2_root();
5579       sprintf ( root2, "%d%d", root,getpid());
5580       
5581       vtmpnam_prefixe=vcalloc (strlen (root2)+strlen (get_tmp_4_tcoffee())+2, sizeof (char));
5582       sprintf (vtmpnam_prefixe, "%s", root2);
5583       set_string_variable ("vtmpnam_prefixe1", vtmpnam_prefixe);
5584       set_string_variable ("vtmpnam_prefixe2", root2);
5585       vfree (vtmpnam_prefixe);
5586     }
5587   if (!s) return NULL;
5588   
5589   sprintf (buf, "%s%d%s",root2, file++,set_file2remove_extension (NULL, GET));
5590   if ( strlen(buf)>=name_size)s=vrealloc (s,(strlen(buf)+1)*sizeof (char));
5591   sprintf (s, "%s", buf);
5592   return s;
5593 }
5594
5595 char *vremove2 (char *s)
5596 {
5597   char list_file[1000];
5598   char ***list;
5599   int a;
5600
5601         
5602   //Remove filenames with a wildcard
5603   
5604   sprintf (list_file, "list_file_%d", (int)getpid());
5605   printf_system_direct("ls -1 %s>%s 2>/dev/null", s, list_file);
5606   list=file2list (list_file, " ");
5607  
5608   a=0;
5609   while (list && list[a])
5610     {
5611       if ( file_exists (NULL,list[a][1]))
5612         {
5613           vremove (list[a][1]);
5614         }
5615       a++;
5616     }
5617   vremove (list_file);
5618   return NULL;
5619 }
5620 void safe_remove (char *s)//remove even if the file is partly unaccessible
5621 {
5622   FILE *fp;
5623
5624
5625   if ( !s) return;
5626   else if (!(fp=fopen (s, "w")))return;
5627   else 
5628     {
5629       fclose (fp);
5630       remove (s);
5631     }
5632 }
5633     
5634 char *vremove (char *s)
5635 {
5636
5637   
5638   if ( s && strstr (s, "*"))return vremove2(s);
5639   else if ( !s || !file_exists(NULL,s) ) return NULL;
5640   else if ( isdir (s))
5641     {
5642       rmdir (s);
5643       return NULL;
5644     }
5645   else
5646     {
5647       remove (s);
5648       return NULL;
5649     }
5650   return NULL;
5651 }
5652 int log_function ( char *fname)
5653 {
5654
5655   
5656   if ( file_exists (NULL,error_file))
5657     {
5658       
5659       printf_system_direct ("cp %s %s", error_file, fname);
5660
5661       fprintf( stderr,"\n\t******************************************************************");
5662       fprintf( stderr, "\n\t* Full Log of [%s, %s] in File [%s]",PROGRAM, VERSION, fname);
5663       fprintf( stderr, "\n\t******************************************************************\n");
5664     }
5665   return 1;
5666 }
5667
5668
5669
5670 FILE *NFP;/*Null file pointer: should only be open once*/
5671
5672 /*********************************************************************/
5673 /*                                                                   */
5674 /*                         CACHE_FUNCTION                            */
5675 /*                                                                   */
5676 /*                                                                   */
5677 /*********************************************************************/
5678 static char *cache;
5679 char * prepare_cache ( const char *mode)
5680 {
5681   cache =vcalloc ( 10000, sizeof(char));
5682   
5683   if (strm (mode, "use"))
5684     {
5685       sprintf (cache, "%s",get_cache_4_tcoffee());
5686     }
5687   
5688   else if ( strm (mode, "ignore") ||  strm (mode, "no"))
5689     {
5690       
5691       cache=vtmpnam(cache);
5692       strcat (cache, "/");
5693       printf_system_direct ("mkdir %s",cache);
5694       
5695     }
5696   else if ( strm (mode, "update"))
5697     {
5698       cache=vtmpnam(cache);
5699       strcat (cache, "/");
5700       printf_system_direct ("mkdir %s",cache);
5701     }
5702   else if ( strm (mode, "local"))
5703     {
5704       cache[0]='\0';
5705     }
5706   else
5707     {
5708       sprintf ( cache, "%s/",mode);
5709       my_mkdir ( cache);
5710     }
5711   return cache;
5712             
5713 }
5714
5715 char * get_cache_dir()
5716 {
5717   if ( cache==NULL){cache=vcalloc (1, sizeof (char));cache[0]='\0';}
5718   return cache;
5719 }
5720
5721 void update_cache ()
5722 {
5723   char old_cache[1000];
5724
5725   sprintf ( old_cache, "%s", get_cache_dir());
5726   prepare_cache( "use");
5727   printf_system_direct ("mv %s* %s",old_cache, get_cache_dir());
5728   printf_system_direct ("rmdir %s",old_cache);
5729 }
5730 void ignore_cache()
5731 {
5732   if (getenv4debug ("DEBUG_TMP_FILE"))
5733     {
5734       fprintf ( stderr, "\n[DEBUG_TMP_FILE:%s] TEMPORARY CACHE HAS NOT Been Removed:\n\t%s\n", PROGRAM,get_cache_dir());
5735     }
5736   else
5737     {
5738
5739       printf_system_direct ("rm -r %s",get_cache_dir());
5740     }
5741   return;
5742   
5743 }
5744
5745 FILE *fopenN   ( char *fname, char *mode, int max_n_tries, int delay);
5746 FILE * vfopen  ( char *name_in, char *mode)
5747     {
5748     FILE *fp;
5749     int get_new_name;
5750     int tolerate_mistake;    
5751     int cache_used=0;
5752     FILE *tmp_fp;
5753     int c;
5754     static char *name;
5755     static char *name2;
5756     static char *stdin_file;
5757
5758   
5759     if ( !name_in)return NULL;
5760     if (!name){name=vcalloc (1000, sizeof (char));}
5761     if (!name2){name2=vcalloc (1000, sizeof (char));}
5762     
5763     sprintf ( name, "%s", name_in);
5764     tild_substitute (name, "~", get_home_4_tcoffee());
5765
5766     get_new_name=tolerate_mistake=0;    
5767     if ( mode[0]=='g'){get_new_name=1; mode++;}
5768     else if ( mode[0]=='t'){tolerate_mistake=1;mode++;}
5769 /*Use the cached version from CACHE_4_TCOFFEE*/    
5770     else if ( mode[0]=='c'){cache_used=1;mode++;}
5771
5772     if (name==NULL ||strm5 ( name, "no","NO","No","NULL","/dev/null") || strm2 (name, "no_file", "NO_FILE"))
5773                 {       
5774                 if ( NFP==NULL)NFP=fopen (NULL_DEVICE, mode);
5775                 return NFP;
5776                 } 
5777     else if ( strm3 (name,"stderr","STDERR","Stderr"))return stderr; 
5778     else if ( strm3 (name,"stdout","STDOUT","Stdout"))return stdout;
5779     else if ( strm3 ( name, "stdin","STDIN","Stdin"))
5780         {
5781           if (!stdin_file)
5782             {
5783               stdin_file=vtmpnam (NULL);
5784               tmp_fp=vfopen ( stdin_file, "w");
5785               while ( (c=fgetc(stdin))!=EOF)fprintf (tmp_fp, "%c", c);
5786               vfclose ( tmp_fp);
5787             }
5788           return vfopen (stdin_file, "r");
5789         }
5790         
5791     else if ( strm (name, "") && (strm (mode, "w") ||strm (mode, "a")) )return stdout;
5792     else if ( strm (name, "") && strm (mode, "r"))return stdin;    
5793     else if ( (fp= fopen ( name, mode))==NULL)
5794                 {
5795                 if ( strcmp (mode, "r")==0 && cache_used==0)
5796                   {
5797                     sprintf ( name2, "%s%s",get_cache_dir(), name);                 
5798                     return vfopen ( name2, "cr");
5799                   }
5800                 else if ( strcmp (mode, "r")==0 && cache_used==1)
5801                         {
5802                         fprintf (stderr, "\n--COULD NOT READ %s\n", name);
5803                         if ( get_new_name){fprintf ( stderr, "\nNew name: ");return vfopen (input_name(), mode-1);}
5804                         else if ( tolerate_mistake)return NULL;
5805                         else 
5806                             {   
5807                               myexit(fprintf_error (stderr, "\nFORCED EXIT (NON INTERACTIVE MODE pid %d)\n", getpid()));
5808                             }
5809                         }
5810                 else if ( strcmp (mode, "a")==0 && cache_used==0)
5811                   {
5812                     sprintf ( name2, "%s%s",get_cache_dir(), name);                 
5813                     return vfopen ( name, "ca");
5814                   }
5815                 else if ( strcmp (mode, "a")==0 && cache_used==1)
5816                         {
5817                         fprintf (stderr, "\nCOULD NOT Append anything to %s\n", name);
5818                         if ( get_new_name){fprintf ( stderr, "\nNew name: ");return vfopen (input_name(), mode-1);}
5819                         else if ( tolerate_mistake)return NULL;
5820                         else 
5821                             {   
5822                               myexit(fprintf_error (stderr, "\nFORCED EXIT (NON INTERACTIVE MODE pid %d)\n", getpid()));
5823                             }
5824                         }
5825                 else if ( strcmp (mode, "w")==0)
5826                         {
5827                         fprintf (stderr, "\nCANNOT WRITE %s\n", name);
5828                         if ( get_new_name==1){fprintf ( stderr, "\nNew name: ");return vfopen (input_name(), mode-1);}  
5829                         else if ( tolerate_mistake)return NULL;
5830                         else 
5831                             {
5832                              myexit(fprintf_error (stderr, "\nFORCED EXIT (NON INTERACTIVE MODE pid %d): %s %s\n", getpid(),(strcmp ( mode, "r")==0)?"READ":"WRITE", name));
5833                             
5834                             }
5835                         }               
5836                 } 
5837     else
5838         return fp;
5839     
5840     return NULL;
5841     }
5842 FILE *fopenN   ( char *fname, char *mode, int max_n_tries, int delay)
5843 {
5844   FILE *fp;
5845   int a;
5846   
5847   for (a=0; a< max_n_tries; a++)
5848     {
5849       if ((fp=fopen (fname, mode))) return fp;
5850       else sleep (delay);
5851       HERE ("---- failed opening: %s", fname);
5852     }
5853   return NULL;
5854 }
5855       
5856 FILE * vfclose ( FILE *fp)
5857        {
5858        if ( fp==NFP)return NULL;
5859        if ( fp==stdout)return stdout;
5860        if ( fp==stderr)return stderr;
5861        if ( fp==stdin) return stdin;
5862        if ( fp==NULL)return NULL;
5863        else fclose (fp);
5864        return NULL;
5865        }
5866         
5867
5868 int echo ( char *string, char *fname)
5869 {
5870 int a;
5871 /*
5872 description:
5873 prints the content of string into file fname
5874
5875 in:
5876 string= string to print
5877 fname =name of the file to create
5878 */
5879
5880 FILE *fp;
5881
5882     fp=vfopen ( fname, "w");
5883     fprintf (fp, "%s", string);
5884     a=fclose (fp);
5885     return a;
5886
5887 }
5888
5889 int   file_cat ( char *from, char *to)
5890 {
5891   FILE *fp;
5892   //appends the content of file1 to file 2
5893   if (!(fp=vfopen (to, "a")))return 0;
5894   if (!display_file_content (fp, from)) return 0;
5895   vfclose (fp);
5896   return 1;
5897 }
5898   
5899 FILE* display_file_content (FILE *output, char *name)
5900 {
5901   FILE *fp;
5902   int c;
5903   if ( !name || !file_exists (NULL,name) || !(fp=vfopen (name, "r")))return NULL;
5904   while ( (c=fgetc(fp))!=EOF)fprintf (output,"%c", c);
5905   vfclose (fp);
5906   return output;
5907 }
5908
5909 char ***file2list ( char *name, char *sep)
5910 {
5911   /*Rturns an array where
5912     list[0]: first line
5913     list[0][0]: number of words
5914     list[0][1]:first word;
5915     list[n]=NULL
5916   */
5917   char **lines, ***list; 
5918   int a, n;
5919
5920   lines=file2lines (name);
5921   if (!lines) return NULL;
5922   else
5923     {
5924       n=atoi (lines[0]);
5925
5926       list=vcalloc ( n+1, sizeof (char**));
5927       for ( a=1; a<n; a++)
5928         {
5929           
5930           list[a-1]=string2list2(lines[a], sep);
5931         }
5932     }
5933   
5934   free_arrayN((void**)lines, 2);
5935   return list;
5936 }
5937 char **file2lines (char *name)
5938 {
5939   /*lines[0]->nlines;
5940     lines[1]->first_line
5941   */
5942   char **lines;
5943   char *string;
5944
5945
5946   string=file2string (name);
5947   if ( !string) return NULL;
5948   else
5949     {
5950       lines=string2list2(string, "\n");
5951       vfree ( string);
5952       return lines;
5953     }
5954 }
5955 int string2file (char *file, char *mode, char *string,...)
5956 {
5957   FILE *fp;
5958   va_list ap;
5959   
5960   if (!file) return 0;
5961   else if ( !mode) return 0;
5962   else if ( !(fp=vfopen (file, mode)))return 0;
5963   va_start (ap, string);
5964   vfprintf (fp, string, ap);
5965   vfclose (fp);
5966   va_end (ap);
5967   return 1;
5968 }
5969
5970 char *file2string (char *name)
5971 {
5972   FILE*fp;
5973   char *string;
5974   int a, c;
5975   
5976   if (!name || !file_exists (NULL,name))return NULL;
5977   else
5978     {
5979       a=0;
5980       if ((fp=fopen (name, "r"))) 
5981         {
5982           while ( (c=fgetc(fp))!=EOF)a++;
5983           fclose (fp);
5984         }
5985       else return NULL;
5986       
5987       string=vcalloc (a+1, sizeof (char));
5988       a=0;
5989       if ((fp=fopen (name, "r")))
5990         {
5991           while ( (c=fgetc(fp))!=EOF)string[a++]=c;
5992           fclose (fp);
5993         }
5994       else return NULL;
5995       string[a]='\0';
5996       return string;
5997     }
5998 }
5999
6000 int get_cl_param (int argc, char **argv, FILE **fp,char *para_name, int *set_flag, char *type, int optional, int max_n_val,char *usage, ...)
6001         {
6002         /*
6003         usage:
6004         argc:       n_ arg
6005         argv        list *
6006         para_name   param
6007         set_flag    set to 1 if param set;
6008         para_type   F, I, S, R_FN (read_file, name), W_FN (written file, name), R_FP (pointer)
6009         max_n_val   maximum number of values;
6010         optional    1 for yes, 0 for no
6011         usage       usage list with optional value;
6012         val         pointer to the varaible holding the value(s)
6013         default1    default value (if value id not there)
6014         default2    default value if the flag is there but no value set ("")indicates an error
6015         range_left  min value ( "any" for any);
6016         range_right  max_value ( "any" for any);
6017         */
6018         int pos=0;
6019         int a;
6020         va_list ap;
6021         
6022         int   *int_val=NULL;
6023         float *float_val=NULL;
6024         char  **string_val=NULL;
6025
6026         
6027         char  *range_right;
6028         char  *range_left;
6029         
6030         
6031         char *default_value1;
6032         char *default_value2;
6033         int n_para=0;        
6034         double max, min;
6035         
6036         static char **parameter_list;
6037         static int    number_of_parameters;
6038
6039         char **para_name_list;
6040         int    n_para_name;
6041         
6042         char **para_val;
6043         int    n_para_val;
6044         
6045         char **pv_l=NULL;
6046         int    n_pv_l;
6047         char **pv_r=NULL;
6048         int    n_pv_r;
6049         char   value[STRING];
6050
6051
6052
6053 /*CHECK THAT ALL THE PARAM IN ARG EXIST*/
6054         if ( para_name==NULL)
6055            {
6056            for ( a=1; a< argc; a++)
6057                {
6058                if ( is_parameter ( argv[a]))
6059                  {
6060                  if (strstr (argv[a], "help"))myexit (EXIT_SUCCESS);
6061                  else if ( name_is_in_list ( argv[a], parameter_list, number_of_parameters, STRING)==-1)
6062                       {
6063                         myexit(fprintf_error ( stderr, "\n%s IS NOT A PARAMETER  OF %s [FATAL/%s %s]\n",argv[a], argv[0], argv[0], VERSION));
6064                       
6065                       }
6066                  }
6067                      
6068                }
6069          
6070            free_char (parameter_list,-1);
6071            return 0;
6072            }
6073
6074         if ( parameter_list==NULL)parameter_list=declare_char(MAX_N_PARAM,STRING);
6075         para_name_list=get_list_of_tokens(para_name,NULL, &n_para_name);
6076         for ( a=0; a< n_para_name; a++)
6077             {
6078             sprintf ( parameter_list[number_of_parameters++],"%s", para_name_list[a]);
6079             }
6080         free_char(para_name_list,-1);
6081         
6082
6083
6084         
6085         
6086         set_flag[0]=0;
6087         va_start (ap, usage);
6088         
6089         if (strm3 (type, "S","R_F","W_F"))
6090                 string_val=va_arg(ap, char**);
6091         else if (strm2 (type, "D","FL"))
6092                 int_val=va_arg(ap, int*);
6093         else if (strm (type, "F"))
6094                 float_val=va_arg(ap, float*);
6095         else 
6096             myexit (EXIT_FAILURE);
6097         
6098         
6099         
6100         default_value1=va_arg(ap, char*);
6101         default_value2=va_arg(ap, char*);
6102         range_left    =va_arg(ap, char*);
6103         range_right   =va_arg(ap, char*);
6104         va_end(ap);
6105
6106
6107         para_name_list=get_list_of_tokens(para_name, NULL, &n_para_name);
6108         for ( a=0; a<n_para_name; a++) 
6109             {
6110             if ( (pos=name_is_in_list(para_name_list[a], argv,argc, STRING))!=-1)break;
6111             }
6112         free_char (para_name_list,-1);
6113         
6114         if (  (name_is_in_list("-help" , argv,argc  ,STRING)!=-1) && (argc==2 || (name_is_in_list( para_name , argv,argc  ,STRING)!=-1)))
6115           {
6116         
6117                fprintf ( stderr, "PARAMETER   : %s\n",  para_name);
6118                fprintf ( stderr, "USAGE       : %s\n",       usage);
6119                fprintf ( stderr, "MAX_N_VALUES: %d\n",   max_n_val);
6120                fprintf ( stderr, "DEFAULT     : %s OR %s (when flag set)\n", default_value1, default_value2);
6121                fprintf ( stderr, "RANGE       : [%s]...[%s]\n", range_left,(strm(range_right,"any"))?"":range_right);
6122                fprintf ( stderr, "TYPE        : %s\n\n", type);
6123                return 0;
6124           }
6125         else if ( name_is_in_list ("-help" , argv,argc  ,STRING)!=-1)
6126           {
6127             return 0;
6128           }
6129         else if (para_name[0]!='-')
6130            {
6131            myexit(fprintf_error ( stderr, "\nWRONG PARAMETER DEFINITION %s Must Start with a dash", para_name));
6132            
6133            }
6134         else if (pos==-1)
6135            {
6136            if ( optional==OPTIONAL)
6137               {
6138               set_flag[0]=0;          
6139               para_val=get_list_of_tokens(default_value1, NULL, &n_para_val);
6140               
6141               for (n_para=0; n_para<n_para_val && !strm (default_value1, "NULL"); n_para++) 
6142                   {
6143                   if ( strm (para_val[n_para], ""))
6144                       {
6145                       set_flag[0]=0;
6146                       break;
6147                       }
6148                   else if ( strm (type, "FL"))
6149                       {
6150                       set_flag[0]=atoi(para_val[n_para]);
6151                       break;
6152                       }
6153                   else if (strm3 (type, "S", "R_F","W_F"))
6154                       {
6155                      
6156                       sprintf ( string_val[n_para], "%s",para_val[n_para]);
6157                       }           
6158                   else if ( strm (type, "D"))
6159                       int_val[n_para]=atoi(para_val[n_para]);
6160                   else if ( strm (type, "F"))
6161                       float_val[n_para]=atof(para_val[n_para]);
6162                   }
6163               free_char (para_val, -1);
6164                
6165               if (n_para==0 && strm3(type, "S","W_F","R_F") && strm (default_value1, "NULL"))
6166                   {
6167                   vfree (string_val[0]);
6168                   string_val[0]=NULL;
6169                   
6170                   }
6171               else if (n_para==0 && strm (type, "D") && strm (default_value1, "NULL"))int_val[0]=0;                
6172               else if (n_para==0 && strm (type, "F") && strm (default_value1, "NULL"))float_val[0]=0;
6173          
6174               }
6175            else
6176               {
6177               myexit(fprintf_error ( stderr, "\nParameter %s is not optional",para_name));
6178               
6179               }    
6180            }
6181         else if (pos!=-1)
6182           {
6183           set_flag[0]=1;
6184           for (a=pos+1; a< argc; a++)
6185               {
6186               if ( is_parameter(argv[a]))break;
6187               else
6188                   {
6189                   if ( n_para>=max_n_val)
6190                      {
6191                      n_para=max_n_val-1;
6192                      
6193                      }
6194                   if ( !(strm ( argv[a], "NULL")))                        
6195                     {
6196                       if ( strm3(type, "S", "R_F", "W_F"))
6197                           {
6198                           sprintf ( string_val[n_para],"%s", argv[a]);
6199                           }
6200                        else if (strm (type, "D"))
6201                           {
6202                           int_val[n_para]=atoi(argv[a]);
6203                           }
6204                        else if (strm ( type,"F"))
6205                           {
6206                           float_val[n_para]=atof(argv[a]);
6207                           }
6208                     }
6209                   n_para++;
6210                   }
6211               }
6212
6213           if ( n_para==0 && !strm2(default_value2,"","NULL") && !strm(type, "FL"))
6214               {
6215               para_val=get_list_of_tokens(default_value2, NULL, &n_para_val);
6216               for ( n_para=0; n_para<n_para_val; n_para++)
6217                   {
6218                   if ( strm3(type, "S", "R_F", "W_F"))sprintf ( string_val[n_para],"%s", para_val[n_para]);               
6219                   else if (strm (type, "D"))int_val  [n_para]=atoi(para_val[n_para]);
6220                   else if (strm ( type,"F"))float_val[n_para]=atof(para_val[n_para]);           
6221                   }
6222               free_char (para_val,-1);
6223               }
6224           else if (n_para==0 && strm (type, "FL"));
6225           else if (n_para==0 && strm3(type, "S","W_F","R_F") && strm (default_value2, "NULL")){vfree (string_val[0]);string_val[0]=NULL;}
6226           else if (n_para==0 && strm (type, "D") && strm (default_value2, "NULL"))int_val[0]=0;            
6227           else if (n_para==0 && strm (type, "F") && strm (default_value2, "NULL"))float_val[0]=0;
6228           else if (n_para==0 && strm (default_value2, ""))
6229                  {
6230                  myexit(fprintf_error ( stderr, "\nParam %s needs a value [FATAL/%s]", para_name, argv[0]));
6231                  
6232                  }
6233           else;
6234           }
6235           
6236 /*Check That The Parameters are in the Good Range*/
6237         
6238         pv_l=get_list_of_tokens( range_left , NULL, &n_pv_l);
6239         pv_r=get_list_of_tokens( range_right, NULL, &n_pv_r);
6240
6241         for ( a=0; a< n_para; a++)
6242             {      
6243             if ( strm (type, "R_F") && !check_file_exists(string_val[a]) && !check_file_exists(string_val[a]+1))
6244                         {                       
6245                         myexit(fprintf_error ( stderr, "PARAM %s: File %s does not exist [FATAL/%s]\n",para_name,string_val[a], argv[0]));
6246                         
6247                         }           
6248             else if ( strm (pv_l[0], "any"));
6249             else if ( strm (type, "D"))
6250                  {
6251                  if ( n_pv_l==1)
6252                     {
6253                     min=(double)atoi(pv_l[0]);
6254                     max=(double)atoi(pv_r[0]);
6255                     if ( int_val[a]<min || int_val[a]>max)
6256                        {
6257                        myexit(fprintf_error ( stderr, "\n%s out of range [%d %d] [FATAL/%s]\n", para_name, (int)min, (int)max,argv[0]));
6258                        
6259                        }
6260                     }
6261                  else
6262                     {
6263                     sprintf ( value, "%d", int_val[a]);
6264                     if ( name_is_in_list(value, pv_l, n_pv_l, STRING)==-1)
6265                         fprintf ( stderr, "\n%s out of range [%s: ", para_name, value);
6266                     print_array_char (stderr, pv_l, n_pv_l, " ");
6267                     fprintf ( stderr, "\n");
6268                     myexit(EXIT_FAILURE);
6269                     }
6270                  }
6271             else if ( strm (type, "F"))
6272                  {
6273                   if ( n_pv_l==1)
6274                     {
6275                     min=(double)atof(range_left);
6276                     max=(double)atof(range_right);
6277                     if ( float_val[a]<min || float_val[a]>max)
6278                        {
6279                        myexit(fprintf_error ( stderr, "\n%s out of range [%f %f] [FATAL/%s]\n", para_name, (float)min, (float)max,argv[0]));
6280                        
6281                        }
6282                      }
6283                   else
6284                      {
6285                      sprintf ( value, "%f", float_val[a]);
6286                      if ( name_is_in_list(value, pv_l, n_pv_l, STRING)==-1)
6287                         fprintf ( stderr, "\n%s out of range [%s: ", para_name, value);
6288                      print_array_char (stderr, pv_l, n_pv_l, " ");
6289                      fprintf ( stderr, "\n");
6290                      
6291                      }
6292                  }
6293             }
6294          
6295
6296          if ( fp[0]!=NULL)
6297               {
6298               fprintf (fp[0], "%-15s\t%s\t[%d] ", para_name, type, set_flag[0]);
6299               for (a=0; a<n_para; a++) 
6300                   {
6301                   if ( strm3 ( type, "S", "R_F", "W_F"))fprintf ( fp[0], "\t%s", string_val[a]);
6302                   else if ( strm  ( type, "D"))fprintf ( fp[0], "\t%d ", int_val[a]);
6303                   else if ( strm  ( type, "F"))fprintf ( fp[0], "\t%f ", float_val[a]);
6304                  }          
6305               if ( strm (type, "FL"))fprintf ( fp[0], "\t%d", int_val[0]);
6306               fprintf ( fp[0], "\n");     
6307               }
6308
6309         free_char ( pv_l, -1);
6310         free_char ( pv_r, -1);
6311         return n_para;
6312         }
6313
6314         
6315         
6316 char ** get_parameter ( char *para_name, int *np, char *fname)
6317 {
6318     /*
6319     In:
6320     para_name: the name of the parameter to look for
6321     fname: the name of the file containing the parameters
6322     np[0]: set to 0
6323
6324     Out:
6325     char ** containing the np[0] values taken by para_name in fname.
6326     
6327     Special:
6328     if fname=NULL, para_name is searched using the last value taken by fp.
6329     
6330     Note: by default, the function keeps a file handle open until the first unsuccessful call.
6331     */
6332
6333     static FILE *fp;
6334     static char *line;
6335     char ** return_value;
6336     
6337     if ( strm (para_name, "CLOSE THE FILE"))
6338       {
6339         vfclose ( fp);
6340         return NULL;
6341       }
6342     
6343     if ( line==NULL)line=vcalloc ( VERY_LONG_STRING+1, sizeof (char));
6344     if ( fname!=NULL && fp!=NULL)vfclose (fp);
6345     
6346     np[0]=0;
6347
6348     if ((fp=find_token_in_file ( fname,(fname==NULL)?fp:NULL, para_name))==NULL) 
6349         {
6350              return NULL;
6351         }
6352     else
6353         {
6354         fgets ( line, VERY_LONG_STRING,fp);
6355         return_value=get_list_of_tokens ( line, NULL, np);      
6356         return return_value;
6357         }
6358 }
6359
6360 FILE * set_fp_id ( FILE *fp, char *id)
6361         {
6362 /*Sets fp just after id, id needs to be at the begining of the line*/
6363         char string[10000];
6364         int cont=1;
6365         int c;
6366         
6367         while ( cont==1)        
6368                 {
6369                 c=fgetc(fp);
6370                 if ( c!=EOF)
6371                         {
6372                         
6373                         ungetc(c, fp);
6374                         fscanf ( fp, "%s", string);
6375                         
6376                         if ( strcmp ( string, id)==0)
6377                                 return fp;
6378                         else while ( c!='\n' && c!=EOF)
6379                                 c=fgetc(fp);                    
6380                         }
6381                 else if ( c==EOF)
6382                         {
6383                         fclose ( fp);
6384                         return NULL;
6385                         }
6386                 }       
6387         return fp;
6388         }
6389 FILE * set_fp_after_char ( FILE *fp, char x)
6390         {
6391 /*sets fp just after the first occurence of x*/
6392         
6393
6394
6395         int cont=1;
6396         int c;
6397         
6398         while ( cont==1)        
6399                 {
6400                 c=fgetc(fp);
6401                 if ( c!=EOF)
6402                         {
6403                         if ( c==x)
6404                                 return fp;
6405                         
6406                         }
6407                 else if ( c==EOF)
6408                         {
6409                         fclose ( fp);
6410                         return NULL;
6411                         }
6412                 }       
6413         return fp;
6414         }
6415
6416 FILE * find_token_in_file_nlines ( char *fname, FILE * fp, char *token, int n_line)
6417
6418         {
6419           /*This function finds the string TOKEN (as a single word) in the n_line first lines of fname.
6420             It returns NULL if not found or the position of the fp
6421           */
6422           
6423           char *tmp_name=NULL;
6424           FILE *fp1;
6425           FILE *fp2;
6426           char buffer[10001];
6427           int a;
6428           if ( !fp && !file_exists(NULL,fname))return NULL;
6429           if ( fp==NULL)
6430             {
6431               tmp_name=vtmpnam ( NULL);
6432         
6433               fp1=vfopen (fname, "r");
6434               fp2=vfopen (tmp_name, "w");
6435               
6436               for ( a=0; a< n_line && fgets(buffer, 10000, fp1)!=NULL; a++)
6437                 {
6438                   fprintf ( fp2, "%s", buffer);
6439                 }
6440               vfclose (fp1);
6441               vfclose (fp2);
6442             }
6443           return find_token_in_file ( tmp_name,fp,token);
6444         }
6445           
6446 int token_is_in_file ( char *fname, char *token)
6447 {
6448   /*TH:an argument against torture: innocents get tortured longer, likewise for token testing*/
6449   FILE *fp;
6450   static char *buf;
6451   char *b, *p;
6452   int begining;
6453   
6454
6455   
6456   if (token[0]=='\n')
6457     {
6458
6459       begining=1;
6460       token++;
6461     }
6462   else
6463     {
6464       begining=0;
6465     }
6466   
6467   if ( !fname || !file_exists(NULL,fname))return 0;
6468   else
6469     {
6470       fp=vfopen (fname, "r");
6471       while ((b=vfgets (buf,fp))!=NULL)
6472         {
6473           buf=b;
6474           p=strstr (buf, token);
6475           if (!p);
6476           else if ( begining==1 && p==buf){vfclose (fp); return 1;}
6477           else if ( begining==0 && p){vfclose (fp); return 1;}
6478         }
6479       vfclose (fp);
6480       return 0;
6481     }
6482   return 0;
6483 }
6484
6485 char *vfgets ( char *buf, FILE *fp)
6486 {
6487   int c;
6488   int buf_len, l;
6489   char *bufin;
6490   static int debug;
6491
6492
6493   if ( !debug)
6494     debug=(getenv ("DEBUG_TCOFFEE"))?1:-1;
6495   
6496
6497   bufin=buf;
6498
6499   if (!buf)
6500     {
6501       buf=vcalloc ( 1000, sizeof (char));
6502       buf_len=1000;
6503     }
6504   else
6505     {
6506       buf_len=read_array_size_new (buf);
6507     }
6508   
6509   l=0;
6510   
6511   if ( (c=fgetc (fp))==EOF)return NULL;
6512   else ungetc (c, fp);
6513   
6514   
6515   while ( (c=fgetc (fp))!='\n' && c!=EOF)
6516     {
6517       if (l>=buf_len)
6518         {buf_len+=100;buf=vrealloc (buf, buf_len*sizeof (char));}
6519       buf[l++]=c;
6520     }
6521   /*Add the cariage return*/
6522   if ( c=='\n')
6523     {
6524       if (l>=buf_len){buf_len+=100,buf=vrealloc (buf, buf_len*sizeof (char));}
6525       buf[l++]='\n';
6526     }
6527   /*add the terminator*/  
6528   if (l>=buf_len){buf_len+=100,buf=vrealloc (buf, buf_len*sizeof (char));}
6529   buf[l]='\0';
6530
6531   if ( bufin!=buf && bufin!=NULL && debug==1)
6532     fprintf ( stderr, "\nPointer change in vfgets...");
6533   
6534   return buf;
6535 }
6536   
6537
6538 FILE * find_token_in_file ( char *fname, FILE * fp, char *token)
6539         {
6540         int c;
6541         static char *name;
6542         int token_len;
6543
6544         int only_start;
6545         
6546         /*Note: Token: any string
6547                 If Token[0]=='\n' Then Token only from the beginning of the line
6548         */
6549
6550         if (!fp && !file_exists("CACHE",fname))return NULL;
6551
6552         if ( token[0]=='\n'){token++;only_start=1;}
6553         else only_start=0;
6554
6555         token_len=strlen (token);
6556
6557         
6558         
6559         
6560         
6561         if (!fp)
6562           {
6563             if (name)vfree (name);
6564             name = vcalloc (((fname)?measure_longest_line_in_file (fname):10000)+1, sizeof (char));
6565             fp=vfopen ( fname, "r");
6566           }
6567             
6568         while ( (fscanf ( fp, "%s", name))!=EOF)
6569                 {
6570                  
6571                 if ( name[0]=='*')while ( ((c=fgetc (fp))!='\n')&& (c!=EOF));
6572                 else if (strncmp ( name, token,token_len)==0){return fp;}
6573                 else if (only_start) while ( ((c=fgetc (fp))!='\n')&& (c!=EOF));
6574                 }
6575
6576         vfclose ( fp);
6577         return NULL;
6578         }
6579 int **get_file_block_pattern (char *fname, int *n_blocks, int max_n_line)
6580         {
6581         int c;
6582         FILE *fp;
6583         char *line;
6584         int lline;
6585         int **l;
6586         int in_block;
6587         
6588         int max_block_size;
6589         int block_size;
6590         int x;
6591         int n_line;
6592         
6593         lline=measure_longest_line_in_file (fname)+1;                   
6594         line=vcalloc ( sizeof (char),lline+1);
6595         
6596         fp=vfopen (fname, "r");
6597         max_block_size=block_size=0;
6598         in_block=1;
6599         n_blocks[0]=0;
6600         n_line=0;
6601         while ((c=fgetc(fp))!=EOF && (n_line<max_n_line || !max_n_line))
6602             {
6603                   ungetc (c, fp);
6604                   fgets ( line, lline,fp);
6605                   n_line++;
6606
6607                   if ( is_alnum_line (line) && !in_block){n_blocks[0]++;in_block=1;}
6608                   if ( is_alnum_line (line))
6609                      {
6610                      block_size++;
6611                      }
6612                   else
6613                       {
6614                       in_block=0;
6615                       max_block_size=MAX( max_block_size, block_size);
6616                       block_size=0;
6617                       }
6618             }
6619
6620         
6621         max_block_size=MAX( max_block_size, block_size);
6622         vfclose ( fp);
6623         
6624         l=declare_int (n_blocks[0]+1,max_block_size+1);  
6625
6626         
6627         fp=vfopen (fname, "r"); 
6628         in_block=1;
6629         n_blocks[0]=0;
6630         n_line=0;
6631         while ((c=fgetc(fp))!=EOF && (n_line<max_n_line || !(max_n_line)))
6632               {
6633                   ungetc (c, fp);
6634                   fgets ( line, lline,fp);
6635                   n_line++;
6636
6637                   if ( is_alnum_line (line) && !in_block){n_blocks[0]++;in_block=1;}
6638                   if ( is_alnum_line (line))
6639                       {
6640                       l[n_blocks[0]][0]++;
6641                       free_char (get_list_of_tokens (line, " \t\n*:,", &x), -1); 
6642                       
6643                       if ( l[n_blocks[0]][0]> max_block_size)myexit(fprintf_error ( stderr, "\nERROR %d", l[n_blocks[0]][0]));
6644
6645                       l[n_blocks[0]] [l[n_blocks[0]][0]]=x;
6646                       }
6647                   else
6648                       {
6649                           in_block=0;
6650                       }
6651               }
6652         n_blocks[0]++;
6653         vfree(line);
6654         vfclose (fp);
6655         return l;
6656         }                 
6657
6658 char * strip_file_from_comments (char *com, char *in_file)
6659 {
6660   /*Removes in file in_file every portion of line to the right of one of the symbols included in com
6661     Writes the striped file into a vtmpnam file
6662    */
6663   FILE *fp1;
6664   FILE *fp2;
6665   char *out_file;
6666   int c;
6667
6668   out_file=vtmpnam(NULL);
6669
6670
6671   fp1=vfopen (in_file , "r");
6672   fp2=vfopen (out_file, "w");
6673   while ( (c=fgetc(fp1))!=EOF)
6674           {
6675             if (strchr(com, c))
6676               { 
6677                 while ( (c=fgetc(fp1))!='\n' && c!=EOF);
6678               }
6679             else
6680               {
6681                 fprintf (fp2, "%c", c);
6682                 while ( (c=fgetc(fp1))!='\n' && c!=EOF)fprintf (fp2, "%c", c);
6683                 if ( c!=EOF)fprintf (fp2, "%c", c);
6684               }
6685           }
6686   vfclose (fp1);
6687   vfclose (fp2);
6688  
6689   return out_file;
6690 }
6691 FILE * skip_commentary_line_in_file ( char com, FILE *fp)
6692 {
6693   int c=0;
6694
6695   if ( fp==NULL)return NULL;
6696   while ((c=fgetc(fp))==com)
6697     {
6698       while ((c=fgetc(fp))!='\n' && c!=EOF);
6699     }
6700   if ( c!=EOF && c!='\n')ungetc(c, fp);
6701   return fp;
6702 }
6703      
6704 int check_for_update ( char *web_address)
6705 {
6706   char command[1000];
6707   char *file;
6708   float new_version, old_version;
6709   FILE *fp;
6710   
6711   check_internet_connection (IS_NOT_FATAL);
6712   file=vtmpnam(NULL);
6713    
6714   sprintf ( command, "%s/%s.version",DISTRIBUTION_ADDRESS, PROGRAM);
6715   url2file ( command, file);
6716     
6717   fp=vfopen ( file, "r");
6718   fscanf ( fp, "Version_%f", &new_version);
6719   vfclose ( fp);
6720   sscanf ( VERSION, "Version_%f", &old_version);
6721
6722   if ( old_version<new_version)
6723     {
6724       fprintf ( stdout, "\nUpdate Status: outdated");
6725       fprintf ( stdout, "\nYour version of %s is not up to date", PROGRAM);
6726       fprintf ( stdout, "\nDownload the latest version %.2f with the following command:", new_version);
6727       fprintf ( stdout, "\n\twget %s/%s_distribution_Version_%.2f.tar.gz\n", DISTRIBUTION_ADDRESS, PROGRAM, new_version);
6728       return EXIT_FAILURE;
6729     }
6730   else if ( old_version> new_version)
6731     {
6732       fprintf ( stdout, "\nUpdate Status: beta-release");
6733       fprintf ( stdout, "\nYour are using a beta-release of %s(%s)\n", PROGRAM, VERSION);
6734     }
6735   else
6736     {
6737       fprintf (stdout, "\nUpdate Status: uptodate");
6738       fprintf (stdout, "\nProgram %s(%s) is up to date\n", PROGRAM, VERSION);
6739     }
6740   return EXIT_SUCCESS;
6741 }
6742         
6743       
6744   
6745   
6746   
6747 int check_environement_variable_is_set ( char *variable, char *description, int fatal)
6748 {
6749   if ( getenv (variable)==NULL)
6750     {
6751       myexit(fprintf_error ( stderr, "\nERROR: You must set %s\n%s %s", variable, description, description));
6752       if ( fatal==IS_FATAL)
6753         {
6754         myexit(fprintf_error ( stderr, "\n[%s:FATAL]\n", PROGRAM));
6755         
6756         }
6757       else
6758         add_warning ( stderr, "\n[%s:WARNING]\n", PROGRAM);
6759     }
6760   return 1;
6761 }
6762
6763 int url2file (char *address, char *out)
6764 {
6765    
6766   if      (check_program_is_installed ("wget",NULL, NULL,WGET_ADDRESS, IS_NOT_FATAL))return printf_system( "wget %s -O%s >/dev/null 2>/dev/null", address, out);
6767   else if (check_program_is_installed ("curl",NULL, NULL,CURL_ADDRESS, IS_NOT_FATAL))return printf_system("curl %s -o%s >/dev/null 2>/dev/null", address, out);
6768   else 
6769     {
6770       printf_exit (EXIT_FAILURE, stderr, "ERROR: Impossible to fectch external file: Neither wget nor curl is installed on your system [FATAL:%s]\n", PROGRAM);
6771       return EXIT_FAILURE;
6772     }
6773 }
6774
6775 int wget (char *address, char *out)
6776 {
6777   return printf_system ( "curl %s -O%s >/dev/null 2>/dev/null", address, out);
6778   }
6779
6780 int curl (char *address, char *out)
6781 {
6782   return printf_system ( "curl %s -o%s >/dev/null 2>/dev/null", address, out);
6783 }
6784         
6785
6786 int simple_check_internet_connection (char *ref_site)
6787 {
6788   char *test;
6789   int n, internet=0;
6790   
6791   test=vtmpnam (NULL);
6792   if (url2file((ref_site)?ref_site:TEST_WWWSITE_4_TCOFFEE,test)!=EXIT_SUCCESS)internet=0;
6793   else if ((n=count_n_char_in_file(test))<10)internet=0;
6794   else internet =1;
6795   
6796   return internet;
6797 }
6798 int check_internet_connection  (int mode)
6799 {
6800   int internet;
6801   internet=simple_check_internet_connection (NULL);
6802   if (internet)return 1;
6803   else if ( mode==IS_NOT_FATAL)return internet;
6804   else proxy_msg(stderr);
6805   myexit (EXIT_FAILURE);
6806 }
6807 char *pg2path (char *pg)
6808 {
6809   char *path;
6810   
6811   char *tmp;
6812  
6813     
6814   if ( !pg) return NULL;
6815   tmp=vtmpnam(NULL);
6816   
6817   printf_system_direct("which %s>%s 2>/dev/null", pg, tmp);
6818   path=file2string (tmp);
6819   chomp (path);
6820   if (!file_exists (NULL,path) && !strstr (pg, ".exe"))
6821     {
6822       char pg2[1000];
6823       sprintf ( pg2, "%s.exe", pg);
6824       path=pg2path (pg2);
6825     }
6826   
6827   return path;
6828 }
6829   
6830
6831 int check_program_is_installed ( char *program_name, char *path_variable, char *path_variable_name, char *where2getit, int fatal)
6832   {
6833    
6834    static char *path;
6835    int install_4_tcoffee=0;
6836    
6837    if (atoigetenv("INSTALL_4_TCOFFEE"))install_4_tcoffee=1;
6838    
6839    if ( strm (where2getit, "built_in"))return 1;
6840    
6841    if (path)vfree (path);
6842    
6843    if ( check_file_exists (path_variable))
6844      {
6845        return 1;
6846      }
6847    else 
6848      {
6849        
6850        path=pg2path (program_name);
6851        if (path && path[0])return 1;
6852        else
6853          {
6854            int install=EXIT_FAILURE;
6855                
6856            if ((fatal==INSTALL || fatal==INSTALL_OR_DIE) && install_4_tcoffee)
6857              {
6858                HERE ("************** %s is missing from your system. T-Coffee will make an attempt to install it.\n", program_name);
6859                install=printf_system ("install.pl %s -plugins=%s -clean", program_name, get_plugins_4_tcoffee());
6860              }
6861            if ( install==EXIT_SUCCESS)return 1;
6862            else if ( fatal==INSTALL)return 0;
6863            else if ( fatal==NO_REPORT)return 0;
6864            
6865            if (fatal==IS_FATAL || fatal==INSTALL_OR_DIE)check_configuration4program();
6866            
6867            fprintf ( stderr, "\n#*****************************************************************");
6868            if (fatal) fprintf_error ( stderr, "\n#ERROR [FATAL:%s]", PROGRAM);
6869            else fprintf ( stderr, "\n#WARNING [%s]", PROGRAM);
6870            fprintf ( stderr, "\n# The Program %s Needed by %s Could not be found", program_name, PROGRAM);
6871            fprintf ( stderr, "\n# If %s is installed on your system:", program_name);
6872            fprintf ( stderr, "\n#\t     -Make sure %s is in your $path:",program_name);
6873            
6874            fprintf ( stderr, "\n# If %s is NOT installed obtain a copy from:", program_name);
6875            fprintf ( stderr, "\n#\t%s\n#\n#",where2getit); 
6876            fprintf ( stderr, "\n# and install it manualy");
6877            fprintf ( stderr, "\n******************************************************************\n");
6878          }
6879      }
6880    if ( fatal==IS_FATAL || fatal==INSTALL_OR_DIE) myexit (EXIT_FAILURE);
6881    return 0;
6882   }
6883
6884 FILE * display_output_filename ( FILE *io, char *type, char *format, char *name, int check_output)
6885 {
6886   static char ***buf;
6887   static int nbuf;
6888   char *f;
6889   
6890   if ( strm ( name, "stdout") || strm (name, "stderr"))return io;
6891   
6892   if ( check_output==STORE)
6893     {
6894       int a;
6895       if ( buf==NULL)buf=vcalloc ( 1000, sizeof (char**));
6896       
6897       for (a=0; a<nbuf; a++)
6898         if ( strm (name, buf[a][2]))return io;
6899       
6900       buf[nbuf]=declare_char (3, 1000);
6901       sprintf ( buf[nbuf][0], "%s", type);
6902       sprintf ( buf[nbuf][1], "%s", format);
6903       sprintf ( buf[nbuf][2], "%s", name);
6904       nbuf++;
6905       return io;
6906     }
6907   else if ( check_output==FLUSH)
6908     {
6909       int a;
6910
6911       for ( a=0; a< nbuf; a++)
6912         {
6913           io=display_output_filename ( io, buf[a][0], buf[a][1], buf[a][2], CHECK);
6914           
6915           free_char (buf[a], -1);
6916         }
6917       nbuf=0;
6918     }
6919   else if ( check_output==CHECK)
6920     {
6921       if (check_file_exists(name)==NULL)
6922         {
6923           if ( !strm (name, "no") && !strm (name, "NO") && !strm (name, "STDOUT") && !strm(name, "stdout"))
6924                add_warning( io, "\n\t#### File Type= %-15s Format= %-15s Name= %s | NOT PRODUCED [WARNING:%s:%s]\n",type, format, name, PROGRAM, VERSION );
6925           return io;
6926         }
6927       fprintf ( io, "\n\t#### File Type= %-15s Format= %-15s Name= %s",type, format, name );
6928       io=display_output_filename ( io,type,format,name, DUMP);
6929     }
6930   else if (check_output==DUMP)
6931     {
6932       
6933       FILE *out;
6934       FILE *fp;
6935       if ((f=get_string_variable ("dump_output_file")))
6936         {
6937           char c;
6938           char *list;
6939           
6940           if ((list=get_string_variable ("dump_output_file_list")))
6941              {
6942                fp=fopen (list, "a");
6943                fprintf (fp, "##%s##",name);
6944                fclose (fp);
6945              }
6946           
6947           if ((out=fopen (f, "a"))!=NULL)
6948             {
6949               fprintf (out, "<file>\n");
6950               fprintf (out,"<stream>output</stream>\n");
6951               fprintf (out,"<type>%s</type>\n", type);
6952               fprintf (out, "<format>%s</format>\n", format);
6953               fprintf (out, "<name>%s</name>\n", name);
6954               fprintf (out, "<content>\n");
6955               if ((fp=fopen (name, "r"))!=NULL)
6956                 {
6957                   while ((c=fgetc (fp))!=EOF){fprintf(out, "%c",c);}
6958                   fclose (fp);
6959                 }
6960               fprintf (out,"</content>\n</file>\n");
6961               fclose (out);
6962             }
6963         }
6964      
6965     }
6966   return io;
6967 }
6968
6969 FILE * display_input_filename ( FILE *io, char *type, char *format, char *name, int check_output)
6970 {
6971   if ( check_output==CHECK && check_file_exists(name)==NULL)
6972     {
6973       fprintf ( io, "\n\tIIII INPUT File Type= %10s Format= %10s Name= %s | NOT PRODUCED [WARNING:%s:%s]\n",type, format, name, PROGRAM, VERSION );
6974       return io;
6975     }
6976   fprintf ( io, "\n\t#### File Type= %10s Format= %10s Name= %s",type, format, name );
6977   return io;
6978 }
6979
6980 int file_is_empty (char *fname)
6981 {
6982   struct stat s;
6983   if (!fname) return 1;
6984
6985   stat (fname, &s);
6986   if (s.st_size)return 0;
6987   else return 1;
6988   }
6989 int file_exists (char *path, char *fname)
6990 {
6991   struct stat s;
6992   char file[1000];
6993
6994   if (!fname)return 0;
6995   else if (path && strm (path, "CACHE"))
6996     {
6997       if (file_exists (NULL, fname))return 1;
6998       else return file_exists (get_cache_dir(), fname);
6999     }
7000   else if (path) sprintf ( file, "%s/%s", path, fname);
7001   else if (!path)sprintf (file, "%s", fname);
7002     
7003   if (stat(file,& s)!=-1)
7004     return S_ISREG(s.st_mode);
7005   else return 0;
7006 }
7007
7008 int isdir  (char *file)
7009 {
7010   struct stat s;
7011   if (stat (file,&s)!=-1)
7012     return S_ISDIR(s.st_mode);
7013   else return 0;
7014 }
7015 int rrmdir (char *s)
7016 {
7017   if (isdir(s))return printf_system_direct ("rm -r %s", s);
7018   return EXIT_FAILURE;
7019 }
7020     
7021 int isexec (char *file)
7022 {
7023   char *state;
7024   
7025   
7026   state=ls_l(NULL,file);
7027   
7028   if (state[0]==0) return 0;
7029   
7030   if ( state[0]=='d') return 0;
7031   if ( state[3]=='x') return 1;
7032   if ( state[6]=='x') return 1;
7033   if ( state[9]=='x') return 1;
7034   return 0;
7035 }
7036
7037 char *ls_l ( char *path,char *file)
7038 {
7039   char *tmpfile;
7040   static char *state;
7041   FILE *fp;
7042   int a;
7043   
7044   tmpfile=vtmpnam (NULL);
7045   if (!state)
7046     {
7047   
7048       state=vcalloc (100, sizeof (char));
7049     }
7050   for (a=0;a<100; a++)state[a]=0;
7051   if (!file || !file_exists (path, file))return state;
7052   printf_system_direct ("ls -l %s%s%s >%s 2>/dev/null",(path!=NULL)?path:"", (path!=NULL)?"/":"",file, tmpfile);
7053   
7054   fp=vfopen (tmpfile, "r");
7055   if (!fscanf ( fp, "%s", state))
7056     {
7057       vfclose(fp); return 0;
7058     }
7059   vfclose (fp);
7060   return state;
7061 }
7062
7063 int my_rmdir ( char *dir_in)
7064 {
7065   int dir_sep='/';
7066   
7067  int a, buf;
7068  char *dir;
7069  
7070  dir=vcalloc ( strlen (dir_in)+strlen (get_home_4_tcoffee())+100, sizeof (char));
7071  sprintf ( dir, "%s", dir_in);
7072  tild_substitute ( dir, "~",get_home_4_tcoffee());
7073  
7074  if (access(dir, F_OK)==-1);
7075  else 
7076    {
7077      if ( strstr (dir, "coffee"))printf_system ( "rm -rf %s", dir);
7078      else myexit(fprintf_error ( stderr, "\nERROR: directory %s does not contain 'coffee' [FATAL:%s]", dir, PROGRAM));          } 
7079  vfree (dir);return;
7080 }
7081
7082 int my_mkdir ( char *dir_in)
7083 {
7084   
7085   int dir_sep='/';
7086   
7087   int a, buf;
7088   char *dir;
7089
7090   dir=vcalloc ( strlen (dir_in)+strlen (get_home_4_tcoffee())+100, sizeof (char));
7091   sprintf ( dir, "%s", dir_in);
7092   tild_substitute ( dir, "~",get_home_4_tcoffee());
7093   
7094       
7095   
7096   a=0;
7097
7098   while (dir[a]!='\0')
7099     {
7100       
7101       if ( dir[a]==dir_sep || dir[a+1]=='\0')
7102         {
7103           buf= dir[a+1];
7104           dir[a+1]='\0';
7105
7106           if (access(dir, F_OK)==-1)
7107             {
7108             
7109
7110               printf_system_direct("mkdir %s", dir);
7111               if ( access (dir, F_OK)==-1)
7112                 {
7113                   myexit(fprintf_error ( stderr, "\nERROR: Could Not Create Directory %s [FATAL:%s]", dir, PROGRAM));           }
7114             }
7115           dir[a+1]=buf;
7116         } 
7117       a++;
7118     }
7119
7120   vfree (dir);
7121   return 1;
7122 }
7123
7124 int filename_is_special (char *fname)
7125 {
7126   if ( strm5 (fname, "default", "stdin", "stdout","stderr", "/dev/null"))return 1;
7127   if ( strm3 (fname, "STDIN", "STDOUT", "STDERR"))return 1;
7128   return 0;
7129 }
7130
7131 char* check_file_exists ( char *fname_in)
7132         {
7133         
7134         static char *fname1;
7135         static char *fname2;
7136         
7137         
7138         if (!fname_in)return NULL;
7139         if (!fname_in[0])return NULL;
7140         if (fname_in[0]=='-')return NULL;
7141         
7142         if (!fname1){fname1=vcalloc (1000, sizeof (char));}
7143         if (!fname2){fname2=vcalloc (1000, sizeof (char));}
7144         
7145         sprintf ( fname1, "%s", fname_in);tild_substitute (fname1, "~", get_home_4_tcoffee());
7146         sprintf ( fname2, "%s%s", get_cache_dir(),fname1);
7147
7148         if ( filename_is_special (fname1))return fname1;
7149         if ( strm5 (fname1, "no", "NO", "No", "NO_FILE","no_file"))return NULL/*fname1*/;
7150         if (!file_exists( NULL,fname1)) 
7151           {
7152             if (!file_exists (NULL,fname2))return NULL;
7153             else return fname2;
7154           }
7155         else return fname1;
7156         return NULL;
7157         }       
7158
7159
7160 void create_file ( char *name)
7161         {
7162         FILE *fp;
7163         
7164         fp=fopen (name, "w");
7165         fclose (fp);
7166         }
7167 void delete_file ( char *fname)
7168         {
7169
7170         FILE * fp;
7171         
7172         fp=fopen ( fname, "w");
7173         fprintf ( fp, "x");
7174         fclose ( fp);
7175         
7176         printf_system_direct ("rm %s", fname);
7177         }       
7178
7179 int util_rename ( char *from, char *to)
7180         {
7181         FILE *fp_from;
7182         FILE *fp_to;
7183         int c;
7184
7185         
7186         if ( !check_file_exists (from))return 0;
7187         else if ( check_file_exists (to) && !vremove (to) && !rename ( from, to)==0 );
7188         else
7189                 {
7190                  
7191                 fp_from=vfopen ( from, "r");
7192                 fp_to=vfopen ( to, "w");
7193                 
7194                 while ( (c=fgetc (fp_from))!=EOF)fprintf ( fp_to, "%c", c);
7195
7196                 fclose (fp_from);
7197                 fclose ( fp_to);
7198
7199                 vremove ( from);
7200                 return 1;
7201                 }
7202         return 0;
7203         }
7204
7205
7206 int util_copy (  char *from, char *to)
7207         {
7208         FILE *fp_from;
7209         FILE *fp_to;
7210         int c;
7211
7212         
7213         if (!check_file_exists (from))return 0;
7214         else
7215                 {
7216                  
7217                 fp_from=vfopen ( from, "r");
7218                 fp_to=vfopen ( to, "w");
7219                 
7220                 while ( (c=fgetc (fp_from))!=EOF)fprintf ( fp_to, "%c", c);
7221
7222                 fclose (fp_from);
7223                 fclose ( fp_to);
7224                 return 1;
7225                 }
7226         return 0;
7227         } 
7228 FILE * output_completion4halfmat ( FILE *fp,int n, int tot, int n_reports, char *s)
7229
7230 {
7231   int max, left, achieved;
7232   int up;
7233   
7234   if (n>=0)up=1;
7235   else up=-1;
7236   
7237
7238   max=((tot*tot)-tot)/2;
7239   left=((tot-n)*(tot-n)-(tot-n))/2;
7240   
7241   achieved=max-left;
7242   if (up==1);
7243   else
7244     {
7245       int b;
7246       b=achieved;
7247       achieved=left;
7248       left=b;
7249     }
7250   return output_completion (fp,achieved, max, n_reports, s);
7251 }
7252   
7253   
7254 FILE * output_completion ( FILE *fp,int n, int tot, int n_reports, char *string)
7255         {
7256
7257           static int ref_val;
7258           static int flag;
7259           static int ref_time;
7260           int t, elapsed;
7261           n++;
7262           
7263           if ( n==1)
7264             {
7265               ref_val=flag=0;
7266               ref_time=get_time()/1000;
7267             }
7268           t=get_time()/1000;
7269           elapsed=t-ref_time;
7270             
7271           if ( !ref_val && !flag)
7272             {
7273               fprintf (fp, "\n\t\t[%s][TOT=%5d][%3d %%][ELAPSED TIME: %4d sec.]",(string)?string:"",tot,(tot==1)?100:0, elapsed);
7274               flag=1;
7275             }
7276           else if ( n==tot)fprintf (fp, "\r\t\t[%s][TOT=%5d][%3d %%][ELAPSED TIME: %4d sec.]",(string)?string:"", tot,100, elapsed);
7277           else if ( ((n*100)/tot)>ref_val)
7278             {
7279               ref_val=((n*100)/tot);
7280               t=(ref_val==0)?0:elapsed/ref_val;
7281               t=t*(100-ref_val);
7282               t=0;
7283               fprintf (fp, "\r\t\t[%s][TOT=%5d][%3d %%][ELAPSED TIME: %4d sec.]", (string)?string:"",tot,ref_val, elapsed);
7284               flag=0;
7285             }      
7286           return fp;
7287         }
7288 void * null_function (int a,...)
7289 {
7290   myexit(fprintf_error ( stderr, "\n[ERROR] Attempt to use the Null Function [FATAL:%s]", PROGRAM));
7291   
7292   return NULL;
7293 }
7294
7295 int  btoi ( int nc,...)
7296 {
7297   va_list ap;
7298   int a, b;
7299   va_start (ap, nc);
7300   for ( a=0, b=0; a< nc; a++)
7301     {
7302       b+=pow(2,a)*va_arg (ap,int);
7303     }
7304   va_end(ap);
7305   return b;
7306 }
7307
7308 /*********************************************************************/
7309 /*                                                                   */
7310 /*                         Geometric FUNCTIONS                    */
7311 /*                                                                   */
7312 /*                                                                   */
7313 /*********************************************************************/
7314
7315 float get_geometric_distance ( float ** matrix, int ncoor, int d1, int d2, char *mode)
7316 {
7317   float d;
7318   float t=0;
7319   int a;
7320
7321   if ( strm (mode, "euclidian"))
7322     {
7323       for ( a=0; a< ncoor; a++)
7324         {
7325           d=(matrix[d1][a]-matrix[d2][a]);
7326           t+=d*d;
7327         }
7328       return (float)sqrt((double)t);
7329     }
7330   return 0;
7331 }
7332        
7333
7334
7335 /*********************************************************************/
7336 /*                                                                   */
7337 /*                         MATHEMATICAL FUNCTIONS                    */
7338 /*                                                                   */
7339 /*                                                                   */
7340 /*********************************************************************/
7341 static double EXP_UNDERFLOW_THRESHOLD = -4.60f;
7342 static double LOG_UNDERFLOW_THRESHOLD = 7.50f;
7343 static double LOG_ZERO = -FLT_MAX;
7344 static double LOG_ONE = 0.0f;
7345 double log_addN (int N, double*L)
7346      
7347 {
7348   double v;
7349   int a;
7350   if (N==0)return 0;
7351   if ( N==1)return L[0];
7352   
7353   v=L[0];
7354   for ( a=1; a<N; a++)
7355     {
7356       v=log_add2(v, L[a]);
7357     }
7358   return v;
7359   }
7360 double log_add6 (double x, double y, double z, double w, double v, double e)
7361 {
7362   return log_add2(log_add3(x, y, z),log_add3(z,w,e));
7363 }
7364 double log_add5 (double x, double y, double z, double w, double v)
7365 {
7366   return log_add3(log_add2(x, y),log_add2(z,w),v );
7367 }
7368 double log_add4 (double x, double y, double z, double w)
7369 {
7370   return log_add2(log_add2(x, y),log_add2(z,w));
7371 }
7372 double log_add3 (double x, double y, double z)
7373 {
7374   return log_add2(log_add2(x, y),z);
7375 }
7376 double log_add2 ( double x, double y)
7377 {
7378   if (x < y)
7379     x = (x == LOG_ZERO || ((y - x) >= LOG_UNDERFLOW_THRESHOLD)) ? y : log (exp (x-y) + 1) + x;
7380   else
7381     x = (y == LOG_ZERO || ((x - y) >= LOG_UNDERFLOW_THRESHOLD)) ? x : log (exp (x-y) + 1) + y;
7382   return x;
7383 }
7384
7385
7386   
7387   
7388 float M_chooses_Nlog ( int m, int N)
7389 {
7390   /*Choose M elemets in N*/
7391   float  z1, z2,z=0;
7392   if ( m==N) return 0;
7393   else if ( m>N)
7394     {
7395       myexit(fprintf_error ( stderr, "\nERROR: M chosses N out of bounds ( M>N) [FATAL:%s]", PROGRAM));
7396       myexit (EXIT_FAILURE);
7397     }
7398   else
7399     {
7400       z1=factorial_log (m+1, N);
7401       z2=factorial_log (1, N-m);
7402       z=z1-z2;
7403       return z;
7404     }
7405   
7406   return -1;
7407 }  
7408
7409 float factorial_log ( int start, int end)
7410 {
7411   if ( end==0)return 0;
7412   else if ( end==start) return (float)my_int_log((double)start);
7413   else if ( start>end)
7414      {
7415        fprintf_error ( stderr, "\nERROR: factorial log out of bounds (%d %d) [FATAL:%s]",start, end, PROGRAM);
7416        myexit (EXIT_FAILURE);
7417     }
7418   else
7419     {
7420       int a=0;
7421       float x=0;
7422       for ( x=0,a=start; a<=end; a++)
7423         {
7424           x+=(float)my_int_log(a);
7425         }
7426       return x;
7427     }
7428   return 0;
7429 }
7430
7431 float my_int_log(int a)
7432 {
7433   
7434   if ( a>=100000)return log(a);
7435   else
7436     {
7437       static float *lu;
7438       if (!lu) lu=vcalloc ( 100000, sizeof (float));
7439       if ( !lu[a]){lu[a]=log(a);}
7440       return lu[a];
7441     }
7442   return 0;
7443 }
7444
7445 double factorial (int start, int end);
7446 double M_chooses_N ( int m, int N)
7447 {
7448   /*Choose M elemets in N*/
7449   if ( m==N) return 1;
7450   else if ( m>N)
7451     {
7452       fprintf_error ( stderr, "\nERROR: M chosses N out of bounds ( M>N) [FATAL:%s]", PROGRAM);
7453       myexit (EXIT_FAILURE);
7454     }
7455   else if ( N<50)
7456     {
7457       return factorial (m+1, N)/factorial (1, N-m);
7458     }
7459   else
7460     {
7461       fprintf_error ( stderr, "\nERROR: M chosses N out of bounds ( N>50). Use log space [FATAL:%s]", PROGRAM);
7462       myexit (EXIT_FAILURE);
7463     }
7464   return -1;
7465 }
7466 double factorial (int start, int end)
7467   {
7468     
7469     if ( start>end || start<0 || end<0)
7470       {
7471         fprintf_error ( stderr, "\nERROR: Negative Factorial [FATAL:%s]", PROGRAM);
7472         myexit ( EXIT_FAILURE);
7473       }
7474     else if (end==0) return 1;
7475     else if (end==start) return end;
7476     else
7477       {
7478         static double **lu;
7479         if ( !lu)lu=declare_double (100, 100);
7480         
7481         if ( lu[start][end])return lu[start][end];
7482         else
7483           {
7484             int a;
7485             lu[start][end]=(double)start;
7486             for ( a=start+1; a<=end; a++)
7487               {
7488                 lu[start][end]*=(double)a;
7489               }
7490             return  lu[start][end];
7491           }
7492       }
7493     return -1;
7494   }
7495 /*********************************************************************/
7496 /*                                                                   */
7497 /*                         Fast Log Additions (adapted from Probcons)*/
7498 /*                                                                   */
7499 /*                                                                   */
7500 /*********************************************************************/
7501 double EXP (double x){
7502   //return exp(x);
7503   if (x > -2){
7504     if (x > -0.5){
7505       if (x > 0)
7506         return exp(x);
7507       return (((0.03254409303190190000*x + 0.16280432765779600000)*x + 0.49929760485974900000)*x + 0.99995149601363700000)*x + 0.99999925508501600000;
7508     }
7509     if (x > -1)
7510       return (((0.01973899026052090000*x + 0.13822379685007000000)*x + 0.48056651562365000000)*x + 0.99326940370383500000)*x + 0.99906756856399500000;
7511     return (((0.00940528203591384000*x + 0.09414963667859410000)*x + 0.40825793595877300000)*x + 0.93933625499130400000)*x + 0.98369508190545300000;
7512   }
7513   if (x > -8){
7514     if (x > -4)
7515       return (((0.00217245711583303000*x + 0.03484829428350620000)*x + 0.22118199801337800000)*x + 0.67049462206469500000)*x + 0.83556950223398500000;
7516     return (((0.00012398771025456900*x + 0.00349155785951272000)*x + 0.03727721426017900000)*x + 0.17974997741536900000)*x + 0.33249299994217400000;
7517   }
7518   if (x > -16)
7519     return (((0.00000051741713416603*x + 0.00002721456879608080)*x + 0.00053418601865636800)*x + 0.00464101989351936000)*x + 0.01507447981459420000;
7520   return 0;
7521 }
7522
7523 float LOOKUP (float x){
7524
7525   if (x <= 1.00f) return ((-0.009350833524763f * x + 0.130659527668286f) * x + 0.498799810682272f) * x + 0.693203116424741f;
7526   if (x <= 2.50f) return ((-0.014532321752540f * x + 0.139942324101744f) * x + 0.495635523139337f) * x + 0.692140569840976f;
7527   if (x <= 4.50f) return ((-0.004605031767994f * x + 0.063427417320019f) * x + 0.695956496475118f) * x + 0.514272634594009f;
7528   
7529   return ((-0.000458661602210f * x + 0.009695946122598f) * x + 0.930734667215156f) * x + 0.168037164329057f;
7530 }
7531 void LOG_PLUS_EQUALS (float *x, float y){
7532   
7533   if (x[0] < y)
7534     x[0] = (x[0] == LOG_ZERO || y - x[0] >= LOG_UNDERFLOW_THRESHOLD) ? y : LOOKUP(y-x[0]) + x[0];
7535   else
7536     x[0] = (y == LOG_ZERO || x[0] - y >= LOG_UNDERFLOW_THRESHOLD) ? x[0]  : LOOKUP(x[0]-y) + y;
7537 }
7538
7539 float LOG_ADD (float x, float y){
7540   if (x < y) return (x == LOG_ZERO || y - x >= LOG_UNDERFLOW_THRESHOLD) ? y : LOOKUP((y-x)) + x;
7541   return (y == LOG_ZERO || x - y >= LOG_UNDERFLOW_THRESHOLD) ? x : LOOKUP((x-y)) + y;
7542 }
7543
7544 float LOG_ADD3 (float x1, float x2, float x3){
7545   return LOG_ADD (x1, LOG_ADD (x2, x3));
7546 }
7547 float LOG_ADD4 (float x1, float x2, float x3, float x4){
7548   return LOG_ADD (x1, LOG_ADD (x2, LOG_ADD (x3, x4)));
7549 }
7550 float LOG_ADD5 (float x1, float x2, float x3, float x4, float x5){
7551   return LOG_ADD (x1, LOG_ADD (x2, LOG_ADD (x3, LOG_ADD (x4, x5))));
7552 }
7553 float LOG_ADD6 (float x1, float x2, float x3, float x4, float x5, float x6){
7554   return LOG_ADD (x1, LOG_ADD (x2, LOG_ADD (x3, LOG_ADD (x4, LOG_ADD (x5, x6)))));
7555 }
7556 float LOG_ADD7 (float x1, float x2, float x3, float x4, float x5, float x6, float x7){
7557   return LOG_ADD (x1, LOG_ADD (x2, LOG_ADD (x3, LOG_ADD (x4, LOG_ADD (x5, LOG_ADD (x6, x7))))));
7558 }
7559
7560
7561 #define LONG_SIZE 2
7562 #define SHORT_SIZE 1
7563 #define SPACE_PAD 4
7564 #define STD_SIZE 0    
7565 char *strscn(char *s, char *pattern);
7566 long unsigned strtou(char *s, int base, char **scan_end);
7567 long int strtoi(char *s, int base, char **scan_end);
7568 int my_isnumber(char c, int base);
7569 int tonumber(char c);
7570
7571 int my_vsscanf(char *buf, char *fmt, va_list parms)
7572  {
7573          int scanned = 0, size = 0, suppress = 0;
7574          int w = 0, flag = 0, l = 0;
7575          char c, *c_ptr;
7576          long int n1, *n1l;
7577          int *n1b;
7578          short int *n1s;
7579          long unsigned n2, *n2l, parsing = 0;
7580          unsigned *n2b;
7581          short unsigned *n2s;
7582          double n3, *n3l;
7583          float *n3s;
7584          char *base = buf;
7585          while (*fmt != 0) {
7586                  if (*fmt != '%' && !parsing) {
7587                          /* No token detected */
7588                          fmt++;
7589                  } else {
7590                          /* We need to make a conversion */
7591                          if (*fmt == '%') {
7592                                  fmt++;
7593                                  parsing = 1;
7594                                  size = STD_SIZE;
7595                                  suppress = 0;
7596                                  w = 0;
7597                                  flag = 0;
7598                                  l = 0;
7599                          }
7600                          /* Parse token */
7601                          switch (*fmt) {
7602                          case '1':
7603                          case '2':
7604                          case '3':
7605                          case '4':
7606                          case '5':
7607                          case '6':
7608                          case '7':
7609                          case '8':
7610                          case '9':
7611                          case '0':
7612                                  if (parsing == 1) {
7613                                          w = strtou(fmt, 10, &base);
7614                                          /* We use SPACE_PAD to parse %10s
7615                                           * commands where the number is the
7616                                           * maximum number of char to store!
7617                                           */
7618                                          flag |= SPACE_PAD;
7619                                          fmt = base - 1;
7620                                  }
7621                                  break;
7622                          case 'c':
7623                                  c = *buf++;
7624                                  c_ptr = va_arg(parms, char *);
7625                                  *c_ptr = c;
7626                                  scanned++;
7627                                  parsing = 0;
7628                                  break;
7629                          case 's':
7630                                  c_ptr = va_arg(parms, char *);
7631                                  while (*buf != 0 && isspace(*buf))
7632                                          buf++;
7633                                  l = 0;
7634                                  while (*buf != 0 && !isspace(*buf)) {
7635                                          if (!(flag & SPACE_PAD))
7636                                                  *c_ptr++ = *buf;
7637                                          else if (l < w) {
7638                                                  *c_ptr++ = *buf;
7639                                                  l++;
7640                                          }
7641                                          buf++;
7642                                  }
7643                                  *c_ptr = 0;
7644                                  scanned++;
7645                                  parsing = 0;
7646                                  break;
7647                          case 'i':
7648                          case 'd':
7649                                  buf = strscn(buf, "1234567890-+");
7650                                  n1 = strtoi(buf, 10, &base);
7651                                  buf = base;
7652                                  if (!suppress) {
7653                                          switch (size) {
7654                                          case STD_SIZE:
7655                                                  n1b = va_arg(parms, int *);
7656                                                  *n1b = (int) n1;
7657                                                  break;
7658                                          case LONG_SIZE:
7659                                                  n1l = va_arg(parms,
7660                                                               long int *);
7661                                                  *n1l = n1;
7662                                                  break;
7663                                          case SHORT_SIZE:
7664                                                  n1s = va_arg(parms,
7665                                                               short int *);
7666                                                  *n1s = (short) (n1);
7667                                                  break;
7668                                          }
7669                                          scanned++;
7670                                  }
7671                                  parsing = 0;
7672                                  break;
7673                          case 'u':
7674                                  buf = strscn(buf, "1234567890");
7675                                  n2 = strtou(buf, 10, &base);
7676                                  buf = base;
7677                                  if (!suppress) {
7678                                          switch (size) {
7679                                          case STD_SIZE:
7680                                                  n2b = va_arg(parms,
7681                                                               unsigned *);
7682                                                  *n2b = (unsigned) n2;
7683                                                  break;
7684                                          case LONG_SIZE:
7685                                                  n2l = va_arg(parms,
7686                                                               long unsigned *);
7687                                                  *n2l = n2;
7688                                                  break;
7689                                          case SHORT_SIZE:
7690                                                  n2s = va_arg(parms, short unsigned
7691                                                               *);
7692                                                  *n2s = (short) (n2);
7693                                                  break;
7694                                          }
7695                                          scanned++;
7696                                  }
7697                                  parsing = 0;
7698                                  break;
7699                          case 'x':
7700                                  buf = strscn(buf, "1234567890xabcdefABCDEF");
7701                                  n2 = strtou(buf, 16, &base);
7702                                  buf = base;
7703                                  if (!suppress) {
7704                                          switch (size) {
7705                                          case STD_SIZE:
7706                                                  n2b = va_arg(parms,
7707                                                               unsigned *);
7708                                                  *n2b = (unsigned) n2;
7709                                                  break;
7710                                          case LONG_SIZE:
7711                                                  n2l = va_arg(parms,
7712                                                               long unsigned *);
7713                                                  *n2l = n2;
7714                                                  break;
7715                                          case SHORT_SIZE:
7716                                                  n2s = va_arg(parms, short unsigned
7717                                                               *);
7718                                                  *n2s = (short) (n2);
7719                                                  break;
7720                                          }
7721                                          scanned++;
7722                                  }
7723                                  parsing = 0;
7724                                  break;
7725                          case 'f':
7726                          case 'g':
7727                          case 'e':
7728                                  buf = strscn(buf, "1234567890.e+-");
7729                                  n3 = strtod(buf, &base);
7730                                  buf = base;
7731                                  if (!suppress) {
7732                                          switch (size) {
7733                                          case STD_SIZE:
7734                                                  n3l = va_arg(parms, double *);
7735                                                  *n3l = n3;
7736                                                  break;
7737                                          case LONG_SIZE:
7738                                                  n3l = va_arg(parms, double *);
7739                                                  *n3l = n3;
7740                                                  break;
7741                                          case SHORT_SIZE:
7742                                                  n3s = va_arg(parms, float *);
7743                                                  *n3s = (float) (n3);
7744                                                  break;
7745                                          }
7746                                          scanned++;
7747                                  }
7748                                  parsing = 0;
7749                                  break;
7750                          case 'l':
7751                                  size = LONG_SIZE;
7752                                  break;
7753                          case 'h':
7754                          case 'n':
7755                                  size = SHORT_SIZE;
7756                                  break;
7757                          case '*':
7758                                  suppress = 1;
7759                                  break;
7760                          default:
7761                                  parsing = 0;
7762                                  break;
7763                          }
7764                          fmt++;
7765                  }
7766          }
7767          return (scanned);
7768  }
7769 char *strscn(char *s, char *pattern)
7770  {
7771          char *scan;
7772          while (*s != 0) {
7773                  scan = pattern;
7774                  while (*scan != 0) {
7775                          if (*s == *scan)
7776                                  return (s);
7777                          else
7778                                  scan++;
7779                  }
7780                  s++;
7781          }
7782          return (NULL);
7783  }
7784
7785 long unsigned strtou(char *s, int base, char **scan_end)
7786  {
7787          int value, overflow = 0;
7788          long unsigned result = 0, oldresult;
7789          /* Skip trailing zeros */
7790          while (*s == '0')
7791                  s++;
7792          if (*s == 'x' && base == 16) {
7793                  s++;
7794                  while (*s == '0')
7795                          s++;
7796          }
7797          /* Convert number */
7798          while (my_isnumber(*s, base)) {
7799                  value = tonumber(*s++);
7800                  if (value > base || value < 0)
7801                          return (0);
7802                  oldresult = result;
7803                  result *= base;
7804                  result += value;
7805                  /* Detect overflow */
7806                  if (oldresult > result)
7807                          overflow = 1;
7808          }
7809          if (scan_end != 0L)
7810                  *scan_end = s;
7811          if (overflow)
7812                  result = INT_MAX;
7813          return (result);
7814  }
7815 long int strtoi(char *s, int base, char **scan_end)
7816  {
7817          int sign, value, overflow = 0;
7818          long int result = 0, oldresult;
7819          /* Evaluate sign */
7820          if (*s == '-') {
7821                  sign = -1;
7822                  s++;
7823          } else if (*s == '+') {
7824                  sign = 1;
7825                  s++;
7826          } else
7827                  sign = 1;
7828          /* Skip trailing zeros */
7829          while (*s == '0')
7830                  s++;
7831          /* Convert number */
7832          while (my_isnumber(*s, base)) {
7833                  value = tonumber(*s++);
7834                  if (value > base || value < 0)
7835                          return (0);
7836                  oldresult = result;
7837                  result *= base;
7838                  result += value;
7839                  /* Detect overflow */
7840                  if (oldresult > result)
7841                          overflow = 1;
7842          }
7843          if (scan_end != 0L)
7844                  *scan_end = s;
7845          if (overflow)
7846                  result = INT_MAX;
7847          result *= sign;
7848          return (result);
7849  }
7850
7851 int my_isnumber(char c, int base)
7852  {
7853          static char *digits = "0123456789ABCDEF";
7854          if ((c >= '0' && c <= digits[base - 1]))
7855                  return (1);
7856          else
7857                  return (0);
7858  }
7859
7860  int tonumber(char c)
7861  {
7862          if (c >= '0' && c <= '9')
7863                  return (c - '0');
7864          else if (c >= 'A' && c <= 'F')
7865                  return (c - 'A' + 10);
7866          else if (c >= 'a' && c <= 'f')
7867                  return (c - 'a' + 10);
7868          else
7869                  return (c);
7870  }
7871
7872 ///////////////////////////////////////////////////////////////////////////////////////////
7873 // Hash function
7874 ////////////////////////////////////////////////////////////////////////////////////////////
7875 unsigned long hash_file(char* file)  //returns the hash value for key 
7876     {
7877       // Calculate a hash value by the division method: 
7878       // Transform key into a natural number k = sum ( key[i]*128^(L-i) ) and calculate i= k % num_slots. 
7879       // Since calculating k would lead to an overflow, i is calculated iteratively 
7880       // and at each iteration the part divisible by num_slots is subtracted, i.e. (% num_slots is taken).
7881       
7882       unsigned long i=0;     // Start of iteration: k is zero
7883       unsigned long num_slots=999999999;
7884       
7885
7886       FILE *fp;
7887       unsigned long c;
7888
7889       
7890       if (file==NULL || !check_file_exists (file) ) {printf("Warning from util.c:hasch_file: No File [FATAL:%s]\n", PROGRAM); myexit (EXIT_FAILURE);}
7891       num_slots/=128;
7892       fp=vfopen (file, "r");
7893       while ( (c=fgetc (fp))!=EOF)
7894         {
7895           i = ((i<<7) + c) % num_slots; 
7896         }
7897       vfclose (fp);
7898               
7899       return i;
7900     }
7901 int ** r_generate_array_int_list ( int len, int min, int max,int step, int **array, int f, int *n,FILE *fp, int *c_array);
7902 int **generate_array_int_list (int len, int min, int max, int step, int *n, char *file)
7903    {
7904      int **array, *c_array;
7905      FILE *fp=NULL;
7906      
7907      if (n==NULL)
7908        {
7909          array=NULL;
7910          fp=vfopen (file, "w");
7911        }
7912      else
7913        {
7914          int a,s;
7915          n[0]=0;
7916          for (s=1, a=0; a<len; a++)s*=((max-min)+1)/step;
7917          array=declare_int (s, len+1);
7918        }
7919      c_array=vcalloc (len, sizeof (int));
7920      array=r_generate_array_int_list ( len, max, min, step, array, 0, n,fp, c_array);
7921      vfree (c_array);
7922      if ( fp) vfclose (fp);
7923      return array;
7924    }
7925 int ** r_generate_array_int_list ( int len, int min, int max,int step, int **array, int f, int *n,FILE *fp, int *c_array)
7926    {
7927      int a;
7928      
7929      if ( f==len)
7930        {
7931          if ( array)
7932            {
7933              for (a=0; a<len; a++)
7934                {
7935                  array[n[0]][a]=c_array[a];
7936                }
7937              n[0]++;
7938            }
7939          else
7940            {
7941              
7942
7943              for (a=0; a<len; a++)fprintf ( fp, "%3d ",c_array[a]);
7944              fprintf (fp, "\n");
7945            }
7946          return array;
7947          
7948        }
7949      else
7950        {
7951          for (a=max; a<=min;a+=step)
7952            {
7953              c_array[f]=a;
7954              r_generate_array_int_list (len, min, max, step, array, f+1, n,fp, c_array);
7955            }
7956        }
7957      return array;
7958    }
7959
7960 char *** r_generate_array_string_list ( int len, char ***alp,int *alp_size, char ***array, int f, int *n,FILE *fp, char **c_array, int mode, int pstart);
7961 char ***generate_array_string_list (int len, char ***alp, int *alp_size, int *n, char *file, int mode)
7962    {
7963      char  ***array, **c_array;
7964      FILE *fp=NULL;
7965      
7966      if (file!=NULL)
7967        {
7968          array=NULL;
7969          n[0]=0;
7970          fp=vfopen (file, "w");
7971        }
7972      else
7973        {
7974          
7975          int a,s;
7976          n[0]=0;
7977          for (s=1, a=0; a<len; a++)
7978            {
7979              s*=alp_size[a];
7980            }
7981          array=declare_arrayN (3,sizeof (char), s, len,0);
7982        }
7983      c_array=declare_char (len,0);
7984      array=r_generate_array_string_list ( len, alp, alp_size, array, 0, n,fp, c_array, mode, -1);
7985      vfree (c_array);
7986      if ( fp) vfclose (fp);
7987      return array;
7988    }
7989 char *** r_generate_array_string_list ( int len, char ***alp, int *alp_size, char  ***array, int f, int *n,FILE *fp, char **c_array, int mode, int pstart)
7990    {
7991      int a;
7992      int start;
7993      
7994      if ( f==len)
7995        {
7996          if ( array)
7997            {
7998              for (a=0; a<len; a++)
7999                {
8000                  array[n[0]][a]=c_array[a];
8001                }
8002              n[0]++;
8003            }
8004          else
8005            {
8006              
8007              n[0]++;
8008              for (a=0; a<len; a++)fprintf ( fp, "%s ",c_array[a]);
8009              fprintf (fp, "\n");
8010            }
8011          return array;
8012          
8013        }
8014      else
8015        {
8016          if ( mode==OVERLAP)
8017            {
8018              start=0;
8019            }
8020          else if ( mode==NO_OVERLAP) 
8021            {
8022              start=pstart+1;
8023            }
8024
8025          for (a=start; a<alp_size[f]; a++)
8026            {
8027              c_array[f]=alp[f][a];
8028              r_generate_array_string_list (len,alp, alp_size, array, f+1, n,fp, c_array, mode, a);
8029            }
8030        }
8031      return array;
8032    }
8033 float *display_accuracy (float *count, FILE *fp)
8034 {
8035   float *r;
8036   r=counts2accuracy (count);
8037   fprintf (fp, "Sp: %.3f Sn: %.3f Sen2: %.3f AC: %.3f\n",r[0], r[1], r[2], r[3]);
8038   vfree (r);
8039   return count;
8040 }
8041 float *counts2accuracy (float *count)
8042 {
8043   //0: TP
8044   //1: TN
8045   //2: FP
8046   //3: FN
8047   float *result;
8048   float TP, TN, FP, FN;
8049   
8050   result=vcalloc (4, sizeof (float));
8051   TP=count[0];
8052   TN=count[1];
8053   FP=count[2];
8054   FN=count[3];
8055   
8056   
8057   result [0]=((TN+FP)==0)?-1:TN/(TN+FP); //Sp
8058   result [1]=((TP+FN)==0)?-1:TP/(TP+FN); //Sn
8059   result [2]=((TP+FP)==0)?-1:TP/(TP+FP); //Sen2
8060   result [3]=(((TP+FN)==0) || ((TP+FP)==0) ||  ((TN+FP)==0) || ((TN+FN)==0))?-1:0.5*((TP/(TP+FN)) + (TP/(TP+FP)) + (TN/(TN+FP)) + (TN/(TN+FN))) - 1 ;//AC
8061   
8062   return result;
8063 }
8064
8065 float  rates2sensitivity (int tp, int tn, int fp, int fn, float *sp, float *sn, float *sen2, float *b)
8066 {
8067   if (sp==NULL)
8068     {
8069       sp=vcalloc (1, sizeof (float));
8070       sn=vcalloc (1, sizeof (float));
8071       sen2=vcalloc (1, sizeof (float));
8072       b=vcalloc (1, sizeof (float));
8073     }
8074   sn[0]  =((tp+fn)==0)?1:(float)tp/(float)(tp+fn);
8075   sen2[0]=((tp+fp)==0)?1:(float)tp/(float)(tp+fp);
8076   sp[0]  =((tn+fp)==0)?1:(float)tn/(float)(tn+fp);
8077   b[0]=MIN((MIN((sp[0]),(sn[0]))),(sen2[0]));
8078   return b[0];
8079 }
8080 float profile2sensitivity (char *pred, char *ref, float *sp, float *sn, float *sen2, float *b)        
8081 {
8082   int tp=0, tn=0, fp=0, fn=0;
8083   int a, l;
8084   
8085   l=strlen (pred);
8086   
8087   for (a=0; a<l; a++)
8088     {
8089       if (pred[a]=='I' && ref[a]=='I')tp++;
8090       if (pred[a]=='O' && ref[a]=='I')fn++;
8091       if (pred[a]=='I' && ref[a]=='O')fp++;
8092       if (pred[a]=='O' && ref[a]=='O')tn++;
8093     }
8094   return  rates2sensitivity (tp, tn, fp, fn, sp, sn, sen2, b);
8095 }
8096
8097 float profile2evalue (char *pred, char *ref)
8098 {
8099   
8100   int a, l;
8101   double P=0;
8102   double E=0;
8103   double II=0;
8104   double p1, p2, p;
8105   l=strlen (pred);
8106   
8107   for (a=0; a<l; a++)
8108     {
8109       if (pred[a]=='I')P++;
8110       if (ref[a]=='I') E++;
8111       
8112       if (pred[a]=='I' && ref[a]=='I')II++;
8113     }
8114
8115   if (II==0)return 0;
8116
8117   p1= M_chooses_Nlog (P,l) + M_chooses_Nlog (II, P) + M_chooses_Nlog (E-II, l-P);
8118   p2=(M_chooses_Nlog (P,l)+M_chooses_Nlog (E,l));
8119   p=(p1-p2);
8120
8121   return (float)-p;
8122 }
8123
8124
8125
8126
8127
8128
8129                       
8130 // NEW Intitialization
8131
8132 int string_putenv    (char *p);
8133 char *env_file;
8134
8135 char ** standard_initialisation  (char **in_argv, int *in_argc)
8136 {
8137   
8138   char *s;
8139   static int done=0;
8140   char buf[1000];
8141   char **out_argv;
8142   int a, stdi,c;
8143
8144
8145
8146   
8147
8148  
8149   //Debug things
8150   debug_lock=atoigetenv("DEBUG_LOCK");
8151   
8152  
8153
8154   if (!in_argv){done=0;return NULL;}
8155   else if ( done){return in_argv;}
8156   else done=1;
8157
8158
8159   get_time();   
8160   
8161 /*Standard exit*/
8162   global_exit_signal=EXIT_SUCCESS;
8163   atexit (clean_exit);  
8164   
8165
8166   
8167   signal (SIGTERM,signal_exit);
8168   signal (SIGINT, signal_exit);
8169   signal (SIGKILL, signal_exit);
8170   
8171   signal (SIGABRT ,error_exit);
8172   signal (SIGFPE  ,error_exit);
8173   signal (SIGILL  ,error_exit);
8174   signal (SIGSEGV ,error_exit);
8175   
8176   program_name=vcalloc ( strlen (in_argv[0])+strlen (PROGRAM)+1, sizeof (char));
8177   if (in_argv)
8178     {
8179       sprintf ( program_name, "%s", in_argv[0]);
8180       out_argv=break_list ( in_argv, in_argc, "=;, \n");
8181       s=list2string2 (out_argv, in_argc[0], " ");
8182       set_command_line (s);
8183     }
8184   else sprintf ( program_name, "%s",PROGRAM); 
8185   
8186   if ( name_is_in_list ( "-no_error_report", out_argv, in_argc[0], 100)!=-1)no_error_report=1;
8187   
8188   //Plugins
8189   
8190   get_os();
8191   get_nproc();
8192         
8193   
8194
8195   if (!getenv ("UPDATED_ENV_4_TCOFFEE"))
8196     {
8197       //1-set the environment variables;
8198       file_putenv ("/usr/local/t_coffee/.t_coffee_env");//make sure child processes do not update env
8199       sprintf (buf, "%s/.t_coffee/.t_coffee_env", getenv ("HOME"));
8200       file_putenv (buf);
8201       file_putenv ("./.t_coffee_env");
8202       if (getenv ("ENV_4_TCOFFEE"))file_putenv (getenv ("ENV_4_TCOFFEE"));
8203     }
8204   
8205   string_putenv (s); //let Command line update go through
8206   
8207   
8208   cputenv ("HOME_4_TCOFFEE=%s",get_home_4_tcoffee());
8209   cputenv ("DIR_4_TCOFFEE=%s",get_dir_4_tcoffee());
8210   cputenv ("TMP_4_TCOFFEE=%s",get_tmp_4_tcoffee());
8211   cputenv ("CACHE_4_TCOFFEE=%s",get_cache_4_tcoffee());
8212   cputenv ("MCOFFEE_4_TCOFFEE=%s",get_mcoffee_4_tcoffee());
8213   cputenv ("METHODS_4_TCOFFEE=%s",get_methods_4_tcoffee());
8214   cputenv ("PLUGINS_4_TCOFFEE=%s",get_plugins_4_tcoffee());
8215   cputenv ("LOCKDIR_4_TCOFFEE=%s",get_lockdir_4_tcoffee());
8216   cputenv ("ERRORFILE_4_TCOFFEE=t_coffee.ErrorReport");
8217   
8218   
8219   
8220   
8221   
8222   string_putenv (s); //let Command line update go through //Twice in case an executable dir not created
8223   
8224   if (!getenv ("ENV_4_TCOFFEE"))cputenv ("ENV_4_TCOFFEE=%s/.t_coffee_env", get_dir_4_tcoffee());
8225   
8226   
8227   if (!getenv ("UPDATED_ENV_4_TCOFFEE"))
8228     {
8229       cputenv4path ("/usr/local/t_coffee/plugins");
8230       sprintf (buf, "%s/.t_coffee/plugins", getenv ("HOME"));
8231       cputenv4path (buf);
8232       cputenv4path ("./.plugins");
8233       if ( getenv ("PLUGINS_4_TCOFFEE"))cputenv4path (getenv ("PLUGINS_4_TCOFFEE"));
8234     }
8235   cputenv ("UPDATED_ENV_4_TCOFFEE=1");
8236  
8237   if ( debug_lock){fprintf ( stderr, "\n*************** LOCKDIR: %s *************\n", get_lockdir_4_tcoffee());}
8238     
8239   lock(getpid(),LLOCK, LRESET, "%d\n",getppid());//set the main lock
8240   if (is_shellpid(getppid()))lock(getppid(),LLOCK, LSET, "%d\n",getpid());//update parent lock when parent is shell
8241       
8242   
8243   //set special Variables
8244   if (getenv ("MAFFT_BINARIES") || isdir4path ("/usr/local/lib/mafft"));
8245   else cputenv ( "MAFFT_BINARIES=%s",get_plugins_4_tcoffee());
8246   
8247   //set proxy
8248   set_proxy(get_proxy_from_env());
8249   set_email(get_email_from_env ());
8250     
8251   //pipe_in
8252   for (a=1, stdi=0; a<in_argc[0]; a++)
8253         {
8254           if ( (strm ( out_argv[a], "stdin") || strm (out_argv[a], "STDIN")) && stdi==0)
8255             {
8256               char *file;
8257               FILE *fp, *fp_stdi;
8258               
8259               if ( stdi==0)
8260                 {
8261                   file=vtmpnam (NULL);
8262                   vfree (out_argv[a]);
8263                   out_argv[a]=vcalloc ( strlen (file)+1, sizeof (char));
8264                   sprintf (out_argv[a], "%s", file);
8265                   fp_stdi=vfopen ("stdin", "r");
8266                   fp=vfopen (file, "w");
8267                   while ( (c=fgetc (fp_stdi))!=EOF)fprintf (fp, "%c", c);
8268                   vfclose (fp);
8269                   vfclose (fp_stdi);
8270                   stdi=1;
8271                 }
8272               else if ( stdi ==1)
8273                 {
8274                   printf_exit ( EXIT_FAILURE,stderr, "ERROR: Attempt to get more than one file via pipe [FATAL:%s]\n", PROGRAM);
8275                 }
8276             }
8277         }
8278   
8279   return out_argv;
8280 }
8281 void signal_exit ()
8282  {
8283    
8284    if (is_rootpid())fprintf ( stderr, "****** Forced interuption of main parent process %d\n", getpid());
8285    
8286    global_exit_signal=EXIT_SUCCESS;
8287    myexit (EXIT_SUCCESS);
8288  }
8289 void error_exit ()
8290  {
8291    lock (getpid(), LERROR, LSET, "%d -- ERROR: COREDUMP: %s %s\n",getpid(), PROGRAM, VERSION, getpid());
8292    global_exit_signal=EXIT_FAILURE;
8293    myexit (EXIT_FAILURE);
8294  }
8295 void clean_exit ()
8296 {
8297   Tmpname *b;
8298   char *tmp;
8299   char *f;
8300   Tmpname *start;
8301   int debug;
8302   
8303   clean_exit_started=1;//prevent new locks 
8304   
8305   start=tmpname;
8306   //1-start killing all the children
8307   
8308   
8309   //3-update error lock if needed
8310   if (has_error_lock())//Update error lock
8311     {
8312       lock (getpid(), LERROR, LSET, "%d -- STACK: %d -> %d -- %s %s\n", getpid(), getppid(), getpid(), PROGRAM, VERSION);
8313       lock (getpid(), LERROR, LSET, "%d -- COM: %s\n",getpid(),in_cl );
8314       
8315       //
8316     }
8317   
8318   
8319   if (is_rootpid())
8320     {
8321       
8322       kill_child_pid(getpid());
8323       if (has_error_lock())
8324         {
8325           char *e=NULL;
8326           stack_msg (stderr);
8327           warning_msg (stderr);
8328           e=lock (getpid(), LERROR, LREAD, NULL);
8329           
8330           
8331                           
8332           //explicit the most common error messages
8333           if ( strstr (e, "EMAIL"))email_msg (stderr);
8334           if ( strstr (e, "INTERNET"))proxy_msg (stderr);
8335           if ( strstr (e, "PG"))   install_msg(stderr);
8336           if ( strstr (e, "COREDUMP"))
8337             {
8338               error_msg (stderr);
8339               dump_error_file();
8340             }
8341           print_exit_failure_message ();
8342           vfree (e);
8343         }
8344       else if ( has_warning_lock())
8345         {
8346           warning_msg (stderr);
8347         }
8348       else
8349         print_exit_success_message();
8350       
8351       if ( (f=get_string_variable ("dump")))
8352         {
8353           dump_tcoffee (f, "standard dump");
8354           //unset_string_variable ("dump");
8355           //unset_string_variable ("dump_output_file");
8356           //display_output_filename (stdout, "DUMP", "DUMP_4_TCOFFEE",f, CHECK);
8357         }
8358
8359       
8360       lock (getpid(), LLOCK, LRELEASE, "");
8361       lock (getpid(), LWARNING, LRELEASE, "");
8362       lock (getpid(), LERROR, LRELEASE, "");
8363     }
8364
8365   
8366   
8367   
8368   add_method_output2method_log (NULL, NULL, NULL, NULL, decode_name (NULL, CODELIST));
8369   
8370   //Remove all temporary files
8371   debug=(atoigetenv ("DEBUG_TMP_FILE"));
8372
8373   
8374   
8375   while ( start)
8376     {
8377       if (!debug)
8378         {
8379           
8380           if (isdir(start->name))rrmdir (start->name);
8381           else 
8382             {
8383               char test[1000];
8384               vremove (start->name);
8385               if (start->name)sprintf (test, "%s.dnd", start->name);vremove (test);
8386               if (start->name)sprintf (test, "%s.html",start->name);vremove (test);
8387             }
8388         }
8389       else
8390         {
8391           if (isdir(start->name))
8392             {fprintf ( stderr, "DEBUG_TMP_FILE SET : Dir  %s not removed (%d)\n", start->name, getpid());}
8393           else
8394             {fprintf ( stderr, "DEBUG_TMP_FILE SET : File %s not removed (%d)\n", start->name, getpid());}
8395         }
8396       b=start;
8397       start=start->next;
8398       //vfree(b->name);vfree(b);
8399     }
8400   if (!debug && is_rootpid())my_rmdir (get_tmp_4_tcoffee());
8401   
8402   
8403   //Remove the lock 
8404   //lock (getpid(), LLOCK, LRELEASE,NULL); Now keep the lock unless it is a parent process
8405   
8406   //UNIQUE TERMINATION FOR EVERYBODY!!!!!!
8407   return;
8408 }
8409
8410     
8411 int cputenv4path (char *p)
8412 {
8413   if (!p)return 0;
8414   else if (isdir4path (p))
8415     {
8416       cputenv ("PATH=%s:%s", p, getenv("PATH"));
8417       return 1;
8418     }
8419   else
8420     {
8421       return 0;
8422     }
8423 }
8424       
8425
8426 int string_putenv ( char *s)
8427 {
8428   //extract from command line all the occurences -setenv val1 val2 and sets environement
8429   
8430   char *p;
8431   int n;
8432   char *v1, *v2;
8433
8434   
8435   if (!s) return 0;
8436   v1=vcalloc ( strlen (s)+1, sizeof (char));
8437   v2=vcalloc ( strlen (s)+1, sizeof (char));
8438   
8439   p=s;
8440   n=0;
8441   while ( (p=strstr (p, "-setenv")))
8442     {
8443       if (sscanf (p, "-setenv %s %s", v1,v2)==2)
8444         {
8445           
8446           if (strm (v1, "PATH"))cputenv4path (v2);
8447           else cputenv ( "%s=%s", v1, v2);
8448         }
8449        p+=strlen ("-setenv");
8450        n++;
8451     }
8452   p=s;
8453   if ( (p=strstr (p, "-plugins")))
8454     {
8455       sscanf (p, "-plugins %s", v1);
8456       cputenv ("PROXY_4_TCOFFEE=%s",v1);
8457       cputenv4path (v1);
8458       
8459     }
8460   p=s;
8461   if ( (p=strstr (p, "-email")))
8462     {
8463       sscanf (p, "-email %s", v1);
8464       cputenv ("EMAIL_4_TCOFFEE=%s", v1);
8465     }
8466   p=s;
8467   if ( (p=strstr (p, "-proxy")))
8468     {
8469       sscanf (p, "-proxy %s", v1);
8470       cputenv ("PROXY_4_TCOFFEE=%s", v1);
8471     }
8472   
8473        
8474   
8475   vfree (v1); vfree (v2);
8476   return n;
8477 }
8478
8479 char* file_putenv (char *file)
8480 {
8481   //puts in environement all the variables conatinned in file
8482   //format VAR=value on each line
8483   
8484   char ***list;
8485   int n=0;
8486   
8487   
8488   if (!file || !file_exists(NULL,file)) return NULL;
8489   
8490   list=file2list (file, "\n=");
8491   fprintf ( stderr, "Import Environement Variables from %s\n", file);
8492   
8493   while (list[n])
8494     {
8495       if ( list[n][1][0]!='#')
8496         {
8497           if ( strm (list[n][1], "PATH"))
8498             {
8499               
8500               cputenv ( "PATH=%s:%s",list[n][2], getenv ("PATH")); 
8501               fprintf ( stderr, "\tPATH=%s:$PATH", list[n][2]);
8502             }
8503           else
8504             {
8505               
8506               cputenv("%s=%s", list[n][1],list[n][2]);
8507               fprintf ( stderr, "\t%s=%s",  list[n][1],list[n][2]);
8508             }
8509           n++;
8510         }
8511     }
8512   free_arrayN ((void ***)list, 3);
8513   return NULL;
8514  }
8515
8516 char * bachup_env (char *mode,char *f)
8517 {
8518   static char *file;
8519   static char *buf;
8520   if (!file)
8521     {
8522       file=vtmpnam (NULL);
8523       buf=vcalloc ( 10000, sizeof (char));
8524     }
8525   
8526   if (!f)f=file;
8527   if (strm (mode, "DUMP"))
8528     {
8529       printf_system_direct ("/usr/bin/env > %s", f);
8530       return EXIT_SUCCESS;
8531     }
8532   else if ( strm (mode,"RESTAURE") && file_exists (NULL,f))
8533     {
8534       file_putenv (f);
8535       return EXIT_SUCCESS;
8536     }
8537   return NULL;
8538 }
8539   
8540  
8541 /******************************COPYRIGHT NOTICE*******************************/
8542 /*© Centro de Regulacio Genomica */
8543 /*and */
8544 /*Cedric Notredame */
8545 /*Fri Feb 18 08:27:45 CET 2011 - Revision 596. */
8546 /*All rights reserved.*/
8547 /*This file is part of T-COFFEE.*/
8548 /**/
8549 /*    T-COFFEE is free software; you can redistribute it and/or modify*/
8550 /*    it under the terms of the GNU General Public License as published by*/
8551 /*    the Free Software Foundation; either version 2 of the License, or*/
8552 /*    (at your option) any later version.*/
8553 /**/
8554 /*    T-COFFEE is distributed in the hope that it will be useful,*/
8555 /*    but WITHOUT ANY WARRANTY; without even the implied warranty of*/
8556 /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the*/
8557 /*    GNU General Public License for more details.*/
8558 /**/
8559 /*    You should have received a copy of the GNU General Public License*/
8560 /*    along with Foobar; if not, write to the Free Software*/
8561 /*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/
8562 /*...............................................                                                                                      |*/
8563 /*  If you need some more information*/
8564 /*  cedric.notredame@europe.com*/
8565 /*...............................................                                                                                                                                     |*/
8566 /**/
8567 /**/
8568 /*      */
8569 /******************************COPYRIGHT NOTICE*******************************/