Ticket #8762: getsavepath2.patch

File getsavepath2.patch, 17.3 KB (added by SF/david_corrales, 12 years ago)

Revision 2

  • home/david/Projects/scummvm/backends/platform/ds/arm9/source/gbampsave.h

    Property changes on: /home/david/Projects/scummvm
    ___________________________________________________________________
    Name: svn:ignore
       - config.log
    scummvm
    scummvm-static
    config.h
    config.mk
    .gdb_history
    dumps
    Credits.rtf
    *.mshark
    
       + .project
    config.h
    config.mk
    reconf.sh
    scummvm
    plugins
    
    
     
    2424#define _GBAMPSAVE_H_
    2525
    2626#include "system.h"
    27 #include "common/savefile.h"
     27#include "saves/default/default-saves.h"
    2828#include "ds-fs.h"
    2929
    3030#define SAVE_BUFFER_SIZE 100000
     
    5858};
    5959
    6060
    61 class GBAMPSaveFileManager : public Common::SaveFileManager {
    62 
    63        
     61class GBAMPSaveFileManager : public DefaultSaveFileManager {
    6462public:
    6563        GBAMPSaveFileManager();
    6664        ~GBAMPSaveFileManager();
     
    8179        void listFiles();
    8280};
    8381
    84 
    8582#endif
  • home/david/Projects/scummvm/backends/platform/ps2/savefile.h

     
    4242        virtual Common::OutSaveFile *openForSaving(const char *filename);
    4343        virtual void listSavefiles(const char *prefix, bool *marks, int num);
    4444
    45         /** Get the path to the save game directory. */
    46         virtual const char *getSavePath() const;
    47 
    4845        void writeSaveNonblocking(char *name, void *buf, uint32 size);
    4946        void saveThread(void);
    5047        void quit(void);
     48       
    5149private:
     50        /** Get the path to the save game directory. */
     51        virtual const char *getSavePath() const;
     52               
    5253        bool setupIcon(const char *dest, const char *ico, const char *descr1, const char *descr2);
    5354
    5455        bool mcReadyForDir(const char *dir);
  • home/david/Projects/scummvm/backends/saves/default/default-saves.cpp

     
    2929#include "common/util.h"
    3030#include "common/fs.h"
    3131#include "common/file.h"
     32#include "common/config-manager.h"
    3233#include "backends/saves/default/default-saves.h"
    3334#include "backends/saves/compressed/compressed-saves.h"
    3435
     
    128129        return results;
    129130}
    130131
    131 Common::InSaveFile *DefaultSaveFileManager::openForLoading(const char *filename) {
    132         char buf[256];
    133         join_paths(filename, getSavePath(), buf, sizeof(buf));
    134 
    135         StdioSaveFile *sf = new StdioSaveFile(buf, false);
    136 
    137         if (!sf->isOpen()) {
    138                 delete sf;
    139                 sf = 0;
    140         }
    141         return wrapInSaveFile(sf);
    142 }
    143 
    144 Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const char *filename) {
    145         char buf[256];
    146 
    147         // Ensure that the savepath exists and is writeable. If not, generate
    148         // an appropriate error
    149         const char *savePath = getSavePath();
     132void DefaultSaveFileManager::checkPath(const char *path) {
     133        clearError();
    150134
    151135#if defined(UNIX) || defined(__SYMBIAN32__)
    152136        struct stat sb;
    153         clearError();
    154137
    155138        // Check whether the dir exists
    156         if (stat(savePath, &sb) == -1) {
     139        if (stat(path, &sb) == -1) {
    157140                // The dir does not exist, or stat failed for some other reason.
    158141                // If the problem was that the path pointed to nothing, try
    159142                // to create the dir (ENOENT case).
     
    159142                // to create the dir (ENOENT case).
    160143                switch (errno) {
    161144                case EACCES:
    162                         setError(SFM_DIR_ACCESS, Common::String("Search or write permission denied"));
     145                        setError(SFM_DIR_ACCESS, Common::String("Search or write permission denied: ")+path);
    163146                        break;
    164147#if !defined(__SYMBIAN32__)
    165148                case ELOOP:
    166                         setError(SFM_DIR_LOOP, Common::String("Too many symbolic links encountered while traversing the path"));
     149                        setError(SFM_DIR_LOOP, Common::String("Too many symbolic links encountered while traversing the path: ")+path);
    167150                        break;
    168151#endif
    169152                case ENAMETOOLONG:
    170                         setError(SFM_DIR_NAMETOOLONG, Common::String("The path name is too long"));
     153                        setError(SFM_DIR_NAMETOOLONG, Common::String("The path name is too long: ")+path);
    171154                        break;
    172155                case ENOENT:
    173                         if (mkdir(savePath, 0755) != 0) {
     156                        if (mkdir(path, 0755) != 0) {
    174157                                // mkdir could fail for various reasons: The parent dir doesn't exist,
    175158                                // or is not writeable, the path could be completly bogus, etc.
    176                                 warning("mkdir for '%s' failed!", savePath);
     159                                warning("mkdir for '%s' failed!", path);
    177160                                perror("mkdir");
    178161
    179162                                switch (errno) {
     
    178161
    179162                                switch (errno) {
    180163                                case EACCES:
    181                                         setError(SFM_DIR_ACCESS, Common::String("Search or write permission denied"));
     164                                        setError(SFM_DIR_ACCESS, Common::String("Search or write permission denied: ")+path);
    182165                                        break;
    183166                                case EMLINK:
    184                                         setError(SFM_DIR_LINKMAX, Common::String("The link count of the parent directory would exceed {LINK_MAX}"));
     167                                        setError(SFM_DIR_LINKMAX, Common::String("The link count of the parent directory would exceed {LINK_MAX}: ")+path);
    185168                                        break;
    186169#if !defined(__SYMBIAN32__)
    187170                                case ELOOP:
    188                                         setError(SFM_DIR_LOOP, Common::String("Too many symbolic links encountered while traversing the path"));
     171                                        setError(SFM_DIR_LOOP, Common::String("Too many symbolic links encountered while traversing the path: ")+path);
    189172                                        break;
    190173#endif
    191174                                case ENAMETOOLONG:
    192                                         setError(SFM_DIR_NAMETOOLONG, Common::String("The path name is too long"));
     175                                        setError(SFM_DIR_NAMETOOLONG, Common::String("The path name is too long: ")+path);
    193176                                        break;
    194177                                case ENOENT:
    195                                         setError(SFM_DIR_NOENT, Common::String("A component of the path does not exist, or the path is an empty string"));
     178                                        setError(SFM_DIR_NOENT, Common::String("A component of the path does not exist, or the path is an empty string: ")+path);
    196179                                        break;
    197180                                case ENOTDIR:
    198                                         setError(SFM_DIR_NOTDIR, Common::String("A component of the path prefix is not a directory"));
     181                                        setError(SFM_DIR_NOTDIR, Common::String("A component of the path prefix is not a directory: ")+path);
    199182                                        break;
    200183                                case EROFS:
    201                                         setError(SFM_DIR_ROFS, Common::String("The parent directory resides on a read-only file system"));
     184                                        setError(SFM_DIR_ROFS, Common::String("The parent directory resides on a read-only file system:")+path);
    202185                                        break;
    203186                                }
    204 
    205                                 return 0;
    206187                        }
    207188                        break;
    208189                case ENOTDIR:
    209                         setError(SFM_DIR_NOTDIR, Common::String("A component of the path prefix is not a directory"));
     190                        setError(SFM_DIR_NOTDIR, Common::String("A component of the path prefix is not a directory: ")+path);
    210191                        break;
    211192                }
    212193        } else {
     
    212193        } else {
    213194                // So stat() succeeded. But is the path actually pointing to a directory?
    214195                if (!S_ISDIR(sb.st_mode)) {
    215                         setError(SFM_DIR_NOTDIR, Common::String("The given savepath is not a directory"));
    216 
    217                         return 0;
     196                        setError(SFM_DIR_NOTDIR, Common::String("The given savepath is not a directory: ")+path);
    218197                }
    219198        }
    220199#endif
     200}
    221201
    222         join_paths(filename, savePath, buf, sizeof(buf));
     202Common::InSaveFile *DefaultSaveFileManager::openForLoading(const char *filename) {
     203        // Ensure that the savepath is valid. If not, generate an appropriate error.
     204        char buf[256];
     205        const char *savePath = getSavePath();
     206        checkPath(savePath);
     207       
     208        if (getError() == SFM_NO_ERROR) {
     209                join_paths(filename, savePath, buf, sizeof(buf));
     210                StdioSaveFile *sf = new StdioSaveFile(buf, false);
     211       
     212                if (!sf->isOpen()) {
     213                        delete sf;
     214                        sf = 0;
     215                }
     216               
     217                return wrapInSaveFile(sf);
     218        } else {
     219                return 0;
     220        }
     221}
    223222
    224         StdioSaveFile *sf = new StdioSaveFile(buf, true);
     223Common::OutSaveFile *DefaultSaveFileManager::openForSaving(const char *filename) {
     224        // Ensure that the savepath is valid. If not, generate an appropriate error.
     225        char buf[256];
     226        const char *savePath = getSavePath();
     227        checkPath(savePath);
    225228
    226         if (!sf->isOpen()) {
    227                 delete sf;
    228                 sf = 0;
     229        if (getError() == SFM_NO_ERROR) {
     230                join_paths(filename, savePath, buf, sizeof(buf));
     231                StdioSaveFile *sf = new StdioSaveFile(buf, true);
     232       
     233                if (!sf->isOpen()) {
     234                        delete sf;
     235                        sf = 0;
     236                }
     237       
     238                return wrapOutSaveFile(sf);
     239        } else {
     240                return 0;
    229241        }
    230 
    231         return wrapOutSaveFile(sf);
    232242}
    233243
    234244bool DefaultSaveFileManager::removeSavefile(const char *filename) {
     
    233243
    234244bool DefaultSaveFileManager::removeSavefile(const char *filename) {
    235245        char buf[256];
     246        clearError();
    236247        join_paths(filename, getSavePath(), buf, sizeof(buf));
    237248       
    238249        if (remove(buf) != 0) {
     
    238249        if (remove(buf) != 0) {
    239250#ifndef _WIN32_WCE
    240251                if (errno == EACCES)
    241                         setError(SFM_DIR_ACCESS, Common::String("Search or write permission denied"));
     252                        setError(SFM_DIR_ACCESS, Common::String("Search or write permission denied: ")+filename);
    242253               
    243254                if (errno == ENOENT)
    244                         setError(SFM_DIR_NOENT, Common::String("A component of the path does not exist, or the path is an empty string"));
     255                        setError(SFM_DIR_NOENT, Common::String("A component of the path does not exist, or the path is an empty string: ")+filename);
    245256#endif
    246257                return false;
    247258        } else {
     
    249260        }
    250261}
    251262
     263const char *DefaultSaveFileManager::getSavePath() const {
     264
     265#if defined(PALMOS_MODE) || defined(__PSP__)
     266        return SCUMMVM_SAVEPATH;
     267#else
     268
     269        const char *dir = NULL;
     270
     271        // Try to use game specific savepath from config
     272        dir = ConfMan.get("savepath").c_str();
     273
     274        // Work around a bug (#999122) in the original 0.6.1 release of
     275        // ScummVM, which would insert a bad savepath value into config files.
     276        if (0 == strcmp(dir, "None")) {
     277                ConfMan.removeKey("savepath", ConfMan.getActiveDomainName());
     278                ConfMan.flushToDisk();
     279                dir = ConfMan.get("savepath").c_str();
     280        }
     281
     282#ifdef _WIN32_WCE
     283        if (dir[0] == 0)
     284                dir = ConfMan.get("path").c_str();
     285#endif
     286
     287        assert(dir);
     288
     289        return dir;
     290#endif
     291}
     292
    252293#endif // !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)
  • home/david/Projects/scummvm/backends/saves/default/default-saves.h

     
    2929#include "common/savefile.h"
    3030#include "common/str.h"
    3131
     32/**
     33 * Provides a default savefile manager implementation for common platforms.
     34 */
    3235class DefaultSaveFileManager : public Common::SaveFileManager {
    3336public:
    3437        virtual Common::StringList listSavefiles(const char *regex);
     
    3538        virtual Common::InSaveFile *openForLoading(const char *filename);
    3639        virtual Common::OutSaveFile *openForSaving(const char *filename);
    3740        virtual bool removeSavefile(const char *filename);
     41
     42protected:
     43        /**
     44         * Get the path to the savegame directory.
     45         * Should only be used internally since some platforms
     46         * might implement savefiles in a completely different way.
     47         */
     48        virtual const char *getSavePath() const;
     49       
     50        /**
     51         * Checks the given path for read access, existence, etc.
     52         * Sets the internal error and error message accordingly.
     53         */
     54        void checkPath(const char *path);
    3855};
    3956
    4057#endif
  • home/david/Projects/scummvm/backends/saves/savefile.cpp

     
    2424 */
    2525
    2626#include "common/util.h"
    27 #include "common/config-manager.h"
    2827#include "common/savefile.h"
    2928
    3029#include <stdio.h>
     
    7271        return success;
    7372}
    7473
    75 const char *SaveFileManager::getSavePath() const {
    76 
    77 #if defined(PALMOS_MODE) || defined(__PSP__)
    78         return SCUMMVM_SAVEPATH;
    79 #else
    80 
    81         const char *dir = NULL;
    82 
    83         // Try to use game specific savepath from config
    84         dir = ConfMan.get("savepath").c_str();
    85 
    86         // Work around a bug (#999122) in the original 0.6.1 release of
    87         // ScummVM, which would insert a bad savepath value into config files.
    88         if (0 == strcmp(dir, "None")) {
    89                 ConfMan.removeKey("savepath", ConfMan.getActiveDomainName());
    90                 ConfMan.flushToDisk();
    91                 dir = ConfMan.get("savepath").c_str();
    92         }
    93 
    94 #ifdef _WIN32_WCE
    95         if (dir[0] == 0)
    96                 dir = ConfMan.get("path").c_str();
    97 #endif
    98 
    99         assert(dir);
    100 
    101         return dir;
    102 #endif
     74String SaveFileManager::popErrorDesc() {
     75        String err = _errorDesc;
     76        clearError();
     77       
     78        return err;
    10379}
    10480
    10581} // End of namespace Common
  • home/david/Projects/scummvm/common/savefile.h

     
    109109         * @return A string describing the last error.
    110110         */
    111111        virtual String getErrorDesc() { return _errorDesc; }
    112 
     112       
     113        /**
     114         * Returns the last ocurred error description. If none ocurred, returns 0.
     115         * Also clears the last error state and description.
     116         *
     117         * @return A string describing the last error.
     118         */
     119        virtual String popErrorDesc();
     120       
    113121        /**
    114122         * Open the file with name filename in the given directory for saving.
    115123         * @param filename      the filename
     
    145153         * returns a list of strings for all present file names.
    146154         */
    147155        virtual Common::StringList listSavefiles(const char *regex) = 0;
    148 
    149         /**
    150          * Get the path to the save game directory.
    151          * Should only be used for error messages, *never* to construct file paths
    152          * from it, since that is highly unportable!
    153          */
    154         virtual const char *getSavePath() const;
    155156};
    156157
    157158} // End of namespace Common
  • home/david/Projects/scummvm/engines/sky/control.cpp

     
    944944                                                refreshNames = true;
    945945                                        }
    946946                                        if (clickRes == NO_DISK_SPACE) {
    947                                                 displayMessage(0, "Could not save game in directory '%s'", _saveFileMan->getSavePath());
     947                                                displayMessage(0, "Could not save the game. (%s)", _saveFileMan->popErrorDesc().c_str());
    948948                                                quitPanel = true;
    949949                                        }
    950950                                        if ((clickRes == CANCEL_PRESSED) || (clickRes == GAME_RESTORED))
     
    11531153                delete outf;
    11541154        }
    11551155        if (ioFailed)
    1156                 displayMessage(NULL, "Unable to store Savegame names to file SKY-VM.SAV in directory %s", _saveFileMan->getSavePath());
     1156                displayMessage(NULL, "Unable to store Savegame names to file SKY-VM.SAV. (%s)", _saveFileMan->popErrorDesc().c_str());
    11571157        free(tmpBuf);
    11581158}
    11591159
     
    11671167
    11681168        outf = _saveFileMan->openForSaving(fName);
    11691169        if (outf == NULL) {
    1170                 displayMessage(0, "Unable to create autosave file '%s' in directory '%s'", fName, _saveFileMan->getSavePath());
     1170                displayMessage(0, "Unable to create autosave file '%s'. (%s)", fName, _saveFileMan->popErrorDesc().c_str());
    11711171                return;
    11721172        }
    11731173        uint8 *saveData = (uint8 *)malloc(0x20000);
     
    11771177        outf->finalize();
    11781178
    11791179        if (outf->ioFailed())
    1180                 displayMessage(0, "Unable to write autosave file '%s' in directory '%s'. Disk full?", fName, _saveFileMan->getSavePath());
     1180                displayMessage(0, "Unable to write autosave file '%s'. Disk full?", fName, _saveFileMan->popErrorDesc().c_str());
    11811181
    11821182        delete outf;
    11831183        free(saveData);
  • home/david/Projects/scummvm/engines/sword1/control.cpp

     
    738738
    739739        if (!outf) {
    740740                // Display an error message, and do nothing
    741                 displayMessage(0, "Can't create SAVEGAME.INF in directory '%s'", _saveFileMan->getSavePath());
     741                displayMessage(0, "Can't create SAVEGAME.INF. (%s)", _saveFileMan->popErrorDesc().c_str());
    742742                return;
    743743        }
    744744
     
    757757        }
    758758        outf->finalize();
    759759        if (outf->ioFailed())
    760                 displayMessage(0, "Can't write to SAVEGAME.INF in directory '%s'. Device full?", _saveFileMan->getSavePath());
     760                displayMessage(0, "Can't write to SAVEGAME.INF. Device full? (%s)", _saveFileMan->popErrorDesc().c_str());
    761761        delete outf;
    762762}
    763763
     
    928928        outf = _saveFileMan->openForSaving(fName);
    929929        if (!outf) {
    930930                // Display an error message and do nothing
    931                 displayMessage(0, "Unable to create file '%s' in directory '%s'", fName, _saveFileMan->getSavePath());
     931                displayMessage(0, "Unable to create file '%s'. (%s)", fName, _saveFileMan->popErrorDesc().c_str());
    932932                return;
    933933        }
    934934
     
    952952                outf->writeUint32LE(playerRaw[cnt2]);
    953953        outf->finalize();
    954954        if (outf->ioFailed())
    955                 displayMessage(0, "Couldn't write to file '%s' in directory '%s'. Device full?", fName, _saveFileMan->getSavePath());
     955                displayMessage(0, "Couldn't write to file '%s'. Device full? (%s)", fName, _saveFileMan->popErrorDesc().c_str());
    956956        delete outf;
    957957}
    958958
     
    964964        inf = _saveFileMan->openForLoading(fName);
    965965        if (!inf) {
    966966                // Display an error message, and do nothing
    967                 displayMessage(0, "Can't open file '%s' in directory '%s'", fName, _saveFileMan->getSavePath());
     967                displayMessage(0, "Can't open file '%s'. (%s)", fName, _saveFileMan->popErrorDesc().c_str());
    968968                return false;
    969969        }
    970970
     
    988988                playerBuf[cnt2] = inf->readUint32LE();
    989989
    990990        if (inf->ioFailed()) {
    991                 displayMessage(0, "Can't read from file '%s' in directory '%s'", fName, _saveFileMan->getSavePath());
     991                displayMessage(0, "Can't read from file '%s'. (%s)", fName, _saveFileMan->popErrorDesc().c_str());
    992992                delete inf;
    993993                free(_restoreBuf);
    994994                _restoreBuf = NULL;