ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/gclib/gclib/GBase.cpp
Revision: 310
Committed: Fri Mar 22 20:06:27 2013 UTC (6 years, 2 months ago) by gpertea
File size: 18737 byte(s)
Log Message:
sync with igm repo

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