MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/Core/MOOSGenLib/MOOSGenLibGlobalHelper.cpp
Go to the documentation of this file.
00001 
00002 //
00003 //   MOOS - Mission Oriented Operating Suite
00004 //
00005 //   A suit of Applications and Libraries for Mobile Robotics Research
00006 //   Copyright (C) 2001-2005 Massachusetts Institute of Technology and
00007 //   Oxford University.
00008 //
00009 //   This software was written by Paul Newman at MIT 2001-2002 and Oxford
00010 //   University 2003-2005. email: pnewman@robots.ox.ac.uk.
00011 //
00012 //   This file is part of a  MOOS Core Component.
00013 //
00014 //   This program is free software; you can redistribute it and/or
00015 //   modify it under the terms of the GNU General Public License as
00016 //   published by the Free Software Foundation; either version 2 of the
00017 //   License, or (at your option) any later version.
00018 //
00019 //   This program is distributed in the hope that it will be useful,
00020 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00022 //   General Public License for more details.
00023 //
00024 //   You should have received a copy of the GNU General Public License
00025 //   along with this program; if not, write to the Free Software
00026 //   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00027 //   02111-1307, USA.
00028 //
00030 #ifdef _WIN32
00031 #pragma warning(disable : 4786)
00032 #endif
00033 
00034 
00035 #include "MOOSGenLibGlobalHelper.h"
00036 #include "MOOSGenLib/MOOSAssert.h"
00037 
00038 #include <algorithm>
00039 #include <iterator>
00040 #include <cctype>
00041 #include <string>
00042 #include <memory>
00043 #include <cstring>
00044 #include <map>
00045 #include <time.h>
00046 #include <stdarg.h>
00047 #include <math.h>
00048 
00049 #ifndef _WIN32
00050 #include <unistd.h>
00051 #include <sys/times.h>
00052 #include <sys/time.h>
00053 #include <termios.h>
00054 #include <dirent.h>
00055 #include <errno.h>
00056 #include <pthread.h>
00057 #endif
00058 
00059 #ifdef _WIN32
00060 #include "windows.h"
00061 #include "winbase.h"
00062 #include "winnt.h"
00063 #include <conio.h>
00064 #endif
00065 
00066 #include <iostream>
00067 #include <sstream>
00068 #include <vector>
00069 #include <iomanip>
00070 
00071 
00072 
00073 #include <sys/types.h>
00074 #include <sys/stat.h>
00075 #include <sys/timeb.h>
00076 #include <stdio.h>
00077 #include <iostream>
00078 
00079 #define ENABLE_WIN32_HPMOOSTIME 0
00080 #define MAX_TIME_WARP 100
00081 
00082 using namespace std;
00083 
00084 #ifndef PI
00085 #define     PI              3.141592653
00086 #endif
00087 #ifndef TWO_PI
00088 #define     TWO_PI          6.28318530717
00089 #endif
00090 
00091 #ifdef _WIN32
00092 typedef std::map<int,bool> THREAD2TRACE_MAP;
00093 #else
00094 typedef std::map<pthread_t,bool> THREAD2TRACE_MAP;
00095 #endif
00096 
00097 double gdfMOOSTimeWarp = 1.0;
00098 double gdfMOOSSkew =0.0;
00099 
00100 void    SetMOOSSkew(double dfSkew)
00101 {
00102     //printf("Clock Skew = %f seconds\n",dfSkew);
00103     gdfMOOSSkew = dfSkew;
00104 
00105     //a call to HPMOOSTime() sets up high performance clocks
00106     HPMOOSTime();
00107 }
00108 
00109 double GetMOOSSkew()
00110 {
00111         return gdfMOOSSkew;
00112 }
00113 
00114 
00115 
00119 bool IsLittleEndian()
00120 {
00121         static bool bTested = false;
00122         static bool bLittleEndIn = false;
00123 
00124         if(!bTested)
00125         {
00126                 short int word = 0x0001;
00127                 char *byte = (char *) &word;
00128                 bLittleEndIn = byte[0]==1;
00129                 bTested = true;
00130         }
00131 
00132         return bLittleEndIn;
00133 }
00134 
00135 
00136 bool gbWin32HPTiming = true;
00137 bool SetWin32HighPrecisionTiming(bool bEnable)
00138 {
00139 #ifndef _WIN32
00140         return false;
00141 #else
00142         gbWin32HPTiming = bEnable;
00143         return true;
00144 #endif
00145 
00146 }
00147 
00148 
00149 double MOOSLocalTime(bool bApplyTimeWarping)
00150 {
00151 #ifndef _WIN32
00152         double dfT=0.0;
00153         struct timeval TimeVal;
00154 
00155         if(gettimeofday(&TimeVal,NULL)==0)
00156         {
00157                 dfT = TimeVal.tv_sec+TimeVal.tv_usec/1000000.0;
00158         }
00159         else
00160         {
00161                 //lost the will to live.....
00162                 MOOSAssert(0);
00163                 dfT =-1;
00164         }
00165     if(bApplyTimeWarping)
00166                 return dfT*gdfMOOSTimeWarp;
00167     else
00168         return dfT;
00169 
00170 #else
00171         if( gbWin32HPTiming )
00172         {       
00173 
00174                 static LARGE_INTEGER liStart;
00175                 static LARGE_INTEGER liPerformanceFreq;
00176                 static double dfMOOSStart;
00177                 static bool bHPTimeInitialised=false;
00178 
00179                 //to do - we should consider thread saftery here..
00180                 if(!bHPTimeInitialised)
00181                 {                       
00182                 
00183                         //initialise with crude time
00184                         struct _timeb timebuffer;
00185                         _ftime( &timebuffer );
00186                         dfMOOSStart = timebuffer.time+ ((double)timebuffer.millitm)/1000;
00187 
00188                         QueryPerformanceCounter(&liStart);
00189                         QueryPerformanceFrequency(&liPerformanceFreq);
00190 
00191                         bHPTimeInitialised=true;
00192 
00193                         return bApplyTimeWarping ? dfMOOSStart*gdfMOOSTimeWarp :dfMOOSStart;
00194 
00195                 
00196                 }
00197                 else
00198                 {
00199                         //use fancy time
00200                         LARGE_INTEGER liNow;
00201                         QueryPerformanceCounter(&liNow);
00202 
00203                         double T = dfMOOSStart+(double)(liNow.QuadPart-liStart.QuadPart)/((double)(liPerformanceFreq.QuadPart));
00204 
00205             return bApplyTimeWarping ? T*gdfMOOSTimeWarp :T;
00206 
00207                 }
00208 
00209 
00210 
00211         }
00212         else
00213         {
00214                 //user has elected to use low precision win32 timing
00215                 struct _timeb timebuffer;
00216                 _ftime( &timebuffer );
00217         double T = timebuffer.time + ((double)timebuffer.millitm)/1000.0; 
00218 
00219         return bApplyTimeWarping ? T*gdfMOOSTimeWarp : T;
00220 
00221         }
00222 #endif
00223 
00224 
00225 }
00226 
00227 
00228 double HPMOOSTime(bool bApplyTimeWarping)
00229 {
00230         return MOOSTime(bApplyTimeWarping);
00231 }
00232 
00233 double MOOSTime(bool bApplyTimeWarping)
00234 {
00235     return MOOSLocalTime(bApplyTimeWarping)+gdfMOOSSkew;
00236 }
00237 
00238 double GetMOOSTimeWarp()
00239 {
00240     return gdfMOOSTimeWarp;
00241 }
00242 
00243 
00244 bool SetMOOSTimeWarp(double dfWarp)
00245 {
00246     if(dfWarp>0 && dfWarp<MAX_TIME_WARP)
00247     {
00248         gdfMOOSTimeWarp = dfWarp;
00249         return true;
00250     }
00251     return MOOSFail("Time warp must be positive and less than %f \n",MAX_TIME_WARP);
00252     
00253 }
00254 
00255 void MOOSPause(int nMS,bool bApplyTimeWarping)
00256 {
00257     if(bApplyTimeWarping)
00258             nMS = int(double(nMS)/gdfMOOSTimeWarp);
00259 #ifdef _WIN32
00260         ::Sleep(nMS);
00261 #else
00262 
00263     timespec TimeSpec;
00264     TimeSpec.tv_sec     = nMS / 1000;
00265     TimeSpec.tv_nsec    = (nMS%1000) *1000000;
00266 
00267     nanosleep(&TimeSpec,NULL);
00268 
00269 #endif
00270 }
00271 
00272 
00273 
00274 
00275 string MOOSChomp(string &sStr, const string &sTk,bool bInsensitive)
00276 {
00277     /*unsigned int*/ size_t  nPos = string::npos;
00278     if((nPos =MOOSStrFind(sStr,sTk,bInsensitive))!=string::npos)
00279     {
00280         string sRet;
00281         sRet = sStr.substr(0,nPos);
00282         sStr.erase(0,nPos+sTk.length());
00283         return sRet;
00284     }
00285     else
00286     {
00287         string sTmp = sStr;
00288         sStr="";
00289         return sTmp;
00290     }
00291 
00292 
00293 }
00294 
00295 //case insensitive character compare functor
00296 struct CompareInsensitive: public std::binary_function< char, char, bool >
00297 {
00298         bool operator()(char lhs, char rhs)
00299         {
00300                 return std::toupper(lhs) == std::toupper(rhs);
00301         }
00302     
00303 };
00304 
00305 //case insensitive find
00306 size_t  MOOSStrFind(const std::string & sSource,const std::string & sToken,bool bInsensitive)
00307 {
00308     
00309         if(bInsensitive)
00310     {
00311         std::string::const_iterator q = std::search(
00312                                               sSource.begin(), sSource.end(), 
00313                                               sToken.begin(), sToken.end(),
00314                                               CompareInsensitive());
00315         if(q==sSource.end())
00316             return std::string::npos;
00317         else
00318         {
00319             return std::distance(sSource.begin(),q);
00320         }
00321     }
00322         else
00323     {
00324         return sSource.find(sToken);
00325     }
00326 }
00327 
00328 
00329 bool MOOSValFromString(string & sVal,const string & sStr,const string & sTk,bool bInsensitive)
00330 {
00331     
00332     size_t  nPos = string::npos;
00333     size_t k = 0;
00334     while((nPos = MOOSStrFind(sStr.substr(k),sTk,bInsensitive))!=string::npos)
00335     {
00336         nPos+=k;
00337         //we have the start of the token at nPos
00338         //we need to be carefull here = there could be many spaces between token and =
00339         /*unsigned int*/ size_t  nEqualsPos = sStr.find('=',nPos);
00340         
00341         //can we find an "="?
00342         if(nEqualsPos!=string::npos)
00343         {
00344          
00345             //there should only be white space twixt token and equals
00346             std::string t = sStr.substr(nPos+sTk.size(),nEqualsPos-(nPos+sTk.size()));
00347             MOOSTrimWhiteSpace(t);
00348                         if(!t.empty())
00349             {
00350                 //k = nEqualsPos;
00351                 k=nPos+1;
00352                 continue;
00353             }
00354             
00355             sVal="";
00356 
00357             int nCommaPos =sStr.find(',',nEqualsPos);
00358 
00359             sVal.append(sStr,nEqualsPos+1,nCommaPos-nEqualsPos-1);
00360                         
00361             return true;
00362         }
00363         else
00364         {
00365             return false;
00366         }
00367 
00368     }
00369 
00370     return false;
00371 }
00372 
00373 bool MOOSValFromString(unsigned int  & nVal,const string & sStr,const string & sTk,bool bInsensitive)
00374 {
00375     int nIntVal;
00376     bool bSuccess = MOOSValFromString(nIntVal,sStr,sTk,bInsensitive);
00377     if(bSuccess)
00378         nVal = (unsigned int) nIntVal;
00379     return bSuccess;
00380 }
00381 
00382 
00383 bool MOOSValFromString(int  & nVal,const string & sStr,const string & sTk,bool bInsensitive)
00384 {
00385     string sVal;
00386 
00387     if(MOOSValFromString(sVal,sStr,sTk,bInsensitive))
00388     {
00389 
00390         /*unsigned int*/ size_t  nPos = sVal.find_first_not_of(' ');
00391 
00392         if(nPos!=string::npos)
00393         {
00394             char c = sVal[nPos];
00395             if(isdigit(c)  || c=='-' || c=='+')
00396             {
00397                 nVal = atoi(sVal.c_str());
00398                 return true;
00399             }
00400         }
00401 
00402     }
00403     return false;
00404 }
00405 
00406 
00407 bool MOOSValFromString(long  & nVal,const string & sStr,const string & sTk,bool bInsensitive)
00408 {
00409     string sVal;
00410 
00411     if(MOOSValFromString(sVal,sStr,sTk,bInsensitive))
00412     {
00413 
00414         /*unsigned int*/ size_t  nPos = sVal.find_first_not_of(' ');
00415 
00416         if(nPos!=string::npos)
00417         {
00418             char c = sVal[nPos];
00419             if(isdigit(c)  || c=='-' || c=='+')
00420             {
00421                 nVal = atol(sVal.c_str());
00422                 return true;
00423             }
00424         }
00425 
00426     }
00427     return false;
00428 }
00429 
00430 
00431 bool MOOSValFromString(bool  & bVal,const string & sStr,const string & sTk,bool bInsensitive)
00432 {
00433     string sVal;
00434 
00435     if(MOOSValFromString(sVal,sStr,sTk,bInsensitive))
00436     {
00437         MOOSRemoveChars(sVal," ");
00438         if(MOOSStrCmp(sVal,"true") || MOOSStrCmp(sVal,"1"))
00439             bVal =  true;
00440         else
00441             bVal =  false;
00442 
00443         return true;
00444     }
00445 
00446     return false;
00447 }
00448 
00449 
00450 bool MOOSValFromString(double  & dfVal,const string & sStr,const string & sTk,bool bInsensitive)
00451 {
00452     string sVal;
00453 
00454     if(MOOSValFromString(sVal,sStr,sTk,bInsensitive))
00455     {
00456 
00457         /*unsigned int*/ size_t  nPos = sVal.find_first_not_of(' ');
00458 
00459         if(nPos!=string::npos)
00460         {
00461             char c = sVal[nPos];
00462             if(isdigit(c) || c=='.' || c=='-' || c=='+')
00463             {
00464                 dfVal = atof(sVal.c_str());
00465                 return true;
00466             }
00467         }
00468 
00469     }
00470     return false;
00471 }
00472 
00473 
00474 
00475 bool MOOSValFromString(float  & fVal,const string & sStr,const string & sTk,bool bInsensitive)
00476 {
00477     string sVal;
00478 
00479     if(MOOSValFromString(sVal,sStr,sTk,bInsensitive))
00480     {
00481 
00482         /*unsigned int*/ size_t  nPos = sVal.find_first_not_of(' ');
00483 
00484         if(nPos!=string::npos)
00485         {
00486             char c = sVal[nPos];
00487             if(isdigit(c) || c=='.' || c=='-' || c=='+')
00488             {
00489                 fVal = static_cast<float> (atof(sVal.c_str()));
00490                 return true;
00491             }
00492         }
00493 
00494     }
00495     return false;
00496 }
00497 
00498 
00499 
00500 bool MOOSVectorFromString(const string & sStr,std::vector<double> & dfValVec,int & nRows, int & nCols)
00501 {
00502 
00503     /*unsigned int*/ size_t  nPos = sStr.find('[');
00504 
00505     if(nPos==string::npos)
00506         return false;
00507 
00508     nRows = atoi( sStr.data()+nPos+1);
00509 
00510 
00511     //if we have [456] then implicitlyt we mean [456x1]
00512     /*unsigned int*/ size_t  nXPos = sStr.find('x',nPos);
00513 
00514     nCols = 1;
00515     if(nXPos!=string::npos)
00516     {
00517         nCols = atoi( sStr.data()+nXPos+1);
00518         nPos = nXPos;
00519     }
00520 
00521     nPos = sStr.find('{',nPos);
00522 
00523     if(nPos==string::npos)
00524         return false;
00525 
00526 
00527     if(nCols==0 ||nRows==0)
00528         return false;
00529 
00530     dfValVec.clear();
00531     dfValVec.reserve(nRows*nCols);
00532 
00533 
00534     const char * pStr = sStr.data();
00535     for(int i = 1; i<=nRows;i++)
00536     {
00537         for(int j = 1; j<=nCols;j++)
00538         {
00539             double dfVal = atof(pStr+nPos+1);
00540 
00541             dfValVec.push_back(dfVal);
00542             nPos = sStr.find(',',nPos+1);
00543         }
00544     }
00545 
00546     return true;
00547 
00548 }
00549 
00550 
00551 bool MOOSVectorFromString(const string & sStr,std::vector<float> & fValVec,int & nRows, int & nCols)
00552 {
00553 
00554     /*unsigned int*/ size_t  nPos = sStr.find('[');
00555 
00556     if(nPos==string::npos)
00557         return false;
00558 
00559     nRows = atoi( sStr.data()+nPos+1);
00560 
00561 
00562     //if we have [456] then implicitlyt we mean [456x1]
00563     /*unsigned int*/ size_t  nXPos = sStr.find('x',nPos);
00564 
00565     nCols = 1;
00566     if(nXPos!=string::npos)
00567     {
00568         nCols = atoi( sStr.data()+nXPos+1);
00569         nPos = nXPos;
00570     }
00571 
00572     nPos = sStr.find('{',nPos);
00573 
00574     if(nPos==string::npos)
00575         return false;
00576 
00577 
00578     if(nCols==0 ||nRows==0)
00579         return false;
00580 
00581     fValVec.clear();
00582     fValVec.reserve(nRows*nCols);
00583 
00584 
00585     const char * pStr = sStr.data();
00586     for(int i = 1; i<=nRows;i++)
00587     {
00588         for(int j = 1; j<=nCols;j++)
00589         {
00590             double dfVal = atof(pStr+nPos+1);
00591 
00592             fValVec.push_back(static_cast<float> (dfVal));
00593             nPos = sStr.find(',',nPos+1);
00594         }
00595     }
00596 
00597     return true;
00598 
00599 }
00600 
00601 
00602 
00603 bool MOOSVectorFromString(const string & sStr,std::vector<unsigned int> & nValVec,int & nRows, int & nCols)
00604 {
00605 
00606 
00607     /*unsigned int*/ size_t  nPos = sStr.find('[');
00608 
00609     if(nPos==string::npos)
00610         return false;
00611 
00612     nRows = atoi( sStr.data()+nPos+1);
00613 
00614 
00615     //if we have [456] then implicitlyt we mean [456x1]
00616     /*unsigned int*/ size_t  nXPos = sStr.find('x',nPos);
00617 
00618     nCols = 1;
00619     if(nXPos!=string::npos)
00620     {
00621         nCols = atoi( sStr.data()+nXPos+1);
00622         nPos = nXPos;
00623     }
00624 
00625     nPos = sStr.find('{',nPos);
00626 
00627     if(nPos==string::npos)
00628         return false;
00629 
00630 
00631     if(nCols==0 ||nRows==0)
00632         return false;
00633 
00634     nValVec.clear();
00635     nValVec.reserve(nRows*nCols);
00636 
00637 
00638     const char * pStr = sStr.data();
00639     for(int i = 1; i<=nRows;i++)
00640     {
00641         for(int j = 1; j<=nCols;j++)
00642         {
00643             unsigned int nVal = atoi(pStr+nPos+1);
00644 
00645             nValVec.push_back(nVal);
00646             nPos = sStr.find(',',nPos+1);
00647         }
00648     }
00649 
00650     return true;
00651 
00652 }
00653 
00654 bool MOOSValFromString(std::vector<double> &dfValVec,
00655                        int &nRows,
00656                        int &nCols,
00657                        const std::string & sStr,
00658                        const std::string & sToken,
00659                                                 bool bInsensitive)
00660 {
00661        /*unsigned int*/ size_t  nPos = MOOSStrFind(sStr,sToken+'=',bInsensitive);
00662 
00663     if(nPos==string::npos)
00664         return false;
00665 
00666     return MOOSVectorFromString(sStr.substr(nPos),dfValVec,nRows,nCols);
00667 
00668 }
00669 
00670 bool MOOSValFromString(std::vector<unsigned int> &nValVec,                      
00671                        int &nRows,
00672                        int &nCols,
00673                        const std::string & sStr, 
00674                        const std::string & sToken,
00675                        bool bInsensitive)
00676 {
00677 
00678     size_t nPos = MOOSStrFind(sStr,sToken+'=',bInsensitive);
00679     
00680     if(nPos==string::npos)
00681         return false;
00682     
00683     return MOOSVectorFromString(sStr.substr(nPos),nValVec,nRows,nCols);   
00684 }
00685 
00686 
00687 
00688 bool MOOSValFromString(long long  & nVal,const string & sStr,const string & sTk,bool bInsensitive)
00689 {
00690     std::string sVal;
00691 
00692     if(MOOSValFromString(sVal,sStr,sTk,bInsensitive))
00693     {
00694         return (std::stringstream(sVal) >> nVal);
00695     }
00696 
00697     return false;
00698 }
00699 
00700 
00701 
00702 bool GetNextAlogLineByMessageName(std::istream & Input,
00703                                                                   const std::string & sMessageName,
00704                                                                   double & dfTime,
00705                                                                   std::string & sSource,
00706                                                                   std::string & sPayload)
00707 {
00708         
00709         while (!Input.eof()) 
00710         {
00711                 std::string sLine;
00712                 std::getline(Input,sLine);
00713                 if(!sLine.empty() && sLine[0]!='%')
00714                 {
00715                         std::string sWhat,sWho;
00716                         std::stringstream ss(sLine);
00717                         
00718                         ss>>dfTime;
00719                         
00720                         ss>>sWhat;
00721                         
00722                         if(MOOSStrCmp(sWhat,sMessageName))
00723                         {
00724                                 ss>>sSource;
00725                                 std::getline(ss,sPayload);
00726                                 return true;
00727                         }
00728                 }
00729         }
00730         return false;
00731 }
00732 
00733 
00734 double MOOS_ANGLE_WRAP(double dfAng)
00735 {
00736     if(dfAng<PI && dfAng>-PI)
00737         return dfAng;
00738 
00739         // Shift so that problem is now to wrap between (0, 2*PI)
00740         dfAng += PI;
00741 
00742         // Wrap
00743         dfAng = fmod(dfAng, 2*PI);
00744 
00745         // fmod seems to ignore the -ve...
00746         if (dfAng < 0) dfAng += 2*PI;
00747 
00748         // Shift back
00749         return (dfAng == 0.0 ? PI : dfAng-PI);
00750         
00751         // Old version did not cope with multiple wraps
00752         //return (dfAng+(dfAng>PI ? -TWO_PI :TWO_PI));
00753 }
00754 
00756 bool MOOSAbsLimit(double & dfVal,double dfLimit)
00757 {
00758     if(dfVal>dfLimit)
00759     {
00760         dfVal = dfLimit;
00761         return true;
00762     }
00763     else if(dfVal<-dfLimit)
00764     {
00765         dfVal = -dfLimit;
00766         return true;
00767     }
00768     return false;
00769 }
00770 
00771 bool MOOSStrCmp(string s1,string s2)
00772 {
00773     MOOSToUpper(s1);
00774     MOOSToUpper(s2);
00775 
00776     return s1 == s2;
00777 
00778 }
00779 
00780 
00781 string MOOSGetDate()
00782 {
00783 #ifndef _WIN32
00784     struct timeb timebuffer;
00785     ftime( &timebuffer );
00786 
00787     char *timeline = ctime( & ( timebuffer.time ) );
00788     char sResult[100];
00789     sprintf(sResult,"%s",timeline);
00790 
00791     string sAnswer =sResult;
00792 
00793     return sAnswer;
00794 #else
00795     struct _timeb timebuffer;
00796     _ftime( &timebuffer );
00797 
00798     char *timeline = ctime( & ( timebuffer.time ) );
00799     char sResult[100];
00800     sprintf(sResult,"%s",timeline);
00801 
00802     string sAnswer =sResult;
00803 
00804     return sAnswer;
00805 #endif
00806 
00807 
00808 }
00809 
00810 
00811 bool MOOSWildCmp(const std::string & sPattern, const std::string & sString ) 
00812 {
00813     const char * sWild = sPattern.c_str();
00814     const char * sStr = sString.c_str();
00815     // Based on code originally written by Jack Handy
00816     
00817     const char *cp = NULL, *mp = NULL;
00818     
00819     while ((*sStr) && (*sWild != '*')) 
00820     {
00821         //no active wild card in place
00822         if ((*sWild != *sStr) && (*sWild != '?')) 
00823         {
00824             //no single char wildcard in place and
00825             //differing characters
00826             return false;
00827         }
00828         
00829         //step on in lockstep
00830         sWild++;
00831         sStr++;
00832     }
00833     
00834     while (*sStr) 
00835     {
00836         
00837         //still more of sStr to explore
00838         if (*sWild == '*') 
00839         {
00840             if (!*++sWild) 
00841             {
00842                 //this * was the last character in the wildcard string
00843                 //any  remaining string is fine... 
00844                 return true;
00845             }
00846             
00847             //sWild is now one past the *
00848             mp = sWild;
00849             cp = sStr+1;
00850         }
00851         else if ((*sWild == *sStr) || (*sWild == '?')) 
00852         {
00853             //lock step advance
00854             sWild++;
00855             sStr++;
00856         }
00857         else 
00858         {
00859             //wildcard active
00860             sWild = mp;
00861             sStr = cp++;
00862         }
00863     }
00864     
00865     while (*sWild == '*') 
00866     {
00867         sWild++;
00868     }
00869     return !*sWild;
00870 }
00871 
00872 
00873 string MOOSGetTimeStampString()
00874 {
00875     struct tm *Now;
00876     time_t aclock;
00877     time( &aclock );
00878         
00879     Now = localtime( &aclock );
00880     //change suggested by toby schneider April 2009 
00881     //Now = gmtime( &aclock );
00882     char sTmp[1000];
00883 
00884     // Print local time as a string
00885 
00886     //14_5_1993_____9_30
00887     sprintf(sTmp, "_%d_%d_%d_____%.2d_%.2d",
00888         Now->tm_mday,
00889         Now->tm_mon+1,
00890         Now->tm_year+1900,
00891         Now->tm_hour,
00892         Now->tm_min         );
00893 
00894 
00895     string sAns = sTmp;
00896     return sAns;
00897 
00898 }
00899 
00900 void MOOSToUpper(string &str)
00901 {
00902     string::iterator p;
00903 
00904     for(p = str.begin();p!=str.end();p++)
00905     {
00906         *p = toupper(*p);
00907     }
00908 }
00909 
00910 bool MOOSIsNumeric(string  str)
00911 {
00912     MOOSTrimWhiteSpace(str);
00913     if(str.find_first_not_of("1234567890.eE-+")==string::npos)
00914     {
00915         return true;
00916     }
00917 
00918     return false;
00919 }
00920 void MOOSTrimWhiteSpace(string &str)
00921 {
00922     if(!str.empty())
00923     {
00924         /*unsigned int*/ size_t  p = str.find_first_not_of(" \t\n\r");
00925         /*unsigned int*/ size_t  q = str.find_last_not_of(" \t\n\r");
00926 
00927         if(p==string::npos || q==string::npos)
00928         {
00929             str="";
00930         }
00931         else
00932         {
00933             str = str.substr(p,q-p+1);
00934         }
00935     }
00936 }
00937 
00938 void MOOSRemoveChars(string & sStr,const string & sTok)
00939 {
00940 
00941     for(unsigned int i = 0;i<sTok.length();i++)
00942     {
00943         string::iterator q = remove(sStr.begin(),sStr.end(),sTok[i]);
00944 
00945         int n = sStr.length()-(sStr.end()-q);
00946 
00947         sStr.resize(n);
00948     }
00949 
00950 }
00951 
00952 
00953 
00954 int MOOSGetch()
00955 {
00956 #ifndef _WIN32
00957 
00958     int c, fd=0;
00959     struct termios term, oterm;
00960 
00961     /* get the terminal settings */
00962     tcgetattr(fd, &oterm);
00963 
00964     /* get a copy of the settings, which we modify */
00965     memcpy(&term, &oterm, sizeof(term));
00966 
00967     /* put the terminal in non-canonical mode, any
00968     reads will wait until a character has been
00969     pressed. This function will not time out */
00970     term.c_lflag = term.c_lflag & (!ICANON);
00971     term.c_cc[VMIN] = 1;
00972     term.c_cc[VTIME] = 0;
00973     tcsetattr(fd, TCSANOW, &term);
00974 
00975     /* get a character. c is the character */
00976     c=getchar();
00977 
00978     /* reset the terminal to its original state */
00979     tcsetattr(fd, TCSANOW, &oterm);
00980 
00981     /* return the charcter */
00982     return c;
00983 #else
00984     return _getch();
00985 #endif
00986 
00987 
00988 }
00989 
00990 
00991 
00992 string MOOSFormat(const char * FmtStr,...)
00993 {
00994     const unsigned int MAX_TRACE_STR = 1024;
00995 
00996     if(strlen(FmtStr)<MAX_TRACE_STR)
00997     {
00998         //double the size for format length!
00999         char buf[MAX_TRACE_STR*2];
01000 
01001         va_list arg_ptr;
01002 
01003         va_start( arg_ptr,FmtStr);
01004 
01005 
01006 #ifdef _WIN32
01007         int n= _vsnprintf(buf,sizeof(buf),FmtStr,arg_ptr);
01008 #else
01009         int n = vsnprintf(buf,sizeof(buf),FmtStr,arg_ptr);
01010 #endif
01011 
01012         if(n==sizeof(buf))
01013         {
01014             MOOSTrace("WARNING MOOFormat() TRUNCATED TO %d CHARS",sizeof(buf));
01015         }
01016 
01017         va_end( arg_ptr );
01018 
01019         return string(buf);
01020     }
01021     else
01022     {
01023         return "STRING TOO LONG TO FORMAT";
01024     }
01025 }
01026 
01027 
01028 
01029 
01030 bool MOOSFail(const char * FmtStr,...)
01031 {
01032     const unsigned int MAX_TRACE_STR = 1024;
01033 
01034     if(strlen(FmtStr)<MAX_TRACE_STR)
01035     {
01036         //double the size for format length!
01037         char buf[MAX_TRACE_STR*2];
01038 
01039         va_list arg_ptr;
01040 
01041         va_start( arg_ptr,FmtStr);
01042 
01043 #ifdef _WIN32
01044         int n= _vsnprintf(buf,sizeof(buf),FmtStr,arg_ptr);
01045 #else
01046         int n = vsnprintf(buf,sizeof(buf),FmtStr,arg_ptr);
01047 #endif
01048 
01049         if(n==sizeof(buf))
01050         {
01051             MOOSTrace("WARNING MOOFormat() TRUNCATED TO %d CHARS",sizeof(buf));
01052         }
01053 
01054         va_end( arg_ptr );
01055 
01056         MOOSTrace(string(buf)+"\n");
01057 
01058     }
01059     return false;
01060 }
01061 
01062 
01063 //this is library scope mapping of threadid to a flag
01064 //specifying whether or no a thread should allow MOOSTracing.
01065 THREAD2TRACE_MAP gThread2TraceMap;
01066 
01067 void InhibitMOOSTraceInThisThread(bool bInhibit)
01068 {
01069     
01070 #ifdef _WIN32
01071     DWORD Me = GetCurrentThreadId(); 
01072 #else
01073     pthread_t Me =  pthread_self();
01074 #endif
01075     
01076     gThread2TraceMap[Me] = bInhibit;
01077 }
01078 
01079 void MOOSTrace(string  sStr)
01080 {
01081     MOOSTrace("%s",sStr.c_str());
01082 }
01083 
01084 
01085 void MOOSTrace(const char *FmtStr,...)
01086 {
01087     
01088     //initially we wqnt to check to see if printing
01089     //from this thread has been inhibited by a call to
01090     //
01091 #ifdef _WIN32
01092     DWORD Me = GetCurrentThreadId(); 
01093 #else
01094     pthread_t Me =  pthread_self();
01095 #endif
01096 
01097     if(!gThread2TraceMap.empty())
01098     
01099     {
01100         THREAD2TRACE_MAP::iterator p = gThread2TraceMap.find(Me);
01101     
01102         //have we been told to be quiet?
01103         if(p!=gThread2TraceMap.end())
01104             if(p->second==true)
01105                 return;
01106     }
01107     
01108     const unsigned int MAX_TRACE_STR = 2048;
01109 
01110     if(strlen(FmtStr)<MAX_TRACE_STR)
01111     {
01112         //double the size for format length!
01113         char buf[MAX_TRACE_STR*2];
01114 
01115         va_list arg_ptr;
01116 
01117         va_start( arg_ptr,FmtStr);
01118 
01119 #ifdef _WIN32
01120         int n= _vsnprintf(buf,sizeof(buf),FmtStr,arg_ptr);
01121 #else
01122         int n = vsnprintf(buf,sizeof(buf),FmtStr,arg_ptr);
01123 #endif
01124 
01125         if(n==sizeof(buf))
01126         {
01127             MOOSTrace("WARNING MOOSTrace() TRUNCATED TO %d CHARS",sizeof(buf));
01128         }
01129 
01130         va_end( arg_ptr );
01131 
01132 #ifdef _WIN32
01133         OutputDebugString(buf);
01134 #endif
01135 
01136     // arh changed this because if you wanted to add a percent character in the string, it would first
01137     // be processed by the _vsnprintf above, then placed in 'buf'.
01138     // Problem is that fprintf finds the '%' in buf and expects us to provide more arguments!
01139         //fprintf(stderr,buf);
01140     fputs(buf, stderr);
01141 
01142     }
01143 }
01144 
01145 double MOOSDeg2Rad(double dfDeg)
01146 {
01147     return dfDeg*PI/180.0;
01148 }
01149 
01150 double MOOSRad2Deg(double dfRad)
01151 {
01152     return dfRad*180.0/PI;
01153 }
01154 
01155 
01156 bool MOOSGetValueFromToken(STRING_LIST & sParams,const string & sToken,string & sVal)
01157 {
01158     STRING_LIST::iterator p;
01159 
01160     for(p = sParams.begin();p!=sParams.end();p++)
01161     {
01162         string sLine = *p;
01163 
01164         if(sLine.find("=")!=string::npos)
01165         {
01166             MOOSRemoveChars(sLine," \t\r");
01167 
01168             string sTok = MOOSChomp(sLine,"=");
01169 
01170             if(MOOSStrCmp(sTok,sToken))
01171             {
01172                 sVal = sLine;
01173                 return true;
01174             }
01175         }
01176     }
01177     return false;
01178 }
01179 
01180 string MOOSThirdPartyStatusString(string sStatusCommand)
01181 {
01182     ostringstream os;
01183     os<<"STATUS:"<<sStatusCommand.c_str()<<","<<ends;
01184     string sAnswer = os.str();
01185     return sAnswer;
01186 
01187 }
01188 
01189 
01190 string MOOSThirdPartyActuationString(double * pdfRudder,double * pdfElevator,double * pdfThrust)
01191 {
01192     ostringstream os;
01193 
01194     os<<"ACTUATION:";
01195     if(pdfRudder!=NULL)
01196     {
01197         os<<"RUDDER="<<*pdfRudder<<",";
01198     }
01199     if(pdfElevator!=NULL)
01200     {
01201         os<<"ELEVATOR="<<*pdfElevator<<",";
01202     }
01203     if(pdfThrust!=NULL)
01204     {
01205         os<<"THRUST="<<*pdfThrust<<",";
01206     }
01207     os<<ends;
01208 
01209     string sAnswer = os.str();
01210 
01211     return sAnswer;
01212 
01213 }
01214 
01215 
01216 double MOOSNormalInv(double dfArea)
01217 {
01218     double dfNormInv[] ={
01219         0,   -2.3263,   -2.0537,   -1.8808 ,  -1.7507,   -1.6449,   -1.5548 ,  -1.4758,   -1.4051,   -1.3408,   -1.2816,   -1.2265,   -1.1750,
01220             -1.1264,   -1.0803,   -1.0364,   -0.9945,   -0.9542,   -0.9154,   -0.8779 ,  -0.8416,   -0.8064,   -0.7722,   -0.7388,   -0.7063,  -0.6745 ,
01221             -0.6433,   -0.6128,   -0.5828,   -0.5534,   -0.5244,   -0.4959,   -0.4677 ,  -0.4399,   -0.4125,   -0.3853,   -0.3585,   -0.3319,   -0.3055,
01222             -0.2793,   -0.2533,   -0.2275,   -0.2019,   -0.1764,   -0.1510,   -0.1257 ,  -0.1004,   -0.0753,   -0.0502,   -0.0251,         0,    0.0251,
01223             0.0502,    0.0753,    0.1004,    0.1257,    0.1510,    0.1764,    0.2019 ,   0.2275,    0.2533,    0.2793,    0.3055,    0.3319,    0.3585,
01224             0.3853,    0.4125,    0.4399,    0.4677,    0.4959,    0.5244,    0.5534 ,   0.5828,    0.6128,    0.6433,    0.6745,    0.7063,    0.7388,
01225             0.7722,    0.8064,    0.8416,    0.8779,    0.9154,    0.9542,    0.9945 ,   1.0364,    1.0803,    1.1264,    1.1750,    1.2265,    1.2816,
01226             1.3408,    1.4051,    1.4758,    1.5548,    1.6449,    1.7507,    1.8808 ,   2.0537,    2.3263,       0};
01227 
01228         if(dfArea<0)
01229             return -1e60;
01230         if(dfArea>=1)
01231             return 1e60;
01232 
01233         int nNdx = (int)(dfArea*100.0);
01234 
01235         return dfNormInv[nNdx];
01236 
01237 
01238 
01239 }
01240 
01241 double MOOSUniformRandom(double dfMin, double dfMax)
01242 {
01243     double dfRand = ((double)rand())/RAND_MAX;
01244     return dfRand*(dfMax-dfMin)+dfMin;
01245 }
01246 
01247 int MOOSDiscreteUniform(int nMin, int nMax)
01248 {
01249     double dfVal = (MOOSUniformRandom(nMin,nMax));
01250 
01251     int nVal = (int)(dfVal);
01252 
01253     if(dfVal-nVal>0.5)
01254     {
01255         nVal++;
01256     }
01257 
01258     return nVal;
01259 
01260 }
01261 
01262 
01263 
01264 double MOOSWhiteNoise(double Sigma)
01265 {
01266     double fac, u1, u2, v1, v2, s;
01267     int u;
01268     static int iset = 0;
01269     static double gset;
01270 
01271 
01272     if (iset == 0)
01273     {
01274         s = 0;
01275         do
01276         {
01277             u = rand ();
01278             u1 = (double) u / RAND_MAX;
01279             u = rand ();
01280             u2 = (double) u / RAND_MAX;
01281             v1 = 2 * u1 - 1;
01282             v2 = 2 * u2 - 1;
01283             s = v1 * v1 + v2 * v2;
01284         } while (s > 1);
01285 
01286 
01287         fac = sqrt ((-2 * log (s)) / s);
01288 
01289 
01290         gset = (v1 * fac);
01291         iset = 1;
01292         v2 = v2 * fac;
01293         return v2*Sigma;
01294     }
01295     else
01296     {
01297         iset = 0;
01298         return gset*Sigma;
01299     }
01300 }
01301 
01302 
01303 
01304 
01307 void Progress(double dfPC)
01308 {
01309     if(dfPC>=1.0)
01310     {
01311         MOOSTrace("\n");
01312     }
01313     else
01314     {
01315         char T[40];
01316         memset(T,'\0',sizeof(T));
01317         int n = (int)(dfPC*sizeof(T));
01318         memset(T,'*',n);
01319         printf("\r%.2f  %s",dfPC,T);
01320     }
01321 }
01322 
01323 
01324 
01326 std::string DoubleVector2String(const std::vector<double> & V)
01327 {
01328     std::stringstream ss;
01329     Write(ss,V);
01330     return ss.str();
01331 }
01332 
01334 std::stringstream & Write (std::stringstream & os,const std::vector<double> & Vec)
01335 {
01336     int nRows = Vec.size();
01337 
01338     os<<std::setiosflags(std::ios::scientific);
01339     os<<std::setprecision(3);
01340 
01341     os <<'['<<nRows<<"x1]{";
01342 
01343     os.unsetf(std::ios::scientific);
01344 
01345     for ( int i = 0; i<nRows; i++ )
01346     {
01347         os.setf(std::ios::fixed);
01348         os<<std::setprecision(4);
01349         os<<Vec[i];
01350         if(i!=nRows-1)
01351         {
01352             os<<',';
01353         }
01354     }
01355     os<<"}";
01356 
01357     return os;
01358 }
01359 
01361 std::stringstream & Write (std::stringstream & os,const std::vector<int> & Vec)
01362 {
01363     int nRows = Vec.size();
01364 
01365     os <<'['<<nRows<<"x1]{";
01366 
01367     for ( int i = 0; i<nRows; i++ )
01368     {
01369         os<<Vec[i];
01370         if(i!=nRows-1)
01371         {
01372             os<<',';
01373         }
01374     }
01375     os<<"}";
01376 
01377     return os;
01378 }
01379 
01382 bool GetDirectoryContents(const std::string & sPath,
01383                           std::list<std::string> &sContents, bool bFiles)
01384 {
01385 #ifdef _WIN32
01386     WIN32_FIND_DATA sfd;
01387     std::string sTemplate = sPath+"/*.*";
01388     HANDLE h = FindFirstFile( sTemplate.c_str(), &sfd );
01389     int n = 0;
01390     if ( h != INVALID_HANDLE_VALUE )
01391     {
01392         do
01393         {
01394             std::string sPossible = std::string(sfd.cFileName);
01395             //look to remove . and ..
01396             if(sPossible!="." && sPossible!="..")
01397             {
01398                 if(bFiles && !(sfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
01399                 {
01400                     // do something with the file name sfd.cFileName...
01401                     sContents.push_front(sPossible);
01402                 }
01403                 else if(!bFiles && (sfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
01404                 {
01405                     // do something with the file name sfd.cFileName...
01406                     sContents.push_front(sPossible);
01407                 }
01408             }
01409 
01410         } while ( FindNextFile( h, &sfd ) );
01411     }
01412     else
01413     {
01414         return MOOSFail("failed to read directory %s",sPath.c_str());
01415     }
01416 
01417     return true;
01418 #else
01419 
01420     struct dirent **namelist;
01421     int n;
01422 
01423     //system call...
01424     n = scandir(sPath.c_str(), &namelist, 0, alphasort);
01425 
01426     if (n < 0)
01427     {
01428         //uh oh...
01429         return MOOSFail("error reading directory contents %s\n",strerror(errno));
01430     }
01431     else
01432     {
01433         while(n--)
01434         {
01435 
01436             std::string sName(namelist[n]->d_name);
01437             std::string sFullName = sPath+"/"+sName;
01438 
01439             //ask a few pertinent questions.
01440             struct stat FileStatus;
01441             stat(sFullName.c_str(),&FileStatus);
01442 
01443             //look to remove . and ..
01444             if(sName!="." && sName!="..")
01445             {
01446 
01447                 if(bFiles &&S_ISREG(FileStatus.st_mode))
01448                 {
01449                     //only want to get regular files
01450                     sContents.push_front(sName);
01451                 }
01452                 else if(!bFiles && S_ISDIR(FileStatus.st_mode))
01453                 {
01454                     //only want directories
01455                     sContents.push_front(sName);
01456                 }
01457             }
01458             //C-like clean up..
01459             free(namelist[n]);
01460         }
01461         //C-like clean up
01462         free(namelist);
01463     }
01464 
01465     return true;
01466 #endif
01467 }
01468 
01470 bool MOOSFileParts(std::string sFullPath, std::string & sPath,std::string &sFile,std::string & sExtension)
01471 {
01472     /*unsigned int*/ size_t nBreak;
01473     /*unsigned int*/ size_t nFS = sFullPath.find_last_of("/");
01474 
01475 #ifdef _WIN32
01476     //Windows user use either forward ot backslash to delimit (or even a combination...)
01477     /*unsigned int*/ size_t nBS = sFullPath.find_last_of("\\");
01478     if(nBS!=std::string::npos)
01479     {
01480         if(nFS!=std::string::npos)
01481         {
01482             //look like a mixture - which is the final one
01483             nBreak=nBS>nFS ? nBS:nFS;
01484         }
01485         else
01486         {
01487             //looks like they are using only back slashes
01488             nBreak= nBS;
01489         }
01490     }
01491     else
01492     {
01493         //looks like they are using nix style forward slashes
01494         nBreak = nFS;
01495     }
01496 #else
01497     nBreak = nFS;
01498 #endif
01499 
01500     std::string sFullFile;
01501     if(nBreak==std::string::npos)
01502     {
01503         //there is no path
01504         sPath = "";
01505         sFullFile = sFullPath;
01506     }
01507     else
01508     {
01509         //split path and file
01510         sPath = sFullPath.substr(0,nBreak);
01511         sFullFile = sFullPath.substr(nBreak+1);
01512     }
01513 
01514     //finally look to split on "." for extension if it is there.
01515         // sFile = MOOSChomp(sFullFile,".");
01516     // sExtension = sFullFile;
01517         size_t nDot = sFullFile.find_last_of(".");
01518         if (nDot==std::string::npos)
01519         {
01520                 // No extension:
01521                 sFile = sFullFile;
01522                 sExtension = "";
01523         }
01524         else
01525         {
01526                 // Split extension:
01527                 sFile = sFullFile.substr(0,nDot);
01528                 sExtension = sFullFile.substr(nDot+1);
01529         }
01530     return true;
01531 }
01532 
01533 
01534 bool MOOSCreateDirectory(const std::string & sDirectory)
01535 {
01536 
01537 #if _WIN32
01538     int bOK  = ::CreateDirectory(sDirectory.c_str(),NULL);
01539 
01540     if(!bOK)
01541     {
01542         DWORD TheError = GetLastError();
01543 
01544         if(TheError!=ERROR_ALREADY_EXISTS)
01545         {
01546 
01547             LPVOID lpMsgBuf;
01548             FormatMessage(
01549                 FORMAT_MESSAGE_ALLOCATE_BUFFER |
01550                 FORMAT_MESSAGE_FROM_SYSTEM |
01551                 FORMAT_MESSAGE_IGNORE_INSERTS,
01552                 NULL,
01553                 TheError,
01554                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
01555                 (LPTSTR) &lpMsgBuf,
01556                 0,
01557                 NULL
01558                 );
01559             // Process any inserts in lpMsgBuf.
01560             // ...
01561             // Display the string.
01562             MOOSTrace("Error %ld  making directory :  \"%s\"\n",TheError,(LPCTSTR)lpMsgBuf);
01563 
01564             // Free the buffer.
01565             LocalFree( lpMsgBuf );
01566 
01567             return false;
01568         }
01569 
01570     }
01571 #else
01572     if(mkdir(sDirectory.c_str(),0755)==-1)
01573     {
01574         switch(errno)
01575         {
01576         case EEXIST:
01577             break;
01578         default:
01579             MOOSTrace("Error %ld  making directory :  \"%s\"\n",errno,strerror(errno));
01580             return false;
01581         }
01582     }
01583 
01584 #endif
01585 
01586 
01587 
01588     return true;
01589 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines