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 return (Idx) ul; 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-pos)); 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, Christine Baier, Tobias Barthel, Christoph Doerr, Marc Duevel, Norman Franchi, Rainer Hartmann, Jochen Hellenschmidt, Tomas Masopust, Andreas Mohr, Thomas Moor, Mihai Musunoi, Bernd Opitz, Irmgard Petzoldt, Sebastian Perk, Thomas Rempel, Daniel Ritter, Berno Schlein, Ece Schmidt, Klaus Schmidt, Matthias Singer, Ulas Turan, Thomas Wittmann, Shi Xiaoxun, 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 if (format == "eps"); 00188 else if (format == "pdf"); 00189 else { 00190 std::stringstream errstr; 00191 errstr << "Dot output format \"" << format << "\" unknown"; 00192 throw Exception("faudes::ProcessDot", errstr.str(), 3); 00193 } 00194 std::string dotcommand = rDotExec + " -T"+format+" \""+rDotFile+"\" -o \""+rOutFile+"\""; 00195 if(system(dotcommand.c_str()) != 0) { 00196 throw Exception("faudes::ProcessDot", 00197 "Error in running " + dotcommand, 3); 00198 } 00199 } 00200 00201 00202 // CreateTempFile(void) 00203 // todo: sys dependant, report, investigate threads 00204 std::string CreateTempFile(void) { 00205 char filename[]= "faudes_temp_XXXXXX"; 00206 int filedes = mkstemp(filename); 00207 if(filedes==-1) { 00208 FD_DF("faudes::CreateTempFile(): error"); 00209 return ""; 00210 } 00211 close(filedes); 00212 std::string res(filename); 00213 00214 FD_DF("faudes::CreateTempFile(): " << res); 00215 return(res); 00216 } 00217 00218 00219 // RemoveFile(void) 00220 // todo: sys dependant * 00221 bool RemoveFile(const std::string& rFileName) { 00222 return std::remove(rFileName.c_str()) == 0; 00223 } 00224 00225 00226 #ifndef FAUDES_DIR_SEPARATORS 00227 #define FAUDES_DIR_SEPARATORS "/" 00228 #endif 00229 00230 // DirSeparatator 00231 const std::string& DirSeparator(void) { 00232 static std::string dsep= std::string(FAUDES_DIR_SEPARATORS).substr(0,1); 00233 return dsep; 00234 } 00235 00236 // ExtractPath 00237 std::string ExtractDirectory(const std::string& rFullPath) { 00238 std::string res=""; 00239 std::size_t seppos = rFullPath.find_last_of(FAUDES_DIR_SEPARATORS); 00240 if(seppos==std::string::npos) return res; 00241 res=rFullPath.substr(0,seppos+1); 00242 return res; 00243 } 00244 00245 // ExtractFilename 00246 std::string ExtractFilename(const std::string& rFullPath) { 00247 std::string res=rFullPath; 00248 std::size_t seppos = rFullPath.find_last_of(FAUDES_DIR_SEPARATORS); 00249 if(seppos==std::string::npos) return res; 00250 res=rFullPath.substr(seppos+1); 00251 return res; 00252 } 00253 00254 // ExtractBasename 00255 std::string ExtractBasename(const std::string& rFullPath) { 00256 std::string res=rFullPath; 00257 std::size_t seppos = res.find_last_of(FAUDES_DIR_SEPARATORS); 00258 if(seppos!=std::string::npos) { 00259 res=res.substr(seppos+1); 00260 } 00261 std::size_t dotpos = res.find_last_of("."); 00262 if(dotpos!=std::string::npos) { 00263 res=res.substr(0,dotpos); 00264 } 00265 return res; 00266 } 00267 00268 // ExtractExtension 00269 std::string ExtractExtension(const std::string& rFullPath) { 00270 std::string res=rFullPath; 00271 std::size_t seppos = res.find_last_of(FAUDES_DIR_SEPARATORS); 00272 if(seppos!=std::string::npos) { 00273 res=res.substr(seppos+1); 00274 } 00275 std::size_t dotpos = res.find_last_of("."); 00276 if(dotpos!=std::string::npos) 00277 if(dotpos < res.size()+1) { 00278 return res.substr(dotpos+1,res.size()-dotpos-1); 00279 } 00280 return std::string(); 00281 } 00282 00283 // PrependPath 00284 std::string PrependDirectory(const std::string& rDirectory, const std::string& rFileName) { 00285 std::string res=rDirectory; 00286 char sepchar=std::string(FAUDES_DIR_SEPARATORS).at(0); 00287 if(res!="") 00288 if(res.at(res.length()-1)!=sepchar) 00289 res.append(1,sepchar); 00290 res.append(rFileName); 00291 return res; 00292 } 00293 00294 // scan directory 00295 std::set< std::string > ReadDirectory(const std::string& rDirectory) { 00296 std::set< std::string > res; 00297 DIR *thedir; 00298 struct dirent *theent; 00299 thedir=opendir(rDirectory.c_str()); 00300 if(!thedir) return res; 00301 while((theent=readdir(thedir))) { 00302 std::string fname(theent->d_name); 00303 if(fname==".") continue; 00304 if(fname=="..") continue; 00305 res.insert(fname); 00306 } 00307 closedir(thedir); 00308 return res; 00309 } 00310 00311 00312 // test file 00313 bool FileExists(const std::string& rFilename) { 00314 std::fstream fp; 00315 fp.open(rFilename.c_str(), std::ios::in | std::ios::binary); 00316 return fp.good(); 00317 } 00318 00319 00320 // ConsoleOut class 00321 // Note: console-out is not re-entrant; for multithreaded applications 00322 // you must derive a class that has built-in mutexes; 00323 ConsoleOut::ConsoleOut(void) : pStream(NULL), mMute(false) { 00324 pInstance=this; 00325 } 00326 ConsoleOut::~ConsoleOut(void) { 00327 if(pStream) { pStream->flush(); delete pStream; } 00328 if(this==smpInstance) smpInstance=NULL; 00329 } 00330 ConsoleOut* ConsoleOut::G(void) { 00331 if(!smpInstance) smpInstance= new ConsoleOut(); 00332 return smpInstance->pInstance; 00333 } 00334 void ConsoleOut::Redirect(ConsoleOut* out) { 00335 std::string fname = smpInstance->pInstance->Filename(); 00336 smpInstance->pInstance->ToFile(""); 00337 smpInstance->pInstance=out; 00338 if(!smpInstance->pInstance) smpInstance->pInstance=smpInstance; 00339 smpInstance->pInstance->ToFile(fname); 00340 } 00341 void ConsoleOut::ToFile(const std::string& filename) { 00342 if(pStream) { pStream->flush(); delete pStream; } 00343 pStream=NULL; 00344 mFilename=filename; 00345 if(mFilename=="") return; 00346 pStream = new std::ofstream(); 00347 pStream->open(mFilename.c_str(),std::ios::app); 00348 } 00349 void ConsoleOut::Write(const std::string& message,long int cntnow, long int cntdone) { 00350 if(mMute) return; 00351 DoWrite(message,cntnow,cntdone); 00352 } 00353 void ConsoleOut::DoWrite(const std::string& message,long int cntnow, long int cntdone) { 00354 (void) cntnow; (void) cntdone; 00355 std::ostream* sout=pStream; 00356 if(!sout) sout=&std::cerr; 00357 *sout << message; 00358 sout->flush(); 00359 } 00360 00361 // global instance 00362 ConsoleOut* ConsoleOut::smpInstance=NULL; 00363 00364 00365 00366 // debugging: objectcount 00367 std::map<std::string,long int>* ObjectCount::mspMax=NULL; 00368 std::map<std::string,long int>* ObjectCount::mspCount=NULL; 00369 bool ObjectCount::msDone=false; 00370 ObjectCount::ObjectCount(void) { 00371 mspCount= new std::map<std::string,long int>(); 00372 mspMax= new std::map<std::string,long int>(); 00373 msDone=true; 00374 } 00375 void ObjectCount::Init(void) { 00376 if(!msDone) ObjectCount(); 00377 } 00378 void ObjectCount::Inc(const std::string& rTypeName) { 00379 if(!msDone) ObjectCount(); 00380 long int cnt = ((*mspCount)[rTypeName]+=1); 00381 if((*mspMax)[rTypeName]<cnt) (*mspMax)[rTypeName]=cnt; 00382 } 00383 void ObjectCount::Dec(const std::string& rTypeName) { 00384 if(!msDone) ObjectCount(); 00385 (*mspCount)[rTypeName]-=1; 00386 } 00387 00388 00389 // debugging: report on exit function 00390 void ExitFunction(void){ 00391 #ifdef FAUDES_DEBUG_CODE 00392 FAUDES_WRITE_CONSOLE("faudes::ExitFunction():"); 00393 // be sure its up and running 00394 ObjectCount::Init(); 00395 // get rid of all registry prototypes 00396 //TypeRegistry::G()->ClearAll(); 00397 //FunctionRegistry::G()->Clear(); 00398 // prepare report 00399 std::map<std::string,long int>::iterator cit; 00400 cit=ObjectCount::mspCount->begin(); 00401 for(;cit!=ObjectCount::mspCount->end();cit++) { 00402 FAUDES_WRITE_CONSOLE( cit->first << ": #" << ToStringInteger(cit->second) << 00403 " (max #" << (*ObjectCount::mspMax)[cit->first] << ")"); 00404 } 00405 #endif 00406 } 00407 00408 00409 #ifdef FAUDES_DEBUG_CODE 00410 // report on exit install 00411 class ExitFunctionInstall { 00412 private: 00413 static bool mDone; 00414 static ExitFunctionInstall mInstance; 00415 ExitFunctionInstall(void) { 00416 if(mDone) return; 00417 FAUDES_WRITE_CONSOLE("ExitFunctionInstall()"); 00418 std::atexit(ExitFunction); 00419 mDone=true; 00420 } 00421 }; 00422 // exit function: global data 00423 bool ExitFunctionInstall::mDone=false; 00424 ExitFunctionInstall ExitFunctionInstall::mInstance; 00425 #endif 00426 00427 // test protocol: token writer and file 00428 TokenWriter* gTestProtocolTw=NULL; 00429 std::string gTestProtocolFr; 00430 00431 // test protocol: setup 00432 std::string TestProtocol(const std::string& rSource) { 00433 if(gTestProtocolTw) return gTestProtocolFr; 00434 // set up filename 00435 std::string filename=rSource; 00436 // fix empty source 00437 if(filename=="") filename="faudes_dump"; 00438 // remove directory 00439 filename=ExtractFilename(filename); 00440 // remove extension 00441 std::string::size_type pos=0; 00442 for(;pos<filename.length();pos++) 00443 if(filename.at(pos)=='.') filename.at(pos)='_'; 00444 // append extension 00445 filename.append(".prot"); 00446 // record nominal case 00447 gTestProtocolFr=filename; 00448 // prepend prefix 00449 filename.insert(0,"tmp_"); 00450 // initialise token writer 00451 gTestProtocolTw= new TokenWriter(filename); 00452 // report filename 00453 return gTestProtocolFr; 00454 } 00455 00456 // test protocol: dump 00457 void TestProtocol(const std::string& rMessage, const Type& rData, bool full) { 00458 if(!gTestProtocolTw) return; 00459 gTestProtocolTw->WriteComment("%%% test mark: " + rMessage); 00460 if(full) rData.Write(*gTestProtocolTw); 00461 else rData.SWrite(*gTestProtocolTw); 00462 gTestProtocolTw->WriteComment(""); 00463 gTestProtocolTw->WriteComment(""); 00464 gTestProtocolTw->WriteComment(""); 00465 *gTestProtocolTw << "\n"; 00466 } 00467 void TestProtocol(const std::string& rMessage, bool data) { 00468 Boolean fbool(data); 00469 TestProtocol(rMessage,fbool,true); 00470 } 00471 void TestProtocol(const std::string& rMessage, long int data) { 00472 Integer fint(data); 00473 TestProtocol(rMessage,fint,true); 00474 } 00475 void TestProtocol(const std::string& rMessage, const std::string& rData) { 00476 String fstr(rData); 00477 TestProtocol(rMessage,fstr,true); 00478 } 00479 00480 // test protocol: compare 00481 bool TestProtocol(void) { 00482 // bail out on no protocol 00483 if(!gTestProtocolTw) return true; 00484 // close protocol file 00485 std::string prot=gTestProtocolTw->FileName(); 00486 delete gTestProtocolTw; 00487 gTestProtocolTw=NULL; 00488 // open protocol 00489 std::fstream fp; 00490 fp.open(prot.c_str(), std::ios::in | std::ios::binary); 00491 if(!fp.good()) { 00492 FAUDES_WRITE_CONSOLE("TestProtocol(): could not open protocol \"" << prot << "\""); 00493 return false; 00494 } 00495 // open reference 00496 std::string ref=gTestProtocolFr; 00497 std::fstream fr; 00498 fr.open(ref.c_str(), std::ios::in | std::ios::binary); 00499 if(!fr.good()) { 00500 ref="data"+DirSeparator()+ref; 00501 fr.clear(); // mingw's runtime will not clear on open 00502 fr.open(ref.c_str(), std::ios::in | std::ios::binary); 00503 } 00504 if(!fr.good()) { 00505 FAUDES_WRITE_CONSOLE("TestProtocol(): could not open/find reference \"" << gTestProtocolFr << "\""); 00506 return true; 00507 } 00508 // perform comparision 00509 int dline=-1; 00510 int cline=1; 00511 try{ 00512 while(true) { 00513 // read next char 00514 char cp = fp.get(); 00515 char cr= fr.get(); 00516 // eof 00517 if(fp.eof() && fr.eof()) { break; } 00518 if(!fp.good() || !fr.good()) { dline=cline; break;} 00519 // cheap normalize cr/lf: ignore \r (assume no double \r 00520 if( cp=='\r' && cr =='\r') continue; 00521 if( cp=='\r' && fp.eof()){ dline=cline; break;} 00522 if( cp=='\r') cp = fp.get(); 00523 if( cr=='\r' && fr.eof()){ dline=cline; break;} 00524 if( cr=='\r') cr = fr.get(); 00525 // count lines 00526 if( cr=='\n') cline++; 00527 // sense mitmatch 00528 if( cp!= cr ){dline=cline; break;} 00529 } 00530 } catch(std::ios::failure&) { 00531 throw Exception("TestProtocol()", "io error at line " + ToStringInteger(cline), 1); 00532 } 00533 // done 00534 if(dline>=0) { 00535 FAUDES_WRITE_CONSOLE("TestProtocol(): using reference " << ref << ""); 00536 FAUDES_WRITE_CONSOLE("TestProtocol(): found difference at line " << dline << ""); 00537 } 00538 return dline== -1; 00539 } 00540 00541 00542 00543 // declare loop callback 00544 static bool (*gBreakFnct)(void)=0; 00545 00546 // set loop callback 00547 void LoopCallback( bool pBreak(void)) { 00548 gBreakFnct=pBreak; 00549 } 00550 00551 // do loop callback 00552 // note: this function is meant to be "quiet" during normal 00553 // operation in order not to mess up console logging 00554 void LoopCallback(void){ 00555 if(!gBreakFnct) return; 00556 if(! (*gBreakFnct)() ) return; 00557 throw Exception("LoopCallback", "break on application request", 110); 00558 } 00559 00560 } // namespace faudes |
libFAUDES 2.20s --- 2011.10.12 --- c++ source docu by doxygen