+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();
+ }
+ }
+}