00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00020 #include<ImLib3D/CppTools.hpp>
00021 #include <unistd.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <stdexcept>
00025 #include <map>
00026 #include <errno.h>
00027 #include <iterator>
00028 void FatalError(const string &message="");
00029
00030
00031
00032
00033
00034
00036
00037 string
00038 TypeNameParser(string typeName)
00039 {
00040 static map<string,string> typeNameCache;
00041
00042 if(typeNameCache.find(typeName)==typeNameCache.end())
00043 {
00044 printf("TypeNameParser:: trying to guess typename for :\"%s\", this may be unreliable, or unportable\n",typeName.c_str());
00045 string demangled=typeName;
00046 #if __GNUC__==2
00047
00048
00049
00050 string fakeFct="FakeFct";
00051 string todemangle=fakeFct+"__G"+typeName;
00052 printf("demangle_typename gcc2:%s\n",todemangle.c_str());
00053 string demangleRes=Command("c++filt "+todemangle);
00054 if(demangleRes!=todemangle)
00055 {
00056 string tmp=demangleRes.substr(fakeFct.size()+1);
00057 demangled=tmp.substr(0,tmp.size()-2);
00058 }
00059 printf("demangled:%s\n",demangled.c_str());
00060 #elif __GNUC__>=3// __GNUC__
00061
00062
00063
00064 string fakeFct="_ZTI";
00065 string todemangle=fakeFct+typeName;
00066 printf("demangle_typename gcc3:%s\n",todemangle.c_str());
00067 string demangleRes=Command("c++filt "+todemangle);
00068 if(demangleRes!=todemangle)
00069 {
00070 if(demangleRes.size()<strlen("typeinfo for ")+1)
00071 {
00072 ThrowError("TypeNameParser demangle failed");
00073 }
00074 demangled=demangleRes.substr(strlen("typeinfo for "));
00075 demangled=demangled.substr(0,demangled.size()-1);
00076 }
00077 printf("demangled:%s\n",demangled.c_str());
00078 #else // __GNUC__
00079 ThrowError("TypeNameParser does supports only gcc2 or gcc3 compilers");
00080 #endif // __GNUC__
00081 typeNameCache[typeName]=demangled;
00082 }
00083 return typeNameCache[typeName];
00084 }
00085
00086
00087
00088
00089
00090 ErrorManagementType errorManagementType(ERROR_USE_EXCEPTIONS);
00091 void (*ErrorHandler)(string)=NULL;
00092 void
00093 SetErrorManagementType(ErrorManagementType _errorManagementType,void(*_ErrorHandler)(string))
00094 {
00095 errorManagementType=_errorManagementType;
00096 ErrorHandler=_ErrorHandler;
00097 }
00098
00100 void
00101 FatalError(const string &message)
00102 {
00103 if(errorManagementType==ERROR_USE_EXCEPTIONS)
00104 {
00105 fprintf(stderr,"FatalError throwing exception:\"%s\"\n",message.c_str());
00106 throw runtime_error(message);
00107 }
00108 else
00109 if(errorManagementType==ERROR_CALL_HANDLER)
00110 {
00111 if(!ErrorHandler)
00112 {
00113 fprintf(stderr,"FatalError: error while processing error: ERROR_CALL_HANDLER requested, but handler is NULL: aborting");
00114 exit(1);
00115 }
00116
00117 (*ErrorHandler)(message);
00118 fprintf(stderr,"FatalError: error while processing error: error handler returned after error processing, this is not allowed. Error handler function should NEVER return: aborting");
00119 exit(1);
00120 }
00121 else
00122 {
00123 fprintf(stderr,"%s\n",message.c_str());
00124 fprintf(stderr,"Aborting with segfault:");
00125 (*((char *)(NULL)))=0;
00126 }
00127
00128 fprintf(stderr,"FatalError: error while processing error: something very strange is happening: aborting");
00129 exit(1);
00130 }
00131
00132 void
00133 ThrowErrorVA(const char *fmt, ...)
00134 {
00135 va_list args;
00136 va_start(args,fmt);
00137 fflush(stdout);
00138 if(!fmt)
00139 {
00140 fprintf(stderr,"ThrowError: error while processing error: no error information\n");
00141 FatalError();
00142 }
00143
00144 char tempString[1000];
00145 #ifdef HPUX
00146 vsprintf(tempString,fmt,args);
00147 #else//HPUX
00148 vsnprintf(tempString,1000,fmt,args);
00149 #endif//HPUX
00150 string message="FATAL ERROR:";
00151 message+=tempString;
00152 va_end(args);
00153
00154 FatalError(message);
00155 }
00156
00157
00158
00159
00160 int globalVerbose=1;
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 vector<string> Strings(string s1,string s2,string s3,string s4,string s5,string s6,string s7,string s8,string s9,string s10)
00174 {string s[]={s1,s2,s3,s4,s5,s6,s7,s8,s9,s10};vector<string> v;v.insert(v.end(),s,s+10);return v;}
00175 vector<string> Strings(string s1,string s2,string s3,string s4,string s5,string s6,string s7,string s8,string s9)
00176 {string s[]={s1,s2,s3,s4,s5,s6,s7,s8,s9};vector<string> v;v.insert(v.end(),s,s+9);return v;}
00177 vector<string> Strings(string s1,string s2,string s3,string s4,string s5,string s6,string s7,string s8)
00178 {string s[]={s1,s2,s3,s4,s5,s6,s7,s8};vector<string> v;v.insert(v.end(),s,s+8);return v;}
00179 vector<string> Strings(string s1,string s2,string s3,string s4,string s5,string s6,string s7)
00180 {string s[]={s1,s2,s3,s4,s5,s6,s7};vector<string> v;v.insert(v.end(),s,s+7);return v;}
00181 vector<string> Strings(string s1,string s2,string s3,string s4,string s5,string s6)
00182 {string s[]={s1,s2,s3,s4,s5,s6};vector<string> v;v.insert(v.end(),s,s+6);return v;}
00183 vector<string> Strings(string s1,string s2,string s3,string s4,string s5)
00184 {string s[]={s1,s2,s3,s4,s5};vector<string> v;v.insert(v.end(),s,s+5);return v;}
00185 vector<string> Strings(string s1,string s2,string s3,string s4)
00186 {string s[]={s1,s2,s3,s4};vector<string> v;v.insert(v.end(),s,s+4);return v;}
00187 vector<string> Strings(string s1,string s2,string s3)
00188 {string s[]={s1,s2,s3};vector<string> v;v.insert(v.end(),s,s+3);return v;}
00189 vector<string> Strings(string s1,string s2)
00190 {string s[]={s1,s2};vector<string> v;v.insert(v.end(),s,s+2);return v;}
00191 vector<string> Strings(string s1)
00192 {string s[]={s1};vector<string> v;v.insert(v.end(),s,s+1);return v;}
00193 vector<string> Strings()
00194 {vector<string> v;return v;}
00195
00197 string
00198 SPrintfVA(const char *fmt, ...)
00199 {
00200 va_list args;
00201 va_start(args,fmt);
00202 if(!fmt){ThrowError("SPrintf: format string null\n");}
00203 char tempString[1000];
00204 #ifdef HPUX
00205 vsprintf(tempString,fmt,args);
00206 #else//HPUX
00207 if(vsnprintf(tempString,1000,fmt,args)<0)
00208 {
00209 ThrowError("SPrintf: string too long \n");
00210 }
00211 #endif//HPUX
00212 va_end(args);
00213 return(tempString);
00214 }
00215
00216
00218 bool
00219 FileIsMoreRecent(const string &filename1,const string &filename2)
00220 {
00221 struct stat s1,s2;
00222 stat(filename1.c_str(),&s1);
00223 stat(filename2.c_str(),&s2);
00224 return s1.st_mtime > s2.st_mtime;
00225 }
00226
00228 bool IsSameFile(string filename1,string filename2)
00229 {
00230 if(filename1==filename2){return true;}
00231 struct stat stat1;
00232 struct stat stat2;
00233 stat(filename1.c_str(), &stat1);
00234 stat(filename2.c_str(), &stat2);
00235 return stat1.st_ino==stat2.st_ino;
00236 }
00237
00238
00240 string
00241 WriteTmpFile(const string &data)
00242 {
00243 static bool init=false;
00244 static string tmpdir;
00245 if(!init)
00246 {
00247 tmpdir=(getenv("IMLIB3D_TMP") ? getenv("IMLIB3D_TMP") : "/tmp");
00248
00249 struct stat stats;
00250 stat(tmpdir.c_str(),&stats);
00251 if(!S_ISDIR(stats.st_mode))
00252 {
00253 ThrowError("WriteTmpFile: invalid temporary directory \"%s\"",tmpdir);
00254 }
00255 }
00256 string fnametemplate=tmpdir+"/imlib3d.XXXXXX";
00257 char *sfn=strdup(fnametemplate.c_str());
00258 FILE *F;
00259 int fd = -1;
00260
00261 if ((fd = mkstemp(sfn)) == -1 || (F = fdopen(fd, "w+")) == NULL)
00262 {
00263 if (fd != -1)
00264 {
00265 unlink(sfn);
00266 close(fd);
00267 }
00268 ThrowError("WriteTmpFile: %s: %s\n", sfn, strerror(errno));
00269 }
00270 fnametemplate=sfn;
00271 free(sfn);
00272 fwrite((void *)data.c_str(),data.length(),1,F);
00273 fclose(F);
00274 return fnametemplate;
00275 }
00277 void
00278 WriteStringToFile(const string& fname,const string& data)
00279 {
00280 FILE *F=fopen(fname.c_str(),"w");
00281 if(!F){ThrowError("WriteStringToFile failed:%s",fname);}
00282 fwrite((void *)data.c_str(),data.length(),1,F);
00283 fclose(F);
00284 }
00285
00287 void
00288 RemoveFile(string fname)
00289 {
00290 remove(fname.c_str());
00291 }
00292
00293
00294 void
00295 RemoveFiles(const vector<string>& fnames)
00296 {
00297 vector<string>::const_iterator p;
00298 for (p=fnames.begin(); p!=fnames.end(); p++)
00299 RemoveFile(*p);
00300 }
00301
00302
00304 int
00305 Split( const string &s, char c, vector<string> &res)
00306 {
00307 res.clear();
00308 if(s==""){return 0;}
00309 uint i;
00310 uint pos=0;
00311 for( i=0; i<=s.size(); i++)
00312 {
00313 if( i == s.size() || s[i] == c )
00314 {
00315 uint j;
00316 string tmps;
00317 for( j=pos; j<i; j++)
00318 {
00319 tmps += s[j];
00320 }
00321 res.push_back(tmps);
00322 pos=i+1;
00323 }
00324 }
00325 return res.size();
00326 }
00327
00329 int
00330 Split( const string &s, const string &sep, vector<string> &res)
00331 {
00332 res.clear();
00333 uint pos=0;
00334 uint lpos=0;
00335 do
00336 {
00337 pos=s.find(sep,lpos);
00338 if(pos==s.npos){pos=s.size();}
00339 string tmps;
00340 tmps.assign(s.begin()+lpos,s.begin()+pos);
00341 res.push_back(tmps);
00342 lpos=pos+sep.size();
00343 }
00344 while(pos<s.size());
00345
00346 return res.size();
00347 }
00348
00349
00350
00352
00354 void
00355 Replace(string &res,const string & s1,const string & s2)
00356 {
00357 uint pos;
00358 while( (pos=res.find(s1)) != res.npos)
00359 {
00360 res.replace(pos,s1.size(),s2);
00361 }
00362 }
00363
00365 int
00366 FileSize(const string& fname)
00367 {
00368 FILE *F=fopen(fname.c_str(),"r");
00369 if(!F)
00370 {
00371 return -1;
00372 }
00373 fseek(F,0,SEEK_END);
00374 int sz=ftell(F);
00375 fclose(F);
00376 return sz;
00377 }
00378
00380 void
00381 AppendToFile(const string& fname,const string &data)
00382 {
00383 FILE *F=fopen(fname.c_str(),"a+");
00384 if(!F)
00385 {
00386 ThrowError("AppendToFile:: failed opening file:\"%s\"",fname);
00387 }
00388 fwrite((void *)data.c_str(),data.length(),1,F);
00389 fclose(F);
00390 }
00391
00392 string FindFileInPath(const string &path,const string &fname)
00393 {
00394 vector<string> pathv;
00395 Split(path, ':', pathv);
00396 return FindFileInPath(pathv,fname);
00397 }
00398 string FindFileInPath(const vector<string> &path,const string &fname)
00399 {
00400 for(uint i=0;i<path.size();i++)
00401 {
00402 string fullName=path[i]+"/"+fname;
00403 if(FileExists(fullName)){return fullName;}
00404 }
00405 return "";
00406 }
00407
00408 string
00409 Command(const string &cmd)
00410 {
00411 string tmp=WriteTmpFile(SPrintf("Command:(%s)empty",cmd));
00412 string call=cmd+" >" +tmp;
00413 errno=0;
00414 int ret=system(call.c_str());
00415 if(ret==-1 && errno!=0)
00416 {
00417 ThrowError("Command: executing command:\"%s\" failed:%s\n",call,strerror(errno));
00418 }
00419 if(ret!=0)
00420 {
00421 ThrowError("Command: command:\"%s\" failed (return value: %d)\n",call,ret);
00422 }
00423 string res;
00424 if(!FileExists(tmp)){ThrowError("Command: while executing:\"%s\", result file not created",cmd);}
00425 Read(tmp,res);
00426 RemoveFile(tmp);
00427 return res;
00428 }
00429
00430
00432 int
00433 Read(const string& fname,string& res,bool fail)
00434 {
00435 FILE *F=fopen(fname.c_str(),"r");
00436 if(!F)
00437 {
00438 if(!fail) {res="";return 0;}
00439 ThrowError("Read: (into string) read file failed for file: \"%s\" ",fname);
00440 }
00441 fseek(F,0,SEEK_END);
00442 int sz=ftell(F);
00443 fseek(F,0,SEEK_SET);
00444 char *s=new char[sz+1];
00445 fread(s,sz,1,F);
00446 fclose(F);
00447 s[sz]=0;
00448 res=s;
00449 delete [] s;
00450
00451
00452
00453 return 1;
00454 }
00456 void *
00457 Read(const string& fname,int *rsize,bool fail)
00458 {
00459 int size0;
00460 int *psize=(rsize ? rsize : &size0);
00461 int &size=*psize;
00462 size=0;
00463 FILE *F=fopen(fname.c_str(),"r");
00464 if(!F)
00465 {
00466 if(!fail) {return NULL;}
00467 ThrowError("Read: (into void*) read file failed for file: \"%s\"",fname);
00468 }
00469 fseek(F,0,SEEK_END);
00470 size=ftell(F);
00471 fseek(F,0,SEEK_SET);
00472 void *res=(void *)(new char[size]);
00473 fread(res,size,1,F);
00474 fclose(F);
00475 return res;
00476 }
00478 void
00479 Write(const string& fname,void *data,int size,bool fail)
00480 {
00481 FILE *F=fopen(fname.c_str(),"w");
00482 if(!F)
00483 {
00484 if(!fail) {return;}
00485 ThrowError("Write file failed : %s",fname);
00486 }
00487 fwrite(data,size,1,F);
00488 fclose(F);
00489 }
00490
00492
00495 string FilenameExtension(const string& fname)
00496 {
00497 vector<string> parts;
00498 Split(fname, '.', parts);
00499 if (parts.size()==1){return "";}
00500 else
00501 {return parts.back();}
00502 }
00503
00505 string FilenamePath(const string& fname)
00506 {
00507 vector<string> parts;
00508 string rstring;
00509 int n = Split(fname, '/', parts);
00510 if (n==1){
00511 return "";
00512 }
00513 else{
00514 for (int i=0; i<n-1; i++)
00515 rstring += parts[i] + "/";
00516 return rstring;
00517 }
00518 }
00519
00521 string FilenameBasename(const string& fname)
00522 {
00523 vector<string> parts;
00524 string rstring;
00525 int n = Split(fname, '/', parts);
00526 return parts[n-1];
00527 }
00528
00530
00535 ostream& operator<< (ostream& out, const vector<string>& v)
00536 {
00537
00538 copy(v.begin(), v.end(), ostream_iterator<string>(out,"\n"));
00539 return out;
00540 }
00541
00543
00550 string Chop(const string&s, char c)
00551 {
00552 vector<string> list;
00553 int n=Split(s, c, list);
00554 string temp = "";
00555 for (int i=0; i<n-1; i++)
00556 {
00557 temp += list[i];
00558 temp += c;
00559 }
00560 return temp;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569 void
00570 GnuPlot(const vector<double> &x,const vector<double> &y,const string &xlabel,const string &ylabel)
00571 {
00572 string plotFile;
00573 string plotData;
00574 for(uint i=0;i<x.size();i++)
00575 {
00576 plotData+=SPrintf("%20.20f %20.20f \n",x[i],y[i]);
00577 }
00578
00579 string dataFname=WriteTmpFile(plotData);
00580 plotFile+="set encoding iso_8859_1\n";
00581 if(xlabel!=""){plotFile+="set xlabel \""+xlabel+"\"\n";}
00582 if(ylabel!=""){plotFile+="set ylabel \""+ylabel+"\"\n";}
00583 plotFile+="plot '"+dataFname+"' with lines\n"+"pause 1000\n";
00584 string plotFname=WriteTmpFile(plotFile);
00585 string cmd=SPrintf("gnuplot %s &",plotFname);
00586 system(cmd.c_str());
00587 usleep(1000000);
00588
00589
00590 }
00591 void
00592 GnuPlot(const vector<double> &y,const string &ylabel)
00593 {
00594 vector<double> x;
00595 for(uint i=0;i<y.size();i++){x.push_back(i);}
00596 GnuPlot(x,y,"",ylabel);
00597 }
00598 void
00599 GnuPlot(const vector<float> &x0,const vector<float> &y0,const string &xlabel,const string &ylabel)
00600 {
00601 vector<double> x;x.insert(x.end(),x0.begin(),x0.end());
00602 vector<double> y;y.insert(y.end(),y0.begin(),y0.end());
00603 GnuPlot(x,y,xlabel,ylabel);
00604 }
00605 void
00606 GnuPlot(const vector<float> &y0,const string &ylabel)
00607 {
00608 vector<double> y;y.insert(y.end(),y0.begin(),y0.end());
00609 GnuPlot(y,ylabel);
00610 }
00611
00612
00613
00614
00615 #ifdef __CYGWIN__
00616 extern "C"
00617 {
00618 double drand48()
00619 {
00620 return((random()%1000000)/1000000.0);
00621 }
00622 }
00623 #endif // __CYGWIN__
00624