/**************************************************************************** gjutil.c: Various utility routines - error checking malloc and free, string functions etc... Copyright: Geoffrey J. Barton (1992, 1993, 1995, 1997) email: geoff@ebi.ac.uk This software is made available for educational and non-commercial research purposes. For commercial use, a commercial licence is required - contact the author at the above address for details. ******************************************************************************/ #include #include #include #include #include #include #include #include #include /* define pointers for standard streams to allow redefinition to files */ FILE *std_err; FILE *std_in; FILE *std_out; /* clock externs */ clock_t start_time, end_time,initial_time,final_time; void *GJmalloc(size_t size) /* malloc with simple error check */ /* G. J. Barton 1992 */ { void *ptr; ptr = (void *) malloc(size); if(ptr == NULL){ GJerror("malloc error"); exit(0); } return ptr; } void *GJrealloc(void *ptr,size_t size) /* realloc with error check */ /* G. J. Barton 1992 */ { ptr = (void *) realloc(ptr,size); if(ptr == NULL){ GJerror("realloc error"); exit(0); } return ptr; } void *GJmallocNQ(size_t size) /* as for GJmalloc, but returns NULL on error*/ /* G. J. Barton 1992 */ { void *ptr; ptr = (void *) malloc(size); if(ptr == NULL){ GJerror("malloc error"); return NULL; } return ptr; } void *GJreallocNQ(void *ptr,size_t size) /* as for GJrealloc with error check but returns NULL on error*/ /* G. J. Barton 1992 */ { ptr = (void *) realloc(ptr,size); if(ptr == NULL){ GJerror("realloc error"); return NULL; } return ptr; } void GJfree(void *ptr) /* free with error check */ /* G. J. Barton 1992 */ { if(ptr == NULL){ GJerror("Attempt to free NULL pointer"); exit(0); } free(ptr); } void GJerror(const char *prefix) /* writes error message contained in prefix and contents of errno to std_err. */ /* G. J. Barton 1992 */ { if(prefix != NULL){ if(*prefix != '\0'){ fprintf(std_err,"%s: ",prefix); } } fprintf(std_err,"%s\n",strerror(errno)); } /* error: calls GJerror */ void error(const char *str,int flag) { GJerror(str); if(flag)exit(0); } char *GJstoupper(const char *s) /* return a copy of s in upper case */ /* G. J. Barton 1992 */ { char *temp; int i; temp = GJstrdup(s); i=0; while(temp[i] != '\0'){ temp[i] = toupper(temp[i]); ++i; } return temp; } char *GJstolower(const char *s) /* return a copy of s in lower case */ /* G. J. Barton 1992 */ { char *temp; int i; temp = GJstrdup(s); i=0; while(temp[i] != '\0'){ temp[i] = tolower(temp[i]); ++i; } return temp; } char *GJstoup(char *s) /* return s in upper case */ /* G. J. Barton 1992 */ { int i; i=0; while(s[i] != '\0'){ s[i] = toupper(s[i]); ++i; } return s; } char *GJstolo(char *s) /* return s in lower case */ /* G. J. Barton 1992 */ { int i; i=0; while(s[i] != '\0'){ s[i] = tolower(s[i]); ++i; } return s; } char *GJstrdup(const char *s) /* returns a pointer to a copy of string s */ /* G. J. Barton 1992 */ { char *temp; temp = (char *) GJmalloc(sizeof(char) * (strlen(s)+1)); temp = strcpy(temp,s); return temp; } char *GJstrrename(char *old,const char *new) /* takes old which is a pointer to a string, then replaces the contents of the string with new, reallocating to the correct size */ { int nlen; nlen = strlen(new); old = (char *) GJrealloc(old,sizeof(char) * (nlen + 1)); old = strcpy(old,new); return old; } FILE *GJfopen(const char *fname,const char *type,int action) /* a file open function with error checking. The third argument is set to 0 if we want a failed open to return, or 1 if we want a failed open to exit the program. */ /* G. J. Barton 1992 */ /* modified July 1995 - error message only printed if action is 1 */ { FILE *ret_val; ret_val = fopen(fname,type); if(ret_val == NULL){ /* GJerror(strcat("Cannot Open File: ",fname));*/ if(action == 1){ GJerror(strcat("Cannot Open File: ",fname)); exit(1); } } return ret_val; } int GJfclose(FILE *fp,int action) /* a file close function with error checking. The second argument is set to 0 if we want a failed close to return, or 1 if we want a failed close to exit the program. */ /* G. J. Barton 1992 */ { int ret_val; ret_val = fclose(fp); if(ret_val != 0){ if(action == 1){ GJerror("Error closing File"); exit(1); } } return ret_val; } GJFILE *GJfilemake(const char *name,const char *type,int action) /* If action = 1 then Tries to open the file with the given name. If successful returns a pointer to a struct file structure with the name and filehandle. If the open fails, or action= 0 then returns a struct file structure with the name and a NULL filehandle */ /* G. J. Barton 1995 */ { GJFILE *ret_val; ret_val = (GJFILE *) GJmalloc(sizeof(GJFILE)); ret_val->name = GJstrdup(name); if(action == 1) { ret_val->handle = GJfopen(ret_val->name,type,0); }else if(action == 0){ ret_val->handle = NULL; } return ret_val; } GJFILE *GJfilerename(GJFILE *ret_val, const char *name) /* When passed the fval structure - renames the name part of the file structure to name, if the handle is non null it tries to close the file, then sets the file handle to NULL. */ /* G. J. Barton 1995 */ { if(ret_val->name != NULL) { GJfree(ret_val->name); ret_val->name = GJstrdup(name); } if(ret_val->handle != NULL) { GJfclose(ret_val->handle,0); ret_val->handle = NULL; } return ret_val; } GJFILE *GJfileclose(GJFILE *ret_val,int action) /* Closes a file named in the struct file structure returns the struct file structure */ /* G. J. Barton July 1995 */ { STD_FILES; if(GJfclose(ret_val->handle,0) == 0){ return ret_val; }else { if(action == 1){ GJerror("Error closing File"); fprintf(std_err,"%s\n",ret_val->name); exit(-1); } } return ret_val; } GJFILE *GJfileopen(GJFILE *ret_val,const char *type,int action) /* Opens a file named in the struct file structure */ /* G. J. Barton October 1995 */ { STD_FILES; ret_val->handle = GJfopen(ret_val->name,type,0); if(ret_val->handle == NULL){ if(action == 1){ GJerror("Error opening File"); fprintf(std_err,"%s\n",ret_val->name); exit(-1); } } return ret_val; } GJFILE *GJfileclean(GJFILE *ret_val,int action) /* Closes the file then sets the file pointer to NULL, then frees the filename string */ /* G. J. Barton July 1995 */ { if(GJfclose(ret_val->handle,0) == 0) { ret_val->handle = NULL; GJfree(ret_val->name); return ret_val; }else { if(action == 1){ GJerror("Error closing File"); fprintf(std_err,"%s\n",ret_val->name); exit(-1); } } return ret_val; } void GJinitfile(void) /* just set the standard streams */ { std_err = stderr; std_in = stdin; std_out = stdout; } char *GJfnonnull(char *string) /* return pointer to first non null character in the string */ /* this could cause problems if the string is not null terminated */ { while(*string != '\0'){ ++string; } return ++string; } char *GJstrappend(char *string1, char *string2) /* appends string2 to the end of string2. Any newline characters are removed from string1, then the first character of string2 overwrites the null at the end of string1. string1 and string2 must have been allocated with malloc. */ /* G. J. Barton July 1992 */ { char *ret_val; ret_val = GJremovechar(string1,'\n'); ret_val = (char *) GJrealloc(ret_val, sizeof(char) * (strlen(ret_val) + strlen(string2) + 1)); ret_val = strcat(ret_val,string2); return ret_val; } char *GJremovechar(char *string,char c) /* removes all instances of character c from string returns a pointer to the reduced, null terminated string 11/8/1996: couple of bugs found in this routine. the length of the string returned was too short by 2 bytes. This is a dodgy routine since string is freed. */ /* G. J. Barton (July 1992) */ { char *temp; int j,i,nchar; nchar = 0; i=0; while(string[i] != '\0'){ if(string[i] == c){ ++nchar; } ++i; } if(nchar == 0){ return string; }else{ temp = (char *) GJmalloc(sizeof(char) * (strlen(string)-nchar + 1)); j=0; i=0; while(string[i] != '\0'){ if(string[i] != c){ temp[j] = string[i]; ++j; } ++i; } temp[j] = '\0'; GJfree(string); return temp; } } char *GJremovechar2(char *string,char c) /* removes all instances of character c from string returns a pointer to the reduced, null terminated string */ /* G. J. Barton (July 1992) */ { char *temp; int i,k,len; k=0; len=strlen(string); temp = (char *) GJmalloc(sizeof(char) * (len+1)); for(i=0;i<(len+1);++i){ if(string[i] != c){ temp[k] = string[i]; ++k; } } for(i=0;i<(strlen(temp)+1);++i){ string[i] = temp[i]; } GJfree(temp); return string; } char *GJsubchar(char *string,char c2,char c1) /* substitutes c1 for c2 in string */ /* G. J. Barton (July 1992) */ { int i; i=0; while(string[i] != '\0'){ if(string[i] == c1){ string[i] = c2; } ++i; } return string; } /* create a string and if fchar != NULL fill with characters */ /* always set the len-1 character to '\0' */ char *GJstrcreate(size_t len,char *fchar) { char *ret_val; ret_val = (char *) GJmalloc(sizeof(char) * len); --len; ret_val[len] = '\0'; if(fchar != NULL){ while(len > -1){ ret_val[len] = *fchar; --len; } } return ret_val; } /* searches for string s2 in string s1 and returns pointer to first instance of s2 in s1 or NULL if no instance found. s1 and s2 must be null terminated */ char *GJstrlocate(char *s1, char *s2) { int i=0; int j=0; int k; if(strlen(s1) == 0 || strlen(s2) == 0) return NULL; while(i < strlen(s1)){ j=0; k=i; while(j < strlen(s2) && s1[k] == s2[j]){ ++k; ++j; } if(j == strlen(s2)) return &s1[i]; ++i; } return NULL; } #include #include /* GJstrtok() This version of strtok places the work pointer at the location of the first character in the next token, rather than just after the last character of the current token. This is useful for extracting quoted strings */ char *GJstrtok(char *input_string,const char *token_list) { static char *work; char *return_ptr; if(input_string != NULL){ /* first call */ work = input_string; } /* search for next non-token character */ while(strchr(token_list,*work)!=NULL){ ++work; } if(*work == '\0'){ /* if we've reached the end of string, then return NULL */ return NULL; }else{ return_ptr = (char *) work; while(strchr(token_list,*work) == NULL){ if(*work == '\0'){ /* end of the string */ return return_ptr; }else{ ++work; } } *work = '\0'; ++work; /* now increment work until we find the next non-delimiter character */ while(strchr(token_list,*work) != NULL){ if(*work == '\0'){ break; }else{ ++work; } } return return_ptr; } } /************************************************************************** return a pointer to space for a rectangular unsigned character array Version 2.0 ANSI and uses GJmallocNQ --------------------------------------------------------------------------*/ unsigned char **uchararr(int i,int j) { unsigned char **temp; int k, rowsiz; temp = (unsigned char **) GJmallocNQ(sizeof(unsigned char *) * i); if(temp == NULL) return NULL; rowsiz = sizeof(unsigned char) * j; for (k = 0; k < i; ++k){ temp[k] = (unsigned char *) GJmallocNQ(rowsiz); if(temp[k] == NULL) return NULL; } return temp; } /************************************************************************** free up space pointed to by rectangular unsigned character array -------------------------------------------------------------------------*/ void ucharfree(unsigned char **array,int i) { int k; for (k = 0; k < i; ++k){ GJfree((char *) array[k]); } GJfree((char *) array); } /************************************************************************** return a pointer to space for a rectangular signed character array Version 2.0 ANSI --------------------------------------------------------------------------*/ signed char **chararr(int i,int j) { signed char **temp; int k, rowsiz; temp = (signed char **) GJmallocNQ(sizeof(char *) * i); if(temp == NULL) return NULL; rowsiz = sizeof(char) * j; for (k = 0; k < i; ++k){ temp[k] = (signed char *) GJmallocNQ(rowsiz); if(temp[k] == NULL) return NULL; } return temp; } /* mcheck - check a call to malloc - if the call has failed, print the error message and exit the program */ /* ANSI Version - also uses GJerror routine and ptr is declared void*/ void mcheck(void *ptr,char *msg) { if(ptr == NULL){ GJerror("malloc/realloc error"); exit(0); } } /* set a string to blanks and add terminating nul */ char *GJstrblank(char *string,int len) { --len; string[len] = '\0'; --len; while(len > -1){ string[len] = ' '; --len; } return string; } /* Initialise an unsigned char array */ void GJUCinit(unsigned char **array,int i,int j,unsigned char val) { int k,l; for(k=0;k0){ token[i] = '\0'; return token; } } /* GJerror("End of File Encountered");*/ GJfree(token); return NULL; } struct tokens *GJgettokens(const char *delims, char *buff) /* This splits a buffer into tokens at each position defined by delims.*/ /* The structure returned contains the number of tokens and the */ /* tokens themselves as a char ** array */ { char *token; struct tokens *tok; token = strtok(buff,delims); if(token == NULL) return NULL; tok = (struct tokens *) GJmalloc(sizeof(struct tokens)); tok->ntok = 0; tok->tok = (char **) GJmalloc(sizeof(char *)); tok->tok[0] = GJstrdup(token); ++tok->ntok; while((token = strtok(NULL,delims)) != NULL) { tok->tok = (char **) GJrealloc(tok->tok,sizeof(char *) * (tok->ntok+1)); tok->tok[tok->ntok] = GJstrdup(token); ++tok->ntok; } return tok; } void GJfreetokens(struct tokens *tok) /* frees a tokens structure */ { int i; for(i=0;intok;++i) { GJfree(tok->tok[i]); } GJfree(tok->tok); GJfree(tok); tok = NULL; /* add this to avoid odd pointer 27/6/1997*/ } char * GJtoktostr(struct tokens *tok,char delim,int s, int e) /* returns a string with the tokens between s and e inclusive written to it separated by delim the tok structure is unmodified. */ { int n, i, j,k; char *ret_val; n = 0; if(s < 0 || s >= tok->ntok) s = 0; if(e < 0 || e >= tok->ntok) e = tok->ntok - 1; for(i=s;i<=e;++i){ n += strlen(tok->tok[i]); ++n; } ret_val = (char *) GJmalloc(sizeof(char) * n); j = 0; for(i=s;i<=e;++i){ for(k=0;ktok[i]);++k){ ret_val[j] = tok->tok[i][k]; ++j; } ret_val[j++] = delim; } ret_val[n-1] = '\0'; return ret_val; } /* void GJ_start_clock() { extern clock_t start_time, end_time,initial_time,final_time; start_time = clock(); initial_time = start_time; } void GJ_stop_clock(FILE *fp) { extern clock_t start_time, end_time,initial_time,final_time; end_time = clock(); fprintf(fp,"CPU time: %f seconds\n", ((float) (end_time - start_time))/CLOCKS_PER_SEC); } */ void GJ_start_clock(void) { GJ_init_times(); } void GJ_stop_clock(FILE *fp) { GJ_show_times(fp,3); GJ_reset_times(); } void GJindexx(int *arrin,int n,int *indx) /* indexed heap sort - adapted from the NR routine indexx. inarr is an integer array to sort, indx is the returned index array */ { int l,j,ir,indxt,i; float q; for (j=1;j<=n;j++) indx[j]=j; l=(n >> 1) + 1; ir=n; for (;;) { if (l > 1) q=arrin[(indxt=indx[--l])]; else { q=arrin[(indxt=indx[ir])]; indx[ir]=indx[1]; if (--ir == 1) { indx[1]=indxt; return; } } i=l; j=l << 1; while (j <= ir) { if (j < ir && arrin[indx[j]] < arrin[indx[j+1]]) j++; if (q < arrin[indx[j]]) { indx[i]=indx[j]; j += (i=j); } else j=ir+1; } indx[i]=indxt; } } void GJpline(FILE *fp,char c,int n) /* print n copies of c to fp terminated by newline */ { int i; for(i=0;i n){ for(i=0;i imax) imax = ivec[i]; if(ivec[i] < imin) imin = ivec[i]; } ret_val = (IRANGE *) GJmalloc(sizeof(IRANGE)); ret_val->min = imin; ret_val->max = imax; return ret_val; } /* $Id: gjutil.c,v 1.1.1.1 1999/07/09 13:34:10 geoff Exp $ $Log: gjutil.c,v $ Revision 1.1.1.1 1999/07/09 13:34:10 geoff Import alscript 2_07 with the cygwin executables. Revision 1.9 1999/07/09 13:34:10 geoff modified these as a test Revision 1.8 1998/08/11 15:38:50 geoff Modified the copyright notice to reflect the new ownership of this software. Revision 1.7 1997/06/29 00:43:57 gjb Changes to add sysinfo calls and test of license reading routines Revision 1.6 1997/06/27 16:42:41 gjb Add trlic.c test.lic and clean up gjutil.c Revision 1.5 1997/06/27 07:17:31 gjb Added rlic.c linfo.h and changes to gjutil.c to give better support for token manipulation Revision 1.4 1997/05/12 11:10:53 gjb Re-added gjutil.c and gjutil.h to repository after deleting them Revision 1.2 1997/05/12 10:47:52 gjb Modified CVS header and log position */