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 default(T) if parsing failed.
public static T Constant(string atom)
{
try
{
return (T)System.Enum.Parse(typeof(T), String(atom));
}
#pragma warning disable 0168
catch (System.Exception ex)
#pragma warning restore 0168
{
return default(T);
}
}
///
/// 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 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();
}
}
}