libFAUDES
Sections
Index
|
cfl_helper.cppGo 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