Minor changes
[jabaws.git] / binaries / src / iupred / gjutil.c
1
2 /****************************************************************************
3
4 gjutil.c:  Various utility routines - error checking malloc and
5 free, string functions etc...
6
7 Copyright:  Geoffrey J. Barton  (1992, 1993, 1995, 1997)
8 email: geoff@ebi.ac.uk
9
10 This software is made available for educational and non-commercial research 
11 purposes.
12
13 For commercial use, a commercial licence is required - contact the author
14 at the above address for details.
15
16
17 ******************************************************************************/
18 #include <stdio.h>
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <ctype.h>
23 #include <errno.h>
24 #include <time.h>
25
26 #include <gjutil.h>
27
28 /* define pointers for standard streams to allow redefinition to files */
29
30 FILE *std_err;
31 FILE *std_in;
32 FILE *std_out;
33
34 /* clock externs */
35 clock_t start_time, end_time,initial_time,final_time;
36
37 void *GJmalloc(size_t size)
38 /* malloc with simple error check */
39 /* G. J. Barton 1992 */
40 {
41         void *ptr;
42         ptr = (void *) malloc(size);
43         if(ptr == NULL){
44                 GJerror("malloc error");
45                 exit(0);
46         }
47         return ptr;
48 }
49
50 void *GJrealloc(void *ptr,size_t size)
51 /* realloc with error check */
52 /* G. J. Barton 1992 */
53 {
54         ptr = (void *) realloc(ptr,size);
55         if(ptr == NULL){
56                 GJerror("realloc error");
57                 exit(0);
58         }
59         return ptr;
60 }
61 void *GJmallocNQ(size_t size)
62 /* as for GJmalloc, but returns NULL on error*/
63 /* G. J. Barton 1992 */
64 {
65         void *ptr;
66         ptr = (void *) malloc(size);
67         if(ptr == NULL){
68                 GJerror("malloc error");
69                 return NULL;
70         }
71         return ptr;
72 }
73
74 void *GJreallocNQ(void *ptr,size_t size)
75 /* as for GJrealloc with error check but returns NULL on error*/
76 /* G. J. Barton 1992 */
77 {
78         ptr = (void *) realloc(ptr,size);
79         if(ptr == NULL){
80                 GJerror("realloc error");
81                 return NULL;
82         }
83         return ptr;
84 }
85 void GJfree(void *ptr)
86 /* free with error check */
87 /* G. J. Barton 1992 */
88 {
89         if(ptr == NULL){
90                 GJerror("Attempt to free NULL pointer");
91                 exit(0);
92         }
93         free(ptr);
94 }
95
96 void GJerror(const char *prefix)
97 /* writes error message contained in prefix and contents of errno
98    to std_err.
99 */
100 /* G. J. Barton 1992 */
101 {
102         if(prefix != NULL){
103                 if(*prefix != '\0'){
104                         fprintf(std_err,"%s: ",prefix);
105                 }
106         }
107         fprintf(std_err,"%s\n",strerror(errno));
108 }
109
110 /*
111 error:   calls GJerror 
112 */
113 void error(const char *str,int flag)
114 {
115     GJerror(str);
116     if(flag)exit(0);
117 }
118
119
120 char *GJstoupper(const char *s)
121 /* return a copy of s in upper case */
122 /* G. J. Barton 1992 */
123 {
124         char *temp;
125         int i;
126         temp = GJstrdup(s);
127         i=0;
128         while(temp[i] != '\0'){
129                 temp[i] = toupper(temp[i]);
130                 ++i;
131         }
132         return temp;
133 }
134 char *GJstolower(const char *s)
135 /* return a copy of s in lower case */
136 /* G. J. Barton 1992 */
137 {
138         char *temp;
139         int i;
140         temp = GJstrdup(s);
141         i=0;
142         while(temp[i] != '\0'){
143                 temp[i] = tolower(temp[i]);
144                 ++i;
145         }
146         return temp;
147 }
148 char *GJstoup(char *s)
149 /* return s in upper case */
150 /* G. J. Barton 1992 */
151 {
152         int i;
153         i=0;
154         while(s[i] != '\0'){
155                 s[i] = toupper(s[i]);
156                 ++i;
157         }
158         return s;
159 }
160 char *GJstolo(char *s)
161 /* return s in lower case */
162 /* G. J. Barton 1992 */
163 {
164         int i;
165         i=0;
166         while(s[i] != '\0'){
167                 s[i] = tolower(s[i]);
168                 ++i;
169         }
170         return s;
171 }  
172
173 char *GJstrdup(const char *s)
174 /* returns a pointer to a copy of string s */
175 /* G. J. Barton 1992 */
176
177 {
178         char *temp;
179         temp = (char *) GJmalloc(sizeof(char) * (strlen(s)+1));
180         temp = strcpy(temp,s);
181         return temp;
182 }
183
184 char *GJstrrename(char *old,const char *new)
185 /* takes old which is a pointer to a string, then replaces the contents
186    of the string with new, reallocating to the correct size
187 */ 
188 {
189   int nlen;
190   nlen = strlen(new);
191   old = (char *) GJrealloc(old,sizeof(char) * (nlen + 1));
192   old = strcpy(old,new);
193   return old;
194 }
195   
196
197
198 FILE *GJfopen(const char *fname,const char *type,int action)
199 /* a file open function with error checking.  The third argument
200 is set to 0 if we want a failed open to return, or 1 if we
201 want a failed open to exit the program.
202 */
203 /* G. J. Barton 1992 */
204 /* modified July 1995 - error message only printed if action is 1 */
205 {
206         FILE *ret_val;
207         ret_val = fopen(fname,type);
208         if(ret_val == NULL){
209           /*      GJerror(strcat("Cannot Open File: ",fname));*/
210                 if(action == 1){
211                   GJerror(strcat("Cannot Open File: ",fname));
212                   exit(1);
213                 }
214         }
215         return ret_val;
216 }
217
218 int GJfclose(FILE *fp,int action)
219 /* a file close function with error checking.  The second argument
220 is set to 0 if we want a failed close to return, or 1 if we
221 want a failed close to exit the program.
222 */
223 /* G. J. Barton 1992 */
224 {
225         int ret_val;
226         ret_val = fclose(fp);
227         if(ret_val != 0){
228                 if(action == 1){
229                         GJerror("Error closing File");
230                         exit(1);
231                 }
232         }
233         return ret_val;
234 }
235
236
237 GJFILE *GJfilemake(const char *name,const char *type,int action)
238 /* If action = 1 then 
239 Tries to open the file with the given name.  If successful returns 
240 a pointer to a struct file structure with the name and filehandle.  If
241 the open fails, or action= 0 then returns a struct file structure 
242 with the name and a NULL filehandle */
243 /* G. J. Barton 1995 */
244 {
245         GJFILE *ret_val;
246         ret_val = (GJFILE *) GJmalloc(sizeof(GJFILE));
247         ret_val->name = GJstrdup(name);
248         if(action == 1) {
249           ret_val->handle = GJfopen(ret_val->name,type,0);
250         }else if(action == 0){
251           ret_val->handle = NULL;
252         }
253         return ret_val;
254 }
255
256 GJFILE *GJfilerename(GJFILE *ret_val, const char *name)
257 /* When passed the fval structure - renames the name part of the
258 file structure to name, if the handle is non null it tries to close 
259 the file, then sets the file handle to NULL. */
260 /* G. J. Barton 1995 */
261 {
262         if(ret_val->name != NULL) {
263           GJfree(ret_val->name);
264           ret_val->name = GJstrdup(name);
265         }
266         if(ret_val->handle != NULL) {
267           GJfclose(ret_val->handle,0);
268           ret_val->handle = NULL;
269         }
270         return ret_val;
271 }
272
273 GJFILE *GJfileclose(GJFILE *ret_val,int action)
274 /* Closes a file named in the  struct file structure returns the struct
275  file structure */
276
277 /* G. J. Barton July 1995 */
278 {
279         STD_FILES;
280
281         if(GJfclose(ret_val->handle,0) == 0){
282           return ret_val;
283         }else {
284           if(action == 1){
285             GJerror("Error closing File");
286             fprintf(std_err,"%s\n",ret_val->name);
287             exit(-1);
288           }
289         }
290         return ret_val;  
291 }
292
293 GJFILE *GJfileopen(GJFILE *ret_val,const char *type,int action)
294 /* Opens a file named in the  struct file structure */
295
296 /* G. J. Barton October 1995 */
297 {
298         STD_FILES;
299
300         ret_val->handle = GJfopen(ret_val->name,type,0);
301         if(ret_val->handle == NULL){
302                 if(action == 1){
303                         GJerror("Error opening File");
304                         fprintf(std_err,"%s\n",ret_val->name);
305                         exit(-1);
306                 }
307         }
308         return ret_val;  
309 }
310
311 GJFILE *GJfileclean(GJFILE *ret_val,int action)
312 /*  Closes the file then sets the file pointer to NULL, then 
313     frees the filename string */
314
315 /* G. J. Barton July 1995 */
316 {
317   if(GJfclose(ret_val->handle,0) == 0) {
318     ret_val->handle = NULL;
319     GJfree(ret_val->name);
320     return ret_val;
321   }else {
322     if(action == 1){
323       GJerror("Error closing File");
324       fprintf(std_err,"%s\n",ret_val->name);
325       exit(-1);
326     }
327   }
328   return ret_val;
329 }
330
331 void GJinitfile(void)
332 /* just set the standard streams */
333 {
334         std_err = stderr;
335         std_in = stdin;
336         std_out = stdout;
337 }
338
339 char *GJfnonnull(char *string)
340 /* return pointer to first non null character in the string */
341 /* this could cause problems if the string is not null terminated */
342 {
343         while(*string != '\0'){
344                 ++string;
345         }
346         return ++string;
347 }
348
349 char *GJstrappend(char *string1, char *string2)
350 /* appends string2 to the end of string2.  Any newline characters are removed
351 from string1, then the first character of string2 overwrites the null at the
352 end of string1.
353 string1 and string2 must have been allocated with malloc.
354 */
355 /* G. J. Barton July 1992 */
356 {
357         char *ret_val;
358         ret_val = GJremovechar(string1,'\n');
359         ret_val = (char *) GJrealloc(ret_val,
360                            sizeof(char) * (strlen(ret_val) + strlen(string2) + 1));
361         ret_val = strcat(ret_val,string2);
362         return ret_val;
363 }
364
365 char *GJremovechar(char *string,char c)
366 /* removes all instances of character c from string
367    returns a pointer to the reduced, null terminated string
368    11/8/1996:  couple of bugs found in this routine.
369    the length of the string returned was too short by 2 bytes.
370    This is a dodgy routine since string is freed.
371 */
372 /* G. J. Barton (July 1992) */
373 {
374         char *temp;
375         int j,i,nchar;
376         nchar = 0;
377         i=0;
378         while(string[i] != '\0'){
379                 if(string[i] == c){
380                         ++nchar;
381                 }
382                 ++i;
383         }
384         if(nchar == 0){
385                  return string;
386         }else{
387                 temp = (char *) GJmalloc(sizeof(char) * (strlen(string)-nchar + 1));
388                 j=0;
389                 i=0;
390                 while(string[i] != '\0'){
391                         if(string[i] != c){
392                                 temp[j] = string[i];
393                                 ++j;
394                         }
395                         ++i;
396                 }
397                 temp[j] = '\0';
398                 GJfree(string);
399                 return temp;
400         }
401 }
402
403 char *GJremovechar2(char *string,char c)
404 /* removes all instances of character c from string
405    returns a pointer to the reduced, null terminated string
406 */
407 /* G. J. Barton (July 1992) */
408 {
409         char *temp;
410         int i,k,len;
411         k=0;
412         len=strlen(string);
413         temp = (char *) GJmalloc(sizeof(char) * (len+1));
414         for(i=0;i<(len+1);++i){
415           if(string[i] != c){
416             temp[k] = string[i];
417             ++k;
418           }
419         }
420         for(i=0;i<(strlen(temp)+1);++i){
421           string[i] = temp[i];
422         }
423         GJfree(temp);
424         return string;
425 }
426
427
428 char *GJsubchar(char *string,char c2,char c1)
429 /* substitutes c1 for c2 in string
430 */
431 /* G. J. Barton (July 1992) */
432 {
433         int i;
434
435         i=0;
436         while(string[i] != '\0'){
437                 if(string[i] == c1){
438                     string[i] = c2;
439                 }
440                 ++i;
441         }
442         return string;
443 }
444
445 /* create a string and if fchar != NULL fill with characters  */
446 /* always set the len-1 character to '\0' */
447
448 char *GJstrcreate(size_t len,char *fchar)
449 {
450         char *ret_val;
451         ret_val = (char *) GJmalloc(sizeof(char) * len);
452         --len;
453         ret_val[len] = '\0';
454         if(fchar != NULL){
455                 while(len > -1){
456                         ret_val[len] = *fchar;
457                         --len;
458                 }
459         }
460         return ret_val;
461 }
462
463 /* searches for string s2 in string s1 and returns pointer to first instance
464 of s2 in s1 or NULL if no instance found.  s1 and s2 must be null terminated
465 */              
466 char *GJstrlocate(char *s1, char *s2)
467 {
468     int i=0;
469     int j=0;
470     int k;
471     if(strlen(s1) == 0 || strlen(s2) == 0) return NULL;
472     while(i < strlen(s1)){
473         j=0;
474         k=i;
475         while(j < strlen(s2) && s1[k] == s2[j]){
476                 ++k;
477                 ++j;
478         }
479         if(j == strlen(s2)) return &s1[i];
480         ++i;
481     }
482     return NULL;
483 }
484 #include <stdlib.h>
485 #include <string.h>
486
487
488 /* GJstrtok()
489
490 This version of strtok places the work pointer at the location of the first 
491 character in the next token, rather than just after the last character of the 
492 current token.  This is useful for extracting quoted strings 
493 */
494
495 char *GJstrtok(char *input_string,const char *token_list)
496 {
497   static char *work;
498   char *return_ptr;
499
500   if(input_string != NULL){
501     /* first call */
502     work =  input_string;
503   }
504
505   /* search for next non-token character */
506   while(strchr(token_list,*work)!=NULL){
507     ++work;
508   }
509
510   if(*work == '\0'){
511     /* if we've reached the end of string, then return NULL */
512     return NULL;
513   }else{
514     return_ptr = (char *) work;
515     while(strchr(token_list,*work) == NULL){
516       if(*work == '\0'){
517         /* end of the string */
518         return return_ptr;
519       }else{
520         ++work;
521       }
522     }
523     *work = '\0';
524     ++work;
525     /* now increment work until we find the next non-delimiter character */
526     while(strchr(token_list,*work) != NULL){
527       if(*work == '\0'){
528         break;
529       }else{
530         ++work;
531       }
532     }
533     return return_ptr;
534   }
535 }
536 /**************************************************************************
537 return a pointer to space for a rectangular unsigned character array
538 Version 2.0  ANSI and uses GJmallocNQ
539 --------------------------------------------------------------------------*/
540
541 unsigned char **uchararr(int i,int j)
542 {
543     unsigned char **temp;
544     int k, rowsiz;
545
546     temp = (unsigned char **) GJmallocNQ(sizeof(unsigned char *) * i);
547     if(temp == NULL) return NULL;
548
549     rowsiz = sizeof(unsigned char) * j;
550
551     for (k = 0; k < i; ++k){
552         temp[k] =  (unsigned char *) GJmallocNQ(rowsiz);
553         if(temp[k] == NULL) return NULL;
554     }
555     return temp;
556 }
557
558 /**************************************************************************
559 free up space pointed to by rectangular unsigned character array
560 -------------------------------------------------------------------------*/
561 void ucharfree(unsigned char **array,int i)
562
563 {
564     int k;
565
566     for (k = 0; k < i; ++k){
567         GJfree((char *) array[k]);
568     }
569     GJfree((char *) array);
570
571 }
572 /**************************************************************************
573 return a pointer to space for a rectangular double array
574 --------------------------------------------------------------------------*/
575
576 double **GJdarr(int i,int j)
577 {
578     double **temp;
579     int k, rowsiz;
580
581     temp = (double **) GJmallocNQ(sizeof(double *) * i);
582     if(temp == NULL) return NULL;
583
584     rowsiz = sizeof(double) * j;
585
586     for (k = 0; k < i; ++k){
587         temp[k] =  (double *) GJmallocNQ(rowsiz);
588         if(temp[k] == NULL) return NULL;
589     }
590     return temp;
591 }
592 void GJdarrfree(double **array,int i)
593
594 {
595     int k;
596
597     for (k = 0; k < i; ++k){
598         GJfree((char *) array[k]);
599     }
600     GJfree((char *) array);
601
602 }
603
604 /**************************************************************************
605 return a pointer to space for a rectangular signed character array
606 Version 2.0  ANSI
607 --------------------------------------------------------------------------*/
608 signed char **chararr(int i,int j)
609
610 {
611     signed char **temp;
612     int k, rowsiz;
613
614     temp = (signed char **) GJmallocNQ(sizeof(char *) * i);
615
616     if(temp == NULL) return NULL;
617
618     rowsiz = sizeof(char) * j;
619
620     for (k = 0; k < i; ++k){
621         temp[k] =  (signed char *) GJmallocNQ(rowsiz);
622         if(temp[k] == NULL) return NULL;
623     }
624     return temp;
625 }
626
627
628 /* mcheck - check a call to malloc - if the call has failed, print the
629 error message and exit the program */
630 /* ANSI Version - also uses GJerror routine and ptr is declared void*/
631
632 void mcheck(void *ptr,char *msg)
633
634 {
635     if(ptr == NULL){
636         GJerror("malloc/realloc error");
637         exit(0);
638     }
639 }
640
641 /* set a string to blanks and add terminating nul */
642 char *GJstrblank(char *string,int len)
643
644 {
645   --len;
646   string[len] = '\0';
647   --len;
648   while(len > -1){
649     string[len] = ' ';
650     --len;
651   }
652   return string;
653 }
654
655 /* Initialise an unsigned char array */  
656 void GJUCinit(unsigned char **array,int i,int j,unsigned char val)
657 {
658   int k,l;
659
660   for(k=0;k<i;++k){
661     for(l=0;l<j;++l){
662       array[k][l] = val;
663     }
664   }
665 }
666 /*Initialise a signed char array */
667
668 void GJCinit(signed char **array,int i,int j,char val)
669
670 {
671   int k,l;
672
673   for(k=0;k<i;++k){
674     for(l=0;l<j;++l){
675       array[k][l] = val;
676     }
677   }
678 }
679
680 /* Initialise an integer vector  */  
681 void GJIinit(int *array,int i,int val)
682 {
683   int k;
684
685   for(k=0;k<i;++k){
686       array[k] = val;
687   }
688 }
689
690 /******************************************************************
691 GJcat:  concatenate N NULL terminated strings into a single string.
692 The source strings are not altered
693 Author: G. J. Barton (Feb 1993)
694 ------------------------------------------------------------------*/
695 char *GJcat(int N,...)
696 {
697         va_list parminfo;
698         int i,j,k;
699         char **values;  /*input strings */
700         int *value_len; /*lengths of input strings */
701         int ret_len;    /*length of returned string */
702         char *ret_val;  /*returned string */
703
704         ret_len = 0;
705         values = (char **) GJmalloc(sizeof(char *) * N);
706         value_len = (int *) GJmalloc(sizeof(int *) * N);
707
708         va_start(parminfo,N);
709
710         /* Get pointers and lengths for the N arguments */
711         for(i=0;i<N;++i){
712                 values[i] = va_arg(parminfo,char *);
713                 value_len[i] = strlen(values[i]);
714                 ret_len += value_len[i];
715         }
716         
717         ret_val = (char *) GJmalloc(sizeof(char) * (ret_len+1));
718
719         /* Transfer input strings to output string */
720         k=0;
721         for(i=0;i<N;++i){
722                 for(j=0;j<value_len[i];++j){
723                         ret_val[k] = values[i][j];
724                         ++k;
725                 }
726         }
727         ret_val[k] = '\0';
728         GJfree(values);
729         GJfree(value_len);
730
731         va_end(parminfo);
732
733         return ret_val;
734 }
735
736 /************************************************************************
737
738 GJGetToken:
739
740 The aim of this routine is to emulate the strtok() function, but reading
741 from a file.  The functionality may differ slightly...
742
743 Characters are read from the file until a character that is found in
744 delim is encountered.  When this occurs, token is returned.  If the
745 file consists entirely of delimiters, then token is freed
746 and NULL is returned.  Similarly, if end of file is encountered.
747
748 ------------------------------------------------------------------------*/
749
750
751 char *GJGetToken(FILE *in, const char *delim)
752
753 {
754         int i;
755         int c;
756         char *token;
757
758         i=0;
759
760         token = GJmalloc(sizeof(char));
761         
762         while((c=fgetc(in)) != EOF){
763                 if(strchr(delim,c) == NULL){
764                         /* not a delimiter */
765                         token[i++] = c;
766                         token = GJrealloc(token,sizeof(char) * (i+1));
767                 }else if(i>0){
768                         token[i] = '\0';
769                         return token;
770                 }
771         }
772 /*      GJerror("End of File Encountered");*/
773         GJfree(token);
774         return NULL;
775 }
776
777 struct tokens *GJgettokens(const char *delims, char *buff)
778 /* This splits a buffer into tokens at each position defined by delims.*/
779 /* The structure returned contains the number of tokens and the */
780 /* tokens themselves as a char ** array */
781 {
782   char *token;
783   struct tokens *tok;
784
785   token = strtok(buff,delims);
786   if(token == NULL) return NULL;
787
788   tok = (struct tokens *) GJmalloc(sizeof(struct tokens));
789   tok->ntok = 0;
790   tok->tok = (char **) GJmalloc(sizeof(char *));
791   tok->tok[0] = GJstrdup(token);
792   ++tok->ntok;
793   while((token = strtok(NULL,delims)) != NULL) {
794       tok->tok = (char **) GJrealloc(tok->tok,sizeof(char *) * (tok->ntok+1));
795       tok->tok[tok->ntok] = GJstrdup(token);
796       ++tok->ntok;
797   }
798   
799   return tok;
800 }
801
802 void GJfreetokens(struct tokens *tok)
803 /* frees a tokens structure */
804
805 {
806   int i;
807   for(i=0;i<tok->ntok;++i) {
808     GJfree(tok->tok[i]);
809   }
810   GJfree(tok->tok);
811   GJfree(tok);
812   tok = NULL;   /* add this to avoid odd pointer 27/6/1997*/
813 }
814
815 char * GJtoktostr(struct tokens *tok,char delim,int s, int e)
816
817 /* 
818    returns a string with the tokens between s and e inclusive written to 
819    it separated by delim 
820    the tok structure is unmodified.
821 */
822
823 {
824   int n, i, j,k;
825   char *ret_val;
826
827   n = 0;
828
829
830   if(s < 0 || s >= tok->ntok) s = 0;
831   if(e < 0 || e >= tok->ntok) e = tok->ntok - 1;
832
833   for(i=s;i<=e;++i){
834     n += strlen(tok->tok[i]);
835     ++n;
836   }
837
838   ret_val = (char *) GJmalloc(sizeof(char) * n);
839   j = 0;
840   for(i=s;i<=e;++i){
841     for(k=0;k<strlen(tok->tok[i]);++k){
842       ret_val[j] = tok->tok[i][k];
843       ++j;
844     }
845     ret_val[j++] = delim;
846   }
847   ret_val[n-1] = '\0';
848   return ret_val;
849 }
850
851
852 void GJindexx(int *arrin,int n,int *indx)
853   /* indexed heap sort - adapted from the NR routine indexx.
854      inarr is an integer array to sort,
855      indx is the returned index array
856   */
857 {
858         int l,j,ir,indxt,i;
859 /* SMJS
860         float q;
861 */
862         int q;
863
864         for (j=1;j<=n;j++) indx[j]=j;
865         l=(n >> 1) + 1;
866         ir=n;
867         for (;;) {
868                 if (l > 1)
869                         q=arrin[(indxt=indx[--l])];
870                 else {
871                         q=arrin[(indxt=indx[ir])];
872                         indx[ir]=indx[1];
873                         if (--ir == 1) {
874                                 indx[1]=indxt;
875                                 return;
876                         }
877                 }
878                 i=l;
879                 j=l << 1;
880                 while (j <= ir) {
881                         if (j < ir && arrin[indx[j]] < arrin[indx[j+1]]) j++;
882                         if (q < arrin[indx[j]]) {
883                                 indx[i]=indx[j];
884                                 j += (i=j);
885                         }
886                         else j=ir+1;
887                 }
888                 indx[i]=indxt;
889         }
890 }
891
892 void GJindexxD(double *arrin,int n,int *indx)
893   /* indexed heap sort - adapted from the NR routine indexx.
894      arrin is a double array to sort,
895      indx is the returned index array
896   */
897 {
898         int l,j,ir,indxt,i;
899 /*
900         float q;
901 */ 
902         double q;
903
904         for (j=1;j<=n;j++) indx[j]=j;
905         l=(n >> 1) + 1;
906         ir=n;
907         for (;;) {
908                 if (l > 1)
909                         q=arrin[(indxt=indx[--l])];
910                 else {
911                         q=arrin[(indxt=indx[ir])];
912                         indx[ir]=indx[1];
913                         if (--ir == 1) {
914                                 indx[1]=indxt;
915                                 return;
916                         }
917                 }
918                 i=l;
919                 j=l << 1;
920                 while (j <= ir) {
921                         if (j < ir && arrin[indx[j]] < arrin[indx[j+1]]) j++;
922                         if (q < arrin[indx[j]]) {
923                                 indx[i]=indx[j];
924                                 j += (i=j);
925                         }
926                         else j=ir+1;
927                 }
928                 indx[i]=indxt;
929         }
930 }
931
932 void GJindexxS1(char **arrin,int n,int *indx)
933      /*indexed sort of a character array - this uses qsort rather than the 
934        heapsort in GJindexxS.  indx runs from 0..(n-1) rather than 1..n as in 
935        GJindexxS.
936      */
937 {
938   int i;
939   CWORK  *ret;
940
941   ret = (CWORK *) GJmalloc(sizeof(CWORK) * n);
942
943   for(i=0;i<n;++i){
944     ret[i].val = arrin[i];
945     ret[i].i = i;
946   }
947   qsort(ret,  n, sizeof(CWORK), Sworkcomp);
948
949   for(i=0;i<n;++i){
950     indx[i] = ret[i].i;
951   }
952   GJfree(ret);
953 }
954
955 int Sworkcomp(const void *left, const void *right)
956 {
957   CWORK *a = (CWORK *) left;
958   CWORK *b = (CWORK *) right;
959
960   return strcmp(a->val,b->val);
961 }
962
963   
964 void GJindexxS(char **arrin,int n,int *indx)
965   /* indexed heap sort - adapted from the NR routine indexx.
966      arrin is a character string array to sort
967      indx is the returned index array
968   */
969 {
970         int l,j,ir,indxt,i;
971 /*
972         float q;
973 */
974         char *q;
975
976         for (j=1;j<=n;j++) indx[j]=j;
977         l=(n >> 1) + 1;
978         ir=n;
979         for (;;) {
980                 if (l > 1)
981                         q=arrin[(indxt=indx[--l])];
982                 else {
983                         q=arrin[(indxt=indx[ir])];
984                         indx[ir]=indx[1];
985                         if (--ir == 1) {
986                                 indx[1]=indxt;
987                                 return;
988                         }
989                 }
990                 i=l;
991                 j=l << 1;
992                 while (j <= ir) {
993                         if (j < ir && (strcmp(arrin[indx[j]],arrin[indx[j+1]]) < 0)  ) j++;
994                         if (strcmp(q,arrin[indx[j]])<0) {
995                                 indx[i]=indx[j];
996                                 j += (i=j);
997                         }
998                         else j=ir+1;
999                 }
1000                 indx[i]=indxt;
1001         }
1002 }
1003  
1004
1005
1006 void GJpline(FILE *fp,char c,int n)
1007 /* print n copies of c to fp terminated by newline */
1008 {
1009   int i;
1010   for(i=0;i<n;++i){
1011     fprintf(fp,"%c",c);
1012   }
1013   fprintf(fp,"\n");
1014 }
1015
1016 char *GJlocaltime(void)
1017 {
1018   time_t t;
1019   char *ret_val;
1020   t = time(NULL);
1021   ret_val=asctime(localtime(&t));
1022   return ret_val;
1023 }
1024
1025 void GJpstring(FILE *fp,char *s,int n)
1026 /* print a string so that it occupies n characters */
1027 /* strings are left-justified and either truncated or padded on output */
1028 {
1029   int i,l;
1030
1031
1032   l = strlen(s);
1033
1034   if(l > n){
1035     for(i=0;i<n;++i){
1036       fprintf(fp,"%c",s[i]);
1037     }
1038   }else{
1039     for(i=0;i<l;++i){
1040       fprintf(fp,"%c",s[i]);
1041     }
1042     for(i=l;i<n;++i){
1043       fprintf(fp," ");
1044     }
1045   }
1046 }
1047
1048 /* return min and max of an integer vector */
1049 IRANGE *irange(int *ivec,int n)
1050 {
1051   int i;
1052   int imin,imax;
1053   IRANGE *ret_val;
1054
1055   imin = imax = ivec[0];
1056   
1057   for(i=1;i<n;++i){
1058     if(ivec[i] > imax) imax = ivec[i];
1059     if(ivec[i] < imin) imin = ivec[i];
1060   }
1061   
1062   ret_val = (IRANGE *) GJmalloc(sizeof(IRANGE));
1063   ret_val->min = imin;
1064   ret_val->max = imax;
1065
1066   return ret_val;
1067 }
1068
1069 #define BLIM 5
1070 int GJbsearchINXS(char **cod, int n, char *query)
1071
1072 /* binary search for query  in table cod.   If query is found, return index of query in cod.*/
1073 /* if it is   not found, return -1 */
1074
1075 {
1076         int r;          /* right limit */
1077         int l;          /* left limit */
1078         int cv;         /* centre value */
1079
1080         r = n-1;
1081         l = 0;
1082
1083         for(;;){
1084                 if((r-l) > BLIM){
1085                         cv = (r+l)/2;
1086                         if(strcmp(query,cod[cv]) == 0){
1087                                 return cv;
1088                         }else if(strcmp(query,cod[cv]) > 0){
1089                                 l = cv;
1090                         }else if(strcmp(query,cod[cv]) < 0){
1091                                 r = cv;
1092                         }
1093                 }else{
1094                         for(cv=l;cv<(r+1);++cv){
1095                                 if(strcmp(query,cod[cv]) == 0){                     
1096                                         return cv;
1097                                 }
1098                         }
1099                         return (int) -1;
1100                 }
1101         }
1102 }
1103
1104 int GJbsearchINX_IS(char **cod, int *inx, int n, char *query)
1105
1106 /* binary search for query  in table cod.  inx is the index into the table that specifies
1107    the sorted order of the table cod.
1108    If query is found, return index of query in inx that can be used to recover the value of 
1109    cod .*/
1110 /* if it is   not found, return -1 */
1111
1112 {
1113         int r;          /* right limit */
1114         int l;          /* left limit */
1115         int cv;         /* centre value */
1116
1117         r = n-1;
1118         l = 0;
1119
1120         for(;;){
1121                 if((r-l) > BLIM){
1122                         cv = (r+l)/2;
1123                         if(strcmp(query,cod[inx[cv]]) == 0){
1124                                 return cv;
1125                         }else if(strcmp(query,cod[inx[cv]]) > 0){
1126                                 l = cv;
1127                         }else if(strcmp(query,cod[inx[cv]]) < 0){
1128                                 r = cv;
1129                         }
1130                 }else{
1131                         for(cv=l;cv<(r+1);++cv){
1132                                 if(strcmp(query,cod[inx[cv]]) == 0){                        
1133                                         return cv;
1134                                 }
1135                         }
1136                         return (int) -1;
1137                 }
1138         }
1139 }
1140
1141 /* 
1142
1143 $Id: gjutil.c,v 1.13 2002/08/09 12:30:31 geoff Exp $ 
1144
1145 $Log: gjutil.c,v $
1146 Revision 1.13  2002/08/09 12:30:31  geoff
1147 Experiment with different weighting schemes.
1148 Changes to build_profile to accommodate new schemes
1149 pwf 3  Complex clustering to get sequence weights at each position
1150 pwf 4  Dirichlet mixture alone
1151 pwf 5  Dirichlet mixture + psiblast windowing + blosum weights
1152 pwf 6  local blosum matrix calculation + HH sequence weights + blosum
1153
1154 Also add wander_check opton
1155 Also add option to turn off sw7 bug work around.
1156 Add option to suppress multiple alignment output
1157 Add gjnoc2 to distribution
1158
1159 Revision 1.12  2000/12/21 17:25:44  geoff
1160 Add the option to output the sequence fragments from the multiple alignment
1161 output option in fasta or pir format.  Unlike the block file output, these
1162 fragments contain the complete sequence between the start and end points, including
1163 any parts deleted in the alignment process.
1164 Add appropriate commands to scanps_alias.dat, getpars and getcmd.
1165
1166 Revision 1.11  2000/07/04 11:01:37  searle
1167 Changes for MMX
1168
1169 Revision 1.10  1999/11/17 21:06:47  geoff
1170 Add setup_caleb and other changes to swpp2 and so on.
1171
1172 Revision 1.9  1999/07/09 13:34:10  geoff
1173 modified these as a test
1174
1175 Revision 1.8  1998/08/11 15:38:50  geoff
1176 Modified the copyright notice to reflect the new
1177 ownership of this software.
1178
1179 Revision 1.7  1997/06/29 00:43:57  gjb
1180 Changes to add sysinfo calls and test of license reading routines
1181
1182 Revision 1.6  1997/06/27 16:42:41  gjb
1183 Add trlic.c test.lic and clean up gjutil.c
1184
1185 Revision 1.5  1997/06/27 07:17:31  gjb
1186 Added rlic.c linfo.h and
1187 changes to gjutil.c to give better support for
1188 token manipulation
1189
1190 Revision 1.4  1997/05/12 11:10:53  gjb
1191 Re-added gjutil.c and gjutil.h to repository
1192 after deleting them
1193
1194 Revision 1.2  1997/05/12 10:47:52  gjb
1195 Modified CVS header and log position
1196
1197 */
1198
1199
1200
1201