/* utils.c c Ivo L Hofacker and Walter Fontana Vienna RNA package */ /* Last changed Time-stamp: <2008-11-25 16:34:36 ivo> */ #include #include #include #include #include #include "../config.h" #ifdef WITH_DMALLOC #include "dmalloc.h" #endif /*@unused@*/ static char rcsid[] = "$Id: utils.c,v 1.19 2008/12/16 22:30:30 ivo Exp $"; #define PRIVATE static #define PUBLIC /*@notnull@ @only@*/ PUBLIC void *space(unsigned int size); /*@exits@*/ PUBLIC void nrerror(const char message[]); PUBLIC double urn(void); PUBLIC int int_urn(int from, int to); PUBLIC void filecopy(FILE *from, FILE *to); /*@observer@*/ PUBLIC char *time_stamp(void); PUBLIC char *random_string(int l, const char symbols[]); PUBLIC int hamming(const char *s1, const char *s2); PUBLIC char *get_line(FILE *fp); PUBLIC unsigned short xsubi[3]; /*-------------------------------------------------------------------------*/ PUBLIC void *space(unsigned size) { void *pointer; if ( (pointer = (void *) calloc(1, (size_t) size)) == NULL) { #ifdef EINVAL if (errno==EINVAL) { fprintf(stderr,"SPACE: requested size: %d\n", size); nrerror("SPACE allocation failure -> EINVAL"); } if (errno==ENOMEM) #endif nrerror("SPACE allocation failure -> no memory"); } return pointer; } #ifdef WITH_DMALLOC #define space(S) calloc(1,(S)) #endif #undef xrealloc /* dmalloc.h #define's xrealloc */ void *xrealloc (void *p, unsigned size) { if (p == 0) return space(size); p = (void *) realloc(p, size); if (p == NULL) { #ifdef EINVAL if (errno==EINVAL) { fprintf(stderr,"xrealloc: requested size: %d\n", size); nrerror("xrealloc allocation failure -> EINVAL"); } if (errno==ENOMEM) #endif nrerror("xrealloc allocation failure -> no memory"); } return p; } /*------------------------------------------------------------------------*/ PUBLIC void nrerror(const char message[]) /* output message upon error */ { fprintf(stderr, "\n%s\n", message); exit(EXIT_FAILURE); } /*------------------------------------------------------------------------*/ PUBLIC void init_rand(void) { time_t t; (void) time(&t); xsubi[0] = xsubi[1] = xsubi[2] = (unsigned short) t; /* lower 16 bit */ xsubi[1] += (unsigned short) ((unsigned)t >> 6); xsubi[2] += (unsigned short) ((unsigned)t >> 12); #ifndef HAVE_ERAND48 srand((unsigned int) t); #endif } /*------------------------------------------------------------------------*/ PUBLIC double urn(void) /* uniform random number generator; urn() is in [0,1] */ /* uses a linear congruential library routine */ /* 48 bit arithmetic */ { #ifdef HAVE_ERAND48 extern double erand48(unsigned short[]); return erand48(xsubi); #else return ((double) rand())/RAND_MAX; #endif } /*------------------------------------------------------------------------*/ PUBLIC int int_urn(int from, int to) { return ( ( (int) (urn()*(to-from+1)) ) + from ); } /*------------------------------------------------------------------------*/ PUBLIC void filecopy(FILE *from, FILE *to) { int c; while ((c = getc(from)) != EOF) (void)putc(c, to); } /*-----------------------------------------------------------------*/ PUBLIC char *time_stamp(void) { time_t cal_time; cal_time = time(NULL); return ( ctime(&cal_time) ); } /*-----------------------------------------------------------------*/ PUBLIC char *random_string(int l, const char symbols[]) { char *r; int i, rn, base; base = (int) strlen(symbols); r = (char *) space(sizeof(char)*(l+1)); for (i = 0; i < l; i++) { rn = (int) (urn()*base); /* [0, base-1] */ r[i] = symbols[rn]; } r[l] = '\0'; return r; } /*-----------------------------------------------------------------*/ PUBLIC int hamming(const char *s1, const char *s2) { int h=0; for (; *s1 && *s2; s1++, s2++) if (*s1 != *s2) h++; return h; } /*-----------------------------------------------------------------*/ PUBLIC char *get_line(FILE *fp) /* reads lines of arbitrary length from fp */ { char s[512], *line, *cp; int len=0, size=0, l; line=NULL; do { if (fgets(s, 512, fp)==NULL) break; cp = strchr(s, '\n'); if (cp != NULL) *cp = '\0'; l = len + strlen(s); if (l+1>size) { size = (l+1)*1.2; line = (char *) xrealloc(line, size*sizeof(char)); } strcat(line+len, s); len=l; } while(cp==NULL); return line; } /*-----------------------------------------------------------------*/ PUBLIC char *pack_structure(const char *struc) { /* 5:1 compression using base 3 encoding */ int i,j,l,pi; unsigned char *packed; l = (int) strlen(struc); packed = (unsigned char *) space(((l+4)/5+1)*sizeof(unsigned char)); j=i=pi=0; while (i=0; k--) { c = p % 3; p /= 3; struc[j+k] = code[c]; } j += 5; } struc[j--] = '\0'; while (struc[j] == '(') /* strip trailing ( */ struc[j--] = '\0'; return struc; } /*--------------------------------------------------------------------------*/ PUBLIC short *make_pair_table(const char *structure) { /* returns array representation of structure. table[i] is 0 if unpaired or j if (i.j) pair. */ short i,j,hx; short length; short *stack; short *table; length = (short) strlen(structure); stack = (short *) space(sizeof(short)*(length+1)); table = (short *) space(sizeof(short)*(length+2)); table[0] = length; for (hx=0, i=1; i<=length; i++) { switch (structure[i-1]) { case '(': stack[hx++]=i; break; case ')': j = stack[--hx]; if (hx<0) { fprintf(stderr, "%s\n", structure); nrerror("unbalanced brackets in make_pair_table"); } table[i]=j; table[j]=i; break; default: /* unpaired base, usually '.' */ table[i]= 0; break; } } if (hx!=0) { fprintf(stderr, "%s\n", structure); nrerror("unbalanced brackets in make_pair_table"); } free(stack); return(table); } /*---------------------------------------------------------------------------*/ PUBLIC int bp_distance(const char *str1, const char *str2) { /* dist = {number of base pairs in one structure but not in the other} */ /* same as edit distance with pair_open pair_close as move set */ int dist; short i,l; short *t1, *t2; dist = 0; t1 = make_pair_table(str1); t2 = make_pair_table(str2); l = (t1[0]i) dist++; if (t2[i]>i) dist++; } free(t1); free(t2); return dist; } #ifndef HAVE_STRDUP char *strdup(const char *s) { char *dup; dup = space(strlen(s)+1); strcpy(dup, s); return(dup); } #endif