/// <summary> /// Initializes the <see cref="ParaffinArgParser"/> with all the /// settings from the first comment block. Used when reading in a .WXS /// to compare to the files on the disk. /// </summary> /// <param name="inputXml"> /// The XML string to process. /// </param> /// <returns> /// True if everything is cool, false if this is a multiple files /// per component file. /// </returns> private static Boolean InitializeArgumentsFromFile(string inputXml) { XElement options = XElement.Parse(inputXml); // Save off the settings from the command line. ParaffinArgParser originalArgs = argValues; // Start the arguments from the comment section. argValues = new ParaffinArgParser { ReportIfDifferent = originalArgs.ReportIfDifferent, PatchUpdate = originalArgs.PatchUpdate, FileName = originalArgs.FileName, PatchCreateFiles = originalArgs.PatchCreateFiles }; // Look for the version element. If it's missing or 1, it's an old // file. var verElem = options.Descendants(VERSIONELEM); if (verElem.Count() == 1) { Int32 ver = Convert.ToInt32(verElem.First().Value, CultureInfo.InvariantCulture); if (ver > argValues.Version) { throw new InvalidOperationException( Constants.MadeWithNewParaffin); } // In file version 2, the <GroupName> is what I need to read. // For previous versions it was <Custom> argValues.GroupName = options.Descendants(GROUPNAMEELEM).First().Value; } else { // This is a file from 3.0 or prior. argValues.Version = Version1File; // These options are deprecated in newer versions, but I don't // want to break old files that are being updated. argValues.IncrementValue = Convert.ToInt32( options.Descendants(INCREMENTELEM).First().Value, CultureInfo.InvariantCulture); directoryNumber = Convert.ToInt32( options.Descendants(NEXTDIRECTORYNUMELEM).First().Value, CultureInfo.InvariantCulture); componentNumber = Convert.ToInt32( options.Descendants(NEXTCOMPONENTNUMBER).First().Value, CultureInfo.InvariantCulture); // The <Custom> value was used in older versions. argValues.GroupName = options.Descendants(CUSTOMELEM).First().Value; } // Get all the easy values out. argValues.Alias = options.Descendants(ALIASELEM).First().Value; // The old multiple files per component option is no longer // supported. var mul = options.Descendants(MULTIPLEELEM); if (mul.Count() != 0) { Boolean value = Convert.ToBoolean(mul.First().Value, CultureInfo.InvariantCulture); if (value) { return false; } } argValues.StartDirectory = options.Descendants(DIRECTORYELEM).First().Value; argValues.NoRecursion = Convert.ToBoolean( options.Descendants(NORECURSELEM).First().Value, CultureInfo.InvariantCulture); var extNode = options.Descendants(EXTEXCLUDEELEM); foreach (var item in extNode.Descendants()) { argValues.ExtensionList.Add(item.Value, true); } var dirEx = options.Descendants(DIREEXCLUDEELEM); foreach (var item in dirEx.Descendants()) { argValues.DirectoryExcludeList.Add(item.Value); } // After releasing 1.0, I've added a few command line options. // Since I don't want to break existing PARAFFIN generated files, // I'll not require the following options to be in existing files. // If they are cool, but no sense crashing out if they aren't. var win64Elems = options.Descendants(WIN64ELEM); if (win64Elems.Count() == 1) { // Check to see if this is an older file that uses "false" for // the value. String rawValue = win64Elems.First().Value; if (0 == String.Compare(rawValue, "false", StringComparison.OrdinalIgnoreCase)) { argValues.Win64 = String.Empty; } else { // Grab the value. argValues.Win64 = win64Elems.First().Value; } } else { // Assume false. argValues.Win64 = null; } var noDirElems = options.Descendants(NODIRECTORYELEM); if (noDirElems.Count() == 1) { argValues.NoRootDirectory = Convert.ToBoolean( noDirElems.First().Value, CultureInfo.InvariantCulture); argValues.NoRootDirectoryState = argValues.NoRootDirectory; } else { argValues.NoRootDirectory = false; argValues.NoRootDirectoryState = false; } var diskIdValue = options.Descendants(DISKIDELEM); if (diskIdValue.Count() == 1) { argValues.DiskId = Convert.ToInt32(diskIdValue.First().Value, CultureInfo.InvariantCulture); } else { argValues.DiskId = 1; } var includeFileNode = options.Descendants(INCLUDEFILESELEM); foreach (var item in includeFileNode.Descendants()) { argValues.IncludeFiles.Add(item.Value); } var regExFileNode = options.Descendants(REGEXEXELEMENT); foreach (var item in regExFileNode.Descendants()) { argValues.RegExExcludes.Add(new Regex(item.Value, RegexOptions.IgnoreCase)); } // Now that everything is read out of the original options block, // add in any additional -ext, -dirExclude, and -regExExclude // options specified on the command line. foreach (var cmdLineExt in originalArgs.ExtensionList.Keys) { if (false == argValues.ExtensionList.ContainsKey(cmdLineExt)) { argValues.ExtensionList.Add(cmdLineExt, true); } } foreach (var dirExclude in originalArgs.DirectoryExcludeList) { if (false == argValues.DirectoryExcludeList.Contains(dirExclude)) { argValues.DirectoryExcludeList.Add(dirExclude); } } foreach (var regExExclude in originalArgs.RegExExcludes) { if (false == argValues.RegExExcludes.Any(rx => rx.ToString() == regExExclude.ToString())) { argValues.RegExExcludes.Add(regExExclude); } } return true; }
/// <summary> /// The entry point for the application. /// </summary> /// <param name="args">The command line arguments.</param> /// <returns> /// 0 - Successful /// 1 - Invalid command line argument. /// 2 - Invalid input file. /// 3 - File contains multiple files per component. No longer supported. /// 4 - If -ReportIfDifferent is specified on an update, a return value /// of 4 indicates the input .WXS and output .PARAFFIN file are /// different. /// </returns> internal static Int32 Main(string[] args) { directoryNumber = 0; componentNumber = 0; errorMessage = String.Empty; verboseOut = new TraceSource(Constants.TraceSourceName, SourceLevels.Critical) { Switch = new SourceSwitch(Constants.SourceSwitchName) }; #if DEBUG == false // In release builds there's no sense doing the OutputDebugString // output since that causes a performance hit. verboseOut.Listeners.Remove("Default"); #endif // Think positive that everything will run completely. Int32 returnValue = 0; argValues = new ParaffinArgParser(); if (args.Length > 0) { Boolean parsed = argValues.Parse(args); if (parsed) { if (argValues.Verbose) { verboseOut.Switch.Level = SourceLevels.Information; SmartConsoleTraceListener sctl = new SmartConsoleTraceListener(); verboseOut.Listeners.Add(sctl); } if (argValues.Update || argValues.PatchUpdate) { returnValue = UpdateExistingFile(); } else if (argValues.PatchCreateFiles) { returnValue = CreateZeroByteFiles(); } else { returnValue = CreateNewFile(); } } } else { argValues.OnUsage(String.Empty); returnValue = 1; } verboseOut.TraceInformation(Constants.VerboseReturnValue, returnValue); if (false == String.IsNullOrEmpty(errorMessage)) { WriteError(errorMessage); } return(returnValue); }
/// <summary> /// Initializes the <see cref="ParaffinArgParser"/> with all the /// settings from the first comment block. Used when reading in a .WXS /// to compare to the files on the disk. /// </summary> /// <param name="inputXml"> /// The XML string to process. /// </param> /// <returns> /// True if everything is cool, false if this is a multiple files /// per component file. /// </returns> private static Boolean InitializeArgumentsFromFile(string inputXml) { XElement options = XElement.Parse(inputXml); // Save off the settings from the command line. ParaffinArgParser originalArgs = argValues; // Start the arguments from the comment section. argValues = new ParaffinArgParser { ReportIfDifferent = originalArgs.ReportIfDifferent, PatchUpdate = originalArgs.PatchUpdate, FileName = originalArgs.FileName, PatchCreateFiles = originalArgs.PatchCreateFiles }; // Look for the version element. If it's missing or 1, it's an old // file. var verElem = options.Descendants(VERSIONELEM); if (verElem.Count() == 1) { Int32 ver = Convert.ToInt32(verElem.First().Value, CultureInfo.InvariantCulture); if (ver > argValues.Version) { throw new InvalidOperationException( Constants.MadeWithNewParaffin); } // In file version 2, the <GroupName> is what I need to read. // For previous versions it was <Custom> argValues.GroupName = options.Descendants(GROUPNAMEELEM).First().Value; } else { // This is a file from 3.0 or prior. argValues.Version = Version1File; // These options are deprecated in newer versions, but I don't // want to break old files that are being updated. argValues.IncrementValue = Convert.ToInt32( options.Descendants(INCREMENTELEM).First().Value, CultureInfo.InvariantCulture); directoryNumber = Convert.ToInt32( options.Descendants(NEXTDIRECTORYNUMELEM).First().Value, CultureInfo.InvariantCulture); componentNumber = Convert.ToInt32( options.Descendants(NEXTCOMPONENTNUMBER).First().Value, CultureInfo.InvariantCulture); // The <Custom> value was used in older versions. argValues.GroupName = options.Descendants(CUSTOMELEM).First().Value; } // Get all the easy values out. argValues.Alias = options.Descendants(ALIASELEM).First().Value; // The old multiple files per component option is no longer // supported. var mul = options.Descendants(MULTIPLEELEM); if (mul.Count() != 0) { Boolean value = Convert.ToBoolean(mul.First().Value, CultureInfo.InvariantCulture); if (value) { return(false); } } argValues.StartDirectory = options.Descendants(DIRECTORYELEM).First().Value; argValues.NoRecursion = Convert.ToBoolean( options.Descendants(NORECURSELEM).First().Value, CultureInfo.InvariantCulture); var extNode = options.Descendants(EXTEXCLUDEELEM); foreach (var item in extNode.Descendants()) { argValues.ExtensionList.Add(item.Value, true); } var dirEx = options.Descendants(DIREEXCLUDEELEM); foreach (var item in dirEx.Descendants()) { argValues.DirectoryExcludeList.Add(item.Value); } // After releasing 1.0, I've added a few command line options. // Since I don't want to break existing PARAFFIN generated files, // I'll not require the following options to be in existing files. // If they are cool, but no sense crashing out if they aren't. var win64Elems = options.Descendants(WIN64ELEM); if (win64Elems.Count() == 1) { // Check to see if this is an older file that uses "false" for // the value. String rawValue = win64Elems.First().Value; if (0 == String.Compare(rawValue, "false", StringComparison.OrdinalIgnoreCase)) { argValues.Win64 = String.Empty; } else { // Grab the value. argValues.Win64 = win64Elems.First().Value; } } else { // Assume false. argValues.Win64 = null; } var noDirElems = options.Descendants(NODIRECTORYELEM); if (noDirElems.Count() == 1) { argValues.NoRootDirectory = Convert.ToBoolean( noDirElems.First().Value, CultureInfo.InvariantCulture); argValues.NoRootDirectoryState = argValues.NoRootDirectory; } else { argValues.NoRootDirectory = false; argValues.NoRootDirectoryState = false; } var diskIdValue = options.Descendants(DISKIDELEM); if (diskIdValue.Count() == 1) { argValues.DiskId = Convert.ToInt32(diskIdValue.First().Value, CultureInfo.InvariantCulture); } else { argValues.DiskId = 1; } var includeFileNode = options.Descendants(INCLUDEFILESELEM); foreach (var item in includeFileNode.Descendants()) { argValues.IncludeFiles.Add(item.Value); } var regExFileNode = options.Descendants(REGEXEXELEMENT); foreach (var item in regExFileNode.Descendants()) { argValues.RegExExcludes.Add(new Regex(item.Value, RegexOptions.IgnoreCase)); } // Now that everything is read out of the original options block, // add in any additional -ext, -dirExclude, and -regExExclude // options specified on the command line. foreach (var cmdLineExt in originalArgs.ExtensionList.Keys) { if (false == argValues.ExtensionList.ContainsKey(cmdLineExt)) { argValues.ExtensionList.Add(cmdLineExt, true); } } foreach (var dirExclude in originalArgs.DirectoryExcludeList) { if (false == argValues.DirectoryExcludeList.Contains(dirExclude)) { argValues.DirectoryExcludeList.Add(dirExclude); } } foreach (var regExExclude in originalArgs.RegExExcludes) { if (false == (argValues.RegExExcludes.Any(rx => rx.ToString() == regExExclude.ToString()))) { argValues.RegExExcludes.Add(regExExclude); } } return(true); }