void locateLegacySavegames(String const &gameId) { LOG_AS("SaveGames"); String const legacySavePath = String("/sys/legacysavegames") / gameId; if (Folder *oldSaveFolder = FileSystem::get().root().tryLocate<Folder>(legacySavePath)) { // Add any new legacy savegames which may have appeared in this folder. oldSaveFolder->populate(Folder::PopulateOnlyThisFolder /* no need to go deep */); } else { try { // Make and setup a feed for the /sys/legacysavegames/<gameId> subfolder if the game // might have legacy savegames we may need to convert later. NativePath const oldSavePath = DoomsdayApp::games()[gameId].legacySavegamePath(); if (oldSavePath.exists() && oldSavePath.isReadable()) { FileSystem::get().makeFolderWithFeed(legacySavePath, new DirectoryFeed(oldSavePath), Folder::PopulateOnlyThisFolder /* no need to go deep */); } } catch (Games::NotFoundError const &) {} // Ignore this error } }
void NativePath::createPath(NativePath const &nativePath) { NativePath parentPath = nativePath.fileNamePath(); if (!parentPath.isEmpty() && !exists(parentPath)) { createPath(parentPath); } QDir::current().mkdir(nativePath); if (!exists(nativePath)) { /// @throw CreateDirError Failed to create directory @a nativePath. throw CreateDirError("NativePath::createPath", "Could not create: " + nativePath); } }
NativePath NativePath::workPath() { if (currentNativeWorkPath.isEmpty()) { currentNativeWorkPath = QDir::currentPath(); } return currentNativeWorkPath; }
int SavegameConvertHook(int /*hook_type*/, int /*parm*/, void *data) { DENG2_ASSERT(data != 0); ddhook_savegame_convert_t const &parm = *static_cast<ddhook_savegame_convert_t *>(data); LOG_AS("importsave"); // First locate the savegametool executable. NativePath bin = findSavegameTool(); if(!bin.exists()) { LOG_RES_ERROR("Failed to locate Savegame Tool"); return false; } CommandLine cmd; cmd << bin; // Specify the fallback game identity key for ambiguous format resolution. cmd << "-idkey" << Str_Text(&parm.fallbackGameId); // We can only convert native files and output to native folders using Savegame Tool. Path const outputPath(Str_Text(&parm.outputPath)); Path const sourcePath(Str_Text(&parm.sourcePath)); try { // Redirect output to the folder specified. cmd << "-output" << App::rootFolder().locate<Folder>(outputPath) .feeds().front()->as<DirectoryFeed>().nativePath().expand(); // Add the path of the savegame to be converted. cmd << App::rootFolder().locate<NativeFile>(sourcePath).nativePath(); LOG_RES_NOTE("Starting conversion of \"%s\" using Savegame Tool") << sourcePath; cmd.executeAndWait(); return true; } catch(Error const &er) { LOG_RES_NOTE("Failed conversion of \"%s\":\n") << sourcePath << er.asText(); } return false; }
Library::Library(NativePath const &nativePath) : d(new Instance(this)) { LOG_AS("Library"); LOG_TRACE("Loading \"%s\"") << nativePath.pretty(); #ifndef DENG2_USE_DLOPEN d->library = new QLibrary(nativePath); d->library->setLoadHints(QLibrary::ResolveAllSymbolsHint); d->library->load(); #else d->fileName = nativePath; d->library = dlopen(nativePath.toUtf8().constData(), RTLD_NOW); #endif if(!d->isLoaded()) { #ifndef DENG2_USE_DLOPEN QString msg = d->library->errorString(); delete d->library; #else QString msg = dlerror(); #endif d->library = 0; /// @throw LoadError Opening of the dynamic library failed. throw LoadError("Library::Library", msg); } if(hasSymbol("deng_LibraryType")) { // Query the type identifier. d->type = DENG2_SYMBOL(deng_LibraryType)(); } // Automatically call the initialization function, if one exists. if(d->type.beginsWith("deng-plugin/") && hasSymbol("deng_InitializePlugin")) { DENG2_SYMBOL(deng_InitializePlugin)(); } }
String NativePath::pretty() const { if (isEmpty()) return *this; String result = *this; // Replace relative directives like '}' (used in FS1 only) with a full symbol. if (result.length() > 1 && (result.first() == '}' || result.first() == '>')) { return String(NATIVE_BASE_SYMBOLIC) + DIR_SEPARATOR + result.mid(1); } // If within one of the known native directories, cut out the known path, // replacing it with a symbolic. This retains the absolute nature of the path // while omitting potentially redundant/verbose information. if (QDir::isAbsolutePath(result)) { NativePath basePath = App::app().nativeBasePath(); if (result.beginsWith(basePath)) { result = NATIVE_BASE_SYMBOLIC + result.mid(basePath.length()); } else { #ifdef MACOSX NativePath contentsPath = App::app().nativeAppContentsPath(); if (result.beginsWith(contentsPath)) { return "(app)" + result.mid(contentsPath.length()); } #endif NativePath homePath = QDir::homePath(); // actual native home dir, not FS2 "/home" if (result.beginsWith(homePath)) { result = NATIVE_HOME_SYMBOLIC + result.mid(homePath.length()); } } } return result; }
bool CanvasWindow::grabToFile(NativePath const &path) const { return d->canvas->grabImage().save(path.toString()); }
LibraryFile::LibraryFile(NativePath const &nativePath) : File(nativePath.fileName()) , d(new Impl) { d->nativePath = nativePath; }
NativePath NativePath::concatenatePath(NativePath const &nativePath) const { if (nativePath.isAbsolute()) return nativePath; return toString().concatenatePath(nativePath, QChar(DIR_SEPARATOR)); }
namespace de { static QString toNative(String const &s) { // This will resolve parent references (".."), multiple separators // (hello//world), and self-references ("."). return Path::normalizeString(QDir::cleanPath(s), DIR_SEPARATOR); } NativePath::NativePath() : Path() {} NativePath::NativePath(String const &str) : Path(toNative(str), DIR_SEPARATOR) {} NativePath::NativePath(QString const &qstr) : Path(toNative(qstr), DIR_SEPARATOR) {} NativePath::NativePath(char const *nullTerminatedCStr) : Path(toNative(nullTerminatedCStr), DIR_SEPARATOR) {} NativePath::NativePath(char const *cStr, dsize length) : Path(toNative(String(cStr, length)), DIR_SEPARATOR) {} NativePath &NativePath::operator = (String const &str) { set(toNative(str), DIR_SEPARATOR); return *this; } NativePath &NativePath::operator = (QString const &str) { set(toNative(str), DIR_SEPARATOR); return *this; } NativePath &NativePath::operator = (char const *nullTerminatedCStr) { return (*this) = String(nullTerminatedCStr); } NativePath NativePath::concatenatePath(NativePath const &nativePath) const { if (nativePath.isAbsolute()) return nativePath; return toString().concatenatePath(nativePath, QChar(DIR_SEPARATOR)); } NativePath NativePath::concatenatePath(String const &nativePath) const { return concatenatePath(NativePath(nativePath)); } NativePath NativePath::operator / (NativePath const &nativePath) const { return concatenatePath(nativePath); } NativePath NativePath::operator / (String const &str) const { return *this / NativePath(str); } NativePath NativePath::operator / (QString const &str) const { return *this / NativePath(str); } NativePath NativePath::operator / (char const *nullTerminatedCStr) const { return *this / NativePath(nullTerminatedCStr); } NativePath NativePath::fileNamePath() const { return String(*this).fileNamePath(DIR_SEPARATOR); } bool NativePath::isAbsolute() const { return QDir::isAbsolutePath(expand()); } NativePath NativePath::expand(bool *didExpand) const { if (first() == '>' || first() == '}') { if (didExpand) *didExpand = true; return App::app().nativeBasePath() / toString().mid(1); } #ifdef UNIX else if (first() == '~') { if (didExpand) *didExpand = true; String const path = toString(); int firstSlash = path.indexOf('/'); if (firstSlash > 1) { // Parse the user's home directory (from passwd). QByteArray userName = path.mid(1, firstSlash - 1).toLatin1(); struct passwd *pw = getpwnam(userName); if (!pw) { /// @throws UnknownUserError User is not known. throw UnknownUserError("NativePath::expand", String("Unknown user '%1'").arg(QLatin1String(userName))); } return NativePath(pw->pw_dir) / path.mid(firstSlash + 1); } else { // Replace with the HOME path. return NativePath(QDir::homePath()) / path.mid(2); } } #endif // No expansion done. if (didExpand) *didExpand = false; return *this; } String NativePath::pretty() const { if (isEmpty()) return *this; String result = *this; // Replace relative directives like '}' (used in FS1 only) with a full symbol. if (result.length() > 1 && (result.first() == '}' || result.first() == '>')) { return String(NATIVE_BASE_SYMBOLIC) + DIR_SEPARATOR + result.mid(1); } // If within one of the known native directories, cut out the known path, // replacing it with a symbolic. This retains the absolute nature of the path // while omitting potentially redundant/verbose information. if (QDir::isAbsolutePath(result)) { NativePath basePath = App::app().nativeBasePath(); if (result.beginsWith(basePath)) { result = NATIVE_BASE_SYMBOLIC + result.mid(basePath.length()); } else { #ifdef MACOSX NativePath contentsPath = App::app().nativeAppContentsPath(); if (result.beginsWith(contentsPath)) { return "(app)" + result.mid(contentsPath.length()); } #endif NativePath homePath = QDir::homePath(); // actual native home dir, not FS2 "/home" if (result.beginsWith(homePath)) { result = NATIVE_HOME_SYMBOLIC + result.mid(homePath.length()); } } } return result; } String NativePath::withSeparators(QChar sep) const { return Path::withSeparators(sep); } bool NativePath::exists() const { if (isEmpty()) return false; return QFile::exists(toString()); } bool NativePath::isReadable() const { return QFileInfo(toString()).isReadable(); } static NativePath currentNativeWorkPath; NativePath NativePath::workPath() { if (currentNativeWorkPath.isEmpty()) { currentNativeWorkPath = QDir::currentPath(); } return currentNativeWorkPath; } bool NativePath::setWorkPath(NativePath const &cwd) { if (QDir::setCurrent(cwd)) { currentNativeWorkPath = cwd; return true; } return false; } bool NativePath::exists(NativePath const &nativePath) { return QDir::current().exists(nativePath); } void NativePath::createPath(NativePath const &nativePath) { NativePath parentPath = nativePath.fileNamePath(); if (!parentPath.isEmpty() && !exists(parentPath)) { createPath(parentPath); } QDir::current().mkdir(nativePath); if (!exists(nativePath)) { /// @throw CreateDirError Failed to create directory @a nativePath. throw CreateDirError("NativePath::createPath", "Could not create: " + nativePath); } } QChar NativePath::separator() { return DIR_SEPARATOR; } } // namespace de