--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using System.Text.RegularExpressions;\r
+using Microsoft.Xna.Framework;\r
+\r
+namespace CarFire\r
+{\r
+ /// <summary>\r
+ /// Class with handy static methods taking strings and returning objects\r
+ /// parsed from those strings.\r
+ /// </summary>\r
+ public class Parse\r
+ {\r
+ /// <summary>\r
+ /// Parses a section header of an INI file.\r
+ /// </summary>\r
+ /// <param name="line">Text.</param>\r
+ /// <returns>The section header, or null if parsing failed.</returns>\r
+ public static string IniSectionHeader(string line)\r
+ {\r
+ Match match = Regex.Match(line, @"^\s*\[(\w+)\]\s*$");\r
+ if (match.Success) return match.Groups[1].Value;\r
+ return null;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Parses a key-value pair.\r
+ /// </summary>\r
+ /// <param name="line">Text.</param>\r
+ /// <returns>An array of two strings containg the key and value,\r
+ /// in that order, or null if parsing failed.</returns>\r
+ public static string[] KeyValuePair(string line)\r
+ {\r
+ Match match = Regex.Match(line, @"^\s*(\w+)\s*=\s*(.+)\s*$");\r
+ if (match.Success)\r
+ {\r
+ string[] pair = { match.Groups[1].Value, match.Groups[2].Value };\r
+ return pair;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Parses a pair of coordinates.\r
+ /// </summary>\r
+ /// <param name="atom">Text.</param>\r
+ /// <returns>The coordinates, or null if parsing failed.</returns>\r
+ public static Point? Coordinates(string atom)\r
+ {\r
+ Match match = Regex.Match(atom, @"^\s*\[(\S+?)\s*,\s*(\S+?)\]\s*$");\r
+ if (match.Success)\r
+ {\r
+ int? x = Integer(match.Groups[1].Value);\r
+ int? y = Integer(match.Groups[2].Value);\r
+ if (x != null && y != null)\r
+ {\r
+ return new Point(x.Value, y.Value);\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Parses a range of integers.\r
+ /// </summary>\r
+ /// <param name="atom">Text.</param>\r
+ /// <returns>An array of two integers containing the min and max,\r
+ /// in that order, or null if parsing failed.</returns>\r
+ public static int[] Range(string atom)\r
+ {\r
+ Match match = Regex.Match(atom, @"^\s*<(\S+?)\s*,\s*(\S+?)>\s*$");\r
+ if (match.Success)\r
+ {\r
+ int? min = Integer(match.Groups[1].Value);\r
+ int? max = Integer(match.Groups[2].Value);\r
+ if (min != null && max != null)\r
+ {\r
+ int[] range = { min.Value, max.Value };\r
+ return range;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Parses a string.\r
+ /// </summary>\r
+ /// <param name="atom">Text.</param>\r
+ /// <returns>The string, or null if parsing failed.</returns>\r
+ public static string String(string atom)\r
+ {\r
+ Match match = Regex.Match(atom, @"^\s*(""?)(.*)\1\s*$");\r
+ if (match.Success) return match.Groups[2].Value;\r
+ return null;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Parses a constant from an enum.\r
+ /// </summary>\r
+ /// <typeparam name="T">An enumeration.</typeparam>\r
+ /// <param name="atom">Text.</param>\r
+ /// <returns>The constant, or null if parsing failed.</returns>\r
+ public static T Constant<T>(string atom)\r
+ {\r
+ string constant = String(atom);\r
+ if (constant != null)\r
+ {\r
+ foreach (string enumConstant in System.Enum.GetNames(typeof(T)))\r
+ {\r
+ if (constant == enumConstant)\r
+ {\r
+ return (T)System.Enum.Parse(typeof(T), constant);\r
+ }\r
+ }\r
+ }\r
+ return default(T);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Parses an integer.\r
+ /// </summary>\r
+ /// <param name="atom">Text.</param>\r
+ /// <returns>The integer, or null if parsing failed.</returns>\r
+ public static int? Integer(string atom)\r
+ {\r
+ try\r
+ {\r
+ int integer = Convert.ToInt32(atom.Trim());\r
+ return integer;\r
+ }\r
+#pragma warning disable 0168\r
+ catch (System.Exception ex)\r
+#pragma warning restore 0168\r
+ {\r
+ return null;\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Parses a boolean value.\r
+ /// </summary>\r
+ /// <param name="atom">Text.</param>\r
+ /// <returns>True or false, or null if parsing failed.</returns>\r
+ public static bool? Boolean(string atom)\r
+ {\r
+ Match match = Regex.Match(atom, @"^\s*(true|false)\s*$", RegexOptions.IgnoreCase);\r
+ if (match.Success)\r
+ {\r
+ if (match.Groups[1].Value[0] == 't' || match.Groups[1].Value[0] == 'T') return true;\r
+ else return false;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Parses a function.\r
+ /// </summary>\r
+ /// <param name="atom">Text.</param>\r
+ /// <returns>An array two strings containing the function name and\r
+ /// parameter-list, in that order, or null if parsing failed.</returns>\r
+ public static string[] Function(string atom)\r
+ {\r
+ Match match = Regex.Match(atom, @"^\s*(\w+)\((.*)\)\s*$");\r
+ if (match.Success)\r
+ {\r
+ string[] pair = { match.Groups[1].Value, match.Groups[2].Value };\r
+ return pair;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Parses a comma-separated list of atoms.\r
+ /// </summary>\r
+ /// <param name="text">Text.</param>\r
+ /// <returns>An array of strings containing the atoms, or null\r
+ /// if parsing failed.</returns>\r
+ public static string[] ParameterList(string text)\r
+ {\r
+ return null;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Parses a whitespace-separated list of atoms.\r
+ /// </summary>\r
+ /// <param name="text">Text.</param>\r
+ /// <returns>An array of atoms, or null if parsing failed.</returns>\r
+ public static string[] List(string text)\r
+ {\r
+ List<string> list = new List<string>();\r
+\r
+ MatchCollection matches = Regex.Matches(text, @"\s*("".*?"")|(\w+\(.*?\))|(\[.*?\])|(<.*?>)|(\S+)(?:\s+|$)");\r
+ // FIXME: This may barf all over itself if there are nested parentheses, doublequotes, brackets, etc.\r
+ foreach (Match match in matches)\r
+ {\r
+ Console.WriteLine("matched: " + match.Value);\r
+ list.Add(match.Value);\r
+ }\r
+\r
+ return list.ToArray();\r
+ }\r
+ }\r
+}\r