ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/gclib/gclib/GBase.cpp
Revision: 16
Committed: Mon Jul 18 20:56:02 2011 UTC (7 years, 11 months ago) by gpertea
File size: 18165 byte(s)
Log Message:
sync with local source

Line File contents
1 #include "GBase.h"
2 #include <stdarg.h>
3 #include <ctype.h>
4 #include <sys/stat.h>
5
6 static char msg[4069];
7 /*
8 #ifdef _DEFINE_WIN32_FSEEKO
9 int fseeko(FILE *stream, off_t offset, int whence) {
10
11 }
12 #endif
13
14 #ifdef _DEFINE_WIN32_FTELLO
15 off_t ftello(FILE *stream) {
16
17 }
18 #endif
19 */
20
21
22 int saprintf(char **retp, const char *fmt, ...) {
23 va_list argp;
24 int len;
25 char *buf;
26
27 va_start(argp, fmt);
28 len = vsnprintf(NULL, 0, fmt, argp);
29 va_end(argp);
30 GMALLOC(buf, (len + 1));
31 if(buf == NULL)
32 {
33 *retp = NULL;
34 return -1;
35 }
36
37 va_start(argp, fmt);
38 vsnprintf(buf, len+1, fmt, argp);
39 va_end(argp);
40
41 *retp = buf;
42 return len;
43 }
44
45 //************************* Debug helpers **************************
46 // Assert failed routine
47 void GAssert(const char* expression, const char* filename, unsigned int lineno){
48 sprintf(msg,"%s(%d): ASSERT(%s) failed.\n",filename,lineno,expression);
49 fprintf(stderr,"%s",msg);
50 //abort();
51 }
52 // Error routine (prints error message and exits!)
53 void GError(const char* format,...){
54 #ifdef __WIN32__
55 va_list arguments;
56 va_start(arguments,format);
57 vsprintf(msg,format,arguments);
58 va_end(arguments);
59 OutputDebugString(msg);
60 fprintf(stderr,"%s",msg); // if a console is available
61 MessageBox(NULL,msg,NULL,MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
62 #else
63 va_list arguments;
64 va_start(arguments,format);
65 vfprintf(stderr,format,arguments);
66 va_end(arguments);
67 #ifdef DEBUG
68 // modify here if you want a core dump
69 abort();
70 #endif
71 #endif
72 exit(1);
73 }
74
75 // Warning routine (just print message without exiting)
76 void GMessage(const char* format,...){
77 va_list arguments;
78 va_start(arguments,format);
79 vsprintf(msg,format,arguments);
80 va_end(arguments);
81 #ifdef __WIN32__
82 OutputDebugString(msg);
83 #endif
84 fprintf(stderr,"%s",msg);fflush(stderr);
85 }
86
87 /*************** Memory management routines *****************/
88 // Allocate memory
89 bool GMalloc(pointer* ptr,unsigned long size){
90 //GASSERT(ptr);
91 if (size!=0) *ptr=malloc(size);
92 return *ptr!=NULL;
93 }
94
95 // Allocate cleaned memory (0 filled)
96 bool GCalloc(pointer* ptr,unsigned long size){
97 GASSERT(ptr);
98 *ptr=calloc(size,1);
99 return *ptr!=NULL;
100 }
101
102 // Resize memory
103 bool GRealloc(pointer* ptr,unsigned long size){
104 //GASSERT(ptr);
105 if (size==0) {
106 GFree(ptr);
107 return true;
108 }
109 if (*ptr==NULL) {//simple malloc
110 void *p=malloc(size);
111 if (p != NULL) {
112 *ptr=p;
113 return true;
114 }
115 else return false;
116 }//malloc
117 else {//realloc
118 void *p=realloc(*ptr,size);
119 if (p) {
120 *ptr=p;
121 return true;
122 }
123 return false;
124 }
125 }
126 // Free memory, resets ptr to NULL afterward
127 void GFree(pointer* ptr){
128 GASSERT(ptr);
129 if (*ptr) free(*ptr);
130 *ptr=NULL;
131 }
132
133 char* Gstrdup(const char* str) {
134 if (str==NULL) return NULL;
135 char *copy=NULL;
136 GMALLOC(copy, strlen(str)+1);
137 strcpy(copy,str);
138 return copy;
139 }
140
141 char* newEmptyStr() {
142 char* zs=NULL;
143 GMALLOC(zs,1);
144 zs[0]=0;
145 return zs;
146 }
147
148 char* Gstrdup(const char* sfrom, const char* sto) {
149 if (sfrom==NULL || sto==NULL) return NULL;
150 char *copy=NULL;
151 if (sfrom[0]==0) return newEmptyStr();
152 GMALLOC(copy, sto-sfrom+2);
153 strncpy(copy, sfrom, sto-sfrom+1);
154 copy[sto-sfrom+1]=0;
155 return copy;
156 }
157
158 int Gstrcmp(char* a, char* b) {
159 if (a==NULL || b==NULL) {
160 return a==NULL ? -1 : 1;
161 }
162 else return strcmp(a,b);
163 }
164
165 int Gstricmp(const char* a, const char* b) {
166 if (a==NULL || b==NULL) return a==NULL ? -1 : 1;
167 register int ua, ub;
168 while ((*a!=0) && (*b!=0)) {
169 ua=tolower((unsigned char)*a);
170 ub=tolower((unsigned char)*b);
171 a++;b++;
172 if (ua!=ub) return ua < ub ? -1 : 1;
173 }
174 return (*a == 0) ? ( (*b == 0) ? 0 : -1 ) : 1 ;
175 }
176
177 int strsplit(char* str, char** fields, int maxfields, const char* delim) {
178 //splits by placing 0 where delim chars are found, setting fields[] to the beginning
179 //of each field (stopping after maxfields); returns number of fields parsed
180 int tidx=0;
181 bool afterdelim=true;
182 int i=0;
183 while (str[i]!=0 && tidx<maxfields) {
184 if (afterdelim) {
185 fields[tidx]=str+i;
186 tidx++;
187 }
188 afterdelim=false;
189 if (chrInStr(str[i],(char*)delim)) {
190 str[i]=0;
191 i++;
192 while (str[i]!=0 && chrInStr(str[i], (char*)delim)) i++;
193 afterdelim=true;
194 continue;
195 }
196 i++;
197 }
198 return tidx;
199 }
200
201 int strsplit(char* str, char** fields, int maxfields, const char delim) {
202 //splits by placing 0 where delim is found, setting fields[] to the beginning
203 //of each field (stopping after maxfields); returns number of fields parsed
204 int tidx=0;
205 bool afterdelim=true;
206 int i=0;
207 while (str[i]!=0 && tidx<maxfields) {
208 if (afterdelim) {
209 fields[tidx]=str+i;
210 tidx++;
211 }
212 afterdelim=false;
213 if (str[i]==delim) {
214 str[i]=0;
215 i++;
216 while (str[i]!=0 && str[i]==delim) i++;
217 afterdelim=true;
218 continue;
219 }
220 i++;
221 }
222 return tidx;
223 }
224
225 int strsplit(char* str, char** fields, int maxfields) {
226 //splits by placing 0 where delim is found, setting fields[] to the beginning
227 //of each field (stopping after maxfields); returns number of fields parsed
228 int tidx=0;
229 bool afterdelim=true;
230 int i=0;
231 while (str[i]!=0 && tidx<maxfields) {
232 if (afterdelim) {
233 fields[tidx]=str+i;
234 tidx++;
235 }
236 afterdelim=false;
237 if (str[i]==' ' || str[i]=='\t') {
238 str[i]=0;
239 i++;
240 while (str[i]!=0 && (str[i]=='\t' || str[i]==' ')) i++;
241 afterdelim=true;
242 continue;
243 }
244 i++;
245 }
246 return tidx;
247 }
248
249
250 char* Gsubstr(const char* str, char* from, char* to) {
251 //extract (and allocate) a substring, including boundaries (from/to)
252 if (str==NULL || from==NULL) return NULL;
253 if (from[0]==0 || str[0]==0) return newEmptyStr();
254 if (from<str) return NULL;
255 if (to==NULL) {
256 to=from;
257 while (to[1]) to++;
258 }
259 if (to<from) return newEmptyStr();
260 int newlen=to-from+1;
261 char* subs;
262 GMALLOC(subs, newlen);
263 memcpy(subs, str, newlen-1);
264 subs[newlen]='\0';
265 return subs;
266 }
267
268 char* replaceStr(char* &str, char* newvalue) {
269 if (str!=NULL) GFREE(str);
270 if (newvalue==NULL) { return NULL; }
271 GMALLOC(str, strlen(newvalue)+1);
272 strcpy(str,newvalue);
273 return str;
274 }
275
276 void* Gmemscan(void *mem, unsigned int len,
277 void *part, unsigned int partlen) {
278 char* p;
279 unsigned int restlen=len-partlen+1;
280 void* oldp=mem;
281 while ( (p=(char*)memchr(oldp, ((char*)part)[0], restlen))!=NULL) {
282 //located first char, try to match the rest:
283 p++;
284 if (memcmp(p, &((char*)part)[1], partlen-1)==0) return p-1;
285 //no string match, prepare next iteration
286 restlen-=(p-(char*)oldp);
287 oldp=p;
288 }//while
289 return NULL;
290 }
291
292 //rindex function is missing on some platforms ?
293 char* rstrchr(char* str, char ch) { /* returns a pointer to the rightmost
294 occurence of ch in str */
295 char *p;
296 if (str==NULL) return NULL;
297 p=str+strlen(str)-1;
298 while (p>=str) {
299 if (*p==ch) return p;
300 p--;
301 }
302 return NULL;
303 }
304
305
306 /* DOS/UNIX safer fgets : reads a text line from a (binary) file and
307 update the file position accordingly and the buffer capacity accordingly.
308 The given buf is resized to read the entire line in memory
309 -- even when it's abnormally long
310 */
311 char* fgetline(char* & buf, int& buf_cap, FILE *stream, off_t* f_pos, int* linelen) {
312 //reads a char at a time until \n and/or \r are encountered
313 int i=0;
314 int c=0;
315 off_t fpos=(f_pos!=NULL) ? *f_pos : 0;
316 while ((c=getc(stream))!=EOF) {
317 if (i>=buf_cap-1) {
318 buf_cap+=1024;
319 GREALLOC(buf, buf_cap);
320 }
321 if (c=='\n' || c=='\r') {
322 if (c=='\r') {
323 if ((c=getc(stream))!='\n') ungetc(c,stream);
324 else fpos++;
325 }
326 fpos++;
327 break;
328 }
329 fpos++;
330 buf[i]=(char)c;
331 i++;
332 } //while i<buf_cap-1
333 if (linelen!=NULL) *linelen=i;
334 if (f_pos!=NULL) *f_pos=fpos;
335 if (c==EOF && i==0) return NULL;
336 buf[i]='\0';
337 return buf;
338 }
339
340 char* GLineReader::getLine(FILE* stream, off_t& f_pos) {
341 if (pushed) { pushed=false; return buf; }
342 //reads a char at a time until \n and/or \r are encountered
343 len=0;
344 int c=0;
345 while ((c=getc(stream))!=EOF) {
346 if (len>=allocated-1) {
347 allocated+=1024;
348 GREALLOC(buf, allocated);
349 }
350 if (c=='\n' || c=='\r') {
351 buf[len]='\0';
352 if (c=='\r') { //DOS file -- special case
353 if ((c=getc(stream))!='\n') ungetc(c,stream);
354 else f_pos++;
355 }
356 f_pos++;
357 lcount++;
358 return buf;
359 }
360 f_pos++;
361 buf[len]=(char)c;
362 len++;
363 } //while i<buf_cap-1
364 if (c==EOF) {
365 isEOF=true;
366 if (len==0) return NULL;
367 }
368 buf[len]='\0';
369 lcount++;
370 return buf;
371 }
372
373
374 //strchr but with a set of chars instead of only one
375 char* strchrs(const char* s, const char* chrs) {
376 if (s==NULL || chrs==NULL || *chrs=='\0' || *s=='\0')
377 return NULL;
378 unsigned int l=strlen(s);
379 unsigned int r=strcspn(s, chrs);
380 if (r==l) return NULL;
381 return ((char*)s+r);
382 }
383
384 char* upCase(const char* str) {
385 if (str==NULL) return NULL;
386 int len=strlen(str);
387 char* upstr;
388 GMALLOC(upstr, len+1);
389 upstr[len]='\0';
390 for (int i=0;i<len;i++) upstr[i]=toupper(str[i]);
391 return upstr;
392 }
393
394 char* loCase(const char* str) {
395 if (str==NULL) return NULL;
396 int len=strlen(str);
397 char* lostr;
398 GMALLOC(lostr, len+1);
399 lostr[len]='\0';
400 for (int i=0;i<len;i++) lostr[i]=tolower(str[i]);
401 return lostr;
402 }
403
404 char* strlower(char * str) {//changes string in place
405 if (str==NULL) return NULL;
406 int i=0;
407 while (str[i]!=0) { str[i]=tolower(str[i]); i++; }
408 return str;
409 }
410
411 char* strupper(char * str) {//changes string in place
412 if (str==NULL) return NULL;
413 int i=0;
414 while (str[i]!=0) { str[i]=toupper(str[i]); i++; }
415 return str;
416 }
417
418
419
420 //test if a char is in a given string (set)
421 bool chrInStr(char c, const char* str) {
422 if (str==NULL || *str=='\0') return false;
423 for (const char* p=str; (*p)!='\0'; p++) {
424 if ((*p)==c) return true;
425 }
426 return false;
427 }
428
429
430
431 char* rstrfind(const char* str, const char* substr) {
432 /* like rindex() for a string */
433 int l,i;
434 if (str==NULL || *str=='\0') return NULL;
435 if (substr==NULL || *substr=='\0') return NULL;
436 l=strlen(substr);
437 char* p=(char*)str+strlen(str)-l;
438 //rightmost position that could match
439
440 while (p>=str) {
441 for (i=0; i<l && *(p+i) == *(substr+i); i++) ;
442 if (i==l) return p; //found!
443 p--;
444 }
445 return NULL;
446 }
447
448
449 char* strifind(const char* str, const char* substr) {
450 // the case insensitive version of strstr -- finding a string within a strin
451 int l,i;
452 if (str==NULL || *str==0) return NULL;
453 if (substr==NULL || *substr==0) return NULL;
454 l=strlen(substr);
455 char* smax=(char*)str+strlen(str)-l;
456 //rightmost position that could match
457 char* p=(char*)str;
458 while (p<=smax) {
459 for (i=0; i<l && tolower(*(p+i))==tolower(*(substr+i)); i++) ;
460 if (i==l) return p; //found!
461 p++;
462 }
463 return NULL;
464 }
465
466
467
468 // tests if string s has the given prefix
469 bool startsWith(const char* s, const char* prefix) {
470 if (prefix==NULL || s==NULL) return false;
471 int i=0;
472 while (prefix[i]!='\0' && prefix[i]==s[i]) i++;
473 return (prefix[i]=='\0');
474 }
475
476 // tests if string s ends with given suffix
477 bool endsWith(const char* s, const char* suffix) {
478 if (suffix==NULL || s==NULL) return false;
479 if (suffix[0]==0) return true; //special case: empty suffix
480 int j=strlen(suffix)-1;
481 int i=strlen(s)-1;
482 if (i<j) return false;
483 while (j>=0 && s[i]==suffix[j]) { i--; j--; }
484 return (j==-1);
485 }
486
487
488 char* reverseChars(char* str, int slen) {
489 if (slen==0) slen=strlen(str);
490 int l=0;
491 int r=slen-1;
492 register char c;
493 while (l<r) {
494 c=str[l];str[l]=str[r];
495 str[r]=c;
496 //swap(str[l],str[r]);
497 l++;r--;
498 }
499 return str;
500 }
501
502
503 char* rstrstr(const char* rstart, const char *lend, const char* substr) { /*like strstr, but starts searching
504 from right end, going up to lend and returns a pointer to the last (right)
505 matching character in str */
506 char *p;
507 int l,i;
508 l=strlen(substr);
509 p=(char*)rstart-l+1;
510 while (p>=lend) {
511 for (i=0;i<l;i++) if (*(p+i) != *(substr+i)) break;
512 if (i==l) return p+l-1;
513 p--;
514 }
515 return NULL;
516 }
517
518
519 //hash function used for strings in GHash
520 int strhash(const char* str){
521 register int h=0;
522 register int g;
523 while (*str) {
524 h=(h<<4)+*str++;
525 g=h&0xF0000000;
526 if(g) h^=g>>24;
527 h&=0x0fffffff;
528 }
529 GASSERT(h<=0x0fffffff);
530 return h;
531 }
532
533 // removes the last part (file or directory name) of a full path
534 // this is a destructive operation for the given string!!!
535 // the trailing '/' is guaranteed to be there
536 void delFileName(char* filepath) {
537 char *p, *sep;
538 if (filepath==NULL) return;
539 for (p=filepath, sep=filepath;*p!='\0';p++)
540 if (*p=='/' || *p=='\\') sep=p+1;
541 *sep='\0'; // truncate filepath
542 }
543
544 // returns a pointer to the last file or directory name in a full path
545 const char* getFileName(const char* filepath) {
546 const char *p, *sep;
547 if (filepath==NULL) return NULL;
548 for (p=filepath, sep=filepath;*p!='\0';p++)
549 if (*p=='/' || *p=='\\') sep=p+1;
550 return sep;
551 }
552
553 // returns a pointer to the file "extension" part in a filename
554 const char* getFileExt(const char* filepath) {
555 const char *p, *dp, *sep;
556 if (filepath==NULL) return NULL;
557 for (p=filepath, dp=filepath, sep=filepath;*p!='\0';p++) {
558 if (*p=='.') dp=p+1;
559 else if (*p=='/' || *p=='\\')
560 sep=p+1;
561 }
562 return (dp>sep) ? dp : NULL ;
563 }
564
565 int fileExists(const char* fname) {
566 struct stat stFileInfo;
567 int r=0;
568 // Attempt to get the file attributes
569 int fs = stat(fname,&stFileInfo);
570 if (fs == 0) {
571 r=3;
572 // We were able to get the file attributes
573 // so the file obviously exists.
574 if (S_ISREG (stFileInfo.st_mode)) {
575 r=2;
576 }
577 if (S_ISDIR (stFileInfo.st_mode)) {
578 r=1;
579 }
580 }
581 return r;
582 }
583
584 /*bool fileExists(const char* filepath) {
585 if (filepath==NULL) return false;
586 FILE* ft=fopen(filepath, "rb");
587 if (ft==NULL) return false;
588 fclose(ft);
589 return true;
590 }
591 */
592 int64 fileSize(const char* fpath) {
593 struct stat results;
594 if (stat(fpath, &results) == 0)
595 // The size of the file in bytes is in
596 return (int64)results.st_size;
597 else
598 // An error occurred
599 //GMessage("Error at stat(%s)!\n", fpath);
600 return 0;
601 }
602
603 bool parseNumber(char* &p, double& v) {
604 //skip any spaces..
605 while (*p==' ' || *p=='\t') p++;
606 char* start=p;
607 /*if (*p=='-') p++;
608 else if (*p=='+') { p++;start++; }*/
609
610 /* while ((*p>='1' && *p<='9') || *p=='0' ||
611 *p=='.' || *p=='-' || tolower(*p)=='e') p++; */
612 int numlen=strspn(start, "0123456789eE.-+");
613 p=start+numlen;
614 //now p is on a non-digit;
615 if (*start=='-' && p==start+1) return false;
616 char saved=*p;
617 *p='\0';
618 char* endptr=p;
619 v=strtod(start,&endptr);
620 *p=saved;
621 if (endptr!=p) return false;
622 return true;
623 }
624
625
626 bool parseDouble(char* &p, double& v) {
627 return parseNumber(p,v);
628 }
629
630 bool parseInt(char* &p, int& i) {
631 while (*p==' ' || *p=='\t') p++;
632 char* start=p;
633 if (*p=='-') p++;
634 else if (*p=='+') { p++;start++; }
635 while ((*p>='1' && *p<='9') || *p=='0') p++;
636 //now p is on a non-digit;
637 if (*start=='-' && p==start+1) return false;
638 char saved=*p;
639 *p='\0';
640 char* endptr=p;
641 long l=strtol(start,&endptr,10);
642 i=(int)l;
643 *p=saved;
644 if (endptr!=p || i!=l) return false;
645 return true;
646 }
647
648 bool parseUInt(char* &p, uint& i) {
649 while (*p==' ' || *p=='\t') p++;
650 char* start=p;
651 if (*p=='-') return false;
652 else if (*p=='+') { p++;start++; }
653 while ((*p>='1' && *p<='9') || *p=='0') p++;
654 //now p is on a non-digit;
655 if (*start=='-' && p==start+1) return false;
656 char saved=*p;
657 *p='\0';
658 char* endptr=p;
659 unsigned long l=strtoul(start,&endptr,10);
660 i=(uint) l;
661 *p=saved;
662 if (endptr!=p || i!=l) return false;
663 return true;
664 }
665
666 bool parseHex(char* &p, uint& i) {
667 //skip initial spaces/prefix
668 while (*p==' ' || *p=='\t' || *p=='0' || *p=='x') p++;
669 char* start=p;
670 if (*p=='-') return false;
671 else if (*p=='+') { p++;start++; }
672 while (isxdigit(*p)) p++;
673 //now p is on a non-hexdigit;
674 if (p==start+1) return false;
675 char saved=*p;
676 *p='\0';
677 char* endptr=p;
678 unsigned long l=strtoul(start,&endptr,16);
679 i=(uint) l;
680 *p=saved;
681 if (endptr!=p || i!=l) return false;
682 return true;
683 }
684
685 //write a formatted fasta record, fasta formatted
686 void writeFasta(FILE *fw, const char* seqid, const char* descr,
687 const char* seq, int linelen, int seqlen) {
688 fflush(fw);
689 // write header line only if given!
690 if (seqid!=NULL) {
691 if (descr==NULL || descr[0]==0)
692 fprintf(fw,">%s\n",seqid);
693 else fprintf(fw,">%s %s\n",seqid, descr);
694 }
695 fflush(fw);
696 if (seq==NULL || *seq==0) return; //nothing to print
697 if (linelen==0) { //unlimited line length: write the whole sequence on a line
698 if (seqlen>0)
699 fwrite((const void*)seq, 1, seqlen,fw);
700 else fprintf(fw,"%s",seq);
701 fprintf(fw,"\n");
702 fflush(fw);
703 return;
704 }
705 int ilen=0;
706 if (seqlen>0) { //seq length given, so we know when to stop
707 for (int i=0; i < seqlen; i++, ilen++) {
708 if (ilen == linelen) {
709 fputc('\n', fw);
710 ilen = 0;
711 }
712 fputc(seq[i], fw);
713 }
714 fputc('\n', fw);
715 }
716 else { //seq length not given, stop when 0 encountered
717 for (int i=0; seq[i]!=0; i++, ilen++) {
718 if (ilen == linelen) {
719 fputc('\n', fw);
720 ilen = 0;
721 }
722 fputc(seq[i], fw);
723 } //for
724 fputc('\n', fw);
725 }
726 fflush(fw);
727 }
728
729 char* commaprint(uint64 n) {
730 static int comma = '\0';
731 static char retbuf[48];
732 char *p = &retbuf[sizeof(retbuf)-1];
733 int i = 0;
734 if(comma == '\0') {
735 /* struct lconv *lcp = localeconv();
736 if(lcp != NULL) {
737 if(lcp->thousands_sep != NULL &&
738 *lcp->thousands_sep != '\0')
739 comma = *lcp->thousands_sep;
740 else */
741 comma = ',';
742 // }
743 }
744 *p = '\0';
745 do {
746 if(i%3 == 0 && i != 0)
747 *--p = comma;
748 *--p = '0' + n % 10;
749 n /= 10;
750 i++;
751 } while(n != 0);
752 return p;
753 }