Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

CppTools.cpp

Go to the documentation of this file.
00001 /* ImLib3D
00002  * Copyright (c) 2001, ULP-IPB Strasbourg.
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or (at
00007  * your option) any later version.
00008  * 
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 // runtime type info
00033 // **************************************************************
00034 
00036 
00037 string 
00038 TypeNameParser(string typeName)
00039 {
00040     static map<string,string> typeNameCache;
00041     // check if typeName is cached
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         // gnuc typeinfo gives mangled result
00048         // try to demangle using external "c++filt" command
00049         // if demangling fails, just use typename
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         // gnuc typeinfo gives mangled result
00062         // try to demangle using external "c++filt" command
00063         // if demangling fails, just use typename
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 // error processing
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);//should never get here!
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 //  fprintf(stderr,"%s\n",message.c_str());
00154     FatalError(message);
00155 }
00156 
00157 // **************************************************************
00158 // debug output
00159 // **************************************************************
00160 int globalVerbose=1;
00161 //  void 
00162 //  mprintf(const char *fmt, ...)
00163 //  {
00164 //      va_list args;
00165 //      va_start(args,fmt);
00166 //      if(globalVerbose){vprintf(fmt,args);}
00167 //  }
00168 
00169 
00170 // **************************************************************
00171 // string related  funtions
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         // check if it is a valid directory
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 //      cout << "Read: fname:" << fname << endl;
00452 //      cout << "Read: file:" << res << endl;
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 //  ThrowError("unimplemented for gcc3.0");
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 // External Unix programs
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     //RemoveFile(plotFname);
00589     //RemoveFile(dataFname);
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 // portability
00614 // **************************************************************
00615 #ifdef __CYGWIN__
00616 extern "C"
00617 {
00618 double drand48()
00619 {
00620     return((random()%1000000)/1000000.0);
00621 }
00622 }
00623 #endif // __CYGWIN__
00624 

Generated on Fri Jun 17 13:36:00 2005 for ImLib3D by  doxygen 1.4.2