diff mde/resource/paths.d @ 18:56a42ec95024

Changes to Init and logging. Moved an Init function; hence events now depends on Init rather than vice-versa. Paths and logging set up by Init's static this(). Logging location set at compile time. committer: Diggory Hardy <diggory.hardy@gmail.com>
author Diggory Hardy <diggory.hardy@gmail.com>
date Tue, 18 Mar 2008 17:51:52 +0000
parents 5f90774ea1ef
children 32eff0e01c05
line wrap: on
line diff
--- a/mde/resource/paths.d	Sat Mar 15 15:14:25 2008 +0000
+++ b/mde/resource/paths.d	Tue Mar 18 17:51:52 2008 +0000
@@ -102,13 +102,23 @@
         paths[pathsLen++] = path~'/';
     }
     
-    // Test a path and add if is a folder
-    void tryPath (char[] path) {
-        PathView pv = FilePath (path);
-        if (pv.exists && pv.isFolder) {
+    // Test a path and add if is a folder.
+    bool tryPath (char[] path, bool create = false) {
+        FilePath fp = FilePath (path);
+        if (fp.exists && fp.isFolder) {
             paths[pathsLen++] = path~'/';
-            logger.info ("Path "~path~" is writable: " ~ (pv.isWritable ? "yes" : "no"));
+            return true;
+        } else if (create) {
+            try {
+                fp.create;
+                paths[pathsLen++] = fp.toString~'/';
+                return true;
+            } catch (Exception e) {
+                logger.warn ("Creating path "~path~" failed:");
+                logger.warn (e.msg);
+            }
         }
+        return false;
     }
     
     // Use a static array to store all possible paths with separate length counters.
@@ -119,34 +129,11 @@
 
 /** These are the actual instances, one for each of the data and conf "directories". */
 mdeDirectory dataDir, confDir;
+char[] logDir;
 
 //BEGIN Path resolution
 static this() {
     logger = Log.getLogger ("mde.resource.paths");
-    
-    // NOTE: May fail. Currently I think I'll just let the exception halt execution.
-    resolvePaths();
-    if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!");
-    if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!");
-}
-
-private:
-// The maximum number of paths for any one "directory".
-// There are NO CHECKS that this is not exceeded.
-const MAX_PATHS = 3;
-
-Logger logger;
-
-/* Try each path in succession, returning the first two exist and be a folder. Throws if none are. */
-char[] findPath (char[][] paths ...) {
-    foreach (path; paths) {
-        PathView pv = new FilePath (path);
-        if (pv.exists && pv.isFolder) return pv.toString;    // got a valid path
-    }
-    // no valid path...
-    logger.fatal ("Unable to resolve a required path! The following were tried:");
-    foreach (path; paths) logger.fatal ('\t' ~ path);
-    throw new mdeException ("Unable to resolve a required path (see log for details).");
 }
 
 // These are used several times:
@@ -155,21 +142,33 @@
 
 version (linux) {
     void resolvePaths () {
+        logger.trace ("1");
         // Home directory:
         char[] HOME = fromStringz (getenv (toStringz ("HOME")));
         
+        logger.trace ("3");
         // Base paths:
-        char[] staticPath = findPath ("/usr/share/games/mde", "/usr/local/share/games/mde", "data");
-        char[] userPath = findPath (HOME~"/.config/mde", HOME~"/.mde");
+        // Static data (must exist):
+        PathView staticPath = findPath (false, "/usr/share/games/mde", "/usr/local/share/games/mde", "data");
+        // Config (can just use defaults if necessary, so long as we can save afterwards):
+        PathView userPath = findPath (true, HOME~"/.config/mde", HOME~"/.mde");
         
+        logger.trace ("5");
         // Static data paths:
-        dataDir.addPath (staticPath);      // we know this is valid anyway
-        dataDir.tryPath (userPath ~ DATA);
+        dataDir.addPath (staticPath.toString);      // we know this is valid anyway
+        dataDir.tryPath (userPath.toString ~ DATA);
+        if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!");
         
+        logger.trace ("7");
         // Configuration paths:
-        confDir.tryPath (staticPath ~ CONF);
-        confDir.tryPath ("/etc/mde");
-        confDir.tryPath (userPath ~ CONF);
+        confDir.tryPath (staticPath.toString ~ CONF);
+        bool sysConf = confDir.tryPath ("/etc/mde");
+        confDir.tryPath (userPath.toString ~ CONF, !sysConf);
+        if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!");
+        
+        logger.trace ("9");
+        // Logging path:
+        logDir = userPath.toString;
     }
 } else version (Windows) {
     void resolvePaths () {
@@ -181,17 +180,52 @@
         char[] staticPath = findPath (installPath ~ DATA);
         
         // Static data paths:
-        dataDir.addPath[dataLength++] = staticPath;   // we know this is valid anyway
-        dataDir.tryPath (userPath ~ DATA);
-        
+        dataDir.addPath (staticPath.toString);   // we know this is valid anyway
+        dataDir.tryPath (userPath.toString ~ DATA);
+        if (!dataDir.pathsLen) throw new mdeException ("Fatal: no data path found!");
+                
         // Configuration paths:
         confDir.tryPath (staticPath.toString ~ CONF);
-        confDir.tryPath (installPath ~ CONF);
-        confDir.tryPath (userPath.toString ~ CONF);
+        bool sysConf = confDir.tryPath (installPath ~ CONF);
+        confDir.tryPath (userPath.toString ~ CONF, !sysConf);   // create if no system conf dir
+        if (!confDir.pathsLen) throw new mdeException ("Fatal: no conf path found!");
+        
+        // Logging path:
+        logDir = userPath;
     }
 } else {
     static assert (false, "Platform is not linux or Windows: no support for paths on this platform yet!");
 }
+
+private:
+// The maximum number of paths for any one "directory".
+// There are NO CHECKS that this is not exceeded.
+const MAX_PATHS = 3;
+
+Logger logger;
+
+/* Try each path in succession, returning the first to exist and be a folder.
+* If none are valid and create is true, will try creating each in turn.
+* If still none are valid, throws. */
+PathView findPath (bool create, char[][] paths ...) {
+    foreach (path; paths) {
+        PathView pv = new FilePath (path);
+        if (pv.exists && pv.isFolder) return pv;    // got a valid path
+    }
+    if (create) {   // try to create a folder, using each path in turn until succesful
+        foreach (path; paths) {
+            PathView pv = new FilePath (path);
+            try {
+                return pv;
+            }
+            catch (Exception e) {}
+        }
+    }
+    // no valid path...
+    logger.fatal ("Unable to find"~(create ? " or create" : "")~" a required path! The following were tried:");
+    foreach (path; paths) logger.fatal ('\t' ~ path);
+    throw new mdeException ("Unable to resolve a required path (see log for details).");
+}
 //END Path resolution
 
 /** A special adapter for reading from multiple mergetag files with the same relative path to an