//////////////////////////////////////////////// //// Example inserter //// //// Version 1.0.1 31.07.04 //// //// www.danielgrunwald.de //// //////////////////////////////////////////////// using System; using System.IO; using System.Text; using System.Collections; using System.Text.RegularExpressions; using System.Xml; /* * If you implement any missing feature or find some bug, please write an e-mail to * daniel@danielgrunwald.de */ public class MainClass { static ArrayList examples = new ArrayList(); public static int ruleCount = 0; public static int matchCount = 0; public static void Main() { int totalStart = Environment.TickCount; int start; const string basePath = "./"; start = Environment.TickCount; //Console.WriteLine("Reading examples..."); GetExamples(new DirectoryInfo(basePath + "doc/examples")); Console.WriteLine("Got {0} examples in {1} ms.", examples.Count, Environment.TickCount - start); start = Environment.TickCount; //Console.WriteLine("Reading xml files..."); GetXMLs(new DirectoryInfo(basePath + "bin")); //Console.WriteLine("Got {0} xml documentation files in {1} ms.", xmlDocs.Count, Environment.TickCount - start); //start = Environment.TickCount; //Console.WriteLine("Applying {0} rules...", ruleCount); foreach (Example e in examples) { foreach (XmlDoc doc in xmlDocs) { e.ApplyTo(doc.Members); } } Console.WriteLine("Got {0} matches using {2} rules in {3} xml files in {1} ms.", matchCount, Environment.TickCount - start, ruleCount, xmlDocs.Count); start = Environment.TickCount; //Console.WriteLine("Saving xml files..."); foreach (XmlDoc doc in xmlDocs) { doc.Save(); } //Console.WriteLine("Files saved in {0} ms.", Environment.TickCount - start); //Console.WriteLine("Finished in total {0} ms.", Environment.TickCount - totalStart); } #region GetExamples static void GetExample(FileInfo file) { try { StreamReader r = file.OpenText(); try { examples.Add(new Example(r)); } finally { r.Close(); } } catch (Exception ex) { Console.WriteLine("Error reading example {0}:", file.Name); Console.WriteLine(ex.Message); } } static void GetExamples(DirectoryInfo dir) { foreach (FileInfo file in dir.GetFiles("*.cs")) { GetExample(file); } foreach (DirectoryInfo subdir in dir.GetDirectories()) { if (subdir.Name.StartsWith(".")) continue; if (subdir.Name == "bin" || subdir.Name == "obj") continue; GetExamples(subdir); } } #endregion #region GetXMLs static ArrayList xmlDocs = new ArrayList(); static void GetXML(FileInfo file) { XmlDocument xml = new XmlDocument(); xml.Load(file.FullName); XmlElement root = xml.DocumentElement; if (root.Name != "doc") return; XmlElement members = root["members"]; if (members == null) return; xmlDocs.Add(new XmlDoc(file, xml, members)); } static void GetXMLs(DirectoryInfo dir) { foreach (FileInfo file in dir.GetFiles("*.xml")) { try { GetXML(file); } catch (Exception ex) { Console.WriteLine(ex.ToString()); Console.Write("Press enter to continue..."); Console.ReadLine(); } } foreach (DirectoryInfo subdir in dir.GetDirectories()) { if (subdir.Name.StartsWith(".")) continue; GetXMLs(subdir); } } #endregion } #region Example class Example { ArrayList applyTo = new ArrayList(); string content; int targetCount = 0; public void ApplyTo(XmlElement members) { foreach (object o in applyTo) { if (o is Regex) { Apply(o as Regex, members); } else if (o is String) { Apply(o as String, members); } else { throw new Exception("Unknown object in applyTo-array: " + o.ToString()); } } } void Apply(Regex r, XmlElement members) { foreach (XmlElement e in members) { string name = e.GetAttribute("name"); if (r.IsMatch(name)) { Apply(e); } } } void Apply(String s, XmlElement members) { foreach (XmlElement e in members) { string name = e.GetAttribute("name"); if (name.Substring(2).ToLower() == s) { Apply(e); } } } void Apply(XmlElement member) { targetCount++; MainClass.matchCount++; XmlElement example = member["example"]; if (example == null) { example = member.OwnerDocument.CreateElement("example"); member.AppendChild(example); } else { example.AppendChild(member.OwnerDocument.CreateElement("br")); } example.InnerXml += this.content; } public Example(StreamReader r) { StringBuilder b = new StringBuilder(); string line; int linenr = 0; bool doc = true; while ((line = r.ReadLine()) != null) { linenr++; try { string trimmed = line.Trim(); if (trimmed.StartsWith("//**")) { trimmed = trimmed.Substring(4).TrimStart(); if (trimmed.StartsWith("~ ")) applyTo.Add(new Regex("^.." + trimmed.Substring(2).Trim() + "$", RegexOptions.IgnoreCase)); else applyTo.Add(trimmed.ToLower()); MainClass.ruleCount++; } else if (trimmed == "////") { // ignore } else if (trimmed.StartsWith("////")) { if (!doc) b.Append("\r\n"); doc = true; b.Append(trimmed.Substring(4).TrimStart()); b.Append("\r\n"); doc = true; } else { if (doc) b.Append("\r\n"); b.Append(ToXML(line)); b.Append("\r\n"); doc = false; } } catch (Exception ex) { throw new Exception("Error in line " + linenr.ToString() + ":\r\n" + ex.Message); } } if (!doc) b.Append("\r\n"); if (applyTo.Count == 0) throw new Exception("No apply-To line (//**) found."); content = b.ToString(); } static string ToXML(string text) { return text.Replace("&", "&").Replace("\"", """).Replace("<", "<").Replace(">", ">"); } } #endregion #region XmlDoc class XmlDoc { FileInfo file; XmlDocument doc; public readonly XmlElement Members; public XmlDoc(FileInfo file, XmlDocument doc, XmlElement members) { this.file = file; this.doc = doc; this.Members = members; } public void Save() { doc.Save(file.FullName); } } #endregion