2 /****************************************************************************
4 gjutil.c: Various utility routines - error checking malloc and
5 free, string functions etc...
7 Copyright: Geoffrey J. Barton (1992, 1993, 1995, 1997)
10 This software is made available for educational and non-commercial research
13 For commercial use, a commercial licence is required - contact the author
14 at the above address for details.
17 ******************************************************************************/
28 /* define pointers for standard streams to allow redefinition to files */
35 clock_t start_time, end_time,initial_time,final_time;
37 void *GJmalloc(size_t size)
38 /* malloc with simple error check */
39 /* G. J. Barton 1992 */
42 ptr = (void *) malloc(size);
44 GJerror("malloc error");
50 void *GJrealloc(void *ptr,size_t size)
51 /* realloc with error check */
52 /* G. J. Barton 1992 */
54 ptr = (void *) realloc(ptr,size);
56 GJerror("realloc error");
61 void *GJmallocNQ(size_t size)
62 /* as for GJmalloc, but returns NULL on error*/
63 /* G. J. Barton 1992 */
66 ptr = (void *) malloc(size);
68 GJerror("malloc error");
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 */
78 ptr = (void *) realloc(ptr,size);
80 GJerror("realloc error");
85 void GJfree(void *ptr)
86 /* free with error check */
87 /* G. J. Barton 1992 */
90 GJerror("Attempt to free NULL pointer");
96 void GJerror(const char *prefix)
97 /* writes error message contained in prefix and contents of errno
100 /* G. J. Barton 1992 */
104 fprintf(std_err,"%s: ",prefix);
107 fprintf(std_err,"%s\n",strerror(errno));
113 void error(const char *str,int flag)
120 char *GJstoupper(const char *s)
121 /* return a copy of s in upper case */
122 /* G. J. Barton 1992 */
128 while(temp[i] != '\0'){
129 temp[i] = toupper(temp[i]);
134 char *GJstolower(const char *s)
135 /* return a copy of s in lower case */
136 /* G. J. Barton 1992 */
142 while(temp[i] != '\0'){
143 temp[i] = tolower(temp[i]);
148 char *GJstoup(char *s)
149 /* return s in upper case */
150 /* G. J. Barton 1992 */
155 s[i] = toupper(s[i]);
160 char *GJstolo(char *s)
161 /* return s in lower case */
162 /* G. J. Barton 1992 */
167 s[i] = tolower(s[i]);
173 char *GJstrdup(const char *s)
174 /* returns a pointer to a copy of string s */
175 /* G. J. Barton 1992 */
179 temp = (char *) GJmalloc(sizeof(char) * (strlen(s)+1));
180 temp = strcpy(temp,s);
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
191 old = (char *) GJrealloc(old,sizeof(char) * (nlen + 1));
192 old = strcpy(old,new);
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.
203 /* G. J. Barton 1992 */
204 /* modified July 1995 - error message only printed if action is 1 */
207 ret_val = fopen(fname,type);
209 /* GJerror(strcat("Cannot Open File: ",fname));*/
211 GJerror(strcat("Cannot Open File: ",fname));
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.
223 /* G. J. Barton 1992 */
226 ret_val = fclose(fp);
229 GJerror("Error closing File");
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 */
246 ret_val = (GJFILE *) GJmalloc(sizeof(GJFILE));
247 ret_val->name = GJstrdup(name);
249 ret_val->handle = GJfopen(ret_val->name,type,0);
250 }else if(action == 0){
251 ret_val->handle = NULL;
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 */
262 if(ret_val->name != NULL) {
263 GJfree(ret_val->name);
264 ret_val->name = GJstrdup(name);
266 if(ret_val->handle != NULL) {
267 GJfclose(ret_val->handle,0);
268 ret_val->handle = NULL;
273 GJFILE *GJfileclose(GJFILE *ret_val,int action)
274 /* Closes a file named in the struct file structure returns the struct
277 /* G. J. Barton July 1995 */
281 if(GJfclose(ret_val->handle,0) == 0){
285 GJerror("Error closing File");
286 fprintf(std_err,"%s\n",ret_val->name);
293 GJFILE *GJfileopen(GJFILE *ret_val,const char *type,int action)
294 /* Opens a file named in the struct file structure */
296 /* G. J. Barton October 1995 */
300 ret_val->handle = GJfopen(ret_val->name,type,0);
301 if(ret_val->handle == NULL){
303 GJerror("Error opening File");
304 fprintf(std_err,"%s\n",ret_val->name);
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 */
315 /* G. J. Barton July 1995 */
317 if(GJfclose(ret_val->handle,0) == 0) {
318 ret_val->handle = NULL;
319 GJfree(ret_val->name);
323 GJerror("Error closing File");
324 fprintf(std_err,"%s\n",ret_val->name);
331 void GJinitfile(void)
332 /* just set the standard streams */
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 */
343 while(*string != '\0'){
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
353 string1 and string2 must have been allocated with malloc.
355 /* G. J. Barton July 1992 */
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);
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.
372 /* G. J. Barton (July 1992) */
378 while(string[i] != '\0'){
387 temp = (char *) GJmalloc(sizeof(char) * (strlen(string)-nchar + 1));
390 while(string[i] != '\0'){
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
407 /* G. J. Barton (July 1992) */
413 temp = (char *) GJmalloc(sizeof(char) * (len+1));
414 for(i=0;i<(len+1);++i){
420 for(i=0;i<(strlen(temp)+1);++i){
428 char *GJsubchar(char *string,char c2,char c1)
429 /* substitutes c1 for c2 in string
431 /* G. J. Barton (July 1992) */
436 while(string[i] != '\0'){
445 /* create a string and if fchar != NULL fill with characters */
446 /* always set the len-1 character to '\0' */
448 char *GJstrcreate(size_t len,char *fchar)
451 ret_val = (char *) GJmalloc(sizeof(char) * len);
456 ret_val[len] = *fchar;
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
466 char *GJstrlocate(char *s1, char *s2)
471 if(strlen(s1) == 0 || strlen(s2) == 0) return NULL;
472 while(i < strlen(s1)){
475 while(j < strlen(s2) && s1[k] == s2[j]){
479 if(j == strlen(s2)) return &s1[i];
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
495 char *GJstrtok(char *input_string,const char *token_list)
500 if(input_string != NULL){
505 /* search for next non-token character */
506 while(strchr(token_list,*work)!=NULL){
511 /* if we've reached the end of string, then return NULL */
514 return_ptr = (char *) work;
515 while(strchr(token_list,*work) == NULL){
517 /* end of the string */
525 /* now increment work until we find the next non-delimiter character */
526 while(strchr(token_list,*work) != NULL){
536 /**************************************************************************
537 return a pointer to space for a rectangular unsigned character array
538 Version 2.0 ANSI and uses GJmallocNQ
539 --------------------------------------------------------------------------*/
541 unsigned char **uchararr(int i,int j)
543 unsigned char **temp;
546 temp = (unsigned char **) GJmallocNQ(sizeof(unsigned char *) * i);
547 if(temp == NULL) return NULL;
549 rowsiz = sizeof(unsigned char) * j;
551 for (k = 0; k < i; ++k){
552 temp[k] = (unsigned char *) GJmallocNQ(rowsiz);
553 if(temp[k] == NULL) return NULL;
558 /**************************************************************************
559 free up space pointed to by rectangular unsigned character array
560 -------------------------------------------------------------------------*/
561 void ucharfree(unsigned char **array,int i)
566 for (k = 0; k < i; ++k){
567 GJfree((char *) array[k]);
569 GJfree((char *) array);
572 /**************************************************************************
573 return a pointer to space for a rectangular double array
574 --------------------------------------------------------------------------*/
576 double **GJdarr(int i,int j)
581 temp = (double **) GJmallocNQ(sizeof(double *) * i);
582 if(temp == NULL) return NULL;
584 rowsiz = sizeof(double) * j;
586 for (k = 0; k < i; ++k){
587 temp[k] = (double *) GJmallocNQ(rowsiz);
588 if(temp[k] == NULL) return NULL;
592 void GJdarrfree(double **array,int i)
597 for (k = 0; k < i; ++k){
598 GJfree((char *) array[k]);
600 GJfree((char *) array);
604 /**************************************************************************
605 return a pointer to space for a rectangular signed character array
607 --------------------------------------------------------------------------*/
608 signed char **chararr(int i,int j)
614 temp = (signed char **) GJmallocNQ(sizeof(char *) * i);
616 if(temp == NULL) return NULL;
618 rowsiz = sizeof(char) * j;
620 for (k = 0; k < i; ++k){
621 temp[k] = (signed char *) GJmallocNQ(rowsiz);
622 if(temp[k] == NULL) return NULL;
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*/
632 void mcheck(void *ptr,char *msg)
636 GJerror("malloc/realloc error");
641 /* set a string to blanks and add terminating nul */
642 char *GJstrblank(char *string,int len)
655 /* Initialise an unsigned char array */
656 void GJUCinit(unsigned char **array,int i,int j,unsigned char val)
666 /*Initialise a signed char array */
668 void GJCinit(signed char **array,int i,int j,char val)
680 /* Initialise an integer vector */
681 void GJIinit(int *array,int i,int val)
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,...)
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 */
705 values = (char **) GJmalloc(sizeof(char *) * N);
706 value_len = (int *) GJmalloc(sizeof(int *) * N);
708 va_start(parminfo,N);
710 /* Get pointers and lengths for the N arguments */
712 values[i] = va_arg(parminfo,char *);
713 value_len[i] = strlen(values[i]);
714 ret_len += value_len[i];
717 ret_val = (char *) GJmalloc(sizeof(char) * (ret_len+1));
719 /* Transfer input strings to output string */
722 for(j=0;j<value_len[i];++j){
723 ret_val[k] = values[i][j];
736 /************************************************************************
740 The aim of this routine is to emulate the strtok() function, but reading
741 from a file. The functionality may differ slightly...
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.
748 ------------------------------------------------------------------------*/
751 char *GJGetToken(FILE *in, const char *delim)
760 token = GJmalloc(sizeof(char));
762 while((c=fgetc(in)) != EOF){
763 if(strchr(delim,c) == NULL){
764 /* not a delimiter */
766 token = GJrealloc(token,sizeof(char) * (i+1));
772 /* GJerror("End of File Encountered");*/
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 */
785 token = strtok(buff,delims);
786 if(token == NULL) return NULL;
788 tok = (struct tokens *) GJmalloc(sizeof(struct tokens));
790 tok->tok = (char **) GJmalloc(sizeof(char *));
791 tok->tok[0] = GJstrdup(token);
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);
802 void GJfreetokens(struct tokens *tok)
803 /* frees a tokens structure */
807 for(i=0;i<tok->ntok;++i) {
812 tok = NULL; /* add this to avoid odd pointer 27/6/1997*/
815 char * GJtoktostr(struct tokens *tok,char delim,int s, int e)
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.
830 if(s < 0 || s >= tok->ntok) s = 0;
831 if(e < 0 || e >= tok->ntok) e = tok->ntok - 1;
834 n += strlen(tok->tok[i]);
838 ret_val = (char *) GJmalloc(sizeof(char) * n);
841 for(k=0;k<strlen(tok->tok[i]);++k){
842 ret_val[j] = tok->tok[i][k];
845 ret_val[j++] = delim;
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
864 for (j=1;j<=n;j++) indx[j]=j;
869 q=arrin[(indxt=indx[--l])];
871 q=arrin[(indxt=indx[ir])];
881 if (j < ir && arrin[indx[j]] < arrin[indx[j+1]]) j++;
882 if (q < arrin[indx[j]]) {
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
904 for (j=1;j<=n;j++) indx[j]=j;
909 q=arrin[(indxt=indx[--l])];
911 q=arrin[(indxt=indx[ir])];
921 if (j < ir && arrin[indx[j]] < arrin[indx[j+1]]) j++;
922 if (q < arrin[indx[j]]) {
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
941 ret = (CWORK *) GJmalloc(sizeof(CWORK) * n);
944 ret[i].val = arrin[i];
947 qsort(ret, n, sizeof(CWORK), Sworkcomp);
955 int Sworkcomp(const void *left, const void *right)
957 CWORK *a = (CWORK *) left;
958 CWORK *b = (CWORK *) right;
960 return strcmp(a->val,b->val);
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
976 for (j=1;j<=n;j++) indx[j]=j;
981 q=arrin[(indxt=indx[--l])];
983 q=arrin[(indxt=indx[ir])];
993 if (j < ir && (strcmp(arrin[indx[j]],arrin[indx[j+1]]) < 0) ) j++;
994 if (strcmp(q,arrin[indx[j]])<0) {
1006 void GJpline(FILE *fp,char c,int n)
1007 /* print n copies of c to fp terminated by newline */
1016 char *GJlocaltime(void)
1021 ret_val=asctime(localtime(&t));
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 */
1036 fprintf(fp,"%c",s[i]);
1040 fprintf(fp,"%c",s[i]);
1048 /* return min and max of an integer vector */
1049 IRANGE *irange(int *ivec,int n)
1055 imin = imax = ivec[0];
1058 if(ivec[i] > imax) imax = ivec[i];
1059 if(ivec[i] < imin) imin = ivec[i];
1062 ret_val = (IRANGE *) GJmalloc(sizeof(IRANGE));
1063 ret_val->min = imin;
1064 ret_val->max = imax;
1070 int GJbsearchINXS(char **cod, int n, char *query)
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 */
1076 int r; /* right limit */
1077 int l; /* left limit */
1078 int cv; /* centre value */
1086 if(strcmp(query,cod[cv]) == 0){
1088 }else if(strcmp(query,cod[cv]) > 0){
1090 }else if(strcmp(query,cod[cv]) < 0){
1094 for(cv=l;cv<(r+1);++cv){
1095 if(strcmp(query,cod[cv]) == 0){
1104 int GJbsearchINX_IS(char **cod, int *inx, int n, char *query)
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
1110 /* if it is not found, return -1 */
1113 int r; /* right limit */
1114 int l; /* left limit */
1115 int cv; /* centre value */
1123 if(strcmp(query,cod[inx[cv]]) == 0){
1125 }else if(strcmp(query,cod[inx[cv]]) > 0){
1127 }else if(strcmp(query,cod[inx[cv]]) < 0){
1131 for(cv=l;cv<(r+1);++cv){
1132 if(strcmp(query,cod[inx[cv]]) == 0){
1143 $Id: gjutil.c,v 1.13 2002/08/09 12:30:31 geoff Exp $
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
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
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.
1166 Revision 1.11 2000/07/04 11:01:37 searle
1169 Revision 1.10 1999/11/17 21:06:47 geoff
1170 Add setup_caleb and other changes to swpp2 and so on.
1172 Revision 1.9 1999/07/09 13:34:10 geoff
1173 modified these as a test
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.
1179 Revision 1.7 1997/06/29 00:43:57 gjb
1180 Changes to add sysinfo calls and test of license reading routines
1182 Revision 1.6 1997/06/27 16:42:41 gjb
1183 Add trlic.c test.lic and clean up gjutil.c
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
1190 Revision 1.4 1997/05/12 11:10:53 gjb
1191 Re-added gjutil.c and gjutil.h to repository
1194 Revision 1.2 1997/05/12 10:47:52 gjb
1195 Modified CVS header and log position