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