Move configuration to Config module
[WebThing.git] / Config.cs
diff --git a/Config.cs b/Config.cs
new file mode 100644 (file)
index 0000000..9ad8095
--- /dev/null
+++ b/Config.cs
@@ -0,0 +1,134 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+
+namespace bytex64.WebThing {
+    public class Config {
+        public static string ConfigurationPrefix = "/etc";
+
+        public static Dictionary<string,string> Options;
+        public static Dictionary<string,Dictionary<string,string>> PluginOptions;
+        public static string[] Arguments;
+        private static HashSet<string> CommandLineOptions;
+
+        public static Regex item_re = new Regex(@"^(?:([\w.]+)\.)?(\w+)$");
+        public static Regex file_var_re = new Regex(@"^([\w.]+)\s*=\s*(.*)$");
+
+        static Config() {
+            Options = new Dictionary<string,string>();
+            PluginOptions = new Dictionary<string,Dictionary<string,string>>();
+            CommandLineOptions = new HashSet<string>();
+        }
+
+        private static void ParseOption(string key, string val) {
+            Match m = item_re.Match(key);
+            string plugin = m.Groups[1].Value;
+            string name = m.Groups[2].Value;
+            if (plugin.Length > 0) {   // Plugin Option
+                if (!PluginOptions.ContainsKey(plugin))
+                    PluginOptions[plugin] = new Dictionary<string,string>();
+                PluginOptions[plugin][name] = val;
+            } else {                   // Global Option
+                Options[name] = val;
+            }
+        }
+
+        public static void DumpOptions() {
+            Console.WriteLine("Options:");
+            foreach (string key in Options.Keys)
+                Console.WriteLine("   {0}\t{1}", key, Options[key]);
+
+            Console.WriteLine("Plugin Options:");
+            foreach (string plugin in PluginOptions.Keys) {
+                Console.WriteLine("    {0}", plugin);
+                foreach (string key in PluginOptions[plugin].Keys)
+                    Console.WriteLine("        {0}\t{1}", key, PluginOptions[plugin][key]);
+            }
+
+            Console.WriteLine("Arguments: {0}", String.Join(" ", Arguments));
+        }
+
+        public static void ParseCommandLine() {
+            Queue<string> q = new Queue<string>();
+            foreach (string s in System.Environment.GetCommandLineArgs()) {
+                q.Enqueue(s);
+            }
+            q.Dequeue();   // Remove self argument
+
+            Regex SimpleOpt = new Regex(@"^-([\w.]+)(?:[:=](.*))?$");
+            Regex LongOpt   = new Regex(@"^--([\w.]+)$");
+            List<string> args = new List<string>();
+
+            while (q.Count > 0) {
+                string opt = q.Dequeue();
+                Match m;
+                   
+                m = SimpleOpt.Match(opt);
+                if (m.Success) {
+                    string key = m.Groups[1].Value;
+                    string val = m.Groups[2].Value;
+                    if (val.Length > 0) {
+                        ParseOption(key, val);
+                    } else {
+                        ParseOption(key, null);
+                    }
+                    CommandLineOptions.Add(key);
+                    continue;
+                }
+
+                m = LongOpt.Match(opt);
+                if (m.Success) {
+                    string key = m.Groups[1].Value;
+                    if (q.Count > 0) {
+                        string val = q.Peek();
+                        if (!(SimpleOpt.IsMatch(val) || LongOpt.IsMatch(val))) {
+                            q.Dequeue();
+                            ParseOption(key, val);
+                        } else {
+                            ParseOption(key, null);
+                        }
+                    } else {
+                        ParseOption(key, null);
+                    }
+                    CommandLineOptions.Add(key);
+                    continue;
+                }
+
+                // else
+
+                args.Add(opt);
+            }
+            Arguments = args.ToArray();
+        }
+
+        public static void Load() {
+            LoadFile(ConfigurationPrefix + "/WebThing.conf");
+            LoadFile(Environment.GetEnvironmentVariable("HOME") + "/.config/WebThing/WebThing.conf");
+            if (Options.ContainsKey("config"))
+                LoadFile(Options["config"]);
+        }
+
+        public static void LoadFile(string filename) {
+            TextReader f;
+            try {
+                f = new StreamReader(File.OpenRead(filename));
+            } catch (FileNotFoundException) {
+                Console.WriteLine("Could not open configuration file {0}", filename);
+                return;
+            }
+
+            string line;
+            while ((line = f.ReadLine()) != null) {
+                Match m = file_var_re.Match(line.Trim());
+                if (m.Success) {
+                    string key = m.Groups[1].Value;
+                    if (!CommandLineOptions.Contains(key))
+                        ParseOption(key, m.Groups[2].Value);
+                }
+            }
+
+            f.Close();
+        }
+    }
+}