From 5b41f374c6db097adad857a445c704446ce6f475 Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 12 Mar 2020 10:51:49 +0000 Subject: [PATCH] L10N fixes: handle UTF8 paths in more places. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Still not complete, but now we set the command line args to be UTF-8 on Windows, we can strip out more of the ‘local 8-bit’ places (which screw up, generally). --- src/FDM/JSBSim/input_output/FGModelLoader.cpp | 2 +- src/Main/options.cxx | 29 +++++------ src/Model/acmodel.cxx | 2 +- src/Scripting/NasalSys.cxx | 50 +++++-------------- 4 files changed, 27 insertions(+), 56 deletions(-) diff --git a/src/FDM/JSBSim/input_output/FGModelLoader.cpp b/src/FDM/JSBSim/input_output/FGModelLoader.cpp index 6170b1bc6..1dbebae82 100644 --- a/src/FDM/JSBSim/input_output/FGModelLoader.cpp +++ b/src/FDM/JSBSim/input_output/FGModelLoader.cpp @@ -57,7 +57,7 @@ Element_ptr FGModelLoader::Open(Element *el) if (!fname.empty()) { FGXMLFileRead XMLFileRead; - SGPath path(SGPath::fromLocal8Bit(fname.c_str())); + SGPath path(SGPath::fromUtf8(fname)); if (path.isRelative()) path = model->FindFullPathName(path); diff --git a/src/Main/options.cxx b/src/Main/options.cxx index c93ec85fe..75cded346 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -719,7 +719,7 @@ clearLocation () static int fgOptAddon(const char *arg) { - const SGPath addonPath = SGPath::fromLocal8Bit(arg); + const SGPath addonPath = SGPath::fromUtf8(arg); const auto& addonManager = addons::AddonManager::instance(); try { @@ -904,7 +904,7 @@ fgOptRoc( const char *arg ) static int fgOptFgScenery( const char *arg ) { - globals->append_fg_scenery(SGPath::pathsFromLocal8Bit(arg)); + globals->append_fg_scenery(SGPath::pathsFromUtf8(arg)); return FG_OPTIONS_OK; } @@ -921,7 +921,7 @@ fgOptEnhancedLighting( const char *arg ) static int fgOptAllowNasalRead( const char *arg ) { - PathList paths = SGPath::pathsFromLocal8Bit(arg); + PathList paths = SGPath::pathsFromUtf8(arg); if(paths.size() == 0) { SG_LOG(SG_GENERAL, SG_WARN, "--allow-nasal-read requires a list of directories to allow"); } @@ -1121,7 +1121,7 @@ fgOptLogDir(const char* arg) if (!strcmp(arg, "desktop")) { dirPath = SGPath::desktop(); } else { - dirPath = SGPath::fromLocal8Bit(arg); + dirPath = SGPath::fromUtf8(arg); } if (!dirPath.isDir()) { @@ -1556,7 +1556,7 @@ fgOptLoadTape(const char* arg) class DelayedTapeLoader : SGPropertyChangeListener { public: DelayedTapeLoader( const char * tape ) : - _tape(SGPath::fromLocal8Bit(tape)) + _tape(SGPath::fromUtf8(tape)) { SGPropertyNode_ptr n = fgGetNode("/sim/signals/fdm-initialized", true); n->addChangeListener( this ); @@ -2104,7 +2104,7 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath) processArgResult(result); } else { // XML properties file - SGPath f = SGPath::fromLocal8Bit(argv[i]); + SGPath f = SGPath::fromUtf8(argv[i]); if (!f.exists()) { SG_LOG(SG_GENERAL, SG_ALERT, "config file not found:" << f); } else { @@ -2191,7 +2191,7 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath) void Options::initPaths() { for (const string& pathOpt : valuesForOption("fg-aircraft")) { - PathList paths = SGPath::pathsFromLocal8Bit(pathOpt); + PathList paths = SGPath::pathsFromUtf8(pathOpt); globals->append_aircraft_paths(paths); } @@ -2241,7 +2241,7 @@ void Options::initAircraft() } if (isOptionSet("aircraft-dir")) { - SGPath aircraftDirPath = SGPath::fromLocal8Bit(valueForOption("aircraft-dir").c_str()); + SGPath aircraftDirPath = SGPath::fromUtf8(valueForOption("aircraft-dir")); globals->append_read_allowed_paths(aircraftDirPath); // Set this now, so it's available in FindAndCacheAircraft. Use realpath() @@ -2565,8 +2565,7 @@ OptionResult Options::processOptions() } // Download dir fix-up - SGPath downloadDir = SGPath::fromLocal8Bit( - valueForOption("download-dir").c_str()); + SGPath downloadDir = SGPath::fromUtf8(valueForOption("download-dir")); if (downloadDir.isNull()) { downloadDir = defaultDownloadDir(); SG_LOG(SG_GENERAL, SG_INFO, @@ -2589,8 +2588,7 @@ OptionResult Options::processOptions() globals->set_download_dir(downloadDir); // Texture Cache directory handling - SGPath textureCacheDir = SGPath::fromLocal8Bit( - valueForOption("texture-cache-dir").c_str()); + SGPath textureCacheDir = SGPath::fromUtf8(valueForOption("texture-cache-dir")); if (textureCacheDir.isNull()) { textureCacheDir = defaultTextureCacheDir(); SG_LOG(SG_GENERAL, SG_INFO, @@ -2612,8 +2610,7 @@ OptionResult Options::processOptions() // TerraSync directory fixup - SGPath terrasyncDir = SGPath::fromLocal8Bit( - valueForOption("terrasync-dir").c_str()); + SGPath terrasyncDir = SGPath::fromUtf8(valueForOption("terrasync-dir")); if (terrasyncDir.isNull()) { terrasyncDir = downloadDir / "TerraSync"; // No “default” qualifier here, because 'downloadDir' may be non-default @@ -2946,13 +2943,13 @@ void Options::setupRoot(int argc, char **argv) } if (isOptionSet("fg-root")) { - root = SGPath::fromLocal8Bit(valueForOption("fg-root").c_str()); // easy! + root = SGPath::fromUtf8(valueForOption("fg-root")); // 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 != nullptr ) { - root = SGPath::fromLocal8Bit(envp); + root = SGPath::fromEnv("FG_ROOT"); SG_LOG(SG_GENERAL, SG_INFO, "set from FG_ROOT env var: fg_root = " << root ); } else { #if defined(HAVE_QT) diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 6b36dd362..5f2d59717 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -110,7 +110,7 @@ FGAircraftModel::init () // no models loaded, load the glider instead if (!_aircraft.get()) { SG_LOG(SG_AIRCRAFT, SG_ALERT, "(Falling back to glider.ac.)"); - osg::Node* model = fgLoad3DModelPanel( SGPath::fromLocal8Bit("Models/Geometry/glider.ac"), + osg::Node* model = fgLoad3DModelPanel( SGPath::fromUtf8("Models/Geometry/glider.ac"), globals->get_props()); _aircraft.reset(new SGModelPlacement); _aircraft->init(model); diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index 45ea02307..5a407c190 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -247,34 +247,6 @@ typedef nasal::Ghost NasalTimeStampObj; /////////////////////////////////////////////////////////////////////////// -// Read and return file contents in a single buffer. Note use of -// stat() to get the file size. This is a win32 function, believe it -// or not. :) Note the REALLY IMPORTANT use of the "b" flag to fopen. -// Text mode brain damage will kill us if we're trying to do bytewise -// I/O. -static char* readfile(const char* file, int* lenOut) -{ - struct stat data; - if(stat(file, &data) != 0) return 0; - FILE* f = fopen(file, "rb"); - if(!f) return 0; - char* buf = new char[data.st_size]; - *lenOut = fread(buf, 1, data.st_size, f); - fclose(f); - if(*lenOut != data.st_size) { - // Shouldn't happen, but warn anyway since it represents a - // platform bug and not a typical runtime error (missing file, - // etc...) - SG_LOG(SG_NASAL, SG_ALERT, - "ERROR in Nasal initialization: " << - "short count returned from fread() of " << file << - ". Check your C library!"); - delete[] buf; - return 0; - } - return buf; -} - FGNasalSys::FGNasalSys() : _inited(false) { @@ -1292,19 +1264,21 @@ void FGNasalSys::logNasalStack(naContext context) // name. bool FGNasalSys::loadModule(SGPath file, const char* module) { - int len = 0; - std::string pdata = file.local8BitStr(); - char* buf = readfile(pdata.c_str(), &len); - if(!buf) { - SG_LOG(SG_NASAL, SG_ALERT, - "Nasal error: could not read script file " << file - << " into module " << module); + if (!file.exists()) { + SG_LOG(SG_NASAL, SG_ALERT, "Cannot load module, missing file:" << file); return false; } - bool ok = createModule(module, pdata.c_str(), buf, len); - delete[] buf; - return ok; + sg_ifstream file_in(file); + string buf; + while (!file_in.eof()) { + char bytes[8192]; + file_in.read(bytes, 8192); + buf.append(bytes, file_in.gcount()); + } + file_in.close(); + auto pathStr = file.utf8Str(); + return createModule(module, pathStr.c_str(), buf.data(), buf.length()); } // Parse and run. Save the local variables namespace, as it will