Cleaned up the FilesystemNode API a little, removing some redundant code.

The debugger 'saverom' command now uses absolute filenames, and by default
will save data in the users home directory if a proper path isn't included
in the filename.  This fixes a major bug where ROMs were being saved to
the current or application directory, which in some cases were invalid
locations.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2250 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2011-06-09 14:00:30 +00:00
parent 4c59d810f1
commit df71aa03d1
16 changed files with 138 additions and 135 deletions

View File

@ -30,6 +30,10 @@
* Tweaked bankswitch autodetection code for 4A50 bankswitching. * Tweaked bankswitch autodetection code for 4A50 bankswitching.
* The 'saverom' debugger command now saves ROMs in your home
directory by default if you don't specify a valid path. This fixes
a bug whereby ROMs were saved and couldn't later be located.
-Have fun! -Have fun!

View File

@ -626,7 +626,7 @@ string CartDebug::loadSymbolFile(string file)
{ {
ifstream in(node.getPath().c_str()); ifstream in(node.getPath().c_str());
if(!in.is_open()) if(!in.is_open())
return DebuggerParser::red("symbol file '" + node.getRelativePath() + "' not found"); return DebuggerParser::red("symbol file '" + node.getPath(false) + "' not found");
myUserAddresses.clear(); myUserAddresses.clear();
myUserLabels.clear(); myUserLabels.clear();
@ -645,9 +645,9 @@ string CartDebug::loadSymbolFile(string file)
addLabel(label, value); addLabel(label, value);
} }
in.close(); in.close();
return "loaded " + node.getRelativePath() + " OK"; return "loaded " + node.getPath(false) + " OK";
} }
return DebuggerParser::red("symbol file '" + node.getRelativePath() + "' not found"); return DebuggerParser::red("symbol file '" + node.getPath(false) + "' not found");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -783,7 +783,7 @@ string CartDebug::loadConfigFile(string file)
} }
in.close(); in.close();
return "loaded " + node.getRelativePath() + " OK"; return "loaded " + node.getPath(false) + " OK";
} }
else else
return DebuggerParser::red("config file not found"); return DebuggerParser::red("config file not found");
@ -827,7 +827,7 @@ string CartDebug::saveConfigFile(string file)
} }
out.close(); out.close();
return "saved " + node.getRelativePath() + " OK"; return "saved " + node.getPath(false) + " OK";
} }
else else
return DebuggerParser::red("config file not found"); return DebuggerParser::red("config file not found");

View File

@ -825,13 +825,16 @@ void Debugger::getCompletions(const char* in, StringList& list) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Debugger::saveROM(const string& filename) const string Debugger::saveROM(const string& filename) const
{ {
ofstream out(filename.c_str(), ios::out | ios::binary); string path = AbstractFilesystemNode::getAbsolutePath(filename, "~", "a26");
if(out.is_open()) FilesystemNode node(path);
return myConsole->cartridge().save(out);
ofstream out(node.getPath(true).c_str(), ios::out | ios::binary);
if(out.is_open() && myConsole->cartridge().save(out))
return node.getPath(false);
else else
return false; return "";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -289,7 +289,7 @@ class Debugger : public DialogContainer
void setBreakPoint(int bp, bool set); void setBreakPoint(int bp, bool set);
bool saveROM(const string& filename) const; string saveROM(const string& filename) const;
bool setBank(int bank); bool setBank(int bank);
bool patchROM(int addr, int value); bool patchROM(int addr, int value);

View File

@ -135,7 +135,7 @@ string DebuggerParser::exec(const FilesystemNode& file)
{ {
ifstream in(file.getPath().c_str()); ifstream in(file.getPath().c_str());
if(!in.is_open()) if(!in.is_open())
return red("autoexec file \'" + file.getRelativePath() + "\' not found"); return red("autoexec file \'" + file.getPath(false) + "\' not found");
ostringstream buf; ostringstream buf;
int count = 0; int count = 0;
@ -148,12 +148,12 @@ string DebuggerParser::exec(const FilesystemNode& file)
count++; count++;
} }
buf << "Executed " << debugger->valueToString(count) << " commands from \"" buf << "Executed " << debugger->valueToString(count) << " commands from \""
<< file.getRelativePath() << "\""; << file.getPath(false) << "\"";
return buf.str(); return buf.str();
} }
else else
return red("autoexec file \'" + file.getRelativePath() + "\' not found"); return red("autoexec file \'" + file.getPath(false) + "\' not found");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1419,8 +1419,9 @@ void DebuggerParser::executeSaveconfig()
// "saverom" // "saverom"
void DebuggerParser::executeSaverom() void DebuggerParser::executeSaverom()
{ {
if(debugger->saveROM(argStrings[0])) const string& result = debugger->saveROM(argStrings[0]);
commandResult << "saved ROM as " << argStrings[0]; if(result != "")
commandResult << "saved ROM as " << result;
else else
commandResult << red("failed to save ROM"); commandResult << red("failed to save ROM");
} }

View File

@ -2182,7 +2182,6 @@ void EventHandler::leaveDebugMode()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::setEventState(State state) void EventHandler::setEventState(State state)
{ {
cerr << "setEventState:" << state << endl;
myState = state; myState = state;
switch(myState) switch(myState)
@ -2231,7 +2230,7 @@ cerr << "setEventState:" << state << endl;
myEvent->clear(); myEvent->clear();
// Sometimes an extraneous mouse motion event is generated // Sometimes an extraneous mouse motion event is generated
// after a state change, which should be surpressed // after a state change, which should be supressed
mySkipMouseMotion = true; mySkipMouseMotion = true;
} }

View File

@ -39,9 +39,7 @@ FilesystemNode::FilesystemNode(AbstractFilesystemNode *realNode)
FilesystemNode::FilesystemNode(const string& p) FilesystemNode::FilesystemNode(const string& p)
{ {
AbstractFilesystemNode* tmp = 0; AbstractFilesystemNode* tmp = 0;
if (p.empty() || p == ".") if (p.empty() || p == "." || p == "~")
tmp = AbstractFilesystemNode::makeCurrentDirectoryFileNode();
else if (p == "~")
tmp = AbstractFilesystemNode::makeHomeDirectoryFileNode(); tmp = AbstractFilesystemNode::makeHomeDirectoryFileNode();
else else
tmp = AbstractFilesystemNode::makeFileNodePath(p); tmp = AbstractFilesystemNode::makeFileNodePath(p);
@ -124,17 +122,10 @@ FilesystemNode FilesystemNode::getParent() const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string FilesystemNode::getPath() const string FilesystemNode::getPath(bool fqn) const
{ {
assert(_realNode); assert(_realNode);
return _realNode->getPath(); return _realNode->getPath(fqn);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string FilesystemNode::getRelativePath() const
{
assert(_realNode);
return _realNode->getRelativePath();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -116,8 +116,8 @@ class FilesystemNode
* Create a new FilesystemNode referring to the specified path. This is * Create a new FilesystemNode referring to the specified path. This is
* the counterpart to the path() method. * the counterpart to the path() method.
* *
* If path is empty or equals ".", then a node representing the "current * If path is empty or equals "." or "~", then a node representing the
* directory" will be created. If that is not possible (since e.g. the * "home directory" will be created. If that is not possible (since e.g. the
* operating system doesn't support the concept), some other directory is * operating system doesn't support the concept), some other directory is
* used (usually the root directory). * used (usually the root directory).
*/ */
@ -166,7 +166,11 @@ class FilesystemNode
virtual string getName() const; virtual string getName() const;
/** /**
* Return a string representation of the file which can be passed to fopen(). * Return a string representation of the file with the following properties:
* 1) can be passed to fopen() if fqn is true
* 2) contains the '~' symbol (if applicable), and is suitable for archiving
* (i.e. writing to the config file) if fqn is false
*
* This will usually be a 'path' (hence the name of the method), but can * This will usually be a 'path' (hence the name of the method), but can
* be anything that fulfills the above criterions. * be anything that fulfills the above criterions.
* *
@ -175,19 +179,7 @@ class FilesystemNode
* *
* @return the 'path' represented by this filesystem node * @return the 'path' represented by this filesystem node
*/ */
virtual string getPath() const; virtual string getPath(bool fqn = true) const;
/**
* Return a string representation of the file which contains the '~'
* symbol (if applicable), and is suitable for archiving (i.e. writing
* to the config file).
*
* @note Do not assume that this string contains (back)slashes or any
* other kind of 'path separators'.
*
* @return the 'path' represented by this filesystem node
*/
virtual string getRelativePath() const;
/** /**
* Determine whether this node has a parent. * Determine whether this node has a parent.
@ -302,14 +294,10 @@ class AbstractFilesystemNode
virtual string getName() const = 0; virtual string getName() const = 0;
/** /**
* Returns the 'path' of the current node, usable in fopen(). * Returns the 'path' of the current node, usable in fopen() or
containing '~' and for archiving.
*/ */
virtual string getPath() const = 0; virtual string getPath(bool fqn = true) const = 0;
/**
* Returns the 'path' of the current node, containing '~' and for archiving.
*/
virtual string getRelativePath() const = 0;
/** /**
* Indicates whether this path refers to a directory or not. * Indicates whether this path refers to a directory or not.
@ -356,6 +344,14 @@ class AbstractFilesystemNode
*/ */
static bool renameFile(const string& oldfile, const string& newfile); static bool renameFile(const string& oldfile, const string& newfile);
/**
Create an absolute pathname from the given path (if it isn't already
absolute), pre-pending 'startpath' when necessary. If the path doesn't
have an extension matching 'ext', append it to the path.
*/
static string getAbsolutePath(const string& p, const string& startpath,
const string& ext);
protected: protected:
/** /**
* The parent node of this directory. * The parent node of this directory.
@ -363,14 +359,6 @@ class AbstractFilesystemNode
*/ */
virtual AbstractFilesystemNode* getParent() const = 0; virtual AbstractFilesystemNode* getParent() const = 0;
/**
* Returns a node representing the "current directory".
* If your system does not support this concept, you can either try to
* emulate it or simply return some "sensible" default directory node,
* e.g. the same value as getRoot() returns.
*/
static AbstractFilesystemNode* makeCurrentDirectoryFileNode();
/** /**
* Returns a node representing the "home directory". * Returns a node representing the "home directory".
* *

View File

@ -325,19 +325,19 @@ void OSystem::setConfigPaths()
if(s == "") s = myBaseDir + "stella.cht"; if(s == "") s = myBaseDir + "stella.cht";
node = FilesystemNode(s); node = FilesystemNode(s);
myCheatFile = node.getPath(); myCheatFile = node.getPath();
mySettings->setString("cheatfile", node.getRelativePath()); mySettings->setString("cheatfile", node.getPath(false));
s = mySettings->getString("palettefile"); s = mySettings->getString("palettefile");
if(s == "") s = myBaseDir + "stella.pal"; if(s == "") s = myBaseDir + "stella.pal";
node = FilesystemNode(s); node = FilesystemNode(s);
myPaletteFile = node.getPath(); myPaletteFile = node.getPath();
mySettings->setString("palettefile", node.getRelativePath()); mySettings->setString("palettefile", node.getPath(false));
s = mySettings->getString("propsfile"); s = mySettings->getString("propsfile");
if(s == "") s = myBaseDir + "stella.pro"; if(s == "") s = myBaseDir + "stella.pro";
node = FilesystemNode(s); node = FilesystemNode(s);
myPropertiesFile = node.getPath(); myPropertiesFile = node.getPath();
mySettings->setString("propsfile", node.getRelativePath()); mySettings->setString("propsfile", node.getPath(false));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -875,7 +875,7 @@ void OSystem::validatePath(const string& setting, const string& partialpath,
node = FilesystemNode(node.getPath()); node = FilesystemNode(node.getPath());
} }
fullpath = node.getPath(); fullpath = node.getPath();
mySettings->setString(setting, node.getRelativePath()); mySettings->setString(setting, node.getPath(false));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -164,7 +164,7 @@ void BrowserDialog::updateListing()
_nodeList->clear(); _nodeList->clear();
// Update the path display // Update the path display
_currentPath->setLabel(_node.getRelativePath()); _currentPath->setLabel(_node.getPath(false));
// Read in the data from the file system // Read in the data from the file system
FSList content; FSList content;

View File

@ -225,31 +225,31 @@ void FileSnapDialog::setDefaults()
const string& basedir = instance().baseDir(); const string& basedir = instance().baseDir();
node = FilesystemNode("~"); node = FilesystemNode("~");
myRomPath->setEditString(node.getRelativePath()); myRomPath->setEditString(node.getPath(false));
const string& statedir = basedir + "state"; const string& statedir = basedir + "state";
node = FilesystemNode(statedir); node = FilesystemNode(statedir);
myStatePath->setEditString(node.getRelativePath()); myStatePath->setEditString(node.getPath(false));
const string& cheatfile = basedir + "stella.cht"; const string& cheatfile = basedir + "stella.cht";
node = FilesystemNode(cheatfile); node = FilesystemNode(cheatfile);
myCheatFile->setEditString(node.getRelativePath()); myCheatFile->setEditString(node.getPath(false));
const string& palettefile = basedir + "stella.pal"; const string& palettefile = basedir + "stella.pal";
node = FilesystemNode(palettefile); node = FilesystemNode(palettefile);
myPaletteFile->setEditString(node.getRelativePath()); myPaletteFile->setEditString(node.getPath(false));
const string& propsfile = basedir + "stella.pro"; const string& propsfile = basedir + "stella.pro";
node = FilesystemNode(propsfile); node = FilesystemNode(propsfile);
myPropsFile->setEditString(node.getRelativePath()); myPropsFile->setEditString(node.getPath(false));
const string& eepromdir = basedir; const string& eepromdir = basedir;
node = FilesystemNode(eepromdir); node = FilesystemNode(eepromdir);
myEEPROMPath->setEditString(node.getRelativePath()); myEEPROMPath->setEditString(node.getPath(false));
const string& ssdir = basedir + "snapshots"; const string& ssdir = basedir + "snapshots";
node = FilesystemNode(ssdir); node = FilesystemNode(ssdir);
mySnapPath->setEditString(node.getRelativePath()); mySnapPath->setEditString(node.getPath(false));
mySnapSingle->setState(false); mySnapSingle->setState(false);
mySnap1x->setState(false); mySnap1x->setState(false);
@ -311,49 +311,49 @@ void FileSnapDialog::handleCommand(CommandSender* sender, int cmd,
case kRomDirChosenCmd: case kRomDirChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myRomPath->setEditString(dir.getRelativePath()); myRomPath->setEditString(dir.getPath(false));
break; break;
} }
case kStateDirChosenCmd: case kStateDirChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myStatePath->setEditString(dir.getRelativePath()); myStatePath->setEditString(dir.getPath(false));
break; break;
} }
case kCheatFileChosenCmd: case kCheatFileChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myCheatFile->setEditString(dir.getRelativePath()); myCheatFile->setEditString(dir.getPath(false));
break; break;
} }
case kPaletteFileChosenCmd: case kPaletteFileChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myPaletteFile->setEditString(dir.getRelativePath()); myPaletteFile->setEditString(dir.getPath(false));
break; break;
} }
case kPropsFileChosenCmd: case kPropsFileChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myPropsFile->setEditString(dir.getRelativePath()); myPropsFile->setEditString(dir.getPath(false));
break; break;
} }
case kSnapDirChosenCmd: case kSnapDirChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
mySnapPath->setEditString(dir.getRelativePath()); mySnapPath->setEditString(dir.getPath(false));
break; break;
} }
case kEEPROMDirChosenCmd: case kEEPROMDirChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myEEPROMPath->setEditString(dir.getRelativePath()); myEEPROMPath->setEditString(dir.getPath(false));
break; break;
} }

View File

@ -293,7 +293,7 @@ void LauncherDialog::updateListing(const string& nameToSelect)
myPrevDirButton->setEnabled(myCurrentNode.hasParent()); myPrevDirButton->setEnabled(myCurrentNode.hasParent());
// Show current directory // Show current directory
myDir->setLabel(myCurrentNode.getRelativePath()); myDir->setLabel(myCurrentNode.getPath(false));
// Now fill the list widget with the contents of the GameList // Now fill the list widget with the contents of the GameList
StringList l; StringList l;
@ -586,7 +586,7 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
case kStartupRomDirChosenCmd: case kStartupRomDirChosenCmd:
{ {
FilesystemNode dir(myRomDir->getResult()); FilesystemNode dir(myRomDir->getResult());
instance().settings().setString("romdir", dir.getRelativePath()); instance().settings().setString("romdir", dir.getPath(false));
// fall through to the next case // fall through to the next case
} }
case kRomDirChosenCmd: case kRomDirChosenCmd:

View File

@ -109,7 +109,7 @@ RomAuditDialog::~RomAuditDialog()
void RomAuditDialog::loadConfig() void RomAuditDialog::loadConfig()
{ {
const string& currentdir = const string& currentdir =
instance().launcher().currentNode().getRelativePath(); instance().launcher().currentNode().getPath(false);
const string& path = currentdir == "" ? const string& path = currentdir == "" ?
instance().settings().getString("romdir") : currentdir; instance().settings().getString("romdir") : currentdir;
@ -209,7 +209,7 @@ void RomAuditDialog::handleCommand(CommandSender* sender, int cmd,
case kAuditDirChosenCmd: case kAuditDirChosenCmd:
{ {
FilesystemNode dir(myBrowser->getResult()); FilesystemNode dir(myBrowser->getResult());
myRomPath->setEditString(dir.getRelativePath()); myRomPath->setEditString(dir.getPath(false));
myResults1->setLabel(""); myResults1->setLabel("");
myResults2->setLabel(""); myResults2->setLabel("");
break; break;

View File

@ -1920,7 +1920,7 @@
2D91752309BA903B0026E9FF /* Deployment */ = { 2D91752309BA903B0026E9FF /* Deployment */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; ARCHS = "$(ARCHS_STANDARD_64_BIT)";
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
., .,
"$(HOME)/Library/Frameworks", "$(HOME)/Library/Frameworks",

View File

@ -58,17 +58,16 @@ class POSIXFilesystemNode : public AbstractFilesystemNode
*/ */
POSIXFilesystemNode(const string& path, bool verify); POSIXFilesystemNode(const string& path, bool verify);
virtual bool exists() const { return access(_path.c_str(), F_OK) == 0; } bool exists() const { return access(_path.c_str(), F_OK) == 0; }
virtual string getDisplayName() const { return _displayName; } string getDisplayName() const { return _displayName; }
virtual string getName() const { return _displayName; } string getName() const { return _displayName; }
virtual string getPath() const { return _path; } string getPath(bool fqn) const;
virtual string getRelativePath() const; bool isDirectory() const { return _isDirectory; }
virtual bool isDirectory() const { return _isDirectory; } bool isReadable() const { return access(_path.c_str(), R_OK) == 0; }
virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; } bool isWritable() const { return access(_path.c_str(), W_OK) == 0; }
virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; }
virtual bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const; bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const;
virtual AbstractFilesystemNode* getParent() const; AbstractFilesystemNode* getParent() const;
protected: protected:
string _displayName; string _displayName;
@ -183,21 +182,17 @@ POSIXFilesystemNode::POSIXFilesystemNode(const string& p, bool verify)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string POSIXFilesystemNode::getRelativePath() const string POSIXFilesystemNode::getPath(bool fqn) const
{ {
// If the path starts with the home directory, replace it with '~' // If the path starts with the home directory, replace it with '~'
const char* home = getenv("HOME"); const char* home = getenv("HOME");
if(home != NULL) if(!fqn && home != NULL && BSPF_startsWithIgnoreCase(_path, home))
{ {
int len = strlen(home); string path = "~";
if(strncmp(_path.c_str(), home, len) == 0) const char* offset = _path.c_str() + strlen(home);
{ if(*offset != '/') path += "/";
string path = "~"; path += offset;
const char* offset = _path.c_str() + len; return path;
if(*offset != '/') path += "/";
path += offset;
return path;
}
} }
return _path; return _path;
} }
@ -301,12 +296,6 @@ AbstractFilesystemNode* AbstractFilesystemNode::makeRootFileNode()
return new POSIXFilesystemNode(); return new POSIXFilesystemNode();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AbstractFilesystemNode* AbstractFilesystemNode::makeCurrentDirectoryFileNode()
{
return new POSIXFilesystemNode("./", true);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AbstractFilesystemNode* AbstractFilesystemNode::makeHomeDirectoryFileNode() AbstractFilesystemNode* AbstractFilesystemNode::makeHomeDirectoryFileNode()
{ {
@ -331,3 +320,29 @@ bool AbstractFilesystemNode::renameFile(const string& oldfile,
{ {
return rename(oldfile.c_str(), newfile.c_str()) == 0; return rename(oldfile.c_str(), newfile.c_str()) == 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string AbstractFilesystemNode::getAbsolutePath(const string& p,
const string& startpath,
const string& ext)
{
// Does p start with the root directory or the given startpath?
// If not, it isn't an absolute path
string path = FilesystemNode(p).getPath(false);
if(!BSPF_startsWithIgnoreCase(p, startpath+"/") &&
!BSPF_startsWithIgnoreCase(p, "/"))
path = startpath + "/" + p;
// Does the path have a valid extension?
// If not, we add the given one
string::size_type idx = path.find_last_of('.');
if(idx != string::npos)
{
if(!BSPF_equalsIgnoreCase(path.c_str() + idx + 1, ext))
path = path.replace(idx+1, ext.length(), ext);
}
else
path += "." + ext;
return path;
}

View File

@ -91,17 +91,16 @@ class WindowsFilesystemNode : public AbstractFilesystemNode
*/ */
WindowsFilesystemNode(const string& path); WindowsFilesystemNode(const string& path);
virtual bool exists() const { return _access(_path.c_str(), F_OK) == 0; } bool exists() const { return _access(_path.c_str(), F_OK) == 0; }
virtual string getDisplayName() const { return _displayName; } string getDisplayName() const { return _displayName; }
virtual string getName() const { return _displayName; } string getName() const { return _displayName; }
virtual string getPath() const { return _path; } string getPath(bool fqn) const;
virtual string getRelativePath() const; bool isDirectory() const { return _isDirectory; }
virtual bool isDirectory() const { return _isDirectory; } bool isReadable() const { return _access(_path.c_str(), R_OK) == 0; }
virtual bool isReadable() const { return _access(_path.c_str(), R_OK) == 0; } bool isWritable() const { return _access(_path.c_str(), W_OK) == 0; }
virtual bool isWritable() const { return _access(_path.c_str(), W_OK) == 0; }
virtual bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const; bool getChildren(AbstractFSList& list, ListMode mode, bool hidden) const;
virtual AbstractFilesystemNode* getParent() const; AbstractFilesystemNode* getParent() const;
protected: protected:
string _displayName; string _displayName;
@ -286,22 +285,16 @@ WindowsFilesystemNode::WindowsFilesystemNode(const string& p)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string WindowsFilesystemNode::getRelativePath() const string WindowsFilesystemNode::getPath(bool fqn) const
{ {
// If the path starts with the home directory, replace it with '~' // If the path starts with the home directory, replace it with '~'
const string& home = myHomeFinder.getHomePath(); const string& home = myHomeFinder.getHomePath();
if(home != "") if(!fqn && home != "" && BSPF_startsWithIgnoreCase(_path, home))
{ string path = "~";
// Windows file system not case sensitive const char* offset = _path.c_str() + home.length();
int len = home.length(); if(*offset != '\\') path += '\\';
if(BSPF_strncasecmp(home.c_str(), _path.substr(0, len).c_str(), len) == 0) path += offset;
{ return path;
string path = "~";
const char* offset = _path.c_str() + len;
if(*offset != '\\') path += '\\';
path += offset;
return path;
}
} }
return _path; return _path;
} }
@ -423,3 +416,12 @@ bool AbstractFilesystemNode::renameFile(const string& oldfile,
{ {
return MoveFile(oldfile.c_str(), newfile.c_str()) != 0; return MoveFile(oldfile.c_str(), newfile.c_str()) != 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string AbstractFilesystemNode::getAbsolutePath(const string& p,
const string& startpath,
const string& ext)
{
assert(false);
return "";
}