ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/gclib/gclib/GBase.cpp
Revision: 41
Committed: Sat Aug 27 16:58:00 2011 UTC (8 years, 2 months ago) by gpertea
File size: 18327 byte(s)
Log Message:
added fix for fileExists() under MSVC

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