About
User Reference
C++ API
luafaudes
Developer
Links
libFAUDES online
libFAUDES

Sections

Index

cfl_helper.cpp

Go to the documentation of this file.
00001 /** @file cfl_helper.cpp   Helper functions */
00002 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005    Copyright (C) 2006  Bernd Opitz
00006    Copyright (C) 2008-2010 Thomas Moor
00007    Exclusive copyright is granted to Klaus Schmidt
00008 
00009    This library is free software; you can redistribute it and/or
00010    modify it under the terms of the GNU Lesser General Public
00011    License as published by the Free Software Foundation; either
00012    version 2.1 of the License, or (at your option) any later version.
00013 
00014    This library is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017    Lesser General Public License for more details.
00018 
00019    You should have received a copy of the GNU Lesser General Public
00020    License along with this library; if not, write to the Free Software
00021    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
00022 
00023 */
00024 
00025 
00026 #include "cfl_helper.h"
00027 
00028 
00029 // Debug includes
00030 #include "cfl_attributes.h"
00031 #include "cfl_registry.h"
00032 #include "cfl_types.h"
00033 #include "cfl_elementary.h"
00034 
00035 /* Include extra defs for mswindows */
00036 #ifdef FAUDES_WINEXTRA
00037 #include "cfl_winextra.h"
00038 #endif
00039 
00040 /* need posix dirent */
00041 #include <dirent.h>
00042 
00043 namespace faudes {
00044 
00045 // ToStringInteger(number)
00046 std::string ToStringInteger(long int number) { 
00047   if(number>= std::numeric_limits<long int>::max()) return "inf";
00048   if(number<= std::numeric_limits<long int>::min()+1) return "-inf";
00049   std::string res;
00050   std::stringstream sstr;
00051   sstr << number;
00052   sstr >> res;
00053   return res;
00054 }
00055 
00056 // ToStringInteger16(number)
00057 std::string ToStringInteger16(long int number) { 
00058    std::string res;
00059    std::stringstream sstr;
00060    sstr << "0x" << std::setbase(16) << number;
00061    sstr >> res;
00062    return res;
00063 }
00064 
00065 // ToStringFloat(number)
00066 // todo: check range, prevent sci notation
00067 std::string ToStringFloat(double number) { 
00068    if(number == (long int) number) 
00069      return(ToStringInteger((long int) number));
00070    std::string res;
00071    std::stringstream sstr;
00072    sstr << std::fixed;
00073    sstr << number;
00074    sstr >> res;
00075    return res;
00076 }
00077 
00078 // ExpandString(rString, len) 
00079 std::string ExpandString(const std::string& rString, unsigned int len) {
00080   std::string res;
00081   res = rString;
00082   std::string::size_type xtra = (std::string::size_type) len - rString.length();
00083   if ((xtra > 0) && (xtra < 10000)) {
00084     res.append(xtra, ' ');
00085   }
00086   return res;
00087 } 
00088 
00089 // CollapseString(rString, len) 
00090 std::string  CollapsString(const std::string& rString, unsigned int len) {
00091   if(len <=1) return rString;
00092   if(rString.length() <= len) return rString;
00093   int chead = len/2;
00094   int ctail = len-chead;
00095   return rString.substr(0,chead) + "..." + rString.substr(rString.length()-ctail,ctail);
00096 } 
00097 
00098 // ToIdx(rString)
00099 Idx ToIdx(const std::string& rString) {
00100   char * end;
00101   unsigned long ul = strtoul (rString.c_str(), &end, 0);
00102   unsigned long idxmax = std::numeric_limits<Idx>::max();
00103   if (ul > idxmax) {
00104     throw Exception("atoidx", "Idx overflow", 600);
00105   }
00106   else {
00107     return (Idx) ul;
00108   }
00109 }
00110 
00111 // String Substitution
00112 std::string StringSubstitute(const std::string& rString,const std::string& rFrom,const std::string& rTo) {
00113   // prep result
00114   std::string res;
00115   std::size_t pos=0; 
00116   // loop over occurences of "from"
00117   while(pos<rString.length()) {
00118     std::size_t next=rString.find(rFrom,pos);
00119     if(next==std::string::npos) break;
00120     res.append(rString.substr(pos, next-pos));
00121     res.append(rTo);
00122     pos=next+rFrom.length();
00123   }
00124   // get end
00125   if(pos<rString.length()) 
00126     res.append(rString.substr(pos));
00127   // done
00128   return res;
00129 }
00130 
00131 // FDVersionString()
00132 std::string FDVersionString() {
00133   return std::string(FAUDES_VERSION);
00134 }
00135 
00136 // FDPluginsString()
00137 std::string FDPluginsString() {
00138   return std::string(FAUDES_PLUGINS);
00139 }
00140 
00141 // FDContributorsString()
00142 std::string FDContributorsString() {
00143   return 
00144     "Ruediger Berndt, Christian Breindl, Christine Baier, Tobias Barthel, Christoph Doerr, Marc Duevel, Norman Franchi, Rainer Hartmann, Jochen Hellenschmidt, Andreas Mohr, Thomas Moor, Mihai Musunoi, Bernd Opitz, Irmgard Petzoldt, Sebastian Perk, Thomas Rempel, Daniel Ritter, Berno Schlein, Klaus Schmidt, Matthias Singer, Thomas Wittmann, Jorgos Zaddach, et al";
00145 }
00146 
00147 
00148 // ProcessDot(infile,outfile,format)
00149 void ProcessDot(const std::string& rDotFile, 
00150   const std::string& rOutFile, const std::string& rOutFormat, const std::string& rDotExec)
00151 {
00152   std::string format=rOutFormat;
00153   // guess format from filename
00154   if(format=="") {
00155     if(rOutFile.rfind('.')+1 < rOutFile.size()) {
00156        format=rOutFile.substr(rOutFile.rfind('.')+1);
00157     }
00158   }  
00159   // test format
00160   if (format == "canon"); 
00161   else if (format == "dot"); 
00162   else if (format == "xdot"); 
00163   else if (format == "cmap");
00164   else if (format == "dia");
00165   else if (format == "fig"); 
00166   else if (format == "gd"); 
00167   else if (format == "gd2"); 
00168   else if (format == "gif"); 
00169   else if (format == "hpgl"); 
00170   else if (format == "imap"); 
00171   else if (format == "cmapx");
00172   else if (format == "ismap"); 
00173   else if (format == "jpg"); 
00174   else if (format == "jpeg"); 
00175   else if (format == "mif"); 
00176   else if (format == "mp"); 
00177   else if (format == "pcl"); 
00178   else if (format == "pic"); 
00179   else if (format == "plain"); 
00180   else if (format == "plain-ext"); 
00181   else if (format == "png"); 
00182   else if (format == "ps"); 
00183   else if (format == "ps2"); 
00184   else if (format == "svg"); 
00185   else if (format == "svgz"); 
00186   else if (format == "vrml"); 
00187   else if (format == "vtx"); 
00188   else if (format == "wbmp"); 
00189   else if (format == "eps"); 
00190   else if (format == "pdf"); 
00191   else {
00192     std::stringstream errstr;
00193     errstr << "Dot output format \"" << format << "\" unknown";
00194     throw Exception("faudes::ProcessDot", errstr.str(), 3);
00195   }
00196   std::string dotcommand = rDotExec + " -T"+format+" \""+rDotFile+"\" -o \""+rOutFile+"\"";
00197   if(system(dotcommand.c_str()) != 0) {
00198     throw Exception("faudes::ProcessDot", 
00199         "Error in running " + dotcommand, 3);
00200   }
00201 }
00202 
00203 
00204 // CreateTempFile(void)
00205 // todo: sys dependant, report, investigate threads
00206 std::string CreateTempFile(void) {
00207  char filename[]= "faudes_temp_XXXXXX";
00208   int filedes = mkstemp(filename);
00209   if(filedes==-1) {
00210     FD_DF("faudes::CreateTempFile(): error");
00211     return "";
00212   }
00213   close(filedes);
00214   std::string res(filename);
00215 
00216   FD_DF("faudes::CreateTempFile(): " << res);
00217   return(res);
00218 }
00219 
00220 
00221 // RemoveFile(void)
00222 // todo: sys dependant *
00223 bool RemoveFile(const std::string& rFileName) {
00224   return std::remove(rFileName.c_str()) == 0;
00225 }
00226 
00227 
00228 #ifndef FAUDES_DIR_SEPARATORS 
00229 #define FAUDES_DIR_SEPARATORS "/"
00230 #endif
00231 
00232 // DirSeparatator
00233 const std::string& DirSeparator(void) {
00234   static std::string dsep= std::string(FAUDES_DIR_SEPARATORS).substr(0,1);
00235   return dsep;
00236 }
00237 
00238 // ExtractPath
00239 std::string ExtractDirectory(const std::string& rFullPath) {
00240   std::string res="";
00241   std::size_t seppos = rFullPath.find_last_of(FAUDES_DIR_SEPARATORS);
00242   if(seppos==std::string::npos) return res;
00243   res=rFullPath.substr(0,seppos+1);
00244   return res;
00245 }
00246 
00247 // ExtractFilename
00248 std::string ExtractFilename(const std::string& rFullPath) {
00249   std::string res=rFullPath;
00250   std::size_t seppos = rFullPath.find_last_of(FAUDES_DIR_SEPARATORS);
00251   if(seppos==std::string::npos) return res;
00252   res=rFullPath.substr(seppos+1);
00253   return res;
00254 }
00255 
00256 // ExtractBasename
00257 std::string ExtractBasename(const std::string& rFullPath) {
00258   std::string res=rFullPath;
00259   std::size_t seppos = res.find_last_of(FAUDES_DIR_SEPARATORS);
00260   if(seppos!=std::string::npos) {
00261     res=res.substr(seppos+1);
00262   }
00263   std::size_t dotpos = res.find_last_of(".");
00264   if(dotpos!=std::string::npos) {
00265     res=res.substr(0,dotpos);
00266   }
00267   return res;
00268 }
00269 
00270 // ExtractExtension
00271 std::string ExtractExtension(const std::string& rFullPath) {
00272   std::string res=rFullPath;
00273   std::size_t seppos = res.find_last_of(FAUDES_DIR_SEPARATORS);
00274   if(seppos!=std::string::npos) {
00275     res=res.substr(seppos+1);
00276   }
00277   std::size_t dotpos = res.find_last_of(".");
00278   if(dotpos!=std::string::npos) 
00279   if(dotpos < res.size()+1) {
00280     return res.substr(dotpos+1,res.size()-dotpos-1);
00281   }
00282   return std::string();
00283 }
00284 
00285 // PrependPath
00286 std::string PrependDirectory(const std::string& rDirectory, const std::string& rFileName) {
00287   std::string res=rDirectory;
00288   char sepchar=std::string(FAUDES_DIR_SEPARATORS).at(0);
00289   if(res!="")
00290   if(res.at(res.length()-1)!=sepchar)
00291     res.append(1,sepchar);
00292   res.append(rFileName);
00293   return res;
00294 }
00295 
00296 // scan directory
00297 std::set< std::string > ReadDirectory(const std::string& rDirectory) {
00298   std::set< std::string >  res;
00299   DIR *thedir;
00300   struct dirent *theent;
00301   thedir=opendir(rDirectory.c_str()); 
00302   if(!thedir) return res;
00303   while((theent=readdir(thedir))) {
00304     std::string fname(theent->d_name);     
00305     if(fname==".") continue;
00306     if(fname=="..") continue;
00307     res.insert(fname);
00308   }
00309   closedir(thedir);
00310   return res;
00311 }
00312 
00313 
00314 // test file
00315 bool FileExists(const std::string& rFilename) {
00316   std::fstream fp;
00317   fp.open(rFilename.c_str(), std::ios::in | std::ios::binary);
00318   return fp.good();
00319 }
00320 
00321 
00322 // ConsoleOut class
00323 ConsoleOut::ConsoleOut(void) : pStream(NULL),mMute(false) {
00324 }
00325 ConsoleOut::~ConsoleOut(void) {
00326   if(pStream) { pStream->flush(); delete pStream; }
00327   if(this==spInstance) spInstance=NULL;
00328 }
00329 ConsoleOut* ConsoleOut::G(void) {
00330   if(!spInstance) spInstance= new ConsoleOut();
00331   return spInstance;
00332 }
00333 void ConsoleOut::Redirect(ConsoleOut* out) {
00334   std::string fname;
00335   if(spInstance) { 
00336     fname = spInstance->Filename();
00337     spInstance->ToFile("");
00338   }
00339   spInstance=out; 
00340   if(!spInstance) spInstance=this;
00341   spInstance->ToFile(fname);
00342 }
00343 void ConsoleOut::ToFile(const std::string& filename) {
00344   if(pStream) { pStream->flush(); delete pStream; }
00345   pStream=NULL;
00346   mFilename=filename;
00347   if(mFilename=="") return;
00348   pStream = new std::ofstream();
00349   pStream->open(mFilename.c_str(),std::ios::app);
00350 }
00351 void ConsoleOut::Write(const std::string& message) {
00352   if(mMute) return;
00353   Buffer() << message;
00354   Flush();
00355 }
00356 std::ostream& ConsoleOut::Buffer(void) {
00357   return mLineBuffer;
00358 }
00359 void ConsoleOut::Flush(long int cntnow, long int cntdone) {
00360   if(!mMute) DoWrite(cntnow, cntdone,mLineBuffer.str());
00361   mLineBuffer.str("");
00362 }
00363   void ConsoleOut::DoWrite(long int cntnow, long int cntdone,const std::string& message) {
00364     (void) cntnow; (void) cntdone;
00365   std::ostream* sout=pStream;
00366   if(!sout) sout=&std::cerr;
00367   *sout << message;
00368   sout->flush();
00369 }
00370 
00371 // global instance
00372 ConsoleOut* ConsoleOut::spInstance=NULL;
00373  
00374 
00375 
00376 // debugging: objectcount
00377 std::map<std::string,long int>* ObjectCount::mspMax=NULL;
00378 std::map<std::string,long int>* ObjectCount::mspCount=NULL;
00379 bool ObjectCount::msDone=false;
00380 ObjectCount::ObjectCount(void) {
00381   mspCount= new std::map<std::string,long int>();
00382   mspMax= new std::map<std::string,long int>();
00383   msDone=true; 
00384 }
00385 void  ObjectCount::Init(void) {
00386  if(!msDone) ObjectCount();
00387 }
00388 void  ObjectCount::Inc(const std::string& rTypeName) {
00389   if(!msDone) ObjectCount();
00390   long int cnt = ((*mspCount)[rTypeName]+=1);
00391   if((*mspMax)[rTypeName]<cnt) (*mspMax)[rTypeName]=cnt;
00392 }
00393 void  ObjectCount::Dec(const std::string& rTypeName) {
00394   if(!msDone) ObjectCount();
00395   (*mspCount)[rTypeName]-=1;
00396 }
00397 
00398 
00399 // debugging: report on exit function
00400 void ExitFunction(void){
00401 #ifdef FAUDES_DEBUG_CODE
00402   FAUDES_WRITE_CONSOLE("faudes::ExitFunction():");
00403   // be sure its up and running
00404   ObjectCount::Init();
00405   // get rid of all registry prototypes
00406   //TypeRegistry::G()->ClearAll();  
00407   //FunctionRegistry::G()->Clear();  
00408   // prepare report
00409   std::map<std::string,long int>::iterator cit;
00410   cit=ObjectCount::mspCount->begin();
00411   for(;cit!=ObjectCount::mspCount->end();cit++) {
00412     FAUDES_WRITE_CONSOLE( cit->first << ": #" << ToStringInteger(cit->second) <<
00413      " (max #" << (*ObjectCount::mspMax)[cit->first] << ")");
00414   }
00415 #endif
00416 }
00417  
00418 
00419 #ifdef FAUDES_DEBUG_CODE
00420 // report on exit install
00421 class ExitFunctionInstall {
00422 private:
00423   static bool mDone;
00424   static ExitFunctionInstall mInstance;
00425   ExitFunctionInstall(void) {
00426     if(mDone) return;
00427     FAUDES_WRITE_CONSOLE("ExitFunctionInstall()");
00428     std::atexit(ExitFunction);
00429     mDone=true;
00430   } 
00431 };
00432 // exit function: global data
00433 bool ExitFunctionInstall::mDone=false;
00434 ExitFunctionInstall ExitFunctionInstall::mInstance;
00435 #endif
00436 
00437 // test protocol: token writer and file
00438 TokenWriter* gTestProtocolTw=NULL;
00439 std::string  gTestProtocolFr;
00440 
00441 // test protocol: setup
00442 std::string TestProtocol(const std::string& rSource) {
00443   if(gTestProtocolTw) return gTestProtocolFr;
00444   // set up filename
00445   std::string filename=rSource;
00446   // fix empty source
00447   if(filename=="") filename="faudes_dump";
00448   // remove directory
00449   filename=ExtractFilename(filename);
00450   // remove extension
00451   std::string::size_type pos=0;
00452   for(;pos<filename.length();pos++) 
00453     if(filename.at(pos)=='.') filename.at(pos)='_';
00454   // append extension
00455   filename.append(".prot");
00456   // record nominal case
00457   gTestProtocolFr=filename;
00458   // prepend prefix
00459   filename.insert(0,"tmp_");
00460   // initialise token writer
00461   gTestProtocolTw= new TokenWriter(filename);
00462   // report filename
00463   return gTestProtocolFr;
00464 }
00465   
00466 // test protocol: dump
00467 void TestProtocol(const std::string& rMessage, const Type& rData, bool full) {
00468   if(!gTestProtocolTw) return;
00469   gTestProtocolTw->WriteComment("%%% test mark: " + rMessage);
00470   if(full) rData.Write(*gTestProtocolTw);
00471   else rData.SWrite(*gTestProtocolTw);
00472   gTestProtocolTw->WriteComment("");
00473   gTestProtocolTw->WriteComment("");
00474   gTestProtocolTw->WriteComment("");
00475   *gTestProtocolTw << "\n";
00476 }
00477 void TestProtocol(const std::string& rMessage, bool data) {
00478   Boolean fbool(data);
00479   TestProtocol(rMessage,fbool,true);
00480 } 
00481 void TestProtocol(const std::string& rMessage, long int data) {
00482   Integer fint(data);
00483   TestProtocol(rMessage,fint,true);
00484 } 
00485 void TestProtocol(const std::string& rMessage, const std::string& rData) {
00486  String fstr(rData);
00487  TestProtocol(rMessage,fstr,true);
00488 } 
00489 
00490 // test protocol: compare
00491 bool TestProtocol(void) {
00492   // bail out on no protocol
00493   if(!gTestProtocolTw) return true;
00494   // close protocol file
00495   std::string prot=gTestProtocolTw->FileName();
00496   delete gTestProtocolTw;
00497   gTestProtocolTw=NULL;
00498   // open protocol 
00499   std::fstream fp;
00500   fp.open(prot.c_str(), std::ios::in | std::ios::binary);
00501   if(!fp.good()) { 
00502     FAUDES_WRITE_CONSOLE("TestProtocol(): could not open protocol \"" << prot << "\"");
00503     return false;
00504   }
00505   // open reference
00506   std::string ref=gTestProtocolFr;
00507   std::fstream fr;
00508   fr.open(ref.c_str(), std::ios::in | std::ios::binary); 
00509   if(!fr.good()) { 
00510     ref="data"+DirSeparator()+ref;
00511     fr.clear(); // mingw's runtime will not clear on open
00512     fr.open(ref.c_str(), std::ios::in | std::ios::binary);
00513   }
00514   if(!fr.good()) { 
00515     FAUDES_WRITE_CONSOLE("TestProtocol(): could not open/find reference \"" << gTestProtocolFr << "\"");
00516     return true;
00517   }
00518   // perform comparision
00519   int dline=-1;
00520   int cline=1;    
00521   try{
00522     while(true) {
00523       // read next char
00524       char cp = fp.get();
00525       char cr= fr.get();
00526       // eof
00527       if(fp.eof() && fr.eof()) { break; }
00528       if(!fp.good() || !fr.good()) { dline=cline; break;}
00529       // cheap normalize cr/lf: ignore \r (assume no double \r
00530       if( cp=='\r' && cr =='\r') continue;
00531       if( cp=='\r' && fp.eof()){ dline=cline; break;}
00532       if( cp=='\r') cp = fp.get();      
00533       if( cr=='\r' && fr.eof()){ dline=cline; break;}
00534       if( cr=='\r') cr = fr.get();   
00535       // count lines
00536       if( cr=='\n') cline++;
00537       // sense mitmatch
00538       if( cp!= cr ){dline=cline; break;}
00539     }
00540   } catch(std::ios::failure&) {
00541     throw Exception("TestProtocol()", "io error at line " + ToStringInteger(cline), 1);
00542   }
00543   // done
00544   if(dline>=0) {
00545     FAUDES_WRITE_CONSOLE("TestProtocol(): using reference " << ref << "");
00546     FAUDES_WRITE_CONSOLE("TestProtocol(): found difference at line " << dline << "");
00547   }
00548   return dline== -1;
00549 }
00550 
00551 
00552 
00553 // declare loop callback
00554 static bool (*gBreakFnct)(void)=0;
00555 
00556 // set loop callback
00557 void LoopCallback( bool pBreak(void)) {
00558   gBreakFnct=pBreak;
00559 }
00560 
00561 // do loop callback
00562 // note: this function is meant to be "quiet" during normal
00563 // operation in order not to mess up console logging
00564 void LoopCallback(void){
00565   if(!gBreakFnct) return;
00566   if(! (*gBreakFnct)() ) return;
00567   throw Exception("LoopCallback", "break on application request", 110);
00568 }
00569 
00570 } // namespace faudes

libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen