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 
00041 namespace faudes {
00042 
00043 // ToStringInteger(number)
00044 std::string ToStringInteger(long int number) { 
00045   if(number>= std::numeric_limits<long int>::max()) return "inf";
00046   if(number<= std::numeric_limits<long int>::min()+1) return "-inf";
00047   std::string res;
00048   std::stringstream sstr;
00049   sstr << number;
00050   sstr >> res;
00051   return res;
00052 }
00053 
00054 // ToStringInteger16(number)
00055 std::string ToStringInteger16(long int number) { 
00056    std::string res;
00057    std::stringstream sstr;
00058    sstr << "0x" << std::setbase(16) << number;
00059    sstr >> res;
00060    return res;
00061 }
00062 
00063 // ToStringFloat(number)
00064 // todo: check range, prevent sci notation
00065 std::string ToStringFloat(double number) { 
00066    if(number == (long int) number) 
00067      return(ToStringInteger((long int) number));
00068    std::string res;
00069    std::stringstream sstr;
00070    sstr << std::fixed;
00071    sstr << number;
00072    sstr >> res;
00073    return res;
00074 }
00075 
00076 // ExpandString(rString, len) 
00077 std::string ExpandString(const std::string& rString, unsigned int len) {
00078   std::string res;
00079   res = rString;
00080   std::string::size_type xtra = (std::string::size_type) len - rString.length();
00081   if ((xtra > 0) && (xtra < 10000)) {
00082     res.append(xtra, ' ');
00083   }
00084   return res;
00085 } 
00086 
00087 // CollapseString(rString, len) 
00088 std::string  CollapsString(const std::string& rString, unsigned int len) {
00089   if(len <=1) return rString;
00090   if(rString.length() <= len) return rString;
00091   int chead = len/2;
00092   int ctail = len-chead;
00093   return rString.substr(0,chead) + "..." + rString.substr(rString.length()-ctail,ctail);
00094 } 
00095 
00096 // ToIdx(rString)
00097 Idx ToIdx(const std::string& rString) {
00098   char * end;
00099   unsigned long ul = strtoul (rString.c_str(), &end, 0);
00100   unsigned long idxmax = std::numeric_limits<Idx>::max();
00101   if (ul > idxmax) {
00102     throw Exception("atoidx", "Idx overflow", 600);
00103   }
00104   else {
00105     return (Idx) ul;
00106   }
00107 }
00108 
00109 // String Substitution
00110 std::string StringSubstitute(const std::string& rString,const std::string& rFrom,const std::string& rTo) {
00111   // prep result
00112   std::string res;
00113   std::size_t pos=0; 
00114   // loop over occurences of "from"
00115   while(pos<rString.length()) {
00116     std::size_t next=rString.find(rFrom,pos);
00117     if(next==std::string::npos) break;
00118     res.append(rString.substr(pos, next));
00119     res.append(rTo);
00120     pos=next+rFrom.length();
00121   }
00122   // get end
00123   if(pos<rString.length()) 
00124     res.append(rString.substr(pos));
00125   // done
00126   return res;
00127 }
00128 
00129 // FDVersionString()
00130 std::string FDVersionString() {
00131   return std::string(FAUDES_VERSION);
00132 }
00133 
00134 // FDPluginsString()
00135 std::string FDPluginsString() {
00136   return std::string(FAUDES_PLUGINS);
00137 }
00138 
00139 // FDContributorsString()
00140 std::string FDContributorsString() {
00141   return 
00142     "Ruediger Berndt, Christian Breindl, 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";
00143 }
00144 
00145 
00146 // ProcessDot(infile,outfile,format)
00147 void ProcessDot(const std::string& rDotFile, 
00148   const std::string& rOutFile, const std::string& rOutFormat, const std::string& rDotExec)
00149 {
00150   std::string format=rOutFormat;
00151   // guess format from filename
00152   if(format=="") {
00153     if(rOutFile.rfind('.')+1 < rOutFile.size()) {
00154        format=rOutFile.substr(rOutFile.rfind('.')+1);
00155     }
00156   }  
00157   // test format
00158   if (format == "canon"); 
00159   else if (format == "dot"); 
00160   else if (format == "xdot"); 
00161   else if (format == "cmap");
00162   else if (format == "dia");
00163   else if (format == "fig"); 
00164   else if (format == "gd"); 
00165   else if (format == "gd2"); 
00166   else if (format == "gif"); 
00167   else if (format == "hpgl"); 
00168   else if (format == "imap"); 
00169   else if (format == "cmapx");
00170   else if (format == "ismap"); 
00171   else if (format == "jpg"); 
00172   else if (format == "jpeg"); 
00173   else if (format == "mif"); 
00174   else if (format == "mp"); 
00175   else if (format == "pcl"); 
00176   else if (format == "pic"); 
00177   else if (format == "plain"); 
00178   else if (format == "plain-ext"); 
00179   else if (format == "png"); 
00180   else if (format == "ps"); 
00181   else if (format == "ps2"); 
00182   else if (format == "svg"); 
00183   else if (format == "svgz"); 
00184   else if (format == "vrml"); 
00185   else if (format == "vtx"); 
00186   else if (format == "wbmp"); 
00187   else {
00188     std::stringstream errstr;
00189     errstr << "Dot output format \"" << format << "\" unknown";
00190     throw Exception("faudes::ProcessDot", errstr.str(), 3);
00191   }
00192   std::string dotcommand = rDotExec + " -T"+format+" \""+rDotFile+"\" -o \""+rOutFile+"\"";
00193   if(system(dotcommand.c_str()) != 0) {
00194     throw Exception("faudes::ProcessDot", 
00195         "Error in running " + dotcommand, 3);
00196   }
00197 }
00198 
00199 
00200 // CreateTempFile(void)
00201 // todo: sys dependant, report, investigate threads
00202 std::string CreateTempFile(void) {
00203  char filename[]= "faudes_temp_XXXXXX";
00204   int filedes = mkstemp(filename);
00205   if(filedes==-1) {
00206     FD_DF("faudes::CreateTempFile(): error");
00207     return "";
00208   }
00209   close(filedes);
00210   std::string res(filename);
00211 
00212   FD_DF("faudes::CreateTempFile(): " << res);
00213   return(res);
00214 }
00215 
00216 
00217 // RemoveFile(void)
00218 // todo: sys dependant *
00219 bool RemoveFile(const std::string& rFileName) {
00220   return std::remove(rFileName.c_str()) == 0;
00221 }
00222 
00223 
00224 #ifndef FAUDES_DIR_SEPARATORS 
00225 #define FAUDES_DIR_SEPARATORS "/"
00226 #endif
00227 
00228 // ExtractPath
00229 std::string ExtractDirectory(const std::string& rFullPath) {
00230   std::string res="";
00231   unsigned int seppos = rFullPath.find_last_of(FAUDES_DIR_SEPARATORS);
00232   if(seppos==std::string::npos) return res;
00233   res=rFullPath.substr(0,seppos+1);
00234   return res;
00235 }
00236 
00237 // ExtractFilename
00238 std::string ExtractFilename(const std::string& rFullPath) {
00239   std::string res=rFullPath;
00240   unsigned int seppos = rFullPath.find_last_of(FAUDES_DIR_SEPARATORS);
00241   if(seppos==std::string::npos) return res;
00242   res=rFullPath.substr(seppos+1);
00243   return res;
00244 }
00245 
00246 // PrependPath
00247 std::string PrependDirectory(const std::string& rDirectory, const std::string& rFileName) {
00248   std::string res=rDirectory;
00249   char sepchar=std::string(FAUDES_DIR_SEPARATORS).at(0);
00250   if(res!="")
00251   if(res.at(res.length()-1)!=sepchar)
00252     res.append(1,sepchar);
00253   res.append(rFileName);
00254   return res;
00255 }
00256 
00257 // ConsoleOut class
00258 ConsoleOut::ConsoleOut(void) : pStream(NULL),mMute(false) {
00259 }
00260 ConsoleOut::~ConsoleOut(void) {
00261   if(pStream) { pStream->flush(); delete pStream; }
00262   if(this==spInstance) spInstance=NULL;
00263 }
00264 ConsoleOut* ConsoleOut::G(void) {
00265   if(!spInstance) spInstance= new ConsoleOut();
00266   return spInstance;
00267 }
00268 void ConsoleOut::Redirect(ConsoleOut* out) {
00269   std::string fname;
00270   if(spInstance) { 
00271     fname = spInstance->Filename();
00272     spInstance->ToFile("");
00273   }
00274   spInstance=out; 
00275   if(!spInstance) spInstance=this;
00276   spInstance->ToFile(fname);
00277 }
00278 void ConsoleOut::ToFile(const std::string& filename) {
00279   if(pStream) { pStream->flush(); delete pStream; }
00280   pStream=NULL;
00281   mFilename=filename;
00282   if(mFilename=="") return;
00283   pStream = new std::ofstream();
00284   pStream->open(mFilename.c_str(),std::ios::app);
00285 }
00286 void ConsoleOut::Write(const std::string& message) {
00287   if(mMute) return;
00288   Buffer() << message;
00289   Flush();
00290 }
00291 std::ostream& ConsoleOut::Buffer(void) {
00292   return mLineBuffer;
00293 }
00294 void ConsoleOut::Flush(long int cntnow, long int cntdone) {
00295   if(!mMute) DoWrite(cntnow, cntdone,mLineBuffer.str());
00296   mLineBuffer.str("");
00297 }
00298   void ConsoleOut::DoWrite(long int cntnow, long int cntdone,const std::string& message) {
00299     (void) cntnow; (void) cntdone;
00300   std::ostream* sout=pStream;
00301   if(!sout) sout=&std::cerr;
00302   *sout << message;
00303   sout->flush();
00304 }
00305 
00306 // global instance
00307 ConsoleOut* ConsoleOut::spInstance=NULL;
00308  
00309 
00310 
00311 // debugging: objectcount
00312 std::map<std::string,long int>* ObjectCount::mspMax=NULL;
00313 std::map<std::string,long int>* ObjectCount::mspCount=NULL;
00314 bool ObjectCount::msDone=false;
00315 ObjectCount::ObjectCount(void) {
00316   mspCount= new std::map<std::string,long int>();
00317   mspMax= new std::map<std::string,long int>();
00318   msDone=true; 
00319 }
00320 void  ObjectCount::Init(void) {
00321  if(!msDone) ObjectCount();
00322 }
00323 void  ObjectCount::Inc(const std::string& rTypeName) {
00324   if(!msDone) ObjectCount();
00325   long int cnt = ((*mspCount)[rTypeName]+=1);
00326   if((*mspMax)[rTypeName]<cnt) (*mspMax)[rTypeName]=cnt;
00327 }
00328 void  ObjectCount::Dec(const std::string& rTypeName) {
00329   if(!msDone) ObjectCount();
00330   (*mspCount)[rTypeName]-=1;
00331 }
00332 
00333 
00334 // debugging: report on exit function
00335 void ExitFunction(void){
00336 #ifdef FAUDES_DEBUG_CODE
00337   FAUDES_WRITE_CONSOLE("faudes::ExitFunction:");
00338   // be sure its up and running
00339   ObjectCount::Init();
00340   // get rid of all registry prototypes
00341   TypeRegistry::G()->Clear();  
00342   // prepare report
00343   std::map<std::string,long int>::iterator cit;
00344   cit=ObjectCount::mspCount->begin();
00345   for(;cit!=ObjectCount::mspCount->end();cit++) {
00346     FAUDES_WRITE_CONSOLE( cit->first << ": #" << ToStringInteger(cit->second) <<
00347      " (max #" << (*ObjectCount::mspMax)[cit->first] << ")");
00348   }
00349 #endif
00350 }
00351  
00352 
00353 #ifdef FAUDES_DEBUG_CODE
00354 // report on exit install
00355 class ExitFunctionInstall {
00356 private:
00357   static bool mDone;
00358   static ExitFunctionInstall mInstance;
00359   ExitFunctionInstall(void) {
00360     if(mDone) return;
00361     FAUDES_WRITE_CONSOLE("ExitFunctionInstall()");
00362     std::atexit(ExitFunction);
00363     mDone=true;
00364   } 
00365 };
00366 // exit function: global data
00367 bool ExitFunctionInstall::mDone=false;
00368 ExitFunctionInstall ExitFunctionInstall::mInstance;
00369 #endif
00370 
00371 // test protocol: token writer
00372 TokenWriter* gTestProtocolTw=NULL;
00373 
00374 // test protocol: setup
00375 void TestProtocol(const std::string& rSource) {
00376   if(gTestProtocolTw) delete gTestProtocolTw;
00377   std::string filename=rSource;
00378   // fix empty source
00379   if(filename=="") filename="test_dump";
00380   // remove directory
00381   filename=ExtractFilename(filename);
00382   // remove extension
00383   std::string::size_type pos=0;
00384   for(;pos<filename.length();pos++) 
00385     if(filename.at(pos)=='.') filename.at(pos)='_';
00386   // append extension
00387   filename.append(".prot");
00388   // prepend prefix
00389   filename.insert(0,"tmp_");
00390   // initialise token writer
00391   gTestProtocolTw= new TokenWriter(filename);
00392 }
00393   
00394 // test protocol: dump
00395 void TestProtocol(const std::string& rSource, const std::string& rMessage, const Type& rData, bool core) {
00396   if(!gTestProtocolTw) TestProtocol(rSource);
00397   gTestProtocolTw->WriteComment("%%% test mark: " + rMessage);
00398   if(core) rData.Write(*gTestProtocolTw);
00399   else rData.SWrite(*gTestProtocolTw);
00400   gTestProtocolTw->WriteComment("");
00401   gTestProtocolTw->WriteComment("");
00402   gTestProtocolTw->WriteComment("");
00403   *gTestProtocolTw << "\n";
00404 }
00405 void TestProtocol(const std::string& rSource, const std::string& rMessage, bool data) {
00406   Boolean fbool(data);
00407   TestProtocol(rSource,rMessage,fbool,true);
00408 } 
00409 void TestProtocol(const std::string& rSource, const std::string& rMessage, long int data) {
00410   Integer fint(data);
00411   TestProtocol(rSource,rMessage,fint,true);
00412 } 
00413 void TestProtocol(const std::string& rSource, const std::string& rMessage, const std::string& rData) {
00414   String fstr(rData);
00415  TestProtocol(rSource,rMessage,fstr,true);
00416 } 
00417 
00418 
00419 // declare loop callback
00420 static bool (*gBreakFnct)(void)=0;
00421 
00422 // set loop callback
00423 void LoopCallback( bool pBreak(void)) {
00424   gBreakFnct=pBreak;
00425 }
00426 
00427 // do loop callback
00428 // note: this function is meant to be "quiet" during normal
00429 // operation in order to to mess up console logging
00430 void LoopCallback(void){
00431   if(!gBreakFnct) return;
00432   if(! (*gBreakFnct)() ) return;
00433   throw Exception("LoopCallback", "break on application request", 110);
00434 }
00435 
00436 } // namespace faudes

libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3