/* _______________________________________________________________________ * * RDPARM/PTRAJ: APR 2000 * _______________________________________________________________________ * * $Header: /thr/gamow/cvsroot/amber7/src/ptraj/utility.c,v 1.6 2000/05/10 21:53:22 cheatham Exp $ * * Revision: $Revision: 1.6 $ * Date: $Date: 2000/05/10 21:53:22 $ * Last checked in by $Author: cheatham $ * * This source is now archived under CVS at Scripps in the amber7 tree. * * NOTE: this is a beta, pre-release version, is under constant development, * probably contains some bugs and is under constant revision; therefore * take care. Please report bugs (and fixes!) to cheatham@chpc.utah.edu or * cheatham@cgl.ucsf.edu * * Do not distribute this code without explicit permission. * Do not incorporate into other codes without explicit permission. * * Current contact information: * * Thomas Cheatham, III * 2000 East, 30 South, Skaggs Hall 201 * Department of Medicinal Chemistry * University of Utah * Salt Lake City, UT 84112-5820 * cheatham@chpc.utah.edu * (801) 587-9653 * FAX: (801) 585-5366 * * Other contributors: * * David Case (Scripps) * Michael Crowley (Scripps) * Jed Pitera (UCSF) * Vickie Tsui (Scripps) * _______________________________________________________________________ */ #include #include #include #include #include #define UTILITY_MODULE #include "utility.h" /* * This file contains various utility functions and structures * and should be general for any C program. * * * The following functions are defined (see also the supporting * header file, utility.h): * * * error(char *function, char *format, ... ) * ...a varargs function that prints out the first argument * (which typically represents the calling function name for * debugging) followed by the error string which may contain * printf format characters, followed by an arbitrary number of * arguments representing the printf style formats. * Execution of the program is terminated when this function * is called. * * warning(char *function, char *format, ... ) * ...same as above, but execution is not terminated. * * void * * safe_malloc(size) * ... allocates size bytes of memory and performs error * checking. * * void * * safe_realloc(memory, cur_size, increase) * ...a safe realloc command, increasing the space pointed to * by memory by increase size. * * void * * allocate(memory, size, allocated, increase) * ...a combination of the above procedures, malloc() or * realloc(). memory is a pointer, size of the sizeof each * element, allocated is the amount currently allocated, and * increase is the increase in elements. The total number * allocated is returned... * * safe_free(memory) * ...frees the memory pointed to by memory (with checking * to make sure the pointer isn't NULL * * scanString(), scanInt(), scanDouble() * ...these functions scan values from a file, printing a * string if an error occurs. See the functions themselves for * more information. * * char * * toLowerCase(string) * ...converts the string to lower case * * shiftArray(src, dest, length) * ...shifts the src array by length elements putting the result * in the dest array. * * pushStack( stackType **stackp, void *entry ) * ...push a pointer to "entry" on the stackType ** stack or * &stack * * pushBottomStack( stackType **stackp, void *entry ) * ...push a pointer to "entry" on to the *bottom* of the * stackType ** structure &stack * * void * * popStack( stackType **stackp ) * ...pop the top element off the &stack and delete the * associated stack element * * clearStack( stackType **stackp ) * ...clear out the whole &stack and free up the associated * memory * * printStack( stackType **stackp, (*fxnPrintStackEntry)(void *), char * ) * ...a debugging routine to print out a stack; the function * passed in (fxnPrintStackEntry)() is set up to print the * entry of interest. The (char *) is optional text to print before * the entry (along with the stack entry number). */ void error(char *function, char *fmt, ...) { va_list args; va_start(args, fmt); fprintf(stderr, "\nERROR in %s: ", function); vfprintf(stderr, fmt, args); fprintf(stderr, "\n" ); va_end(args); exit(1); } void warning(char *function, char *fmt, ...) { va_list args; va_start(args, fmt); fprintf(stderr, "\nERROR in %s: ", function); vfprintf(stderr, fmt, args); fprintf(stderr, "\n" ); va_end(args); } void * safe_malloc(int size) { void *mem; if ( size ) { if ( (mem = (void *) malloc( (size_t) size )) == NULL ) error( "safe_malloc", "Error in alloc of %i bytes", size); } else mem = NULL; return( mem ); } /* Performs error checking on realloc(). NOTE: the semantics of the * call are slightly different than realloc()! */ void * safe_realloc(void *mem, int cur_size, int increase) { void *temp; if ( increase < 0 ) error("safe_realloc", "Cannot increase memory by %i", increase); if ( cur_size == 0 ) return ( safe_malloc( increase ) ); else if ( (temp = (void *) realloc((void *) mem, (size_t) (cur_size + increase))) == NULL ) error( "safe_realloc", "Couldn't allocate %i bytes more", increase); mem = temp; return(mem); } int allocate(void **pointer, int size, int cur, int inc) { if (size == 0) { *pointer = NULL; return ( 0 ); } if (cur == 0) { *pointer = (void *) malloc( (size_t) size * inc ); if ( *pointer == NULL ) error("allocate()", "Error in allocation of %i bytes", inc); } else { if ( inc < 0 ) error("allocate()", "Cannot allocate %i bytes!\n", inc); else if ( inc == 0 ) return(cur+inc); else { *pointer = (void *) realloc((void *) *pointer, (size_t) size * (cur + inc)); if ( *pointer == NULL ) error( "allocate()", "Couldn't allocate %i more bytes", size * inc); } } return( cur + inc ); } void safe_free(void *pointer) { if ( pointer != NULL ) free(pointer); } /* * Scan for a string from the file (fp). If failure occurs * print a warning message and exit if isError is TRUE. */ int scanString(FILE *fp, char *ip, int isError, char *err_string) { if ( ! fscanf( fp, "%s", ip ) ) { if ( isError == TRUE ) error("scanString", "...scanning %s\n", err_string); else { warning("scanString", "...scanning %s\n", err_string); return TRUE; } } return FALSE; } /* * Scan for a integer from the file (fp). If failure occurs * print a warning message and exit if Error is TRUE. */ int scanInt(FILE *fp, int *ip, int isError, char *err_string) { if ( ! fscanf( fp, "%d", ip ) ) { if ( isError == TRUE ) error("scanInt", "...scanning %s\n", err_string); else { warning("scanInt", "...scanning %s\n", err_string); return TRUE; } } return FALSE; } /* * Scan for a double from the file (fp). If failure occurs * print a warning message and exit if isError is TRUE. */ int scanDouble(FILE *fp, double *ip, int isError, char *err_string) { if ( ! fscanf( fp, "%lf", ip ) ) { if ( isError == TRUE ) error("scanDouble", "...scanning %s\n", err_string); else { warning("scanDouble", "...scanning %s\n", err_string); return TRUE; } } return FALSE; } /* Convert the string to lower case. This has not been tested on * all character sets. For this to work, it is necessary that * there be a constant difference in values between a lower case * letter and it's corresponding upper case value. */ char * toLowerCase( char *string_in ) { int i, length; length = strlen( string_in ); for (i=0; i < length; i++ ) { string_in[i] = tolower( string_in[i] ); } return string_in; } /* * stringContains(string, match) -- this is like strstr except that instead * of returning a pointer to the first occurrence of "match" in "string" * 1 is returned if the "match" is within "string" otherwise 0 is returned. * AN ADDITIONAL DIFFERENCE is that this matching is not case sensitive!!! */ int stringContains(char *string, char *match) { char *lowerString, *lowerMatch; if (string == NULL || match == NULL) return 0; lowerString = safe_malloc(sizeof(char) * (strlen(string)+1)); strcpy(lowerString,string); lowerMatch = safe_malloc(sizeof(char) * (strlen(match)+1)); strcpy(lowerMatch,match); lowerString = toLowerCase(lowerString); lowerMatch = toLowerCase(lowerMatch); if (strstr(lowerString, lowerMatch) != NULL) { safe_free(lowerString); safe_free(lowerMatch); return 1; } else { safe_free(lowerString); safe_free(lowerMatch); return 0; } } /* * this is like strcmp, however the match is only check on the length * of the string "match" and the comparison is case insenstive */ int stringMatch(char *string, char *match) { char *lowerString, *lowerMatch; if (string == NULL || match == NULL) return 0; lowerString = safe_malloc(sizeof(char) * (strlen(string)+1)); strcpy(lowerString,string); lowerMatch = safe_malloc(sizeof(char) * (strlen(match)+1)); strcpy(lowerMatch,match); lowerString = toLowerCase(lowerString); lowerMatch = toLowerCase(lowerMatch); if (strncmp(lowerMatch, lowerString, strlen(lowerMatch)) == 0) { safe_free(lowerString); safe_free(lowerMatch); return 1; } else { safe_free(lowerString); safe_free(lowerMatch); return 0; } } /* * Performs a safety check on a bcopy() call */ void shiftArray( void *src, void *dest, int length ) { if ( length < 0 ) warning("shiftArray", "Cannot currently shift array < 0 bytes (%i)", length); else if ( length > 0 ) { bcopy( src, dest, (size_t) length ); } } void pushStack( stackType **stackp, void *entry ) { stackType *sp; sp = safe_malloc( sizeof(stackType) ); sp->entry = entry; sp->next = *stackp; *stackp = sp; } void pushBottomStack( stackType **stackp, void *entry ) { stackType *sp; if ( *stackp == NULL ) pushStack( stackp, entry ); else { sp = *stackp; while ( sp->next != NULL ) sp = sp->next; sp->next = safe_malloc( sizeof(stackType) ); sp->next->entry = entry; sp->next->next = NULL; } } void * popStack( stackType **stackp ) { void *entry; stackType *sp; if ( *stackp == NULL ) { return( (char *) NULL ); } sp = *stackp; entry = sp->entry; *stackp = sp->next; sp->next=NULL; free( sp ); return( entry ); } void clearStack( stackType **stackp ) { stackType *sp, *tmp; if (stackp == NULL) { return; } tmp = NULL; for (sp = *stackp; sp != NULL; ) { if ( tmp != NULL ) safe_free( (void *) tmp); safe_free( (void *) sp->entry); sp->entry = NULL; tmp = sp; sp = sp->next; } *stackp = NULL; } void printStack( stackType **stackp, fxnPrintStackEntry fxn, char *babble) { stackType *p; int i; for (p = *stackp, i = 1; p != NULL; p = p->next, i++) { if ( babble != NULL ) fprintf(stdout, "%s (%i)\n", babble, i); fxn(p->entry); } }