ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/gclib/gclib/GBase.cpp
Revision: 2
Committed: Mon Mar 22 22:03:27 2010 UTC (9 years, 5 months ago) by gpertea
File size: 14900 byte(s)
Log Message:
added my gclib source files

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