00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "OSGConfig.h"
00044
00045 #if defined(WIN32_LEAN_AND_MEAN)
00046 #include "winsock2.h"
00047 #endif
00048
00049 #include <stdlib.h>
00050 #include <stdio.h>
00051 #include <math.h>
00052 #include <locale.h>
00053
00054 #include <string.h>
00055
00056 #include <vector>
00057
00058 #include "OSGBaseFunctions.h"
00059 #include "OSGThreadManager.h"
00060 #include "OSGSharedObjectHandler.h"
00061 #include "OSGFileSystem.h"
00062
00063 #ifdef OSG_GV_BETA
00064 #include <OSGFactoryController.h>
00065 #endif
00066
00067 OSG_BEGIN_NAMESPACE
00068
00069 static std::vector<InitFuncF> *osgInitFunctions = NULL;
00070 static std::vector<ExitFuncF> *osgSystemExitFunctions = NULL;
00071
00072 static std::vector<InitFuncF> *osgPreMPInitFunctions = NULL;
00073 static std::vector<ExitFuncF> *osgPostMPExitFunctions = NULL;
00074
00075 static std::vector<std::string> *osgPreloadSharedObject = NULL;
00076
00080 OSG_BASE_DLLMAPPING
00081 SystemState GlobalSystemState = Startup;
00082
00083 void osgGetHostname(char *szBuffer, UInt32 uiSize)
00084 {
00085
00086 if(getenv("OSG_HOSTNAME") != NULL)
00087 {
00088 strncpy(szBuffer, getenv("OSG_HOSTNAME"), uiSize);
00089 }
00090 else
00091 {
00092 gethostname(szBuffer, uiSize);
00093 }
00094 }
00095
00096
00106 void addInitFunction(InitFuncF initFunc)
00107 {
00108 if(osgInitFunctions == NULL)
00109 {
00110 osgInitFunctions = new std::vector<InitFuncF>(0);
00111 }
00112
00113 osgInitFunctions->push_back(initFunc);
00114 }
00115
00121 void addPreMPInitFunction(InitFuncF initFunc)
00122 {
00123 if(osgPreMPInitFunctions == NULL)
00124 {
00125 osgPreMPInitFunctions = new std::vector<InitFuncF>;
00126 }
00127
00128 osgPreMPInitFunctions->push_back(initFunc);
00129 }
00130
00132
00141 void addSystemExitFunction(ExitFuncF exitFunc)
00142 {
00143 if(osgSystemExitFunctions == NULL)
00144 {
00145 osgSystemExitFunctions = new std::vector<ExitFuncF>(0);
00146 }
00147
00148 osgSystemExitFunctions->push_back(exitFunc);
00149 }
00150
00156 void addPostMPExitFunction(ExitFuncF exitFunc)
00157 {
00158 if(osgPostMPExitFunctions == NULL)
00159 {
00160 osgPostMPExitFunctions = new std::vector<ExitFuncF>;
00161 }
00162
00163 osgPostMPExitFunctions->push_back(exitFunc);
00164 }
00165
00167
00174 void preloadSharedObject(const Char8 *szName)
00175 {
00176 if(osgPreloadSharedObject == NULL)
00177 {
00178 osgPreloadSharedObject = new std::vector<std::string>;
00179 }
00180
00181 std::string tmpString(szName);
00182
00183 osgPreloadSharedObject->push_back(tmpString);
00184 }
00185
00189 static void osgExitWrapper(void)
00190 {
00191 osgExit();
00192 }
00193
00203 struct OSG_BASE_DLLMAPPING CompileConfig
00204 {
00205
00209 CompileConfig(UInt16 major, UInt16 minor, UInt16 release,
00210 bool debug, bool dll, bool mt) :
00211 _major(major),
00212 _minor(minor),
00213 _release(release),
00214 _debug(debug),
00215 _dll(dll),
00216 _mt(mt)
00217 {}
00218
00219 bool compare(const CompileConfig& c);
00220
00222
00226 UInt16 _major;
00227 UInt16 _minor;
00228 UInt16 _release;
00229
00230
00231
00232 bool _mt;
00233 bool _dll;
00234 bool _debug;
00235
00237 };
00238
00239 bool CompileConfig::compare(const CompileConfig& c)
00240 {
00241 FDEBUG(("CompileConfig::compare: lib: version %d.%d.%d, %sdebug, %sdll, "
00242 "%smt \n",
00243 _major, _minor, _release,
00244 _debug?"":"non-", _dll?"":"non-", _mt?"":"non-"));
00245 FDEBUG(("CompileConfig::compare: prog: version %d.%d.%d, %sdebug, %sdll, "
00246 "%smt \n",
00247 c._major, c._minor, c._release,
00248 c._debug?"":"non-", c._dll?"":"non-", c._mt?"":"non-"));
00249
00250 if(_major != c._major)
00251 {
00252 FFATAL(("The program is compiled against version %d headers, "
00253 "but the library is version %d! It's a miracle it linked, "
00254 "but it will not work.\n", _major, c._major));
00255 return true;
00256 }
00257 if(_minor != c._minor)
00258 {
00259 FWARNING(("The program is compiled against version %d.%d headers, "
00260 "but the library is version %d.%d! This is not recommended "
00261 "use at your own risk.\n", _major, _minor, c._major, c._minor));
00262 }
00263 if(_release != c._release)
00264 {
00265 FNOTICE(("The program is compiled against version %d.%d.%d headers, "
00266 "but the library is version %d.%d.%d! This should "
00267 "work fine, but if you have problems please mention it "
00268 "in your report.\n", _major, _minor, _release,
00269 c._major, c._minor, c._release));
00270 }
00271 if(_mt != c._mt)
00272 {
00273 FFATAL(("The program is linked against the %s-threaded runtime lib, "
00274 "but the library is linked against the %s-threaded one! "
00275 "This will lead to memory corruption, please link the "
00276 "%s-threaded lib (use /M%s%s instead of /M%s%s)!\n",
00277 c._mt?"multi":"single",
00278 _mt?"multi":"single", _mt?"multi":"single",
00279 _mt?"D":"L", _debug?"d":"", _mt?"L":"D", _debug?"d":""));
00280 return true;
00281 }
00282
00283 #ifdef WIN32
00284 if(_debug != c._debug)
00285 {
00286 FFATAL(("The program is linked against the %sdebug runtime lib, "
00287 "but the library is linked against the %sdebug one! "
00288 "This will lead to memory corruption, please link the "
00289 "%sdebug lib (use /M%s%s instead of /M%s%s)!\n",
00290 c._debug?"":"non-",
00291 _debug?"":"non-", _debug?"":"non-",
00292 _mt?"D":"L", _debug?"d":"", _mt?"D":"L", _debug?"d":""));
00293 return true;
00294 }
00295 #endif
00296
00297 return false;
00298 }
00299
00303 bool osgInit(Int32, Char8 **, UInt16 major, UInt16 minor, UInt16 release,
00304 bool debug, bool dll, bool mt
00305 )
00306 {
00307 CompileConfig prog(major, minor, release, debug, dll, mt),
00308 lib(OSG_MAJOR_VERSION, OSG_MINOR_VERSION,
00309 OSG_RELEASE_VERSION,
00310 #ifdef _DEBUG
00311 true,
00312 #else
00313 false,
00314 #endif
00315 #ifdef _DLL
00316 true,
00317 #else
00318 false,
00319 #endif
00320 #ifdef _MT
00321 true
00322 #else
00323 false
00324 #endif
00325 );
00326
00327 if(lib.compare(prog))
00328 {
00329 exit(1);
00330 }
00331
00332
00333 setlocale(LC_NUMERIC, "English");
00334
00335 UInt32 i;
00336 bool returnValue = true;
00337
00338 returnValue = SharedObjectHandler::the()->initialize();
00339
00340 if(osgPreloadSharedObject != NULL)
00341 {
00342 for(UInt32 i = 0; i < osgPreloadSharedObject->size(); ++i)
00343 {
00344 SharedObjectHandler::the()->getOSGSharedObject(
00345 (*osgPreloadSharedObject)[i].c_str());
00346 }
00347 }
00348
00349 #ifdef WIN32
00350 std::string pathSep(";");
00351 #else
00352 std::string pathSep(":");
00353 #endif
00354
00355 char *szEnvLibs = getenv("OSG_LOAD_LIBS");
00356
00357 if(szEnvLibs != NULL)
00358 {
00359 std::string tmpString(szEnvLibs);
00360 string_token_iterator libIt(tmpString, pathSep.c_str());
00361
00362 string_token_iterator libEnd;
00363
00364 while(libIt != libEnd)
00365 {
00366 SharedObjectHandler::the()->getOSGSharedObject(
00367 (*libIt).c_str());
00368
00369 ++libIt;
00370 }
00371 }
00372
00373 const char *szEnvPlugins = getenv("OSG_PLUGIN_PATH");
00374 const char *szEnvPluginPattern = getenv("OSG_PLUGIN_PATTERN");
00375
00376 if(szEnvPlugins != NULL)
00377 {
00378 if(szEnvPluginPattern == NULL)
00379 {
00380 szEnvPluginPattern = PluginPattern;
00381 }
00382
00383 FINFO(("Get Plugins %s from %s\n",
00384 szEnvPluginPattern,
00385 szEnvPlugins));
00386
00387 std::vector<Char8 *> *pPlugins =
00388 Directory::getEntries(szEnvPlugins, szEnvPluginPattern);
00389
00390 if(pPlugins != NULL)
00391 {
00392 std::string szPluginName;
00393
00394 for(UInt32 i = 0; i < pPlugins->size(); ++i)
00395 {
00396 if((*pPlugins)[i][0] == '.')
00397 {
00398 if((*pPlugins)[i][1] == '\0')
00399 {
00400 continue;
00401 }
00402 else if((*pPlugins)[i][1] == '.' &&
00403 (*pPlugins)[i][2] == '\0')
00404 {
00405 continue;
00406 }
00407 }
00408
00409 szPluginName.assign(szEnvPlugins);
00410 szPluginName += '/';
00411 szPluginName += (*pPlugins)[i];
00412
00413 FINFO(("Loading plugin %s\n",
00414 szPluginName.c_str()));
00415
00416 SharedObjectHandler::the()->getSharedObject(
00417 szPluginName.c_str());
00418 }
00419 }
00420
00421 delete pPlugins;
00422 }
00423
00424 SharedObjectHandler::the()->dump();
00425
00426 if(returnValue == false)
00427 return returnValue;
00428
00429 if(osgPreMPInitFunctions != NULL)
00430 {
00431 for(i = 0; i < osgPreMPInitFunctions->size(); i++)
00432 {
00433 returnValue &= (*osgPreMPInitFunctions)[i]();
00434
00435 if(returnValue == false)
00436 break;
00437 }
00438
00439 osgPreMPInitFunctions->clear();
00440 }
00441
00442 if(returnValue == false)
00443 return returnValue;
00444
00445 returnValue &= ThreadManager::initialize();
00446
00447 if(returnValue == false)
00448 return returnValue;
00449
00450 if(osgInitFunctions != NULL)
00451 {
00452 for(i = 0; i < osgInitFunctions->size(); i++)
00453 {
00454 returnValue &= (*osgInitFunctions)[i]();
00455
00456 if(returnValue == false)
00457 break;
00458 }
00459
00460 osgInitFunctions->clear();
00461 }
00462
00463 if(returnValue == false)
00464 return returnValue;
00465
00466 #ifdef OSG_GV_BETA
00467 returnValue &= FactoryController::the()->initialize();
00468 #endif
00469
00470 GlobalSystemState = Running;
00471
00472 atexit(osgExitWrapper);
00473
00474 return returnValue;
00475 }
00476
00480 bool osgExit(void)
00481 {
00482 bool returnValue = true;
00483
00484 if(GlobalSystemState != Running)
00485 return true;
00486
00487 GlobalSystemState = Shutdown;
00488
00489 #ifdef OSG_GV_BETA
00490 returnValue &= FactoryController::the()->terminate();
00491 #endif
00492 SharedObjectHandler::the()->terminate();
00493
00494 if(osgSystemExitFunctions != NULL)
00495 {
00496 for(Int32 i = osgSystemExitFunctions->size() - 1; i >= 0; i--)
00497 {
00498 returnValue &= (*osgSystemExitFunctions)[i]();
00499
00500 if(returnValue == false)
00501 break;
00502 }
00503 }
00504
00505 returnValue &= ThreadManager::terminate();
00506
00507 if(osgPostMPExitFunctions != NULL)
00508 {
00509 for(Int32 i = osgPostMPExitFunctions->size() - 1; i >= 0; i--)
00510 {
00511 returnValue &= (*osgPostMPExitFunctions)[i]();
00512
00513 if(returnValue == false)
00514 break;
00515 }
00516 }
00517
00518 return returnValue;
00519 }
00520
00523 OSG_END_NAMESPACE
00524
00525
00526 OSG_USING_NAMESPACE
00527
00528
00529 InitFuncWrapper::InitFuncWrapper(const InitFuncF func)
00530 {
00531 addInitFunction(func);
00532 }
00533
00534
00535
00536 StaticInitFuncWrapper::StaticInitFuncWrapper(const InitFuncF func)
00537 {
00538 func();
00539 }
00540
00541
00553 string_token_iterator::string_token_iterator() : _str(0), _start(0), _end(0)
00554 {
00555 }
00556
00557 string_token_iterator::string_token_iterator(const std::string &str,
00558 const char *separator) :
00559 _separator(separator),
00560 _str(&str),
00561 _end(0)
00562 {
00563 find_next();
00564 }
00565
00566 string_token_iterator::string_token_iterator(const string_token_iterator & rhs) :
00567 _separator(rhs._separator),
00568 _str(rhs._str),
00569 _start(rhs._start),
00570 _end(rhs._end)
00571 {
00572 }
00573
00574 string_token_iterator & string_token_iterator::operator++()
00575 {
00576 find_next();
00577 return *this;
00578 }
00579
00580 string_token_iterator string_token_iterator::operator++(int)
00581 {
00582 string_token_iterator temp(*this);
00583 ++(*this);
00584 return temp;
00585 }
00586
00587 std::string string_token_iterator::operator*() const
00588 {
00589 if(_end == std::string::npos)
00590 {
00591 return std::string(*_str, _start, std::string::npos);
00592 }
00593 else
00594 {
00595 return std::string(*_str, _start, _end - _start);
00596 }
00597 }
00598
00599 bool string_token_iterator::operator==(const string_token_iterator & rhs) const
00600 {
00601 return (rhs._str == _str && rhs._start == _start && rhs._end == _end);
00602 }
00603
00604 bool string_token_iterator::operator!=(const string_token_iterator & rhs) const
00605 {
00606 return !(rhs == *this);
00607 }
00608
00609 void string_token_iterator::find_next(void)
00610 {
00611 _start = _str->find_first_not_of(_separator, _end);
00612
00613 if(_start == std::string::npos || _start >= _str->length())
00614 {
00615 _start = _end = 0;
00616 _str = 0;
00617 return;
00618 }
00619
00620 _end = _str->find_first_of(_separator, _start);
00621 }
00622
00623
00624
00625
00626 #ifdef __sgi
00627 #pragma set woff 1174
00628 #endif
00629
00630 #ifdef OSG_LINUX_ICC
00631 #pragma warning( disable : 177 )
00632 #endif
00633
00634 namespace
00635 {
00636 static Char8 cvsid_cpp[] = "@(#)$Id: $";
00637 static Char8 cvsid_hpp[] = OSGBASEFUNCTIONS_HEADER_CVSID;
00638 static Char8 cvsid_inl[] = OSGBASEFUNCTIONS_INLINE_CVSID;
00639 }