1
0
Fork 0

L10N fixes: handle UTF8 paths in more places.

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).
This commit is contained in:
James Turner 2020-03-12 10:51:49 +00:00
parent 3cb05a9207
commit 5b41f374c6
4 changed files with 27 additions and 56 deletions

View file

@ -57,7 +57,7 @@ Element_ptr FGModelLoader::Open(Element *el)
if (!fname.empty()) { if (!fname.empty()) {
FGXMLFileRead XMLFileRead; FGXMLFileRead XMLFileRead;
SGPath path(SGPath::fromLocal8Bit(fname.c_str())); SGPath path(SGPath::fromUtf8(fname));
if (path.isRelative()) if (path.isRelative())
path = model->FindFullPathName(path); path = model->FindFullPathName(path);

View file

@ -719,7 +719,7 @@ clearLocation ()
static int static int
fgOptAddon(const char *arg) fgOptAddon(const char *arg)
{ {
const SGPath addonPath = SGPath::fromLocal8Bit(arg); const SGPath addonPath = SGPath::fromUtf8(arg);
const auto& addonManager = addons::AddonManager::instance(); const auto& addonManager = addons::AddonManager::instance();
try { try {
@ -904,7 +904,7 @@ fgOptRoc( const char *arg )
static int static int
fgOptFgScenery( const char *arg ) fgOptFgScenery( const char *arg )
{ {
globals->append_fg_scenery(SGPath::pathsFromLocal8Bit(arg)); globals->append_fg_scenery(SGPath::pathsFromUtf8(arg));
return FG_OPTIONS_OK; return FG_OPTIONS_OK;
} }
@ -921,7 +921,7 @@ fgOptEnhancedLighting( const char *arg )
static int static int
fgOptAllowNasalRead( const char *arg ) fgOptAllowNasalRead( const char *arg )
{ {
PathList paths = SGPath::pathsFromLocal8Bit(arg); PathList paths = SGPath::pathsFromUtf8(arg);
if(paths.size() == 0) { if(paths.size() == 0) {
SG_LOG(SG_GENERAL, SG_WARN, "--allow-nasal-read requires a list of directories to allow"); 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")) { if (!strcmp(arg, "desktop")) {
dirPath = SGPath::desktop(); dirPath = SGPath::desktop();
} else { } else {
dirPath = SGPath::fromLocal8Bit(arg); dirPath = SGPath::fromUtf8(arg);
} }
if (!dirPath.isDir()) { if (!dirPath.isDir()) {
@ -1556,7 +1556,7 @@ fgOptLoadTape(const char* arg)
class DelayedTapeLoader : SGPropertyChangeListener { class DelayedTapeLoader : SGPropertyChangeListener {
public: public:
DelayedTapeLoader( const char * tape ) : DelayedTapeLoader( const char * tape ) :
_tape(SGPath::fromLocal8Bit(tape)) _tape(SGPath::fromUtf8(tape))
{ {
SGPropertyNode_ptr n = fgGetNode("/sim/signals/fdm-initialized", true); SGPropertyNode_ptr n = fgGetNode("/sim/signals/fdm-initialized", true);
n->addChangeListener( this ); n->addChangeListener( this );
@ -2104,7 +2104,7 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath)
processArgResult(result); processArgResult(result);
} else { } else {
// XML properties file // XML properties file
SGPath f = SGPath::fromLocal8Bit(argv[i]); SGPath f = SGPath::fromUtf8(argv[i]);
if (!f.exists()) { if (!f.exists()) {
SG_LOG(SG_GENERAL, SG_ALERT, "config file not found:" << f); SG_LOG(SG_GENERAL, SG_ALERT, "config file not found:" << f);
} else { } else {
@ -2191,7 +2191,7 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath)
void Options::initPaths() void Options::initPaths()
{ {
for (const string& pathOpt : valuesForOption("fg-aircraft")) { for (const string& pathOpt : valuesForOption("fg-aircraft")) {
PathList paths = SGPath::pathsFromLocal8Bit(pathOpt); PathList paths = SGPath::pathsFromUtf8(pathOpt);
globals->append_aircraft_paths(paths); globals->append_aircraft_paths(paths);
} }
@ -2241,7 +2241,7 @@ void Options::initAircraft()
} }
if (isOptionSet("aircraft-dir")) { 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); globals->append_read_allowed_paths(aircraftDirPath);
// Set this now, so it's available in FindAndCacheAircraft. Use realpath() // Set this now, so it's available in FindAndCacheAircraft. Use realpath()
@ -2565,8 +2565,7 @@ OptionResult Options::processOptions()
} }
// Download dir fix-up // Download dir fix-up
SGPath downloadDir = SGPath::fromLocal8Bit( SGPath downloadDir = SGPath::fromUtf8(valueForOption("download-dir"));
valueForOption("download-dir").c_str());
if (downloadDir.isNull()) { if (downloadDir.isNull()) {
downloadDir = defaultDownloadDir(); downloadDir = defaultDownloadDir();
SG_LOG(SG_GENERAL, SG_INFO, SG_LOG(SG_GENERAL, SG_INFO,
@ -2589,8 +2588,7 @@ OptionResult Options::processOptions()
globals->set_download_dir(downloadDir); globals->set_download_dir(downloadDir);
// Texture Cache directory handling // Texture Cache directory handling
SGPath textureCacheDir = SGPath::fromLocal8Bit( SGPath textureCacheDir = SGPath::fromUtf8(valueForOption("texture-cache-dir"));
valueForOption("texture-cache-dir").c_str());
if (textureCacheDir.isNull()) { if (textureCacheDir.isNull()) {
textureCacheDir = defaultTextureCacheDir(); textureCacheDir = defaultTextureCacheDir();
SG_LOG(SG_GENERAL, SG_INFO, SG_LOG(SG_GENERAL, SG_INFO,
@ -2612,8 +2610,7 @@ OptionResult Options::processOptions()
// TerraSync directory fixup // TerraSync directory fixup
SGPath terrasyncDir = SGPath::fromLocal8Bit( SGPath terrasyncDir = SGPath::fromUtf8(valueForOption("terrasync-dir"));
valueForOption("terrasync-dir").c_str());
if (terrasyncDir.isNull()) { if (terrasyncDir.isNull()) {
terrasyncDir = downloadDir / "TerraSync"; terrasyncDir = downloadDir / "TerraSync";
// No “default” qualifier here, because 'downloadDir' may be non-default // 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")) { 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 ); SG_LOG(SG_GENERAL, SG_INFO, "set from command-line argument: fg_root = " << root );
} else { } else {
// Next check if fg-root is set as an env variable // Next check if fg-root is set as an env variable
char *envp = ::getenv( "FG_ROOT" ); char *envp = ::getenv( "FG_ROOT" );
if ( envp != nullptr ) { 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 ); SG_LOG(SG_GENERAL, SG_INFO, "set from FG_ROOT env var: fg_root = " << root );
} else { } else {
#if defined(HAVE_QT) #if defined(HAVE_QT)

View file

@ -110,7 +110,7 @@ FGAircraftModel::init ()
// no models loaded, load the glider instead // no models loaded, load the glider instead
if (!_aircraft.get()) { if (!_aircraft.get()) {
SG_LOG(SG_AIRCRAFT, SG_ALERT, "(Falling back to glider.ac.)"); 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()); globals->get_props());
_aircraft.reset(new SGModelPlacement); _aircraft.reset(new SGModelPlacement);
_aircraft->init(model); _aircraft->init(model);

View file

@ -247,34 +247,6 @@ typedef nasal::Ghost<TimeStampObjRef> 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() : FGNasalSys::FGNasalSys() :
_inited(false) _inited(false)
{ {
@ -1292,19 +1264,21 @@ void FGNasalSys::logNasalStack(naContext context)
// name. // name.
bool FGNasalSys::loadModule(SGPath file, const char* module) bool FGNasalSys::loadModule(SGPath file, const char* module)
{ {
int len = 0; if (!file.exists()) {
std::string pdata = file.local8BitStr(); SG_LOG(SG_NASAL, SG_ALERT, "Cannot load module, missing file:" << file);
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);
return false; return false;
} }
bool ok = createModule(module, pdata.c_str(), buf, len); sg_ifstream file_in(file);
delete[] buf; string buf;
return ok; 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 // Parse and run. Save the local variables namespace, as it will