|
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 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