/* Function: AddPrototypeEnders * Sets the <PrototypeEnders> for the passed comment type. If enders already existed for that type they will be replaced. */ public void AddPrototypeEnders(PrototypeEnders prototypeEnders) { bool delete = (prototypeEnders == null || (!prototypeEnders.HasSymbols && !prototypeEnders.IncludeLineBreaks)); int index = PrototypeEndersIndex(prototypeEnders.CommentTypeID); if (index == -1) { if (!delete) { if (this.prototypeEnders == null) { this.prototypeEnders = new List <PrototypeEnders>(); } this.prototypeEnders.Add(prototypeEnders); } } else { if (!delete) { this.prototypeEnders[index] = prototypeEnders; } else { if (this.prototypeEnders.Count == 1) { this.prototypeEnders = null; } else { this.prototypeEnders.RemoveAt(index); } } } }
/* Function: SetPrototypeEnders * Sets the <PrototypeEnders> for the passed comment type. */ public void SetPrototypeEnders(int commentTypeID, PrototypeEnders prototypeEnders) { // Simplify prototypeEnders if (prototypeEnders != null) { if (prototypeEnders.Symbols != null && prototypeEnders.Symbols.Length == 0) { prototypeEnders.Symbols = null; } if (prototypeEnders.Symbols == null && prototypeEnders.IncludeLineBreaks == false) { prototypeEnders = null; } } if (prototypeEnders == null) { if (commentTypesToPrototypeEnders != null) { commentTypesToPrototypeEnders.Remove(commentTypeID); if (commentTypesToPrototypeEnders.Count == 0) { commentTypesToPrototypeEnders = null; } } } else { if (commentTypesToPrototypeEnders == null) { commentTypesToPrototypeEnders = new SafeDictionary <int, PrototypeEnders>(); } commentTypesToPrototypeEnders[commentTypeID] = prototypeEnders; } }
/* Function: PrototypeEndersAreEqual * Compares two prototype ender dictionaries. Is case sensitive and safe to use with nulls. */ protected static bool PrototypeEndersAreEqual(SafeDictionary <int, PrototypeEnders> commentTypesToPrototypeEnders1, SafeDictionary <int, PrototypeEnders> commentTypesToPrototypeEnders2) { if (commentTypesToPrototypeEnders1 == null && commentTypesToPrototypeEnders2 == null) { return(true); } else if (commentTypesToPrototypeEnders1 == null || commentTypesToPrototypeEnders2 == null) { return(false); } else if (commentTypesToPrototypeEnders1.Count != commentTypesToPrototypeEnders2.Count) { return(false); } else { foreach (System.Collections.Generic.KeyValuePair <int, PrototypeEnders> prototypeEnders1Pair in commentTypesToPrototypeEnders1) { PrototypeEnders prototypeEnders2Value = commentTypesToPrototypeEnders2[prototypeEnders1Pair.Key]; if (prototypeEnders2Value == null) { return(false); } if (prototypeEnders1Pair.Value.IncludeLineBreaks != prototypeEnders2Value.IncludeLineBreaks || !StringArraysAreEqual(prototypeEnders1Pair.Value.Symbols, prototypeEnders2Value.Symbols)) { return(false); } } return(true); } }
// Group: Saving Functions // __________________________________________________________________________ /* Function: Save * Saves the current computed languages into <Languages.nd>. Throws an exception if unsuccessful. */ public void Save(Path filename, IDObjects.Manager <Language> languages, StringTable <Language> aliases, StringTable <Language> extensions, SortedStringTable <Language> shebangStrings, StringSet ignoredExtensions) { BinaryFile file = new BinaryFile(); file.OpenForWriting(filename); try { // [String: Language Name] // [Int32: ID] // [Byte: Type] // [String: Simple Identifier] // [Byte: Enum Values] // [Byte: Case Sensitive (1 or 0)] // [String: Member Operator Symbol] // [String: Line Extender Symbol] // [String: Line Comment Symbol] [] ... [String: null] // [String: Opening Block Comment Symbol] [String: Closing Block Comment Symbo] [] [] ... [String: null] // [String: Opening Javadoc Line Comment Symbol] [String: Remainder Javadoc Line Comment Symbol [] ... [String: null] // [String: Opening Javadoc Block Comment Symbol] [String: Closing Javadoc Block Comment Symbol] [] [] ... [String: null] // [String: XML Line Comment Symbol] [] ... [String: null] // [Int32: Comment Type ID] // [Byte: Include Line Breaks (0 or 1)] // [String: Prototype Ender Symbol] [] ... [String: null] // ... // [Int32: 0] // ... // [String: null] foreach (Language language in languages) { file.WriteString(language.Name); file.WriteInt32(language.ID); file.WriteByte((byte)language.Type); file.WriteString(language.SimpleIdentifier); file.WriteByte((byte)language.EnumValue); file.WriteByte((byte)(language.CaseSensitive ? 1 : 0)); file.WriteString(language.MemberOperator); file.WriteString(language.LineExtender); WriteStringArray(file, language.LineCommentStrings); WriteStringArray(file, language.BlockCommentStringPairs); WriteStringArray(file, language.JavadocLineCommentStringPairs); WriteStringArray(file, language.JavadocBlockCommentStringPairs); WriteStringArray(file, language.XMLLineCommentStrings); int[] commentTypes = language.GetCommentTypesWithPrototypeEnders(); if (commentTypes != null) { foreach (int commentType in commentTypes) { PrototypeEnders prototypeEnders = language.GetPrototypeEnders(commentType); file.WriteInt32(commentType); file.WriteByte((byte)(prototypeEnders.IncludeLineBreaks ? 1 : 0)); WriteStringArray(file, prototypeEnders.Symbols); } } file.WriteInt32(0); } file.WriteString(null); // [String: Alias] [Int32: Language ID] [] [] ... [String: Null] foreach (KeyValuePair <string, Language> pair in aliases) { file.WriteString(pair.Key); file.WriteInt32(pair.Value.ID); } file.WriteString(null); // [String: Extension] [Int32: Language ID] [] [] ... [String: Null] foreach (KeyValuePair <string, Language> pair in extensions) { file.WriteString(pair.Key); file.WriteInt32(pair.Value.ID); } file.WriteString(null); // [String: Shebang String] [Int32: Language ID] [] [] ... [String: Null] foreach (KeyValuePair <string, Language> pair in shebangStrings) { file.WriteString(pair.Key); file.WriteInt32(pair.Value.ID); } file.WriteString(null); // [String: Ignored Extension] [] ... [String: Null] foreach (string ignoredExtension in ignoredExtensions) { file.WriteString(ignoredExtension); } file.WriteString(null); } finally { file.Close(); } }
/* Function: Start_AddLanguage * A helper function that is used only by <Start()> to add a <ConfigFileLanguage> into <languages>. * Returns whether it was able to do so without any errors. */ private bool Start_AddLanguage(ConfigFileLanguage configFileLanguage, Path sourceFile, bool isSystemFile, StringSet ignoredExtensions, Errors.ErrorList errorList) { bool success = true; // Validate or create the language. if (configFileLanguage.AlterLanguage == true) { // If altering a language that doesn't exist at all, at least not in the config files... if (languages.Contains(configFileLanguage.Name) == false || languages[configFileLanguage.Name].InConfigFiles == false) { errorList.Add( Locale.Get("NaturalDocs.Engine", "Languages.txt.AlteredLanguageDoesntExist(name)", configFileLanguage.Name), sourceFile, configFileLanguage.LineNumber ); success = false; } } else // define language, not alter { // Error if defining a language that already exists in the config files. Having it exist otherwise is fine. if (languages.Contains(configFileLanguage.Name)) { if (languages[configFileLanguage.Name].InConfigFiles == true) { errorList.Add( Locale.Get("NaturalDocs.Engine", "Languages.txt.LanguageAlreadyExists(name)", configFileLanguage.Name), sourceFile, configFileLanguage.LineNumber ); success = false; } } else { Language newLanguage = new Language(this, configFileLanguage.Name); languages.Add(newLanguage); } if (isSystemFile) { languages[configFileLanguage.Name].InSystemFile = true; } else { languages[configFileLanguage.Name].InProjectFile = true; } } if (success == false) { return(false); } // Apply the properties. Language language = languages[configFileLanguage.Name]; if (configFileLanguage.SimpleIdentifier != null) { language.SimpleIdentifier = configFileLanguage.SimpleIdentifier; } if (configFileLanguage.LineCommentStrings != null) { if (language.Type != Language.LanguageType.BasicSupport) { Start_CantDefinePropertyError(configFileLanguage, language.Type, sourceFile, "Line Comment", errorList); success = false; } else { language.LineCommentStrings = configFileLanguage.LineCommentStrings; } } if (configFileLanguage.BlockCommentStringPairs != null) { if (language.Type != Language.LanguageType.BasicSupport) { Start_CantDefinePropertyError(configFileLanguage, language.Type, sourceFile, "Block Comment", errorList); success = false; } else { language.BlockCommentStringPairs = configFileLanguage.BlockCommentStringPairs; } } if (configFileLanguage.MemberOperator != null) { if (language.Type != Language.LanguageType.BasicSupport && language.Type != Language.LanguageType.TextFile) { Start_CantDefinePropertyError(configFileLanguage, language.Type, sourceFile, "Member Operator", errorList); success = false; } else { language.MemberOperator = configFileLanguage.MemberOperator; } } if (configFileLanguage.LineExtender != null) { if (language.Type != Language.LanguageType.BasicSupport) { Start_CantDefinePropertyError(configFileLanguage, language.Type, sourceFile, "Line Extender", errorList); success = false; } else { language.LineExtender = configFileLanguage.LineExtender; } } if (configFileLanguage.EnumValue != null) { if (language.Type != Language.LanguageType.BasicSupport && language.Type != Language.LanguageType.TextFile) { Start_CantDefinePropertyError(configFileLanguage, language.Type, sourceFile, "Enum Value", errorList); success = false; } else { language.EnumValue = (Language.EnumValues)configFileLanguage.EnumValue; } } if (configFileLanguage.CaseSensitive != null) { if (language.Type != Language.LanguageType.BasicSupport && language.Type != Language.LanguageType.TextFile) { Start_CantDefinePropertyError(configFileLanguage, language.Type, sourceFile, "Case Sensitive", errorList); success = false; } else { language.CaseSensitive = (bool)configFileLanguage.CaseSensitive; } } string[] commentTypeNamesWithPrototypeEnders = configFileLanguage.GetCommentTypeNamesWithPrototypeEnders(); if (commentTypeNamesWithPrototypeEnders != null) { if (language.Type != Language.LanguageType.BasicSupport) { Start_CantDefinePropertyError(configFileLanguage, language.Type, sourceFile, "Prototype Enders", errorList); success = false; } else { foreach (string commentTypeName in commentTypeNamesWithPrototypeEnders) { CommentTypes.CommentType commentType = EngineInstance.CommentTypes.FromName(commentTypeName); if (commentType == null) { errorList.Add( Locale.Get("NaturalDocs.Engine", "Languages.txt.PrototypeEnderCommentTypeDoesntExist(name)", commentTypeName), sourceFile, configFileLanguage.LineNumber ); success = false; } else { string[] prototypeEnderStrings = configFileLanguage.GetPrototypeEnderStrings(commentTypeName); PrototypeEnders prototypeEnders = new PrototypeEnders(prototypeEnderStrings); language.SetPrototypeEnders(commentType.ID, prototypeEnders); } } } } // Apply the aliases, extensions, and shebang strings. if (configFileLanguage.Aliases != null) { // If using Replace Aliases, find all existing aliases pointing to this language and remove them. if (configFileLanguage.AlterLanguage == true && configFileLanguage.AddAliases == false) { List <string> removedAliases = new List <string>(); foreach (KeyValuePair <string, Language> pair in aliases) { if ((object)pair.Value == (object)language) { removedAliases.Add(pair.Key); } } foreach (string removedAlias in removedAliases) { aliases.Remove(removedAlias); } } // Add new aliases. foreach (string alias in configFileLanguage.Aliases) { aliases[alias] = language; } } if (configFileLanguage.Extensions != null) { // If using Replace Extensions, find all existing extensions pointing to this language and remove them. if (configFileLanguage.AlterLanguage == true && configFileLanguage.AddExtensions == false) { List <string> removedExtensions = new List <string>(); foreach (KeyValuePair <string, Language> pair in extensions) { if ((object)pair.Value == (object)language) { removedExtensions.Add(pair.Key); } } foreach (string removedExtension in removedExtensions) { extensions.Remove(removedExtension); } } // Add new extensions. foreach (string extension in configFileLanguage.Extensions) { if (ignoredExtensions.Contains(extension) == false) { extensions[extension] = language; } } } if (configFileLanguage.ShebangStrings != null) { // If using Replace Shebang Strings, find all existing shebang strings pointing to this language and remove them. if (configFileLanguage.AlterLanguage == true && configFileLanguage.AddShebangStrings == false) { List <string> removedShebangStrings = new List <string>(); foreach (KeyValuePair <string, Language> pair in shebangStrings) { if ((object)pair.Value == (object)language) { removedShebangStrings.Add(pair.Key); } } foreach (string removedShebangString in removedShebangStrings) { shebangStrings.Remove(removedShebangString); } } // Add new shebang strings. foreach (string shebangString in configFileLanguage.ShebangStrings) { shebangStrings[shebangString] = language; } } return(success); }