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, 7 months ago) by gpertea
File size: 14900 byte(s)
Log Message:
added my gclib source files

Line File contents
1 #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 }