|
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(void) { 00295 if(!mMute) DoWrite(mLineBuffer.str()); 00296 mLineBuffer.str(""); 00297 } 00298 void ConsoleOut::DoWrite(const std::string& message) { 00299 std::ostream* sout=pStream; 00300 if(!sout) sout=&std::cerr; 00301 *sout << message; 00302 sout->flush(); 00303 } 00304 00305 // global instance 00306 ConsoleOut* ConsoleOut::spInstance=NULL; 00307 00308 00309 00310 // debugging: objectcount 00311 std::map<std::string,long int>* ObjectCount::mspMax=NULL; 00312 std::map<std::string,long int>* ObjectCount::mspCount=NULL; 00313 bool ObjectCount::msDone=false; 00314 ObjectCount::ObjectCount(void) { 00315 mspCount= new std::map<std::string,long int>(); 00316 mspMax= new std::map<std::string,long int>(); 00317 msDone=true; 00318 } 00319 void ObjectCount::Init(void) { 00320 if(!msDone) ObjectCount(); 00321 } 00322 void ObjectCount::Inc(const std::string& rTypeName) { 00323 if(!msDone) ObjectCount(); 00324 long int cnt = ((*mspCount)[rTypeName]+=1); 00325 if((*mspMax)[rTypeName]<cnt) (*mspMax)[rTypeName]=cnt; 00326 } 00327 void ObjectCount::Dec(const std::string& rTypeName) { 00328 if(!msDone) ObjectCount(); 00329 (*mspCount)[rTypeName]-=1; 00330 } 00331 00332 00333 // debugging: report on exit function 00334 void ExitFunction(void){ 00335 #ifdef FAUDES_DEBUG_CODE 00336 FAUDES_WRITE_CONSOLE("faudes::ExitFunction:"); 00337 // be sure its up and running 00338 ObjectCount::Init(); 00339 // get rid of all registry prototypes 00340 TypeRegistry::G()->Clear(); 00341 // prepare report 00342 std::map<std::string,long int>::iterator cit; 00343 cit=ObjectCount::mspCount->begin(); 00344 for(;cit!=ObjectCount::mspCount->end();cit++) { 00345 FAUDES_WRITE_CONSOLE( cit->first << ": #" << ToStringInteger(cit->second) << 00346 " (max #" << (*ObjectCount::mspMax)[cit->first] << ")"); 00347 } 00348 #endif 00349 } 00350 00351 00352 #ifdef FAUDES_DEBUG_CODE 00353 // report on exit install 00354 class ExitFunctionInstall { 00355 private: 00356 static bool mDone; 00357 static ExitFunctionInstall mInstance; 00358 ExitFunctionInstall(void) { 00359 if(mDone) return; 00360 FAUDES_WRITE_CONSOLE("ExitFunctionInstall()"); 00361 std::atexit(ExitFunction); 00362 mDone=true; 00363 } 00364 }; 00365 // exit function: global data 00366 bool ExitFunctionInstall::mDone=false; 00367 ExitFunctionInstall ExitFunctionInstall::mInstance; 00368 #endif 00369 00370 // test protocol: token writer 00371 TokenWriter* gTestProtocolTw=NULL; 00372 00373 // test protocol: setup 00374 void TestProtocol(const std::string& rSource) { 00375 if(gTestProtocolTw) delete gTestProtocolTw; 00376 std::string filename=rSource; 00377 // fix empty source 00378 if(filename=="") filename="test_dump"; 00379 // remove directory 00380 filename=ExtractFilename(filename); 00381 // remove extension 00382 std::string::size_type pos=0; 00383 for(;pos<filename.length();pos++) 00384 if(filename.at(pos)=='.') filename.at(pos)='_'; 00385 // append extension 00386 filename.append(".prot"); 00387 // prepend prefix 00388 filename.insert(0,"tmp_"); 00389 // initialise token writer 00390 gTestProtocolTw= new TokenWriter(filename); 00391 } 00392 00393 // test protocol: dump 00394 void TestProtocol(const std::string& rSource, const std::string& rMessage, const Type& rData, bool core) { 00395 if(!gTestProtocolTw) TestProtocol(rSource); 00396 gTestProtocolTw->WriteComment("%%% test mark: " + rMessage); 00397 if(core) rData.Write(*gTestProtocolTw); 00398 else rData.SWrite(*gTestProtocolTw); 00399 gTestProtocolTw->WriteComment(""); 00400 gTestProtocolTw->WriteComment(""); 00401 gTestProtocolTw->WriteComment(""); 00402 *gTestProtocolTw << "\n"; 00403 } 00404 void TestProtocol(const std::string& rSource, const std::string& rMessage, bool data) { 00405 Boolean fbool(data); 00406 TestProtocol(rSource,rMessage,fbool,true); 00407 } 00408 void TestProtocol(const std::string& rSource, const std::string& rMessage, long int data) { 00409 Integer fint(data); 00410 TestProtocol(rSource,rMessage,fint,true); 00411 } 00412 void TestProtocol(const std::string& rSource, const std::string& rMessage, const std::string& rData) { 00413 String fstr(rData); 00414 TestProtocol(rSource,rMessage,fstr,true); 00415 } 00416 00417 00418 // declare loop callback 00419 static bool (*gBreakFnct)(void)=0; 00420 00421 // set loop callback 00422 void LoopCallback( bool pBreak(void)) { 00423 gBreakFnct=pBreak; 00424 } 00425 00426 // do loop callback 00427 void LoopCallback(void){ 00428 if(!gBreakFnct) return; 00429 if(! (*gBreakFnct)() ) return; 00430 throw Exception("LoopCallback", "break on application request", 110); 00431 } 00432 00433 } // namespace faudes |
libFAUDES 2.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3