CSharp Environment Variables Class

From CrossWire Bible Society
Revision as of 17:28, 23 February 2015 by David Haslam (Talk | contribs) (Category:CSharp)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

C# code should be portable between Windows and Linux using Mono. The sword project is at heart a Linux program, so figuring out where configuration files, book modules and environment variables live can sometimes cause subtle errors. This class is intended to abstract that process so that the rest of the C# project can proceed without worrying about it.

// Copyright 2014  CrossWire Bible Society (http://www.crosswire.org)
//    CrossWire Bible Society
//    P. O. Box 2528
//    Tempe, AZ  85280-2528
//  
//  This program is free software; you can redistribute it and/or modify it
//  under the terms of the GNU General Public License as published by the
//  Free Software Foundation version 2.
//  
//  This program is distributed in the hope that it will be useful, but
//  WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  General Public License for more details.

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Text.RegularExpressions;

namespace Sword {
   public static class Enviro {
     static private List<string> configSections = new List<string>();
     static private NameValueCollection configValues = new NameValueCollection();
     static private bool configNotRead = true;

     public static string dataPath {
       get {
         if (configNotRead) {
            readConfigFile();
         }
         return configValues["DataPath"];
       }
     }

     public static string installMgrPath {
       get {
         if (configNotRead) {
            readConfigFile();
         }
         if (string.IsNullOrEmpty (configValues ["InstallMgrPath"]))
            return dataPath;
         return configValues["InstallMgrPath"];
       }
     }

     public static string swordHome {
       get {
       if (String.IsNullOrEmpty (configValues ["swordHome"])) {
         string home = Environment.GetEnvironmentVariable ("HOME");
         if (String.IsNullOrEmpty (home))
            home = Environment.GetEnvironmentVariable ("APPDATA");
         /*
          * Figure out where sword.conf lives
          */
         string thePath = home.Replace ('\\', '/');
         if (File.Exists (Path.Combine (thePath, "sword.conf"))) {
            configValues ["swordHome"] = Path.Combine (thePath, "sword.conf");
            } else if (File.Exists (Path.Combine (thePath, ".sword", "sword.conf"))) {
              configValues ["swordHome"] = Path.Combine (thePath, ".sword", "sword.conf");
            } else if (File.Exists (Path.Combine (thePath, "sword", "sword.conf"))) {
              configValues ["swordHome"] = Path.Combine (thePath, "sword", "sword.conf");
         } else if (File.Exists ("/etc/sword.conf")) {
            configValues ["swordHome"] = "/etc/sword.conf";
         } else {
         /*
          * TODO: Don't know enough about Linux Sword to know where all else the 
          * file could be located. This might need to be expanded.
          */
            throw new Exception("Cannot find the file sword.conf. " +
                           "Should be in one of the following places: " +
                           "~/Home/sword/.sword.conf " +
                           "/AppData/roaming/sword/sword.conf " +
                           "/etc/sword.conf");
            }
         }
         return configValues["swordHome"]; ;
       }
     }

     private static void readConfigFile() {
       string line;
       StreamReader config = new StreamReader(swordHome);
       while ((line = config.ReadLine()) != null) {
         /*
          * Section headings are enclosed in []
          * 
          * TODO: Not sure if we need these for anything. At the moment just store them.
          * If in the future there are multiple config sections, may want to key the 
          * values with the appropriate section.
          */
         if(Regex.IsMatch(line, @"\[*\]")) {
            configSections.Add(Regex.Replace(line, @"[\[\]]", ""));
         } else {
            /*
            * Regular lines are of the form key=value
            */
            string[] raw = line.Split('=');
            /*
            * Value may need some special treatment
            */
            switch (raw[0]) {
              /*
               * Sword expects a data path using / as separaters rather than Windows \
               * Also expects no trailing /
               */
              case "DataPath": 
              case "InstallMgrPath":
                raw[1] = Regex.Replace(raw[1], @"\\", "/").TrimEnd('/');
                break;
              default:
                break;
            }
            configValues.Add(raw[0].Trim(),raw[1].Trim());
         }
       }
       configNotRead = false;
     }
   }
}