diff --git a/src/Airports/xmlloader.cxx b/src/Airports/xmlloader.cxx index dc24ec6c1..d5b90ad2f 100644 --- a/src/Airports/xmlloader.cxx +++ b/src/Airports/xmlloader.cxx @@ -75,15 +75,15 @@ bool XMLLoader::findAirportData(const std::string& aICAO, fileName.append(".xml"); } - string_list sc = globals->get_fg_scenery(); + PathList sc = globals->get_fg_scenery(); char buffer[128]; ::snprintf(buffer, 128, "%c/%c/%c/%s.%s", aICAO[0], aICAO[1], aICAO[2], aICAO.c_str(), fileName.c_str()); - for (string_list_iterator it = sc.begin(); it != sc.end(); ++it) { + for (PathList::const_iterator it = sc.begin(); it != sc.end(); ++it) { // fg_senery contains empty strings as "markers" (see FGGlobals::set_fg_scenery) - if (!it->empty()) { + if (!it->isNull()) { SGPath path(*it); path.append("Airports"); path.append(string(buffer)); diff --git a/src/GUI/AircraftModel.cxx b/src/GUI/AircraftModel.cxx index 774608d1c..1bc27cb88 100644 --- a/src/GUI/AircraftModel.cxx +++ b/src/GUI/AircraftModel.cxx @@ -516,8 +516,8 @@ void AircraftItemModel::scanDirs() QStringList dirs = m_paths; - Q_FOREACH(std::string ap, globals->get_aircraft_paths()) { - dirs << QString::fromStdString(ap); + Q_FOREACH(SGPath ap, globals->get_aircraft_paths()) { + dirs << QString::fromStdString(ap.utf8Str()); } SGPath rootAircraft(globals->get_fg_root()); diff --git a/src/GUI/CocoaHelpers.mm b/src/GUI/CocoaHelpers.mm index 126b17c21..f93ff1edc 100644 --- a/src/GUI/CocoaHelpers.mm +++ b/src/GUI/CocoaHelpers.mm @@ -133,14 +133,14 @@ SGPath platformDefaultDataPath() namespace flightgear { -std::string Options::platformDefaultRoot() const +SGPath Options::platformDefaultRoot() const { CocoaAutoreleasePool ap; NSURL* url = [[NSBundle mainBundle] resourceURL]; SGPath dataDir(URLToPath(url)); dataDir.append("data"); - return dataDir.str(); + return dataDir; } } // of namespace flightgear diff --git a/src/GUI/FGFontCache.cxx b/src/GUI/FGFontCache.cxx index e5a0752a3..6d42e1c5c 100644 --- a/src/GUI/FGFontCache.cxx +++ b/src/GUI/FGFontCache.cxx @@ -177,9 +177,9 @@ void FGFontCache::init() if (!_initialized) { char *envp = ::getenv("FG_FONTS"); if (envp != NULL) { - _path.set(envp); + _path = SGPath::fromEnv("FG_FONTS"); } else { - _path.set(globals->get_fg_root()); + _path = globals->get_fg_root(); _path.append("Fonts"); } _initialized = true; diff --git a/src/GUI/QtLauncher.cxx b/src/GUI/QtLauncher.cxx index f407f43fc..ed99bfa6f 100644 --- a/src/GUI/QtLauncher.cxx +++ b/src/GUI/QtLauncher.cxx @@ -386,7 +386,7 @@ void initApp(int& argc, char** argv) QSettings::setDefaultFormat(QSettings::IniFormat); QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, - QString::fromStdString(globals->get_fg_home())); + QString::fromStdString(globals->get_fg_home().utf8Str())); // reset numeric / collation locales as described at: // http://doc.qt.io/qt-5/qcoreapplication.html#details @@ -655,7 +655,7 @@ void QtLauncher::setSceneryPaths() SGPath terraSyncDir(downloadDir.toStdString()); terraSyncDir.append("TerraSync"); if (terraSyncDir.exists()) { - globals->append_fg_scenery(terraSyncDir.utf8Str()); + globals->append_fg_scenery(terraSyncDir); } } diff --git a/src/GUI/SetupRootDialog.cxx b/src/GUI/SetupRootDialog.cxx index c0db35804..46c9f476c 100644 --- a/src/GUI/SetupRootDialog.cxx +++ b/src/GUI/SetupRootDialog.cxx @@ -90,7 +90,7 @@ bool SetupRootDialog::runDialog(PromptState prompt) return true; } -std::string SetupRootDialog::restoreUserSelectedRoot() +SGPath SetupRootDialog::restoreUserSelectedRoot() { QSettings settings; QString path = settings.value("fg-root").toString(); @@ -153,8 +153,8 @@ bool SetupRootDialog::validateVersion(QString path) bool SetupRootDialog::defaultRootAcceptable() { - std::string r = flightgear::Options::sharedInstance()->platformDefaultRoot(); - QString defaultRoot = QString::fromStdString(r); + SGPath r = flightgear::Options::sharedInstance()->platformDefaultRoot(); + QString defaultRoot = QString::fromStdString(r.utf8Str()); return validatePath(defaultRoot) && validateVersion(defaultRoot); } @@ -200,8 +200,8 @@ void SetupRootDialog::onDownload() void SetupRootDialog::onUseDefaults() { - std::string r = flightgear::Options::sharedInstance()->platformDefaultRoot(); - m_browsedPath = QString::fromStdString(r); + SGPath r = flightgear::Options::sharedInstance()->platformDefaultRoot(); + m_browsedPath = QString::fromStdString(r.utf8Str()); globals->set_fg_root(r); QSettings settings; settings.remove("fg-root"); // remove any setting @@ -211,7 +211,7 @@ void SetupRootDialog::onUseDefaults() void SetupRootDialog::updatePromptText() { QString t; - QString curRoot = QString::fromStdString(globals->get_fg_root()); + QString curRoot = QString::fromStdString(globals->get_fg_root().utf8Str()); switch (m_promptState) { case DefaultPathCheckFailed: t = tr("This copy of FlightGear does not include the base data files. " \ diff --git a/src/GUI/SetupRootDialog.hxx b/src/GUI/SetupRootDialog.hxx index 2a1d4eae3..d294c1938 100644 --- a/src/GUI/SetupRootDialog.hxx +++ b/src/GUI/SetupRootDialog.hxx @@ -24,6 +24,8 @@ #include +#include + namespace Ui { class SetupRootDialog; @@ -38,7 +40,7 @@ public: static bool runDialog(bool usingDefaultRoot); - static std::string restoreUserSelectedRoot(); + static SGPath restoreUserSelectedRoot(); private slots: void onBrowse(); diff --git a/src/GUI/gui_funcs.cxx b/src/GUI/gui_funcs.cxx index ce3c79eb0..7b4922dae 100644 --- a/src/GUI/gui_funcs.cxx +++ b/src/GUI/gui_funcs.cxx @@ -439,7 +439,7 @@ namespace { using namespace flightgear; - SGPath nextScreenshotPath(const std::string& screenshotDir) + SGPath nextScreenshotPath(const SGPath& screenshotDir) { char filename[32]; static int count = 1; @@ -497,12 +497,11 @@ namespace fgSetMouseCursor(MOUSE_CURSOR_NONE); - string dir = fgGetString("/sim/paths/screenshot-dir"); - if (dir.empty()) - dir = SGPath::desktop().str(); + SGPath dir = SGPath::fromUtf8(fgGetString("/sim/paths/screenshot-dir")); + if (dir.isNull()) + dir = SGPath::desktop(); - _path.set(dir + '/'); - if (_path.create_dir( 0755 )) { + if (!dir.exists() && dir.create_dir( 0755 )) { SG_LOG(SG_GENERAL, SG_ALERT, "Cannot create screenshot directory '" << dir << "'. Trying home directory."); dir = globals->get_fg_home(); diff --git a/src/Main/AircraftDirVisitorBase.hxx b/src/Main/AircraftDirVisitorBase.hxx index 78e7c90b8..7705dbdf2 100644 --- a/src/Main/AircraftDirVisitorBase.hxx +++ b/src/Main/AircraftDirVisitorBase.hxx @@ -43,11 +43,10 @@ protected: VisitResult visitAircraftPaths() { - const string_list& paths(globals->get_aircraft_paths()); - string_list::const_iterator it = paths.begin(); + const PathList& paths(globals->get_aircraft_paths()); + PathList::const_iterator it = paths.begin(); for (; it != paths.end(); ++it) { - SGPath p(*it); - VisitResult vr = visitDir(p, 0); + VisitResult vr = visitDir(*it, 0); if (vr != VISIT_CONTINUE) { return vr; } diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx index 98ea4b67c..8bce2f2be 100644 --- a/src/Main/fg_commands.cxx +++ b/src/Main/fg_commands.cxx @@ -538,7 +538,7 @@ do_materials_reload (const SGPropertyNode * arg) SGMaterialLib* new_matlib = new SGMaterialLib; SGPath mpath( globals->get_fg_root() ); mpath.append( fgGetString("/sim/rendering/materials-file") ); - bool loaded = new_matlib->load(globals->get_fg_root(), + bool loaded = new_matlib->load(globals->get_fg_root().local8BitStr(), mpath.str(), globals->get_props()); diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 8b724d134..d95c80cab 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -172,7 +172,7 @@ string fgBasePackageVersion(const SGPath& base_path) { return string(); } - sg_gzifstream in( p.str() ); + sg_gzifstream in( p ); if (!in.is_open()) { return string(); } @@ -277,27 +277,18 @@ public: } private: - SGPath getAircraftPaths() { - string_list pathList = globals->get_aircraft_paths(); - SGPath aircraftPaths; - string_list::const_iterator it = pathList.begin(); - if (it != pathList.end()) { - aircraftPaths.set(*it); - it++; + std::string getAircraftPaths() + { + return SGPath::join(globals->get_aircraft_paths(), ";"); } - for (; it != pathList.end(); ++it) { - aircraftPaths.add(*it); - } - return aircraftPaths; - } bool checkCache() { - if (globals->get_fg_root() != _cache->getStringValue("fg-root", "")) { + if (globals->get_fg_root().utf8Str() != _cache->getStringValue("fg-root", "")) { return false; // cache mismatch } - if (getAircraftPaths().str() != _cache->getStringValue("fg-aircraft", "")) { + if (getAircraftPaths() != _cache->getStringValue("fg-aircraft", "")) { return false; // cache mismatch } @@ -377,7 +368,7 @@ static SGPath platformDefaultDataPath() bool fgInitHome() { SGPath dataPath = SGPath::fromEnv("FG_HOME", platformDefaultDataPath()); - globals->set_fg_home(dataPath.c_str()); + globals->set_fg_home(dataPath); simgear::Dir fgHome(dataPath); if (!fgHome.exists()) { @@ -387,7 +378,7 @@ bool fgInitHome() if (!fgHome.exists()) { flightgear::fatalMessageBox("Problem setting up user data", "Unable to create the user-data storage folder at: '" - + dataPath.str() + "'"); + + dataPath.utf8Str() + "'"); return false; } @@ -503,13 +494,12 @@ static void initAircraftDirsNasalSecurity() sim->removeChildren("fg-aircraft"); int index = 0; - string_list const aircraft_paths = globals->get_aircraft_paths(); - for( string_list::const_iterator it = aircraft_paths.begin(); - it != aircraft_paths.end(); - ++it, ++index ) + const PathList& aircraft_paths = globals->get_aircraft_paths(); + for (PathList::const_iterator it = aircraft_paths.begin(); + it != aircraft_paths.end(); ++it, ++index ) { SGPropertyNode* n = sim->getChild("fg-aircraft", index, true); - n->setStringValue(*it); + n->setStringValue(it->utf8Str()); n->setAttribute(SGPropertyNode::WRITE, false); } } @@ -638,20 +628,18 @@ fgInitNav () // General house keeping initializations bool fgInitGeneral() { - string root; SG_LOG( SG_GENERAL, SG_INFO, "General Initialization" ); SG_LOG( SG_GENERAL, SG_INFO, "======= ==============" ); - root = globals->get_fg_root(); - if ( ! root.length() ) { + if ( globals->get_fg_root().isNull() ) { // No root path set? Then bail ... SG_LOG( SG_GENERAL, SG_ALERT, "Cannot continue without a path to the base package " << "being defined." ); return false; } - SG_LOG( SG_GENERAL, SG_INFO, "FG_ROOT = " << '"' << root << '"' << endl ); + SG_LOG( SG_GENERAL, SG_INFO, "FG_ROOT = " << '"' << globals->get_fg_root() << '"' << endl ); // Note: browser command is hard-coded for Mac/Windows, so this only affects other platforms globals->set_browser(fgGetString("/sim/startup/browser-app", WEB_BROWSER)); @@ -683,8 +671,8 @@ void fgOutputSettings() SG_LOG( SG_GENERAL, SG_INFO, "download-dir = " << '"' << fgGetString("/sim/paths/download-dir") << '"' ); SG_LOG( SG_GENERAL, SG_INFO, "terrasync-dir = " << '"' << fgGetString("/sim/terrasync/scenery-dir") << '"' ); - SG_LOG( SG_GENERAL, SG_INFO, "aircraft-search-paths = \n\t" << simgear::strutils::join(globals->get_aircraft_paths(), "\n\t") ); - SG_LOG( SG_GENERAL, SG_INFO, "scenery-search-paths = \n\t" << simgear::strutils::join(globals->get_fg_scenery(), "\n\t") ); + SG_LOG( SG_GENERAL, SG_INFO, "aircraft-search-paths = \n\t" << SGPath::join(globals->get_aircraft_paths(), "\n\t") ); + SG_LOG( SG_GENERAL, SG_INFO, "scenery-search-paths = \n\t" << SGPath::join(globals->get_fg_scenery(), "\n\t") ); } // This is the top level init routine which calls all the other @@ -743,7 +731,7 @@ void fgCreateSubsystems(bool duringReset) { SGPath mpath( globals->get_fg_root() ); mpath.append( fgGetString("/sim/rendering/materials-file") ); - if ( ! globals->get_matlib()->load(globals->get_fg_root(), mpath.str(), + if ( ! globals->get_matlib()->load(globals->get_fg_root().local8BitStr(), mpath.str(), globals->get_props()) ) { throw sg_io_exception("Error loading materials file", mpath); } diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx index 796b18cd8..5a51cbc0d 100644 --- a/src/Main/globals.cxx +++ b/src/Main/globals.cxx @@ -108,10 +108,11 @@ public: // try each aircraft dir in turn std::string res(aResource, 9); // resource path with 'Aircraft/' removed - const string_list& dirs(globals->get_aircraft_paths()); - string_list::const_iterator it = dirs.begin(); + const PathList& dirs(globals->get_aircraft_paths()); + PathList::const_iterator it = dirs.begin(); for (; it != dirs.end(); ++it) { - SGPath p(*it, res); + SGPath p(*it); + p.append(res); if (p.exists()) { return p; } @@ -131,8 +132,7 @@ public: virtual SGPath resolve(const std::string& aResource, SGPath&) const { - const char* aircraftDir = fgGetString("/sim/aircraft-dir"); - SGPath p(aircraftDir); + SGPath p = SGPath::fromUtf8(fgGetString("/sim/aircraft-dir")); p.append(aResource); return p.exists() ? p : SGPath(); } @@ -248,7 +248,7 @@ FGGlobals::~FGGlobals() } // set the fg_root path -void FGGlobals::set_fg_root (const std::string &root) { +void FGGlobals::set_fg_root (const SGPath &root) { SGPath tmp(root); fg_root = tmp.realpath(); @@ -256,9 +256,9 @@ void FGGlobals::set_fg_root (const std::string &root) { tmp.append( "data" ); tmp.append( "version" ); if ( tmp.exists() ) { - fgGetNode("BAD_FG_ROOT", true)->setStringValue(fg_root); - fg_root += "/data"; - fgGetNode("GOOD_FG_ROOT", true)->setStringValue(fg_root); + fgGetNode("BAD_FG_ROOT", true)->setStringValue(fg_root.utf8Str()); + fg_root.append("data"); + fgGetNode("GOOD_FG_ROOT", true)->setStringValue(fg_root.utf8Str()); SG_LOG(SG_GENERAL, SG_ALERT, "***\n***\n*** Warning: changing bad FG_ROOT/--fg-root to '" << fg_root << "'\n***\n***"); } @@ -268,7 +268,7 @@ void FGGlobals::set_fg_root (const std::string &root) { SGPropertyNode *n = fgGetNode("/sim", true); n->removeChild("fg-root", 0); n = n->getChild("fg-root", 0, true); - n->setStringValue(fg_root.c_str()); + n->setStringValue(fg_root.utf8Str()); n->setAttribute(SGPropertyNode::WRITE, false); simgear::ResourceManager::instance()->addBasePath(fg_root, @@ -276,15 +276,15 @@ void FGGlobals::set_fg_root (const std::string &root) { } // set the fg_home path -void FGGlobals::set_fg_home (const std::string &home) { - SGPath tmp(home); - fg_home = tmp.realpath(); +void FGGlobals::set_fg_home (const SGPath &home) +{ + fg_home = home.realpath(); } PathList FGGlobals::get_data_paths() const { PathList r(additional_data_paths); - r.push_back(SGPath(fg_root)); + r.push_back(fg_root); return r; } @@ -329,69 +329,74 @@ SGPath FGGlobals::find_data_dir(const std::string& pathSuffix) const return SGPath(); } -void FGGlobals::append_fg_scenery (const std::string &paths, bool secure) +void FGGlobals::append_fg_scenery (const PathList &paths, bool secure) +{ + BOOST_FOREACH(const SGPath& path, paths) { + append_fg_scenery(path); + } +} + +void FGGlobals::append_fg_scenery (const SGPath &path, bool secure) { SGPropertyNode* sim = fgGetNode("/sim", true); - // find first unused fg-scenery property in /sim + // find first unused fg-scenery property in /sim int propIndex = 0; while (sim->getChild("fg-scenery", propIndex) != NULL) { - ++propIndex; + ++propIndex; } - BOOST_FOREACH(const SGPath& path, sgPathSplit( paths )) { - SGPath abspath(path.realpath()); - if (!abspath.exists()) { - SG_LOG(SG_GENERAL, SG_WARN, "scenery path not found:" << abspath.str()); - continue; - } + SGPath abspath(path.realpath()); + if (!abspath.exists()) { + SG_LOG(SG_GENERAL, SG_WARN, "scenery path not found:" << abspath); + return; + } - // check for duplicates - string_list::const_iterator ex = std::find(fg_scenery.begin(), fg_scenery.end(), abspath.str()); - if (ex != fg_scenery.end()) { - SG_LOG(SG_GENERAL, SG_INFO, "skipping duplicate add of scenery path:" << abspath.str()); - continue; - } + // check for duplicates + PathList::const_iterator ex = std::find(fg_scenery.begin(), fg_scenery.end(), abspath); + if (ex != fg_scenery.end()) { + SG_LOG(SG_GENERAL, SG_INFO, "skipping duplicate add of scenery path:" << abspath); + return; + } - // tell the ResouceManager about the scenery path - // needed to load Models from this scenery path - simgear::ResourceManager::instance()->addBasePath(abspath.str(), - simgear::ResourceManager::PRIORITY_DEFAULT); + // tell the ResouceManager about the scenery path + // needed to load Models from this scenery path + simgear::ResourceManager::instance()->addBasePath(abspath.str(), + simgear::ResourceManager::PRIORITY_DEFAULT); - simgear::Dir dir(abspath); - SGPath terrainDir(dir.file("Terrain")); - SGPath objectsDir(dir.file("Objects")); + simgear::Dir dir(abspath); + SGPath terrainDir(dir.file("Terrain")); + SGPath objectsDir(dir.file("Objects")); - // this code used to add *either* the base dir, OR add the - // Terrain and Objects subdirs, but the conditional logic was commented - // out, such that all three dirs are added. Unfortunately there's - // no information as to why the change was made. - fg_scenery.push_back(abspath.str()); - if (secure) { - secure_fg_scenery.push_back(abspath.str()); - } + // this code used to add *either* the base dir, OR add the + // Terrain and Objects subdirs, but the conditional logic was commented + // out, such that all three dirs are added. Unfortunately there's + // no information as to why the change was made. + fg_scenery.push_back(abspath); + if (secure) { + secure_fg_scenery.push_back(abspath); + } - if (terrainDir.exists()) { - fg_scenery.push_back(terrainDir.str()); - } + if (terrainDir.exists()) { + fg_scenery.push_back(terrainDir); + } - if (objectsDir.exists()) { - fg_scenery.push_back(objectsDir.str()); - } + if (objectsDir.exists()) { + fg_scenery.push_back(objectsDir); + } - // insert a marker for FGTileEntry::load(), so that - // FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "", - // "B/Terrain", "B/Objects", ""] - fg_scenery.push_back(""); + // insert a marker for FGTileEntry::load(), so that + // FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "", + // "B/Terrain", "B/Objects", ""] + fg_scenery.push_back(SGPath()); - // make scenery dirs available to Nasal - SGPropertyNode* n = sim->getChild("fg-scenery", propIndex++, true); - n->setStringValue(abspath.str()); - n->setAttribute(SGPropertyNode::WRITE, false); - - // temporary fix so these values survive reset - n->setAttribute(SGPropertyNode::PRESERVE, true); - } // of path list iteration + // make scenery dirs available to Nasal + SGPropertyNode* n = sim->getChild("fg-scenery", propIndex++, true); + n->setStringValue(abspath.utf8Str()); + n->setAttribute(SGPropertyNode::WRITE, false); + + // temporary fix so these values survive reset + n->setAttribute(SGPropertyNode::PRESERVE, true); } void FGGlobals::clear_fg_scenery() @@ -407,18 +412,18 @@ void FGGlobals::set_catalog_aircraft_path(const SGPath& path) catalog_aircraft_dir = path; } -string_list FGGlobals::get_aircraft_paths() const +PathList FGGlobals::get_aircraft_paths() const { - string_list r; + PathList r; if (!catalog_aircraft_dir.isNull()) { - r.push_back(catalog_aircraft_dir.str()); + r.push_back(catalog_aircraft_dir); } r.insert(r.end(), fg_aircraft_dirs.begin(), fg_aircraft_dirs.end()); return r; } -void FGGlobals::append_aircraft_path(const std::string& path) +void FGGlobals::append_aircraft_path(const SGPath& path) { SGPath dirPath(path); if (!dirPath.exists()) { @@ -438,13 +443,11 @@ void FGGlobals::append_aircraft_path(const std::string& path) dirPath = acSubdir; } - std::string abspath = dirPath.realpath(); - fg_aircraft_dirs.push_back(abspath); + fg_aircraft_dirs.push_back(dirPath.realpath()); } -void FGGlobals::append_aircraft_paths(const std::string& path) +void FGGlobals::append_aircraft_paths(const PathList& paths) { - string_list paths = sgPathSplit(path); for (unsigned int p = 0; pget_fg_root(), globals->get_props()); + simgear::SGModelLib::init(globals->get_fg_root().local8BitStr(), globals->get_props()); TimeManager* timeManager = (TimeManager*) globals->get_subsystem("time"); timeManager->init(); diff --git a/src/Main/options.cxx b/src/Main/options.cxx index 659c052c1..75199e744 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -852,15 +852,16 @@ fgOptRoc( const char *arg ) static int fgOptFgScenery( const char *arg ) { - globals->append_fg_scenery(arg, true); + globals->append_fg_scenery(SGPath::pathsFromLocal8Bit(arg), true); return FG_OPTIONS_OK; } static int fgOptTerrasyncDir( const char *arg ) { - globals->append_fg_scenery(arg, true); - fgSetString("/sim/terrasync/scenery-dir", arg); + SGPath p = SGPath::fromLocal8Bit(arg); + globals->append_fg_scenery(p, true); + fgSetString("/sim/terrasync/scenery-dir", p.utf8Str()); return FG_OPTIONS_OK; } @@ -1340,8 +1341,8 @@ fgOptVersion( const char *arg ) cerr << "FG_SCENERY="; int didsome = 0; - string_list scn = globals->get_fg_scenery(); - for (string_list::const_iterator it = scn.begin(); it != scn.end(); it++) + PathList scn = globals->get_fg_scenery(); + for (PathList::const_iterator it = scn.begin(); it != scn.end(); it++) { if (didsome) cerr << ":"; didsome++; @@ -2007,7 +2008,7 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath) // fg-root/fg-home/fg-aircraft and hence control what files Nasal can access std::string name_for_error = homedir.empty() ? appDataConfig.str() : config.str(); if( ! hostname.empty() ) { - config.set(globals->get_fg_root()); + config = globals->get_fg_root(); config.append( "system.fgfsrc" ); config.concat( "." ); config.concat( hostname ); @@ -2018,7 +2019,7 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath) } } - config.set(globals->get_fg_root()); + config = globals->get_fg_root(); config.append( "system.fgfsrc" ); if (config.exists()) { flightgear::fatalMessageBox("Unsupported configuration", @@ -2029,13 +2030,14 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath) void Options::initPaths() { - BOOST_FOREACH(const string& paths, valuesForOption("fg-aircraft")) { + BOOST_FOREACH(const string& pathOpt, valuesForOption("fg-aircraft")) { + PathList paths = SGPath::pathsFromLocal8Bit(pathOpt); globals->append_aircraft_paths(paths); } const char* envp = ::getenv("FG_AIRCRAFT"); if (envp) { - globals->append_aircraft_paths(envp); + globals->append_aircraft_paths(SGPath::pathsFromEnv("FG_AIRCRAFT")); } } @@ -2057,22 +2059,22 @@ void Options::initAircraft() } if (p->showAircraft) { - vector path_list; + PathList path_list; fgOptLogLevel( "alert" ); // First place to check is the 'Aircraft' sub-directory in $FG_ROOT - path_list.push_back( SGPath( globals->get_fg_root() ) ); - path_list.back().append("Aircraft"); + SGPath rootAircraft = globals->get_fg_root(); + rootAircraft.append("Aircraft"); + path_list.push_back(rootAircraft); // Additionally, aircraft may also be found in user-defined places // (via $FG_AIRCRAFT or with the '--fg-aircraft' option) + PathList aircraft_paths = globals->get_aircraft_paths(); - string_list aircraft_paths = globals->get_aircraft_paths(); - for (string_list::iterator it = aircraft_paths.begin(); - it != aircraft_paths.end(); ++it) - path_list.push_back( SGPath(*it)); + path_list.insert(path_list.end(), aircraft_paths.begin(), + aircraft_paths.end()); fgShowAircraft(path_list); exit(0); @@ -2354,7 +2356,7 @@ OptionResult Options::processOptions() // now options are process, do supplemental fixup const char *envp = ::getenv( "FG_SCENERY" ); if (envp) { - globals->append_fg_scenery(envp, true); + globals->append_fg_scenery(SGPath::pathsFromEnv("FG_SCENERY"), true); } // download dir fix-up @@ -2394,10 +2396,10 @@ OptionResult Options::processOptions() // always add the terrasync location, regardless of whether terrasync // is enabled or not. This allows us to toggle terrasync on/off at // runtime and have things work as expected - const string_list& scenery_paths(globals->get_fg_scenery()); - if (std::find(scenery_paths.begin(), scenery_paths.end(), terrasyncDir) == scenery_paths.end()) { + const PathList& scenery_paths(globals->get_fg_scenery()); + if (std::find(scenery_paths.begin(), scenery_paths.end(), SGPath(terrasyncDir)) == scenery_paths.end()) { // terrasync dir is not in the scenery paths, add it - globals->append_fg_scenery(terrasyncDir); + globals->append_fg_scenery(SGPath(terrasyncDir)); } if (addFGDataScenery) { @@ -2405,7 +2407,7 @@ OptionResult Options::processOptions() // ensure this path is added last SGPath root(globals->get_fg_root()); root.append("Scenery"); - globals->append_fg_scenery(root.str()); + globals->append_fg_scenery(root); } return FG_OPTIONS_OK; @@ -2544,20 +2546,20 @@ void Options::showUsage() const } #if defined(__CYGWIN__) -string Options::platformDefaultRoot() const +SGPath Options::platformDefaultRoot() const { return "../data"; } #elif defined(SG_WINDOWS) -string Options::platformDefaultRoot() const +SGPath Options::platformDefaultRoot() const { return "..\\data"; } #elif defined(SG_MAC) // platformDefaultRoot defined in CocoaHelpers.mm #else -string Options::platformDefaultRoot() const +SGPath Options::platformDefaultRoot() const { return PKGLIBDIR; } @@ -2565,24 +2567,24 @@ string Options::platformDefaultRoot() const void Options::setupRoot(int argc, char **argv) { - string root; + SGPath root; bool usingDefaultRoot = false; if (isOptionSet("fg-root")) { - root = valueForOption("fg-root"); // easy! - SG_LOG(SG_GENERAL, SG_INFO, "set from command-line argument: fg_root = " << root ); + root = SGPath::fromLocal8Bit(valueForOption("fg-root").c_str()); // easy! + SG_LOG(SG_GENERAL, SG_INFO, "set from command-line argument: fg_root = " << root ); } else { // Next check if fg-root is set as an env variable char *envp = ::getenv( "FG_ROOT" ); if ( envp != NULL ) { - root = envp; - SG_LOG(SG_GENERAL, SG_INFO, "set from FG_ROOT env var: fg_root = " << root ); + root = SGPath::fromLocal8Bit(envp); + SG_LOG(SG_GENERAL, SG_INFO, "set from FG_ROOT env var: fg_root = " << root ); } else { #if defined(HAVE_QT) flightgear::initApp(argc, argv); root = SetupRootDialog::restoreUserSelectedRoot(); #endif - if (root.empty()) { + if (root.isNull()) { usingDefaultRoot = true; root = platformDefaultRoot(); SG_LOG(SG_GENERAL, SG_INFO, "platform default fg_root = " << root ); diff --git a/src/Main/options.hxx b/src/Main/options.hxx index 4f618213b..3679b72ff 100644 --- a/src/Main/options.hxx +++ b/src/Main/options.hxx @@ -142,7 +142,7 @@ public: */ static bool checkForArg(int argc, char* argv[], const char* arg); - std::string platformDefaultRoot() const; + SGPath platformDefaultRoot() const; private: void showUsage() const; diff --git a/src/Main/util.cxx b/src/Main/util.cxx index a661a5212..3269a379f 100644 --- a/src/Main/util.cxx +++ b/src/Main/util.cxx @@ -92,8 +92,8 @@ void fgInitAllowedPaths() } read_allowed_paths.clear(); write_allowed_paths.clear(); - std::string fg_root = SGPath(globals->get_fg_root()).realpath(); - std::string fg_home = SGPath(globals->get_fg_home()).realpath(); + std::string fg_root = globals->get_fg_root().realpath(); + std::string fg_home = globals->get_fg_home().realpath(); #if defined(_MSC_VER) /*for MS compilers */ || defined(_WIN32) /*needed for non MS windows compilers like MingW*/ std::string sep = "\\"; #else @@ -103,32 +103,28 @@ void fgInitAllowedPaths() read_allowed_paths.push_back(fg_home + sep + "*"); read_allowed_paths.push_back(fg_root); read_allowed_paths.push_back(fg_home); - string_list const aircraft_paths = globals->get_aircraft_paths(); - string_list const scenery_paths = globals->get_secure_fg_scenery(); + + const PathList& aircraft_paths = globals->get_aircraft_paths(); + const PathList& scenery_paths = globals->get_secure_fg_scenery(); // not plain fg_scenery, to avoid making // /sim/terrasync/scenery-dir a security hole + PathList read_paths = aircraft_paths; + read_paths.insert(read_paths.end(), scenery_paths.begin(), scenery_paths.end()); - const string_list * path_lists_to_add[] = { - &aircraft_paths, - &scenery_paths - }; - for( size_t i = 0; i < sizeof(path_lists_to_add)/sizeof(path_lists_to_add[0]); i++ ) - { - for( string_list::const_iterator it = path_lists_to_add[i]->begin(); it != path_lists_to_add[i]->end();++it ) + for( PathList::const_iterator it = read_paths.begin(); it != read_paths.end(); ++it ) { // if we get the initialization order wrong, better to have an // obvious error than a can-read-everything security hole... - if (it->empty() || fg_root.empty() || fg_home.empty()){ + if (it->isNull() || fg_root.empty() || fg_home.empty()) { flightgear::fatalMessageBox("Nasal initialization error", "Empty string in FG_ROOT, FG_HOME, FG_AIRCRAFT or FG_SCENERY", "or fgInitAllowedPaths() called too early"); exit(-1); } - read_allowed_paths.push_back(SGPath(*it).realpath() + sep + "*"); - read_allowed_paths.push_back(SGPath(*it).realpath()); + read_allowed_paths.push_back(it->realpath() + sep + "*"); + read_allowed_paths.push_back(it->realpath()); } - } write_allowed_paths.push_back(fg_home + sep + "*.sav"); write_allowed_paths.push_back(fg_home + sep + "*.log"); @@ -141,13 +137,14 @@ void fgInitAllowedPaths() write_allowed_paths.push_back(fg_home + sep + "Input" + sep + "Joysticks" + sep + "*.xml"); // Check that it works - if(!fgValidatePath(globals->get_fg_home() + "/../no.log",true).empty() || - !fgValidatePath(globals->get_fg_home() + "/no.logt",true).empty() || - !fgValidatePath(globals->get_fg_home() + "/nolog",true).empty() || - !fgValidatePath(globals->get_fg_home() + "no.log",true).empty() || - !fgValidatePath(globals->get_fg_home() + "\\..\\no.log",false).empty() || - fgValidatePath(globals->get_fg_home() + "/aircraft-data/yes..xml",true).empty() || - fgValidatePath(globals->get_fg_root() + "/.\\yes.bmp",false).empty()) { + std::string homePath = globals->get_fg_home().utf8Str(); + if(!fgValidatePath(homePath + "/../no.log",true).empty() || + !fgValidatePath(homePath + "/no.logt",true).empty() || + !fgValidatePath(homePath + "/nolog",true).empty() || + !fgValidatePath(homePath + "no.log",true).empty() || + !fgValidatePath(homePath + "\\..\\no.log",false).empty() || + fgValidatePath(homePath + "/aircraft-data/yes..xml",true).empty() || + fgValidatePath(homePath + "/.\\yes.bmp",false).empty()) { flightgear::fatalMessageBox("Nasal initialization error", "The FG_HOME directory must not be inside any of the FG_ROOT, FG_AIRCRAFT or FG_SCENERY directories", "(check that you have not accidentally included an extra :, as an empty part means the current directory)"); diff --git a/src/Navaids/NavDataCache.cxx b/src/Navaids/NavDataCache.cxx index 99894a0fb..be8b1d606 100644 --- a/src/Navaids/NavDataCache.cxx +++ b/src/Navaids/NavDataCache.cxx @@ -1223,7 +1223,7 @@ void NavDataCache::doRebuild() d->flushDeferredOctreeUpdates(); - string sceneryPaths = simgear::strutils::join(globals->get_fg_scenery(), ";"); + string sceneryPaths = SGPath::join(globals->get_fg_scenery(), ";"); writeStringProperty("scenery_paths", sceneryPaths); st.stamp(); diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 99a7cf915..a2498db97 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -165,10 +165,13 @@ void FGTileMgr::reinit() _options->setPropertyNode(globals->get_props()); osgDB::FilePathList &fp = _options->getDatabasePathList(); - const string_list &sc = globals->get_fg_scenery(); + const PathList &sc = globals->get_fg_scenery(); fp.clear(); - std::copy(sc.begin(), sc.end(), back_inserter(fp)); - _options->setPluginStringData("SimGear::FG_ROOT", globals->get_fg_root()); + PathList::const_iterator it; + for (it = sc.begin(); it != sc.end(); ++it) { + fp.push_back(it->local8BitStr()); + } + _options->setPluginStringData("SimGear::FG_ROOT", globals->get_fg_root().local8BitStr()); if (_terra_sync) { _options->setPluginStringData("SimGear::TERRASYNC_ROOT", fgGetString("/sim/terrasync/scenery-dir")); diff --git a/src/Sound/VoiceSynthesizer.cxx b/src/Sound/VoiceSynthesizer.cxx index fb40b439c..0942e2a7d 100644 --- a/src/Sound/VoiceSynthesizer.cxx +++ b/src/Sound/VoiceSynthesizer.cxx @@ -58,8 +58,8 @@ void FLITEVoiceSynthesizer::WorkerThread::run() string FLITEVoiceSynthesizer::getVoicePath( voice_t voice ) { if( voice < 0 || voice >= VOICE_UNKNOWN ) return string(""); - string voicePath = globals->get_fg_root() + "/ATC/" + VOICE_FILES[voice]; - return voicePath; + SGPath voicePath = globals->get_fg_root() / "ATC" / VOICE_FILES[voice]; + return voicePath.local8BitStr(); } string FLITEVoiceSynthesizer::getVoicePath( const string & voice ) diff --git a/src/Sound/flitevoice.cxx b/src/Sound/flitevoice.cxx index 2c98edd5a..c38e96154 100644 --- a/src/Sound/flitevoice.cxx +++ b/src/Sound/flitevoice.cxx @@ -38,10 +38,10 @@ FGFLITEVoice::FGFLITEVoice(FGVoiceMgr * mgr, const SGPropertyNode_ptr node, cons _sampleName = node->getStringValue("desc", node->getPath().c_str()); - string voice = globals->get_fg_root() + "/ATC/" + + SGPath voice = globals->get_fg_root() / "ATC" / node->getStringValue("htsvoice", "cmu_us_arctic_slt.htsvoice"); - _synthesizer = new FLITEVoiceSynthesizer(voice.c_str()); + _synthesizer = new FLITEVoiceSynthesizer(voice.local8BitStr()); SGSoundMgr *smgr = globals->get_subsystem(); _sgr = smgr->find(sampleGroupRefName, true); diff --git a/src/Traffic/Schedule.cxx b/src/Traffic/Schedule.cxx index 09efa2dec..7e53cda06 100644 --- a/src/Traffic/Schedule.cxx +++ b/src/Traffic/Schedule.cxx @@ -343,9 +343,8 @@ SGPath FGAISchedule::resolveModelPath(const std::string& modelPath) } // check aircraft dirs - BOOST_FOREACH(std::string aircraftPath, globals->get_aircraft_paths()) { - SGPath mp(aircraftPath); - mp.append(modelPath); + BOOST_FOREACH(SGPath aircraftPath, globals->get_aircraft_paths()) { + SGPath mp = aircraftPath / modelPath; if (mp.exists()) { return mp; } diff --git a/src/Traffic/TrafficMgr.cxx b/src/Traffic/TrafficMgr.cxx index 2fe014091..73af68c4d 100644 --- a/src/Traffic/TrafficMgr.cxx +++ b/src/Traffic/TrafficMgr.cxx @@ -534,12 +534,14 @@ void FGTrafficManager::init() simgear::PathList dirs = globals->get_data_paths("AI/Traffic"); // temporary flag to restrict loading while traffic data is found - // through terrasync /and/ fgdata. Ultimatley we *do* want to be able to + // through terrasync /and/ fgdata. Ultimately we *do* want to be able to // overlay sources. if (dirs.size() > 1) { SGPath p = dirs.back(); - if (simgear::strutils::starts_with(p.str(), globals->get_fg_root())) { + if (simgear::strutils::starts_with(p.utf8Str(), + globals->get_fg_root().utf8Str())) + { dirs.pop_back(); } } diff --git a/src/Viewer/fgviewer.cxx b/src/Viewer/fgviewer.cxx index aa0fbf9a1..850a33a1b 100644 --- a/src/Viewer/fgviewer.cxx +++ b/src/Viewer/fgviewer.cxx @@ -180,21 +180,21 @@ fgviewerMain(int argc, char** argv) osgDB::FilePathList filePathList = osgDB::Registry::instance()->getDataFilePathList(); - filePathList.push_back(globals->get_fg_root()); + filePathList.push_back(globals->get_fg_root().local8BitStr()); - string_list path_list = globals->get_fg_scenery(); + const PathList& path_list = globals->get_fg_scenery(); for (unsigned i = 0; i < path_list.size(); ++i) { - filePathList.push_back(path_list[i]); + filePathList.push_back(path_list[i].local8BitStr()); } globals->set_matlib( new SGMaterialLib ); - simgear::SGModelLib::init(globals->get_fg_root(), globals->get_props()); + simgear::SGModelLib::init(globals->get_fg_root().local8BitStr(), globals->get_props()); // Initialize the material property subsystem. SGPath mpath( globals->get_fg_root() ); mpath.append( fgGetString("/sim/rendering/materials-file") ); - if ( ! globals->get_matlib()->load(globals->get_fg_root(), mpath.str(), + if ( ! globals->get_matlib()->load(globals->get_fg_root().local8BitStr(), mpath.str(), globals->get_props()) ) { throw sg_io_exception("Error loading materials file", mpath); } diff --git a/src/Viewer/renderer.cxx b/src/Viewer/renderer.cxx index 552a880c8..8a3256b1a 100644 --- a/src/Viewer/renderer.cxx +++ b/src/Viewer/renderer.cxx @@ -1173,7 +1173,7 @@ FGRenderer::buildDeferredFullscreenCamera( flightgear::CameraInfo* info, const F g->setUseDisplayList(false); simgear::EffectGeode* eg = new simgear::EffectGeode; osg::ref_ptr opt; - opt = SGReaderWriterOptions::fromPath(globals->get_fg_root()); + opt = SGReaderWriterOptions::fromPath(globals->get_fg_root().local8BitStr()); opt->setPropertyNode(globals->get_props()); simgear::Effect* effect = simgear::makeEffect(pass->effect, true, opt.get()); if (effect) { @@ -1226,7 +1226,7 @@ FGRenderer::buildDeferredDisplayCamera( osg::Camera* camera, flightgear::CameraI g->setUseDisplayList(false); //DEBUG simgear::EffectGeode* eg = new simgear::EffectGeode; osg::ref_ptr opt; - opt = SGReaderWriterOptions::fromPath(globals->get_fg_root()); + opt = SGReaderWriterOptions::fromPath(globals->get_fg_root().local8BitStr()); opt->setPropertyNode(globals->get_props()); simgear::Effect* effect = simgear::makeEffect(stage->effect, true, opt.get()); if (!effect) { @@ -1459,7 +1459,7 @@ FGRenderer::setupView( void ) // Moon diameter: 3,476 kilometers // Sun diameter: 1,390,000 kilometers osg::ref_ptr opt; - opt = SGReaderWriterOptions::fromPath(globals->get_fg_root()); + opt = SGReaderWriterOptions::fromPath(globals->get_fg_root().local8BitStr()); opt->setPropertyNode(globals->get_props()); _sky->build( 80000.0, 80000.0, 463.3, 361.8, diff --git a/utils/fgpanel/FGPanelApplication.cxx b/utils/fgpanel/FGPanelApplication.cxx index 3806f071e..f8aecf86a 100644 --- a/utils/fgpanel/FGPanelApplication.cxx +++ b/utils/fgpanel/FGPanelApplication.cxx @@ -71,18 +71,18 @@ inline static string ParseArgs( int argc, char ** argv, const char * token ) // define default location of fgdata (use the same as for fgfs) #if defined(__CYGWIN__) -inline static string platformDefaultRoot() +inline static SGPath platformDefaultRoot() { - return "../data"; + return SGPath("../data"); } #elif defined(_WIN32) -inline static string platformDefaultRoot() +inline static SGPath platformDefaultRoot() { - return "..\\data"; + return SGPath("..\\data"); } #elif defined(__APPLE__) -inline static string platformDefaultRoot() +inline static SGPath platformDefaultRoot() { /* The following code looks for the base package inside the application @@ -101,12 +101,12 @@ inline static string platformDefaultRoot() CFRelease(dataDir); CFRelease(path); - return root; + return SGPath(root); } #else -inline static string platformDefaultRoot() +inline static SGPath platformDefaultRoot() { - return PKGLIBDIR; + return SGPath(PKGLIBDIR); } #endif @@ -122,7 +122,7 @@ FGPanelApplication::FGPanelApplication( int argc, char ** argv ) : FGCroppedTexture::registerTextureLoader( "png", &pngTextureLoader ); FGCroppedTexture::registerTextureLoader( "rgb", &rgbTextureLoader ); - ApplicationProperties::root = platformDefaultRoot(); + ApplicationProperties::root = platformDefaultRoot().local8BitStr(); string panelFilename; string fgRoot;