From 2a3c79df83e800d5dfe75a1a3b140ed81da2b1d6 Mon Sep 17 00:00:00 2001 From: Sean Dague Date: Mon, 16 Jul 2007 15:40:11 +0000 Subject: changed to native line ending encoding --- Prebuild/src/Core/Kernel.cs | 1514 +++++++++++++++++++++---------------------- 1 file changed, 757 insertions(+), 757 deletions(-) (limited to 'Prebuild/src/Core/Kernel.cs') diff --git a/Prebuild/src/Core/Kernel.cs b/Prebuild/src/Core/Kernel.cs index 3117e7c..170d0f5 100644 --- a/Prebuild/src/Core/Kernel.cs +++ b/Prebuild/src/Core/Kernel.cs @@ -1,758 +1,758 @@ -#region BSD License -/* -Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehead (dan05a@gmail.com) - -Redistribution and use in source and binary forms, with or without modification, are permitted -provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#endregion - -#region CVS Information -/* - * $Source$ - * $Author: robloach $ - * $Date: 2006-09-26 00:30:53 +0200 (ti, 26 sep 2006) $ - * $Revision: 165 $ - */ -#endregion - -using System; -using System.Diagnostics; -using System.Collections; -using System.Collections.Specialized; -using System.IO; -using System.Reflection; -using System.Xml; -using System.Xml.Schema; -using System.Text; - -using Prebuild.Core.Attributes; -using Prebuild.Core.Interfaces; -using Prebuild.Core.Nodes; -using Prebuild.Core.Parse; -using Prebuild.Core.Utilities; - -namespace Prebuild.Core -{ - /// - /// - /// - public class Kernel : IDisposable - { - #region Inner Classes - - private struct NodeEntry - { - public Type Type; - public DataNodeAttribute Attribute; - } - - #endregion - - #region Fields - - private static Kernel m_Instance = new Kernel(); - - /// - /// This must match the version of the schema that is embeeded - /// - private static string m_SchemaVersion = "1.7"; - private static string m_Schema = "prebuild-" + m_SchemaVersion + ".xsd"; - private static string m_SchemaURI = "http://dnpb.sourceforge.net/schemas/" + m_Schema; - bool disposed; - private Version m_Version; - private string m_Revision = ""; - private CommandLineCollection m_CommandLine; - private Log m_Log; - private CurrentDirectory m_CurrentWorkingDirectory; - private XmlSchemaCollection m_Schemas; - - private Hashtable m_Targets; - private Hashtable m_Nodes; - - ArrayList m_Solutions; - string m_Target; - string m_Clean; - string[] m_RemoveDirectories; - string m_CurrentFile; - bool m_PauseAfterFinish; - string[] m_ProjectGroups; - StringCollection m_Refs; - - - #endregion - - #region Constructors - - private Kernel() - { - } - - #endregion - - #region Properties - - /// - /// Gets a value indicating whether [pause after finish]. - /// - /// true if [pause after finish]; otherwise, false. - public bool PauseAfterFinish - { - get - { - return m_PauseAfterFinish; - } - } - - /// - /// Gets the instance. - /// - /// The instance. - public static Kernel Instance - { - get - { - return m_Instance; - } - } - - /// - /// Gets the version. - /// - /// The version. - public string Version - { - get - { - return String.Format("{0}.{1}.{2}{3}", m_Version.Major, m_Version.Minor, m_Version.Build, m_Revision); - } - } - - /// - /// Gets the command line. - /// - /// The command line. - public CommandLineCollection CommandLine - { - get - { - return m_CommandLine; - } - } - - /// - /// Gets the targets. - /// - /// The targets. - public Hashtable Targets - { - get - { - return m_Targets; - } - } - - /// - /// Gets the log. - /// - /// The log. - public Log Log - { - get - { - return m_Log; - } - } - - /// - /// Gets the current working directory. - /// - /// The current working directory. - public CurrentDirectory CurrentWorkingDirectory - { - get - { - return m_CurrentWorkingDirectory; - } - } - - /// - /// Gets the solutions. - /// - /// The solutions. - public ArrayList Solutions - { - get - { - return m_Solutions; - } - } - - #endregion - - #region Private Methods - - private void RemoveDirectories(string rootDir, string[] dirNames) - { - foreach(string dir in Directory.GetDirectories(rootDir)) - { - string simpleName = Path.GetFileName(dir); - - if(Array.IndexOf(dirNames, simpleName) != -1) - { - //delete if the name matches one of the directory names to delete - string fullDirPath = Path.GetFullPath(dir); - Directory.Delete(fullDirPath,true); - } - else//not a match, so check children - { - RemoveDirectories(dir,dirNames); - //recurse, checking children for them - } - } - } - -// private void RemoveDirectoryMatches(string rootDir, string dirPattern) -// { -// foreach(string dir in Directory.GetDirectories(rootDir)) -// { -// foreach(string match in Directory.GetDirectories(dir)) -// {//delete all child directories that match -// Directory.Delete(Path.GetFullPath(match),true); -// } -// //recure through the rest checking for nested matches to delete -// RemoveDirectoryMatches(dir,dirPattern); -// } -// } - - private void LoadSchema() - { - Assembly assembly = this.GetType().Assembly; - Stream stream = assembly.GetManifestResourceStream("Prebuild.data." + m_Schema); - if(stream == null) - { - //try without the default namespace prepending to it in case was compiled with SharpDevelop or MonoDevelop instead of Visual Studio .NET - stream = assembly.GetManifestResourceStream(m_Schema); - if(stream == null) - { - throw new System.Reflection.TargetException(string.Format("Could not find the scheme embedded resource file '{0}'.", m_Schema)); - } - } - XmlReader schema = new XmlTextReader(stream); - - m_Schemas = new XmlSchemaCollection(); - m_Schemas.Add(m_SchemaURI, schema); - } - - private void CacheVersion() - { - m_Version = Assembly.GetEntryAssembly().GetName().Version; - } - - private void CacheTargets(Assembly assm) - { - foreach(Type t in assm.GetTypes()) - { - TargetAttribute ta = (TargetAttribute)Helper.CheckType(t, typeof(TargetAttribute), typeof(ITarget)); - if(ta == null) - { - continue; - } - - ITarget target = (ITarget)assm.CreateInstance(t.FullName); - if(target == null) - { - throw new MissingMethodException("Could not create ITarget instance"); - } - - m_Targets[ta.Name] = target; - } - } - - private void CacheNodeTypes(Assembly assm) - { - foreach(Type t in assm.GetTypes()) - { - DataNodeAttribute dna = (DataNodeAttribute)Helper.CheckType(t, typeof(DataNodeAttribute), typeof(IDataNode)); - if(dna == null) - { - continue; - } - - NodeEntry ne = new NodeEntry(); - ne.Type = t; - ne.Attribute = dna; - m_Nodes[dna.Name] = ne; - } - } - - private void LogBanner() - { - m_Log.Write("Prebuild v" + this.Version); - m_Log.Write("Copyright (c) Matthew Holmes, Dan Moorehead and David Hudson"); - m_Log.Write("See 'prebuild /usage' for help"); - m_Log.Write(); - } - - private void ProcessFile(string file) - { - m_CurrentWorkingDirectory.Push(); - - string path = file; - try - { - try - { - path = Helper.ResolvePath(path); - } - catch(ArgumentException) - { - m_Log.Write("Could not open Prebuild file: " + path); - m_CurrentWorkingDirectory.Pop(); - return; - } - - m_CurrentFile = path; - Helper.SetCurrentDir(Path.GetDirectoryName(path)); - - - XmlTextReader reader = new XmlTextReader(path); - - Core.Parse.Preprocessor pre = new Core.Parse.Preprocessor(); - - //register command line arguments as XML variables - IDictionaryEnumerator dict = m_CommandLine.GetEnumerator(); - while (dict.MoveNext()) - { - string name = dict.Key.ToString().Trim(); - if (name.Length > 0) - pre.RegisterVariable(name, dict.Value.ToString()); - } - - string xml = pre.Process(reader);//remove script and evaulate pre-proccessing to get schema-conforming XML - - - XmlDocument doc = new XmlDocument(); - try - { - XmlValidatingReader validator = new XmlValidatingReader(new XmlTextReader(new StringReader(xml))); - - //validate while reading from string into XmlDocument DOM structure in memory - foreach(XmlSchema schema in m_Schemas) - { - validator.Schemas.Add(schema); - } - doc.Load(validator); - } - catch(XmlException e) - { - throw new XmlException(e.ToString()); - } - - //is there a purpose to writing it? An syntax/schema problem would have been found during pre.Process() and reported with details - if(m_CommandLine.WasPassed("ppo")) - { - string ppoFile = m_CommandLine["ppo"]; - if(ppoFile == null || ppoFile.Trim().Length < 1) - { - ppoFile = "preprocessed.xml"; - } - - StreamWriter writer = null; - try - { - writer = new StreamWriter(ppoFile); - writer.Write(xml); - } - catch(IOException ex) - { - Console.WriteLine("Could not write PPO file '{0}': {1}", ppoFile, ex.Message); - } - finally - { - if(writer != null) - { - writer.Close(); - } - } - return; - } - //start reading the xml config file - XmlElement rootNode = doc.DocumentElement; - //string suggestedVersion = Helper.AttributeValue(rootNode,"version","1.0"); - Helper.CheckForOSVariables = Helper.ParseBoolean(rootNode,"checkOsVars",false); - - foreach(XmlNode node in rootNode.ChildNodes)//solutions or if pre-proc instructions - { - IDataNode dataNode = ParseNode(node, null); - if(dataNode is ProcessNode) - { - ProcessNode proc = (ProcessNode)dataNode; - if(proc.IsValid) - { - ProcessFile(proc.Path); - } - } - else if(dataNode is SolutionNode) - { - m_Solutions.Add(dataNode); - } - } - } - catch(XmlSchemaException xse) - { - m_Log.Write("XML validation error at line {0} in {1}:\n\n{2}", - xse.LineNumber, path, xse.Message); - } - finally - { - m_CurrentWorkingDirectory.Pop(); - } - } - - #endregion - - #region Public Methods - - /// - /// Allows the project. - /// - /// The project groups flags. - /// - public bool AllowProject(string projectGroupsFlags) - { - if(m_ProjectGroups != null && m_ProjectGroups.Length > 0) - { - if(projectGroupsFlags != null && projectGroupsFlags.Length == 0) - { - foreach(string group in projectGroupsFlags.Split('|')) - { - if(Array.IndexOf(m_ProjectGroups, group) != -1) //if included in the filter list - { - return true; - } - } - } - return false;//not included in the list or no groups specified for the project - } - return true;//no filter specified in the command line args - } - - /// - /// Gets the type of the node. - /// - /// The node. - /// - public Type GetNodeType(XmlNode node) - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } - if(!m_Nodes.ContainsKey(node.Name)) - { - return null; - } - - NodeEntry ne = (NodeEntry)m_Nodes[node.Name]; - return ne.Type; - } - - /// - /// - /// - /// - /// - /// - public IDataNode ParseNode(XmlNode node, IDataNode parent) - { - return ParseNode(node, parent, null); - } - - //Create an instance of the data node type that is mapped to the name of the xml DOM node - /// - /// Parses the node. - /// - /// The node. - /// The parent. - /// The pre node. - /// - public IDataNode ParseNode(XmlNode node, IDataNode parent, IDataNode preNode) - { - IDataNode dataNode = null; - - try - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } - if(preNode == null) - { - if(!m_Nodes.ContainsKey(node.Name)) - { - //throw new XmlException("Unknown XML node: " + node.Name); - return null; - } - - NodeEntry ne = (NodeEntry)m_Nodes[node.Name]; - Type type = ne.Type; - //DataNodeAttribute dna = ne.Attribute; - - dataNode = (IDataNode)type.Assembly.CreateInstance(type.FullName); - if(dataNode == null) - { - throw new System.Reflection.TargetException("Could not create new parser instance: " + type.FullName); - } - } - else - dataNode = preNode; - - dataNode.Parent = parent; - dataNode.Parse(node); - } - catch(WarningException wex) - { - m_Log.Write(LogType.Warning, wex.Message); - return null; - } - catch(FatalException fex) - { - m_Log.WriteException(LogType.Error, fex); - throw; - } - catch(Exception ex) - { - m_Log.WriteException(LogType.Error, ex); - throw; - } - - return dataNode; - } - - /// - /// Initializes the specified target. - /// - /// The target. - /// The args. - public void Initialize(LogTargets target, string[] args) - { - m_Targets = new Hashtable(); - CacheTargets(this.GetType().Assembly); - m_Nodes = new Hashtable(); - CacheNodeTypes(this.GetType().Assembly); - CacheVersion(); - - m_CommandLine = new CommandLineCollection(args); - - string logFile = null; - if(m_CommandLine.WasPassed("log")) - { - logFile = m_CommandLine["log"]; - - if(logFile != null && logFile.Length == 0) - { - logFile = "Prebuild.log"; - } - } - else - { - target = target & ~LogTargets.File; //dont output to a file - } - - m_Log = new Log(target, logFile); - LogBanner(); - - m_CurrentWorkingDirectory = new CurrentDirectory(); - - m_Target = m_CommandLine["target"]; - m_Clean = m_CommandLine["clean"]; - string removeDirs = m_CommandLine["removedir"]; - if(removeDirs != null && removeDirs.Length == 0) - { - m_RemoveDirectories = removeDirs.Split('|'); - } - - string flags = m_CommandLine["allowedgroups"];//allows filtering by specifying a pipe-delimited list of groups to include - if(flags != null && flags.Length == 0) - { - m_ProjectGroups = flags.Split('|'); - } - m_PauseAfterFinish = m_CommandLine.WasPassed("pause"); - - LoadSchema(); - - m_Solutions = new ArrayList(); - m_Refs = new StringCollection(); - } - - /// - /// Processes this instance. - /// - public void Process() - { - bool perfomedOtherTask = false; - if(m_RemoveDirectories != null && m_RemoveDirectories.Length > 0) - { - try - { - RemoveDirectories(".",m_RemoveDirectories); - } - catch(IOException e) - { - m_Log.Write("Failed to remove directories named {0}",m_RemoveDirectories); - m_Log.WriteException(LogType.Error,e); - } - catch(UnauthorizedAccessException e) - { - m_Log.Write("Failed to remove directories named {0}",m_RemoveDirectories); - m_Log.WriteException(LogType.Error,e); - } - perfomedOtherTask = true; - } - - if(m_Target != null && m_Clean != null) - { - m_Log.Write(LogType.Error, "The options /target and /clean cannot be passed together"); - return; - } - else if(m_Target == null && m_Clean == null) - { - if(perfomedOtherTask) //finished - { - return; - } - m_Log.Write(LogType.Error, "Must pass either /target or /clean to process a Prebuild file"); - return; - } - - string file = "./prebuild.xml"; - if(m_CommandLine.WasPassed("file")) - { - file = m_CommandLine["file"]; - } - - ProcessFile(file); - - string target = (m_Target != null ? m_Target.ToLower() : m_Clean.ToLower()); - bool clean = (m_Target == null); - if(clean && target != null && target.Length == 0) - { - target = "all"; - } - if(clean && target == "all")//default to all if no target was specified for clean - { - //check if they passed yes - if (!m_CommandLine.WasPassed("yes")) - { - Console.WriteLine("WARNING: This operation will clean ALL project files for all targets, are you sure? (y/n):"); - string ret = Console.ReadLine(); - if(ret == null) - { - return; - } - ret = ret.Trim().ToLower(); - if((ret.ToLower() != "y" && ret.ToLower() != "yes")) - { - return; - } - } - //clean all targets (just cleaning vs2002 target didn't clean nant) - foreach(ITarget targ in m_Targets.Values) - { - targ.Clean(this); - } - } - else - { - ITarget targ = (ITarget)m_Targets[target]; - - if(clean) - { - targ.Clean(this); - } - else - { - targ.Write(this); - } - } - - m_Log.Flush(); - } - - #endregion - - #region IDisposable Members - - /// - /// - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Dispose objects - /// - /// - /// If true, it will dispose close the handle - /// - /// - /// Will dispose managed and unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - if (!this.disposed) - { - if (disposing) - { - if (this.m_Log != null) - { - this.m_Log.Close(); - this.m_Log = null; - } - } - } - this.disposed = true; - } - - /// - /// - /// - ~Kernel() - { - this.Dispose(false); - } - - /// - /// Closes and destroys this object - /// - /// - /// Same as Dispose(true) - /// - public void Close() - { - Dispose(); - } - - #endregion - } +#region BSD License +/* +Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehead (dan05a@gmail.com) + +Redistribution and use in source and binary forms, with or without modification, are permitted +provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#endregion + +#region CVS Information +/* + * $Source$ + * $Author: robloach $ + * $Date: 2006-09-26 00:30:53 +0200 (ti, 26 sep 2006) $ + * $Revision: 165 $ + */ +#endregion + +using System; +using System.Diagnostics; +using System.Collections; +using System.Collections.Specialized; +using System.IO; +using System.Reflection; +using System.Xml; +using System.Xml.Schema; +using System.Text; + +using Prebuild.Core.Attributes; +using Prebuild.Core.Interfaces; +using Prebuild.Core.Nodes; +using Prebuild.Core.Parse; +using Prebuild.Core.Utilities; + +namespace Prebuild.Core +{ + /// + /// + /// + public class Kernel : IDisposable + { + #region Inner Classes + + private struct NodeEntry + { + public Type Type; + public DataNodeAttribute Attribute; + } + + #endregion + + #region Fields + + private static Kernel m_Instance = new Kernel(); + + /// + /// This must match the version of the schema that is embeeded + /// + private static string m_SchemaVersion = "1.7"; + private static string m_Schema = "prebuild-" + m_SchemaVersion + ".xsd"; + private static string m_SchemaURI = "http://dnpb.sourceforge.net/schemas/" + m_Schema; + bool disposed; + private Version m_Version; + private string m_Revision = ""; + private CommandLineCollection m_CommandLine; + private Log m_Log; + private CurrentDirectory m_CurrentWorkingDirectory; + private XmlSchemaCollection m_Schemas; + + private Hashtable m_Targets; + private Hashtable m_Nodes; + + ArrayList m_Solutions; + string m_Target; + string m_Clean; + string[] m_RemoveDirectories; + string m_CurrentFile; + bool m_PauseAfterFinish; + string[] m_ProjectGroups; + StringCollection m_Refs; + + + #endregion + + #region Constructors + + private Kernel() + { + } + + #endregion + + #region Properties + + /// + /// Gets a value indicating whether [pause after finish]. + /// + /// true if [pause after finish]; otherwise, false. + public bool PauseAfterFinish + { + get + { + return m_PauseAfterFinish; + } + } + + /// + /// Gets the instance. + /// + /// The instance. + public static Kernel Instance + { + get + { + return m_Instance; + } + } + + /// + /// Gets the version. + /// + /// The version. + public string Version + { + get + { + return String.Format("{0}.{1}.{2}{3}", m_Version.Major, m_Version.Minor, m_Version.Build, m_Revision); + } + } + + /// + /// Gets the command line. + /// + /// The command line. + public CommandLineCollection CommandLine + { + get + { + return m_CommandLine; + } + } + + /// + /// Gets the targets. + /// + /// The targets. + public Hashtable Targets + { + get + { + return m_Targets; + } + } + + /// + /// Gets the log. + /// + /// The log. + public Log Log + { + get + { + return m_Log; + } + } + + /// + /// Gets the current working directory. + /// + /// The current working directory. + public CurrentDirectory CurrentWorkingDirectory + { + get + { + return m_CurrentWorkingDirectory; + } + } + + /// + /// Gets the solutions. + /// + /// The solutions. + public ArrayList Solutions + { + get + { + return m_Solutions; + } + } + + #endregion + + #region Private Methods + + private void RemoveDirectories(string rootDir, string[] dirNames) + { + foreach(string dir in Directory.GetDirectories(rootDir)) + { + string simpleName = Path.GetFileName(dir); + + if(Array.IndexOf(dirNames, simpleName) != -1) + { + //delete if the name matches one of the directory names to delete + string fullDirPath = Path.GetFullPath(dir); + Directory.Delete(fullDirPath,true); + } + else//not a match, so check children + { + RemoveDirectories(dir,dirNames); + //recurse, checking children for them + } + } + } + +// private void RemoveDirectoryMatches(string rootDir, string dirPattern) +// { +// foreach(string dir in Directory.GetDirectories(rootDir)) +// { +// foreach(string match in Directory.GetDirectories(dir)) +// {//delete all child directories that match +// Directory.Delete(Path.GetFullPath(match),true); +// } +// //recure through the rest checking for nested matches to delete +// RemoveDirectoryMatches(dir,dirPattern); +// } +// } + + private void LoadSchema() + { + Assembly assembly = this.GetType().Assembly; + Stream stream = assembly.GetManifestResourceStream("Prebuild.data." + m_Schema); + if(stream == null) + { + //try without the default namespace prepending to it in case was compiled with SharpDevelop or MonoDevelop instead of Visual Studio .NET + stream = assembly.GetManifestResourceStream(m_Schema); + if(stream == null) + { + throw new System.Reflection.TargetException(string.Format("Could not find the scheme embedded resource file '{0}'.", m_Schema)); + } + } + XmlReader schema = new XmlTextReader(stream); + + m_Schemas = new XmlSchemaCollection(); + m_Schemas.Add(m_SchemaURI, schema); + } + + private void CacheVersion() + { + m_Version = Assembly.GetEntryAssembly().GetName().Version; + } + + private void CacheTargets(Assembly assm) + { + foreach(Type t in assm.GetTypes()) + { + TargetAttribute ta = (TargetAttribute)Helper.CheckType(t, typeof(TargetAttribute), typeof(ITarget)); + if(ta == null) + { + continue; + } + + ITarget target = (ITarget)assm.CreateInstance(t.FullName); + if(target == null) + { + throw new MissingMethodException("Could not create ITarget instance"); + } + + m_Targets[ta.Name] = target; + } + } + + private void CacheNodeTypes(Assembly assm) + { + foreach(Type t in assm.GetTypes()) + { + DataNodeAttribute dna = (DataNodeAttribute)Helper.CheckType(t, typeof(DataNodeAttribute), typeof(IDataNode)); + if(dna == null) + { + continue; + } + + NodeEntry ne = new NodeEntry(); + ne.Type = t; + ne.Attribute = dna; + m_Nodes[dna.Name] = ne; + } + } + + private void LogBanner() + { + m_Log.Write("Prebuild v" + this.Version); + m_Log.Write("Copyright (c) Matthew Holmes, Dan Moorehead and David Hudson"); + m_Log.Write("See 'prebuild /usage' for help"); + m_Log.Write(); + } + + private void ProcessFile(string file) + { + m_CurrentWorkingDirectory.Push(); + + string path = file; + try + { + try + { + path = Helper.ResolvePath(path); + } + catch(ArgumentException) + { + m_Log.Write("Could not open Prebuild file: " + path); + m_CurrentWorkingDirectory.Pop(); + return; + } + + m_CurrentFile = path; + Helper.SetCurrentDir(Path.GetDirectoryName(path)); + + + XmlTextReader reader = new XmlTextReader(path); + + Core.Parse.Preprocessor pre = new Core.Parse.Preprocessor(); + + //register command line arguments as XML variables + IDictionaryEnumerator dict = m_CommandLine.GetEnumerator(); + while (dict.MoveNext()) + { + string name = dict.Key.ToString().Trim(); + if (name.Length > 0) + pre.RegisterVariable(name, dict.Value.ToString()); + } + + string xml = pre.Process(reader);//remove script and evaulate pre-proccessing to get schema-conforming XML + + + XmlDocument doc = new XmlDocument(); + try + { + XmlValidatingReader validator = new XmlValidatingReader(new XmlTextReader(new StringReader(xml))); + + //validate while reading from string into XmlDocument DOM structure in memory + foreach(XmlSchema schema in m_Schemas) + { + validator.Schemas.Add(schema); + } + doc.Load(validator); + } + catch(XmlException e) + { + throw new XmlException(e.ToString()); + } + + //is there a purpose to writing it? An syntax/schema problem would have been found during pre.Process() and reported with details + if(m_CommandLine.WasPassed("ppo")) + { + string ppoFile = m_CommandLine["ppo"]; + if(ppoFile == null || ppoFile.Trim().Length < 1) + { + ppoFile = "preprocessed.xml"; + } + + StreamWriter writer = null; + try + { + writer = new StreamWriter(ppoFile); + writer.Write(xml); + } + catch(IOException ex) + { + Console.WriteLine("Could not write PPO file '{0}': {1}", ppoFile, ex.Message); + } + finally + { + if(writer != null) + { + writer.Close(); + } + } + return; + } + //start reading the xml config file + XmlElement rootNode = doc.DocumentElement; + //string suggestedVersion = Helper.AttributeValue(rootNode,"version","1.0"); + Helper.CheckForOSVariables = Helper.ParseBoolean(rootNode,"checkOsVars",false); + + foreach(XmlNode node in rootNode.ChildNodes)//solutions or if pre-proc instructions + { + IDataNode dataNode = ParseNode(node, null); + if(dataNode is ProcessNode) + { + ProcessNode proc = (ProcessNode)dataNode; + if(proc.IsValid) + { + ProcessFile(proc.Path); + } + } + else if(dataNode is SolutionNode) + { + m_Solutions.Add(dataNode); + } + } + } + catch(XmlSchemaException xse) + { + m_Log.Write("XML validation error at line {0} in {1}:\n\n{2}", + xse.LineNumber, path, xse.Message); + } + finally + { + m_CurrentWorkingDirectory.Pop(); + } + } + + #endregion + + #region Public Methods + + /// + /// Allows the project. + /// + /// The project groups flags. + /// + public bool AllowProject(string projectGroupsFlags) + { + if(m_ProjectGroups != null && m_ProjectGroups.Length > 0) + { + if(projectGroupsFlags != null && projectGroupsFlags.Length == 0) + { + foreach(string group in projectGroupsFlags.Split('|')) + { + if(Array.IndexOf(m_ProjectGroups, group) != -1) //if included in the filter list + { + return true; + } + } + } + return false;//not included in the list or no groups specified for the project + } + return true;//no filter specified in the command line args + } + + /// + /// Gets the type of the node. + /// + /// The node. + /// + public Type GetNodeType(XmlNode node) + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } + if(!m_Nodes.ContainsKey(node.Name)) + { + return null; + } + + NodeEntry ne = (NodeEntry)m_Nodes[node.Name]; + return ne.Type; + } + + /// + /// + /// + /// + /// + /// + public IDataNode ParseNode(XmlNode node, IDataNode parent) + { + return ParseNode(node, parent, null); + } + + //Create an instance of the data node type that is mapped to the name of the xml DOM node + /// + /// Parses the node. + /// + /// The node. + /// The parent. + /// The pre node. + /// + public IDataNode ParseNode(XmlNode node, IDataNode parent, IDataNode preNode) + { + IDataNode dataNode = null; + + try + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } + if(preNode == null) + { + if(!m_Nodes.ContainsKey(node.Name)) + { + //throw new XmlException("Unknown XML node: " + node.Name); + return null; + } + + NodeEntry ne = (NodeEntry)m_Nodes[node.Name]; + Type type = ne.Type; + //DataNodeAttribute dna = ne.Attribute; + + dataNode = (IDataNode)type.Assembly.CreateInstance(type.FullName); + if(dataNode == null) + { + throw new System.Reflection.TargetException("Could not create new parser instance: " + type.FullName); + } + } + else + dataNode = preNode; + + dataNode.Parent = parent; + dataNode.Parse(node); + } + catch(WarningException wex) + { + m_Log.Write(LogType.Warning, wex.Message); + return null; + } + catch(FatalException fex) + { + m_Log.WriteException(LogType.Error, fex); + throw; + } + catch(Exception ex) + { + m_Log.WriteException(LogType.Error, ex); + throw; + } + + return dataNode; + } + + /// + /// Initializes the specified target. + /// + /// The target. + /// The args. + public void Initialize(LogTargets target, string[] args) + { + m_Targets = new Hashtable(); + CacheTargets(this.GetType().Assembly); + m_Nodes = new Hashtable(); + CacheNodeTypes(this.GetType().Assembly); + CacheVersion(); + + m_CommandLine = new CommandLineCollection(args); + + string logFile = null; + if(m_CommandLine.WasPassed("log")) + { + logFile = m_CommandLine["log"]; + + if(logFile != null && logFile.Length == 0) + { + logFile = "Prebuild.log"; + } + } + else + { + target = target & ~LogTargets.File; //dont output to a file + } + + m_Log = new Log(target, logFile); + LogBanner(); + + m_CurrentWorkingDirectory = new CurrentDirectory(); + + m_Target = m_CommandLine["target"]; + m_Clean = m_CommandLine["clean"]; + string removeDirs = m_CommandLine["removedir"]; + if(removeDirs != null && removeDirs.Length == 0) + { + m_RemoveDirectories = removeDirs.Split('|'); + } + + string flags = m_CommandLine["allowedgroups"];//allows filtering by specifying a pipe-delimited list of groups to include + if(flags != null && flags.Length == 0) + { + m_ProjectGroups = flags.Split('|'); + } + m_PauseAfterFinish = m_CommandLine.WasPassed("pause"); + + LoadSchema(); + + m_Solutions = new ArrayList(); + m_Refs = new StringCollection(); + } + + /// + /// Processes this instance. + /// + public void Process() + { + bool perfomedOtherTask = false; + if(m_RemoveDirectories != null && m_RemoveDirectories.Length > 0) + { + try + { + RemoveDirectories(".",m_RemoveDirectories); + } + catch(IOException e) + { + m_Log.Write("Failed to remove directories named {0}",m_RemoveDirectories); + m_Log.WriteException(LogType.Error,e); + } + catch(UnauthorizedAccessException e) + { + m_Log.Write("Failed to remove directories named {0}",m_RemoveDirectories); + m_Log.WriteException(LogType.Error,e); + } + perfomedOtherTask = true; + } + + if(m_Target != null && m_Clean != null) + { + m_Log.Write(LogType.Error, "The options /target and /clean cannot be passed together"); + return; + } + else if(m_Target == null && m_Clean == null) + { + if(perfomedOtherTask) //finished + { + return; + } + m_Log.Write(LogType.Error, "Must pass either /target or /clean to process a Prebuild file"); + return; + } + + string file = "./prebuild.xml"; + if(m_CommandLine.WasPassed("file")) + { + file = m_CommandLine["file"]; + } + + ProcessFile(file); + + string target = (m_Target != null ? m_Target.ToLower() : m_Clean.ToLower()); + bool clean = (m_Target == null); + if(clean && target != null && target.Length == 0) + { + target = "all"; + } + if(clean && target == "all")//default to all if no target was specified for clean + { + //check if they passed yes + if (!m_CommandLine.WasPassed("yes")) + { + Console.WriteLine("WARNING: This operation will clean ALL project files for all targets, are you sure? (y/n):"); + string ret = Console.ReadLine(); + if(ret == null) + { + return; + } + ret = ret.Trim().ToLower(); + if((ret.ToLower() != "y" && ret.ToLower() != "yes")) + { + return; + } + } + //clean all targets (just cleaning vs2002 target didn't clean nant) + foreach(ITarget targ in m_Targets.Values) + { + targ.Clean(this); + } + } + else + { + ITarget targ = (ITarget)m_Targets[target]; + + if(clean) + { + targ.Clean(this); + } + else + { + targ.Write(this); + } + } + + m_Log.Flush(); + } + + #endregion + + #region IDisposable Members + + /// + /// + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Dispose objects + /// + /// + /// If true, it will dispose close the handle + /// + /// + /// Will dispose managed and unmanaged resources. + /// + protected virtual void Dispose(bool disposing) + { + if (!this.disposed) + { + if (disposing) + { + if (this.m_Log != null) + { + this.m_Log.Close(); + this.m_Log = null; + } + } + } + this.disposed = true; + } + + /// + /// + /// + ~Kernel() + { + this.Dispose(false); + } + + /// + /// Closes and destroys this object + /// + /// + /// Same as Dispose(true) + /// + public void Close() + { + Dispose(); + } + + #endregion + } } \ No newline at end of file -- cgit v1.1