diff --git a/External/Plugins/CodeAnalyzer/PluginMain.cs b/External/Plugins/CodeAnalyzer/PluginMain.cs index 327c46dac9..e426d9fd17 100644 --- a/External/Plugins/CodeAnalyzer/PluginMain.cs +++ b/External/Plugins/CodeAnalyzer/PluginMain.cs @@ -164,7 +164,7 @@ private void CreateMenuItem() /// private void OpenCreator(Object sender, EventArgs e) { - String url = "http://opensource.adobe.com/svn/opensource/flexpmd/bin/flex-pmd-ruleset-creator.html"; + String url = "http://www.flashdevelop.org/flexpmd/index.html"; PluginBase.MainForm.CallCommand("Browse", url); } diff --git a/External/Plugins/CodeFormatter/AStyle/AStyleInterface.cs b/External/Plugins/CodeFormatter/AStyle/AStyleInterface.cs new file mode 100644 index 0000000000..6c1e3377d2 --- /dev/null +++ b/External/Plugins/CodeFormatter/AStyle/AStyleInterface.cs @@ -0,0 +1,117 @@ +using System; +using System.Runtime.InteropServices; +using PluginCore.Managers; + +namespace CodeFormatter +{ + public class AStyleInterface + { + #region Imports + + /// http://astyle.sourceforge.net/astyle.html + /// Cannot use String as a return value because Mono runtime will attempt to free the returned pointer resulting in a runtime crash. + + [DllImport("AStyle.dll", EntryPoint = "AStyleGetVersion")] + private static extern IntPtr AStyleGetVersion_32(); + + [DllImport("AStyle64.dll", EntryPoint = "AStyleGetVersion")] + private static extern IntPtr AStyleGetVersion_64(); + + [DllImport("AStyle.dll", EntryPoint = "AStyleMainUtf16", CharSet = CharSet.Unicode)] + private static extern IntPtr AStyleMainUtf16_32([MarshalAs(UnmanagedType.LPWStr)] String sIn, [MarshalAs(UnmanagedType.LPWStr)] String sOptions, AStyleErrorDelgate errorFunc, AStyleMemAllocDelgate memAllocFunc); + + [DllImport("AStyle64.dll", EntryPoint = "AStyleMainUtf16", CharSet = CharSet.Unicode)] + private static extern IntPtr AStyleMainUtf16_64([MarshalAs(UnmanagedType.LPWStr)] String sIn, [MarshalAs(UnmanagedType.LPWStr)] String sOptions, AStyleErrorDelgate errorFunc, AStyleMemAllocDelgate memAllocFunc); + + private static IntPtr AStyleMainUtf16(String textIn, String options, AStyleErrorDelgate AStyleError, AStyleMemAllocDelgate AStyleMemAlloc) + { + return (IntPtr.Size == 4 ? AStyleMainUtf16_32(textIn, options, AStyleError, AStyleMemAlloc) : AStyleMainUtf16_64(textIn, options, AStyleError, AStyleMemAlloc)); + } + + private static IntPtr AStyleGetVersion() + { + return (IntPtr.Size == 4 ? AStyleGetVersion_32() : AStyleGetVersion_64()); + } + + #endregion + + /// AStyleMainUtf16 callbacks. + private delegate IntPtr AStyleMemAllocDelgate(int size); + private delegate void AStyleErrorDelgate(int errorNum, [MarshalAs(UnmanagedType.LPStr)]String error); + + /// AStyleMainUtf16 Delegates. + private AStyleMemAllocDelgate AStyleMemAlloc; + private AStyleErrorDelgate AStyleError; + + /// AStyleMainUtf16 Constants. + public const String DefaultOptions = "--indent-namespaces --indent-preproc-block --indent-preproc-cond --indent-switches --indent-cases --delete-empty-lines --pad-header --keep-one-line-blocks --keep-one-line-statements --close-templates"; + + /// + /// Declare callback functions. + /// + public AStyleInterface() + { + AStyleMemAlloc = new AStyleMemAllocDelgate(OnAStyleMemAlloc); + AStyleError = new AStyleErrorDelgate(OnAStyleError); + } + + /// + /// Call the AStyleMainUtf16 function in Artistic Style. An empty string is returned on error. + /// + public String FormatSource(String textIn, String options) + { + // Memory space is allocated by OnAStyleMemAlloc, a callback function + String sTextOut = String.Empty; + try + { + IntPtr pText = AStyleMainUtf16(textIn, options, AStyleError, AStyleMemAlloc); + if (pText != IntPtr.Zero) + { + sTextOut = Marshal.PtrToStringUni(pText); + Marshal.FreeHGlobal(pText); + } + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + return sTextOut; + } + + /// + /// Get the Artistic Style version number. + /// + public String GetVersion() + { + String sVersion = String.Empty; + try + { + IntPtr pVersion = AStyleGetVersion(); + if (pVersion != IntPtr.Zero) sVersion = Marshal.PtrToStringAnsi(pVersion); + } + catch (Exception ex) + { + ErrorManager.ShowError(ex); + } + return sVersion; + } + + /// + /// Allocate the memory for the Artistic Style return string. + /// + private IntPtr OnAStyleMemAlloc(int size) + { + return Marshal.AllocHGlobal(size); + } + + /// + /// Display errors from Artistic Style. + /// + private void OnAStyleError(int errorNumber, String errorMessage) + { + ErrorManager.ShowError(errorMessage, null); + } + + } + +} diff --git a/External/Plugins/CodeFormatter/CodeFormatter.csproj b/External/Plugins/CodeFormatter/CodeFormatter.csproj index 40f02fad6f..1861ab57b2 100644 --- a/External/Plugins/CodeFormatter/CodeFormatter.csproj +++ b/External/Plugins/CodeFormatter/CodeFormatter.csproj @@ -76,6 +76,7 @@ + diff --git a/External/Plugins/CodeFormatter/PluginMain.cs b/External/Plugins/CodeFormatter/PluginMain.cs index 436e97fcfc..116f756df0 100644 --- a/External/Plugins/CodeFormatter/PluginMain.cs +++ b/External/Plugins/CodeFormatter/PluginMain.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.IO; +using System.Text.RegularExpressions; using System.Windows.Forms; using ASCompletion.Context; using CodeFormatter.Handlers; @@ -19,7 +20,7 @@ public class PluginMain : IPlugin { private String pluginName = "CodeFormatter"; private String pluginGuid = "f7f1e15b-282a-4e55-ba58-5f2c02765247"; - private String pluginDesc = "Adds an MXML and ActionScript code formatter to FlashDevelop."; + private String pluginDesc = "Adds multiple code formatters to FlashDevelop."; private String pluginHelp = "www.flashdevelop.org/community/"; private String pluginAuth = "FlashDevelop Team"; private ToolStripMenuItem contextMenuItem; @@ -167,7 +168,7 @@ private void UpdateMenuItems() { if (this.mainMenuItem == null || this.contextMenuItem == null) return; ITabbedDocument doc = PluginBase.MainForm.CurrentDocument; - Boolean isValid = doc != null && doc.IsEditable && this.IsSupportedLanguage(doc.FileName); + Boolean isValid = doc != null && doc.IsEditable && this.DocumentType != TYPE_UNKNOWN; this.mainMenuItem.Enabled = this.contextMenuItem.Enabled = isValid; } @@ -199,15 +200,6 @@ public void AttachContextMenuItem(ToolStripMenuItem contextMenu) contextMenu.DropDownItems.Insert(6, this.contextMenuItem); } - /// - /// Checks if the language is supported - /// - public Boolean IsSupportedLanguage(String file) - { - String lang = ScintillaControl.Configuration.GetLanguageFromFile(file); - return (lang == "as2" || lang == "as3" || lang == "xml"); - } - /// /// Loads the plugin settings /// @@ -241,7 +233,8 @@ public void SaveSettings() private const int TYPE_AS3 = 0; private const int TYPE_MXML = 1; private const int TYPE_XML = 2; - private const int TYPE_UNKNOWN = 3; + private const int TYPE_CPP = 3; + private const int TYPE_UNKNOWN = 4; /// /// Formats the current document @@ -267,7 +260,7 @@ private void DoFormat(ITabbedDocument doc) { case TYPE_AS3: ASPrettyPrinter asPrinter = new ASPrettyPrinter(true, source); - FormatUtility.configureASPrinter(asPrinter, this.settingObject, PluginBase.Settings.TabWidth); + FormatUtility.configureASPrinter(asPrinter, this.settingObject); String asResultData = asPrinter.print(0); if (asResultData == null) { @@ -284,7 +277,7 @@ private void DoFormat(ITabbedDocument doc) case TYPE_MXML: case TYPE_XML: MXMLPrettyPrinter mxmlPrinter = new MXMLPrettyPrinter(source); - FormatUtility.configureMXMLPrinter(mxmlPrinter, this.settingObject, PluginBase.Settings.TabWidth); + FormatUtility.configureMXMLPrinter(mxmlPrinter, this.settingObject); String mxmlResultData = mxmlPrinter.print(0); if (mxmlResultData == null) { @@ -297,6 +290,27 @@ private void DoFormat(ITabbedDocument doc) doc.SciControl.ConvertEOLs(doc.SciControl.EOLMode); } break; + + case TYPE_CPP: + AStyleInterface asi = new AStyleInterface(); + String optionData = this.GetOptionData(doc.SciControl.ConfigurationLanguage.ToLower()); + String resultData = asi.FormatSource(source, optionData); + if (String.IsNullOrEmpty(resultData)) + { + TraceManager.Add(TextHelper.GetString("Info.CouldNotFormat"), -3); + PluginBase.MainForm.CallCommand("PluginCommand", "ResultsPanel.ShowResults"); + } + else + { + // Remove all empty lines if specified + if (optionData.Contains("--delete-empty-lines")) + { + resultData = Regex.Replace(resultData, @"(\r?\n){3,}", "$1"); + } + doc.SciControl.Text = resultData; + doc.SciControl.ConvertEOLs(doc.SciControl.EOLMode); + } + break; } } catch (Exception) @@ -310,7 +324,31 @@ private void DoFormat(ITabbedDocument doc) } /// - /// + /// Get the options for the formatter based on FD settings or manual command + /// + private String GetOptionData(String language) + { + String optionData; + if (language == "cpp") optionData = this.settingObject.Pref_AStyle_CPP; + else optionData = this.settingObject.Pref_AStyle_Others; + if (String.IsNullOrEmpty(optionData)) + { + Int32 tabSize = PluginBase.Settings.TabWidth; + Boolean useTabs = PluginBase.Settings.UseTabs; + Int32 spaceSize = PluginBase.Settings.IndentSize; + CodingStyle codingStyle = PluginBase.Settings.CodingStyle; + optionData = AStyleInterface.DefaultOptions + " --mode=c"; + if (language != "cpp") optionData += "s"; // --mode=cs + if (useTabs) optionData += " --indent=force-tab=" + tabSize.ToString(); + else optionData += " --indent=spaces=" + spaceSize.ToString(); + if (codingStyle == CodingStyle.BracesAfterLine) optionData += " --style=allman"; + else optionData += " --style=attach"; + } + return optionData; + } + + /// + /// Gets or sets the current position, ignoring whitespace /// public int CurrentPos { @@ -348,28 +386,29 @@ public int CurrentPos } /// - /// + /// Gets the formatting type of the document /// public Int32 DocumentType { get { - var xmls = new List { ".xml" }; ITabbedDocument document = PluginBase.MainForm.CurrentDocument; if (!document.IsEditable) return TYPE_UNKNOWN; String ext = Path.GetExtension(document.FileName).ToLower(); + String lang = document.SciControl.ConfigurationLanguage.ToLower(); if (ASContext.Context.CurrentModel.Context != null && ASContext.Context.CurrentModel.Context.GetType().ToString().Equals("AS3Context.Context")) { if (ext == ".as") return TYPE_AS3; else if (ext == ".mxml") return TYPE_MXML; } - else if (xmls.Contains(ext)) return TYPE_XML; + else if (lang == "xml") return TYPE_XML; + else if (document.SciControl.Lexer == 3) return TYPE_CPP; return TYPE_UNKNOWN; } } /// - /// + /// Compress text for finding correct restore position /// public String CompressText(String originalText) { @@ -380,14 +419,6 @@ public String CompressText(String originalText) return compressedText; } - /// - /// - /// - public bool IsBlankChar(Char ch) - { - return (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); - } - #endregion } diff --git a/External/Plugins/CodeFormatter/Settings.cs b/External/Plugins/CodeFormatter/Settings.cs index 6c0bcd5f1b..6be29a7505 100644 --- a/External/Plugins/CodeFormatter/Settings.cs +++ b/External/Plugins/CodeFormatter/Settings.cs @@ -13,9 +13,8 @@ public class Settings { public const char LineSplitter = '\n'; - /////////////// ActionScript ///////////////////////////////////// + /////////////// AS3 ///////////////////////////////////// - private bool pref_Flex_UseTabs = true; private int pref_AS_SpacesBeforeComma = 0; private int pref_AS_SpacesAfterComma = 1; private int pref_AS_SpacesAroundColons = 0; @@ -52,8 +51,6 @@ public class Settings private bool pref_AS_AlwaysGenerateIndent = true; private bool pref_AS_DontIndentPackageItems = false; private bool pref_AS_LeaveExtraWhitespaceAroundVarDecls = false; - private BraceStyle pref_AS_BraceStyle = BraceStyle.AfterLine; - private bool pref_AS_UseBraceStyle = true; private int pref_AS_SpacesInsideParens = 0; private bool pref_AS_UseGlobalSpacesInsideParens = true; private int pref_AS_AdvancedSpacesInsideArrayDeclBrackets = 1; @@ -136,7 +133,7 @@ public class Settings // private string pref_AS_MetaTagsOnSameLineAsTargetFunction = ""; private string pref_AS_MetaTagsOnSameLineAsTargetProperty = ""; - + ////////////////// MXML /////////////////////////////////////// private int pref_MXML_SpacesAroundEquals = 0; @@ -156,8 +153,6 @@ public class Settings private bool pref_MXML_RequireCDATAForASFormatting = true; private bool pref_MXML_AutoFormatStyle = true; private bool pref_MXML_DoAutoFormat = true; - public int pref_Flex_IndentSize = 4; - public int pref_Flex_TabSize = 4; public bool pref_MXML_KeepRelativeIndentInMultilineComments = false; public int pref_MXML_BlankLinesBeforeComments = 0; public int pref_MXML_BlankLinesAfterSpecificParentTags = 0; @@ -184,20 +179,35 @@ public class Settings private string pref_MXML_ParentTagsWithBlankLinesAfter = ""; private string pref_MXML_SortAttrData = ""; - ////////////////// ActionScript /////////////////////////////////////// + ////////////////// Others /////////////////////////////////////// - [DefaultValue(true)] - [Category("ActionScript")] - [DisplayName("Use Tabs")] - [LocalizedDescription("CodeFormatter.Description.AS.UseTabs")] - public bool Pref_Flex_UseTabs + private string pref_AStyle_CPP = ""; + private string pref_AStyle_Others = ""; + + [DefaultValue("")] + [Category("Others")] + [DisplayName("Manual CPP Options")] + [LocalizedDescription("CodeFormatter.Description.AStyle.OptionsCPP")] + public string Pref_AStyle_CPP { - get { return this.pref_Flex_UseTabs; } - set { this.pref_Flex_UseTabs = value; } + get { return this.pref_AStyle_CPP; } + set { this.pref_AStyle_CPP = value; } } + [DefaultValue("")] + [Category("Others")] + [DisplayName("Manual Options For Others")] + [LocalizedDescription("CodeFormatter.Description.AStyle.OptionsOthers")] + public string Pref_AStyle_Others + { + get { return this.pref_AStyle_Others; } + set { this.pref_AStyle_Others = value; } + } + + ////////////////// AS3 /////////////////////////////////////// + [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Before Comma")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesBeforeComma")] public int Pref_AS_SpacesBeforeComma @@ -207,7 +217,7 @@ public int Pref_AS_SpacesBeforeComma } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces After Comma")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesAfterComma")] public int Pref_AS_SpacesAfterComma @@ -217,7 +227,7 @@ public int Pref_AS_SpacesAfterComma } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Around Colons")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesAroundColons")] public int Pref_AS_SpacesAroundColons @@ -227,7 +237,7 @@ public int Pref_AS_SpacesAroundColons } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Use Global Spaces Around Colons")] [LocalizedDescription("CodeFormatter.Description.AS.UseGlobalSpacesAroundColons")] public bool Pref_AS_UseGlobalSpacesAroundColons @@ -237,7 +247,7 @@ public bool Pref_AS_UseGlobalSpacesAroundColons } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Before Colons")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedSpacesBeforeColons")] public int Pref_AS_AdvancedSpacesBeforeColons @@ -247,7 +257,7 @@ public int Pref_AS_AdvancedSpacesBeforeColons } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces After Colons")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedSpacesAfterColons")] public int Pref_AS_AdvancedSpacesAfterColons @@ -257,7 +267,7 @@ public int Pref_AS_AdvancedSpacesAfterColons } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Blank Lines Before Functions")] [LocalizedDescription("CodeFormatter.Description.AS.BlankLinesBeforeFunctions")] public int Pref_AS_BlankLinesBeforeFunctions @@ -267,7 +277,7 @@ public int Pref_AS_BlankLinesBeforeFunctions } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Blank Lines Before Classes")] [LocalizedDescription("CodeFormatter.Description.AS.BlankLinesBeforeClasses")] public int Pref_AS_BlankLinesBeforeClasses @@ -277,7 +287,7 @@ public int Pref_AS_BlankLinesBeforeClasses } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Blank Lines Before Properties")] [LocalizedDescription("CodeFormatter.Description.AS.BlankLinesBeforeProperties")] public int Pref_AS_BlankLinesBeforeProperties @@ -287,7 +297,7 @@ public int Pref_AS_BlankLinesBeforeProperties } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Blank Lines Before Control Statements")] [LocalizedDescription("CodeFormatter.Description.AS.BlankLinesBeforeControlStatements")] public int Pref_AS_BlankLinesBeforeControlStatements @@ -297,7 +307,7 @@ public int Pref_AS_BlankLinesBeforeControlStatements } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Keep Blank Lines")] [LocalizedDescription("CodeFormatter.Description.AS.KeepBlankLines")] public bool Pref_AS_KeepBlankLines @@ -307,7 +317,7 @@ public bool Pref_AS_KeepBlankLines } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Blank Lines To Keep")] [LocalizedDescription("CodeFormatter.Description.AS.BlankLinesToKeep")] public int Pref_AS_BlankLinesToKeep @@ -317,7 +327,7 @@ public int Pref_AS_BlankLinesToKeep } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Open Brace On New Line")] [LocalizedDescription("CodeFormatter.Description.AS.OpenBraceOnNewLine")] public bool Pref_AS_OpenBraceOnNewLine @@ -327,7 +337,7 @@ public bool Pref_AS_OpenBraceOnNewLine } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Else On New Line")] [LocalizedDescription("CodeFormatter.Description.AS.ElseOnNewLine")] public bool Pref_AS_ElseOnNewLine @@ -337,7 +347,7 @@ public bool Pref_AS_ElseOnNewLine } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Catch On New Line")] [LocalizedDescription("CodeFormatter.Description.AS.CatchOnNewLine")] public bool Pref_AS_CatchOnNewLine @@ -347,7 +357,7 @@ public bool Pref_AS_CatchOnNewLine } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("ElseIf On Same Line")] [LocalizedDescription("CodeFormatter.Description.AS.ElseIfOnSameLine")] public bool Pref_AS_ElseIfOnSameLine @@ -357,7 +367,7 @@ public bool Pref_AS_ElseIfOnSameLine } [DefaultValue(200)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Max Line Length")] [LocalizedDescription("CodeFormatter.Description.AS.MaxLineLength")] public int Pref_AS_MaxLineLength @@ -367,7 +377,7 @@ public int Pref_AS_MaxLineLength } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Around Assignment")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesAroundAssignment")] public int Pref_AS_SpacesAroundAssignment @@ -377,7 +387,7 @@ public int Pref_AS_SpacesAroundAssignment } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Around Symbolic Operator")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesAroundSymbolicOperator")] public int Pref_AS_SpacesAroundSymbolicOperator @@ -387,7 +397,7 @@ public int Pref_AS_SpacesAroundSymbolicOperator } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Keep Single Line Comments On Column One")] [LocalizedDescription("CodeFormatter.Description.AS.KeepSingleLineCommentsOnColumnOne")] public bool Pref_AS_KeepSLCommentsOnColumn1 @@ -397,7 +407,7 @@ public bool Pref_AS_KeepSLCommentsOnColumn1 } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Break Lines Before Comma")] [LocalizedDescription("CodeFormatter.Description.AS.BreakLinesBeforeComma")] public bool Pref_AS_BreakLinesBeforeComma @@ -407,7 +417,7 @@ public bool Pref_AS_BreakLinesBeforeComma } [DefaultValue(WrapType.None)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap Expression Mode")] [LocalizedDescription("CodeFormatter.Description.AS.WrapExpressionMode")] public WrapType Pref_AS_WrapExpressionMode @@ -417,7 +427,7 @@ public WrapType Pref_AS_WrapExpressionMode } [DefaultValue(WrapType.None)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap Method Declaration Mode")] [LocalizedDescription("CodeFormatter.Description.AS.WrapMethodDeclarationMode")] public WrapType Pref_AS_WrapMethodDeclMode @@ -427,7 +437,7 @@ public WrapType Pref_AS_WrapMethodDeclMode } [DefaultValue(WrapType.None)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap Method Call Mode")] [LocalizedDescription("CodeFormatter.Description.AS.WrapMethodCallMode")] public WrapType Pref_AS_WrapMethodCallMode @@ -437,7 +447,7 @@ public WrapType Pref_AS_WrapMethodCallMode } [DefaultValue(WrapType.None)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap Array Declaration Mode")] [LocalizedDescription("CodeFormatter.Description.AS.WrapArrayDeclarationMode")] public WrapType Pref_AS_WrapArrayDeclMode @@ -447,7 +457,7 @@ public WrapType Pref_AS_WrapArrayDeclMode } [DefaultValue(WrapType.DontProcess)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap XML Mode")] [LocalizedDescription("CodeFormatter.Description.AS.WrapXMLMode")] public WrapType Pref_AS_WrapXMLMode @@ -457,7 +467,7 @@ public WrapType Pref_AS_WrapXMLMode } [DefaultValue(WrapIndent.Normal)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap Indent Style")] [LocalizedDescription("CodeFormatter.Description.AS.WrapIndentStyle")] public WrapIndent Pref_AS_WrapIndentStyle @@ -467,7 +477,7 @@ public WrapIndent Pref_AS_WrapIndentStyle } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Collapse Spaces For Adjacent Parens")] [LocalizedDescription("CodeFormatter.Description.AS.CollapseSpacesForAdjacentParens")] public bool Pref_AS_CollapseSpacesForAdjacentParens @@ -477,7 +487,7 @@ public bool Pref_AS_CollapseSpacesForAdjacentParens } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces After Label")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesAfterLabel")] public int Pref_AS_SpacesAfterLabel @@ -487,7 +497,7 @@ public int Pref_AS_SpacesAfterLabel } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Trim Trailing Whitespace")] [LocalizedDescription("CodeFormatter.Description.AS.TrimTrailingWhitespace")] public bool Pref_AS_TrimTrailingWhitespace @@ -497,7 +507,7 @@ public bool Pref_AS_TrimTrailingWhitespace } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Empty Statements On New Line")] [LocalizedDescription("CodeFormatter.Description.AS.PutEmptyStatementsOnNewLine")] public bool Pref_AS_PutEmptyStatementsOnNewLine @@ -507,7 +517,7 @@ public bool Pref_AS_PutEmptyStatementsOnNewLine } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Before Open Control Paren")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesBeforeOpenControlParen")] public int Pref_AS_SpacesBeforeOpenControlParen @@ -517,7 +527,7 @@ public int Pref_AS_SpacesBeforeOpenControlParen } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Always Generate Indent")] [LocalizedDescription("CodeFormatter.Description.AS.AlwaysGenerateIndent")] public bool Pref_AS_AlwaysGenerateIndent @@ -527,7 +537,7 @@ public bool Pref_AS_AlwaysGenerateIndent } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Don't Indent Package Items")] [LocalizedDescription("CodeFormatter.Description.AS.DontIndentPackageItems")] public bool Pref_AS_DontIndentPackageItems @@ -537,7 +547,7 @@ public bool Pref_AS_DontIndentPackageItems } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Leave Extra Whitespace Around Var Declarations")] [LocalizedDescription("CodeFormatter.Description.AS.LeaveExtraWhitespaceAroundVarDeclarations")] public bool Pref_AS_LeaveExtraWhitespaceAroundVarDecls @@ -546,28 +556,8 @@ public bool Pref_AS_LeaveExtraWhitespaceAroundVarDecls set { this.pref_AS_LeaveExtraWhitespaceAroundVarDecls = value; } } - [DefaultValue(BraceStyle.AfterLine)] - [Category("ActionScript")] - [DisplayName("Brace Style")] - [LocalizedDescription("CodeFormatter.Description.AS.BraceStyle")] - public BraceStyle Pref_AS_BraceStyle - { - get { return this.pref_AS_BraceStyle; } - set { this.pref_AS_BraceStyle = value; } - } - - [DefaultValue(true)] - [Category("ActionScript")] - [DisplayName("Use Brace Style")] - [LocalizedDescription("CodeFormatter.Description.AS.UseBraceStyle")] - public bool Pref_AS_UseBraceStyle - { - get { return this.pref_AS_UseBraceStyle; } - set { this.pref_AS_UseBraceStyle = value; } - } - [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Inside Parens")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesInsideParens")] public int Pref_AS_SpacesInsideParens @@ -577,7 +567,7 @@ public int Pref_AS_SpacesInsideParens } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Use Global Spaces Inside Parens")] [LocalizedDescription("CodeFormatter.Description.AS.UseGlobalSpacesInsideParens")] public bool Pref_AS_UseGlobalSpacesInsideParens @@ -587,7 +577,7 @@ public bool Pref_AS_UseGlobalSpacesInsideParens } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Inside Array Declaration Brackets")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedSpacesInsideArrayDeclarationBrackets")] public int Pref_AS_AdvancedSpacesInsideArrayDeclBrackets @@ -597,7 +587,7 @@ public int Pref_AS_AdvancedSpacesInsideArrayDeclBrackets } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Inside Array Reference Brackets")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedSpacesInsideArrayReferenceBrackets")] public int Pref_AS_AdvancedSpacesInsideArrayRefBrackets @@ -607,7 +597,7 @@ public int Pref_AS_AdvancedSpacesInsideArrayRefBrackets } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Inside Literal Braces")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedSpacesInsideLiteralBraces")] public int Pref_AS_AdvancedSpacesInsideLiteralBraces @@ -617,7 +607,7 @@ public int Pref_AS_AdvancedSpacesInsideLiteralBraces } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Inside Parens")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedSpacesInsideParens")] public int Pref_AS_AdvancedSpacesInsideParens @@ -627,7 +617,7 @@ public int Pref_AS_AdvancedSpacesInsideParens } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Use Spaces Around Equals In Optional Parameters")] [LocalizedDescription("CodeFormatter.Description.AS.UseSpacesAroundEqualsInOptionalParameters")] public bool Pref_AS_Tweak_UseSpacesAroundEqualsInOptionalParameters @@ -637,7 +627,7 @@ public bool Pref_AS_Tweak_UseSpacesAroundEqualsInOptionalParameters } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Around Equals In Optional Parameters")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesAroundEqualsInOptionalParameters")] public int Pref_AS_Tweak_SpacesAroundEqualsInOptionalParameters @@ -647,7 +637,7 @@ public int Pref_AS_Tweak_SpacesAroundEqualsInOptionalParameters } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Indent Multiline Comments")] [LocalizedDescription("CodeFormatter.Description.AS.IndentMultilineComments")] public bool Pref_AS_IndentMultilineComments @@ -657,7 +647,7 @@ public bool Pref_AS_IndentMultilineComments } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Blank Lines Before Import Block")] [LocalizedDescription("CodeFormatter.Description.AS.BlankLinesBeforeImportBlock")] public int Pref_AS_BlankLinesBeforeImportBlock @@ -667,7 +657,7 @@ public int Pref_AS_BlankLinesBeforeImportBlock } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Blank Lines At Function Start")] [LocalizedDescription("CodeFormatter.Description.AS.BlankLinesAtFunctionStart")] public int Pref_AS_BlankLinesAtFunctionStart @@ -677,7 +667,7 @@ public int Pref_AS_BlankLinesAtFunctionStart } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Blank Lines At Function End")] [LocalizedDescription("CodeFormatter.Description.AS.BlankLinesAtFunctionEnd")] public int Pref_AS_BlankLinesAtFunctionEnd @@ -687,7 +677,7 @@ public int Pref_AS_BlankLinesAtFunctionEnd } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("While On New Line")] [LocalizedDescription("CodeFormatter.Description.AS.WhileOnNewLine")] public bool Pref_AS_WhileOnNewLine @@ -697,7 +687,7 @@ public bool Pref_AS_WhileOnNewLine } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Around Equals In Metatags")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesAroundEqualsInMetatags")] public int Pref_AS_Tweak_SpacesAroundEqualsInMetatags @@ -707,7 +697,7 @@ public int Pref_AS_Tweak_SpacesAroundEqualsInMetatags } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Use Spaces Around Equals In Metatags")] [LocalizedDescription("CodeFormatter.Description.AS.UseSpacesAroundEqualsInMetatags")] public bool Pref_AS_Tweak_UseSpacesAroundEqualsInMetatags @@ -717,7 +707,7 @@ public bool Pref_AS_Tweak_UseSpacesAroundEqualsInMetatags } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces After Colons In Declarations")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesAfterColonsInDeclarations")] public int Pref_AS_AdvancedSpacesAfterColonsInDeclarations @@ -727,7 +717,7 @@ public int Pref_AS_AdvancedSpacesAfterColonsInDeclarations } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Before Colons In Declarations")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesBeforeColonsInDeclarations")] public int Pref_AS_AdvancedSpacesBeforeColonsInDeclarations @@ -737,7 +727,7 @@ public int Pref_AS_AdvancedSpacesBeforeColonsInDeclarations } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces After Colons In Function Types")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesAfterColonsInFunctionTypes")] public int Pref_AS_AdvancedSpacesAfterColonsInFunctionTypes @@ -747,7 +737,7 @@ public int Pref_AS_AdvancedSpacesAfterColonsInFunctionTypes } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Before Colons In Function Types")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesBeforeColonsInFunctionTypes")] public int Pref_AS_AdvancedSpacesBeforeColonsInFunctionTypes @@ -757,7 +747,7 @@ public int Pref_AS_AdvancedSpacesBeforeColonsInFunctionTypes } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Use Line Comment Wrapping")] [LocalizedDescription("CodeFormatter.Description.AS.UseLineCommentWrapping")] public bool Pref_AS_UseLineCommentWrapping @@ -767,7 +757,7 @@ public bool Pref_AS_UseLineCommentWrapping } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Use Multiline Comment Wrapping")] [LocalizedDescription("CodeFormatter.Description.AS.UseMLCommentWrapping")] public bool Pref_AS_UseMLCommentWrapping @@ -777,7 +767,7 @@ public bool Pref_AS_UseMLCommentWrapping } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Multiline Comment Reflow")] [LocalizedDescription("CodeFormatter.Description.AS.MLCommentReflow")] public bool Pref_AS_MLCommentReflow @@ -787,7 +777,7 @@ public bool Pref_AS_MLCommentReflow } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Doc Comment Reflow")] [LocalizedDescription("CodeFormatter.Description.AS.DocCommentReflow")] public bool Pref_AS_DocCommentReflow @@ -797,7 +787,7 @@ public bool Pref_AS_DocCommentReflow } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Multiline Comment Header On Separate Line")] [LocalizedDescription("CodeFormatter.Description.AS.MLCommentHeaderOnSeparateLine")] public bool Pref_AS_MLCommentHeaderOnSeparateLine @@ -807,7 +797,7 @@ public bool Pref_AS_MLCommentHeaderOnSeparateLine } [DefaultValue(AsteriskMode.AsIs)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Multiline Comment Asterisk Mode")] [LocalizedDescription("CodeFormatter.Description.AS.MLCommentAsteriskMode")] public AsteriskMode Pref_AS_MLCommentAsteriskMode @@ -817,7 +807,7 @@ public AsteriskMode Pref_AS_MLCommentAsteriskMode } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Use Doc Comment Wrapping")] [LocalizedDescription("CodeFormatter.Description.AS.UseDocCommentWrapping")] public bool Pref_AS_UseDocCommentWrapping @@ -827,7 +817,7 @@ public bool Pref_AS_UseDocCommentWrapping } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Doc Comment Hanging Indent Tabs")] [LocalizedDescription("CodeFormatter.Description.AS.DocCommentHangingIndentTabs")] public int Pref_AS_DocCommentHangingIndentTabs @@ -837,7 +827,7 @@ public int Pref_AS_DocCommentHangingIndentTabs } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Doc Comment Keep Blank Lines")] [LocalizedDescription("CodeFormatter.Description.AS.DocCommentKeepBlankLines")] public bool Pref_AS_DocCommentKeepBlankLines @@ -847,7 +837,7 @@ public bool Pref_AS_DocCommentKeepBlankLines } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Multiline Comment Keep Blank Lines")] [LocalizedDescription("CodeFormatter.Description.AS.MLCommentKeepBlankLines")] public bool Pref_AS_MLCommentKeepBlankLines @@ -857,7 +847,7 @@ public bool Pref_AS_MLCommentKeepBlankLines } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Keep Single Line Functions")] [LocalizedDescription("CodeFormatter.Description.AS.LeaveSingleLineFunctions")] public bool Pref_AS_LeaveSingleLineFunctions @@ -867,7 +857,7 @@ public bool Pref_AS_LeaveSingleLineFunctions } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Unindent Expression Terminators")] [LocalizedDescription("CodeFormatter.Description.AS.UnindentExpressionTerminators")] public bool Pref_AS_UnindentExpressionTerminators @@ -877,7 +867,7 @@ public bool Pref_AS_UnindentExpressionTerminators } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("No New Newlines Before Break")] [LocalizedDescription("CodeFormatter.Description.AS.NoNewCRsBeforeBreak")] public bool Pref_AS_NoNewCRsBeforeBreak @@ -887,7 +877,7 @@ public bool Pref_AS_NoNewCRsBeforeBreak } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("No New Newlines Before Continue")] [LocalizedDescription("CodeFormatter.Description.AS.NoNewCRsBeforeContinue")] public bool Pref_AS_NoNewCRsBeforeContinue @@ -897,7 +887,7 @@ public bool Pref_AS_NoNewCRsBeforeContinue } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("No New Newlines Before Return")] [LocalizedDescription("CodeFormatter.Description.AS.NoNewCRsBeforeReturn")] public bool Pref_AS_NoNewCRsBeforeReturn @@ -907,7 +897,7 @@ public bool Pref_AS_NoNewCRsBeforeReturn } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("No New Newlines Before Throw")] [LocalizedDescription("CodeFormatter.Description.AS.NoNewCRsBeforeThrow")] public bool Pref_AS_NoNewCRsBeforeThrow @@ -917,7 +907,7 @@ public bool Pref_AS_NoNewCRsBeforeThrow } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("No New Newlines Before Expression")] [LocalizedDescription("CodeFormatter.Description.AS.NoNewCRsBeforeExpression")] public bool Pref_AS_NoNewCRsBeforeExpression @@ -927,7 +917,7 @@ public bool Pref_AS_NoNewCRsBeforeExpression } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Keep Relative Indent In Doc Comments")] [LocalizedDescription("CodeFormatter.Description.AS.KeepRelativeIndentInDocComments")] public bool Pref_AS_KeepRelativeIndentInDocComments @@ -937,7 +927,7 @@ public bool Pref_AS_KeepRelativeIndentInDocComments } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Tabs In Hanging Indent")] [LocalizedDescription("CodeFormatter.Description.AS.TabsInHangingIndent")] public int Pref_AS_TabsInHangingIndent @@ -947,7 +937,7 @@ public int Pref_AS_TabsInHangingIndent } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Inside Parens In Other Places")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesInsideParensInOtherPlaces")] public int Pref_AS_AdvancedSpacesInsideParensInOtherPlaces @@ -957,7 +947,7 @@ public int Pref_AS_AdvancedSpacesInsideParensInOtherPlaces } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Inside Parens In Parameter Lists")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesInsideParensInParameterLists")] public int Pref_AS_AdvancedSpacesInsideParensInParameterLists @@ -967,7 +957,7 @@ public int Pref_AS_AdvancedSpacesInsideParensInParameterLists } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Inside Parens In Argument Lists")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesInsideParensInArgumentLists")] public int Pref_AS_AdvancedSpacesInsideParensInArgumentLists @@ -977,7 +967,7 @@ public int Pref_AS_AdvancedSpacesInsideParensInArgumentLists } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Before Formal Parameters")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesBeforeFormalParameters")] public int Pref_AS_SpacesBeforeFormalParameters @@ -987,7 +977,7 @@ public int Pref_AS_SpacesBeforeFormalParameters } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Spaces Before Arguments")] [LocalizedDescription("CodeFormatter.Description.AS.SpacesBeforeArguments")] public int Pref_AS_SpacesBeforeArguments @@ -997,7 +987,7 @@ public int Pref_AS_SpacesBeforeArguments } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Use Gnu Brace Indent")] [LocalizedDescription("CodeFormatter.Description.AS.UseGnuBraceIndent")] public bool Pref_AS_UseGnuBraceIndent @@ -1007,7 +997,7 @@ public bool Pref_AS_UseGnuBraceIndent } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Ensure Loops Have Braces")] [LocalizedDescription("CodeFormatter.Description.AS.EnsureLoopsHaveBraces")] public bool Pref_AS_EnsureLoopsHaveBraces @@ -1017,7 +1007,7 @@ public bool Pref_AS_EnsureLoopsHaveBraces } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Add Braces To Loops")] [LocalizedDescription("CodeFormatter.Description.AS.AddBracesToLoops")] public int Pref_AS_AddBracesToLoops @@ -1027,7 +1017,7 @@ public int Pref_AS_AddBracesToLoops } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Ensure Switch Cases Have Braces")] [LocalizedDescription("CodeFormatter.Description.AS.EnsureSwitchCasesHaveBraces")] public bool Pref_AS_EnsureSwitchCasesHaveBraces @@ -1037,7 +1027,7 @@ public bool Pref_AS_EnsureSwitchCasesHaveBraces } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Add Braces To Cases")] [LocalizedDescription("CodeFormatter.Description.AS.AddBracesToCases")] public int Pref_AS_AddBracesToCases @@ -1047,7 +1037,7 @@ public int Pref_AS_AddBracesToCases } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Ensure Conditionals Have Braces")] [LocalizedDescription("CodeFormatter.Description.AS.EnsureConditionalsHaveBraces")] public bool Pref_AS_EnsureConditionalsHaveBraces @@ -1057,7 +1047,7 @@ public bool Pref_AS_EnsureConditionalsHaveBraces } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Add Braces To Conditionals")] [LocalizedDescription("CodeFormatter.Description.AS.AddBracesToConditionals")] public int Pref_AS_AddBracesToConditionals @@ -1067,7 +1057,7 @@ public int Pref_AS_AddBracesToConditionals } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Don't Indent Switch Cases")] [LocalizedDescription("CodeFormatter.Description.AS.DontIndentSwitchCases")] public bool Pref_AS_DontIndentSwitchCases @@ -1077,7 +1067,7 @@ public bool Pref_AS_DontIndentSwitchCases } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Align Declaration Equals")] [LocalizedDescription("CodeFormatter.Description.AS.AlignDeclEquals")] public bool Pref_AS_AlignDeclEquals @@ -1087,7 +1077,7 @@ public bool Pref_AS_AlignDeclEquals } [DefaultValue(DeclAlignMode.Consecutive)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Align Declaration Mode")] [LocalizedDescription("CodeFormatter.Description.AS.AlignDeclMode")] public DeclAlignMode Pref_AS_AlignDeclMode @@ -1097,7 +1087,7 @@ public DeclAlignMode Pref_AS_AlignDeclMode } [DefaultValue(true)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Keep Spaces Before Line Comments")] [LocalizedDescription("CodeFormatter.Description.AS.KeepSpacesBeforeLineComments")] public bool Pref_AS_KeepSpacesBeforeLineComments @@ -1107,7 +1097,7 @@ public bool Pref_AS_KeepSpacesBeforeLineComments } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Align Line Comments At Column")] [LocalizedDescription("CodeFormatter.Description.AS.AlignLineCommentsAtColumn")] public int Pref_AS_AlignLineCommentsAtColumn @@ -1117,7 +1107,7 @@ public int Pref_AS_AlignLineCommentsAtColumn } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Use Global Newline Before Brace")] [LocalizedDescription("CodeFormatter.Description.AS.UseGlobalCRBeforeBrace")] public bool Pref_AS_UseGlobalCRBeforeBrace @@ -1127,7 +1117,7 @@ public bool Pref_AS_UseGlobalCRBeforeBrace } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Newline Before Brace Settings")] [LocalizedDescription("CodeFormatter.Description.AS.CRBeforeBraceSettings")] public int Pref_AS_AdvancedCRBeforeBraceSettings @@ -1137,7 +1127,7 @@ public int Pref_AS_AdvancedCRBeforeBraceSettings } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Newline Before Bindable Function")] [LocalizedDescription("CodeFormatter.Description.AS.NewlineBeforeBindableFunction")] public bool Pref_AS_NewlineBeforeBindableFunction @@ -1147,7 +1137,7 @@ public bool Pref_AS_NewlineBeforeBindableFunction } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Newline Before Bindable Property")] [LocalizedDescription("CodeFormatter.Description.AS.NewlineBeforeBindableProperty")] public bool Pref_AS_NewlineBeforeBindableProperty @@ -1157,7 +1147,7 @@ public bool Pref_AS_NewlineBeforeBindableProperty } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Break Lines Before Arithmetic")] [LocalizedDescription("CodeFormatter.Description.AS.BreakLinesBeforeArithmetic")] public bool Pref_AS_BreakLinesBeforeArithmetic @@ -1167,7 +1157,7 @@ public bool Pref_AS_BreakLinesBeforeArithmetic } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Break Lines Before Logical")] [LocalizedDescription("CodeFormatter.Description.AS.BreakLinesBeforeLogical")] public bool Pref_AS_BreakLinesBeforeLogical @@ -1177,7 +1167,7 @@ public bool Pref_AS_BreakLinesBeforeLogical } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Break Lines Before Assignment")] [LocalizedDescription("CodeFormatter.Description.AS.BreakLinesBeforeAssignment")] public bool Pref_AS_BreakLinesBeforeAssignment @@ -1187,7 +1177,7 @@ public bool Pref_AS_BreakLinesBeforeAssignment } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Use Advanced Wrapping")] [LocalizedDescription("CodeFormatter.Description.AS.UseAdvancedWrapping")] public bool Pref_AS_UseAdvancedWrapping @@ -1197,7 +1187,7 @@ public bool Pref_AS_UseAdvancedWrapping } [DefaultValue(0)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap Elements")] [LocalizedDescription("CodeFormatter.Description.AS.UseAdvancedWrapping")] public int Pref_AS_AdvancedWrappingElements @@ -1207,7 +1197,7 @@ public int Pref_AS_AdvancedWrappingElements } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Enforce Maximum Wrapping")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingEnforceMax")] public bool Pref_AS_AdvancedWrappingEnforceMax @@ -1217,7 +1207,7 @@ public bool Pref_AS_AdvancedWrappingEnforceMax } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap All Arguments")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingAllArgs")] public bool Pref_AS_AdvancedWrappingAllArgs @@ -1227,7 +1217,7 @@ public bool Pref_AS_AdvancedWrappingAllArgs } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap All Parameters")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingAllParms")] public bool Pref_AS_AdvancedWrappingAllParms @@ -1237,7 +1227,7 @@ public bool Pref_AS_AdvancedWrappingAllParms } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap First Argument")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingFirstArg")] public bool Pref_AS_AdvancedWrappingFirstArg @@ -1247,7 +1237,7 @@ public bool Pref_AS_AdvancedWrappingFirstArg } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap First Parameter")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingFirstParm")] public bool Pref_AS_AdvancedWrappingFirstParm @@ -1257,7 +1247,7 @@ public bool Pref_AS_AdvancedWrappingFirstParm } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("WrapFirst Array Item")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingFirstArrayItem")] public bool Pref_AS_AdvancedWrappingFirstArrayItem @@ -1267,7 +1257,7 @@ public bool Pref_AS_AdvancedWrappingFirstArrayItem } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap First Object Item")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingFirstObjectItem")] public bool Pref_AS_AdvancedWrappingFirstObjectItem @@ -1277,7 +1267,7 @@ public bool Pref_AS_AdvancedWrappingFirstObjectItem } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap All Array Items")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingAllArrayItems")] public bool Pref_AS_AdvancedWrappingAllArrayItems @@ -1287,7 +1277,7 @@ public bool Pref_AS_AdvancedWrappingAllArrayItems } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Wrap All Object Items")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingAllObjectItems")] public bool Pref_AS_AdvancedWrappingAllObjectItems @@ -1297,7 +1287,7 @@ public bool Pref_AS_AdvancedWrappingAllObjectItems } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Align Array Items With Wrap")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingAlignArrayItems")] public bool Pref_AS_AdvancedWrappingAlignArrayItems @@ -1307,7 +1297,7 @@ public bool Pref_AS_AdvancedWrappingAlignArrayItems } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Align Object Items With Wrap")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingAlignObjectItems")] public bool Pref_AS_AdvancedWrappingAlignObjectItems @@ -1317,7 +1307,7 @@ public bool Pref_AS_AdvancedWrappingAlignObjectItems } [DefaultValue(1)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Grace Columns With Wrap")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingGraceColumns")] public int Pref_AS_AdvancedWrappingGraceColumns @@ -1327,7 +1317,7 @@ public int Pref_AS_AdvancedWrappingGraceColumns } [DefaultValue(false)] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Preserve Phrases With Wrap")] [LocalizedDescription("CodeFormatter.Description.AS.AdvancedWrappingPreservePhrases")] public bool Pref_AS_AdvancedWrappingPreservePhrases @@ -1337,7 +1327,7 @@ public bool Pref_AS_AdvancedWrappingPreservePhrases } [DefaultValue("")] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Metatags To Keep On Same Line As Target Function")] [LocalizedDescription("CodeFormatter.Description.AS.MetaTagsOnSameLineAsTargetFunction")] public string Pref_AS_MetaTagsOnSameLineAsTargetFunction @@ -1347,7 +1337,7 @@ public string Pref_AS_MetaTagsOnSameLineAsTargetFunction } [DefaultValue("")] - [Category("ActionScript")] + [Category("AS3")] [DisplayName("Metatags To Keep On Same Line As Target Property")] [LocalizedDescription("CodeFormatter.Description.AS.MetaTagsOnSameLineAsTargetProperty")] public string Pref_AS_MetaTagsOnSameLineAsTargetProperty @@ -1546,26 +1536,6 @@ public string Pref_MXML_TagsWithBlankLinesBefore set { this.pref_MXML_TagsWithBlankLinesBefore = value; } } - [DefaultValue(4)] - [Category("MXML")] - [DisplayName("Indent Size")] - [LocalizedDescription("CodeFormatter.Description.MXML.IndentSize")] - public int Pref_Flex_IndentSize - { - get { return this.pref_Flex_IndentSize; } - set { this.pref_Flex_IndentSize = value; } - } - - [DefaultValue(4)] - [Category("MXML")] - [DisplayName("Tab Size")] - [LocalizedDescription("CodeFormatter.Description.MXML.TabSize")] - public int Pref_Flex_TabSize - { - get { return this.pref_Flex_TabSize; } - set { this.pref_Flex_TabSize = value; } - } - [DefaultValue(false)] [Category("MXML")] [DisplayName("Keep Relative Indent In Multiline Comments")] @@ -2285,13 +2255,6 @@ public enum WrapMode None = 53 } - public enum BraceStyle - { - OnLine = 4, - AfterLine = 5, - Inherit = 100 - } - public enum WrapType { None = 1, diff --git a/External/Plugins/CodeFormatter/Utilities/FormatUtility.cs b/External/Plugins/CodeFormatter/Utilities/FormatUtility.cs index 78999b78c5..5e0fe19528 100644 --- a/External/Plugins/CodeFormatter/Utilities/FormatUtility.cs +++ b/External/Plugins/CodeFormatter/Utilities/FormatUtility.cs @@ -2,20 +2,23 @@ using System.Collections.Generic; using CodeFormatter.Handlers; using CodeFormatter.Preferences; +using PluginCore; namespace CodeFormatter.Utilities { public class FormatUtility { - public static void configureMXMLPrinter(MXMLPrettyPrinter printer, Settings settings, int tabSize) + public static void configureMXMLPrinter(MXMLPrettyPrinter printer, Settings settings) { + Boolean useTabs = PluginBase.Settings.UseTabs; + Int32 tabSize = PluginBase.Settings.TabWidth; + Int32 spaceSize = PluginBase.Settings.IndentSize; printer.setAttrSortMode((Int32)settings.Pref_MXML_SortAttrMode); - printer.setIndentAmount(settings.Pref_Flex_IndentSize); - printer.setUseTabs(settings.Pref_Flex_UseTabs); - printer.setTabSize(settings.Pref_Flex_TabSize); + printer.setIndentAmount(spaceSize); + printer.setUseTabs(useTabs); + printer.setTabSize(tabSize); printer.setTabSize(tabSize); printer.setIndentAmount(tabSize); - //printer.setManualAttrSortData(settings.Pref_MXML_SortAttrData.Split('\n')); printer.setSortOtherAttrs(settings.Pref_MXML_SortExtraAttrs); printer.setSpacesAroundEquals(settings.Pref_MXML_SpacesAroundEquals); printer.setSpacesBeforeEmptyTagEnd(settings.Pref_MXML_SpacesBeforeEmptyTagEnd); @@ -35,7 +38,7 @@ public static void configureMXMLPrinter(MXMLPrettyPrinter printer, Settings sett printer.setCDATAIndentTabs(settings.Pref_MXML_ScriptCDataIndentTabs); printer.setScriptIndentTabs(settings.Pref_MXML_ScriptIndentTabs); printer.setBlankLinesAtCDataStart(settings.Pref_MXML_BlankLinesAtCDataStart); - printer.setBlankLinesAtCDataEnd(settings.Pref_MXML_BlankLinesAtCDataStart); //TODO: change pref constant if I split them on the pref page + printer.setBlankLinesAtCDataEnd(settings.Pref_MXML_BlankLinesAtCDataStart); printer.setKeepCDataOnSameLine(settings.Pref_MXML_KeepScriptCDataOnSameLine); printer.setMaxLineLength(settings.Pref_MXML_MaxLineLength); printer.setWrapMode((Int32)settings.Pref_MXML_AttrWrapMode); @@ -116,12 +119,16 @@ public static void configureMXMLPrinter(MXMLPrettyPrinter printer, Settings sett } } printer.setPrivateTags(tagList); - configureASPrinter(printer.getASPrinter(), settings, tabSize); + configureASPrinter(printer.getASPrinter(), settings); printer.getASPrinter().setBlankLinesBeforeImports(0); //special case: we only want blank lines before imports in .as files } - public static void configureASPrinter(ASPrettyPrinter printer, Settings settings, int tabSize) + public static void configureASPrinter(ASPrettyPrinter printer, Settings settings) { + Boolean useTabs = PluginBase.Settings.UseTabs; + Int32 tabSize = PluginBase.Settings.TabWidth; + Int32 spaceSize = PluginBase.Settings.IndentSize; + Int32 braceStyle = PluginBase.Settings.CodingStyle == CodingStyle.BracesOnLine ? 4 : 5; printer.setIndentMultilineComments(settings.Pref_AS_IndentMultilineComments); printer.setBlankLinesBeforeFunction(settings.Pref_AS_BlankLinesBeforeFunctions); printer.setBlankLinesBeforeClass(settings.Pref_AS_BlankLinesBeforeClasses); @@ -130,8 +137,8 @@ public static void configureASPrinter(ASPrettyPrinter printer, Settings settings printer.setBlankLinesBeforeProperties(settings.Pref_AS_BlankLinesBeforeProperties); printer.setBlankLinesToStartFunctions(settings.Pref_AS_BlankLinesAtFunctionStart); printer.setBlankLinesToEndFunctions(settings.Pref_AS_BlankLinesAtFunctionEnd); - printer.setBlockIndent(tabSize); - printer.setUseTabs(settings.Pref_Flex_UseTabs); + printer.setBlockIndent(spaceSize); + printer.setUseTabs(useTabs); printer.setTabSize(tabSize); printer.setSpacesAfterComma(settings.Pref_AS_SpacesAfterComma); printer.setSpacesBeforeComma(settings.Pref_AS_SpacesBeforeComma); @@ -139,8 +146,8 @@ public static void configureASPrinter(ASPrettyPrinter printer, Settings settings printer.setCRBeforeCatch(settings.Pref_AS_CatchOnNewLine); printer.setCRBeforeElse(settings.Pref_AS_ElseOnNewLine); printer.setCRBeforeWhile(settings.Pref_AS_WhileOnNewLine); - printer.setUseBraceStyleSetting(settings.Pref_AS_UseBraceStyle); - printer.setBraceStyleSetting((Int32)settings.Pref_AS_BraceStyle); + printer.setUseBraceStyleSetting(true); + printer.setBraceStyleSetting(braceStyle); printer.setKeepBlankLines(settings.Pref_AS_KeepBlankLines); printer.setBlankLinesToKeep(settings.Pref_AS_BlankLinesToKeep); printer.setSpacesAroundAssignment(settings.Pref_AS_SpacesAroundAssignment); diff --git a/External/Tools/AStyle/LICENSE.txt b/External/Tools/AStyle/LICENSE.txt new file mode 100644 index 0000000000..bcc3a2c920 --- /dev/null +++ b/External/Tools/AStyle/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 by Jim Pattee . + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/External/Tools/AStyle/README.txt b/External/Tools/AStyle/README.txt new file mode 100644 index 0000000000..56ee8b7e04 --- /dev/null +++ b/External/Tools/AStyle/README.txt @@ -0,0 +1,9 @@ +Instructions for using Artistic Style are included in the 'doc' directory. + +The file 'install.html' contains instructions for compiling and +installing Artistic Style. + +The file 'astyle.html' contains information on using Artistic Style. + +The files 'news.html' and 'notes.html' contain information on changes +made to the various releases. diff --git a/External/Tools/AStyle/VERSION.txt b/External/Tools/AStyle/VERSION.txt new file mode 100644 index 0000000000..fa447db737 --- /dev/null +++ b/External/Tools/AStyle/VERSION.txt @@ -0,0 +1 @@ +SVN r493 + extra builds removed \ No newline at end of file diff --git a/External/Tools/AStyle/build/vs2015/AStyleDll.sln b/External/Tools/AStyle/build/vs2015/AStyleDll.sln new file mode 100644 index 0000000000..406a54161a --- /dev/null +++ b/External/Tools/AStyle/build/vs2015/AStyleDll.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AStyleDll", "AStyleDll\AStyleDll.vcxproj", "{8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + Static|x64 = Static|x64 + Static|x86 = Static|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}.Debug|x64.ActiveCfg = Debug|x64 + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}.Debug|x64.Build.0 = Debug|x64 + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}.Debug|x86.ActiveCfg = Debug|Win32 + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}.Debug|x86.Build.0 = Debug|Win32 + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}.Release|x64.ActiveCfg = Release|x64 + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}.Release|x64.Build.0 = Release|x64 + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}.Release|x86.ActiveCfg = Release|Win32 + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}.Release|x86.Build.0 = Release|Win32 + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}.Static|x64.ActiveCfg = Static|x64 + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}.Static|x64.Build.0 = Static|x64 + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}.Static|x86.ActiveCfg = Static|Win32 + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF}.Static|x86.Build.0 = Static|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/External/Tools/AStyle/build/vs2015/AStyleDll/AStyleDll.vcxproj b/External/Tools/AStyle/build/vs2015/AStyleDll/AStyleDll.vcxproj new file mode 100644 index 0000000000..ced661e65b --- /dev/null +++ b/External/Tools/AStyle/build/vs2015/AStyleDll/AStyleDll.vcxproj @@ -0,0 +1,272 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Static + Win32 + + + Static + x64 + + + + {8ECC1E60-2E56-4ACD-96D0-D7F7B11BCEBF} + Win32Proj + AStyleDll + 8.1 + + + + DynamicLibrary + true + v140 + NotSet + + + DynamicLibrary + false + v140 + true + NotSet + + + DynamicLibrary + false + v140 + true + NotSet + + + DynamicLibrary + true + v140 + NotSet + + + DynamicLibrary + false + v140 + true + NotSet + + + DynamicLibrary + false + v140 + true + NotSet + + + + + + + + + + + + + + + + + + + + + + + + + + + false + $(SolutionDir)debug\ + AStyle-2.06d + + + false + $(SolutionDir)$(Platform)\debug\ + AStyle-2.06d + + + false + $(SolutionDir)bin\ + AStyle + + + false + $(SolutionDir)binstatic\ + AStyle-2.06 + + + false + $(SolutionDir)$(Platform)\bin\ + AStyle64 + + + false + $(SolutionDir)$(Platform)\binstatic\ + AStyle-2.06 + + + + + + Level4 + Disabled + _DEBUG;ASTYLE_LIB + false + ProgramDatabase + + + Windows + /EXPORT:AStyleMain=_AStyleMain%4016 +/EXPORT:AStyleGetVersion=_AStyleGetVersion%400 + + + + + + + Level4 + Disabled + _DEBUG;ASTYLE_LIB + false + ProgramDatabase + + + Windows + + + + + Level4 + + + MaxSpeed + true + true + NDEBUG;_HAS_EXCEPTIONS=0;ASTYLE_LIB + false + AnySuitable + Speed + true + false + + + Windows + No + true + true + UseLinkTimeCodeGeneration + /EXPORT:AStyleMain=_AStyleMain%4016 +/EXPORT:AStyleGetVersion=_AStyleGetVersion%400 + + + + + Level4 + + + MaxSpeed + true + true + NDEBUG;_HAS_EXCEPTIONS=0;ASTYLE_LIB + false + AnySuitable + Speed + true + MultiThreaded + false + + + Windows + No + true + true + UseLinkTimeCodeGeneration + /EXPORT:AStyleMain=_AStyleMain%4016 +/EXPORT:AStyleGetVersion=_AStyleGetVersion%400 + + + + + Level4 + + + MaxSpeed + true + true + NDEBUG;_HAS_EXCEPTIONS=0;ASTYLE_LIB + false + AnySuitable + Speed + true + false + + + Windows + No + true + true + UseLinkTimeCodeGeneration + + + + + Level4 + + + MaxSpeed + true + true + NDEBUG;_HAS_EXCEPTIONS=0;ASTYLE_LIB + false + AnySuitable + Speed + true + MultiThreaded + false + + + Windows + No + true + true + UseLinkTimeCodeGeneration + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/External/Tools/AStyle/build/vs2015/AStyleDll/AStyleDll.vcxproj.filters b/External/Tools/AStyle/build/vs2015/AStyleDll/AStyleDll.vcxproj.filters new file mode 100644 index 0000000000..165b88c638 --- /dev/null +++ b/External/Tools/AStyle/build/vs2015/AStyleDll/AStyleDll.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/External/Tools/AStyle/doc/astyle.html b/External/Tools/AStyle/doc/astyle.html new file mode 100644 index 0000000000..c4849cfa47 --- /dev/null +++ b/External/Tools/AStyle/doc/astyle.html @@ -0,0 +1,2395 @@ + + + + + + Artistic Style + + + + + + + + + + + + + + + +

Artistic Style 2.06

+ +

+ A Free, Fast, and Small Automatic Formatter
+ for C, C++, C++/CLI, Objective‑C, C#, and Java Source Code +

+ +

Contents

+ +

+ General Information +

+

+ Quick Start +

+

+ Usage +

+

+ Options +

+

+ Options File +

+

+ Disable Formatting +

+

+ Bracket Style Options +

+

+ default bracket style    + style=allman    + style=java    + style=kr    + style=stroustrup    + style=whitesmith    + style=vtk    + style=banner    + style=gnu    + style=linux    + style=horstmann    + style=1tbs    + style=google    + style=pico    + style=lisp    +

+

+ Tab Options +

+

+ default indent    + indent=spaces    + indent=tab    + indent=force‑tab    + --indent=force‑tab‑x    +

+

+ Bracket Modify Options +

+

+ attach‑namespaces    + attach‑classes    + attach‑inlines    + attach‑extern‑c    +

+

+ Indentation Options +

+

+ indent‑classes    + indent‑modifiers    + indent‑switches    + indent‑cases    + indent‑namespaces    + indent‑labels    + indent‑preproc‑block    + indent‑preproc‑define    + indent‑preproc‑cond    + indent‑col1‑comments    + min‑conditional‑indent    + max‑instatement‑indent    +

+

+ Padding Options +

+

+ break‑blocks    + break‑blocks=all    + pad‑oper    + pad‑comma    + pad‑paren    + pad‑paren‑out    + pad‑first‑paren‑out    + pad‑paren‑in    + pad‑header    + unpad‑paren    + delete‑empty‑lines    + fill‑empty‑lines    + align‑pointer    + align‑reference    +

+

+ Formatting Options +

+

+ break‑closing‑brackets    + break‑elseifs    + add‑brackets    + add‑one‑line‑brackets    + remove‑brackets    + keep‑one‑line‑blocks    + keep‑one‑line‑statements    + convert‑tabs    + close‑templates    + remove‑comment‑prefix    + max‑code‑length    + break‑after‑logical    + mode    +

+

+ Objective‑C Options +

+

+ pad‑method‑prefix    + unpad‑method‑prefix    + pad‑return‑type    + unpad‑return‑type    + align‑method‑colon    + pad‑method‑colon    +

+

+ Other Options    +

+

+ suffix    suffix=none    + recursive    + dry-run    + exclude    + ignore‑exclude‑errors    + ignore‑exclude‑errors‑x    + errors‑to‑stdout    + preserve‑date    + verbose    + formatted    + quiet    + lineend    +

+

+ Command Line Only +

+

+ options    + options=none    + ascii    + version    + help    + html    + html=    +

+

+   +

+
+ + + +

General Information

+ +

Line Endings

+ +

+ Line endings in the formatted file will be the same as the input file. If there are mixed line endings the most + frequent occurrence will be used. There is also an option to specify or change the line endings. +

+ +

File Type

+ +

+ Artistic Style will determine the file type from the file extension. The extension ".java" indicates a Java file, + and ".cs" indicates a C# file. Everything else is a C type file (C, C++, C++/CLI, or Objective-C). If you are + using a non-standard file extension for Java or C#, use one of the --mode= options. +

+ +

Wildcards and Recursion

+ +

+ Artistic Style can process directories recursively. Wildcards (such as "*.cpp" or "*.c??") are processed internally. + If a shell is used it should pass the wildcards to Artistic Style instead of resolving them first. For Linux use + double quotes around paths whose file name contains wildcards. For Windows use double quotes around paths whose + file name contains spaces. The recursive option in the + Other Options section contains information on recursive processing. +

+ +

File Names

+ +

+ When a file is formatted, the newly indented file retains the original file name. A copy of the original file + is created with an .orig appended to the original file name. (This can be set to + a different string by the option --suffix=, or suppressed altogether by the options -n + or --suffix=none). Thus, after indenting SourceFile.cpp the indented file will + be named SourceFile.cpp, while the original pre-indented file will be renamed to SourceFile.cpp.orig. +

+ +

Internationalization

+ +

+ Artistic Style has been internationalized to process files and directories in any language. +

+

+ It has also been translated into several languages. The translation to use is determined from the User Locale + for Windows and the LANG environment variable for other systems. The translation will be done automatically from + these settings. If no translation is available it will default to English. There is an ascii option to use English + instead of the system language. +

+

+ The source code for the translations is at the end of ASLocalizer.cpp in the form of an English‑Translation + pair. If you make corrections to a translation, send the source as a bug report and it will be included in the + next release. +

+

+ To add a new language, add a new translation class to ASLocalizer.h. Add the English‑Translation pair to + the constructor in ASLocalizer.cpp. Update the WinLangCode array and add the language code to the function setTranslationClass(). + The ASLocalizer.cpp program contains comments that give web pages for obtaining the LCIDs and language codes. + Send the source code as a bug report and it will be included in the next release. +

+ +

Other Considerations

+ +

+ The names of special characters used in programming vary by region. The terminology used by Artistic Style, + followed by other common names, is: +

+
+ brackets { } ‑ also called braces, curly brackets, or curly braces.
+ parens ( ) ‑ also called parentheses, brackets, round brackets, circle brackets, or soft brackets.
+ block parens [ ] ‑ also called brackets, square brackets, closed brackets, or hard brackets.
+ angle brackets < > ‑ also called brackets, pointy brackets, triangular brackets, diamond brackets, tuples, + or chevrons. +
+

+ Artistic Style can format standard class library statements such as Open GL, wxWidgets, Qt, and MFC. +

+

+ Embedded assembler language is formatted correctly. This includes extended assembly and Microsoft specific assembler + lines and blocks. +

+

+ Artistic Style can format embedded SQL statements. The SQL formatting will be maintained as long as the standard + hanging indent format is used. If the "exec sql" statement is indented more than the following statements, the + SQL will be aligned in a single column. +

+

+ Unicode files encoded as UTF‑16, both big and little endian, will be formatted. The files must begin with + a byte order mark (BOM) to be recognized. Files encoded as UTF‑32 will be rejected. Some compilers do not + support these encodings. These files can be converted to UTF‑8 encoding with the program "iconv". There + are Linux and Windows versions available (the Windows version does not seem to work for all encodings). A sample + command line is "iconv ‑f  UTF‑16 ‑t UTF‑8 < filein.cpp > fileout.cpp. Visual + Studio can convert the files from the "File > Advanced Save Options" menu. Then select encoding "Unicode (UTF‑8 + with signature) - Codepage 65001". There are other development environments and text editors, such as SciTE, that + can convert files to UTF‑8. +

+

+ Embedded statements that are multiple-line and are NOT in a C-type format, such as Python, are usually mal-formatted + (a C-type format has blocks enclosed by brackets and statements terminated by a semi-colon). Macros that define + functions may cause the following code to be mal-formatted because the macro is missing the brackets and semi-colons + from the definition. If you have source code with these types of statements, exclude them with the + exclude=#### option described in the Other Options section. +

+

+   +

+
+ + + +

Quick Start

+ +

+ If you have never used Artistic Style there are a couple of ways to start. +

+

+ One is to run it with no options at all. This will use the default bracket + style, 4 spaces per indent, and no formatting changes. This will break the brackets for one + line blocks and will break one line statements. To change this use the option + keep-one-line-blocks and/or + keep-one-line-statements described in the + Formatting Options section +

+

+ Another way is to use one of the bracket styles described in the Bracket Style + Options section. Select one with a bracket formatting style you like. If no indentation option is set, + the default option of 4 spaces will be used. These options also break one line blocks and one line statements + as described above. +

+

+ Once you are familiar with the options you can customize the format to your personal preference. +

+

+   +

+
+ + + +

Usage

+ +

+ Artistic style is a console program that receives information from the command line. The format of the command + line is: +

+
astyle  [OPTIONS]  SourceFile1  SourceFile2  SourceFile3  [ . . . ]
+
+

+ The block parens [ ] indicate that more than one option or more than one file name can be entered. They are NOT + actually included in the command. For the options format see the following Options section. +

+
+

+   Example to format a single file: +

+
astyle  --style=allman  /home/user/project/foo.cpp
+
+

+   Example to format all .cpp and .h files recursively: +

+
astyle  --style=allman --recursive  /home/user/project/*.cpp  /home/user/project/*.h
+
+
+

+ Another option will format a single file and change the name: +

+
astyle  [OPTIONS] < OriginalSourceFile > BeautifiedSourceFile
+
+

+ This option can be used to display the formatted file without updating: +

+
astyle  [OPTIONS] < OriginalSourceFile | less
+
+

+ The < and > characters are used + to redirect the files into standard input (cin) and out of standard output (cout) - don't forget them! With this + option only one file at a time can be formatted. Wildcards are not recognized, there are no console messages, + and a backup is not created. On Windows the output will always have Windows line ends. +

+

+   +

+
+ + + +

Options

+ +

+ Not specifying any options will result in the default bracket style, + 4 spaces per indent, and no formatting changes. +

+

+ Options may be written in two different ways. +

+ +

Long options

+ +

+ These options start with '--', and must be written one at a time.
+ (Example: '--style=allman --indent=spaces=4') +

+ +

Short Options

+ +

+ These options start with a single '-', and may be concatenated together.
+ (Example: '-bps4' is the same as writing '-b -p -s4'.) +

+

+   +

+
+ + + +

Options File

+ +

+ An OPTIONAL default options file may be used to supplement or replace the command line options.  +

+
    +
  • The command line options have precedence. If there is a conflict between a command line option and an option in + the default options file, the command line option will be used. +
  • +
  • Artistic Style looks for this file in the following locations (in order): +
      +
    1. the file indicated by the --options= command line option;
    2. +
    3. the file and directory indicated by the environment variable ARTISTIC_STYLE_OPTIONS (if it exists);
    4. +
    5. the file named .astylerc in the directory pointed to by the HOME environment variable (e.g. "$HOME/.astylerc" + on Linux); +
    6. +
    7. the file named astylerc in the directory pointed to by the USERPROFILE environment variable (e.g. "%USERPROFILE%\astylerc" + on Windows). +
    8. +
    +
  • +
  • This option file lookup can be disabled by specifying --options=none on the command line.
  • +
  • Options may be set apart by new-lines, tabs, commas, or spaces.
  • +
  • Long options in the options file may be written without the preceding '--'.
  • +
  • Lines within the options file that begin with '#' are considered line-comments.
  • +
+

+ Example of a default options file: +

+
+
# this line is a comment
+--style=allman      # this is a line-end comment
+# long options can be written without the preceding '--'
+indent-switches     # cannot do this on the command line
+# short options must have the preceding '-'
+-t -p
+# short options can be concatenated together
+-M60Ucv
+
+

+   +

+ +
+ + + +

+ Disable Formatting +

+ +

+ Formatting and indenting can be disabled with comment tags inserted in the source code. +

+ +

+ Disable Block +

+ +

+ Blocks of code can be disabled using "off" and "on" tags. The tags are included in the source + file as comments. The comment may be a C comment (/* ... */) or a C++ line comment (//). The tag must be included + in a single line comment. If the comment exceeds one line the indent tag will be ignored. Additional information + can be included with the tag. +

+

+ The beginning tag is "*INDENT-OFF*" and the ending tag is "*INDENT-ON*". + They may be used anywhere in the program with the following condition; parsing is partially disabled between the + tags. Disabling partial statements may result in incorrect formatting after the ending tag. If this happens expand + the tags to include additional code. +

+
+

+ The following retains the format of a preprocessor define: +

+
// *INDENT-OFF*
+#define FOO_DECLARE_int32_(name) \
+        FOO_API_ extern ::Int32 FOO_FLAG(name)
+// *INDENT-ON*
+
+ +

+ Disable Line +

+ +

+ Artistic Style cannot always determine the usage of symbols with more than one meaning. For example an asterisk + (*) can be multiplication, a pointer, or a pointer dereference. The "&" and "&&" + symbols are a similar + problem. +

+

+ If a symbol is being padded incorrectly, padding it manually may fix the problem. If it is still being + padded incorrectly, then disabling the formatting may be necessary. To avoid having to use the "disable block" + tags above, a single line disable is available. +

+

+ A line-end comment tag "*NOPAD* will disable the "pad-oper", "align-pointer", and "align-reference" + options. Parsing does NOT stop and all other formatting will be applied to the line. The tag applies to the + one line only. +

+
+

+ The following prevents the operator padding from changing: +

+
size_t foo = (unsigned int) -1;  // *NOPAD*
+
+

+   +

+
+ + + +

Bracket Style Options

+ +

+ Bracket Style options define the bracket style to use. All options default to 4 spaces per indent, indented with + spaces. + By default, none of the styles indent namespaces. Other indentations are indicated in the individual style + description. All options will break the brackets for one line blocks and will break one line statements. To change + this + use the option keep-one-line-blocks and/or + keep-one-line-statements described in the Formatting Options section +

+

+   +

+

+ default bracket style
+ If no bracket style is requested, the default bracket style will be used. The opening brackets are not changed + and the closing brackets will be broken from the preceding line. There are a few exceptions to this. +

+

+   +

+

+ --style=allman / --style=bsd / --style=break / -A1
+ Allman style uses broken brackets. +

+
+
int Foo(bool isBar)
+{
+    if (isBar)
+    {
+        bar();
+        return 1;
+    }
+    else
+        return 0;
+}
+
+
+

+   +

+

+ --style=java / --style=attach / -A2
+ Java style uses attached brackets. +

+
+
int Foo(bool isBar) {
+    if (isBar) {
+        bar();
+        return 1;
+    } else
+        return 0;
+}
+
+
+

+   +

+

+ --style=kr / --style=k&r / --style=k/r / -A3
+ Kernighan & Ritchie style uses linux brackets. Opening brackets are broken from namespaces, classes, and function + definitions. Brackets are attached to everything else including statements within a function, arrays, structs, + and enums. +

+

+ Using the k&r option may cause problems because of the &. This can be resolved by enclosing the k&r + in quotes (e.g. ‑‑style="k&r") or by using one of the alternates ‑‑style=kr or ‑‑style=k/r. +

+
+
int Foo(bool isBar)
+{
+    if (isBar) {
+        bar();
+        return 1;
+    } else
+        return 0;
+}
+
+
+

+   +

+

+ --style=stroustrup / -A4
+ Stroustrup style uses stroustrup brackets. Brackets are broken from function definitions only. Brackets are attached + to everything else including namespaces, classes, and statements within a function, arrays, structs, and enums. + This style frequently is used with an indent of 5 spaces. +

+
+
int Foo(bool isBar)
+{
+    if (isBar) {
+        bar();
+        return 1;
+    } else
+        return 0;
+}
+
+
+

+   +

+

+ --style=whitesmith / -A5
+ Whitesmith style uses broken, indented brackets. Switch blocks and class blocks are indented to prevent a 'hanging + indent' with following case statements and C++ class modifiers (public, private, protected).  +

+
+
int Foo(bool isBar)
+    {
+    if (isBar)
+        {
+        bar();
+        return 1;
+        }
+    else
+        return 0;
+    }
+
+
+

+   +

+

+ --style=vtk / -A15
+ VTK (Visualization Toolkit) style uses broken, indented brackets, except for the opening bracket. Switch blocks + are indented to prevent a 'hanging indent' with following case statements.  +

+
+
int Foo(bool isBar)
+{
+    if (isBar)
+        {
+        bar();
+        return 1;
+        }
+    else
+        return 0;
+}
+
+
+

+   +

+

+ --style=banner / -A6
+ Banner style uses attached, indented brackets. Switch blocks and class blocks are indented to prevent a 'hanging + indent' with following case statements and C++ class modifiers (public, private, protected).  +

+
+
int Foo(bool isBar) {
+    if (isBar) {
+        bar();
+        return 1;
+        }
+    else
+        return 0;
+    }
+
+
+

+   +

+

+ --style=gnu / -A7
+ GNU style uses broken brackets and indented blocks. This style frequently is used with + an indent of 2 spaces. +

+

+ Extra indentation is added to blocks within a function. The opening bracket for namespaces, classes, + and functions is not indented. +

+
+
int Foo(bool isBar)
+{
+    if (isBar)
+        {
+            bar();
+            return 1;
+        }
+    else
+        return 0;
+}
+
+
+

+   +

+

+ --style=linux / --style=knf / -A8
+ Linux style uses linux brackets. Opening brackets are broken from namespace, class, and function + definitions. Brackets are attached to everything else including statements within a function, arrays, structs, + and enums. Minimum conditional indent is one-half indent. If you want a different minimum conditional + indent use the K&R style instead. This style works best with a large indent. It frequently is used with an + indent of 8 spaces. +

+

+ Also known as Kernel Normal Form (KNF) style, this is the style used in the Linux kernel. +

+
+
int Foo(bool isBar)
+{
+        if (isFoo) {
+                bar();
+                return 1;
+        } else
+                return 0;
+}
+
+
+

+   +

+

+ --style=horstmann / -A9
+ Horstmann style uses run-in brackets. Brackets are broken and allow run-in statements. + Switches are indented to allow a run-in to the opening switch block. This style frequently is used with an indent + of 3 spaces. +

+
+
int Foo(bool isBar)
+{   if (isBar)
+    {   bar();
+        return 1;
+    }
+    else
+        return 0;
+}
+
+
+

+   +

+

+ --style=1tbs / --style=otbs / -A10
+ "One True Brace Style" uses linux brackets and adds brackets to unbracketed one line conditional + statements. Opening brackets are broken from namespaces, classes, and function definitions. Brackets are attached + to everything else including statements within a function, arrays, structs, and enums.  +

+

+ In the following example brackets have been added to the "return 0;" statement. The option + ‑‑add‑one‑line‑brackets can also be used with this style. +

+
+
int Foo(bool isBar)
+{
+    if (isFoo) {
+        bar();
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+
+

+   +

+

+ --style=google / -A14
+ Google style uses attached brackets and indented class access modifiers. See the indent-modifiers + option for an example of the indented modifiers format. This style frequently is used with an indent of 2 spaces. +

+
+
int Foo(bool isBar) {
+    if (isBar) {
+        bar();
+        return 1;
+    } else
+        return 0;
+}
+
+
+

+   +

+

+ --style=pico / -A11
+ Pico style uses run-in brackets and attached closing brackets. Opening brackets are broken + and allow run-in statements. The closing bracket is attached to the last line in the block. Switches are indented + to allow a run-in to the opening switch block. The style implies keep-one-line-blocks and keep-one-line-statements. + If add-brackets is used they will be added as one-line brackets. This style frequently is used with an indent + of 2 spaces. +

+
+
int Foo(bool isBar)
+{   if (isBar)
+    {   bar();
+        return 1; }
+    else
+        return 0; }
+
+
+

+   +

+

+ --style=lisp / --style=python / -A12
+ Lisp style uses attached opening and closing brackets. Opening brackets are attached at the + end of the statement. The closing bracket is attached to the last line in the block. The style implies keep-one-line-statements + but NOT keep-one-line-blocks. This style does not support one-line brackets. If add-one-line-brackets is used + they will be added as multiple-line brackets. +

+
+
int Foo(bool isBar) {
+    if (isBar) {
+        bar()
+        return 1; }
+    else
+        return 0; }
+
+
+

+   +

+
+ + + +

Tab Options

+ +

+ The following examples show whitespace characters. A space is indicated with a . (dot), a tab + is indicated by a > (greater than). +

+

+ default indent
+ If no indentation option is set, the default option of 4 spaces will be used (e.g. -s4 + --indent=spaces=4 + ). +

+
+

+ with default values: +

+
void Foo() {
+....if (isBar1
+............&& isBar2)    // indent of this line can be changed with min-conditional-indent
+........bar();
+}
+
+
+

+   +

+

+ --indent=spaces / --indent=spaces=# / -s#
+ Indent using # spaces per indent (e.g. -s3 --indent=spaces=3 + ). # must be between 2 and 20. Not specifying # will result in a default of + 4 spaces per indent. +

+
+

+ with indent=spaces=3 +

+
void Foo() {
+...if (isBar1
+.........&& isBar2)    // indent of this line can be changed with min-conditional-indent
+......bar();
+}
+
+
+

+   +

+

+ --indent=tab / --indent=tab=# / -t / -t#
+ Indent using tabs for indentation, and spaces for continuation line alignment. This ensures that + the code is displayed correctly  regardless of the viewer’s tab size. Treat each indent as # spaces + (e.g. -t6 / --indent=tab=6). + # must be between 2 and 20. If no # is set, treats indents as 4 spaces. +

+
+

+ with indent=tab: +

+
void Foo() {
+>   if (isBar1
+>   ........&& isBar2)    // indent of this line can be changed with min-conditional-indent
+>   >   bar();
+}
+
+

+ with style=linux, indent=tab=8: +

+
void Foo()
+{
+>       if (isBar1
+>       ....&& isBar2)    // indent of this line can NOT be changed with style=linux
+>       >       bar();
+}
+
+
+

+   +

+

+ --indent=force-tab / --indent=force-tab=# / -T / -T#
+ Indent using all tab characters, if possible. If a continuation line is not an even number of + tabs, spaces will be added at the end. Treat each tab as # spaces (e.g. -T6 + / --indent=force-tab=6). # must be between + 2 and 20. If no # is set, treats tabs as 4 spaces. +

+
+

+ with indent=force-tab: +

+
void Foo() {
+>   if (isBar1
+>   >   >   && isBar2)    // indent of this line can be changed with min-conditional-indent
+>   >   bar();
+}
+
+
+

+   +

+

+ --indent=force-tab-x / --indent=force-tab-x=# / -xT / -xT# +
+ This force-tab option allows the tab length to be set to a length that is different than the indent length. This + may cause the indentation to be a mix of both tabs and spaces. Tabs will be used to indent, if + possible. If a tab indent cannot be used, spaces will be used instead. +

+

+ This option sets the tab length. Treat each tab as # spaces (e.g. -xT6 + / --indent=force-tab-x=6). # must be between + 2 and 20. If no # is set, treats tabs as 8 spaces. To change the indent length from the default + of 4 spaces the option "indent=force-tab" must also be used. +

+
+

+ with indent=force-tab-x (default tab length of 8 and default indent length of 4): +

+
void Foo() {
+....if (isBar1
+>       ....&& isBar2)    // indent of this line can be changed with min-conditional-indent
+>       bar();
+}
+
+
+

+   +

+
+ + + +

Bracket Modify Options

+ +

+ --attach-namespaces / -xn
+ Attach brackets to a namespace statement. This is done regardless of the bracket style being used. +

+
+

+ the bracket is always attached to a namespace statement: +

+
namespace FooName {
+...
+}
+
+
+

+   +

+

+ --attach-classes / -xc
+ Attach brackets to a class statement. This is done regardless of the bracket style being used. +

+
+

+ the bracket is always attached to a class statement: +

+
class FooClass {
+...
+};
+
+
+

+   +

+

+ --attach-inlines / -xl
+ Attach brackets to class and struct inline function definitions. This is not done for run-in type brackets (Horstmann + and Pico styles). This option is effective for C++ files only. +

+
+

+ all brackets are always attached to class and struct inline function definitions: +

+
class FooClass
+{
+    void Foo() {
+    ...
+    }
+};
+
+
+

+   +

+

+ --attach-extern-c / -xk
+ Attach brackets to a bracketed extern "C" statement. This is done regardless of the bracket style being used. + This option is effective for C++ files only. +

+

+ An extern "C" statement that is part of a function definition is formatted according to the requested bracket + style. Bracketed extern "C" statements are unaffected by the bracket style and this option is the only way to + change them. +

+
+

+ this option attaches brackets to a bracketed extern "C" statement: +

+
#ifdef __cplusplus
+extern "C" {
+#endif
+
+

+ but function definitions are formatted according to the requested bracket style: +

+
extern "C" EXPORT void STDCALL Foo()
+{}
+
+
+

+   +

+
+ + + +

Indentation Options

+ +

+ --indent-classes / -C
+ Indent 'class' and 'struct' blocks so that the entire block is indented. The struct + blocks are indented only if an access modifier, 'public:', 'protected:' or 'private:', + is declared somewhere in the struct. This option is effective for C++ files only. +

+
+
class Foo
+{
+public:
+    Foo();
+    virtual ~Foo();
+};
+
+

+ becomes: +

+
class Foo
+{
+    public:
+        Foo();
+        virtual ~Foo();
+};
+
+
+

+   +

+

+ --indent-modifiers / -xG
+ Indent 'class' and 'struct' access modifiers, 'public:', 'protected:' + and 'private:', one half indent. The rest of the class is not indented. This option is effective + for C++ files only. If used with indent‑classes this option will be ignored. +

+
+
class Foo
+{
+public:
+    Foo();
+    virtual ~Foo();
+};
+
+

+ becomes: +

+
class Foo
+{
+  public:
+    Foo();
+    virtual ~Foo();
+};
+
+
+

+   +

+

+ --indent-switches / -S
+ Indent 'switch' blocks so that the 'case X:' statements are indented in the switch + block. The entire case block is indented. +

+
+
switch (foo)
+{
+case 1:
+    a += 1;
+    break;
+
+case 2:
+{
+    a += 2;
+    break;
+}
+}
+
+

+ becomes: +

+
switch (foo)
+{
+    case 1:
+        a += 1;
+        break;
+
+    case 2:
+    {
+        a += 2;
+        break;
+    }
+}
+
+
+

+   +

+

+ --indent-cases / -K
+ Indent 'case X:' blocks from the 'case X:' headers. Case statements not enclosed in + blocks are NOT indented. +

+
+
switch (foo)
+{
+    case 1:
+        a += 1;
+        break;
+
+    case 2:
+    {
+        a += 2;
+        break;
+    }
+}
+
+

+ becomes: +

+
switch (foo)
+{
+    case 1:
+        a += 1;
+        break;
+
+    case 2:
+        {
+            a += 2;
+            break;
+        }
+}
+
+
+

+   +

+

+ --indent-namespaces / -N
+ Add extra indentation to namespace blocks. This option has no effect on Java files. +

+
+
namespace foospace
+{
+class Foo
+{
+    public:
+        Foo();
+        virtual ~Foo();
+};
+}
+
+

+ becomes: +

+
namespace foospace
+{
+    class Foo
+    {
+        public:
+            Foo();
+            virtual ~Foo();
+    };
+}
+
+
+

+   +

+

+ --indent-labels / -L
+ Add extra indentation to labels so they appear 1 indent less than the current indentation, rather than being flushed + to the left (the default). +

+
+
void Foo() {
+    while (isFoo) {
+        if (isFoo)
+            goto error;
+        ...
+error:
+        ...
+        }
+}
+
+

+ becomes (with indented 'error:'): +

+
void Foo() {
+    while (isFoo) {
+        if (isFoo)
+            goto error;
+        ... 
+    error:
+        ...
+        }
+}
+
+
+

+   +

+ +

+ --indent-preproc-block / -xW
+ Indent preprocessor blocks at bracket level zero, and immediately within a namespace. There are restrictions on + what will be indented. Blocks within methods, classes, arrays, etc, will not be indented. Blocks containing brackets + or multi-line define statements will not be indented. Without this option the preprocessor block is not indented. +

+
+
#ifdef _WIN32
+#include <windows.h>
+#ifndef NO_EXPORT
+#define EXPORT
+#endif
+#endif
+
+

+ becomes: +

+
#ifdef _WIN32
+    #include <windows.h>
+    #ifndef NO_EXPORT
+        #define EXPORT
+    #endif
+#endif
+
+
+

+   +

+

+ --indent-preproc-define / -w
+ Indent multi-line preprocessor definitions ending with a backslash. Should be used with --convert-tabs for proper + results. Does a pretty good job, but cannot perform miracles in obfuscated preprocessor definitions. Without this + option the preprocessor statements remain unchanged. +

+
+
#define Is_Bar(arg,a,b) \
+(Is_Foo((arg), (a)) \
+|| Is_Foo((arg), (b)))
+
+

+ becomes: +

+
#define Is_Bar(arg,a,b) \
+    (Is_Foo((arg), (a)) \
+     || Is_Foo((arg), (b)))
+
+
+

+   +

+

+ --indent-preproc-cond / -xw
+ Indent preprocessor conditional statements to the same level as the source code. +

+
+
        isFoo = true;
+#ifdef UNICODE
+        text = wideBuff;
+#else
+        text = buff;
+#endif
+

+ becomes: +

+
        isFoo = true;
+        #ifdef UNICODE
+        text = wideBuff;
+        #else
+        text = buff;
+        #endif
+
+
+

+   +

+

+ --indent-col1-comments / -Y
+ Indent C++ comments beginning in column one. By default C++ comments beginning in column one are + assumed to be commented‑out code and not indented. This option will allow the comments to be indented with + the code. +

+
+
void Foo()\n"
+{
+// comment
+    if (isFoo)
+        bar();
+}
+
+

+ becomes: +

+
void Foo()\n"
+{
+    // comment
+    if (isFoo)
+        bar();
+}
+
+
+

+   +

+

+ --min-conditional-indent=# / -m#
+ Set the minimal indent that is added when a header is built of multiple lines. This indent helps to easily separate + the header from the command statements that follow. The value for # + indicates a number of indents and is a minimum value. The indent may be greater to align with + the data on the previous line.
+ The valid values are:
+ 0 - no minimal indent. The lines will be aligned with the paren on the preceding line.
+ 1 - indent at least one additional indent.
+ 2 - indent at least two additional indents.
+ 3 - indent at least one-half an additional indent. This is intended for large indents (e.g. 8).
+ The default value is 2, two additional indents. +

+
+
// default setting makes this non-bracketed code clear
+if (a < b
+        || c > d)
+    foo++;
+
+// but creates an exaggerated indent in this bracketed code
+if (a < b
+        || c > d)
+{
+    foo++;
+}
+
+

+ becomes (when setting --min-conditional-indent=0): +

+
// setting makes this non-bracketed code less clear
+if (a < b
+    || c > d)
+    foo++;
+
+// but makes this bracketed code clearer
+if (a < b
+    || c > d)
+{
+    foo++;
+}
+
+
+

+   +

+

+ --max-instatement-indent=# / -M#
+ Set the  maximum of # spaces to indent a continuation line. The + # indicates a number of columns and must not be less than 40 nor greater than 120. + If no value is set, the default value of 40 will be + used. This option will prevent continuation lines from + extending too far to the right. Setting a larger value will allow the code to be extended further to the right. +

+
+
fooArray[] = { red,
+         green,
+         blue };
+
+fooFunction(barArg1,
+         barArg2,
+         barArg3);
+
+

+ becomes (with larger value): +

+
fooArray[] = { red,
+               green,
+               blue };
+
+fooFunction(barArg1,
+            barArg2,
+            barArg3);
+
+
+

+   +

+
+ + + +

Padding Options

+ +

+ --break-blocks / -f
+ Pad empty lines around header blocks (e.g. 'if', 'for', 'while'...). +

+
+
isFoo = true;
+if (isFoo) {
+    bar();
+} else {
+    anotherBar();
+}
+isBar = false;
+
+

+ becomes: +

+
isFoo = true;
+
+if (isFoo) {
+    bar();
+} else {
+    anotherBar();
+}
+
+isBar = false;
+
+
+

+   +

+

+ --break-blocks=all / -F
+ Pad empty lines around header blocks (e.g. 'if', 'for', 'while'...). Treat + closing header blocks (e.g. 'else', 'catch') as stand-alone blocks. +

+
+
isFoo = true;
+if (isFoo) {
+    bar();
+} else {
+    anotherBar();
+}
+isBar = false;
+
+

+ becomes: +

+
isFoo = true;
+
+if (isFoo) {
+    bar();
+
+} else {
+    anotherBar();
+}
+
+isBar = false;
+
+
+

+   +

+

+ --pad-oper / -p
+ Insert space padding around operators. This will also pad commas. Any end of line comments will remain in the + original column, if possible. Note that there is no option to unpad. Once padded, they stay padded. +

+
+
if (foo==2)
+    a=bar((b-c)*a,d--);
+
+

+ becomes: +

+
if (foo == 2)
+    a = bar((b - c) * a, d--);
+
+
+

+   +

+

+ --pad-comma / -xg
+ Insert space padding after commas. This is not needed if pad-oper is used. Any end of line comments will remain + in the original column, if possible. Note that there is no option to unpad. Once padded, they stay padded. +

+
+
if (isFoo(a,b)
+    bar(a,b);
+
+

+ becomes: +

+
if (isFoo(a, b)
+    bar(a, b);
+
+
+

+   +

+

+ --pad-paren / -P +
+ Insert space padding around parenthesis on both the outside and the inside. + Any end of line comments will remain in the original column, if possible. +

+
+
if (isFoo((a+2), b))
+    bar(a, b);
+
+

+ becomes: +

+
if ( isFoo ( ( a+2 ), b ) )
+    bar ( a, b );
+
+
+

+   +

+

+ --pad-paren-out / -d +
+ Insert space padding around parenthesis on the outside only. Parentheses that are empty will + not be padded. Any end of line comments will remain in the original column, if possible. This can be used with + unpad-paren below to remove unwanted spaces. +

+
+
if (isFoo((a+2), b))
+    bar(a, b);
+
+

+ becomes: +

+
if (isFoo ( (a+2), b) )
+    bar (a, b);
+
+
+

+   +

+

+ --pad-first-paren-out / -xd +
+ Insert space padding around the first parenthesis in a series on the outside + only. Parentheses that are empty will not be padded. Any end of line comments will remain in the original column, + if possible. This can be used with unpad-paren below to remove unwanted spaces. If used with pad‑paren or + pad‑paren‑out, this option will be ignored. If used with pad‑paren‑in, the result will + be the same as pad‑paren. +

+
+
if (isFoo((a+2), b))
+    bar(a, b);
+
+

+ becomes: +

+
if (isFoo ((a+2), b))
+    bar (a, b);
+
+
+

+   +

+

+ --pad-paren-in / -D +
+ Insert space padding around parenthesis on the inside only. Any end of line comments will remain + in the original column, if possible. This can be used with unpad-paren below to remove unwanted spaces. +

+
+
if (isFoo((a+2), b))
+    bar(a, b);
+
+

+ becomes: +

+
if ( isFoo( ( a+2 ), b ) )
+    bar( a, b );
+
+
+

+   +

+

+ --pad-header / -H +
+ Insert space padding between a header (e.g. 'if', 'for', 'while'...) + and the following paren. Any end of line comments will remain in the original column, if possible. This can + be used with unpad-paren to remove unwanted spaces. +

+
+
if(isFoo((a+2), b))
+    bar(a, b);
+

+ becomes: +

+
if (isFoo((a+2), b))
+    bar(a, b);
+
+
+

+   +

+

+ --unpad-paren / -U +
+ Remove extra space padding around parenthesis on the inside and outside. Any end of line comments will remain + in the original column, if possible. This option can be used in combination with the paren padding options pad‑paren, + pad‑paren‑out, pad‑paren‑in, and pad‑header + above. Only padding that has not been requested by other options will be removed. +

+

+ For example, if a source has parens padded on both the inside and outside, and you want inside only. You need + to use unpad-paren to remove the outside padding, and pad‑paren‑in to retain + the inside padding. Using only pad‑paren‑in would not remove the outside padding. +

+
+
if ( isFoo( ( a+2 ), b ) )
+    bar ( a, b );
+
+

+ becomes (with no padding option requested): +

+
if(isFoo((a+2), b))
+    bar(a, b);
+
+
+

+   +

+

+ --delete-empty-lines / -xe
+ Delete empty lines within a function or method. Empty lines outside of functions or methods are NOT deleted. If + used with break-blocks or break-blocks=all it will delete all lines EXCEPT the lines added by the break-blocks + options. +

+
+
void Foo()
+{
+
+    foo1 = 1;
+
+    foo2 = 2;
+
+}
+
+

+ becomes: +

+
void Foo()
+{
+    foo1 = 1;
+    foo2 = 2;
+}
+
+
+

+   +

+

+ --fill-empty-lines / -E
+ Fill empty lines with the white space of the previous line. +

+

+   +

+

+ --align-pointer=type   / -k1
+ --align-pointer=middle / -k2
+ --align-pointer=name   / -k3 +

+ Attach a pointer or reference operator (*, &, or ^) to either the variable type (left) or variable name (right), + or place it between the type and name (middle). The spacing between the type and name will be preserved, if possible. + This option is for C/C++, C++/CLI, and C# files. To format references separately use the following align-reference + option. +

+
+
char* foo1;
+char & foo2;
+String ^s1;
+

+ becomes (with align-pointer=type): +

+
char* foo1;
+char& foo2;
+String^ s1;
+
+
+
char* foo1;
+char & foo2;
+String ^s1;
+

+ becomes (with align-pointer=middle): +

+
char * foo1;
+char & foo2;
+String ^ s1;
+
+
+
char* foo1;
+char & foo2;
+String ^s1;
+

+ becomes (with align-pointer=name): +

+
char *foo1;
+char &foo2;
+String ^s1;
+
+

+   +

+

+ --align-reference=none   / -W0
+ --align-reference=type   / -W1
+ --align-reference=middle / -W2
+ --align-reference=name   / -W3 +

+ This option will align references separate from pointers. Pointers are not changed by this option. If pointers + and references are to be aligned the same, use the previous align-pointer option. The option align-reference=none + will not change the reference alignment. The other options are the same as for align-pointer. This option is for + C/C++, C++/CLI, and C# files. +

+
+
char &foo1;
+

+ becomes (with align-reference=type): +

+
char& foo1;
+
+
+
char& foo2;
+

+ becomes (with align-reference=middle): +

+
char & foo2;
+
+
+
char& foo3;
+

+ becomes (with align-reference=name): +

+
char &foo3;
+
+

+   +

+
+ + + +

Formatting Options

+ +

+ --break-closing-brackets / -y +
+ When used with --style=java, --style=kr, --style=stroustrup, --style=linux, or --style=1tbs, this breaks closing + headers (e.g. 'else', 'catch', ...) from their immediately preceding closing brackets. Closing header brackets + are always broken with the other styles. +

+
+
void Foo(bool isFoo) {
+    if (isFoo) {
+        bar();
+    } else {
+        anotherBar();
+    }
+}
+
+

+ becomes (a broken 'else'): +

+
void Foo(bool isFoo) {
+    if (isFoo) {
+        bar();
+    }
+    else {
+        anotherBar();
+    }
+}
+
+
+

+   +

+

+ --break-elseifs / -e
+ Break "else if" header combinations into separate lines. This option has no effect if keep-one-line-statements + is used, the "else if" statements will remain as they are. +

+

+ If this option is NOT used, "else if" header combinations will be placed on a single line. +

+
+
if (isFoo) {
+    bar();
+}
+else if (isFoo1()) {
+    bar1();
+}
+else if (isFoo2()) {
+    bar2;
+}
+
+

+ becomes: +

+
if (isFoo) {
+    bar();
+}
+else
+    if (isFoo1()) {
+        bar1();
+    }
+    else
+        if (isFoo2()) {
+            bar2();
+        }
+
+
+

+   +

+

+ --add-brackets / -j +
+ Add brackets to unbracketed one line conditional statements (e.g. 'if', 'for', + 'while'...). The statement must be on a single line. The brackets will be added according to + the currently requested predefined style or bracket type. If no style or bracket type is requested the brackets + will be attached. If --add-one-line-brackets is also used the result will be one line brackets. +

+
+
if (isFoo)
+    isFoo = false;
+
+

+ becomes: +

+
if (isFoo) {
+    isFoo = false;
+}
+
+
+

+   +

+

+ --add-one-line-brackets / -J +
+ Add one line brackets to unbracketed one line conditional statements (e.g. 'if', 'for', + 'while'...). The statement must be on a single line. The option implies --keep-one-line-blocks and + will not break the one line blocks. +

+
+
if (isFoo)
+    isFoo = false;
+
+

+ becomes: +

+
if (isFoo)
+    { isFoo = false; }
+
+
+

+   +

+

+ --remove-brackets / -xj
+ Remove brackets from conditional statements (e.g. 'if', 'for', 'while'...). + The statement must be a single statement on a single line. If --add-brackets or --add-one-line-brackets is also + used the result will be to add brackets. Brackets will not be removed from "One True Brace Style", --style=1tbs. +

+
+
if (isFoo)
+{
+    isFoo = false;
+}
+

+ becomes: +

+
if (isFoo)
+    isFoo = false;
+
+
+

+   +

+

+ --keep-one-line-blocks / -O +
+ Don't break one-line blocks. +

+
+
if (isFoo)
+{ isFoo = false; cout << isFoo << endl; }
+
+

+ remains unchanged. +

+
+

+   +

+

+ --keep-one-line-statements / -o +
+ Don't break complex statements and multiple statements residing on a single line. +

+
+
if (isFoo)
+{
+    isFoo = false; cout << isFoo << endl;
+}
+
+

+ remains unchanged. +

+
if (isFoo) DoBar();
+
+

+ remains unchanged. +

+
+

+   +

+

+ --convert-tabs / -c
+ Converts tabs into spaces in the non-indentation part of the + line. The number of spaces inserted will maintain the spacing of the tab. The current setting for spaces per tab + is used. It may not produce the expected results if convert-tabs is used when changing spaces per tab. Tabs are + not replaced in quotes. +

+

+   +

+

+ --close-templates / -xy
+ Closes whitespace in the angle brackets of template definitions. Closing the ending angle brackets is now allowed + by the C++11 standard. Be sure your compiler supports this before making the changes. +

+
+
Stack< int,List< int > > stack1;
+

+ becomes: +

+
Stack<int,List<int>> stack1;
+
+

+   +

+

+ --remove-comment-prefix / -xp
+ Remove the preceding '*' in a multi-line comment that begins a line. A trailing '*', if present, is also removed. + Text that is less than one indent is indented to one indent. Text greater than one indent is not changed. Multi-line + comments that begin a line but without the preceding '*' are indented to one indent for consistency. This can + slightly modify the indentation of commented out blocks of code. Lines containing all '*' are left unchanged. + Extra spacing is removed from the comment close '*/'. +

+
+
/*
+ * comment line 1
+ * comment line 2
+ */
+

+ becomes: +

+
/*
+    comment line 1
+    comment line 2
+*/
+
+

+   +

+

+ --max-code-length=#   / -xC# +
+ --break-after-logical / -xL

+ The option max‑code‑length will break a line if the code exceeds # + characters. The valid values are 50 thru 200. Lines without logical conditionals will break on a logical conditional + (||, &&, ...), comma, paren, semicolon, or space. +

+

+ Some code will not be broken, such as comments, quotes, and arrays. If used with keep‑one‑line‑blocks + or add-one-line-brackets the blocks will NOT be broken. If used with keep‑one‑line‑statements + the statements will be broken at a semicolon if the line goes over the maximum length. If there is no available + break point within the max code length, the line will be broken at the first available break point after the max + code length. +

+

+ By default logical conditionals will be placed first on the new line. The option break‑after‑logical + will cause the logical conditionals to be placed last on the previous line. This option has no effect without + max‑code‑length. +

+
+
if (thisVariable1 == thatVariable1 || thisVariable2 == thatVariable2 || thisVariable3 == thatVariable3)
+    bar();
+

+ becomes: +

+
if (thisVariable1 == thatVariable1
+        || thisVariable2 == thatVariable2
+        || thisVariable3 == thatVariable3)
+    bar();
+

+ becomes (with break‑after‑logical): +

+
if (thisVariable1 == thatVariable1 ||
+        thisVariable2 == thatVariable2 ||
+        thisVariable3 == thatVariable3)
+    bar();
+
+

+   +

+

+ --mode=c
+ --mode=cs
+ --mode=java
+ Indent a C type, C#, or Java file. C type files are C, C++, C++/CLI, and Objective-C. The option is usually + set from the file extension for each file. You can override the setting with this entry. It will be used for all + files regardless of the file extension. It allows the formatter to identify language specific syntax such as C++ + classes, templates, and keywords. +

+

+   +

+
+ + + +

Objective‑C Options

+ +

+ These options are effective for Objective‑C files only. The paren padding options will still apply to the + Objective-C method prefix and return type unless overridden by the following options. +

+

+ Because of the longer indents sometimes needed for Objective‑C, the option "max-instatement-indent" may + need to be increased. If you are not getting the paren and square bracket alignment you want try increasing this + value. The option is described in the "Indentation Options" section. +

+

+ --pad-method-prefix / -xQ
+ Insert space padding after the '-' or '+' Objective‑C method prefix. This will add exactly + one space. Any additional spaces will be deleted. This option takes precedence over the pad-paren options. +

+
+
-(void)foo1;
++(void)foo2;
+

+ becomes: +

+
- (void)foo1;
++ (void)foo2;
+
+

+   +

+

+ --unpad-method-prefix / -xR
+ Remove all space padding after the '-' or '+' Objective‑C method prefix.  + This option will be ignored if used with pad‑method‑prefix. It takes precedence over the pad-paren + options. +

+
+
- (void)foo1;
++ (void)foo2;
+

+ becomes: +

+
-(void)foo1;
++(void)foo2;
+
+

+   +

+

+ --pad-return-type / -xq
+ Insert space padding after the Objective‑C return type. This will add exactly one + space. Any additional spaces will be deleted. This option takes precedence over the pad-paren options. +

+
+
-(void)foo1;
++(void)foo2;
+

+ becomes: +

+
-(void) foo1;
++(void) foo2;
+
+

+   +

+

+ --unpad-return-type / -xr
+ Remove all space padding after the Objective‑C return type. This option + will be ignored if used with pad‑return‑type. It takes precedence over the pad-paren options. +

+
+
-(void) foo1;
++(void) foo2;
+

+ becomes: +

+
-(void)foo1;
++(void)foo2;
+
+

+   +

+

+ --align-method-colon / -xM
+ Align the colons in Objective‑C method declarations. +

+
+
-(void)deleteKey:(id)key
+    atIndex:(int)index
+    ofNode:(Node*)node;
+

+ becomes: +

+
-(void)deleteKey:(id)key
+         atIndex:(int)index
+          ofNode:(Node*)node;
+
+

+   +

+

+ --pad-method-colon=none   / -xP0
+ --pad-method-colon=all    / -xP1
+ --pad-method-colon=after  / -xP2
+ --pad-method-colon=before / -xP3 +

+ Add or remove space padding before or after the colons in an Objective‑C method call. These options will + pad exactly one space. Any additional spaces will be deleted. +

+
+

+ with pad-method-colon=none: +

+
[node insertKey:key];
+

+ with pad-method-colon=all: +

+
[node insertKey : key];
+

+ with pad-method-colon=after: +

+
[node insertKey: key];
+

+ with pad-method-colon=before: +

+
[node insertKey :key];
+
+

+   +

+
+ + + +

Other Options

+ +

+ These are non-formatting options available for the command-line. They can also be included in an options file. +

+ +

+ --suffix=####
+ Append the suffix #### instead of '.orig' to original file name (e.g. --suffix=.bak). + If this is to be a file extension, the dot '.' must be included. Otherwise the suffix will be appended to the + current file extension. +

+

+ --suffix=none / -n
+ Do not retain a backup of the original file. The original file is purged after it is formatted. +

+

+ --recursive / -r / -R
+ For each directory in the command line, process all subdirectories recursively. When using the recursive option + the file name statement should contain a wildcard. Linux users should place the file path and name in double quotes + so the shell will not resolve the wildcards (e.g. "$HOME/src/*.cpp"). Windows users should place the file path + and name in double quotes if the path or name contains spaces. +

+

+ --dry-run
+ Perform a trial run with no changes made to the files. The report will be output as usual. +

+

+ --exclude=####
+ Specify a file or sub directory #### to be excluded from processing. +

+

+ Excludes are matched from the end of the file path. An exclude option of "templates" will exclude ALL directories + named "templates". An exclude option of "cpp/templates" will exclude ALL "cpp/templates" directories. You may + proceed backwards in the directory tree to exclude only the required directories. +

+

+ Specific files may be excluded in the same manner. An exclude option of "default.cpp" will exclude ALL files named + "default.cpp". An exclude option of "python/default.cpp" will exclude ALL files named "default.cpp" contained + in a "python" subdirectory. You may proceed backwards in the directory tree to exclude only the required files. +

+

+ Wildcards are NOT allowed. There may be more than one exclude statement. The file path and name may be placed + in double quotes (e.g. ‑‑exclude="foo bar.cpp"). +

+

+ --ignore-exclude-errors / -i
+ Allow processing to continue if there are errors in the "exclude=###" options.
+ This option lets the excludes for several projects be entered in a single option file. This option may be placed + in the same option file as the excludes. It will display the unmatched excludes. The following option will not + display the unmatched excludes. +

+

+ --ignore-exclude-errors-x / -xi
+ Allow processing to continue if there are errors in the "exclude=###" options.
+ This option lets the excludes for several projects be entered in a single option file. This option may be placed + in the same option file as the excludes. It will NOT display the unmatched excludes. The preceding option will + display the unmatched excludes.
+

+

+ --errors-to-stdout / -X
+ Print errors to standard-output rather than to standard-error.
+ This option should be helpful for systems/shells that do not have a separate output to standard-error, such as + in Windows95. +

+

+ --preserve-date / -Z
+ Preserve the original file's date and time modified. The time modified will be changed a few micro seconds to + force the changed files to compile. This option is not effective if redirection is used to rename the input file. +

+

+ --verbose / -v
+ Verbose display mode. Display optional information, such as release number, date, and statistical data. +

+

+ --formatted / -Q
+ Formatted files display mode. Display only the files that have been formatted. Do not display files that + are unchanged. +

+

+ --quiet / -q
+ Quiet display mode. Suppress all output except error messages. +

+

+ --lineend=windows / -z1
+ --lineend=linux   / -z2
+ --lineend=macold  / -z3 +

+ Force use of the specified line end style. Valid options are windows (CRLF), linux (LF), and macold (CR). MacOld + style is the format for Mac OS 9 and earlier. OS X uses the Linux style. If one of these options + is not used the line ends will be determined automatically from the input file. +

+

+ When redirection is used on Windows the output will always have Windows line ends. This option + will be ignored. +

+

+   +

+
+ + + +

Command Line Only

+ +

These options are available for the command-line only. They are NOT available in an options file.

+

+ --options=####
+ Specify an options file #### to read and use. It must contain a file path for the file. This will allow the file + name to be changed from astylerc or .astylerc. +

+

+ --options=none
+ Disable the default options file. Only the command-line parameters will be used. +

+

+ --ascii / -I
+ The displayed output will be ascii characters only. The text will be displayed in English and numbers will not + be formatted. The short option must be by itself, it cannot be concatenated with other options. +

+

+ --version / -V
+ Print version number and quit. The short option must be by itself, it cannot be concatenated with other options. +

+

+ --help / -h / -?
+ Print a help message and quit. The short option must be by itself, it cannot be concatenated with other options. +

+

+ --html / -!
+ Open the HTML help + file "astyle.html" in the default browser and quit. The short option must be by itself, it + cannot be concatenated with other options. The documentation must be installed in the standard install path (/usr/share/doc/astyle/html + for Linux or %PROGRAMFILES%\AStyle\doc for Windows). If installed to a different path use html=###. +

+

+ --html=####
+ Open a HTML help file in the default browser using the file path #### and quit. A HTML file other than "astyle.help" + may be specified. The path may include a directory path and a file name, or a file name only (e.g. html=install.html). + If only a file name is used it is assumed to be in the standard install path (/usr/share/doc/astyle/html + for Linux or %PROGRAMFILES%\AStyle\doc for Windows). In both cases the file name must include the html extension. + File paths containing spaces must be enclosed in quotes. +

+

+ On Linux the HTML file is opened using the script "xdg-open" from the install package "xdg-utils". This should + be installed + by default on most distributions. +

+

+ Any HTML file can be opened by this option. The files you are likely to need are astyle.html (the default), install.html, + and index.html. +

+

+   +

+
+ +

+ + + +

+ +

+   +

+

+   +

+ + + + + diff --git a/External/Tools/AStyle/doc/favicon.ico b/External/Tools/AStyle/doc/favicon.ico new file mode 100644 index 0000000000..0de820b57d Binary files /dev/null and b/External/Tools/AStyle/doc/favicon.ico differ diff --git a/External/Tools/AStyle/doc/index.html b/External/Tools/AStyle/doc/index.html new file mode 100644 index 0000000000..039976240b --- /dev/null +++ b/External/Tools/AStyle/doc/index.html @@ -0,0 +1,230 @@ + + + + + + Artistic Style - Index + + + + + + + + + + +

Artistic Style 2.06

+ +

+ A Free, Fast, and Small Automatic Formatter
+ for C, C++, C++/CLI, Objective‑C, C#, and Java Source Code +

+ +
+ + + + + + + + + + + + + +
+ Project Page:http://astyle.sourceforge.net/
+ SourceForge:http://sourceforge.net/projects/astyle/
+
+ +

+   +

+

+ Artistic Style is a source code indenter, formatter, and beautifier for the C, C++, C++/CLI, Objective‑C, + C# and Java programming languages. +

+

+ When indenting source code, we as programmers have a tendency to use both spaces and tab characters to create + the wanted indentation. Moreover, some editors by default insert spaces instead of tabs when pressing the tab + key, and other editors (Emacs for example) have the ability to "pretty up" lines by automatically setting up the + white space before the code on the line, possibly inserting spaces in a code that up to now used only tabs for + indentation. +

+

+ Since the NUMBER of space characters showed on screen for each tab character in the source code changes between + editors (unless the user sets up the number to his liking...), one of the standard problems programmers are facing + when moving from one editor to another is that code containing both spaces and tabs that was up to now perfectly + indented, suddenly becomes a mess to look at when changing to another editor. Even if you as a programmer take + care to ONLY use spaces or tabs, looking at other people's source code can still be problematic. +

+

+ To address this problem, Artistic Style was created – a filter written in C++ that automatically re-indents + and re-formats C / C++ / Objective‑C / C++/CLI / C# / Java source files. It can be used from a command line, + or it can be incorporated as classes in another C++ program. +

+ +

+ Documentation +

+ +

+ There is complete documentation for using Artistic Style. The documentation needed to install and run Artistic + Style is included in the distribution package. It does not need an Internet connection. +

+ +

+ News and Release Notes +

+ +

+ These contain information on the changes in the current release. The News contains information on major changes + and how they might affect the use of Artistic Style. The Release Notes contains a list of all changes made to + the program. Information on old releases is also listed. +

+ +

+ Download +

+ +

+ The latest release can be downloaded from the SourceForge file releases page. A link to the "latest version" near + the top of the page will download the correct package for your platform. Or you can select the appropriate + package from the "astyle" release folders. The Windows package contains a compiled binary. Other platforms + will need to compile the source code. Makefiles are included for the most popular compilers. Follow the install + instructions for the appropriate platform as described in the "Install" documentation. +

+ +

+ Subversion +

+ +

+ The latest development files can be checked out from the Artistic Style repository using Subversion. +

+ +

+ Install +

+ +

+ This containd information on compiling and installing Artistic Style. The Windows platform comes with a precompiled + executable. Other platforms must compile the project. Follow the instructions for the appropriate platform (Linux, + Mac, or Windows). +

+ +

+ License +

+ +

+ Artistic Style may be used and distributed under the + MIT license. The MIT is a permiissive license with a minimum of restrictions on software use. It is compatable + with the GNU General Public License (GPL) and most other licenses. You can use Artistic Style in free or commercial + software without charge. Projects that use Artistic Style do NOT have to make the Artistic Style source code available. +

+ +

+ Scripts +

+ +

+ This page contains scripts to support the Artistic Style program. They are in various script languages and work + on different platforms. It includes scripts to clean the directories of backup files created by Artistic Style. +

+ +

+ Links +

+ +

+ There are several applications that use Artistic Style as contributed software. It is either embedded in the application + or called as a command line program. The applications include Graphical User Interfaces to view the effect of + formatting on the source code, development environments for various platforms, and other software. There + are also links to style information and various style guides.

+ +

+ Developer Information +

+ +

+ Artistic Style has compile options for creating a shared library (DLL) or static library for use with a Graphical + User Interface (GUI). With the Java Development Kit (JDK) installed it can be compiled as a Java Native Interface + (JNI) and called from a Java program. The Developer Information documents the calling procedure and has example + programs for C++, C++/CLI, Objective‑C, Java, C#, and Python. +

+ +

Bug Reports, Change Requests, Update Notifications

+ +

+ Bug reports and change requests should be submitted to the bug tracker + page. You must be logged in to SourceForge to submit a report. If possible include an example + that shows the problem. It does not need to be functional code. Note that code copied and pasted into the bug + report will not be indented after the data is submitted. You must indicate the indentation when + you submit the request (e.g. replace leading spaces with periods). +

+

+ The best way to subscribe to update notifications is using the + SourceForge Project Page "Update Notifications" button. The option to subscribe is also displayed + during a file download. The subscription options for a project can be modified using the "Me", "Account + Settings" option on the SourceForge bar at the top of the page. Select the "Subscriptions" tab + and check the notifications you want. Usually only the "files" option is needed. +

+

+ You can also subscribe to change notifications using an RSS feed. There is an RSS symbol on the + SourceForge Files page. Or you can use the "subscriptions" + or "add content" option available in your RSS reader. +

+

+ To contact the project by email use the address jimp03@email.com. +

+ +

Maintainers

+ +

+ Artistic Style is maintained and updated by Jim Pattee. The original author + was Tal Davidson, Israel. +

+ +

Acknowledgments

+ +

+ Thanks to Jim Watson, Fred Shwartz, W. Nathaniel Mills III, Danny Deschenes, Andre Houde, + Richard Bullington, Paul-Michael Agapow, Daryn Adler, Dieter Bayer, Sam Cooler, Jim Duff, + Emilio Guijarro, Jens Krinke, Eran Ifrah, Travis Robinson, Max Horn, Ettl Martin, + Mario Gleichmann, J P Nurmi, Colin D Bennett, Christian Stimming, MrTact, Wim Rosseel, + Matthew Woehlke, Chris Schwarz, Chang Jiang, Arseny Solokha, Milian Wolff, Johannes Martin, + Arne F?rlie, Marvin Humphrey, J, Christopher Sean Morrison, Keith OHara, louis6g, Evmenov Georgiy, + beta100100, Ruzzz, Peter A. Bigot, HyungKi Jeong, David Faure, Carl Moore, Mofi, Travis Vitek + for their patches and contributions to Artistic Style. +

+

+ Thanks to SourceForge for giving Artistic Style its home. +

+

+ Thanks to all the dedicated beta-testers and bug notifiers! +

+ + + +

+   +

+ +

+ + + +

+ +

+   +

+ + + + + diff --git a/External/Tools/AStyle/doc/install.html b/External/Tools/AStyle/doc/install.html new file mode 100644 index 0000000000..199cd2d2b3 --- /dev/null +++ b/External/Tools/AStyle/doc/install.html @@ -0,0 +1,477 @@ + + + + + + Artistic Style - Install Information + + + + + + + + +

+ Artistic Style Install Information +

+ +

+   +

+ +

+ Contents +

+ +

+ Artistic Style Versions +

+

+ Linux Version +

+

+ GCC Compiler +

+

+ Clang Compiler +

+

+ Intel Compiler +

+

+ Other Makefile Targets +

+

+ Mac OS X Version +

+

+ Xcode +

+

+ Makefile +

+

+ Windows Version +

+

+ Precompiled Executable +

+

+ Visual C++ Compiler +

+

+ Other Compilers +

+

+ Compiler Options +

+ +

+ Artistic Style Versions +

+ +

+ astyle_x.x_linux.tar.gz is the Linux version of Artistic Style. It contains the source code, + documentation, and makefiles. The Linux Version compile instructions below give information for compiling the + source code. +

+

+ astyle_x.x_macosx.tar.gz is the Mac OS X version of Artistic Style. It contains the source code, + documentation, Xcode project files, and a makefile. The Mac OS X Version compile instructions below give information + for compiling the source code. +

+

+ astyle_x.x_windows.zip is the Windows version of Artistic Style. It contains the source code, + documentation, Visual C project files, and an executable. The Windows Version compile instructions below give + information for compiling the source code. +

+

+ Only one platform is supported in each distribution package. If you use Artistic Style on more than one platform + you will need to download packages for each platform. The main difference in platforms is the build directories + and the line endings. Most compilers and development packages will accept any type of line ending. The source + code and documentation are the same for all distributions. +

+ +

+ Linux Version +

+ +

+ GCC Compiler +

+ +

+ To compile using the GCC compiler you must have GCC (3.1 or better) installed. +

+

+ The build has no autoconf dependency. To build the Artistic Style configurations use the makefile located in the + astyle/build/gcc directory. The executables will be in the astyle/build/gcc/bin directory. To build the command + line configuration enter the following: +

+
cd astyle/build/gcc
make +
+

+ To build the other astyle configurations you can enter the file name or a symbolic name. Entering "make astyle" + or "make release" will build the command line configuration. Following are the symbolic names and file names (in + parens) of the various configurations: +

+
    +
  • release builds the Artistic Style command line program (astyle). This is the default option. +
  • +
  • shared builds the Artistic Style program as a shared library (libastyle.so).
  • +
  • static builds the Artistic Style program as a static library (libastyle.a).
  • +
  • debug builds the Artistic Style command line program with debugging information (astyled). +
  • +
  • shareddebug builds the Artistic Style program as a shared library with debugging information + (libastyled.so). +
  • +
  • staticdebug builds the Artistic Style program as a static library with debugging information + (libastyled.a). +
  • +
  • all builds all the above configurations. +

    + The following Java shared library builds are separate from the above. They include a Java Native Interface (JNI) + and require that the Java Development Kit (JDK) be installed. The environment variable JAVA_HOME should be defined. + It defines the install directory for the JDK. The makefile also has default install directories for Java 5 and + 6. If the compile cannot find the file jni.h, either set the variable or change the value in the makefile. +

    +
  • +
  • java builds the Artistic Style program as a shared library which includes the JNI (libastylej.so). +
  • +
  • javadebug builds the Artistic Style program as a shared library which includes the JNI and debugging + information + (libastylejd.so).
  • +
  • javaall builds all the above java configurations.
  • +
+

+ More than one configuration can be built at the same time. For example, to build all the release configurations + enter: +

+
cd astyle/build/gcc
make release shared static
+

+ The Other Makefile Targets section contains additional target options. +

+ +

+ Clang Compiler +

+ +

+ Clang has a static analyzer that finds potential bugs in C/C++ and Objective-C programs. It can be run as a standalone + tool from the command-line, and runs in tandem with a build. There is a script file, analyze.sh, that will run + the analysis on Artistic Style. +

+

+ The build has no autoconf dependency. To build the Artistic Style configurations use the makefile located in the + astyle/build/clang directory. The executables will be in the astyle/build/clang/bin directory. To build the command + line configuration enter the following: +

+
cd astyle/build/clang
make +
+

+ To build the other astyle configurations you can enter the file name or a symbolic name. The configurations for + Clang are the same as for the GCC compiler. More than one configuration can be + built at the same time. For example, to build all the release configurations enter: +

+
cd astyle/build/clang
make release shared static +
+

+ The Other Makefile Targets section contains additional target options. +

+ +

+ Intel Compiler +

+ +

+ These procedures and the makefile are for recent versions of the compiler. They may not work for earlier versions. + Instructions for your compiler are in the compiler documentation file "get_started_lc.htm". +

+

+ To compile the source there are environment variables that must be set by running the compiler environment script + compilervars.sh (or compilervars.csh) with an argument that specifies the target architecture. If this has not + been done already enter: "source  <install-dir>/bin/compilervars.sh <arg>", + where <install-dir> is the directory where the compiler is installed and <arg> is ia32 + or intel64. If this is not done "make" will display an error message "*** The compiler environment + variables are not set." On an Intel x64 platform installed in the default directory the instruction would be +

+
source /opt/intel/composer_xe_2015/bin/compilervars.sh intel64
+

+ The build has no autoconf dependency. To build the Artistic Style configurations use the makefile located in the + astyle/build/intel directory. The output executables will be in the astyle/build/intel/bin directory. To build + the command line configuration enter the following: +

+
cd astyle/build/intel
make
+

+ To build the other astyle configurations you can enter the file name or a symbolic name. The configuration names + for Intel are the same as for the GCC compiler. More than one configuration can be + built at the same time. For example, to build the entire debug configurations enter: +

+
cd astyle/build/intel
make debug shareddebug staticdebug
+

+ The Other Makefile Targets section contains additional target options. +

+ +

+ Other Makefile Targets +

+ +

+ The following makefile targets are available for GCC, Clang, Intel, and Mac. +

+ +
+ clean +
+ +

+ Removes the object and executable files for all configurations. +

+

+ To remove the files for all configurations: +

+
make clean
+
+ +
+ cleanobj +
+ +

+ Removes the object files for all configurations. The executables will not be removed. +

+

+ To remove only the object files for all configurations: +

+
make cleanobj
+
+ +
+ install +
+ +

+ Installs the + astyle executable and documentation files. The default is /usr/bin for the executable and /usr/share/doc/astyle + for the documentation. You must have the appropriate permissions to use install. +

+

+ To install the astyle to the default directories: +

+
sudo make install
+
+

+ To install astyle to a different bin directory set a value for the macro $(prefix). For example to install the + executable to a user's home directory (/home/user/bin): +

+
sudo make prefix=$HOME install
+
+ +
+ uninstall +
+ +

+ Uninstalls the executable and documentation. You must have the appropriate permissions to use uninstall. +

+

+ To uninstall astyle from the default directories: +

+
sudo make uninstall
+
+

+ To uninstall the files from a different directory set a value for the macro $(prefix). For example to uninstall + the files from a user's home directory (/home/user): +

+
 sudo make prefix=$HOME uninstall
+
+

+ NOTE: The uninstall option will NOT remove the .astylerc files from the users home directories. The files must + be removed individually for each user. +

+ +

+ Mac OS X Version +

+ +

Xcode

+ +

+ Artistic Style workspace and project files for the Xcode development environment are available in the "build/xcode" + directory. A workspace can be used to build a single project or all the projects. The project files have Debug + and Release configurations. The following projects are available. +

+
    +
  • AStyle builds the Artistic Style command line program (astyle).
  • +
  • AStyleA builds the Artistic Style program as a Static Library (libastyle.a). This can be statically + linked with an executable.
  • +
  • AStyleDylib builds the Artistic Style program as a Dynamic Library (libastyle.dylib). It can + be used with C/C++, Objective C, C#, and Python programs.
  • +
  • AStyleJava builds the Artistic Style program as a Dynamic Library (libastylej.dylib) that can + be called from a Java program. The Java Development (JDK) is required for the project to compile. The Project + Properties must have an include path to the JDK include directory. The output dylib can also be called from a + C++ or C# program.
  • +
+ +
install
+ +

+ Only the astyle executable is installed. The library project installs are sent to UninstalledProjects in + the Build directory. The following instructions are for the astyle executable and documentation files. The default + install directory is /usr/bin for the executable and /usr/share/doc/astyle + for the documentation. You must have the appropriate permissions to use install. + If sudo is not used for the install an error will occur during the build. +

+

+ To install the astyle executable to the default directory: +

+
cd astyle/build/xcode
+sudo xcodebuild install -project AStyle.xcodeproj
+
+

+ A script is used to install the documentation + from the same directory. +

+
sudo bash install.sh
+
+ +
+ uninstall +
+ +

+ Uninstalls the executable and documentation. You must have the appropriate permissions to use uninstall. +

+

+ A script is used to uninstall astyle and the documentation: +

+
sudo bash uninstall.sh
+
+

+ NOTE: The uninstall option will NOT remove the .astylerc files from the users home directories. The files must + be removed individually for each user. +

+ +

Makefile

+ +

+ The Artistic Style makefile compile uses the OS X "Command Line Tools". If you have Xcode 4.3 or newer + the command line tools, such as "make", are NOT installed by default. They must be downloaded and installed + separately. Once everything is successfully installed you should see "make" and other command line developer + tools in /usr/bin. +

+

+ The build has no autoconf dependency. To build the Artistic Style configurations use the makefile located in the + astyle/build/mac directory. The executables will be in the astyle/build/mac/bin directory. To build the command + line configuration enter the following: +

+
cd astyle/build/mac
make +
+

+ To build the other astyle configurations you can enter the file name or a symbolic name. The configurations for + Mac are the same as for the Linux GCC compiler. More than one configuration can be + built at the same time. For example, to build all the release configurations enter: +

+
cd astyle/build/mac
make release shared static +
+

+ The Other Makefile Targets section contains additional target options. +

+ +

+ Windows Version +

+ +

+ Precompiled Executable +

+ +

+ In addition to the source files, the Windows distribution package contains an Artistic Style Win32 executable + (AStyle.exe). If you prefer to compile the executable yourself follow the following instructions. +

+ +

+ Visual C++ Compiler +

+ +

+ There are + solution and project files for + several versions of the Visual C compiler. Open an Artistic Style solution + file in the appropriate "build" directory. All projects have Debug, Release and Static configurations. + Debug file output will be in the "debug" directory. Release file output will be in the "bin" + directory. Static file output will be in the "binstatic" directory. The following solution files are available. +

+
    +
  • All AStyle ll AStyle builds the release and the debug configurations for all the following. +
  • +
  • AStyle builds the Artistic Style command line program (AStyle.exe). This project has an extra + "Static" option. It is the same as the "Release" build except that it is linked with a static runtime library. + This is needed if the executable is to be run on a system without Visual Studio installed. The builds for this + configuration are placed in a separate "binstatic" directory.
  • +
  • AStyleDll builds the Artistic Style program as a Dynamic Link Library (AStyle.dll). This will + also build an exports library and a static library for linking the dll.
  • +
  • AStyleJava builds the Artistic Style program as a Dynamic Link Library (AStylej.dll) that can + be called from a Java program. The Java Development (JDK) is required for the project to compile. The Project + Properties must have an include path to the JDK include and include/win32 directories. This is set in "Project + > Properties > C/C++ > General > Additional Include Directories". The default setting + is for the JDK to be installed in the default directory, but it may not be the most current release. The output + DLL can also be called from a C++ or C# program.
  • +
  • AStyleLib builds the Artistic Style program as a Static Library (libAStyle.lib). This can be + statically linked to a calling program.
  • +
+ +

+ Other Compilers +

+ +

+ To use other compilers a project file must be built using a development environment. +

+
    +
  • Create a project using the compiler's development environment.
  • +
  • Add to the project all the .cpp and .h files in the "src" directory.
  • +
  • The Compiler Options section discusses the compiler options to use.
  • +
  • Compile.
  • +
+ +

+ Compiler Options +

+ +

+ No macro definitions are required to compile the executable. To compile as a static or shared (dynamic) library + define the macro ASTYLE_LIB. To compile a Java shared (dynamic) library define the macro ASTYLE_JNI. The + option ASTYLE_NO_EXPORTS is sometimes needed for static libraries to prevent compiler error and warning + messages. Use the appropriate compiler and linker options to compile the static or shared library. Add debug + options to compile the debug versions. +

+

+ Artistic Style is a small program and it is best to optimize for speed. The debug configurations are not usually + optimized. To optimize for speed in the release configurations use the macro NDEBUG to remove asserts. If + necessary, use an option to activate the C++11 standards (--std=c++0x on GCC and MinGW). Use an + option that allows inline function expansion. Runtime Type Information (RTTI) is NOT needed. Exceptions are + NOT + used. Use whole program optimization if your compiler supports it. There may be other options you can use depending + on the compiler. +

+

+   +

+ +

+ + + +

+ +

+   +

+ + + + + diff --git a/External/Tools/AStyle/doc/links.html b/External/Tools/AStyle/doc/links.html new file mode 100644 index 0000000000..8cb15036bb --- /dev/null +++ b/External/Tools/AStyle/doc/links.html @@ -0,0 +1,254 @@ + + + + + + Artistic Style - Links + + + + + + + + +

Artistic Style Links

+ +

+   +

+ +

Programs Using AStyle

+ +

+ The following development environments use Artistic Style as a contributed add-on. It is either embedded in the + application or called as a command line program. +

+

+ Dev-Cpp + is a new and improved fork of the original Bloodshed Dev-C++. It is a free IDE for programming in C and C++. It + is bundled with, and uses, the MinGW or TDM-GCC port of the GCC as its compiler. It is currently Windows only. + The Artictic Style interface includes a live Preview window. +

+

+ CodeBender is a + browser-based IDE for programming and uploading to Arduino boards. It includes built-in libraries for code sharing. + Artistic Style is used as the code formatter. +

+

+ CodeBlocks is + a multi-platform, open source, C++ development environment based on wxWidgets. It has support for multiple compilers and plug-ins for wxWidgets development. +

+

+ CodeLite is an + open source, free, cross platform IDE specialized in C, C++, PHP and JavaScript. It supports all major + compilers. Threr is support for wxWidgets and includes a class + generator and a unit test program generator. Code completion is based on Ctags. +

+

+ KDevelop is a + multi-platform, integrated development environment for building + KDE applications. It supports many programming languages and can be used to develop applications other + than KDE. +

+

+ Monkey Studio + is a cross platform IDE written in C++/Qt. Its primary goal was to be a Qt only IDE, but it evolved into a way to support Qt development and any kind + of project. +

+

+ Qt + Creator is a cross-platform integrated development environment tailored to the needs of Qt developers. An Artistic Style Plugin is available as an integrated plugin. + It can format source code within the editor or format an entire project. There is a help display available to + show the effect of each option. +

+

+ SciTE + is a Scintilla based source code editor. Originally built to demonstrate Scintilla, it has grown to be a generally useful editor with facilities for building + and running programs. It is currently available for Windows, Linux, and Mac OS X operating systems. The Linux + and Mac versions are based on GTK+. +

+

+ Sublime Text + is a is a sophisticated text editor for code, markup and prose that includes Artistic Style as a plug-in. Nearly + everything in Sublime Text is customizable with simple JSON files.The plug-ins are Python based. + Sublime Text is available for OS X, Windows and Linux. +

+

+ tIDE is + a full featured open source + Java integrated development environment. It is a small, powerful, quick, efficient, easy and open framework + to create 100% Java applications. +

+

+ UltraEdit is a commercial programmer's text editor for Microsoft + Windows, Linux and Mac OS X. It can be evaluated for free for 30 days. Artistic Style is included in the Tools + Toolbar. It includes an options dialog. The number of indent spaces is passed to Artistic Style is based on + the Indent Spaces value defined under Word Wrap/Tab Settings in Configuration based on the file extension of + the active file. +

+

+ Visual Studio + is an integrated development environment from Microsoft. + AStyle Extension is an extension written in C# and formats C/C++ + and C# + source code using Artistic Style. It can be installed in Visual Studio (except Express editions) + using the "Tools" > "Extensions and Updates" menu. Search the "Online" entry + for "astyle". The source code is available on GitHub. +

+ +

Graphical User Interfaces

+ +

+ Artistic Style is a command line program and, as such, does not give you a chance to review the effect of different + options before formatting the source code. The following Graphical User Interface program will allow you to review + the changes before the code is updated. They allow you to select the options you want without actually updating + the source. +

+

+ Artistic Style for Windows + is an Artistic Style GUI program for Windows. It uses an unmodified Artistic Style program in a Windows GUI. It + will work under Linux using WINE. Everything done in the editor is undo-able, including formatting of the entire + document. Documents can be reviewed and reformatted using different options. It can be executed from most development + environments and will open the currently selected document.
+ Here are the links for downloading version 2.05.1 of + + AStyleWin and + + AStyleWinD. The website has been having problems and I have not been able to update it. + The downloads contain Windows executables and documentation. +

+

+ Universal Indent + Gui is a cross platform GUI that supports several code formatters. The main feature is a live + preview to show how the selected formatting options affect the source code. This allows review and testing of + the various options before formatting a file. It can be used with a sample file or with your actual source code. + It is a good way to try out the options from various indentation programs. This program is not always kept up + to date. Be sure to check the AStyle release before relying on the results. +

+ +

Other Programs

+ +

+ These programs were mentioned in previous versions of the News + or other documentation. They are included here for reference. +

+

+ Google Test + and Google Mock + are frameworks for writing C++ tests on a variety of platforms. Based on the xUnit architecture it supports automatic + test discovery, a rich set of assertions, user-defined assertions, death tests, fatal and non-fatal failures, + value- and type-parameterized tests, various options for running the tests, and XML test report generation. Google + Mock is a library for writing and using C++ mock methods. +

+

+ Highlight converts + source code to formatted text with syntax highlighting. Output is in several formats including HTML. It supports + over 160 programming languages and includes 80 color themes. Highlight is used for the examples in the "Developer + Information" section. +

+

+ Python Tools for Visual Studio + is a free, open source plug-in that turns Visual Studio into a Python IDE. It can be switched between Python versions + or different Python interpreters. It uses the Visual Studio integrated debugger that enables you to set break + points, step through functions, change the current statement, inspect local variables, and perform other operations + while debugging. +

+ +

Information

+ +

The following links contain general information on coding and coding styles.

+ +

+ Indent Style + at Wikipedia discusses the common indent styles used in programming. The basic criteria for most Artistic Style + predefined styles were taken from this discussion. +

+

+ Programming + style at Wikipedia is a set of rules or guidelines used when writing the source code for a computer + program. It is often claimed that following a particular programming style will help programmers to read and understand + source code conforming to the style, and help to avoid introducing errors. +

+

+ Programming with Style + describes popular indent styles. Its purpose is to provide enough information to help people decide on which indent + style to use. +

+ +

Style Guides

+ +

+ Chromium + style guide generally follows the Google Style Guide but has extensions beyond the Google style + guide. There is interesting information on common C++ Dos and Don'ts. +

+

+ Google style + guides have Google's standards for several programming languages along with a python program + to verify the style and an Emacs script for using the style. +

+ +

+ Kdelibs + Coding Style describes the recommended coding style for kdelibs. It follows the Qt 4 coding style, + with one main difference. +

+

+ LLVM coding standards + describes a few coding standards that are being used in the LLVM source tree. +

+

+ + Mozilla’s style guide explains the basic styles and patterns that are used in the + Mozilla codebase. +

+

+ Qt Coding Style + is an overview of the coding conventions used when writing Qt code. +

+ +

Other Links

+ +

+ These links were mentioned in previous versions of the News. They are included here for reference. +

+

+ Install Instructions for .NET Framework SDK + are instructions for adding x64 platforms to Visual Studio Express 2010. Express editions after 2010 have the + x64 platforms already installed. Visual Studio 2010 is the last edition that will work on Windows XP (platform + toolset v100). Visual Studio 2012 (platform toolset v110) and higher contains dependencies on Windows API functions + that exist only on Windows Vista, Windows 7, and Windows 8. This means that applications built with Visual Studio + 2012 and higher would fail to load and execute on Windows XP. +

+

+ Survey + General Information and Survey Options are the results of an Artistic Style survey + from May 2011. There is a commentary on the survey in the May 2011 News under the heading "Survey Results". +

+

+   +

+ +

+ + +

+ +

+   +

+ + + + diff --git a/External/Tools/AStyle/doc/news.html b/External/Tools/AStyle/doc/news.html new file mode 100644 index 0000000000..e914b87b50 --- /dev/null +++ b/External/Tools/AStyle/doc/news.html @@ -0,0 +1,553 @@ + + + + + + Artistic Style - News + + + + + + + + +

Artistic Style News

+ +

+   +

+ +

Artistic Style 2.06  (Pending)

+ +

+ A new option, "pad‑comma", will add a space following a comma. The option "pad‑oper" + has not been changed and will also add a space following a comma. +

+

+ All spaces before a comma are now removed. Use the disable block comments if there are arrays with vertical alignment + where this is not wanted. +

+

+ New Objective‑C options "pad‑return‑type" and "unpad‑return‑type" will + add or remove space padding after the Objective‑C return type. It is described in the "Objective‑C" + section of the documentation. +

+

+ The Objective‑C align‑method‑colon has been changed for method declarations and definitions. + For multi‑line arguments when the first keyword is shorter than the others the colons are aligned on the + longest line instead of the first line. The alignment includes room for the indentation. This aligns all colons + after the first line for a better appaerance. Arguments that do not have a short keyword in the first line will + remain the same. This style conforms to the Google Objective‑C Style Guide. +

+

+ The Objective‑C align‑method‑colon option is now applied to Objective‑C method calls in + addition to method declarations and definitions. +

+

+ Processing for c++14 single‑quote digit separators has been added. +

+ +

+ New + Software License +

+ +

+ The Artisic Style software license has changed. It is now under the MIT license. This is a permissive license + which can be used in proprietory software and does NOT require modified Artistic Style source code be made available. + It is compatable with the GNU General Public License (GPL) and most other software licenses. The change was made + to remove restrictions on using the software and to make it available for any project that wants to use it. +

+

+ If there are problems with the license change send an email to Artistic Style and its use will be approved on + a individual basis. +

+ +

+ Assignment Operator Alignment +

+ +

+ Visual Studio 2013 and 2015 have an Edit option "Align Assignments" that will align assignment operators + across multiple lines. There is also an extension named "Code alignment" that will align the code on + other items as well. Other development environments may have something similar. These will selectively align the + data and allow for customization of the format. +

+

+ These options and extensions can be used with Artistic Style. If you choose to do this, the space padding will + be maintained and the alignment will be preserved. +

+ +

+ Microsoft Clang Compiler +

+ + +

+ The Microsoft Clang Compiler is available with Visual Studio 2015 Update 1. It is usually + used for Android or iOS + support but the CodeGen support can be used with Windows. The Clang Update 1 version is a preview and is + incomplete, but can be used if you want. It will require modification of the Visual Studio 2015 project files. +

+

+ The Clang compiler can be installed from the Visual Studio 2015 install program by selecting the "Clang + with Microsoft CodeGen" option. If Visual Studio 2015 Update 1 is already installed, Clang can be installed + by selecting File > New > Project > Visual C++ > Cross Platform, select CodeGen support option. +

+

+ To use Clang open a Visual Studio 2015 AStyle Solution. Make the following change to all configurations: +

+
    +
  • General > Platform Toolset, select "Clang 3.7 with Microsoft CodeGen".
  • +
+

+ Make sure to hit "Apply" before editing other properties to let the project system load the corresponding + toolset definition. +

+

+ The Update 1 preview release does not provide any support for automatic migration of values between Visual Studio + 2015 and Clang 3.7. The invalid properties must be fixed manually manually. These may change with subsequent Visual + Studio updates. +

+

+ The properties that need changing in Visual Studio Update 1 are: +

+
    +
  • C/C++ > General > Debug Information Format, select "Full Debug Information (DWARF2)" for Debug + or "None" for Release.
  • +
  • C/C++ > General > Warning Level, select "Enable All Warnings".
  • +
  • C/C++ > Code Generation > Enable C++ Exceptions, select "Yes" for Debug or "No" for + Release.
  • +
  • C/C++ > Precompiled Headers > Precompiled Header, select "Not Using Precompiled Headers".
  • +
+

+ The following is needed if you are building an executable instead of a static or dynamic library: +

+
    +
  • C/C++ > Preprocessor > Preprocessor Definitions, add " __STDC__=0". To remove the warnings + this causes, C/C++ > Command Line > Additional Options, enter "-Wno-macro-redefined". +
  • +
+

+ The project should now compile and run. +

+ +

+ Windows XP +

+ +

+ The executable in the Windows distribution package is now compiled with a Visual Studio version that will no + longer work on Windows XP. Beginning with Visual Studio 2012, auto‑vectorization tries to make loops run + faster by automatically vectorizing the code. Auto‑vectorization is on by default, there are no compiler + switches, #pragmas, or hints. But it uses SSE instructions not available in Windows XP. Microsoft ended + support and updates for XP on April 8, 2014, and the usage share percentage continues to decrease. +

+

+ If you are using XP, Artistic Style should be compiled on the XP machine. Compiling on XP with any + compiler should produce an XP executable. +

+

+ To compile on a non‑XP machine for use on  XP, using a compiler other than Visaul Studio should always + produce an XP executable. Using Vusual Studio 2010 or earlier should always produce an XP executable. If + you are using Visual Studio 2012, 2013, or 2015 on a non‑XP machine, do the following for the Artistic Style + configuration you want to use: +

+
    +
  • "Windows XP Support for C++" must be installed. It is available as an option in the Visual Studio install + and can be installed as a modification to the original install.
  • +
  • In the Artistic Style Properties, change General > Platform Toolset, to "Windows XP".
  • +
  • In the Artistic Style Properties, change C/C++ > Preprocessor > Preprocessor Definitions to include + _USING_V110_SDK71_.
  • +
  • Change other Properties if you want, such as Output Directory or Target Name.
  • +
  • Compile. The output should be executable on Windows XP. It will also execute on the later versions of Windows. +
  • +
+ +

+ SourceForge +

+ +

+ Recently, SourceForge began adding potentially unwanted programs (PUPs), also known as "crapware", to + software installers of certain applications. Some large projects have already left the site. Artistic Style does + not use installer downloads and therefore was not affected by this. Downloads are in the form + of .zip or .tar.gz files. However, having the PUPs available on the host site affects the integrity of every + application that uses the site. +

+

+ What is even more troubling is that the uBlock browser add‑on, and all of its spin‑offs, is now blocking + access to the site by default. Even though Artistic Style has never used PUPs, the site is prevented from loading. + The block can be easily removed, but may discourage some people from using the software. are. +

+

+ SourceForge is apparently taking steps to correct the situation. If this is not resolved fairly soon, Artistic + Style will be relocated to another site. If this happens, I will give notification of the new site at the + current SourceForge address. + ess. +

+ +

+ Acknowledgments +

+ +

+ Thanks to David Faure for their contributions. +

+ +

Artistic Style 2.05  (November 2014)

+ +

+ Release 2.05.1 (December 2014) is a maintenance release and no new features were added. A list of changes is in + the Release Notes. The following information is for the original 2.05 release. +

+ +

+ A new bracket style option, "style=vtk", has been added. It uses indented brackets, like Whitesmith, + except opening brackets for classes, functions, and methods are not indented. A complete description of the VTK + style is available at the "Visualization Toolkit" website (http://www.vtk.org/). +

+

+ A new preprocessor indent option "indent-preproc-block" will indent preprocessor block statements one additional + indent. The block must be top-level, or included within a namespace, and there are restrictions on what can be + indented. + The option is described in the "Indentation Options" section of the documentation. +

+

+ A new option, "dry-run", will run Artistic Style without updating the files. The report will be output as usual. +

+

+ Formatting of source code may now be disabled for portions of a program by embedding special comment tags in the + program. These are described in a new "Disable Formatting" section of the documentation. They work the + same as in other formatters. There are tags to disable formatting for a block of code, and a tag to disable formatting + of a single line. This should allow any custom formatting to be retained. +

+

+ The product version number has been added to the filename of shared library (DLL) compiles. This will allow multiple + versions of a shared library on the same system without conflicts. +

+

+ An attribute '__attribute__ ((visibility ("default")))' has been added to exported functions + on Linux shared libraries. This allows the option "-fvisibility=hidden" to be used on dynamic library + compiles. According to the GNU documentation, "Using this feature can very substantially improve linking + and load times of shared object libraries, produce more optimized code, provide near-perfect API export and prevent + symbol clashes. It is strongly recommended that you use this in any shared objects you distribute." +

+

+ Improvements have been made in the formatting of C++11 uniform initializers (enclosed by brackets). The opening + bracket will not be space padded unless it is padded initially. The closing bracket will not be broken from the + final line unless it is broken initially. And the known problems with uniform initializers in class constructors + have been fixed. +

+

+ The Windows compiler definition ASTYLE_NO_VCX (no Visual Studio exports) has been changed to ASTYLE_NO_EXPORTS. + It is sometimes needed for static libraries on other compilers to prevent error and warning messages. +

+

+ Qt and Boost macros foreach, forever, Q_FOREACH, and Q_FOREVER will now be recognized as headers. +

+

+ The main documentation for Artistic Style is in HTML format. Until now there has not been a way to display it + from the astyle console program. A new option, "html" or "-!" will display the help documentation in the default + browser. This documentation is more complete than the astyle "help" option. It includes examples, and has an index + for easier navigation. Since astyle is typically run from a script this should allow an easy way to access the + documentation. The option is available only from the command line. +

+

+ The new "html" option assumes the documentation is installed in the standard install path. This is /usr/share/doc/astyle/html + for Linux and the path %programfiles%\AStyle\doc for Windows. If it is installed to a different directory, use + the variation "html=<actual_install_path>astyle.html. This option can also be used to open other HTML files. + More information is in the "Command Line Only" section of the documentation. +

+

+ The "html" option on Linux uses the script "xdg-open" from the install package "xdg-utils" to find the default + browser. This should be available on most systems.  If it is not available on your system you can file a + bug report requesting a change. It would be helpful if you could determine how it is done before filing the report. + You can also file a bug report if the documentation is not installed to the above "default" directories. The HTML + documentation takes quite a bit of effort to maintain and I would like to make it easily available. +

+

+ The "help" option has been changed to send the output to stdout instead of stderr. This will allow piping and + redirection of the output. A common way to use the option on Linux is "astyle --help | less", which + will page the display. The "version" option has also been changed to stdout. +

+

+ A shared library error handler argument has been changed from "char*" to "const char*". In + some cases this may cause compile errors in a user program until the references have been changed. +

+

+ The "Indent Style" topic on Wikipedia states that the "ANSI" style refers to K&R style brackets + and not Allman style as used by Artistic Style. The option "style=ansi" is therefore being depreciated and will + be removed in a future release. Use one of the other long options instead (style=allman, style=bsd, or style=break). +

+

+ Some of the documentation has been removed from the distribution package. It still contains all files needed to + install and run Artistic Style. The included files can be used without an Internet connection. +

+

+ There are now build files available for Xcode on Mac. The makefile is still available for those who want it. Both + now use the LLVM Clang compiler. There has been a + change to the makefile debug locations to make them similar to Xcode. The "Install Instructions" have + been updated for both. +

+

+ The Python Example in the Developer Information now supports Iron Python. The + programming instructions are sometimes different since the ctypes module works differently. The example script + documents the differences. If you use Python Tools for Visual Studio, it now installs in the Express editions + (beginning with release 2.1). Node.js can also be installed in Visual Studio Express. +

+

+ The executable in the Windows distribution package is now compiled with Visual Studio 2013 and will no longer + work on XP. If you are using XP, Artistic Style will need to be recompiled on the XP machine. +

+

+ A new Visual + Studio Community Edition has been released. It is free, combines all of the Express editions into a single + development environment, and allows the addition of Visual Studio extensions. There is an + + AStyle Extension available for installation. It has a graphic interface, adds menu entries, and can be + used from within Visual Studio. To install it search the "Extensions and Updates", "Online" + entry for "astyle". +

+

+ Thanks to Peter A. Bigot, HyungKi Jeong, David Faure, and Carl Moore for their contributions. +

+ +

Artistic Style 2.04  (November 2013)

+ +

+ With a new Artistic Style release some unchanged source files will be formatted because of changes to Artistic + Style. You may want to format your source before making program changes in order to bring it up to date. +

+

+ A new programming language, Objective‑C, has been added to Artistic Style. Four new options, "align‑method‑colon", + "pad‑method‑colon=", "pad‑method‑prefix", and "unpad‑method‑prefix" have been + added to format the methods. The options are described in a new "Objective‑C" section in the documentation. + These new options affect only Objective‑C source code. They have no effect on the other programming languages. +

+

+ Because of the longer continuation indents sometimes needed for Objective‑C, the option "max-instatement-indent" + may need to be increased. If you are not getting the paren and square bracket alignment you want, try increasing + this value. The default minimum is 40 and the maximum is 120. +

+

+ A new bracket style option, "style=google", has been added. It uses attached brackets and indents the class access + modifiers one-half indent.  A complete description of the Google style is available at the google‑styleguide + website (https://code.google.com/p/google-styleguide/). The website has standards for several programming languages + along with a python program to verify the style and an emacs script for using the style. +

+

+ A new indent option "indent-modifiers" will indent class access modifiers (public, protected, or 'private) one-half + indent. The rest of the class is not indented. It is described in the "Indentation Options" section of the documentation. +

+

+ Four new bracket modify options, "attach-namespaces", "attach-classes", "attach-inlines", and "attach-extern-c", + can be used to modify your selected bracket style. They are described in a new "Bracket Modify Options" section + of the documentation. +

+

+ A new option, "remove-brackets", will remove brackets from conditional statements. The statement must be a single + statement on a single line. It is described in the "Formatting Options" section of the documentation. +

+

+ A new option, "indent-preproc-cond", will indent preprocessor conditional statements (#if #elif, #else, #endif). + It is described in the "Indentation Options" section of the documentation. The option "indent-preprocessor" has + been deprecated and will be removed in a future release. Use "indent-preproc-define" instead. The processing of + preprocessor #define statements has not changed. +

+

+ A new option, "remove-comment-prefix", will remove a leading '*' from multi-line comments. It is described in + the "Formatting Options" section of the documentation. With the syntax coloring of modern editors a leading '*' + for comment lines is not as useful as it once was. The current trend is toward code that is easier to maintain. + The idea is that a style that is hard to maintain will discourage modification and updating. The converted style + should retain most of the formatting within the comment and result in a comment that is easier to maintain. For + consistency the option also indents multi-line comments that are not preceded by the '*'. This may slightly modify + the indentation of any commented-out code. +

+

+ The option "pad-first-paren-out" was fixed to not pad if the following paren is empty. This makes the option consistent + with "pad-paren-out". To fix empty parens that have been padded run with the option "unpad-paren" in addition + to "pad-first-paren-out". This needs to be done only once. +

+

+ Processing of C++11 raw string literals has been added. +

+

+ The compiler definition ASTYLE_NO_VCX (no Visual Studio exports) has been changed to ASTYLE_NO_EXPORTS and can + be used with any Windows compiler. The Clang compiler needs this option to avoid errors on dynamic libraries. + It removes the "__declspec(dllexport)" + definition from exported functions. Linux compilers do not use this. +

+

+ A new shared object (DLL) entry point, AStyleMainUtf16, has been added for processing C# UTF-16 strings. C# does + not have built in functions for converting the UTF-16 strings to UTF-8. This entry point will accept UTF-16 strings, + format the source code, and return UTF-16 strings. The error handling function and version number still use UTF-8 + strings. The C# example program in the "Developer Information" shows the new calling procedure. Changes from the + previous release are marked in the example. +

+

+ C# strings are UTF-16 on both Windows and Linux. C# does not use the UTF-32 wchar_t strings on Linux. Qt also + uses UTF-16 on both Windows and Linux, but has built in UTF-8 conversion functions. Qt strings can be converted + to UTF-8 by Qt, or the new entry point can be used. There may be other "managed code" applications on Linux that + use UTF-16. +

+

+ The "Links" page has two new sections for links mentioned in previous versions of Artistic Style. It links to + free software and other information. +

+

+ The "Developer Information" section has a new example and download for calling Artistic Style from an Objective‑C + program. Since it is another "C" language the only thing needed is to link the program with a library build of + Artistic Style. The example was developed on Windows and Linux using the GNUstep project. Since the example is + a console program the problems with the GNUstep GUI have been avoided. It has not been tested on a Mac, but should + be close to working. The "Developer Information" section also has new page for "Objective‑C on Windows and + Linux" which has information on compiling and running the example on those systems. +

+

+ The executable included in the Windows distribution was compiled with Visual Studio 2010 (platform toolset v100). + Higher releases contain dependencies on Windows API functions that exist only on Windows Vista, Windows 7, and + Windows 8. This means that applications built with a Visual Studio 2012 C++ compiler would fail to load and execute + on Windows XP. +

+

+ If you are using Windows Vista or higher, and have a Visual Studio 2012 or higher compiler available, recompiling + will probably result in faster execution. If you use a compiler other than Visual Studio, you can probably get + better execution by compiling using the C++11 standards. Artistic Style uses a lot of string vectors and the new + move semantics will probably result in faster execution. +

+

+ Thanks to Evmenov Georgiy, Matthew Woehlke, Jiang, Ruzzz, and beta100100 for their contributions. +

+ +

Artistic Style 2.03  (April 2013)

+ +

+ With a new Artistic Style release some unchanged source files will be formatted because of changes to Artistic + Style. You may want to format your source before making program changes in order to bring it up to date. +

+

+ A new option, "max-code-length=#" or "xC#", will limit the length of code on a line. A new option "break‑after‑logical", + or "xL", will modify a line break for conditionals. See the documentation for details. +

+

+ A new option, "pad-first-paren-out" or "xd", will pad only the first paren in a series on the outside. See the + documentation for details. +

+

+ A new option, "indent=force-tab-tab=#" or "xT#", will allow force tab indents with a tab length that is different + than the indent length. See the documentation for details. +

+

+ The short option for delete-empty-lines has changed from "xd" to "xe". +

+

+ The C++11 standard for range-based "for" loops, "enum" with a base type, and rvalue references is now supported. + The formatting of rvalue references is determined from the existing "align-pointer" and "align-reference" + options. +

+

+ Closing the ending angle brackets of templates is now allowed by the C++11 standard. A new option, "close-templates" + or "xy", will close the whitespace in the angle brackets of template definitions. Be sure your compiler supports + this before making the changes. +

+

+ The C/C++ keyword 'extern "C"' in a preprocessor no longer causes an extra indent. +

+

+ Formatting of C++/CLI managed pointers (the '^' character) has been added to the "align-pointer" + option. +

+

+  The breaking of switch "default" statements has been fixed. The "default" statements + that have been incorrectly broken will be fixed in this release. +

+

+ The byte order mark (BOM) has been removed from ASLocalizer.cpp for all platforms. The encoding of the file is + UTF-8. Many Windows editors can now recognize UTF-8 encoding without the BOM. Visual Studio has an option that + needs to be set. With others. such as CodeBlocks, identification is automatic. On Linux, UTF-8 is the default + encoding. +

+

+ Translations have been added for Dutch, Finnish, Italian, Japanese, Korean, Polish, Portuguese, Russian, Swedish, + and Ukrainian. The translations were done with an automated translation program, Google Translate, so they may + not be the best translation possible. The translations are at the end of ASLocalizer.cpp in the form of an English‑Translation + pair. If you correct a translation, send the source as a bug report and it will be included in the next release. + To add a language, see "Internationalization" in the "General Information" section of the documentation. Send + the addition as a bug report and it will be included in the next release. +

+

+ There is a new Linux makefile for the Clang Compiler. Clang is a free compiler can be installed as a package on + many Linux distributions. Some of its features are fast compiles, low memory use, expressive diagnostic messages, + and GCC compatibility. It includes a static analyzer tool that finds potential bugs in your source code. An experimental + version can be installed on a Windows platform. There is more information in the Install Information documentation. +

+

+ Visual Studio automatically creates an import library and an export file when you link a program that contains + exports. It will do this for even a static library if it contains a __declspec(dllexport) definition. The Artistic + Style library (ASTYLE_LIB) build contains such exports which causes an import library and export file to be created + when they may not be needed. A new preprocessor definition, ASTYLE_NO_VCX (no Visual Studio exports) can be declared + to eliminate the files from the output. Use this only for static libraries or when the AStyle source is included + in the compile. Do NOT use this when compiled as a shared (dynamic) library. It is effective only for Visual Studio + 2012. It will NOT work with previous versions. It has no effect with other compilers since they require a separate + option to create the import library and export files. +

+

+ The executable included in the Windows distribution was compiled with Visual Studio 2010 (platform toolset v100). + Visual Studio 2012 (platform toolset v110) contains dependencies on Windows API functions that exist only on Windows + Vista, Windows 7, and Windows 8. This means that applications built with a Visual Studio 2012 C++ compiler would + fail to load and execute on Windows XP. Artistic Style was therefore compiled with Visual Studio 2010 to work + on computers using Windows XP. +

+

+ If you are using Windows Vista or higher, and have the Visual Studio 2012 compiler available, recompiling with + Visual Studio 2012 will probably result in faster execution. The Windows distribution has Visual Studio 2012 project + files available. +

+

+ If you use a compiler other than Visual Studio, you can probably get better execution by compiling using the C++11 + standards. Artistic Style uses a lot of string vectors and the new move semantics will probably result in faster + execution. (To use C++11 on GCC and MinGW use the option --std=c++0x). This may change on future compiler releases.). +

+

+ The "Developer Information" page has a new example and download for calling Artistic Style from a Python script. + It will run with both Python 2 and Python 3. Using Python 3 shows an example of formatting a Unicode string with + Artistic Style. Unicode strings must be encoded to UTF-8 before formatting and decoded back to Unicode afterward. + The example script shows the technique for doing this. It also shows how to set up the function pointers and allocate + memory in Python. +

+

+ If you use Visual Studio on Windows, it can now be used for Python development. Python Tools for Visual Studio + (PTVS) is a free and open source plug-in for Visual Studio 2010 that supports Python and Iron Python. Other interpreters + such Jython can be added. It can be easily switched between Python versions or different interpreters. But the + best thing is the Visual Studio debugging support using the .NET debugger and the normal Visual Studio debugger. + It enables you to set break points, step through functions, change the current statement, inspect local variables, + and perform other operations while debugging. It is best to use it with a project file, a minor irritation for + single page scripts. And there are some minor bugs. But overall it works quite well. +

+

+ Thanks to Christopher Sean Morrison, Keith OHara, louis6g, and J for their contributions. +

+

+   +

+

+ Previous releases are available in the News Archives. +

+

+   +

+ +

+ + +

+ +

+   +

+ + + + + diff --git a/External/Tools/AStyle/doc/newsArchives.html b/External/Tools/AStyle/doc/newsArchives.html new file mode 100644 index 0000000000..791f1e20ad --- /dev/null +++ b/External/Tools/AStyle/doc/newsArchives.html @@ -0,0 +1,1004 @@ + + + + + + Artistic Style - News Archives + + + + + + + + +

Artistic Style News Archives

+ +

+   +

+ +

Artistic Style 2.02  (May 2011)

+ +

+ With a new Artistic Style release some unchanged source files will be formatted because of changes to Artistic + Style. You may want to format your source before making program changes in order to bring it up to date. +

+ +

Release 2.02.1 - November 2011

+ +

+ This bug fix release is issued because of the length of time required for the some of the changes in the next + release (2.03). Bugs with the breaking of "case" statements and a crash with pointer to pointer (**) in align-pointer=type + have been fixed. The "case" statements that have been incorrectly broken will be fixed in this release. Pointers + and references are now processed for C# files. See the "Release Notes" for more information and additional changes. +

+ +

The following information is for the original 2.02 release.

+ +

Translations

+ +

+ A new program module and header, ASLocalizer.cpp and ASLocalizer.h, have been added. These are required for the + console build and are optional for the library builds. It contains language translations for several of the most + common users of Artistic Style. The method used was adapted from the Gnu "gettext" method. +

+

+ The translation to use is determined from the User Locale for Windows and the LANG environment variable for other + systems. The translation will be done automatically from these settings. If no translation is available it will + default to English. +

+

+ A new option, "ascii" or "I", will display the text in English regardless of your system settings. This option + must be input from the command line and not an option file. See the documentation for details. +

+

+ The translations were mostly done with an automated translation program, Google Translate, so they may not be + the best translation possible. The translations are at the end of ASLocalizer.cpp in the form of an English‑Translation + pair. If you correct a translation, send the source as a bug report and it will be included in the next release. +

+

+ To add a language, add a new translation class to ASLocalizer.h. Add the English‑Translation pair to the + constructor in ASLocalizer.cpp. Update the WinLangCode array, if necessary, and add the language code to the function + setTranslationClass(). The ASLocalizer.cpp program contains comments that give web pages for obtaining the LCIDs + and language codes. Send the source code as a bug report and it will be included in the next release. +

+ +

Brackets

+ +

+ Since release 1.22 (April 2008) the predefined styles have increased from 5 to 12 and the bracket types have increased + from 4 to 6. Having two different ways of defining bracket styles has resulted in some confusion and unnecessary + duplication. This release starts a redesign of the bracket definitions to simplify the user interface. The predefined + styles and bracket types will be combined into a single option category. +

+

+ The "Predefined Style" options have been renamed "Bracket Style" options. The "Bracket Options" have been depreciated + and will be removed in a future release. If you are using a "brackets=" option, you should start changing to one + of the "style=" options. There is a "style" option available for every "brackets" option. +

+

+ All "Bracket Style" options now default to 4 spaces per indent. If you were using a "Predefined Style" with a + default indent other than 4, you will need to add one of the "Tab Options" to maintain the same indentation. The + styles which used indents other than 4 were: +

+
    +
  • Stroustrup - 5 spaces per indent.
  • +
  • Gnu - 2 spaces per indent.
  • +
  • Linux - 8 spaces per indent.
  • +
  • Horstmann - 3 spaces per indent.
  • +
+

+ There is a new "Bracket Style" option "style=pico" or "A11". It uses run-in brackets, like Horstmann style, and + attaches the closing bracket to the last line in the block. It sets the options "keep one line blocks" and "keep + one line statements". This is a very compact style and is a good style for small monitors. +

+

+ Another new "Bracket Style" option is "style=lisp" or "style=python" or "A12". It uses attached brackets, like + Java style, and attaches the closing bracket to the last line in the block. It sets the option "keep one line + statements". This style makes indentation the only way of distinguishing blocks of code, but has the advantage + of containing no uninformative lines. Like Pico, it is also a very compact style. +

+

+ The option "brackets=horstmann" has been removed. Instead use "style=horstmann" or "A9". The short option "g" + is now equivalent to the new "brackets=run-in". Run-in brackets are used for both Horstmann and Pico styles. +

+

+ The option "indent-brackets" and short option "B" have been removed. Instead use "style=whitesmith" or "style=banner". +

+

+ The option "indent-blocks" and short option "G" have been removed. Instead use "style=gnu". +

+

+ Two new options, "style=break" and "style=attach", have been added for Allman and Java bracket styles respectively. +

+ +

Other Changes

+ +

+ To allow for future expansion the short options will now allow an "x" prefix to be used. New short options may + start with an "x" and will be followed by another character (e.g. "xa", "xb", "xc" ...). The current options, + with one exception, will still be valid. +

+

+ The short option for "delete-empty-lines" has been changed from "x" to "xd" to allow for the expansion of short + options. +

+

+ A new option "align-reference=" (-W#) allows references to be aligned separate from pointers. See the documentation + for details. +

+

+ Since computer screens are getting wider the maximum value for "max-instatement-indent" has been increased from + 80 to 120. +

+

+ New options ignore‑exclude‑errors (‑i) and ignore‑exclude‑errors‑x (‑xi) + will allow processing to continue if there are errors in the "exclude" options. This lets the excludes for several + projects to be entered in a single option file. The "ignore" options may be placed in the same option file as + the excludes. The ignore‑exclude‑errors option will display the unmatched excludes, ignore‑exclude‑errors‑x + will not display them. +

+

+ Artistic Style can now format UTF-16 encoded files, both little and big endian. This encoding is the default for + Visual Studio Unicode files. The file is formatted by converting it to UTF‑8 and then back to UTF‑16. + The conversion process does not add a significant amount of time to the formatting. The UTF-16 file must be encoded + with a byte-order-mark (BOM) to be recognized. Again, this is the Visual Studio default. +

+

+ The Visual Studio project files now have a solution for both Win32 and x64 compiles. The x64 version will be needed + if you are using an Artistic Style DLL for Java or C# on a Windows 7 platform. Or you may just prefer an + x64 console program. The executable included in the Windows distribution is still Win32. It will work on both + Win32 and x64 systems. +

+

+ If you use Visual Studio C++ Express the 2010 release has the ability to compile x64 code. But you must use Vista + or Windows 7 and need to install the .NET Framework SDK. I have created a brief instruction page here. Note + that a fix is required if you apply Service Pack 1 after installing the .NET Framework SDK. +

+

+ The documentation contains a new section "Command-line Only" which lists commands that are not available from + an options file. The options were transferred from the "Other Options" section. +

+

+ Thanks to Milian Wolff, Johannes Martin, and Arne F?rlie, and Marvin Humphrey for their contributions. The UTF‑8 + and UTF‑16 conversions were obtained from the SciTE source code editor. +

+ +

Survey Results

+ +

+ The results of the survey posted last release are available at General Information and Artistic Style Options. + Thanks to everyone who took the time to complete it. +

+

+ Surveys give an indication of how many people are using an option or want certain features. This is information + that is not available in the bug reports. +

+

+ In the "Enhancements" group there were three items with multiple requests. The most frequent request by far was + to enforce a maximum line length. This is also the oldest request in the bug reports. Another item with multiple + requests was to disable/enable Artistic Style formatting on request within source files. This is the second oldest + request in the bug reports. A third item with multiple requests was to customize namespace brackets independent + of the requested bracket style. I will try to address these in the next release. +

+

+ Things that stand out to me in the multiple‑choice sections: +

+
    +
  • The predefined styles and brackets options were each used about 50% each. That will change with this release. +
  • +
  • Over 50% of the survey uses Artistic Style for Windows. I have been working for a couple of years on a new program + based on wxWidgets. I will try to give this more priority in the future.
  • +
  • Over 75% of the survey uses Artistic Style to format entire projects.
  • +
  • About one‑third of the Windows C++ users use Artistic Style for Managed C++.
  • +
  • The most popular option is add‑brackets (60%), which was just recently added.
  • +
  • The attach‑pointer options, in total (70%), are even more popular than add-brackets. They were also recently + added.
  • +
  • The preserve-date option is used by nearly one-third of the survey.
  • +
  • All of the options are used by someone in the survey, even the ones I thought were outdated. The bracket styles + that are not used are probably a result of not having enough response.
  • +
+ +

Developers

+ +

+ The Artistic Style for Windows program contains a sample GUI using the new bracket style options. The old predefined + styles are now the bracket styles. The bracket options have been removed along with the indent‑brackets + and indent‑blocks options. The new bracket styles all use the same default indent of 4 spaces, therefore + it is not necessary to set an indentation from the bracket style. The new format is available for use with this + release. +

+

+   +

+ +

Artistic Style 2.01  (November 2010)

+ +

+ With a new Artistic Style release some unchanged source files will be formatted because of changes to Artistic + Style. You may want to format your source before making program changes in order to bring it up to date. +

+

+ A new feature at SourceForge is download maps that show a list of downloads by country. It is available from the + top menu at Develop > Download Stats (Beta), and clicking on the "top country" area. The list of downloads + shows about 75% of Artistic Style downloads are from non English speaking countries. This release is the start + of the internationalization of Artistic Style. +

+

+ Artistic Style now sets the native local so that characters from the user’s native language will be recognized + in directory names and file names. Artistic Style for Windows has also been changed to use the native locale. + For Linux systems using UTF-8 locales, characters from any language will be recognized and any combination of + languages can be used. For Windows, only languages recognized by the native codepage can be used. For example, + the English locale (codepage 1252) also has French, German, Italian, Portuguese, Spanish, plus several other languages. + Other locals, such as Chinese and Japanese, only support one language. Unicode was not used due to the varying + degree of support by different compilers for console applications. +

+

+ The locale setting also affects the way numbers are displayed. Language translations may be provided in a future + release. +

+

+ This is a major release (2.01) because of the internationalization and changes that will occur in the next couple + of releases. Future releases will contain a major change to the bracket options and a rewrite of the file access + method. Some of the requested changes require looking at blocks of code instead of single lines. The current program + has been patched to do this but a rewrite of the file input is needed. These are both major changes but with the + new test framework in place they should be manageable. +

+

+ There has been a change to the ‑‑min‑conditional‑indent option. Instead of using the number + of spaces it now uses a code expressed in number of indents. This will allow the option to be set independently + of the spaces per indent. If you are using the default setting of two indents, or a setting of zero indents, there + is no change necessary to the input. Otherwise, check the documentation for the new codes. +

+

+ The --style=linux has been changed to ALWAYS use a minimum conditional indent of one-half the indent length. This + is in the style definition and cannot be changed. If you do not want this setting use the K&R style instead. +

+

+ The MFC macros BEGIN_DISPATCH_MAP, BEGIN_EVENT_MAP, and BEGIN_PROPPAGEIDS are now formatted. +

+

+ Checksum verification has been added to source file output that will help assure that no code has been duplicated + or omitted. This is effective only in the debug configuration used for testing. +

+

+ The test framework has been changed from UnitTest++ to Google Test, which is actively maintained, has a mock object + framework (Google Mock), and good documentation. Regression and system testing have been automated with Python + scripts. Python has also been used for class verification checks and other repetitive procedures. +

+

+ If you use Visual Studio C++ Express the 2010 release has the ability to create x64 code. But you must use Vista + or Windows 7 and need to install the .NET Framework SDK. I have created a brief instruction page here. +

+

+ Thanks to Matthew Woehlke, Chris Schwarz, Chang Jiang, and Arseny Solokha for their contributions. +

+ +

Developers

+ +

+ On the library build of Artistic Style, the second argument of the fpError typedef and the javaErrorHandler declaration + has been changed from "char*" to "const char*". This could cause a compile error if not changed in the source + statements. +

+

+ There has been a change in the ‑‑min‑conditional‑indent option. Instead of using number + of spaces to indent it now uses a code expressed in number of indents. In the past this option was a problem because + it was also affected by changes in indent length. With this release there is only one variable affected. The option + is not affected by changes in indent length. The minimum conditional indent length is computed automatically by + ASFormatter after all the options have been processed. Refer to the code in astyle_main.cpp to see how the option + is processed. +

+

+ The --style=linux has been changed to ALWAYS use a minimum conditional indent of one-half the indent length. The + option is set in the function fixOptionVariableConflicts. +

+

+ The use of locales affects only the command line build. +

+ +

Artistic Style 1.24  (February 2010)

+ +

+ With a new Artistic Style release some unchanged source files will be formatted because of changes to Artistic + Style. You may want to format your source before making program changes in order to bring it up to date. +

+

+ A new bracket type option, ‑‑brackets=horstmann (-g), uses broken brackets and places run-in statements + on the same line as an opening bracket. This bracket type has about the same vertical compression as attached + brackets and in addition provides bracket alignment. It is the only style that combines the advantages of saving + space and aligning brackets. The "Tab and Bracket Options" section in the documentation contains the + details. To accommodate Hostmann brackets the "none mode" brackets will now allow run-in statements. + Array formatting has been changed to format run-in statements when required. There have been some general improvements + to array formatting. The minimum value for spaces per tab was changed from one to two. The example programs in + the "Developer Information" section have been changed to Horstmann brackets. +

+

+ Two new options, ‑‑add‑brackets (-j) and ‑‑add‑one‑line‑brackets + (-J), will add brackets to unbracketed one line conditional statements. The ‑‑add-brackets will add + the brackets according to the currently requested predefined style or bracket type. If no style or bracket type + is requested the brackets will be the attached type. The ‑‑add‑one‑line‑brackets + will add the brackets as single line brackets. This option implies ‑‑keep‑one‑line‑blocks + and will not break single line blocks. +

+

+ The above options allow two new predefined styles. Horstmann style, ‑‑style=horstmann (-A9), uses + Horstmann brackets and three spaces per indent. The so called "One True Brace Style", ‑‑style=1tbs + or ‑‑style=otbs (-A10), uses linux brackets and the option ‑‑add‑brackets. The basic + criteria for most predefined styles were obtained from the Indent Style discussion at Wikipedia. The "Predefined + Style Options" section in the documentation contains the details. +

+

+ The spaces per indent can now be changed for any of the predefined styles. In previous releases the option would + be ignored. This will allow any of the ‑‑indent options to be used with a predefined style. If the + spaces per indent is not specified, the default for the style will be used. +

+

+ A new option, ‑‑pad‑header (‑H), will insert space padding after headers ('if', 'for', + 'while'...). To remove any unwanted current space padding, use the option ‑‑unpad‑paren (‑U). + If both ‑‑pad‑header and ‑‑unpad‑paren are used, the headers will be padded + and the padding will be removed from other parens. This has required a change to the default formatting of paren + headers. They will now be left unchanged instead of automatically inserting space padding, unless the new option + is requested. +

+

+ New options --align-pointer=type (-k1), ‑‑align‑pointer=middle (-k2), and ‑‑align‑pointer=name + (-k3) will attach a pointer or reference operator (* or &) to either the operator type (left), operator name + (right), or align it between the type and name. The spacing between the type and name will be preserved, if possible. + The recognition of pointers and references has been improved. This resulted in an improvement of the ‑‑pad‑oper + (-p) option. +

+

+ A new option, ‑‑indent‑col1‑comments (-Y), will indent C++ comments beginning in column + one. By default C++ comments beginning in column one are not indented. This option will allow the comments to + be indented with the code. +

+

+ New options --lineend=windows (-z1), --lineend=linux (-z2), and --lineend=macold (-z3) will force + use of the specified line end style. Valid options are windows (CRLF), linux (LF), and macold (CR). MacOld style + is the format for OS 9 and earlier. Mac OS X uses the Linux style. Changes in line ends will cause the file to + be updated, even if no other changes occur. If one of these options is not used the line ends will be determined + automatically from the input file. +

+

+ Default line end processing has been improved to always output consistent line ends. It will use the line ends + that are most frequently used in the input. +

+

+ The Stroustrup predefined style has been changed to use 5 spaces per indent. This is the indentation used in the + book "The C++ Programming Language" by Bjarne Stroustrup. +

+

+ The minimum conditional indent for the Linux predefined style has been changed to 4, or one-half the indent-length. + The previous minimum conditional indent was 16 (2 indents). The new value corresponds to the soft tab in the style + description at Wikipedia and gives a better conformance to the definition of the style. And it gives a better + appearance to the continuation lines. +

+

+ Embedded SQL statements are now formatted correctly. The formatting of the SQL statements will be maintained as + long as the standard hanging indent format is used. If the "exec sql" statement is indented more than the following + statements, the SQL will be aligned in a single column. +

+

+ Assembler statement processing has been improved to include extended assembly and Microsoft specific assembler + lines and blocks. +

+

+ The --indent-classes (-C) option has been fixed to indent C++ struct blocks containing access modifiers (public, + protected, and private). The struct block is not indented if there are no access modifiers in the block. +

+

+ The formatting for C++ class initializer statements has been changed from two indents to one and an in-statement + indent added for continuation lines. +

+

+ The intermediate .tmp file used in formatting has been eliminated and memory is used instead. In most cases this + should result in a noticeable speed improvement. +

+

+ Checks for the maximum in-statement indent have been fixed. The indent for some long continuation lines may be + decreased. If you want the previous indentation, increase the ‑‑max‑in‑statement option. +

+

+ Occasionally, someone will use Artistic Style to format a file encoded with UTF-16 or UTF-32 bit encoding. These + files contain many nul bytes are incompatible with the 8 bit encoding assumed by Artistic Style. Since this rarely + happens, Artistic Style has been changed to list these files as "unformatted" and display a warning message. The + files must have a Byte Order Mark (BOM) for the encoding to be recognized. These files can be changed with the + program iconv and with some text editors such as SciTE. For more information see the Wikipedia discussion on "Comparison + of Unicode encodings", "Compatibility issues". +

+

+ The Artistic Style documentation has been changed to include a new "Padding Options" section. The padding options + were previously in the "Formatting Options" section. This was done to allow space for additional options in GUIs. +

+

+ The Scripts page has a couple of new scripts, including a "clean" script in python. +

+

+ There are new configuration and project files for Visual Studio, and additional files for Visual Studio 2010. + There are instructions in the "Install Information". +

+

+ The Intel compiler for Linux, release 11.1, has a new procedure for compiles. Read the new "Install Information" + before using this compiler release. +

+

+ There is now a Subversion repository for Artistic Style. A new Subversion web page describes how to check-out + the files. The source code is under development and some changes take several weeks to complete. And the intermediate + source files have not been through the extensive system tests that are done before each release. Use reasonable + precautions when using source code from the repository. +

+

+ SourceForge recently made changes to their website which caused a few problems. The web page links should be fixed + with this release. It seems that some bug reports may have been lost. If you have submitted a report that has + not been addressed please check to be sure it is still there. In addition Yahoo closed their GeoCities site which + made the AStyleWin programs temporarily unavailable. The new site is jimp03.zxq.net/. +

+

+ The release announcements mailing list was discontinued with the new SourceForge system. There is a new astyle-announce + mailing list that will be used instead. This is a low volume list that will be used for new release announcements + and notification of important repository commits. Member postings will not be accepted. Membership in the old + list was not retained so you will need to register for the new list. There is information for subscribing on the + "Bug Reports, Change Requests, Notification" section of the Home page. +

+

+ Thanks to J P Nurmi (align-pointer), Mario Gleichmann (pad-header), MrTact (lineend), Christian Stimming (<< + and >> operators), Wim Rosseel (Perl script), Colin D Bennett (64-bit code), and Ettl Martin (cppcheck) + for their contributions. +

+

+ The OpenVMS distribution is prepared by Jim Duff, an OpenVMS Systems Specialist living in Sydney, Australia. His + website is eight‑cubed.com. +

+ +

Developers

+ +

+ The Artistic Style for Windows program has been updated to support the current release and can be used for an + example GUI. It will run on Linux under WINE. It is available at jimp03.zxq.net +

+

+ The options --lineend=windows (-z1), --lineend=linux (-z2), and --lineend=macold (-z3) apply only + to the console build. It was not included in the developer builds because developers usually have their own method + for handling line ends. +

+

+ The option --break-closing-brackets has been moved from Bracket Options to Formatting Options. It was being mistaken + for a bracket type, which it is not. +

+

+ Rejecting a file for  UTF-16 or UTF-32 bit encoding apply only to the console build. Some class libraries, + such as wxWidgets (and probably Qt), have the methods to convert the files to UTF-8. The handling for these types + of files must be determined by the individual applications. +

+

+ There has been an additional variable, formattingStyle, added to the ASFormatter class. This is now the ONLY option + that needs to be set to define the style. Setting the individual options is no longer necessary. The individual + options are now set in the fixOptionVariableConflicts function in ASFormatter. The predefined style options will + now override all other options. The order of entry does not matter as in previous versions. +

+

+   +

+ +

Artistic Style 1.23  (February 2009)

+ +

+ With a new Artistic Style release some unchanged source files will be formatted because of changes to Artistic + Style. You may want to format your source before making program changes in order to bring it up to date. +

+

+ In the last few years the names of indent styles have been somewhat standardized. A typical example is the Indent + Style discussion at Wikipedia. To keep up to date with the industry, changes have been made to the names of two + of the styles. The ANSI style can now also be Allman or BSD, and for the KR or Java style you should now use only + Java. The KR style has always been basically the same as the Java style. The KR style is depreciated and will + be removed sometime in the future. +

+

+ Four new predefined styles have been added, K&R (with an &), Stroustrup, Whitesmith, and Banner. K&R + style uses Linux type brackets where the depreciated KR style uses attached brackets. Notice that K&R and + KR are two different styles. Stroustrup style uses the new stroustrup brackets described below. Whitesmith has + broken brackets that are indented. Banner has attached brackets that are indented. The following table summarizes + the changes: +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
old style    new style
ansiallman or ansi or bsd
java or krjava
gnugnu
linuxlinux
nonek&r or k/r
nonestroustrup
nonewhitesmith
nonebanner
+
+ +

+   +

+

+ There is a new Stroustrup style and bracket type. It is similar to the Linux bracket type except that the brackets + are attached to namespaces and classes instead of being broken. It is the style used by Bjarne Stroustrup, the + founding father of C++, in his book "The C++ Programming Language". +

+

+ Indenting brackets in the Whitesmith and Banner styles causes a 'hanging indent' with switch statements and C++ + class modifiers (public, private, protected). Microsoft Visual Studio avoids this by giving class and switch blocks + an extra indent when brackets are broken (Whitesmith style). Gnu Emacs gives switch blocks an extra indent but + not class blocks. With indented, attached brackets (Banner style), Visual Studio does not use an extra indent + and Emacs does not have the style. Artistic Style uses an extra indent for switch blocks and C++ class blocks + for both Whitesmith and Banner styles. This provides the best appearance in defining the style. If + a different format is wanted, use the individual options instead of the predefined style. You can try indent‑brackets, + indent‑classes, and indent‑swiches on a class or switch block to see the results. +

+

+ The GNU style and indent‑blocks option have been changed to indent only the blocks within a function body. + The opening bracket for namespaces and classes is no longer indented. The opening bracket for functions remains + not indented. This is the same formatting used by the Emacs editor and is in compliance with the GNU standard. + The GNU style has also been changed to NOT indent namespaces by default. Namespaces can be indented by using the + indent‑namespaces option. This is consistent with the other predefined style options. +

+

+ The predefined style options will now override all other options. It does not depend on order of entry as in previous + versions. Using a predefined style will give that style regardless of other conflicting entries. The predefined + styles options now define only the bracket placement and sometimes the spaces per tab. This will give users the + option to define the other details according to their preference. The 'Predefined Style Options' section in the + documentation contains the details. +

+

+ Changes have been made to some of the long options. Most configuration files will NOT allow options to have duplicate + keys (e.g. the Windows registry and wxWidgets). The key is the value before the first '=' sign. If there is no + '=' sign then the entire option is the key. The options were changed to eliminate duplicate keys when + more than one option is allowed. The old options are depreciated but will still be valid until at least the next + release. The short options remain the same. The following options have changed: +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
old option    new option
force-indent=tab=#indent=force-tab=#
brackets=break-closingbreak-closing-brackets
pad=operpad-oper
pad=parenpad-paren
pad=paren-outpad-paren-out
pad=paren-inpad-paren-in
unpad=parenunpad-paren
one-line=keep-statementskeep-one-line-statements
one-line=keep-blockskeep-one-line-blocks
+
+ +

+   +

+

+ The "else if" statements will now be placed on a single line by default. This is described as a 'fix' since it + was apparently always supposed to do this. The headers will be broken only if the option 'break‑elseifs' + is specified. Most users want the statements joined since breaking them requires an extra indent. +

+

+ The convert‑tabs option has been changed to maintain the correct spacing according to the current tab setting. + Previously a tab was replaced by a single space. The current option for spaces per tab is used. It may NOT produce + the expected results if convert‑tabs is used when changing the spaces per tab. The tabs are NOT replaced + in quotes. +

+

+ The break‑blocks and break‑blocks=all options have finally been fixed. They will no longer break statements + following the block and will keep preceding comments with the block. Many other fixes were required for the options + to work correctly. The "Release Notes" page has the details. +

+

+ A new delete‑empty‑lines option will delete empty lines within a function or method. If used with + break‑blocks or break‑blocks=all it will delete all lines EXCEPT the lines added by the break‑blocks + options. +

+

+ There is a new 'formatted' (‑Q) option that displays only the files that have been formatted. Files that + are unchanged are not displayed. +

+

+ Short options have been added for the predefined styles. +

+

+ Semi‑colons are now always space padded. All commas are space padded if pad‑oper is used. +

+

+ The C/C++ keyword 'extern' no longer causes an extra indent. +

+

+ There have been several important fixes to the indent‑brackets and indent‑blocks options. +

+

+ There have been several important fixes to C# formatting. +

+

+ The scripts page has a new Emacs script containing hooks that will set the Emacs style options to the default + options used by Artistic Style. It also defines a Banner style. It can be used to compare output from the two + programs. The files will not be exact but it should be reasonably close. If you can improve the Emacs script I + would like to have the changes. +

+

+ There are two new projects on the Links page. CodeLite is a C++ development environment with + some useful features, including a template to generate a test program using the excellent tool UnitTest++. target="astyle" + title="open new window">Highlight converts source code to formatted text with syntax highlighting. + It was used it for the source code in the Developer Information section. +

+

+ I need a Mac OS X user to do testing on new releases. The test usually take 30 minutes at the most. They may need + to be repeated two or three times depending on the results. Programming knowledge is not necessary but will probably + be helpful. Reply to the project email address if you would like to volunteer. +

+

+ The OpenVMS distribution is prepared by Jim Duff, an OpenVMS Systems Specialist living in Sydney, Australia. His + website is eight‑cubed.com. +

+

+ Thanks to Eran Ifrah and Max Horn for their contributions. Travis Robinson wrote the original C# interface program. +

+ +

Developers

+ +

+ There is a new page in the Developer Information that has an example of calling Artistic Style from a C# program. +

+

+ There was an omission in the peekNextLine function added in the last release which causes it to bypass empty lines. + If you copied the function into a program, the change is at the end of peekNextLine in astyle_main. The line containing + the change is marked with comments. Not correcting it may cause an infrequent line break if the option break‑blocks + or break‑blocks=all is used. The break will occur only if there are empty lines within comment lines that + precede a header. +

+

+ There has been an additional variable, formattingStyle, added to the ASFormatter class. This is now the ONLY option + that needs to be set to define the style. Setting the individual options is no longer necessary. The individual + options are now set in the fixOptionVariableConflicts function in ASFormatter. +

+

+ The predefined style options will now override all other options. The order of entry does not matter as in previous + versions. This will be done even if astyle_main is not used by your system. This was done by moving the checks + from astyle_main to ASFormatter. The procedure is in the function fixOptionVariableConflicts in ASFormatter. +

+

+ The predefined style options now define only the bracket placement and sometimes the spaces per tab. This will + give users the option to define the other details according to their preference. It is best if the other options + are NOT disabled when a predefined style is selected. All options should be left available to modify the style. + The conflicts will be resolved by the fixOptionVariableConflicts function which is called after all options have + been processed. All you need to do is set the options selected by the user. +

+

+ The Artistic Style for Windows program has been updated to support the current release. It is available at jimp03.zxq.net +

+

+ I apologize for the unplanned changes this may add to your system. But Artistic Style is starting to mature as + an application and the changes are needed to bring it up to date. If you have any questions or problems, email + me and I will do my best to help you resolve them. +

+

+   +

+ +

Artistic Style 1.22  (April 2008)

+ +

+ This release contains many bug fixes. The emphasis was on formatting fixes for C# files. In the last two releases + there have been over 80 items removed from the bug report. There have been many more fixes which were not reported + but were discovered while testing. The new options in this release exposed many unreported formatting problems. + I will try to fix the ones remaining in the next two or three releases. Some of them will be difficult to fix. + See the Release Notes for a complete list of changes. +

+

+ Starting with this release, if a file is not changed by Artistic Style a new file and a backup + file are not created. A "make" will not recompile the unchanged file and it will not be committed to a revision + control system. A console message will indicate that the file is unchanged. Note that this is different from using + the ‑‑preserve‑date option. This option retains the date on files that have + changed. In this case the changed files will still be recompiled and committed to revision control. (‑‑preserve‑date + actually changes the time by one unit). +

+

+ In the rare case when Artistic Style aborts, the file being formatted will no longer be deleted. This is done + by using a temporary output file (.tmp). It should now be safe to manually abort Artistic Style and restart at + any time. The backup of files that were previously formatted will not be replaced. +

+

+ The console display has been changed. The default now displays one line per file. This will be useful if only + one file is being formatted, such as when Artistic Style is called from a text editor or development environment. + A new ‑‑verbose (‑v) option will display optional information, such as release number and statistical + data. A new ‑‑quiet (-q) option will suppress all output except error messages. Some short options + have changed to accommodate the new options. The short option for ‑‑version is now -V (old -v) and + for ‑‑convert‑tabs is ‑c (old ‑V). +

+

+ A new ‑‑recursive (-r, or -R) option will process subdirectories recursively. The filename should + contain a wildcard (e.g. "$HOME/astyle/src/*.cpp"). Linux users should place the filename in double quotes so + the shell will not resolve the wildcards. Windows users should not include wildcard object files, + like setargv (Visual C) or wildargs (Borland), in the compiles. Wildcard processing in MinGW was excluded by adding + "int _CRT_glob = 0" as a global variable. (It could also be excluded by linking to CRT_noglob.o). + Artistic Style now does the wildcard processing internally. +

+

+ When processing directories recursively it is sometimes necessary to exclude certain files or directories. This + can be done using a new exclude (‑‑exclude=file‑or‑directory) option. There is no short + option. Multiple exclude statements are allowed. The Other Options section of the documentation contains the details. +

+

+ It is always a good idea to create a backup for files that have been formatted. This can cause a problem in that + it creates a lot of excess files in your source directories. There are now new script files available that will + move the files to a backup directory. The original directory structure will be maintained the in the backup. There + is a batch file for Windows and a shell script for everyone else. They are available in the Scripts section of + the home page. +

+

+ There is a new Links page that lists programs using Artistic Style. In general, they seem to be good quality software. +

+

+ If you are using a development environment to compile Artistic Style, be sure to read the Compiler Options section + in the Install Information. In particular, you should define NDEBUG in the Release compile to remove the assert + statements. There are quite a few of these and they will slow down processing if NDEBUG is not used. The assert + statements are necessary due to the nature of the program. Also, when reporting bugs it is a good idea to log + in first. Occasionally, more information is needed on a problem. If the poster did not log in there is no way + to contact them. +

+

+ A Java Native Interface has been added for Java developers. This will allow an Artistic Style shared library (DLL) + to be called from a Java program. A shared library (Dll) using the Java interface can still be called from C, + C++, or C# programs. There is a sample program in the Developer Information. +

+

+ Developers using Artistic Style in another project should be aware that there are two new functions + that have been added to the ASStreamIterator class (peekNextLine() and peekReset()). These will have to be coded + into source modules which use Artistic Style without astyle_main. In most cases the functions can simply be copied + without the template information. The assert statements may also be removed. A variable will need to be added + to the class and another may need to be modified. If the shared or static library configuration is being used + then no changes are necessary. +

+

+ The file globing function was obtained from "The Code Project" and was written by Jack Handy. It was modified + slightly to make the comparisons case insensitive for Windows. +

+

+ The OpenVMS distribution is prepared by Jim Duff, an OpenVMS Systems Specialist living in Sydney, Australia. His + website is eight‑cubed.com. +

+

+ Thanks to Emilio Guijarro and Jens Krinke for their contributions, and to Sam Cooler for testing the Mac OS X + version. +

+

+   +

+ +

Artistic Style 1.21  (June 2007)

+ +

+ This release contains many bug fixes. Array formatting and indentation has been improved. Arrays and enums are + now formatted by a different procedure than functions. Brackets will now attach to lines with comments. Brackets + will be broken from lines with comments without bringing the comments with them. All comments will remain in their + original column, if possible. The formatting of empty blocks was fixed. The BracketType definition was expanded + and the bracket types are now correctly identified. There are several formatting fixes for Java files. See the + Release Notes for a complete list of changes. +

+

+ A new option, --preserve-date (-Z), has been added. This will retain the date modified of the original file in + the new formatted file. Otherwise the new file will contain the current date. +

+

+ The option --errors-to-standard-output has been shortened to --errors-to-stdout. The short options + -c (mode=c) and -j (mode=java) have been removed. The options should seldom be needed since the mode is now set + automatically from the file extension for each source file instead of for each program execution. + A new long option --mode=cs (C#) has been added. Key words are now set for each file depending on the file mode + (C, Java, or C#). This will eliminate formatting problems caused by not being able to identify the source code + language. +

+

+ There has been a change to the Linux style bracket formatting for C++ header files. In the past brackets have + been broken for function definitions within a class. With this release the brackets will be attached. The brackets + will also be attached for arrays, structs, enums, and other top level objects that are not classes or functions. + The Linux style formatting for Java and C# has not been changed. +

+

+ This release supports only one platform in each distribution package. In the past all platforms were included + in every package. If you use Artistic Style on more than one platform you will need to download packages for each + platform. The main difference in platforms is the build directory and the line endings. The source code and documentation + are the same for all packages. +

+

+ There are new instructions about optimizing compiler options in the Install Instructions. If you are compiling + using a development environment you may want to read them. +

+

+ If you have broken brackets with comments attached to the opening bracket instead of the previous line, do the + following before formatting again with broken brackets. Use the current Artistic Style release + (1.21). Format the source using attached brackets to reattach the brackets and the comments to the previous line. + Then format the source again using broken brackets. This will move the brackets to the next line without the comments. + The comments will now be on the correct line. +

+

+ There is a new multi-platform GUI program, UniversalIndent, available at sourceforge.net/projects/universalindent. + It allows you to view the effects of the Artistic Style options on your source code without saving the file. You + can review the results of the formatting options before updating the file. It can be used with a test file or + with your actual source code. It supports several other formatting programs. The Artistic Style for Windows + program has been updated to support the current release. It is available at jimp03.zxq.net +

+

+ There have been a few inquiries about how to customize Artistic Style for an unsupported format. Changes can be + made with Python or another text processing program after formatting the source, or you can modify the Artistic + Style source code itself. The best place to modify the code is usually in ASEnhancer.cpp. The ASEnhancer class + is called after the main formatting has been done so you are getting a formatted file. If you just need to change + the indentation of a few things this is probably the best place to do it. +

+

+ There is now a distribution package for OpenVMS thanks to Jim Duff, an OpenVMS Systems Specialist living in Sydney + Australia. His website is at eight-cubed.com. +

+

+ Thanks to Norbert Holzki and Siemens AG, Medical Solutions, Forchheim, Germany for testing the array formatting. +

+

+ Thanks to Sam Cooler for testing the Mac OS X version. +

+

+   +

+ +

Artistic Style 1.20  (January 2007)

+ +

+ Release 1.20.2 fixed problems with the new stream I/O procedure added in release 1.20.1. Release 1.20.1 improved + the processing for Mac OS X platforms. The compatibility with TextWrangler was improved. There is now a separate + release for Mac. +

+

+ Artistic Style will now indent message maps for Microsoft Foundation Class (MFC) and event tables for wxWidgets. + The option --brackets=break-closing-headers has been shortened to --brackets=break-closing and a short option + added (-y). There have been short options added for --break-elseifs (-e), --indent-preprocessor (-w), --break-blocks + (-f), and --break-blocks=all (-F). +

+

+ With this release the Artistic Style license changes from the GNU General Public License (GPL) to the GNU Lesser + General Public License (LGPL). You can use Artistic Style for free or commercial software without charge. Projects + that use Artistic Style do not have to make the their source code available. If Artistic Style itself is modified, + however, the modified Artistic Style source code must be made available. See the GNU Lesser General Public License + for more information. +

+

+ There is a new preprocessor option to aid developers in using Artistic Style with a Graphical User Interface (GUI). + It is no longer necessary to remove the source module astyle_main.cpp and write embedded code to call the formatter. + It can be compiled as a static library or a shared library (DLL), or the entire source code can be included in + the project. See the Artistic Style Developer Information for the calling procedure and other details. +

+

+ There is a sample GUI program for Windows available at http://jimp03.zxq.net/. It uses the unmodified Artistic + Style compiled for a GUI. The source code needs some work so it is not available for now. It should work under + Linux using WINE. Future enhancements and platform support will depend on the response to the sample program. +

+

+ To support the new Artistic Style preprocessor option there are new makefiles and project files. Windows users + have a project file for Microsoft Visual C++ 2003 (version 7). Linux users have a new makefile that has several + new options. The location of both files is in the build directory. Be sure to read the "Artistic Style Install + Information" for the details. +

+

+ Intel® is now offering it's C++ and Fortran compilers free for non-commercial use. Information is available + at the Intel® Software Development Products website. Click on the "Free Non-Commercial Download" link to see + if you qualify. The Intel Compilers on Windows and Linux require that other compilers be installed (Microsoft + Visual C++ or GNU gcc respectively). This is because the Intel Compilers require the header files, runtime libraries + and linkers distributed as part of these other compilers. If you want to use this compiler there is now a makefile + (makeintel) included with the project. See "Artistic Style Install Information" for instructions. +

+

+   +

+ +

Artistic Style 1.19  (July 2006)

+ +

+ Most changes this release were again concerned with the options pad=oper and pad=paren. The formatting still worked + a little different if both options were declared than if only one was used. The problems with distinguishing the + multiplication operator from pointers, and of separating an object from the member access pointer (->) were + fixed. +

+

+ A new option, unpad=paren, was added. This will undo the pad=paren, pad=paren-out and pad=paren-in options. It + can be used alone or with pad=paren-out or pad=paren-in. If used alone it will unpad all parens that have been + previously padded. If used with a paren padding option, the paren padding option will take precedence and only + the unnecessary padding will be removed. This will enable the paren padding to be changed in one formatting run. +

+

+ Padding to paren headers (e.g. "if", "for", "while") was reinstated. This was done in previous releases if pad=oper + was used. Since most people used this option, the headers were usually padded. The general opinion was that they + looked better padded, especially in the case of "else if" statements. Since it is a minor point, it was not made + an option. +

+

+ This is the third release of Artistic Style in the last four months. The reason for the frequent releases was + the number of pervasive errors in the formatting. In the future there will probably be two or three new releases + per year, or one every four to six months. It will take about three years to make all the changes that are planned + at this time.; The releases will be a combination of fixes, changes to formatting, and new features. +

+

+   +

+ + + + diff --git a/External/Tools/AStyle/doc/notes.html b/External/Tools/AStyle/doc/notes.html new file mode 100644 index 0000000000..0c59056303 --- /dev/null +++ b/External/Tools/AStyle/doc/notes.html @@ -0,0 +1,284 @@ + + + + + + Artistic Style - Release Notes + + + + + + + + +

Artistic Style Release Notes

+ +

+   +

+ +

Artistic Style 2.06  (Pending)

+ +
    +
  • Add new Objective‑C options "pad-return-type" (-xq) and "unpad-return-type" (-xr).
  • +
  • Add new option pad-comma (#100).
  • +
  • Add removing spaces before a comma (#100).
  • +
  • Add formatting of C++14 single-quote digit separators (#337).
  • +
  • Improve align-method-colon to applied to Objective‑C method calls.
  • +
  • Improve recognition of C++11 uniform initializer brackets (#381).
  • +
  • Change align-method-colon short first line to align on the longest line instead of the first line.
  • +
  • Fix attaching "if" statements to a #else preprocessor directive (#356).
  • +
  • Fix not clearing global variables for a new file (#364).
  • +
  • Fix C# to recognize "using" as a header.
  • +
  • Fix C# to always recognize "forever" as a header.
  • +
  • Fix end of line comments for "pad-method-prefix" and "unpad-method-prefix".
  • +
  • Fix end of line comments for "pad-method-colon".
  • +
  • Refactoring: +
      +
    • Consolidate scattered ASFormatter conditional statements into a padParenObjC method.
    • +
    • Remove ASBase methods from being inlined as class definitions.
    • +
    • Portability changes for additional compiler support (#352).
    • +
    +
  • +
+ +

Artistic Style 2.05.1  (December 2014)

+ +
    +
  • Fix incorrectly reporting files containing disabled formatting as being formatted.
  • +
  • Fix incorrect handling of quoted arguments in the options file (#321).
  • +
  • Fix error in identifying an enum return type as an enumeration (#322, 323).
  • +
  • Fix error in identifying an enum argument as an enumeration (#327).
  • +
  • Fix recognition of Qt keywords when used as variables in C++ (#329).
  • +
  • Fix recognition of a pointer in a C++ cast (#316).
  • +
  • Fix removing trailing whitespace after a changed pointer or reference cast.
  • +
+ +

Artistic Style 2.05  (November 2014)

+ +
    +
  • Add new bracket style option "style=vtk" (#155).
  • +
  • Add new option "indent-preproc-block" to indent blocks of preprocessor directives (#21, #114, #229, + #242, #294).
  • +
  • Add new option, "dry-run", to run AStyle without updating the files (#184, #285).
  • +
  • Add new options, "html" (-!") and "html=###", to display the HTML help documentation in the default browser. +
  • +
  • Add tags "*INDENT-OFF*" and "*INDENT_ON*" to disable formatting of source code blocks + (#2, #47, #55, #78, #110, #176).
  • +
  • Add tag *NOPAD* to disable selected formatting on a single line.
  • +
  • Add '__attribute__ ((visibility ("default")))' to Linux exported functions.
  • +
  • Remove option "style=ansi" and make it depreciated (#146).
  • +
  • Remove fix for broken 'case' statements from release 2.02.1, Nov 21, 2011.
  • +
  • Improve Korean translation (#256).
  • +
  • Change shared libraries to include the version number as part of the file name (#264)
  • +
  • Change "help" display to stdout to allow piping and redirection (#63).
  • +
  • Change "version" display to stdout.
  • +
  • Change headers to include foreach, forever, Q_FOREACH, and Q_FOREVER (#98, #154).
  • +
  • Change compiler definition ASTYLE_NO_VCX (no Visual Studio exports) to ASTYLE_NO_EXPORTS.
  • +
  • Change shared library error handler argument from "char*" to "const char*".
  • +
  • Fix not recognizing noexcept, interrupt, and autoreleasepool as pre-command headers (#225, #259).
  • +
  • Fix formatting of C++11 uniform initializer brackets (#253, #257, #260, #284).
  • +
  • Fix to not automatically space pad C++11 uniform initializer brackets (#275).
  • +
  • Fix formatting of enums with leading commas (#159, #179, #270).
  • +
  • Fix formatting of logical && operator in class initializers (#290).
  • +
  • Fix flagging a 'const' variable as a 'const' method (#275).
  • +
  • Fix piping and redirection adding an extra character to the output (#245, #252, #305).
  • +
  • Fix "indent-modifiers" to attach class access modifiers to Horstmann style brackets.
  • +
  • Fix ASFormatter to correctly recognize the end of a C++ raw string literal (#261).
  • +
  • Fix to recognize C++11 "enum class" as an enum (#303).
  • +
  • Fix indent of C++11 "noexecpt" statements within a class (#260, #304).
  • +
  • Fix not resetting templateDepth when a template was not found (#295).
  • +
  • Fix formatting of multiplication in a block paren (#144).
  • +
  • Fix whitespace padding when formatting an rvalue references (#297).
  • +
  • Fix to recognize an rvalue reference without a name (#265).
  • +
  • Fix to not identify an operator overload method as a calculation (#296).
  • +
  • Fix concatenating multiplication with a pointer dereference (#291).
  • +
  • Fix recognition of a pointer dereference following a question mark (#213).
  • +
  • Fix extra space after a trailing reference type (#300).
  • +
  • Fix _asm blocks not being identified as a block opener and the variable not cleared on exit (#163).
  • +
  • Fix indentation of line comments before a "class" opening bracket.
  • +
  • Fix indentation of line comments before a "namespace" opening bracket.
  • +
  • Fix isBracketType() method to correctly process a NULL_TYPE.
  • +
  • Fix unpad-paren to recognize additional variables (#43, #132, #143).
  • +
  • Fix indentation of C# "let" statements.
  • +
  • Fix a few omissions with "fill-empty-lines".
  • +
  • Fix file read to read 64K blocks of data.
  • +
  • Refactor to un-obfuscate (clarify) the code, and improve design and decomposition: +
      +
    • Extract class Utf8_16 from ASConsole.
    • +
    • Replace Linux dependency on iconv with a Utf8_16 class for ASLibrary.
    • +
    • Move global "using" statements to the astyle namespace in astyle.h and ASLocalizer.h.
    • +
    • Move shared library declarations from astyle.h to astyle_main.h.
    • +
    • Move indentable macros from ASEnhancer to ASResource and create static pairs.
    • +
    • Simplify ASBeautifier procedure to identify the colon (:) type.
    • +
    • Major refactoring in ASBeautifier to create separate variables for an enum, a class statement and a class initializer.
      + This was needed to fix the processing of C++11 uniform initializers in a class initializer. +
    • +
    • Minor changes to ASFormatter and ASBeautifier based on results of the Clang analyzer.
    • +
    • Change several methods in astyle_main to "const".
    • +
    +
  • +
+ +

Artistic Style 2.04  (November 2013)

+ +
    +
  • Add new programming language Objective‑C.
  • +
  • Add new bracket style option "style=google" (-A14).
  • +
  • Add new option "indent-preproc-cond" (xw) to indent preprocessor conditional statements (#118).
  • +
  • Add new bracket modify options "attach-namespaces", "attach-classes", "attach-inlines", and "attach-extern-c". +
  • +
  • Add new option "indent-modifiers" (-xG) to indent class access modifiers one-half indent (#130).
  • +
  • Add new option "remove-brackets" (-xj) to remove brackets from single line conditional statements.
  • +
  • Add new option "remove-comment-prefix" (-xp) to remove the leading '*' from multi-line comments.
  • +
  • Add new option "align-method-colon" (-xM) to align Objective‑C method colons.
  • +
  • Add new option "pad-method-colon=#" (-xP#) to space pad Objective‑C method colons.
  • +
  • Add new options "pad-method-prefix" (-xQ), and "unpad-method-prefix" (-xR) to pad the Objective‑C "-" and + "+" method prefix.
  • +
  • Add new dll entry point AStyleMainUtf16 for processing C# UTF-16 strings.
  • +
  • Add formatting of C++11 raw string literals (#222).
  • +
  • Add "style=knf" as an alternative to "style=linux".
  • +
  • Remove depreciated "bracket=" options.
  • +
  • Improve recognition and formatting of pointers and references (#174 and other changes).
  • +
  • Improve the recognition of block-opening brackets.
  • +
  • Improve code using a static code analyzer (#195).
  • +
  • Change "max-code-length" to include Objective‑C methods.
  • +
  • Change "indent-elseifs" and "break-blocks" to look ahead only if in command-type brackets (speed improvement). +
  • +
  • Fix linux bracket styles to break the opening bracket in inline function definitions (#185).
  • +
  • Fix indentation of switch block comments (#164).
  • +
  • Fix enums to indent with tabs when requested (#92, #121).
  • +
  • Fix formatting of rvalue reference without a name in a declaration (#219).
  • +
  • Fix "pad-first-paren-out" to not pad if the following parens are empty (#232).
  • +
  • Fix end-of-statement reset when comments follow closing bracket.
  • +
  • Fix the ASBeautifier active and waiting stacks to delete the ASBeautifier objects before deleting the pointers. +
  • +
  • Fix ASBeautifier "init" to delete the tempStack vectors before deleting the tempStack.
  • +
  • Fix Linux piping problem by changing "cin" input to build a stringstream before formatting.
  • +
  • Fix to identify the correct bracket type when 'extern "C"' is part of the enum definition.
  • +
  • Fix to clear 'extern "C"' variables when the block is closed.
  • +
  • Fix unindented 'extern "C"' to not indent when in a #else preprocessor directive.
  • +
  • Fix not always correctly formatting linux type brackets for enum blocks.
  • +
  • Fix align-pointer in a range-based for statement (#217).
  • +
  • Fix pointer-reference argument alignment to correctly position a following comment (#235).
  • +
  • Fix to not attach a bracket to a line ending in a backslash '\' (#186, #214, #220).
  • +
  • Fix to recognize templates using multiple lines (#85, #87, #136).
  • +
  • Fix formatting of template continuation lines (#85, #87, #136).
  • +
  • Fix to allow '^' as an array operator (#233).
  • +
  • Fix an "enum" argument being mistaken for an enumeration (#211).
  • +
  • Fix to recognize a non-instatement array after a "},{" sequence.
  • +
  • Fix "pad-oper" to not pad before a following comma.
  • +
  • Fix recognition of an operator when the calculation contains a bitwise "not" '~' (#166).
  • +
  • Fix to allow a preprocessor statement within a preprocessor define (#238).
  • +
  • Fix preprocessor comparison to check for whole words (#246).
  • +
  • Fix "add-brackets" when a line contains more than one paren pairs (#181).
  • +
  • Fix to allow Mac old CR line endings in the options file (#129).
  • +
  • Refactor to aid debugging and improve design and decomposition: +
      +
    • Move ALL preliminary indentation calculations to computePreliminaryIndentation() in ASBeautifier.
    • +
    • Move calculation of 'force tab' indents to preLineWS() in ASBeautifier.
    • +
    • Combine methods init() and init(ASSourceIterator*) in ASBeautifier.
    • +
    • Extract method adjustParsedLineIndentation() in ASBeautifier.
    • +
    • Extract method parseCurrentLine() in ASEnhancer. 
    • +
    • Remove astyle_main.cpp unused functions getFilesUnchanged, getOptionsFileRequired, and setOptionsFileRequired. +
    • +
    +
  • +
+ +

Artistic Style 2.03  (April 2013)

+ +
    +
  • Add new option "indent=force-tab-x=#" (-xT#) to allow a tab length that different from the indent length (3430662). +
  • +
  • Add new option, "pad-first-paren-out" (xd), to pad only the first paren in a series on the outside (3350356). +
  • +
  • Add new option "max-code-length=#" (-xC#) to limit the length of code on a line.
  • +
  • Add new option "break-after-logical" (-xL) to modify a "max-code-length" line break for conditionals.
  • +
  • Add new option "close-templates" (-xy) to close whitespace in the angle brackets ">" of template + definitions.
  • +
  • Add formatting of C++ rvalue references (&&) using the existing "align-pointer" and "align-reference" + options.
  • +
  • Add formatting of C++/CLI managed pointers (the "^" character) to the "align-pointer" option.
  • +
  • Add translations for Dutch, Finnish, Italian, Japanese, Korean, Polish, Portuguese, Russian, Swedish, and Ukrainian. +
  • +
  • Remove byte-order-mark from ASLocalizer.cpp.
  • +
  • Change the short option for delete-empty-lines from "xd" to "xe".
  • +
  • Change the ASTYLE_LIB option to remove __declspec for a Visual C static library when ASTYLE_NO_VCX is also declared. +
  • +
  • Change to remove any space padding in  a pointer to pointer (**).
  • +
  • Fix "break-elseifs" to format one-line "if" and "else" statements the same as when the option is not used. +
  • +
  • Fix "break-elseifs" to break else-if statements when "keep-one-line-statements" also is requested.
  • +
  • Fix "break-elseifs" to correctly format comments preceding the else-if.
  • +
  • Fix C# not correctly identifying lambda expressions as a command-type bracket.
  • +
  • Fix C# preprocessor statements adding extra empty lines when "break-blocks" is used.
  • +
  • Fix C# padding "get" and "set" statements that are not headers when "break-blocks" is used.
  • +
  • Fix C# to recognize the "#line" statement.
  • +
  • Fix C++11 standard for range-based "for" loops (3458402, 3480095).
  • +
  • Fix C++11 standard for "enum" with a base type (3458402).
  • +
  • Fix C++11 standard for template closing angle brackets (no space required) (3495192).
  • +
  • Fix C/C++ keyword 'extern "C"' in a preprocessor causing an extra indent (1514844, 2953388, 2963382, 3093842, + 3467479).
  • +
  • Fix breaking after a switch "default" statement when "break-elseifs" is used without "keep-one-line-statements" + (3559365).
  • +
  • Fix in-statement arrays to indent correctly when they exceed the "max-instatement-indent".
  • +
  • Fix quote continuation sometimes being processed as a preprocessor directive (3445475).
  • +
  • Fix formatting of some conditional statements on a continuation-line.
  • +
  • Fix Java formatting of generics with wildcards (3428140).
  • +
  • Fix formatting of pointers and references to work with the new "max-code-length" option.
  • +
  • Fix formatting of pointers and references after a template close.
  • +
  • Fix formatting of empty attached brackets (3505002).
  • +
  • Fix C comments beginning a line breaking if they follow a semi-colon (3502700).
  • +
  • Fix "pad-header" not padding "return" and "throw" statements (3509134).
  • +
  • Fix recognition problems with templates.
  • +
  • Fix "struct" return type being mistaken for a struct.
  • +
  • Fix "pad-oper" in java for-each loop.
  • +
  • Fix recognition of a macro multi-line comment (3414970).
  • +
  • Fix bracketTypeStack entries added by #if and #else if the # is separated from the word.
  • +
  • Fix C++ breaking a line on an access modifier in a one-line block when "keep-one-line-blocks" is used. +
  • +
  • Fix memory leak when "ascii" option is used.
  • +
  • Fix memory leak when a preprocessor statement is used without a closing #endif.
  • +
  • Fix preprocessor directive to allow compiling with mingw-x64 compiler.
  • +
  • Fix redirection on Windows so it does not hang when Linux line ends are used (3514712).
  • +
  • Fix redirection on Linux to output the correct line ends (3514712).
  • +
  • Fix non-portable return value on locale name (3452574).
  • +
  • Fix assert errors caused by not checking the text length on the return from peekNextText().
  • +
  • Fix spelling of "depreciated" in help message (3454735).
  • +
  • Refactor to improve design and decomposition: +
      +
    • Fix warning messages from Visual Studio static code analysis.
    • +
    • Fix warning messages from cppcheck, except for constructor uninitialized variables (false positive).
    • +
    • Remove astyle_main.h dependency from ASLocalizer.h
    • +
    • Remove appendChar() from the inline functions.
    • +
    • Extract methods for pointer or reference alignment in ASFormatter.
    • +
    +
  • +
+ +

+   +

+

+ Previous releases are available in the Release + Notes Archives. +

+

+   +

+ +

+ + +

+ +

+   +

+ + + + + diff --git a/External/Tools/AStyle/doc/notesArchives.html b/External/Tools/AStyle/doc/notesArchives.html new file mode 100644 index 0000000000..5bb695c030 --- /dev/null +++ b/External/Tools/AStyle/doc/notesArchives.html @@ -0,0 +1,1215 @@ + + + + + + Artistic Style - Release Notes Archives + + + + + + + + +

Artistic Style Release Notes Archives

+ +

+   +

+ +

Artistic Style 2.02.1  (November 2011)

+ +
    +
  • Add to C# the recognition of pointers and address-of operators.
  • +
  • Improve recognition of pointers and references (3,314,499, 3,298,204, and 2,990,608).
  • +
  • Improve alignment of a reference to a pointer (*&).
  • +
  • Fix crash with "align-pointer=type" when pointer to pointer (**) starts a new line (3,431,431).
  • +
  • Fix breaking after a "case" statement when "break-elseifs" is used without "keep-one-line-statements" (3,421,577, + and 3,314,247).
  • +
  • Fix "pad-oper" used with "keep-one-line-statements" not padding operators in a one-line "case" statement. +
  • +
  • Fix not recognizing a "pointer dereference" or "address of" that follows a comment (3,431,431).
  • +
  • Fix "break-blocks" used with "delete-empty-lines" not correctly breaking blocks on the first run.
  • +
  • Fix "pad-oper" not padding the alternate comparison operators "and" and "or" (3,342,373).
  • +
+ +

Artistic Style 2.02  (May 2011)

+ +
    +
  • Add new program module, ASLocalizer, containing language translations.
  • +
  • Add new short option prefix "x" to allow for expansion of short options.
  • +
  • Add new command line only option "ascii" (-I).
  • +
  • Add new bracket style, "style=pico" (-A11).
  • +
  • Add new bracket style, "style=lisp" (-A12).
  • +
  • Add new option "align-reference=" (-W#) (3,136,744).
  • +
  • Add new options ignore-exclude-errors (-i) and ignore-exclude-errors-x (-xi) (3,259,910).
  • +
  • Add new option "style=break" for Allman style brackets.
  • +
  • Add new option "style=attach" for Java style brackets.
  • +
  • Add processing of UTF-16 files by converting to UTF-8 and back to UTF-16.
  • +
  • Add Microsoft C++ extensions for try-finally and try-except statements (3,222,216).
  • +
  • Add "override" and "sealed" modifiers (Visual C specific) to preCommandHeaders vector (3,167,978).
  • +
  • Add "case" and "default" to the list of formatters in ASFormatter (3,276,212).
  • +
  • Remove "indent-brackets" and "indent-blocks" from the valid options.
  • +
  • Remove "volatile" from headers and remove comparisons in ASBeautifier.
  • +
  • Change "delete-empty-lines" short option from "x" to "xd".
  • +
  • Change "max-instatement-indent" maximum value from 80 to 120 (3,255,930).
  • +
  • Change "brackets=horstman" to "brackets=run-in", used for both Horstmann and Pico styles.
  • +
  • Change C enumerations to allow in-statement indents (3,280,454).
  • +
  • Change functions setting the "indent-brackets" and "indent-blocks" variables from public to protected.
  • +
  • Change to indent lines beginning with an assignment operator (3,292,880).
  • +
  • Change to abort if UTF-32 files are detected.
  • +
  • Change "Cannot set native locale" error message from cout to cerr (3,139,873).
  • +
  • Fix Linux infinite loop when a directory name is entered instead of a file name.
  • +
  • Fix trying to process directories as files when a wildcard is used without recursive (3,134,108).
  • +
  • Fix processing a "const" variable as a "const" method when it follows a header (3,168,156).
  • +
  • Fix indentation of a one-line block that follows a header.
  • +
  • Fix breaking a preprocessor define that has code after a comment end (3,132,531).
  • +
  • Fix "pad-oper" padding a dereference that follows a C-style cast (3,259,713).
  • +
  • Fix "unpad-parens" not recognizing an xor (^) operator (3,285,639).
  • +
  • Fix "break-blocks" procedure for "case" and "default" headers.
  • +
  • Fix "add-brackets" adding brackets to the "while" of a "do-while" loop (3,267,880).
  • +
  • Fix "add-brackets" adding brackets to an empty statement.
  • +
  • Fix "pad-paren" used with "align-pointer=name" incorrectly adding an extra space.
  • +
  • Fix not clearing a flag when a "?" conditional is included in an "if" statement (2,989,638).
  • +
  • Fix incorrect indentation when "volatile" modifier is used (3,279,856).
  • +
  • Fix indentation for Microsoft "#pragma region" and "#pragma endregion" preprocessor directives.
  • +
  • Fix not printing a zero for formatted numbers.
  • +
  • Fix indentation of a class opening bracket followed by a class modifier on the same line when indent‑namespaces + and indent‑classes are used.
  • +
  • Refactor to aid debugging, improve speed, and improve the design and decomposition: +
      +
    • Extract method processProcessor() from beautify() in ASBeautifier.
    • +
    • Extract method computePreliminaryIndentation() from beautify() in ASBeautifier.
    • +
    • Extract method parseCurrentLine() from beautify() in ASBeautifier.
    • +
    • Remove unnecessary copies to outBuffer variable in ASBeautifier.
    • +
    • Add preCommandHeaders vector to ASBeautifier and remove the "const" modifier comparisons.
    • +
    • Change static vectors to member variables.
    • +
    • Add isDigit() function to avoid the assert statements in Visual C.
    • +
    +
  • +
+ +

Artistic Style 2.01  (November 2010)

+ +
    +
  • Add recognition of language characters supported by the native locale.
  • +
  • Add formatting of numbers according to the native locale.
  • +
  • Add checksum verification to source file output.
  • +
  • Add formatting of MFC macros BEGIN_DISPATCH_MAP, BEGIN_EVENT_MAP, and BEGIN_PROPPAGEIDS.
  • +
  • Add error message if --recursive is used without a wildcard in the file name.
  • +
  • Add private (unusable) copy constructors for classes with dynamic allocation.
  • +
  • Add error message if the "cin" stream cannot be processed because a pipe is used.
  • +
  • Improve recognition of ARRAY_TYPE brackets.
  • +
  • Improve formatting of multi-line comments when the number of leading spaces must be changed.
  • +
  • Improve formatting of embedded SQL when the number of leading spaces must be changed.
  • +
  • Improve recognition of C++ templates.
  • +
  • Change --style=linux to always use a minimum conditional indent of one-half the indent length.
  • +
  • Change --pad-oper to pad operators in block parens.
  • +
  • Change to indent OpenMP pragmas with the code.
  • +
  • Change to display all (instead of one) option errors before abort.
  • +
  • Change the second argument of the fpError typedef from "char*" to "const char*".
  • +
  • Change Linux Makefiles to allow external values for CFLAGS and LDFLAGS.
  • +
  • Change all destructors to virtual.
  • +
  • Fix crash when --break-blocks is used and there is no closing bracket.
  • +
  • Fix deleting the previous line when a closing bracket follows a comment close.
  • +
  • Fix not recognizing text in quotes when identifying struct access modifiers.
  • +
  • Fix not popping the paren stack when a bracket precedes an end of line comment.
  • +
  • Fix not breaking a closing bracket when empty parens are enclosed in a single line block.
  • +
  • Fix indenting of C# anonymous statement closing bracket.
  • +
  • Fix recognition of C# non in-statement arrays.
  • +
  • Fix breaking single line blocks for C# abstract methods.
  • +
  • Fix not always clearing isNonInStatementArray flag.
  • +
  • Fix indenting "case" statements in a preprocessor definition when --indent-preprocessor is not requested.
  • +
  • Fix not recognizing the "volatile" type qualifier as a keyword.
  • +
  • Fix class initializers not being recognized as an in-statement indent.
  • +
  • Fix indenting Java abstract methods when "new" starts the line and brackets are broken.
  • +
  • Fix broken initializer lines (ending with comma) when there is more than one space after the type.
  • +
  • Fix --brackets=attach inserting a bracket inside comments following a preprocessor statement.
  • +
  • Fix --brackets=attach attaching an array bracket from a one line block to the previous line.
  • +
  • Fix --brackets=horstmann not breaking a comment line when the comment ends the line with a bracket.
  • +
  • Fix --pad-oper to recognize all * and & operators within a function call.
  • +
  • Fix --unpad-paren to recognize * and & operators within a function call.
  • +
  • Fix --pad-paren used with --delete-empty-lines causing a space to be added at end of line in some cases.
  • +
  • Fix --pad-paren padding a closing paren followed by a block paren.
  • +
  • Fix --add-brackets when a header is followed by a semi-colon.
  • +
  • Fix --align-pointer to pad or unpad pointers followed by parens or comments.
  • +
  • Fix --align-pointer to pad or unpad pointers following a scope resolution operator.
  • +
  • Fix --align-pointer to pad or unpad pointers that end the line.
  • +
  • Fix --align-pointer used with --pad-parens-out causing a space to be padded for each run.
  • +
  • Fix --break-blocks used with --delete-empty-lines causing an assert error when end of file is reached.
  • +
  • Fix --break-blocks used with --delete-empty-lines causing an assert error for some combinations of comment lines. +
  • +
  • Fix --break-blocks used with --delete-empty-lines causing a duplicate line in some cases.
  • +
  • Fix --break-blocks used with --delete-empty-lines not always breaking opening blocks.
  • +
  • Fix --break-blocks used with --delete-empty-lines not always deleting empty lines for closing blocks.
  • +
  • Fix --break-blocks used with --fill-empty-lines not always correctly filling empty lines in a switch statement. +
  • +
  • Fix --unpad-paren used with --pad-paren-in not padding between opening parens when multiple parens are used. +
  • +
  • Fix --pad-oper incorrectly padding a template with a default parameter.
  • +
  • Fix ASBeautifier findOperator() method to recognize a C# lambda (=>) operator.
  • +
  • Fix ASFormatter nextLine() method to output an entire operator instead of individual characters.
  • +
  • Fix incorrectly identifying "*" as pointers in block parens.
  • +
  • Fix MinGW -Wshadow warnings.
  • +
  • Fix VS2010 "string subscript out of range" asserts.
  • +
  • Refactor: +
      +
    • Remove template definition for parseOptions() by using a vector reference instead of iterators as function arguments. +
    • +
    • New ASOptions class to encapsulate global functions used by both the console and library builds.
    • +
    • Replace argc and argv in processOptions() with a vector to simplify test cases.
    • +
    • Replace IS_OPTION and IS_OPTIONS macros with ASOptions methods.
    • +
    • Replace GET_PARAM and GET_PARAMS macros with ASOptions methods.
    • +
    • Extract ASFormatter methods checkIfTemplateOpener() and isClosingHeader().
    • +
    +
  • +
+ +

Artistic Style 1.24  (February 2010)

+ +
    +
  • Add new option ‑‑brackets=horstmann (-g) to place run‑in statements on the same line as an opening + bracket.
  • +
  • Add new style --style=horstmann (-A9) using horstmann brackets to predefined styles.
  • +
  • Add new option ‑‑add-brackets (-j) and --add-one-line-brackets (-J) to place brackets around one line + statements.
  • +
  • Add new style --style=1tbs and --style=otbs (-A10) using linux brackets and the --add-brackets option to predefined + styles.
  • +
  • Add new option ‑‑pad‑header (‑H) from Mario Gleichmann to insert space padding after paren + headers.
  • +
  • Add new option ‑‑align‑pointer=type (-k1), ‑‑align‑pointer=middle (-k2) and + ‑‑align‑pointer=name (-k3) from J P Nurmi.
  • +
  • Add new option ‑‑lineend=windows (-z1), ‑‑lineend=linux (-z2) and ‑‑lineend=macold + (-z3) from MrTact.
  • +
  • Add new option ‑‑indent‑col1‑comments (-Y) to indent C++ comments beginning in column + one.
  • +
  • Add formatting of embedded SQL statements in C/C++.
  • +
  • Add rejecting 16 or 32 bit file encoding and display a warning message.
  • +
  • Remove .tmp file by using ostringstream instead of ofstream.  
  • +
  • Remove depreciated option style=kr.
  • +
  • Remove trace file from ASFormatter and use 'cout' instead.
  • +
  • Improve assembler statement processing to include extended assembly.
  • +
  • Improve assembler statement processing to include Microsoft specific lines and blocks.
  • +
  • Improve recognition of pointers and references vs. arithmetic operators.
  • +
  • Improve recognition of arithmetic operators for --pad-oper (-p) option.
  • +
  • Change "class" initializer statement to one indent.
  • +
  • Change "class" initializer statement continuation lines to align on the first initializer.
  • +
  • Change predefined styles to allow changes to spaces per indent.
  • +
  • Change --style=stroustrup to 5 spaces per indent.
  • +
  • Change --style=linux default minimum conditional indent to 4.
  • +
  • Change default formatting to leave paren headers unchanged instead of inserting space padding.
  • +
  • Change ‑‑unpad‑paren to unpad headers unless padding is requested.
  • +
  • Change NONE_MODE brackets to allow run-in statements from horstmann type brackets.
  • +
  • Change array brackets to allow run-in statements from horstmann type brackets.
  • +
  • Change --min-conditional-indent to allow for statements preceded by a bracket (horstmann brackets).
  • +
  • Change ASBeautifier and ASFormatter to output an entire comment line instead of characters.
  • +
  • Change quote formatting in ASFormatter to output the entire string instead of single characters.
  • +
  • Change from Ettl Martin for cppcheck compliance.
  • +
  • Change space padding of line end comments to one space when the proper alignment cannot be maintained.
  • +
  • Change spaces per tab minimum value from 1 to 2.
  • +
  • Change the help display of "Formatting Options" to "Formatting Options" and "Padding Options".
  • +
  • Fix MinGW file globing by moving the _CRT_glob variable outside the astyle namespace.
  • +
  • Fix default line end processing to always output consistent line ends.
  • +
  • Fix identification of pointer dereferences and address-of indicators.
  • +
  • Fix memory leaks by changing static vectors to static vector pointers so the object can be deleted.
  • +
  • Fix console build trying to use Unicode character set.
  • +
  • Fix stringEndsWith method when end is longer than the string.
  • +
  • Fix --exclude option rejecting a full file path.
  • +
  • Fix --verbose option when used with --quiet.
  • +
  • Fix --quiet option for excluded files and directories.
  • +
  • Fix --indent-classes for C++ structs containing access modifiers.
  • +
  • Fix formatting of variable types with multiple names.
  • +
  • Fix from Christian Stimming for alignment of << and >> operators.
  • +
  • Fix in-statement indent of "enum class".
  • +
  • Fix 'if' statement following an 'else' sometimes attaching to a comment.
  • +
  • Fix recognition of non-indent line comments in the first two lines of a source file.
  • +
  • Fix non-instatement array to recognize an empty bracket.
  • +
  • Fix indenting non-indent line comments in an event table or message map.
  • +
  • Fix to move comments when breaking one line blocks and -keep-one-line-statements is used.
  • +
  • Fix to recognize parens in template definitions.
  • +
  • Fix recognition of class initializer when class description contains multiple lines.
  • +
  • Fix from Colin D Bennett for 64-bit comparison.
  • +
  • Fix console error procedure to terminate on an error.
  • +
  • Fix 'return' statement for padding or not padding arithmetic operators.
  • +
  • Fix C# 'delegate' and 'unchecked' not being identified as keywords.
  • +
  • Fix occasional array formatting problem with one-line blocks when indent-brackets is used.
  • +
  • Fix to check for max-instatement-indent when the previous line ends with an opening paren.
  • +
  • Fix predefined style options to allow the use of --indent=tab (-t) and --indent=force-tab (-T) options.
  • +
  • Fix --in-statement indent to allow for non-indentation tabs in the line.
  • +
  • Fix formatting problems with non in-statement arrays.
  • +
  • Fix infinite loop when preprocessor #else is missing #if.
  • +
  • Fix Borland string compares to check for comparison past the end of string.
  • +
  • Fix ‑‑fill‑empty‑lines when ‑‑indent=force‑tab is also used.
  • +
  • Fix break-blocks formatting with preceding mixed comments and line comments.
  • +
  • Fix not breaking a closing bracket following a comment.
  • +
  • Fix attached brackets to not change empty brackets when both are on the same line.
  • +
  • Fix attached brackets sometimes deleting a previous comment line when the bracket cannot be attached.
  • +
  • Fix attached brackets attaching a closing header to a single line block.
  • +
  • Fix broken brackets breaking a single line block before a comment.
  • +
  • Fix 'extern' keyword using in-statement indents instead of tab indents.
  • +
  • Fix errno checking problem on old OpenVMS versions.
  • +
  • Fix deleting a space before a line end comment when attaching 'else' to a closing bracket.
  • +
  • Fix adding a space before a line end comment when the comment is preceded by a tab.
  • +
  • Fix to leave tab indentation on no-indent line comments.
  • +
  • Fix comments when a bracket is added or removed from a line.
  • +
  • Fix indenting preprocessor statements in a wxWidgets or MFC macro.
  • +
  • Fix memory leak reporting of global and static class member vectors.
  • +
  • Refactor to implement unit testing and improve design and decomposition: +
      +
    • Replace multiple line conditional statements with a method to eliminate complex "not" (!) logic.
    • +
    • Change to call standardizePath when a vector entry is built.
    • +
    • Change g_console from an object to an object pointer to allow rebuilding the object.
    • +
    • Change ASConsole variables to private with getters and setters.
    • +
    • Change processOptions method to return to main instead of exiting.
    • +
    • Move formatFile call from getFilePaths to main.
    • +
    • Move peekNextChar function from ASBeautifier to ASBase.
    • +
    • Move multi-line comment alignment from ASBeautifier to ASFormatter.
    • +
    • Encapsulate global variable isModeManuallySet.
    • +
    • Extract methods formatOpeningBracket, formatClosingBracket and isCurrentBracketBroken.
    • +
    • Extract methods formatCommentOpener and formatCommentBody.
    • +
    • Extract methods formatLineCommentOpener and formatLineCommentBody.
    • +
    • Extract methods formatQuoteOpener and formatQuoteBody.
    • +
    • Extract methods processFiles and writeOutputFile.
    • +
    • Extract methods processSwitchBlock and findCaseColon.
    • +
    • Extract method updateExcludeVector.
    • +
    • Extract method copyTempStacks.
    • +
    • Extract method formatCinToCout.
    • +
    • Extract method isLineBreakBeforeClosingHeader.
    • +
    +
  • +
+ +

Artistic Style 1.23  (February 2009)

+ +
    +
  • Add --brackets=stroustrup (-u) to bracket types.
  • +
  • Add --style=stroustrup to predefined styles.
  • +
  • Add --style=whitesmith to predefined styles.
  • +
  • Add --style=banner to predefined styles.
  • +
  • Add --style=k&r and --style=k/r to predefined styles.
  • +
  • Add --style=allman and --style=bsd to predefined styles.
  • +
  • Change --style=kr to --style=java.
  • +
  • Add short options -A1 thru -A8 for predefined styles.
  • +
  • Change the following long options to eliminate duplicate keys (the short options have not changed). +
      +
    • --force-indent=tab=# changed to --indent=force-tab=#
    • +
    • --brackets=break-closing changed to --break-closing-brackets
    • +
    • --pad=oper changed to --pad-oper
    • +
    • --pad=paren changed to --pad-paren
    • +
    • --pad=paren-out changed to --pad-paren-out
    • +
    • --pad=paren-out changed to --pad-paren-in
    • +
    • --unpad=paren changed to --unpad-paren
    • +
    • --one-line=keep-statement changed to --keep-one-line-statements
    • +
    • --one-line=keep-blocks changed to --keep-one-line-blocks
    • +
    +
  • +
  • Add new option --indent=force-tab (assumes tab setting is 4).
  • +
  • Add new option --delete‑empty‑lines to delete the empty lines within a function.
  • +
  • Add new option --formatted (-Q) to display only the files that are formatted.
  • +
  • Change --convert-tabs to replace tabs with spaces and maintain the correct spacing.
  • +
  • Change --indent-blocks to indent only blocks within a function.
  • +
  • Change --indent-blocks to NOT indent the opening bracket for namespaces, classes, and interfaces.
  • +
  • Change --indent-blocks and --indent-brackets to NOT indent namespaces unless --indent-namespaces is used.
  • +
  • Change --indent-blocks and --indent-brackets to always break closing headers so the 'else' aligns with the corresponding + 'if'.
  • +
  • Change --indent-blocks and --indent-brackets to be mutually exclusive (--indent‑blocks will be used). +
  • +
  • Fix --indent-blocks indenting a java 'interface' statement. 
  • +
  • Fix --indent-blocks to indenting opening brackets in a java method containing a 'throws' clause.
  • +
  • Fix --indent-blocks indenting opening brackets in a java static constructor.
  • +
  • Fix --indent-blocks formatting in a C++ const function.
  • +
  • Fix --indent‑brackets indenting brackets within comments.
  • +
  • Move set-up of predefined styles to ASFormatter so the style options will override all other options.
  • +
  • Fix --else-if statements to join by default.
  • +
  • Fix to always space pad after semi‑colons.
  • +
  • Fix --pad-oper to space pad all commas.
  • +
  • Fix --break‑blocks and --break‑blocks=all options. +
      +
    • Fix to recognize a semi‑colon as end of block when brackets are not used.
    • +
    • Fix to break comments preceding a block so that comments are kept with the block.
    • +
    • Fix 'for' statement semi‑colons being mistaken for the end of a statement.
    • +
    • Fix bracketFormatMode of  NONE_MODE to break closing headers.
    • +
    • Fix incorrect breaking of a block that follows a comment.
    • +
    • Fix breaking of opening and closing headers preceded by a comment.
    • +
    • Fix breaking of statements when comments follow a header block.
    • +
    • Fix incorrectly breaking blocks for namespaces, interfaces, and classes.
    • +
    • Fix incorrectly breaking blocks for access modifiers when keep-one-line-statements is used.
    • +
    • Fix to NOT break single line blocks.
    • +
    • Fix breaking a closing 'while' statement in a do-while block.
    • +
    • Fix preprocessor directives not resetting all variables.
    • +
    • Fix peekNextText function not correctly identifying an end of file condition.
    • +
    +
  • +
  • Add C# lambda expression arrow '=>' to list of operators so pad‑oper will not separate.
  • +
  • Add C# '??' to list of operators so pad‑oper will not separate.
  • +
  • Fix C# to identify 'add' and 'remove' methods as command type brackets.
  • +
  • Fix C# indentation of closing headers 'set' and 'remove'.
  • +
  • Fix C# to identify methods containing a 'where' keyword as block headers. 
  • +
  • Fix C# files to recognize preprocessor statements.
  • +
  • Fix C# indentation following a #region statement containing a keyword.
  • +
  • Fix C# to recognize nullable types so --pad‑paren will not separate (e.g. 'int?').
  • +
  • Fix C# to recognize non-generic default values (e.g. 'default(int)').
  • +
  • Fix C# indentation when a class declaration contains multiple class statements.
  • +
  • Fix C# linux bracket placement for an  interface statement.
  • +
  • Fix C# --break-elseifs also breaking 'catch' statements.
  • +
  • Fix C# --break-blocks breaking of 'set' and 'remove' statements.
  • +
  • Fix Java static constructor not being identified as a command type bracket.
  • +
  • Fix Java 'new' array not having an in statement indent.
  • +
  • Refactor NONE_MODE in ASFormatter to use common procedures with other bracket types.
  • +
  • Refactor astyle_main to improve maintainability. +
      +
    • New class ASConsole to encapsulate console variables.
    • +
    • New header file astyle_main.h
    • +
    • Move console only functions to ASConsole class.
    • +
    • New functions processOptions and processFilePath to improve decomposition.
    • +
    +
  • +
  • Apply patches from Eran Ifrah to remove memory leaks.
  • +
  • Apply patches from Max Horn for the unary plus operator.
  • +
  • Fix initialization of vector stack objects to remove memory leaks.
  • +
  • Add comma (,) to valid options separators in the options file.
  • +
  • Change to display all (instead of one) --exclude errors before abort.
  • +
  • Change astyle namespace to include all of astyle_main except the functions called externally.
  • +
  • Change licensing comments from LGPL version 2.1 to LGPL version 3.
  • +
  • Change JNI function call from GetVersion to AStyleGetVersion.
  • +
  • Remove 'extern' keyword from headers, nonParenHeaders, PreBlockStatements, and  PreCommandHeaders. +
  • +
  • Fix not always space padding a closing bracket.
  • +
  • Fix not space padding a closing header when breaking one line statements.
  • +
  • Fix --keep-one-line-blocks breaking closing headers on broken brackets.
  • +
  • Fix incorrectly attaching a bracket inside a comment after the end of a statement.
  • +
  • Add number of output lines processed to the --verbose option display.
  • +
  • Remove trace file from ASEnhancer and use 'cout' instead.
  • +
  • Replace INIT_CONTAINER and DELETE_CONTAINER macros with template functions.
  • +
  • Replace IS_A macro with isBracketType function.
  • +
  • Add GCC extended operators '<?' and '>?' (min and max) to list of operators.
  • +
  • Fix indentation and breaking of lines in struct and class bit fields.
  • +
  • Fix indentation of struct definitions.
  • +
  • Add 'union' to preDefinitionHeaders.
  • +
  • Change preBlockStatements and preDefinitionHeaders to be dependent on file type.
  • +
  • Fix a single quote mark used as an apostrophe in preprocessor directives being processed as a quotation.
  • +
  • Fix linux bracket formatting in nested namespaces.  
  • +
  • Fix --pad‑paren‑in not converting a tab to spaces if convert‑tabs is requested.
  • +
  • Fix incorrectly breaking a closing bracket when a header is not present.
  • +
  • Fix inserting duplicate bracketTypeStack entries when preprocessor directives contain unmatched brackets.
  • +
  • Fix bracketFormatMode of  NONE_MODE to correctly break single line blocks. 
  • +
  • Fix --keep‑one‑line‑blocks breaking 'if' statements when --break‑elseifs is used.
  • +
  • Remove inefficiencies for speed improvement. +
      +
    • Reduce calls to frequently used functions by first checking for specific requirements.
    • +
    • New class ASBase to inline frequently used functions and eliminate duplication between classes.
    • +
    • Change ASEnhancer from inherited to embedded to eliminate scope resolution requirements.
    • +
    • Change ASFormatter to output words instead of characters.
    • +
    • Resequence operator vectors and add new findHeader and findOperator functions.
    • +
    +
  • +
  • Fix NONE_MODE brackets to break a statement on the same line as an opening broken bracket.
  • +
  • Add 'errno' message for file and directory errors in the Linux build.
  • +
  • Add error checking for file remove and rename procedure.
  • +
  • Fix Linux abort for file sizes over 2 GB.
  • +
  • Fix searching the entire directory when only one file is requested.
  • +
  • Change --preserve-date increment to 2 units for Visual Studio 2008.
  • +
+ +

Artistic Style 1.22  (April 2008)

+ +
    +
  • New --recursive (-r, -R) option to recursively process sub directories.
  • +
  • New --exclude option to exclude files and sub directories from processing.
  • +
  • New --verbose (-v) option to display optional information, such as release number and statistical data.
  • +
  • New --quiet (-q) option to suppress all informational messages.
  • +
  • Change --version short option to -V.
  • +
  • Change --convert‑tabs short option to -c.
  • +
  • Change to NOT write a new or backup file if a file contents has not changed, 
  • +
  • Change console file input procedure to create a .tmp file and preserve the input file on a crash.
  • +
  • Add Java Native Interface (JNI) for developers.
  • +
  • New peekNextLine and peekReset functions in ASStreamIterator.
  • +
  • Change ASEnhancer static variables to class member variables and reset them in the init() function.
  • +
  • Patch from Jens Krinke to fix stack underrun when the number of closing brackets exceed opening brackets.
  • +
  • Fix stack underrun when the number of closing parens exceed opening parens.
  • +
  • Fix processing of C/C++ string literal continuation lines.
  • +
  • Patch from Emilio Guijarro to correct padding and formatting of C# 'foreach' statements.
  • +
  • Fix C# to correctly identify accessor calls as not being headers.
  • +
  • Fix C# accessors (get and set) to break when breaking single line blocks.
  • +
  • Modify template procedure to process C# generics.
  • +
  • Fix processing of C# verbatim string literals.
  • +
  • Fix indentation of C# methods containing 'base' or 'this' keywords.
  • +
  • Fix indentation of C# methods containing generics.
  • +
  • Fix indentation of C# enums containing a type.
  • +
  • Fix indentation of C# catch blocks when 'catch' is a non-paren header.
  • +
  • Fix C# breaking of linux style brackets for methods containing generics and methods containing accessors.
  • +
  • Allow @ as a C# identifier prefix.
  • +
  • Fix assert error on C# UTF-8 files when the byte-order mark (BOM) is not followed by a space or a comment. +
  • +
  • Fix nested preprocessor formatting by adding waitingBeautifierStack, activeBeautifierStack, waitingBeautifierStackLengthStack, + and activeBeautifierStackLengthStack to the ASBeautifier copy constructor and class destructor.
  • +
  • Fix ASStreamIterator end of file procedure for ASTYLE_LIB option.
  • +
  • Add pragma statements for Intel compiler to disable specific warning messages.
  • +
  • Move line number accumulators from ASSourceIterator class to private in ASStreamIterator class.
  • +
  • Fix reset of ASFormatter isInPreprocessor flag when \ is followed by a blank line.
  • +
  • Fix cin, cout, and cerr continuation lines to be indented.
  • +
  • Fix indentation of inner classes that inherit a base class.
  • +
  • Add astyle_main.cpp function declarations to astyle_main.cpp.
  • +
  • Change global variable prefix from '_' to 'g_'.
  • +
  • Inline selected ASStreamIterator functions.
  • +
  • Fix brackets=attach from attaching a bracket to a preprocessor directive.
  • +
  • Fix brackets=attach and brackets=linux breaking in an array immediately after a preprocessor directive.
  • +
  • Modify Jack Handy's wildcmp() function to make Windows comparisons case insensitive.
  • +
  • Fix not indenting a bracket when an attached bracket is broken and the following line is a no-indent comment. +
  • +
  • Add error message if 'options=' file cannot be opened.
  • +
  • Bypass colon enclosed in quotes when processing 'case' statements.
  • +
  • Fix brackets=none not always breaking a closing bracket when breaking single line blocks.
  • +
  • Fix padding of header words that are in a definition (array).
  • +
  • Fix indentation of line immediately after a case statement where the object is enclosed in parens.
  • +
  • Fix breaking of multiple case statements when the object is enclosed in parens.
  • +
  • Fix indentation when there is more than one case statement on a line.
  • +
  • Remove processing for shouldBreakLineAfterComments (no longer used).
  • +
  • Fix brackets=break not breaking if before a comment that is not at end of line.
  • +
  • Fix brackets=none not space padding before a bracket.
  • +
  • Fix brackets=break and brackets=none not breaking comments following a bracket.
  • +
  • Fix blank line not being trimmed if inside a comment.
  • +
  • Fix brackets=break incorrectly space padding a preceding preprocessor statement line.
  • +
  • Fix brackets=attach attaching two consecutive opening brackets before an end-of-line comment.
  • +
  • Fix break-blocks not inserting a blank line if a bracket preceding a comment was moved to the following line. +
  • +
  • Add 'X' to selected ASEnhancer variables to prevent conflict with ASBeautifier.
  • +
  • Fix brackets=none not space padding after a closing bracket that precedes a closing header.
  • +
  • Change minimum indent edit from 2 spaces to 1 space.
  • +
  • Change to check for preprocessor definitions in C/C++ files only.
  • +
  • Fix padding of template definitions when pad=oper is used.
  • +
  • Fix comment formatting in nested preprocessor definitions.
  • +
  • Fix header dependencies and warning messages for Linux GCC 4.3.
  • +
  • Use file name from disk for output to maintain correct case in Windows.
  • +
  • Fix pad=operator padding a negative value in a case statement.
  • +
  • Fix incorrect identification of bracket type following a struct statement.
  • +
  • Fix indentation of blank lines outside of brackets when --fill‑empty‑lines is used with --indent‑blocks + or --indent‑brackets.
  • +
  • Fix ASFormatter not identifying comments in preprocessor directives.
  • +
  • Fix brackets=attach deleting a preceding blank line in array type brackets.
  • +
+ +

Artistic Style 1.21  (June 2007)

+ +
    +
  • New function, formatArrayBrackets, to improve array formatting and indentation.
  • +
  • Attach brackets to lines with end-of-line comments.
  • +
  • Break brackets from lines with end-of-line comments without bringing the comments with them.
  • +
  • Move ASFormatter and ASBeautifier static initialization from constructor to "init" function to allow for changes + in the file type.
  • +
  • Add --preserve-date (-Z) option.
  • +
  • New functions formatBrackets, padOperators and PadParens to improve decomposition.
  • +
  • Add identification of file mode (C, C#, or Java) to file open procedure.
  • +
  • Keywords in headers now depend on file mode (C, C#, or Java) and object type (formatter or beautifier).
  • +
  • Remove short options -c (mode=c) and -j (mode=java) since the mode is now set automatically from the file extension. +
  • +
  • Change Linux bracket formatting for header files.
  • +
  • Fix formatting of empty blocks.
  • +
  • Expand BracketType definition.
  • +
  • Fix "do not change" bracket mode inconsistencies with other bracket formatting.
  • +
  • Remove mode=java from Java predefined style.
  • +
  • Change long option --errors-to-standard-output to --errors-to-stdout.
  • +
  • Fix breaking of struct variable declaration.
  • +
  • Add support for OpenVMS compiler.
  • +
  • Inline the ASBeautifier function isLegalNameChar.
  • +
  • Fix no-indent of block comments starting in column 1 or 2.
  • +
  • Fix formatting of Java anonymous class defined as a method call parameter (bracket within a paren).
  • +
  • Fix indentation for Java "for each" statement.
  • +
  • Fix bracket being attached to a preprocessor directive.
  • +
  • Fix extra indent of single line blocks when a previous line probation header is found.
  • +
  • Fix formatting of block comments when continuation lines have different leading whitespace characters.
  • +
  • Fix deleting a blank line before a bracket when brackets=attach.
  • +
  • Fix segmentation fault on preprocessor continuation line followed by an empty line.
  • +
  • Fix bad bracket indent that sometimes occurs when brackets=attach and it cannot be attached.
  • +
  • Fix trimming of comment lines.
  • +
  • Fix incorrect identification of "new" operator pointers as calculations.
  • +
  • Fix incorrect identification of assignments as command type bracket.
  • +
  • Fix incorrect indentation of pointers following a dot operator or pointer.
  • +
  • Fix attaching "else if" statements to a single line block.
  • +
  • Fix header recognition problem when header is proceeded by a tab instead of a space.
  • +
  • Fix line break when colon is followed by a comment.
  • +
  • Fix ASBeautifier not identifying a template definition.
  • +
  • Change indents around the end of line to two indents.
  • +
  • Change header includes to fix header dependencies for Linux GCC 4.3.
  • +
  • Add output line number for debugging.
  • +
  • Add filename to trace output.
  • +
  • Add trace for arrays.
  • +
  • Add trace for bracketType.
  • +
  • Fix no-indent comment in a #else preprocessor directive.
  • +
  • Fix block comment continuation line indent when block comments do not start the line.
  • +
  • Adjust position of block comments (/*) when padding is added or deleted.
  • +
  • Fix incorrect formatting if "return" is included in a function name.
  • +
  • Fix incorrect padding if template depth is greater that one and pad=oper is used.
  • +
  • Fix incorrect bracket type identification when bracket is followed by a comment.
  • +
  • Fix incorrect bracket type identification when a "const" method is declared.
  • +
  • Fix incorrect bracket type identification when pre-definition header is inside a paren.
  • +
  • Fix deleting a space when attaching a bracket with line comments.
  • +
  • Fix indentation when the conditional "?" operator is used in a single line statement.
  • +
  • Fix indentation when single line "if" statement is used.
  • +
  • Add pointers, multiply operators, and selected variables to do not unpad in paren unpad procedure.
  • +
  • Return exit code 0 for --version and --help.
  • +
+ +

Artistic Style 1.20.2  (February 2007)

+ +
    +
  • Fix problems with the new stream I/O procedure added in release 1.20.1: +
      +
    • Fix adding an extra blank line at end of document.
    • +
    • Fix line ending on last line when cin and cout option is used.
    • +
    +
  • +
+ +

Artistic Style 1.20.1  (January 2007)

+ +
    +
  • The following changes were made to improve processing for Mac OS X platforms: +
      +
    • Remove Makefile linker option -s and add a separate "strip" command.
    • +
    • Open console input and output streams as binary to allow Linux line ends on a Windows platform.
    • +
    • Change stream I/O procedure to allow for Mac OS 9 line endings.
    • +
    • Change output stream end of line from endl so output stream is not flushed with each write.
    • +
    • Change information messages from cerr to cout.
    • +
    • Removed messages when I/O is to cin and cout to accommodate TextWrangler.
    • +
    +
  • +
+ +

Artistic Style 1.20  (January 2007)

+ +
    +
  • Call importOptions() from function AStyleMain() to allow slop in options parameters.
  • +
  • New makefiles for GCC and Intel with new compile options.
  • +
  • New project file for Visual C with new compile options.
  • +
  • Change comments to reflect the GNU Lesser General Public License.
  • +
  • Indent message maps for MFC and event tables for wxWidgets.
  • +
  • Fix incorrect formatting for an empty comment.
  • +
  • Fix "Unknown option" in default options file when last line does not contain CR or LF.
  • +
  • Patch from Dieter Bayer to fix case indent when a scope resolution operator is used.
  • +
  • Change long option --brackets=break-closing-headers to --brackets=break-closing.
  • +
  • Add short option -y for --brackets=break-closing.
  • +
  • Add short option -e for --break-elseifs.
  • +
  • Add short option -w for --indent-preprocessor.
  • +
  • Add short option -f for --break-blocks.
  • +
  • Add short option -F for --break-blocks=all.
  • +
  • Remove the backup file after formatting when --suffix=none.
  • +
  • Show total time at end of job.
  • +
  • Improved error handling for invalid options with ASTYLE_LIB.
  • +
  • Add function AStyleGetVersion() to ASTYLE_LIB option.
  • +
  • Change preprocessor macro from ASTYLE_GUI to ASTYLE_LIB.
  • +
  • Add astyle namespace to ASEnhancer.
  • +
  • Add #include <ctype.h> for Red Hat distribution of GCC 3.2 (prior to Jan 2004).
  • +
  • Remove commented-out code.
  • +
+ +

Artistic Style 1.19  (July 2006)

+ +
    +
  • Add unpad=paren option.
  • +
  • Always pad paren headers (e.g. 'if', 'for', 'while').
  • +
  • Fix problem of pad=oper working different if pad=paren is declared.
  • +
  • Add additional tests to distinguish the multiplication operator from pointers.
  • +
  • Fix padding parens before a member access pointer (->).
  • +
  • If space padding has changed, move end-of-line comments to the original column, if possible.
  • +
  • Move potential calculation decision to outside of operator padding function.
  • +
  • Fix duplication of last line of source if a final endline is not present.
  • +
  • Fix class initializer not indented on last line if bracket is attached.
  • +
  • Fix identification of templates contained in parens.
  • +
  • Fix one line block occurring before end of class.
  • +
  • Fix line added after one line block with bracketFormatMode = NONE_MODE.
  • +
  • Add needed variables to ASBeautifier copy constructor.
  • +
  • Trim end of line for multi-line comments.
  • +
  • Add a breakLine before paren checks (needed for unpad=paren option).
  • +
  • Add trace file to ASFormatter.
  • +
  • Move formatting message from end to beginning of formatting.
  • +
  • Move the building of vectors to ASResource. Vectors for classes ASBeautifier and ASFormatter should now have the + same values.
  • +
  • Move debugging variable inLineNumber from ASFormatter to ASBeautifier.
  • +
  • Bypass char processing for UTF8 characters in ASBeautifier.
  • +
  • Move switchVariables struct from ASEnhancer to the header file.
  • +
  • Remove preprocessorHeader vector (not used).
  • +
  • Remove variable isInConst (not used).
  • +
  • Remove commented-out code.
  • +
+ +

Artistic Style 1.18  (June 2006)

+ +
    +
  • The following changes were made for the option pad=oper: +
      +
    • Does not remove extra spaces from formatted expressions.
    • +
    • Does not pad opening parens on the outside.
    • +
    • Does not remove leading spaces from multi-line comments.
    • +
    • Does not pad negative numbers.
    • +
    • Does not add a space to the end of preprocessor directives.
    • +
    • Will not pad operators inside block parens [].
    • +
    +
  • +
  • The following changes were made for the option pad=paren: +
      +
    • Formats correctly with or without pad=oper.
    • +
    • Does not add a space for each additional run if pad=oper is not used.
    • +
    • Outside of opening paren is padded correctly.
    • +
    • Inside of closing paren is padded correctly.
    • +
    • Does not pad block parens [].
    • +
    • Added short option P, previously used for pad=all.
    • +
    +
  • +
  • Added new options pad=paren-out (d) and pad=paren-in (D).
  • +
  • Removed option pad=all.
  • +
  • Add short option V for convert-tabs.
  • +
  • Added bounds checking to options containing parameters.
  • +
  • Display a message when a default options file is used.
  • +
  • Replaced IS_PARAM_OPTION(S) macros with overloaded isParamOption. Fixed compare problem with short param options. +
  • +
  • Fix EOF problem with default options file.
  • +
+ +

Artistic Style 1.17  (May 2006)

+ +
    +
  • The following changes were made for processing bracketFormatMode = NONE_MODE: +
      +
    • Removed the function isFormattingEnabled() and always performed the formatting.
    • +
    • Removed the formatting bypass for NONE_MODE.
    • +
    • Fix brackets always being broken in the 2 cases where NONE_MODE formatting was done.
    • +
    • Added new functions to support the processing of NONE_MODE brackets.
    • +
    • Made other minor changes necessary for correct NONE_MODE processing.
    • +
    +
  • +
  • Changed indent cases option to indent the entire case block.
  • +
  • Changed to output Windows or Linux line endings.
  • +
  • Added ASEnhancer module for case statement indenting.
  • +
  • Corrected errors in identifying options indent=tab=, and force-indent=tab=.
  • +
  • Corrected errors in identifying options min-conditional-indent=, and max-instatement-indent=.
  • +
  • Improved error and information messages.
  • +
  • Added capability to compile as a console program, shared library, or static library.
  • +
  • Fixed problem with semicolons and parens being put on a line by themselves.
  • +
  • Fixed spaces being added before a line comment.
  • +
  • Fixed blank line added after some preprocessor statements.
  • +
  • Fixed preprocessor statements not being trimmed.
  • +
  • Do not indent line comments that begin in column 1 or 2.
  • +
  • Fixed indentation problem with ending }; of class statements.
  • +
  • Changed nextLine() function to eliminate char buffer limits.
  • +
  • Moved Windows default options file to %USERPROFILE%.
  • +
  • Removed NEW operators to prevent memory leaks.
  • +
  • Fixed space before the semicolon in return ; statement.
  • +
  • Fixed extra space that was sometimes added when pad operators was used.
  • +
  • Removed string parameter from IS_PARAM_OPTION.
  • +
  • Added forward declaration of parseOption() to eliminate compile error.
  • +
  • Added input line number counter for debugging.
  • +
  • Add statements to check for markers if break-blocks or break-blocks=all is used.
  • +
  • Remove warnings for signed/unsigned mismatch.
  • +
  • Removed COMPARE macro and used string compare.
  • +
  • Removed compiler_defines.h.
  • +
  • Removed USES_NAMESPACE declaration.
  • +
+ +

Artistic Style 1.16

+ +
+ There was no release 1.16. +
+ +

Artistic Style 1.15.3 (7 March 2002)

+ +
    +
  • Bug fix in handling of brackets after line-comments.
  • +
  • Bug fix: C# add/remove event property headers now properly formatted.
  • +
+ +

Artistic Style 1.15.2 (2 March 2002)

+ +
    +
  • Bug fixes in exception handling phrases, e.g. multiple catches and try..finally.
  • +
+ +

Artistic Style 1.15.1 (2 March 2002)

+ +
    +
  • Bug fix: C# properties are now formatted properly.
  • +
+ +

Artistic Style 1.15.0 (2 March 2002)

+ +
    +
  • Added support for C#.
  • +
  • Artistic Style is now licensed only under the GNU Public License (GPL).
  • +
  • Compilation under G++ 3.0 now works properly.
  • +
  • Bug fix: Opening brackets that appear at the beginning of a line immediately after an empty line comment are now + handled properly, and not appended as part of the line comment.
  • +
  • Bug fix: Brackets inside comments are now not mis-indented within the comment.
  • +
+ +

Artistic Style 1.14.1 (2 June 2001)

+ +
    +
  • Bug fix: : '<' and '>' symbols within template declarations (e.g. 'foo<bar*, xoo>') are now left unpadded + in the padding modes.
  • +
  • Bug fix: Fixed false recognizing of headers within larger words (e.g. 'catch' in 'gcatch').
  • +
+ +

Artistic Style 1.14.0 (1 June 2001)

+ +
    +
  • Bug fix: Fixed indentation of statements within preprocessor '#if...' statements.
  • +
  • Bug fix: Templates are now not broken from their bodies.
  • +
  • Bug fix: '<' and '>' symbols within template definitions (e.g. 'template<class T>') are now left unpadded + in the padding modes.
  • +
+ +

Artistic Style 1.13.8 (13 April 2001)

+ +
    +
  • Bug fix: Fixed indentation of multiple nested non-block brackets, such as in multi bracketed static array declarations. +
  • +
+ +

Artistic Style 1.13.7 (6 April 2001)

+ +
    +
  • New option:'--force-indent=tab=#' (or 'T#') instructs astyle to indent using tabs in all the pre-statement white + space, including areas astyle's '--indent=tab' prefers to indent using spaces, such as white space in multi-line + statements.
  • +
  • Bug fix: Fixed unwanted empty line insertions between empty blocks (e.g. '{}') and closing brackets that come + immediately after them.
  • +
  • Bug fix: Fixed unwanted empty line insertions immediately after colons (e.g. 'default:', 'label:', ...)
  • +
+ +

Artistic Style 1.13.6 (24 January 2001)

+ +
    +
  • Bug fix: Preprocessor lines now remain unpadded in padding modes.
  • +
+ +

Artistic Style 1.13.5 (24 January 2001)

+ +
    +
  • Bug fix: Fixed the insertion of phantom empty lines immediately after {} blocks.
  • +
  • Bug fix: Bare open brackets ('{') with no preceding headers are now broken appropriately from their preceding + code lines in the 'attach' and 'linux' bracketmodes.
  • +
  • Bug fix: Fixed operator recognition for long operators such as '>>=', '<<= '.
  • +
+ +

Artistic Style 1.13.4 (24 January 2001)

+ +
    +
  • Bug fix: L" unicode strings are now handled properly in padding modes.
  • +
  • Bug fix: Fixed the padding around '-' operators (which went sour somewhere in the past).
  • +
  • Bug fix: Fixed the handling of exponent numbers (e.g. 12.2e+2) in padding modes. The fix enables 'e+' to be regarded + as part of the exponent.
  • +
+ +

Artistic Style 1.13.3 (23 January 2001)

+ +
    +
  • Line that contain both headers and their following non-header code (e.g. 'if (isFoo) doBar();') are now broken + by default into multiple lines. To keep these lines as single lines, use '--one-line= keep-statements'.
  • +
  • Added the new option '--break-elseifs' which breaks 'else if()' statements into multiple lines.
  • +
  • The option block breaking options now works properly with the padding options.
  • +
  • Various minor bug fixes.
  • +
+ +

Artistic Style 1.13.2 (21 January 2001)

+ +
    +
  • Added the new option '--brackets=break-closing-headers'. When this option is added to either '--brackets=attach' + or '--brackets= linux', astyle breaks closing headers (e.g. 'else', 'catch') from their preceding closing brackets. +
  • +
  • '--break-blocks' and '--break-blocks= all' now correctly handle blocks that appear immediately before closing + brackets, and do not append empty lines between them and the closing brackets.
  • +
+ +

Artistic Style 1.13.0 (27 September 1999)

+ +
    +
  • Moved back to odd-minor-numbered development versions, and even-minor-numbered stable versions.
  • +
  • Added the new option '--break-blocks' which breaks apart unrelated blocks, labels, classes, etc.
  • +
  • Added the new option '--break-blocks=all' which also breaks apart blocks of closing headers, such as 'else', 'catch', + etc.
  • +
  • Fixed indentation handling of labels and class-definition identifiers such as 'public:', 'protected:', ... (thanks + to Daryn Adler for his patch)
  • +
  • Fixed indentation of nested class definitions. (thanks to Daryn Adler for his patch)
  • +
  • Added the new option '--indent-preprocessor' which (surprisingly) tries to reindent C/C++ preprocessor macro lines. + Astyle should do an pretty nice indentation job if the macro code is sane, but don't expect miracles for horrid + macro definitions...
  • +
+ +

Artistic Style 1.11.6 (27 September 1999)

+ +
    +
  • Improved indentation of lines containing single-line blocks.
  • +
+ +

Artistic Style 1.11.5 (25 September 1999)

+ +
    +
  • Improved the bug fix for a 'const' keyword bug which resulted in wrong indentation of methods that are declared + const.
  • +
+ +

Artistic Style 1.11.4 (18 September 1999)

+ +
    +
  • Improved handling of single colons (':') in class headers, e.g. class Foo : public Bar { ... }
  • +
  • Improved handling of single colons (':') in method (constructor) headers, e.g. Foo::Foo(int a) : Bar(a)
  • +
+ +

Artistic Style 1.11.3 (16 September 1999)

+ +
    +
  • Fixed a serious bug in the formatting of brackets, introduced in 1.11.2.
  • +
+ +

Artistic Style 1.11.2 (10 September 1999)

+ +
    +
  • Fixed an indentation bug in statements that contain the 'const', that resulted in wrong indentation of array blocks + that where declared const. (Thanks Daniel!)
  • +
  • Fixed an indentation bug that could arise in lines that appear immediately after several preprocessor commands. + (Thanks Daniel!).
  • +
  • Fixed a bug that inserted an empty line after closing brackets if a comment appeared immediately prior to the + closing bracket. (Thanks Ed!)
  • +
  • Fixed a bug that eliminated empty lines between closing brackets and immediately following opening brackets. (Thanks + Ed!)
  • +
+ +

Artistic Style 1.11.1 (3 September 1999)

+ +
    +
  • Fixed a bug that inserted an empty line at the begining of source files.
  • +
+ +

Artistic Style 1.11.0 (3 September 1999)

+ +
    +
  • Astyle now filters out line-feeds ('\r') before begining to parse lines. This should take care of bizarre formatting + that existed when moving source files from Windows (which breaks lines with a linefeed AND newline ("\r\n") to + unix (which breaks lines only with newlines).
  • +
  • The "struct", "static" and "synchronized" keywords are now finally handled correctly in both the contexts of block + headers AND simple keywords.
  • +
  • Better treatment of precompiler lines that end with backslashes, and the lines that immediately follow them. +
  • +
  • The '--indent-classes' (or '-C') option now works correctly (again...).
  • +
  • Series of short command-line options (e.g. "-b -s4 -C") are now parsed correctly.
  • +
+ +

Artistic Style 1.10.4  (27 July 1999)

+ +
    +
  • Fixed a MAJOR bug (inserted in 1.10.3) that resulted wrong handling of double-colons ('::') in C++.
  • +
+ +

Artistic Style 1.10.3 (24 July 1999)

+ +
    +
  • Fixed a bug (inserted yesterday) that resulted in unwanted line breaks before closing-brackets.
  • +
  • Fixed a bug in the handling of 'static' blocks in java.
  • +
  • Added the new option '--indent-cases' (or '-K') for indenting 'case XXX:' lines so they are flush with their following + code lines.
  • +
  • Added the new option '--fill-empty-lines' (or '-E') which fills empty lines with the white-space of their previous + line.
  • +
+ +

Artistic Style 1.10.2 (23 July 1999)

+ +
    +
  • Fixed a series of related bugs that resulted in certain cases of lacking line breaks after close-brackets, and + colons. Thanks Jeroen!
  • +
+ +

Artistic Style 1.10.1 (18 July 1999)

+ +
    +
  • Fixed a bug (introduced in astyle 1.10.0) that can result in missing line breaks before closing brackets if they + appear immediately after comments. Thanks Larry!
  • +
+ +

Artistic Style 1.10.0 Release (14 July 1999)

+ +
    +
  • Improved handling of empty bracket blocks ( e.g.{ } ). Thanks Michael!
  • +
+ +

Artistic Style 1.10.0 Prerelease (4 July 1999)

+ +
    +
  • Fixed a bug in the in-statement indentation algorithm which resulted in sub-optimal indentation of multiple-line + conditional statements that immediately follow headers such as 'if', 'else if', 'while', etc... As a result, the + current in-statement indentation is finally what it should have been long ago - MUCH better then in the last stable + versions.
  • +
  • The "linux" bracket style (in which definition brackets are broken while code brackets are attached) has been + fixed, and should finally work correctly.
  • +
  • Artistic Style can now parse both C/C++ and Java files in the same command. Unless a specific language mode is + specified (e.g. --style=java or --style=c), astyle will now automatically set the language mode according to each + file's suffix (java mode for the '.java' suffix , c mode otherwise).
  • +
  • Multiple statements in a single line (e.g. aaa; bbb; fff;) are now broken up by default.
  • +
  • Added the option '--one-line=keep-statements' (or '-o') that keeps multiple + statements in a single line attached, thus countering the default break detailed above.
  • +
  • Changed the option previously called '--keep-one-line-blocks' to '--one-line=keep-blocks', + for similarity with the new option above.
  • +
  • Changed the short option name of the option '--errors-to-standard-output' from '-o' + to '-X'.
  • +
  • Up to now, Artistic Style always inserted a minimal indent of twice the current selected indent + size inside multi-line conditional headers ('if', 'while' ...), so that it would be clear where the headers end + and the code after them begins. The current version adds the option '--min-conditional-indent=#' + (or '-m#') that sets the absolute minimal indent between conditional headers and their multiple-line + conditional statements. If this option is not specified, the default indent remains twice the current selected + indent size.
    + For example, This option should come very handy in code that already has brackets after EVERY conditional statement + (even if just one line is in that bracket...) - in such a case, it would be wise to set --min-conditional-indent=0 + since the brackets already make it clear where the header ends and the code begins...
  • +
  • Added the ability to set the assumed tab size when in '--indent-tab' mode by using '--indent-tab=#' + or '-t#' and replacing the # with the wanted size. If the size is not specified, + the size of each tab is assumed to be 4 spaces long.
  • +
+ +

Artistic Style 1.8.2 (18 March 1999)

+ +
    +
  • Fixed pointer handling problems in ASBeautifier that led to crashes when parsing preprocessor commands.
  • +
  • Fixed the problem in locating the default options file in the directory pointed to by $HOME or %HOMEPATH% when + these system variables do not contain an '/' (or '\' ...) at their end.
  • +
  • Fixed inverse insertion of spaces vs. tabs when in -t mode. (Thanks Brian!)
  • +
  • Got rid of those pesky C4786 warnings when compiling under Visual C++ (Thanks John!)
  • +
+ +

Artistic Style 1.8.1 (9 March 1999)

+ +
    +
  • Changed the '--style=k&r' option to '--style= kr' , so that linux/unix machines don't misinterpret the '&' + as a background processing command.
  • +
+ +

Artistic Style 1.8.0 (3 March 1999)

+ +
    +
  • Added support for predefined styles. Current supported styles are: ansi, k&r, linux, gnu, java. + these can be set by using '--style=THESTYLE' (e.g. '--style=linux').
  • +
  • Added '--indent-blocks' (or -G) option, which adds indentation to entire blocks, including their + brackets, in similar fashion to the standard gnu style.
  • +
  • Added option '--brackets=linux' (or '-l') which breaks definition-block brackets, but attaches command-block + brackets.
  • +
  • Padding can now be set separately for operators alone('-p' or '--pad=oper'), parentheses alone ('--pad=paren) + or both ('-P' or '--pad=all').
  • +
  • Artistic Style looks for a default options file in the following order:
    + 1. The contents of the ARTISTIC_STYLE_OPTIONS environment variable if it exists.
    + 2. The file called .astylerc in the directory pointed to by the HOME environment variable ( i.e. + $HOME/.astylerc ).
    + 3. The file called .astylerc in the directory pointed to by the HOMEPATH environment variable + ( i.e. %HOMEPATH%\.astylerc ).
    + If a default options file is found, the options in this file will be parsed BEFORE the command-line options. Options + within the default option file may be written without the preliminary '-' or '--'. Indentation within #if , #else + and #endif precompiler commands now works correctly even if the program lines between these precompiler commands + contain non-pared brackets.
  • +
  • Improved handling of labels (e.g. 'exit:'). By default, labels are now flushed completely to the left. Labels + can also be indented to one indent LESS than current standard indentation by using the new option '--indent-labels' + (or '-L') .
  • +
  • Fixed handling of the 'operator' keyword when it is preceded by a non space character (such as '&' or '*'). +
  • +
  • Fixed wrong bracket handling after 'throws' statements.
  • +
  • Fixed wrong indentation of single-line blocks. These where indented 1 indent to much.
  • +
  • Fixed wrong indentation of headers in internal classes (java mode). These where indented 1 indent to little. +
  • +
  • The option ' --errors-to-standard-output' now has the one-letter option '-o'.
  • +
  • Fixed bug which resulted in an unneeded indent in function-declarations in which function-variables are declared + before the function declaration and are preceded by the 'static' keyword. Thanks Scott.
  • +
+ +

Artistic Style 1.6.0 (5 January 1999)

+ +
    +
  • Fixed zero indentation that resulted when a '-suffix' option was set after a '--indent=spaces' (or '-s') option. +
  • +
  • Wrong options are now announced.
  • +
  • Changed default indentation to NOT automatically indent class blocks and switch blocks. Instead, the new options + '--indent-classes' (or '-C') and '--indent-switches' (or '-S') should be used. The option '--indent-switches' + replaces the old option '--flush-switches'.
  • +
+ +

Artistic Style 1.4.1 (4 January 1999)

+ +
    +
  • Fixed ability to write options without the preceding '--' in the default options file.
  • +
  • Added one-letter options to most options that had only long-options in version 1.4.0.
  • +
  • Added a '-v' or '--version' option that writes the current Artistic Style version.
  • +
+ +

Artistic Style 1.4.0 (3 January 1999)

+ +
    +
  • MAJOR NEW CHANGE IN THE FORMAT OF OPTIONS:
    + Options are now either short one-letter options starting with '-', or long multi-letter options + starting with '--'. The Short one-letter options MAY BE ATTACHED TOGETHER. Thus, writing '-bps4' is the same as + writing '-b -p -s4'.
    + Many options that have up to now had a 2 letter format now retain only their long format. I truly believe that + the combination of attached-one-letter options PLUS a default option's file containing long-letter-options related + to style will be much easier to work with than the previous setup.
  • +
  • Added support for a default options file (pointed to by the ARTISTIC_STYLE_OPTIONS environment + variable).
  • +
  • Changed downloading method from the server. From now, there will be specific directories containing the latest + stable sources, stable binaries, and development sources.
  • +
  • Space padding ('-p' or '--pad') now works correctly (1) around semicolons and commas, (2) between headers that + require parentheses after them (such as 'if', 'while'...)and those parentheses, and (3) after parentheses (unless + immediately followed by a ';' or ',' or '.').
  • +
  • From now on, namespace blocks are NOT indented by default. To indent namespace blocks use the new '--indent-namespaces' + option.
  • +
  • Added options '--errors-to-standard-output' for redirection of standard-error to standard-output from within Artistic + Style, and '--suffix=' for specifying a suffix other than '.orig' to append to original filenames.
  • +
  • Corrected indentation of 'default' in switch statements. (Up to now, this only worked correctly in java mode...). +
  • +
+ +

Artistic Style 1.2.0 (19 December 1998)

+ +
    +
  • Artistic Style 1.2.0 is the first stable result of a new version numbering, in which development versions are + numbered with an odd minor number (such as 1.1.x), and stable versions are numbered with an even number (1.2.x). + Thus, version 1.2.0 accumulates all the additions/changes of the 1.1.x development versions of Artistic Style. +
  • +
  • A new '-ol' formatting mode that eliminates breaking of one-line blocks.
  • +
  • Fixed a SERIOUS bug, which resulted in wrong formatting of brackets ('{', '}') that came IMMEDIATELY AFTER definition + type brackets, (e.g. brackets that come right after 'class', 'interface', 'name-space', etc ...). This bug was + mistakenly introduced when I set out to correctly space-pad pointer and reference signs, somewhere in version + 0.9.x.
  • +
  • Fixed unwanted elimination of final empty lines.
  • +
  • Fixed broken indentation of virgin opening-brackets that occur immediately after a previous closing-bracket. +
  • +
  • Fixed space-padding to not insert a space in front of ':' characters unless they are a part of a '? ... : ' statement. +
  • +
+ +

Artistic Style 1.0.5  (11 December 1998)

+ +
    +
  • 'extern' blocks now handled correctly.
  • +
  • Fixed handling of ^= in '-p' mode.
  • +
  • Win32 executables now contain wildcard expansion. *** Look at the README.TXT for info + on how to include wildcard expansion abilities when compiling Artistic Style under Win32. (Thanks for the info + on wildcard-expansion enabling, Nat!!!)
  • +
+ +

Artistic Style 1.0.4  (2 December 1998)

+ +
    +
  • Fixed unwanted space-padding around urinary minuses and '-' symbols within exponents + (e.g. 2.5E-5) when using the '-p' option.
  • +
+ +

Artistic Style 1.0.3  (1 December 1998)

+ +
    +
  • Control characters now remain in the indented file.
  • +
  • Fixed a bug in which long quoted white-space sequences where mistakenly eliminated + in the '-p' mode.
  • +
  • Fixed unwanted line-breaks in '-ab -p' mode, that in some cases occurred between '//' + and the rest of a line comment.
  • +
  • Fixed handling of '>>=', '<<= ' in '-p' mode.
  • +
+ +

Artistic Style 1.0.2 (27 November 1998)

+ +
    +
  • Fixed a SERIOUS bug of missing needed line-breaks in lines immediately after line-comments + when in '-ab' mode.
  • +
  • Support for the 'finally' header.
  • +
  • lines that contain only white-space now become empty lines.
  • +
+ +

Artistic Style 1.0.1  (26 November 1998)

+ +
    +
  • Fixed a SERIOUS bug, which lacked a needed line-break between closing brackets and + the headers that follow them (e.g. '} else') when in '-bb' mode. In fixing the bug, I used a variation on a patch + sent by Richard Bullington - THANKS!
  • +
  • Fixed a set of SERIOUS bugs which inserted an empty line into both the start and end + of the reindented file.
  • +
  • Improved documentation of formatting options in the file astyle.html .
  • +
+ +

Artistic Style 1.0.0 (24 November 1998)

+ +
    +
  • Indented files now retain the original file name, while the original + pre-indented file is saved with a ".orig"at its end. Thus, after the call "astyle -bb foo.cpp", + the newly indented file will be called "foo.cpp", while a file called "foo.cpp.orig" + will contain the original pre-indented file.
  • +
  • Artistic Style may now be used and /or modified and/or distributed under EITHER + the "Artistic License", or the GNU General Public License (GPL).
  • +
  • Methods with headers that end with 'const' are now properly indented.
  • +
  • Cleaner, more robust, and better documented source code.
  • +
+ +

Artistic Style 0.9.2

+ +
    +
  • Fixed a serious bug which led to a maximal supported source code line size of 128 + characters!!!
  • +
  • Maximal supported line size is now 1024 characters.
  • +
  • Fixed a serious bug in the handling of brackets inside '#define' statements.
  • +
  • Fixed a serious bug in which '#include' files containing slashes (i.e. #include <foo_dir/foo> ) where space-padded + when using option '-p' on C, C++ files.
  • +
+ +

Artistic Style 0.9.1

+ +
    +
  • Much improved space-padding around pointers ('*') and references ('&') and the + 'operator' key-word in C and C++ source files when using the '-p' space padding option.
  • +
  • Fixed several pointer handling bugs which led to potential core dumps.
  • +
  • Version 0.9.1 now includes all the abilities I am planning for the final 1.0 version, and should be looked + at as the first pre-release version of Artistic Style.
  • +
+ +

Artistic Style 0.9.0

+ +
    +
  • Added a formatting layer (ASFormatter.cpp) around the indentation + layer (ASBeautifier.cpp). +
  • +
  • As a result, the following formatting capabilities have been added: +
      +
    • Bracket ('{' and '}') placement in either ANSI C style or Java style.
    • +
    • Space padding around operators, i.e. (1+2)*3-4 becomes ( 1 + 2 ) * 3 - 4.
    • +
    +
  • +
  • Fixed the 'tab' elimination bug introduced in ASBeautifier 0.8.2.
  • +
  • Fixed a bug which under-indented class headers containing inheritance info.
  • +
+ +

ASBeautifier 0.8.2

+ +
    +
  • Fixed indentation problem in brackets around 'struct', and 'union' blocks.
  • +
  • Added recognition for '\' characters in the end of lines.
  • +
  • Improved indentation of post-method-declaration variable initializations.
  • +
  • Several minor bug fixes.
  • +
+ +

ASBeautifier 0.8.1

+ +
    +
  • Fixed an important bug in pointer arithmetic which resulted both in phantom indentation errors, and in core-dumps + when trying to indent java files.
  • +
+ +

ASBeautifier 0.8.0

+ +
    +
  • This is the first public release of ASBeautifier. It is a direct port to C++ of JSBeautifier + 1.1.1, PLUS extensions to for C++ indentation.
  • +
  • So far, very little beta-testing has been done for the C++ extensions. This should + change extremely with the open-source release (this was the case with JSBeautifier...), so expect ASBeautifier + to become bug-free fast!!!
  • +
  • The C++ source code is not yet written in optimal quality. I rushed a little so that I could release this initial + release as soon as possible. This will soon change.
  • +
+

+   +

+ + + + diff --git a/External/Tools/AStyle/doc/scripts.html b/External/Tools/AStyle/doc/scripts.html new file mode 100644 index 0000000000..21841178c7 --- /dev/null +++ b/External/Tools/AStyle/doc/scripts.html @@ -0,0 +1,94 @@ + + + + + + Artistic Style - Scripts + + + + + + + + +

Artistic Style Scripts

+ +

+   +

+

+ The following are scripts to support the Artistic Style program. They are in various computer languages for multiple + platforms. +

+ +

Scripts

+ +

+ + astyle-clean.py  is a Python script to clean a directory tree by + moving Artistic Style backup files to a separate directory. This allows Artistic Style to create backup files + without cluttering your source directories. There are four variables at the start of the script that need to be + set for each application. The script will move or copy backup files to a backup directory maintaining the original + directory structure. New backup files will be copied over the old so you will always have the most current backup. +

+

+ + astyle-clean.sh  is a Linux shell script to clean a directory tree + by moving Artistic Style backup files to a separate directory. This allows Artistic Style to create backup files + without cluttering your source directories. There are four variables at the start of the script that need to be + set for each application. The script will move or copy backup files to a backup directory maintaining the original + directory structure. New backup files will be copied over the old so you will always have the most current backup. +

+

+ + astyle-clean.bat  is a Windows batch file to clean a directory + tree by moving Artistic Style backup files to a separate directory. This allows Artistic Style to create backup + files without cluttering your source directories. There are four variables at the start of the script that need + to be set for each application. The script will move or copy backup files to a backup directory maintaining the + original directory structure. New backup files will be copied over the old so you will always have the most current + backup. +

+

+ + astyle.pl  is a Mac Perl script to indent source files in TextWrangler + and BBEdit using Artistic Style. Selected text from the editor can be passed to Artistic Style and replaced with + the reformatted text. Save the script in the "Unix Filters" directory (you need to restart TextWrangler to see + new scripts). Then simply highlight the text you would like to indent, choose the script from the Shebang (#!) + menu, and the text will be immaculately formatted. You can add Artistic Style options to the "my $astyle" line + in the script. +

+

+ + indent-commit.pl  is a Perl script to integrate Artistic Style + with a CVS repository check-in. Before code is checked in, Artistic Style is automatically called so that the + repository files have a consistent style. This script was posted on the web site several years ago and probably + needs to be updated. +

+

+ + astyle-hooks.el  is an Emacs Lisp script containing hooks to convert + Emacs default styles to Artistic Style default styles. There are hooks for C++, Java, and C# files. The C# hook + requires the csharp-mode.el file from + csharpmode on Google Project Hosting. For best results Artistic Style should use the options ‑‑min‑conditional‑indent=0 + (‑m0) and ‑‑max‑instatement‑indent=50 (‑M50). Emacs does not seem to have + an option equivalent to these. The formatting for Emacs and Artistic Style will not be identical but should be + reasonably close. +

+

+   +

+ +

+ + +

+ +

+   +

+ + + + + diff --git a/External/Tools/AStyle/doc/styles.css b/External/Tools/AStyle/doc/styles.css new file mode 100644 index 0000000000..892ca1c93a --- /dev/null +++ b/External/Tools/AStyle/doc/styles.css @@ -0,0 +1,35 @@ + +/* h1 is a title + * h2 is a subtitle + * h3 is a hanging text title + * h4 is a non-hanging text title + * p.noindent is non-hanging text (text without a title) + * p.contents entries are for the table of contents + * a.contents are table of contents links (not underlined) + * a.links are links (underlined) + * img does not have a border + * pre is a predefined format for formatting code + */ + + +body { background-color: white; margin-top: 0.5in; margin-right: 0.8in; margin-bottom: 0.5in; margin-left: 1.3in; } + +h1 { color: #0000A0; text-align: center; font-style: italic; margin-top: 18pt; margin-left: -0.5in; } +h2.large { color: #0000A0; text-align: center; font-size: x-large; margin-top: 0.4in; margin-left: -0.5in; } +h2 { color: #0000A0; text-align: center; font-size: larger; margin-top: 0.4in; margin-left: -0.5in; } +h3 { color: #0000A0; margin-top: 0.4in; margin-left: -0.4in; } +h4 { color: #0000A0; margin-top: 0.3in; } + +p.noindent { margin-left: -0.4in; } +p.contents1 { font-size: 105%; margin-top: 0in; margin-left: 0in; margin-bottom: 0in; margin-right: 0in; } +p.contents2 { margin-top: 0in; margin-left: .4in; margin-bottom: 0in; margin-right: .4in; } +/* p.contents3 { margin-top:0in; margin-left:.8in; margin-bottom:0in; margin-right:.8in; } */ +a.contents:link, a.contents:visited { color: #0000A0; text-decoration: none; } +a.contents:hover { color: #F00000; text-decoration: none; } + +a:link, a:visited { color: #0000A0; text-decoration: underline; } +a:hover { color: #F00000; text-decoration: underline; } + +img { border: none; } + +pre { margin-left: 0.3in; color: navy; font-weight: bold; } diff --git a/External/Tools/AStyle/doc/subversion.html b/External/Tools/AStyle/doc/subversion.html new file mode 100644 index 0000000000..6b09ce1a6b --- /dev/null +++ b/External/Tools/AStyle/doc/subversion.html @@ -0,0 +1,99 @@ + + + + + + Artistic Style - Subversion + + + + + + + + +

Artistic Style Subversion Repository

+ +

+   +

+ +

Artistic Style

+ +

+ The latest development source is in the Artistic Style repository at SourceForge. It can be checked out using + Subversion. The source code is under development and some changes take several weeks to complete. The intermediate + source files have not been through the extensive system tests that are done before each release. Use reasonable + precautions when using source code from the repository. +

+

+ The current version is in the "trunk/AStyle" branch of the repository. The file and directory names are case sensitive. +

+

+ A sample checkout is:
+ svn  checkout  "https://svn.code.sf.net/p/astyle/code/trunk/AStyle"  "$HOME/astyle" +

+

+ You can also browse the subversion repository. + The current development release is in the "trunk" directory. This gives you a view into the current status of + the project's code without actually checking-out the files. +

+

+   +

+ +

Other Projects

+ +

+ Two additional Artistic Style projects are available in the repository. They are not maintained for the general + public but are available if you want them. You may have to create your own project files and scripts to use them. + These projects require the Artistic Style project above. They are an extension that requires the Artistic Style + source. All projects, and any additional source required, should be installed in the same top level folder. +

+ +

AStyleDev

+ +

+ AStyleDev contains the development files that are made available in the "Developer Information" section. Refer + to that section for more information. +

+

+ A sample checkout is:
+ svn  checkout  "https://svn.code.sf.net/p/astyle/code/trunk/AStyleDev"  "$HOME/astyledev" +

+ +

AStyleTest

+ +

+ AStyleTest contains the unit test programs and test scripts for Artistic Style. There are over 2000 tests in the + main test program. +

+

+ A sample checkout is:
+ svn  checkout  "https://svn.code.sf.net/p/astyle/code/trunk/AStyleTest"  "$HOME/astyletest" +

+

+ In addition to the Artistic Style source the test program requires + Google Mock. This is the Google multi-platform framework for writing + C++ unit tests. The main Artistic Style test project, AStyleTest, actually uses "integration" tests + instead of "unit" tests. This type of testing can be effective for programs that were written without + unit tests to begin with. +

+

+   +

+ +

+ + +

+ +

+   +

+ + + + + diff --git a/External/Tools/AStyle/doc/vsinstall.html b/External/Tools/AStyle/doc/vsinstall.html new file mode 100644 index 0000000000..149132e9da --- /dev/null +++ b/External/Tools/AStyle/doc/vsinstall.html @@ -0,0 +1,108 @@ + + + + + + .NET Framework SDK + + + + + + + + +

Visual Studio 2010 C++ Express

+ +

Install Instructions for .NET Framework SDK

+ +

+   +

+ +

+ Following are instructions for installing the .NET Framework SDK in Visual Studio 2010 Express and adding x64 + platforms to an existing project in a manner similar to the more expensive Visual Studio editions. +

+ +

Installing .NET Framework SDK

+ +

+ 64-bit tools are not available on the Visual Studio 2010 C++ Express Edition by default. To enable 64-bit targets, + install the .NET Framework SDK in addition to the Visual Studio 2010 Express Edition. Otherwise, the x64 solution + platform is not available and a warning will occur if you open a project containing a 64-bit target. +

+

+ Install the + Windows SDK appropriate for your operating system. Use the "Install Now" link to get the SDK. You can + optionally install the Windows Performance Toolkit, Debugging Tools, and Application Verifier. The Help is also + optional. +

+

+ After installing this package the x64 configurations can be created. +

+

+ IMPORTANT: If Visual Studio 2010 Service Pack 1 is applied after the .NET Framework SDK install, an additional + update is required to restore the Visual C++ compilers and libraries that may have been removed. Information is + available here. +

+ + +

Adding x64 to Project Files

+ +

+ Open a Win32 project. Open the Configuration Manager from the Build menu. In the Active Solution Platform select + New. For the New Platform select x64. You will need to “Copy settings from Win32” and check + “Create new project platforms”. +

+

+ Open the Properties from the Project menu. There is a new configuration property that needs to be set for the + linker to find the system libraries. Be sure the x64 platform is selected and change "Configuration Properties + > General + > Platform Toolset", to Windows7.1SDK. Otherwise you will get linker errors + such as "LINK : fatal error LNK1104: cannot open file 'kernel32.lib'". This setting can also optionally be used + for the Win32 platform. +

+

+ The x64 configuration can now be compiled, but the compiles will place the files in the same directories as the + Win32 compiles. To correct this the x64 compiles should be placed in an x64 directory using the $(Platform) + macro. +

+

+ Add the $(Platform) macro to “Configuration Properties > General > Output directory” so the + entry becomes $(SolutionDir)$(Platform)\$(Configuration)\. +

+

+ Leave “Configuration Properties  > General> Intermediate Directory” at the default which + should be $(Platform)\$(Configuration)\. +

+

+ Check the x64 Debug configuration “Configuration Properties > Linker > Debugging > Generate Program + Database File” for $(TargetDir)$(TargetName).pdb. +

+

+ Compile the project. If there are compile errors you may need to add the $(Platform) macro + to other settings as well. For example, if there are user library files the macro may need to be added to + “Configuration Properties > Linker > General > Additional Library Directories”. +

+

+ You should now be able to compile both Win32 and x64 platforms in a manner similar to the more expensive Visual + Studio editions. +

+

+   +

+ +

+ + +

+ +

+   +

+ + + + + diff --git a/External/Tools/AStyle/src/ASBeautifier.cpp b/External/Tools/AStyle/src/ASBeautifier.cpp new file mode 100644 index 0000000000..da90599f9b --- /dev/null +++ b/External/Tools/AStyle/src/ASBeautifier.cpp @@ -0,0 +1,3486 @@ +// ASBeautifier.cpp +// Copyright (c) 2016 by Jim Pattee . +// Licensed under the MIT license. +// License.txt describes the conditions under which this software may be distributed. + +//----------------------------------------------------------------------------- +// headers +//----------------------------------------------------------------------------- + +#include "astyle.h" + +#include + +//----------------------------------------------------------------------------- +// astyle namespace +//----------------------------------------------------------------------------- + +namespace astyle { +// +// this must be global +static int g_preprocessorCppExternCBracket; + +//----------------------------------------------------------------------------- +// ASBeautifier class +//----------------------------------------------------------------------------- + +/** + * ASBeautifier's constructor + * This constructor is called only once for each source file. + * The cloned ASBeautifier objects are created with the copy constructor. + */ +ASBeautifier::ASBeautifier() +{ + waitingBeautifierStack = NULL; + activeBeautifierStack = NULL; + waitingBeautifierStackLengthStack = NULL; + activeBeautifierStackLengthStack = NULL; + + headerStack = NULL; + tempStacks = NULL; + blockParenDepthStack = NULL; + blockStatementStack = NULL; + parenStatementStack = NULL; + bracketBlockStateStack = NULL; + inStatementIndentStack = NULL; + inStatementIndentStackSizeStack = NULL; + parenIndentStack = NULL; + preprocIndentStack = NULL; + sourceIterator = NULL; + isModeManuallySet = false; + shouldForceTabIndentation = false; + setSpaceIndentation(4); + setMinConditionalIndentOption(MINCOND_TWO); + setMaxInStatementIndentLength(40); + classInitializerIndents = 1; + tabLength = 0; + setClassIndent(false); + setModifierIndent(false); + setSwitchIndent(false); + setCaseIndent(false); + setBlockIndent(false); + setBracketIndent(false); + setBracketIndentVtk(false); + setNamespaceIndent(false); + setLabelIndent(false); + setEmptyLineFill(false); + setCStyle(); + setPreprocDefineIndent(false); + setPreprocConditionalIndent(false); + setAlignMethodColon(false); + + // initialize ASBeautifier member vectors + beautifierFileType = 9; // reset to an invalid type + headers = new vector; + nonParenHeaders = new vector; + assignmentOperators = new vector; + nonAssignmentOperators = new vector; + preBlockStatements = new vector; + preCommandHeaders = new vector; + indentableHeaders = new vector; +} + +/** + * ASBeautifier's copy constructor + * Copy the vector objects to vectors in the new ASBeautifier + * object so the new object can be destroyed without deleting + * the vector objects in the copied vector. + * This is the reason a copy constructor is needed. + * + * Must explicitly call the base class copy constructor. + */ +ASBeautifier::ASBeautifier(const ASBeautifier& other) : ASBase(other) +{ + // these don't need to copy the stack + waitingBeautifierStack = NULL; + activeBeautifierStack = NULL; + waitingBeautifierStackLengthStack = NULL; + activeBeautifierStackLengthStack = NULL; + + // vector '=' operator performs a DEEP copy of all elements in the vector + + headerStack = new vector; + *headerStack = *other.headerStack; + + tempStacks = copyTempStacks(other); + + blockParenDepthStack = new vector; + *blockParenDepthStack = *other.blockParenDepthStack; + + blockStatementStack = new vector; + *blockStatementStack = *other.blockStatementStack; + + parenStatementStack = new vector; + *parenStatementStack = *other.parenStatementStack; + + bracketBlockStateStack = new vector; + *bracketBlockStateStack = *other.bracketBlockStateStack; + + inStatementIndentStack = new vector; + *inStatementIndentStack = *other.inStatementIndentStack; + + inStatementIndentStackSizeStack = new vector; + *inStatementIndentStackSizeStack = *other.inStatementIndentStackSizeStack; + + parenIndentStack = new vector; + *parenIndentStack = *other.parenIndentStack; + + preprocIndentStack = new vector >; + *preprocIndentStack = *other.preprocIndentStack; + + // Copy the pointers to vectors. + // This is ok because the original ASBeautifier object + // is not deleted until end of job. + beautifierFileType = other.beautifierFileType; + headers = other.headers; + nonParenHeaders = other.nonParenHeaders; + assignmentOperators = other.assignmentOperators; + nonAssignmentOperators = other.nonAssignmentOperators; + preBlockStatements = other.preBlockStatements; + preCommandHeaders = other.preCommandHeaders; + indentableHeaders = other.indentableHeaders; + + // protected variables + // variables set by ASFormatter + // must also be updated in activeBeautifierStack + inLineNumber = other.inLineNumber; + horstmannIndentInStatement = other.horstmannIndentInStatement; + nonInStatementBracket = other.nonInStatementBracket; + objCColonAlignSubsequent = other.objCColonAlignSubsequent; + lineCommentNoBeautify = other.lineCommentNoBeautify; + isElseHeaderIndent = other.isElseHeaderIndent; + isCaseHeaderCommentIndent = other.isCaseHeaderCommentIndent; + isNonInStatementArray = other.isNonInStatementArray; + isSharpAccessor = other.isSharpAccessor; + isSharpDelegate = other.isSharpDelegate; + isInExternC = other.isInExternC; + isInBeautifySQL = other.isInBeautifySQL; + isInIndentableStruct = other.isInIndentableStruct; + isInIndentablePreproc = other.isInIndentablePreproc; + + // private variables + sourceIterator = other.sourceIterator; + currentHeader = other.currentHeader; + previousLastLineHeader = other.previousLastLineHeader; + probationHeader = other.probationHeader; + lastLineHeader = other.lastLineHeader; + indentString = other.indentString; + verbatimDelimiter = other.verbatimDelimiter; + isInQuote = other.isInQuote; + isInVerbatimQuote = other.isInVerbatimQuote; + haveLineContinuationChar = other.haveLineContinuationChar; + isInAsm = other.isInAsm; + isInAsmOneLine = other.isInAsmOneLine; + isInAsmBlock = other.isInAsmBlock; + isInComment = other.isInComment; + isInPreprocessorComment = other.isInPreprocessorComment; + isInHorstmannComment = other.isInHorstmannComment; + isInCase = other.isInCase; + isInQuestion = other.isInQuestion; + isInStatement = other.isInStatement; + isInHeader = other.isInHeader; + isInTemplate = other.isInTemplate; + isInDefine = other.isInDefine; + isInDefineDefinition = other.isInDefineDefinition; + classIndent = other.classIndent; + isIndentModeOff = other.isIndentModeOff; + isInClassHeader = other.isInClassHeader; + isInClassHeaderTab = other.isInClassHeaderTab; + isInClassInitializer = other.isInClassInitializer; + isInClass = other.isInClass; + isInObjCMethodDefinition = other.isInObjCMethodDefinition; + isImmediatelyPostObjCMethodDefinition = other.isImmediatelyPostObjCMethodDefinition; + isInIndentablePreprocBlock = other.isInIndentablePreprocBlock; + isInObjCInterface = other.isInObjCInterface; + isInEnum = other.isInEnum; + isInEnumTypeID = other.isInEnumTypeID; + isInLet = other.isInLet; + modifierIndent = other.modifierIndent; + switchIndent = other.switchIndent; + caseIndent = other.caseIndent; + namespaceIndent = other.namespaceIndent; + bracketIndent = other.bracketIndent; + bracketIndentVtk = other.bracketIndentVtk; + blockIndent = other.blockIndent; + labelIndent = other.labelIndent; + isInConditional = other.isInConditional; + isModeManuallySet = other.isModeManuallySet; + shouldForceTabIndentation = other.shouldForceTabIndentation; + emptyLineFill = other.emptyLineFill; + lineOpensWithLineComment = other.lineOpensWithLineComment; + lineOpensWithComment = other.lineOpensWithComment; + lineStartsInComment = other.lineStartsInComment; + backslashEndsPrevLine = other.backslashEndsPrevLine; + blockCommentNoIndent = other.blockCommentNoIndent; + blockCommentNoBeautify = other.blockCommentNoBeautify; + previousLineProbationTab = other.previousLineProbationTab; + lineBeginsWithOpenBracket = other.lineBeginsWithOpenBracket; + lineBeginsWithCloseBracket = other.lineBeginsWithCloseBracket; + lineBeginsWithComma = other.lineBeginsWithComma; + lineIsCommentOnly = other.lineIsCommentOnly; + lineIsLineCommentOnly = other.lineIsLineCommentOnly; + shouldIndentBrackettedLine = other.shouldIndentBrackettedLine; + isInSwitch = other.isInSwitch; + foundPreCommandHeader = other.foundPreCommandHeader; + foundPreCommandMacro = other.foundPreCommandMacro; + shouldAlignMethodColon = other.shouldAlignMethodColon; + shouldIndentPreprocDefine = other.shouldIndentPreprocDefine; + shouldIndentPreprocConditional = other.shouldIndentPreprocConditional; + indentCount = other.indentCount; + spaceIndentCount = other.spaceIndentCount; + spaceIndentObjCMethodDefinition = other.spaceIndentObjCMethodDefinition; + colonIndentObjCMethodDefinition = other.colonIndentObjCMethodDefinition; + lineOpeningBlocksNum = other.lineOpeningBlocksNum; + lineClosingBlocksNum = other.lineClosingBlocksNum; + fileType = other.fileType; + minConditionalOption = other.minConditionalOption; + minConditionalIndent = other.minConditionalIndent; + parenDepth = other.parenDepth; + indentLength = other.indentLength; + tabLength = other.tabLength; + blockTabCount = other.blockTabCount; + maxInStatementIndent = other.maxInStatementIndent; + classInitializerIndents = other.classInitializerIndents; + templateDepth = other.templateDepth; + squareBracketCount = other.squareBracketCount; + prevFinalLineSpaceIndentCount = other.prevFinalLineSpaceIndentCount; + prevFinalLineIndentCount = other.prevFinalLineIndentCount; + defineIndentCount = other.defineIndentCount; + preprocBlockIndent = other.preprocBlockIndent; + quoteChar = other.quoteChar; + prevNonSpaceCh = other.prevNonSpaceCh; + currentNonSpaceCh = other.currentNonSpaceCh; + currentNonLegalCh = other.currentNonLegalCh; + prevNonLegalCh = other.prevNonLegalCh; +} + +/** + * ASBeautifier's destructor + */ +ASBeautifier::~ASBeautifier() +{ + deleteBeautifierContainer(waitingBeautifierStack); + deleteBeautifierContainer(activeBeautifierStack); + deleteContainer(waitingBeautifierStackLengthStack); + deleteContainer(activeBeautifierStackLengthStack); + deleteContainer(headerStack); + deleteTempStacksContainer(tempStacks); + deleteContainer(blockParenDepthStack); + deleteContainer(blockStatementStack); + deleteContainer(parenStatementStack); + deleteContainer(bracketBlockStateStack); + deleteContainer(inStatementIndentStack); + deleteContainer(inStatementIndentStackSizeStack); + deleteContainer(parenIndentStack); + deleteContainer(preprocIndentStack); +} + +/** + * initialize the ASBeautifier. + * + * This init() should be called every time a ABeautifier object is to start + * beautifying a NEW source file. + * It is called only when a new ASFormatter object is created. + * init() receives a pointer to a ASSourceIterator object that will be + * used to iterate through the source code. + * + * @param iter a pointer to the ASSourceIterator or ASStreamIterator object. + */ +void ASBeautifier::init(ASSourceIterator* iter) +{ + sourceIterator = iter; + initVectors(); + ASBase::init(getFileType()); + g_preprocessorCppExternCBracket = 0; + + initContainer(waitingBeautifierStack, new vector); + initContainer(activeBeautifierStack, new vector); + + initContainer(waitingBeautifierStackLengthStack, new vector); + initContainer(activeBeautifierStackLengthStack, new vector); + + initContainer(headerStack, new vector); + + initTempStacksContainer(tempStacks, new vector*>); + tempStacks->push_back(new vector); + + initContainer(blockParenDepthStack, new vector); + initContainer(blockStatementStack, new vector); + initContainer(parenStatementStack, new vector); + initContainer(bracketBlockStateStack, new vector); + bracketBlockStateStack->push_back(true); + initContainer(inStatementIndentStack, new vector); + initContainer(inStatementIndentStackSizeStack, new vector); + inStatementIndentStackSizeStack->push_back(0); + initContainer(parenIndentStack, new vector); + initContainer(preprocIndentStack, new vector >); + + previousLastLineHeader = NULL; + currentHeader = NULL; + + isInQuote = false; + isInVerbatimQuote = false; + haveLineContinuationChar = false; + isInAsm = false; + isInAsmOneLine = false; + isInAsmBlock = false; + isInComment = false; + isInPreprocessorComment = false; + isInHorstmannComment = false; + isInStatement = false; + isInCase = false; + isInQuestion = false; + isIndentModeOff = false; + isInClassHeader = false; + isInClassHeaderTab = false; + isInClassInitializer = false; + isInClass = false; + isInObjCMethodDefinition = false; + isImmediatelyPostObjCMethodDefinition = false; + isInIndentablePreprocBlock = false; + isInObjCInterface = false; + isInEnum = false; + isInEnumTypeID = false; + isInLet = false; + isInHeader = false; + isInTemplate = false; + isInConditional = false; + + indentCount = 0; + spaceIndentCount = 0; + spaceIndentObjCMethodDefinition = 0; + colonIndentObjCMethodDefinition = 0; + lineOpeningBlocksNum = 0; + lineClosingBlocksNum = 0; + templateDepth = 0; + squareBracketCount = 0; + parenDepth = 0; + blockTabCount = 0; + prevFinalLineSpaceIndentCount = 0; + prevFinalLineIndentCount = 0; + defineIndentCount = 0; + preprocBlockIndent = 0; + prevNonSpaceCh = '{'; + currentNonSpaceCh = '{'; + prevNonLegalCh = '{'; + currentNonLegalCh = '{'; + quoteChar = ' '; + probationHeader = NULL; + lastLineHeader = NULL; + backslashEndsPrevLine = false; + lineOpensWithLineComment = false; + lineOpensWithComment = false; + lineStartsInComment = false; + isInDefine = false; + isInDefineDefinition = false; + lineCommentNoBeautify = false; + isElseHeaderIndent = false; + isCaseHeaderCommentIndent = false; + blockCommentNoIndent = false; + blockCommentNoBeautify = false; + previousLineProbationTab = false; + lineBeginsWithOpenBracket = false; + lineBeginsWithCloseBracket = false; + lineBeginsWithComma = false; + lineIsCommentOnly = false; + lineIsLineCommentOnly = false; + shouldIndentBrackettedLine = true; + isInSwitch = false; + foundPreCommandHeader = false; + foundPreCommandMacro = false; + + isNonInStatementArray = false; + isSharpAccessor = false; + isSharpDelegate = false; + isInExternC = false; + isInBeautifySQL = false; + isInIndentableStruct = false; + isInIndentablePreproc = false; + inLineNumber = 0; + horstmannIndentInStatement = 0; + nonInStatementBracket = 0; + objCColonAlignSubsequent = 0; +} + +/* + * initialize the vectors + */ +void ASBeautifier::initVectors() +{ + if (fileType == beautifierFileType) // don't build unless necessary + return; + + beautifierFileType = fileType; + + headers->clear(); + nonParenHeaders->clear(); + assignmentOperators->clear(); + nonAssignmentOperators->clear(); + preBlockStatements->clear(); + preCommandHeaders->clear(); + indentableHeaders->clear(); + + ASResource::buildHeaders(headers, fileType, true); + ASResource::buildNonParenHeaders(nonParenHeaders, fileType, true); + ASResource::buildAssignmentOperators(assignmentOperators); + ASResource::buildNonAssignmentOperators(nonAssignmentOperators); + ASResource::buildPreBlockStatements(preBlockStatements, fileType); + ASResource::buildPreCommandHeaders(preCommandHeaders, fileType); + ASResource::buildIndentableHeaders(indentableHeaders); +} + +/** + * set indentation style to C/C++. + */ +void ASBeautifier::setCStyle() +{ + fileType = C_TYPE; +} + +/** + * set indentation style to Java. + */ +void ASBeautifier::setJavaStyle() +{ + fileType = JAVA_TYPE; +} + +/** + * set indentation style to C#. + */ +void ASBeautifier::setSharpStyle() +{ + fileType = SHARP_TYPE; +} + +/** + * set mode manually set flag + */ +void ASBeautifier::setModeManuallySet(bool state) +{ + isModeManuallySet = state; +} + +/** + * set tabLength equal to indentLength. + * This is done when tabLength is not explicitly set by + * "indent=force-tab-x" + * + */ +void ASBeautifier::setDefaultTabLength() +{ + tabLength = indentLength; +} + +/** + * indent using a different tab setting for indent=force-tab + * + * @param length number of spaces per tab. + */ +void ASBeautifier::setForceTabXIndentation(int length) +{ + // set tabLength instead of indentLength + indentString = "\t"; + tabLength = length; + shouldForceTabIndentation = true; +} + +/** + * indent using one tab per indentation + */ +void ASBeautifier::setTabIndentation(int length, bool forceTabs) +{ + indentString = "\t"; + indentLength = length; + shouldForceTabIndentation = forceTabs; +} + +/** + * indent using a number of spaces per indentation. + * + * @param length number of spaces per indent. + */ +void ASBeautifier::setSpaceIndentation(int length) +{ + indentString = string(length, ' '); + indentLength = length; +} + +/** + * set the maximum indentation between two lines in a multi-line statement. + * + * @param max maximum indentation length. + */ +void ASBeautifier::setMaxInStatementIndentLength(int max) +{ + maxInStatementIndent = max; +} + +/** + * set the minimum conditional indentation option. + * + * @param min minimal indentation option. + */ +void ASBeautifier::setMinConditionalIndentOption(int min) +{ + minConditionalOption = min; +} + +/** + * set minConditionalIndent from the minConditionalOption. + */ +void ASBeautifier::setMinConditionalIndentLength() +{ + if (minConditionalOption == MINCOND_ZERO) + minConditionalIndent = 0; + else if (minConditionalOption == MINCOND_ONE) + minConditionalIndent = indentLength; + else if (minConditionalOption == MINCOND_ONEHALF) + minConditionalIndent = indentLength / 2; + // minConditionalOption = INDENT_TWO + else + minConditionalIndent = indentLength * 2; +} + +/** + * set the state of the bracket indent option. If true, brackets will + * be indented one additional indent. + * + * @param state state of option. + */ +void ASBeautifier::setBracketIndent(bool state) +{ + bracketIndent = state; +} + +/** +* set the state of the bracket indent VTK option. If true, brackets will +* be indented one additional indent, except for the opening bracket. +* +* @param state state of option. +*/ +void ASBeautifier::setBracketIndentVtk(bool state) +{ + // need to set both of these + setBracketIndent(state); + bracketIndentVtk = state; +} + +/** + * set the state of the block indentation option. If true, entire blocks + * will be indented one additional indent, similar to the GNU indent style. + * + * @param state state of option. + */ +void ASBeautifier::setBlockIndent(bool state) +{ + blockIndent = state; +} + +/** + * set the state of the class indentation option. If true, C++ class + * definitions will be indented one additional indent. + * + * @param state state of option. + */ +void ASBeautifier::setClassIndent(bool state) +{ + classIndent = state; +} + +/** + * set the state of the modifier indentation option. If true, C++ class + * access modifiers will be indented one-half an indent. + * + * @param state state of option. + */ +void ASBeautifier::setModifierIndent(bool state) +{ + modifierIndent = state; +} + +/** + * set the state of the switch indentation option. If true, blocks of 'switch' + * statements will be indented one additional indent. + * + * @param state state of option. + */ +void ASBeautifier::setSwitchIndent(bool state) +{ + switchIndent = state; +} + +/** + * set the state of the case indentation option. If true, lines of 'case' + * statements will be indented one additional indent. + * + * @param state state of option. + */ +void ASBeautifier::setCaseIndent(bool state) +{ + caseIndent = state; +} + +/** + * set the state of the namespace indentation option. + * If true, blocks of 'namespace' statements will be indented one + * additional indent. Otherwise, NO indentation will be added. + * + * @param state state of option. + */ +void ASBeautifier::setNamespaceIndent(bool state) +{ + namespaceIndent = state; +} + +/** + * set the state of the label indentation option. + * If true, labels will be indented one indent LESS than the + * current indentation level. + * If false, labels will be flushed to the left with NO + * indent at all. + * + * @param state state of option. + */ +void ASBeautifier::setLabelIndent(bool state) +{ + labelIndent = state; +} + +/** + * set the state of the preprocessor indentation option. + * If true, multi-line #define statements will be indented. + * + * @param state state of option. + */ +void ASBeautifier::setPreprocDefineIndent(bool state) +{ + shouldIndentPreprocDefine = state; +} + +void ASBeautifier::setPreprocConditionalIndent(bool state) +{ + shouldIndentPreprocConditional = state; +} + +/** + * set the state of the empty line fill option. + * If true, empty lines will be filled with the whitespace. + * of their previous lines. + * If false, these lines will remain empty. + * + * @param state state of option. + */ +void ASBeautifier::setEmptyLineFill(bool state) +{ + emptyLineFill = state; +} + +void ASBeautifier::setAlignMethodColon(bool state) +{ + shouldAlignMethodColon = state; +} + +/** + * get the file type. + */ +int ASBeautifier::getFileType() const +{ + return fileType; +} + +/** + * get the number of spaces per indent + * + * @return value of indentLength option. + */ +int ASBeautifier::getIndentLength(void) const +{ + return indentLength; +} + +/** + * get the char used for indentation, space or tab + * + * @return the char used for indentation. + */ +string ASBeautifier::getIndentString(void) const +{ + return indentString; +} + +/** + * get mode manually set flag + */ +bool ASBeautifier::getModeManuallySet() const +{ + return isModeManuallySet; +} + +/** + * get the state of the force tab indentation option. + * + * @return state of force tab indentation. + */ +bool ASBeautifier::getForceTabIndentation(void) const +{ + return shouldForceTabIndentation; +} + +/** +* Get the state of the Objective-C align method colon option. +* +* @return state of shouldAlignMethodColon option. +*/ +bool ASBeautifier::getAlignMethodColon(void) const +{ + return shouldAlignMethodColon; +} + +/** + * get the state of the block indentation option. + * + * @return state of blockIndent option. + */ +bool ASBeautifier::getBlockIndent(void) const +{ + return blockIndent; +} + +/** + * get the state of the bracket indentation option. + * + * @return state of bracketIndent option. + */ +bool ASBeautifier::getBracketIndent(void) const +{ + return bracketIndent; +} + +/** +* Get the state of the namespace indentation option. If true, blocks +* of the 'namespace' statement will be indented one additional indent. +* +* @return state of namespaceIndent option. +*/ +bool ASBeautifier::getNamespaceIndent(void) const +{ + return namespaceIndent; +} + +/** + * Get the state of the class indentation option. If true, blocks of + * the 'class' statement will be indented one additional indent. + * + * @return state of classIndent option. + */ +bool ASBeautifier::getClassIndent(void) const +{ + return classIndent; +} + +/** + * Get the state of the class access modifier indentation option. + * If true, the class access modifiers will be indented one-half indent. + * + * @return state of modifierIndent option. + */ +bool ASBeautifier::getModifierIndent(void) const +{ + return modifierIndent; +} + +/** + * get the state of the switch indentation option. If true, blocks of + * the 'switch' statement will be indented one additional indent. + * + * @return state of switchIndent option. + */ +bool ASBeautifier::getSwitchIndent(void) const +{ + return switchIndent; +} + +/** + * get the state of the case indentation option. If true, lines of 'case' + * statements will be indented one additional indent. + * + * @return state of caseIndent option. + */ +bool ASBeautifier::getCaseIndent(void) const +{ + return caseIndent; +} + +/** + * get the state of the empty line fill option. + * If true, empty lines will be filled with the whitespace. + * of their previous lines. + * If false, these lines will remain empty. + * + * @return state of emptyLineFill option. + */ +bool ASBeautifier::getEmptyLineFill(void) const +{ + return emptyLineFill; +} + +/** + * get the state of the preprocessor indentation option. + * If true, preprocessor "define" lines will be indented. + * If false, preprocessor "define" lines will be unchanged. + * + * @return state of shouldIndentPreprocDefine option. + */ +bool ASBeautifier::getPreprocDefineIndent(void) const +{ + return shouldIndentPreprocDefine; +} + +/** + * get the length of the tab indentation option. + * + * @return length of tab indent option. + */ +int ASBeautifier::getTabLength(void) const +{ + return tabLength; +} + +/** + * beautify a line of source code. + * every line of source code in a source code file should be sent + * one after the other to the beautify method. + * + * @return the indented line. + * @param originalLine the original unindented line. + */ +string ASBeautifier::beautify(const string& originalLine) +{ + string line; + bool isInQuoteContinuation = isInVerbatimQuote | haveLineContinuationChar; + + currentHeader = NULL; + lastLineHeader = NULL; + blockCommentNoBeautify = blockCommentNoIndent; + isInClass = false; + isInSwitch = false; + lineBeginsWithOpenBracket = false; + lineBeginsWithCloseBracket = false; + lineBeginsWithComma = false; + lineIsCommentOnly = false; + lineIsLineCommentOnly = false; + shouldIndentBrackettedLine = true; + isInAsmOneLine = false; + lineOpensWithLineComment = false; + lineOpensWithComment = false; + lineStartsInComment = isInComment; + previousLineProbationTab = false; + haveLineContinuationChar = false; + lineOpeningBlocksNum = 0; + lineClosingBlocksNum = 0; + if (isImmediatelyPostObjCMethodDefinition) + clearObjCMethodDefinitionAlignment(); + + // handle and remove white spaces around the line: + // If not in comment, first find out size of white space before line, + // so that possible comments starting in the line continue in + // relation to the preliminary white-space. + if (isInQuoteContinuation) + { + // trim a single space added by ASFormatter, otherwise leave it alone + if (!(originalLine.length() == 1 && originalLine[0] == ' ')) + line = originalLine; + } + else if (isInComment || isInBeautifySQL) + { + // trim the end of comment and SQL lines + line = originalLine; + size_t trimEnd = line.find_last_not_of(" \t"); + if (trimEnd == string::npos) + trimEnd = 0; + else + trimEnd++; + if (trimEnd < line.length()) + line.erase(trimEnd); + // does a bracket open the line + size_t firstChar = line.find_first_not_of(" \t"); + if (firstChar != string::npos) + { + if (line[firstChar] == '{') + lineBeginsWithOpenBracket = true; + else if (line[firstChar] == '}') + lineBeginsWithCloseBracket = true; + else if (line[firstChar] == ',') + lineBeginsWithComma = true; + } + } + else + { + line = trim(originalLine); + if (line.length() > 0) + { + if (line[0] == '{') + lineBeginsWithOpenBracket = true; + else if (line[0] == '}') + lineBeginsWithCloseBracket = true; + else if (line[0] == ',') + lineBeginsWithComma = true; + else if (line.compare(0, 2, "//") == 0) + lineIsLineCommentOnly = true; + else if (line.compare(0, 2, "/*") == 0) + { + if (line.find("*/", 2) != string::npos) + lineIsCommentOnly = true; + } + } + + isInHorstmannComment = false; + size_t j = line.find_first_not_of(" \t{"); + if (j != string::npos && line.compare(j, 2, "//") == 0) + lineOpensWithLineComment = true; + if (j != string::npos && line.compare(j, 2, "/*") == 0) + { + lineOpensWithComment = true; + size_t k = line.find_first_not_of(" \t"); + if (k != string::npos && line.compare(k, 1, "{") == 0) + isInHorstmannComment = true; + } + } + + // When indent is OFF the lines must still be processed by ASBeautifier. + // Otherwise the lines immediately following may not be indented correctly. + if ((lineIsLineCommentOnly || lineIsCommentOnly) + && line.find("*INDENT-OFF*", 0) != string::npos) + isIndentModeOff = true; + + if (line.length() == 0) + { + if (backslashEndsPrevLine) + { + backslashEndsPrevLine = false; + isInDefine = false; + isInDefineDefinition = false; + } + if (emptyLineFill && !isInQuoteContinuation) + { + if (isInIndentablePreprocBlock) + return preLineWS(preprocBlockIndent, 0); + else if (!headerStack->empty() || isInEnum) + return preLineWS(prevFinalLineIndentCount, prevFinalLineSpaceIndentCount); + // must fall thru here + } + else + return line; + } + + // handle preprocessor commands + if (isInIndentablePreprocBlock + && line.length() > 0 + && line[0] != '#') + { + string indentedLine; + if (isInClassHeaderTab || isInClassInitializer) + { + // parsing is turned off in ASFormatter by indent-off + // the originalLine will probably never be returned here + indentedLine = preLineWS(prevFinalLineIndentCount, prevFinalLineSpaceIndentCount) + line; + return getIndentedLineReturn(indentedLine, originalLine); + } + else + { + indentedLine = preLineWS(preprocBlockIndent, 0) + line; + return getIndentedLineReturn(indentedLine, originalLine); + } + } + if (!isInComment + && !isInQuoteContinuation + && line.length() > 0 + && ((line[0] == '#' && !isIndentedPreprocessor(line, 0)) + || backslashEndsPrevLine)) + { + if (line[0] == '#' && !isInDefine) + { + string preproc = extractPreprocessorStatement(line); + processPreprocessor(preproc, line); + if (isInIndentablePreprocBlock || isInIndentablePreproc) + { + string indentedLine; + if ((preproc.length() >= 2 && preproc.substr(0, 2) == "if")) // #if, #ifdef, #ifndef + { + indentedLine = preLineWS(preprocBlockIndent, 0) + line; + preprocBlockIndent += 1; + isInIndentablePreprocBlock = true; + } + else if (preproc == "else" || preproc == "elif" || preproc == "elseif") + { + indentedLine = preLineWS(preprocBlockIndent - 1, 0) + line; + } + else if (preproc == "endif" || preproc == "end") + { + preprocBlockIndent -= 1; + indentedLine = preLineWS(preprocBlockIndent, 0) + line; + if (preprocBlockIndent == 0) + isInIndentablePreprocBlock = false; + } + else + indentedLine = preLineWS(preprocBlockIndent, 0) + line; + return getIndentedLineReturn(indentedLine, originalLine); + } + if (shouldIndentPreprocConditional && preproc.length() > 0) + { + string indentedLine; + if (preproc.length() >= 2 && preproc.substr(0, 2) == "if") // #if, #ifdef, #ifndef + { + pair entry; // indentCount, spaceIndentCount + if (!isInDefine && activeBeautifierStack != NULL && !activeBeautifierStack->empty()) + entry = activeBeautifierStack->back()->computePreprocessorIndent(); + else + entry = computePreprocessorIndent(); + preprocIndentStack->push_back(entry); + indentedLine = preLineWS(preprocIndentStack->back().first, + preprocIndentStack->back().second) + line; + return getIndentedLineReturn(indentedLine, originalLine); + } + else if (preproc == "else" || preproc == "elif" || preproc == "elseif") + { + if (preprocIndentStack->size() > 0) // if no entry don't indent + { + indentedLine = preLineWS(preprocIndentStack->back().first, + preprocIndentStack->back().second) + line; + return getIndentedLineReturn(indentedLine, originalLine); + } + } + else if (preproc == "endif" || preproc == "end") + { + if (preprocIndentStack->size() > 0) // if no entry don't indent + { + indentedLine = preLineWS(preprocIndentStack->back().first, + preprocIndentStack->back().second) + line; + preprocIndentStack->pop_back(); + return getIndentedLineReturn(indentedLine, originalLine); + } + } + } + } + + // check if the last char is a backslash + if (line.length() > 0) + backslashEndsPrevLine = (line[line.length() - 1] == '\\'); + // comments within the definition line can be continued without the backslash + if (isInPreprocessorUnterminatedComment(line)) + backslashEndsPrevLine = true; + + // check if this line ends a multi-line #define + // if so, use the #define's cloned beautifier for the line's indentation + // and then remove it from the active beautifier stack and delete it. + if (!backslashEndsPrevLine && isInDefineDefinition && !isInDefine) + { + isInDefineDefinition = false; + ASBeautifier* defineBeautifier = activeBeautifierStack->back(); + activeBeautifierStack->pop_back(); + + string indentedLine = defineBeautifier->beautify(line); + delete defineBeautifier; + return getIndentedLineReturn(indentedLine, originalLine); + } + + // unless this is a multi-line #define, return this precompiler line as is. + if (!isInDefine && !isInDefineDefinition) + return originalLine; + } + + // if there exists any worker beautifier in the activeBeautifierStack, + // then use it instead of me to indent the current line. + // variables set by ASFormatter must be updated. + if (!isInDefine && activeBeautifierStack != NULL && !activeBeautifierStack->empty()) + { + activeBeautifierStack->back()->inLineNumber = inLineNumber; + activeBeautifierStack->back()->horstmannIndentInStatement = horstmannIndentInStatement; + activeBeautifierStack->back()->nonInStatementBracket = nonInStatementBracket; + activeBeautifierStack->back()->objCColonAlignSubsequent = objCColonAlignSubsequent; + activeBeautifierStack->back()->lineCommentNoBeautify = lineCommentNoBeautify; + activeBeautifierStack->back()->isElseHeaderIndent = isElseHeaderIndent; + activeBeautifierStack->back()->isCaseHeaderCommentIndent = isCaseHeaderCommentIndent; + activeBeautifierStack->back()->isNonInStatementArray = isNonInStatementArray; + activeBeautifierStack->back()->isSharpAccessor = isSharpAccessor; + activeBeautifierStack->back()->isSharpDelegate = isSharpDelegate; + activeBeautifierStack->back()->isInExternC = isInExternC; + activeBeautifierStack->back()->isInBeautifySQL = isInBeautifySQL; + activeBeautifierStack->back()->isInIndentableStruct = isInIndentableStruct; + activeBeautifierStack->back()->isInIndentablePreproc = isInIndentablePreproc; + // must return originalLine not the trimmed line + return activeBeautifierStack->back()->beautify(originalLine); + } + + // Flag an indented header in case this line is a one-line block. + // The header in the header stack will be deleted by a one-line block. + bool isInExtraHeaderIndent = false; + if (!headerStack->empty() + && lineBeginsWithOpenBracket + && (headerStack->back() != &AS_OPEN_BRACKET + || probationHeader != NULL)) + isInExtraHeaderIndent = true; + + size_t iPrelim = headerStack->size(); + + // calculate preliminary indentation based on headerStack and data from past lines + computePreliminaryIndentation(); + + // parse characters in the current line. + parseCurrentLine(line); + + // handle special cases of indentation + adjustParsedLineIndentation(iPrelim, isInExtraHeaderIndent); + + // Objective-C continuation line + if (isInObjCMethodDefinition) + { + // register indent for Objective-C continuation line + if (line.length() > 0 + && (line[0] == '-' || line[0] == '+')) + { + if (shouldAlignMethodColon) + { + colonIndentObjCMethodDefinition = line.find(':'); + int objCColonAlignSubsequentIndent = objCColonAlignSubsequent + indentLength; + if (objCColonAlignSubsequentIndent > colonIndentObjCMethodDefinition) + colonIndentObjCMethodDefinition = objCColonAlignSubsequentIndent; + } + else if (inStatementIndentStack->empty() + || inStatementIndentStack->back() == 0) + { + inStatementIndentStack->push_back(indentLength); + isInStatement = true; + } + } + // set indent for last definition line + else if (!lineBeginsWithOpenBracket) + { + if (shouldAlignMethodColon) + spaceIndentCount = computeObjCColonAlignment(line, colonIndentObjCMethodDefinition); + else if (inStatementIndentStack->empty()) + spaceIndentCount = spaceIndentObjCMethodDefinition; + } + } + + if (isInDefine) + { + if (line.length() > 0 && line[0] == '#') + { + // the 'define' does not have to be attached to the '#' + string preproc = trim(line.substr(1)); + if (preproc.compare(0, 6, "define") == 0) + { + if (!inStatementIndentStack->empty() + && inStatementIndentStack->back() > 0) + { + defineIndentCount = indentCount; + } + else + { + defineIndentCount = indentCount - 1; + --indentCount; + } + } + } + + indentCount -= defineIndentCount; + } + + if (indentCount < 0) + indentCount = 0; + + if (lineCommentNoBeautify || blockCommentNoBeautify || isInQuoteContinuation) + indentCount = spaceIndentCount = 0; + + // finally, insert indentations into beginning of line + + string indentedLine = preLineWS(indentCount, spaceIndentCount) + line; + indentedLine = getIndentedLineReturn(indentedLine, originalLine); + + prevFinalLineSpaceIndentCount = spaceIndentCount; + prevFinalLineIndentCount = indentCount; + + if (lastLineHeader != NULL) + previousLastLineHeader = lastLineHeader; + + if ((lineIsLineCommentOnly || lineIsCommentOnly) + && line.find("*INDENT-ON*", 0) != string::npos) + isIndentModeOff = false; + + return indentedLine; +} + +string& ASBeautifier::getIndentedLineReturn(string& newLine, const string& originalLine) const +{ + if (isIndentModeOff) + return const_cast(originalLine); + return newLine; +} + +string ASBeautifier::preLineWS(int lineIndentCount, int lineSpaceIndentCount) const +{ + if (shouldForceTabIndentation) + { + if (tabLength != indentLength) + { + // adjust for different tab length + int indentCountOrig = lineIndentCount; + int spaceIndentCountOrig = lineSpaceIndentCount; + lineIndentCount = ((indentCountOrig * indentLength) + spaceIndentCountOrig) / tabLength; + lineSpaceIndentCount = ((indentCountOrig * indentLength) + spaceIndentCountOrig) % tabLength; + } + else + { + lineIndentCount += lineSpaceIndentCount / indentLength; + lineSpaceIndentCount = lineSpaceIndentCount % indentLength; + } + } + + string ws; + for (int i = 0; i < lineIndentCount; i++) + ws += indentString; + while ((lineSpaceIndentCount--) > 0) + ws += string(" "); + return ws; +} + +/** + * register an in-statement indent. + */ +void ASBeautifier::registerInStatementIndent(const string& line, int i, int spaceTabCount_, + int tabIncrementIn, int minIndent, bool updateParenStack) +{ + int remainingCharNum = line.length() - i; + int nextNonWSChar = getNextProgramCharDistance(line, i); + + // if indent is around the last char in the line, indent instead one indent from the previous indent + if (nextNonWSChar == remainingCharNum) + { + int previousIndent = spaceTabCount_; + if (!inStatementIndentStack->empty()) + previousIndent = inStatementIndentStack->back(); + int currIndent = /*2*/ indentLength + previousIndent; + if (currIndent > maxInStatementIndent + && line[i] != '{') + currIndent = indentLength * 2 + spaceTabCount_; + inStatementIndentStack->push_back(currIndent); + if (updateParenStack) + parenIndentStack->push_back(previousIndent); + return; + } + + if (updateParenStack) + parenIndentStack->push_back(i + spaceTabCount_ - horstmannIndentInStatement); + + int tabIncrement = tabIncrementIn; + + // check for following tabs + for (int j = i + 1; j < (i + nextNonWSChar); j++) + { + if (line[j] == '\t') + tabIncrement += convertTabToSpaces(j, tabIncrement); + } + + int inStatementIndent = i + nextNonWSChar + spaceTabCount_ + tabIncrement; + + // check for run-in statement + if (i > 0 && line[0] == '{') + inStatementIndent -= indentLength; + + if (inStatementIndent < minIndent) + inStatementIndent = minIndent + spaceTabCount_; + + // this is not done for an in-statement array + if (inStatementIndent > maxInStatementIndent + && !(prevNonLegalCh == '=' && currentNonLegalCh == '{')) + inStatementIndent = indentLength * 2 + spaceTabCount_; + + if (!inStatementIndentStack->empty() + && inStatementIndent < inStatementIndentStack->back()) + inStatementIndent = inStatementIndentStack->back(); + + // the block opener is not indented for a NonInStatementArray + if (isNonInStatementArray && !isInEnum && !bracketBlockStateStack->empty() && bracketBlockStateStack->back()) + inStatementIndent = 0; + + inStatementIndentStack->push_back(inStatementIndent); +} + +/** +* Register an in-statement indent for a class header or a class initializer colon. +*/ +void ASBeautifier::registerInStatementIndentColon(const string& line, int i, int tabIncrementIn) +{ + assert(line[i] == ':'); + assert(isInClassInitializer || isInClassHeaderTab); + + // register indent at first word after the colon + size_t firstChar = line.find_first_not_of(" \t"); + if (firstChar == (size_t)i) // firstChar is ':' + { + size_t firstWord = line.find_first_not_of(" \t", firstChar + 1); + if (firstChar != string::npos) + { + int inStatementIndent = firstWord + spaceIndentCount + tabIncrementIn; + inStatementIndentStack->push_back(inStatementIndent); + isInStatement = true; + } + } +} + +/** + * Compute indentation for a preprocessor #if statement. + * This may be called for the activeBeautiferStack + * instead of the active ASBeautifier object. + */ +pair ASBeautifier::computePreprocessorIndent() +{ + computePreliminaryIndentation(); + pair entry(indentCount, spaceIndentCount); + if (!headerStack->empty() + && entry.first > 0 + && (headerStack->back() == &AS_IF + || headerStack->back() == &AS_ELSE + || headerStack->back() == &AS_FOR + || headerStack->back() == &AS_WHILE)) + --entry.first; + return entry; +} + +/** + * get distance to the next non-white space, non-comment character in the line. + * if no such character exists, return the length remaining to the end of the line. + */ +int ASBeautifier::getNextProgramCharDistance(const string& line, int i) const +{ + bool inComment = false; + int remainingCharNum = line.length() - i; + int charDistance; + char ch; + + for (charDistance = 1; charDistance < remainingCharNum; charDistance++) + { + ch = line[i + charDistance]; + if (inComment) + { + if (line.compare(i + charDistance, 2, "*/") == 0) + { + charDistance++; + inComment = false; + } + continue; + } + else if (isWhiteSpace(ch)) + continue; + else if (ch == '/') + { + if (line.compare(i + charDistance, 2, "//") == 0) + return remainingCharNum; + else if (line.compare(i + charDistance, 2, "/*") == 0) + { + charDistance++; + inComment = true; + } + } + else + return charDistance; + } + + return charDistance; +} + +// check if a specific line position contains a header. +const string* ASBeautifier::findHeader(const string& line, int i, + const vector* possibleHeaders) const +{ + assert(isCharPotentialHeader(line, i)); + // check the word + size_t maxHeaders = possibleHeaders->size(); + for (size_t p = 0; p < maxHeaders; p++) + { + const string* header = (*possibleHeaders)[p]; + const size_t wordEnd = i + header->length(); + if (wordEnd > line.length()) + continue; + int result = (line.compare(i, header->length(), *header)); + if (result > 0) + continue; + if (result < 0) + break; + // check that this is not part of a longer word + if (wordEnd == line.length()) + return header; + if (isLegalNameChar(line[wordEnd])) + continue; + const char peekChar = peekNextChar(line, wordEnd - 1); + // is not a header if part of a definition + if (peekChar == ',' || peekChar == ')') + break; + // the following accessor definitions are NOT headers + // goto default; is NOT a header + // default(int) keyword in C# is NOT a header + else if ((header == &AS_GET || header == &AS_SET || header == &AS_DEFAULT) + && (peekChar == ';' || peekChar == '(' || peekChar == '=')) + break; + return header; + } + return NULL; +} + +// check if a specific line position contains an operator. +const string* ASBeautifier::findOperator(const string& line, int i, + const vector* possibleOperators) const +{ + assert(isCharPotentialOperator(line[i])); + // find the operator in the vector + // the vector contains the LONGEST operators first + // must loop thru the entire vector + size_t maxOperators = possibleOperators->size(); + for (size_t p = 0; p < maxOperators; p++) + { + const size_t wordEnd = i + (*(*possibleOperators)[p]).length(); + if (wordEnd > line.length()) + continue; + if (line.compare(i, (*(*possibleOperators)[p]).length(), *(*possibleOperators)[p]) == 0) + return (*possibleOperators)[p]; + } + return NULL; +} + +/** + * find the index number of a string element in a container of strings + * + * @return the index number of element in the container. -1 if element not found. + * @param container a vector of strings. + * @param element the element to find . + */ +int ASBeautifier::indexOf(vector& container, const string* element) const +{ + vector::const_iterator where; + + where = find(container.begin(), container.end(), element); + if (where == container.end()) + return -1; + else + return (int) (where - container.begin()); +} + +/** + * convert tabs to spaces. + * i is the position of the character to convert to spaces. + * tabIncrementIn is the increment that must be added for tab indent characters + * to get the correct column for the current tab. + */ +int ASBeautifier::convertTabToSpaces(int i, int tabIncrementIn) const +{ + int tabToSpacesAdjustment = indentLength - 1 - ((tabIncrementIn + i) % indentLength); + return tabToSpacesAdjustment; +} + +/** + * trim removes the white space surrounding a line. + * + * @return the trimmed line. + * @param str the line to trim. + */ +string ASBeautifier::trim(const string& str) const +{ + int start = 0; + int end = str.length() - 1; + + while (start < end && isWhiteSpace(str[start])) + start++; + + while (start <= end && isWhiteSpace(str[end])) + end--; + + // don't trim if it ends in a continuation + if (end > -1 && str[end] == '\\') + end = str.length() - 1; + + string returnStr(str, start, end + 1 - start); + return returnStr; +} + +/** + * rtrim removes the white space from the end of a line. + * + * @return the trimmed line. + * @param str the line to trim. + */ +string ASBeautifier::rtrim(const string& str) const +{ + size_t len = str.length(); + size_t end = str.find_last_not_of(" \t"); + if (end == string::npos + || end == len - 1) + return str; + string returnStr(str, 0, end + 1); + return returnStr; +} + +/** + * Copy tempStacks for the copy constructor. + * The value of the vectors must also be copied. + */ +vector*>* ASBeautifier::copyTempStacks(const ASBeautifier& other) const +{ + vector*>* tempStacksNew = new vector*>; + vector*>::iterator iter; + for (iter = other.tempStacks->begin(); + iter != other.tempStacks->end(); + ++iter) + { + vector* newVec = new vector; + *newVec = **iter; + tempStacksNew->push_back(newVec); + } + return tempStacksNew; +} + +/** + * delete a member vectors to eliminate memory leak reporting + */ +void ASBeautifier::deleteBeautifierVectors() +{ + beautifierFileType = 9; // reset to an invalid type + delete headers; + delete nonParenHeaders; + delete preBlockStatements; + delete preCommandHeaders; + delete assignmentOperators; + delete nonAssignmentOperators; + delete indentableHeaders; +} + +/** + * delete a vector object + * T is the type of vector + * used for all vectors except tempStacks + */ +template +void ASBeautifier::deleteContainer(T& container) +{ + if (container != NULL) + { + container->clear(); + delete (container); + container = NULL; + } +} + +/** + * Delete the ASBeautifier vector object. + * This is a vector of pointers to ASBeautifier objects allocated with the 'new' operator. + * Therefore the ASBeautifier objects have to be deleted in addition to the + * ASBeautifier pointer entries. + */ +void ASBeautifier::deleteBeautifierContainer(vector*& container) +{ + if (container != NULL) + { + vector::iterator iter = container->begin(); + while (iter < container->end()) + { + delete *iter; + ++iter; + } + container->clear(); + delete (container); + container = NULL; + } +} + +/** + * Delete the tempStacks vector object. + * The tempStacks is a vector of pointers to strings allocated with the 'new' operator. + * Therefore the strings have to be deleted in addition to the tempStacks entries. + */ +void ASBeautifier::deleteTempStacksContainer(vector*>*& container) +{ + if (container != NULL) + { + vector*>::iterator iter = container->begin(); + while (iter < container->end()) + { + delete *iter; + ++iter; + } + container->clear(); + delete (container); + container = NULL; + } +} + +/** + * initialize a vector object + * T is the type of vector used for all vectors + */ +template +void ASBeautifier::initContainer(T& container, T value) +{ + // since the ASFormatter object is never deleted, + // the existing vectors must be deleted before creating new ones + if (container != NULL) + deleteContainer(container); + container = value; +} + +/** + * Initialize the tempStacks vector object. + * The tempStacks is a vector of pointers to strings allocated with the 'new' operator. + * Any residual entries are deleted before the vector is initialized. + */ +void ASBeautifier::initTempStacksContainer(vector*>*& container, + vector*>* value) +{ + if (container != NULL) + deleteTempStacksContainer(container); + container = value; +} + +/** + * Determine if an assignment statement ends with a comma + * that is not in a function argument. It ends with a + * comma if a comma is the last char on the line. + * + * @return true if line ends with a comma, otherwise false. + */ +bool ASBeautifier::statementEndsWithComma(const string& line, int index) const +{ + assert(line[index] == '='); + + bool isInComment_ = false; + bool isInQuote_ = false; + int parenCount = 0; + size_t lineLength = line.length(); + size_t i = 0; + char quoteChar_ = ' '; + + for (i = index + 1; i < lineLength; ++i) + { + char ch = line[i]; + + if (isInComment_) + { + if (line.compare(i, 2, "*/") == 0) + { + isInComment_ = false; + ++i; + } + continue; + } + + if (ch == '\\') + { + ++i; + continue; + } + + if (isInQuote_) + { + if (ch == quoteChar_) + isInQuote_ = false; + continue; + } + + if (ch == '"' + || (ch == '\'' && !isDigitSeparator(line, i))) + { + isInQuote_ = true; + quoteChar_ = ch; + continue; + } + + if (line.compare(i, 2, "//") == 0) + break; + + if (line.compare(i, 2, "/*") == 0) + { + if (isLineEndComment(line, i)) + break; + else + { + isInComment_ = true; + ++i; + continue; + } + } + + if (ch == '(') + parenCount++; + if (ch == ')') + parenCount--; + } + if (isInComment_ + || isInQuote_ + || parenCount > 0) + return false; + + size_t lastChar = line.find_last_not_of(" \t", i - 1); + + if (lastChar == string::npos || line[lastChar] != ',') + return false; + + return true; +} + +/** + * check if current comment is a line-end comment + * + * @return is before a line-end comment. + */ +bool ASBeautifier::isLineEndComment(const string& line, int startPos) const +{ + assert(line.compare(startPos, 2, "/*") == 0); + + // comment must be closed on this line with nothing after it + size_t endNum = line.find("*/", startPos + 2); + if (endNum != string::npos) + { + size_t nextChar = line.find_first_not_of(" \t", endNum + 2); + if (nextChar == string::npos) + return true; + } + return false; +} + +/** + * get the previous word index for an assignment operator + * + * @return is the index to the previous word (the in statement indent). + */ +int ASBeautifier::getInStatementIndentAssign(const string& line, size_t currPos) const +{ + assert(line[currPos] == '='); + + if (currPos == 0) + return 0; + + // get the last legal word (may be a number) + size_t end = line.find_last_not_of(" \t", currPos - 1); + if (end == string::npos || !isLegalNameChar(line[end])) + return 0; + + int start; // start of the previous word + for (start = end; start > -1; start--) + { + if (!isLegalNameChar(line[start]) || line[start] == '.') + break; + } + start++; + + return start; +} + +/** + * get the instatement indent for a comma + * + * @return is the indent to the second word on the line (the in statement indent). + */ +int ASBeautifier::getInStatementIndentComma(const string& line, size_t currPos) const +{ + assert(line[currPos] == ','); + + // get first word on a line + size_t indent = line.find_first_not_of(" \t"); + if (indent == string::npos || !isLegalNameChar(line[indent])) + return 0; + + // bypass first word + for (; indent < currPos; indent++) + { + if (!isLegalNameChar(line[indent])) + break; + } + indent++; + if (indent >= currPos || indent < 4) + return 0; + + // point to second word or assignment operator + indent = line.find_first_not_of(" \t", indent); + if (indent == string::npos || indent >= currPos) + return 0; + + return indent; +} + +/** + * get the next word on a line + * the argument 'currPos' must point to the current position. + * + * @return is the next word or an empty string if none found. + */ +string ASBeautifier::getNextWord(const string& line, size_t currPos) const +{ + size_t lineLength = line.length(); + // get the last legal word (may be a number) + if (currPos == lineLength - 1) + return string(); + + size_t start = line.find_first_not_of(" \t", currPos + 1); + if (start == string::npos || !isLegalNameChar(line[start])) + return string(); + + size_t end; // end of the current word + for (end = start + 1; end <= lineLength; end++) + { + if (!isLegalNameChar(line[end]) || line[end] == '.') + break; + } + + return line.substr(start, end - start); +} + +/** + * Check if a preprocessor directive is always indented. + * C# "region" and "endregion" are always indented. + * C/C++ "pragma omp" is always indented. + * + * @return is true or false. + */ +bool ASBeautifier::isIndentedPreprocessor(const string& line, size_t currPos) const +{ + assert(line[0] == '#'); + string nextWord = getNextWord(line, currPos); + if (nextWord == "region" || nextWord == "endregion") + return true; + // is it #pragma omp + if (nextWord == "pragma") + { + // find pragma + size_t start = line.find("pragma"); + if (start == string::npos || !isLegalNameChar(line[start])) + return false; + // bypass pragma + for (; start < line.length(); start++) + { + if (!isLegalNameChar(line[start])) + break; + } + start++; + if (start >= line.length()) + return false; + // point to start of second word + start = line.find_first_not_of(" \t", start); + if (start == string::npos) + return false; + // point to end of second word + size_t end; + for (end = start; end < line.length(); end++) + { + if (!isLegalNameChar(line[end])) + break; + } + // check for "pragma omp" + string word = line.substr(start, end - start); + if (word == "omp" || word == "region" || word == "endregion") + return true; + } + return false; +} + +/** + * Check if a preprocessor directive is checking for __cplusplus defined. + * + * @return is true or false. + */ +bool ASBeautifier::isPreprocessorConditionalCplusplus(const string& line) const +{ + string preproc = trim(line.substr(1)); + if (preproc.compare(0, 5, "ifdef") == 0 && getNextWord(preproc, 4) == "__cplusplus") + return true; + if (preproc.compare(0, 2, "if") == 0) + { + // check for " #if defined(__cplusplus)" + size_t charNum = 2; + charNum = preproc.find_first_not_of(" \t", charNum); + if (preproc.compare(charNum, 7, "defined") == 0) + { + charNum += 7; + charNum = preproc.find_first_not_of(" \t", charNum); + if (preproc.compare(charNum, 1, "(") == 0) + { + ++charNum; + charNum = preproc.find_first_not_of(" \t", charNum); + if (preproc.compare(charNum, 11, "__cplusplus") == 0) + return true; + } + } + } + return false; +} + +/** + * Check if a preprocessor definition contains an unterminated comment. + * Comments within a preprocessor definition can be continued without the backslash. + * + * @return is true or false. + */ +bool ASBeautifier::isInPreprocessorUnterminatedComment(const string& line) +{ + if (!isInPreprocessorComment) + { + size_t startPos = line.find("/*"); + if (startPos == string::npos) + return false; + } + size_t endNum = line.find("*/"); + if (endNum != string::npos) + { + isInPreprocessorComment = false; + return false; + } + isInPreprocessorComment = true; + return true; +} + +void ASBeautifier::popLastInStatementIndent() +{ + assert(!inStatementIndentStackSizeStack->empty()); + int previousIndentStackSize = inStatementIndentStackSizeStack->back(); + if (inStatementIndentStackSizeStack->size() > 1) + inStatementIndentStackSizeStack->pop_back(); + while (previousIndentStackSize < (int) inStatementIndentStack->size()) + inStatementIndentStack->pop_back(); +} + +// for unit testing +int ASBeautifier::getBeautifierFileType() const +{ return beautifierFileType; } + +/** + * Process preprocessor statements and update the beautifier stacks. + */ +void ASBeautifier::processPreprocessor(const string& preproc, const string& line) +{ + // When finding a multi-lined #define statement, the original beautifier + // 1. sets its isInDefineDefinition flag + // 2. clones a new beautifier that will be used for the actual indentation + // of the #define. This clone is put into the activeBeautifierStack in order + // to be called for the actual indentation. + // The original beautifier will have isInDefineDefinition = true, isInDefine = false + // The cloned beautifier will have isInDefineDefinition = true, isInDefine = true + if (shouldIndentPreprocDefine && preproc == "define" && line[line.length() - 1] == '\\') + { + if (!isInDefineDefinition) + { + // this is the original beautifier + isInDefineDefinition = true; + + // push a new beautifier into the active stack + // this beautifier will be used for the indentation of this define + ASBeautifier* defineBeautifier = new ASBeautifier(*this); + activeBeautifierStack->push_back(defineBeautifier); + } + else + { + // the is the cloned beautifier that is in charge of indenting the #define. + isInDefine = true; + } + } + else if (preproc.length() >= 2 && preproc.substr(0, 2) == "if") + { + if (isPreprocessorConditionalCplusplus(line) && !g_preprocessorCppExternCBracket) + g_preprocessorCppExternCBracket = 1; + // push a new beautifier into the stack + waitingBeautifierStackLengthStack->push_back(waitingBeautifierStack->size()); + activeBeautifierStackLengthStack->push_back(activeBeautifierStack->size()); + if (activeBeautifierStackLengthStack->back() == 0) + waitingBeautifierStack->push_back(new ASBeautifier(*this)); + else + waitingBeautifierStack->push_back(new ASBeautifier(*activeBeautifierStack->back())); + } + else if (preproc == "else") + { + if (waitingBeautifierStack && !waitingBeautifierStack->empty()) + { + // MOVE current waiting beautifier to active stack. + activeBeautifierStack->push_back(waitingBeautifierStack->back()); + waitingBeautifierStack->pop_back(); + } + } + else if (preproc == "elif" || preproc == "elseif") + { + if (waitingBeautifierStack && !waitingBeautifierStack->empty()) + { + // append a COPY current waiting beautifier to active stack, WITHOUT deleting the original. + activeBeautifierStack->push_back(new ASBeautifier(*(waitingBeautifierStack->back()))); + } + } + else if (preproc == "endif" || preproc == "end") + { + int stackLength = 0; + ASBeautifier* beautifier = NULL; + + if (waitingBeautifierStackLengthStack != NULL && !waitingBeautifierStackLengthStack->empty()) + { + stackLength = waitingBeautifierStackLengthStack->back(); + waitingBeautifierStackLengthStack->pop_back(); + while ((int) waitingBeautifierStack->size() > stackLength) + { + beautifier = waitingBeautifierStack->back(); + waitingBeautifierStack->pop_back(); + delete beautifier; + } + } + + if (!activeBeautifierStackLengthStack->empty()) + { + stackLength = activeBeautifierStackLengthStack->back(); + activeBeautifierStackLengthStack->pop_back(); + while ((int) activeBeautifierStack->size() > stackLength) + { + beautifier = activeBeautifierStack->back(); + activeBeautifierStack->pop_back(); + delete beautifier; + } + } + } +} + +// Compute the preliminary indentation based on data in the headerStack +// and data from previous lines. +// Update the class variable indentCount. +void ASBeautifier::computePreliminaryIndentation() +{ + indentCount = 0; + spaceIndentCount = 0; + isInClassHeaderTab = false; + + if (isInObjCMethodDefinition && !inStatementIndentStack->empty()) + spaceIndentObjCMethodDefinition = inStatementIndentStack->back(); + + if (!inStatementIndentStack->empty()) + spaceIndentCount = inStatementIndentStack->back(); + + for (size_t i = 0; i < headerStack->size(); i++) + { + isInClass = false; + + if (blockIndent) + { + // do NOT indent opening block for these headers + if (!((*headerStack)[i] == &AS_NAMESPACE + || (*headerStack)[i] == &AS_CLASS + || (*headerStack)[i] == &AS_STRUCT + || (*headerStack)[i] == &AS_UNION + || (*headerStack)[i] == &AS_INTERFACE + || (*headerStack)[i] == &AS_THROWS + || (*headerStack)[i] == &AS_STATIC)) + ++indentCount; + } + else if (!(i > 0 && (*headerStack)[i - 1] != &AS_OPEN_BRACKET + && (*headerStack)[i] == &AS_OPEN_BRACKET)) + ++indentCount; + + if (!isJavaStyle() && !namespaceIndent && i > 0 + && (*headerStack)[i - 1] == &AS_NAMESPACE + && (*headerStack)[i] == &AS_OPEN_BRACKET) + --indentCount; + + if (isCStyle() && i >= 1 + && (*headerStack)[i - 1] == &AS_CLASS + && (*headerStack)[i] == &AS_OPEN_BRACKET) + { + if (classIndent) + ++indentCount; + isInClass = true; + } + + // is the switchIndent option is on, indent switch statements an additional indent. + else if (switchIndent && i > 1 + && (*headerStack)[i - 1] == &AS_SWITCH + && (*headerStack)[i] == &AS_OPEN_BRACKET) + { + ++indentCount; + isInSwitch = true; + } + + } // end of for loop + + if (isInClassHeader) + { + if (!isJavaStyle()) + isInClassHeaderTab = true; + if (lineOpensWithLineComment || lineStartsInComment || lineOpensWithComment) + { + if (!lineBeginsWithOpenBracket) + --indentCount; + if (!inStatementIndentStack->empty()) + spaceIndentCount -= inStatementIndentStack->back(); + } + else if (blockIndent) + { + if (!lineBeginsWithOpenBracket) + ++indentCount; + } + } + + if (isInClassInitializer || isInEnumTypeID) + { + indentCount += classInitializerIndents; + } + + if (isInEnum && lineBeginsWithComma && !inStatementIndentStack->empty()) + { + // unregister '=' indent from the previous line + inStatementIndentStack->pop_back(); + isInStatement = false; + spaceIndentCount = 0; + } + + // Objective-C interface continuation line + if (isInObjCInterface) + ++indentCount; + + // unindent a class closing bracket... + if (!lineStartsInComment + && isCStyle() + && isInClass + && classIndent + && headerStack->size() >= 2 + && (*headerStack)[headerStack->size() - 2] == &AS_CLASS + && (*headerStack)[headerStack->size() - 1] == &AS_OPEN_BRACKET + && lineBeginsWithCloseBracket + && bracketBlockStateStack->back() == true) + --indentCount; + + // unindent an indented switch closing bracket... + else if (!lineStartsInComment + && isInSwitch + && switchIndent + && headerStack->size() >= 2 + && (*headerStack)[headerStack->size() - 2] == &AS_SWITCH + && (*headerStack)[headerStack->size() - 1] == &AS_OPEN_BRACKET + && lineBeginsWithCloseBracket) + --indentCount; + + // handle special case of horstmann comment in an indented class statement + if (isInClass + && classIndent + && isInHorstmannComment + && !lineOpensWithComment + && headerStack->size() > 1 + && (*headerStack)[headerStack->size() - 2] == &AS_CLASS) + --indentCount; + + if (isInConditional) + --indentCount; + if (g_preprocessorCppExternCBracket >= 4) + --indentCount; +} + +void ASBeautifier::adjustParsedLineIndentation(size_t iPrelim, bool isInExtraHeaderIndent) +{ + if (lineStartsInComment) + return; + + // unindent a one-line statement in a header indent + if (!blockIndent + && lineBeginsWithOpenBracket + && headerStack->size() < iPrelim + && isInExtraHeaderIndent + && (lineOpeningBlocksNum > 0 && lineOpeningBlocksNum <= lineClosingBlocksNum) + && shouldIndentBrackettedLine) + --indentCount; + + /* + * if '{' doesn't follow an immediately previous '{' in the headerStack + * (but rather another header such as "for" or "if", then unindent it + * by one indentation relative to its block. + */ + else if (!blockIndent + && lineBeginsWithOpenBracket + && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum <= lineClosingBlocksNum) + && (headerStack->size() > 1 && (*headerStack)[headerStack->size() - 2] != &AS_OPEN_BRACKET) + && shouldIndentBrackettedLine) + --indentCount; + + // must check one less in headerStack if more than one header on a line (allow-addins)... + else if (headerStack->size() > iPrelim + 1 + && !blockIndent + && lineBeginsWithOpenBracket + && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum <= lineClosingBlocksNum) + && (headerStack->size() > 2 && (*headerStack)[headerStack->size() - 3] != &AS_OPEN_BRACKET) + && shouldIndentBrackettedLine) + --indentCount; + + // unindent a closing bracket... + else if (lineBeginsWithCloseBracket + && shouldIndentBrackettedLine) + --indentCount; + + // correctly indent one-line-blocks... + else if (lineOpeningBlocksNum > 0 + && lineOpeningBlocksNum == lineClosingBlocksNum + && previousLineProbationTab) + --indentCount; + + if (indentCount < 0) + indentCount = 0; + + // take care of extra bracket indentation option... + if (!lineStartsInComment + && bracketIndent + && shouldIndentBrackettedLine + && (lineBeginsWithOpenBracket || lineBeginsWithCloseBracket)) + { + if (!bracketIndentVtk) + ++indentCount; + else + { + // determine if a style VTK bracket is indented + bool haveUnindentedBracket = false; + for (size_t i = 0; i < headerStack->size(); i++) + { + if (((*headerStack)[i] == &AS_NAMESPACE + || (*headerStack)[i] == &AS_CLASS + || (*headerStack)[i] == &AS_STRUCT) + && i + 1 < headerStack->size() + && (*headerStack)[i + 1] == &AS_OPEN_BRACKET) + i++; + else if (lineBeginsWithOpenBracket) + { + // don't double count the current bracket + if (i + 1 < headerStack->size() + && (*headerStack)[i] == &AS_OPEN_BRACKET) + haveUnindentedBracket = true; + } + else if ((*headerStack)[i] == &AS_OPEN_BRACKET) + haveUnindentedBracket = true; + } // end of for loop + if (haveUnindentedBracket) + ++indentCount; + } + } +} + +/** + * Compute indentCount adjustment when in a series of else-if statements + * and shouldBreakElseIfs is requested. + * It increments by one for each 'else' in the tempStack. + */ +int ASBeautifier::adjustIndentCountForBreakElseIfComments() const +{ + assert(isElseHeaderIndent && !tempStacks->empty()); + int indentCountIncrement = 0; + vector* lastTempStack = tempStacks->back(); + if (lastTempStack != NULL) + { + for (size_t i = 0; i < lastTempStack->size(); i++) + { + if (*lastTempStack->at(i) == AS_ELSE) + indentCountIncrement++; + } + } + return indentCountIncrement; +} + +/** + * Extract a preprocessor statement without the #. + * If a error occurs an empty string is returned. + */ +string ASBeautifier::extractPreprocessorStatement(const string& line) const +{ + string preproc; + size_t start = line.find_first_not_of("#/ \t"); + if (start == string::npos) + return preproc; + size_t end = line.find_first_of("/ \t", start); + if (end == string::npos) + end = line.length(); + preproc = line.substr(start, end - start); + return preproc; +} + +/** + * Clear the variables used to align the Objective-C method definitions. + */ +void ASBeautifier::clearObjCMethodDefinitionAlignment() +{ + assert(isImmediatelyPostObjCMethodDefinition); + spaceIndentCount = 0; + spaceIndentObjCMethodDefinition = 0; + colonIndentObjCMethodDefinition = 0; + objCColonAlignSubsequent = 0; + isInObjCMethodDefinition = false; + isImmediatelyPostObjCMethodDefinition = false; + if (!inStatementIndentStack->empty()) + inStatementIndentStack->pop_back(); +} + +/** + * Compute the spaceIndentCount necessary to align the current line colon + * with the colon position in the argument. + * If it cannot be aligned indentLength is returned and a new colon + * position is calculated. + */ +int ASBeautifier::computeObjCColonAlignment(string& line, int colonAlignPosition) const +{ + int colonPosition = line.find(':'); + if (colonPosition < 0 || colonPosition > colonAlignPosition) + return indentLength; + return (colonAlignPosition - colonPosition); +} + +/** + * Parse the current line to update indentCount and spaceIndentCount. + */ +void ASBeautifier::parseCurrentLine(const string& line) +{ + bool isInLineComment = false; + bool isInOperator = false; + bool isSpecialChar = false; + bool haveCaseIndent = false; + bool haveAssignmentThisLine = false; + bool closingBracketReached = false; + bool previousLineProbation = (probationHeader != NULL); + char ch = ' '; + int tabIncrementIn = 0; + + for (size_t i = 0; i < line.length(); i++) + { + ch = line[i]; + + if (isInBeautifySQL) + continue; + + if (isWhiteSpace(ch)) + { + if (ch == '\t') + tabIncrementIn += convertTabToSpaces(i, tabIncrementIn); + continue; + } + + // handle special characters (i.e. backslash+character such as \n, \t, ...) + + if (isInQuote && !isInVerbatimQuote) + { + if (isSpecialChar) + { + isSpecialChar = false; + continue; + } + if (line.compare(i, 2, "\\\\") == 0) + { + i++; + continue; + } + if (ch == '\\') + { + if (peekNextChar(line, i) == ' ') // is this '\' at end of line + haveLineContinuationChar = true; + else + isSpecialChar = true; + continue; + } + } + else if (isInDefine && ch == '\\') + continue; + + // handle quotes (such as 'x' and "Hello Dolly") + if (!(isInComment || isInLineComment) + && (ch == '"' + || (ch == '\'' && !isDigitSeparator(line, i)))) + { + if (!isInQuote) + { + quoteChar = ch; + isInQuote = true; + char prevCh = i > 0 ? line[i - 1] : ' '; + if (isCStyle() && prevCh == 'R') + { + int parenPos = line.find('(', i); + if (parenPos != -1) + { + isInVerbatimQuote = true; + verbatimDelimiter = line.substr(i + 1, parenPos - i - 1); + } + } + else if (isSharpStyle() && prevCh == '@') + isInVerbatimQuote = true; + // check for "C" following "extern" + else if (g_preprocessorCppExternCBracket == 2 && line.compare(i, 3, "\"C\"") == 0) + ++g_preprocessorCppExternCBracket; + } + else if (isInVerbatimQuote && ch == '"') + { + if (isCStyle()) + { + string delim = ')' + verbatimDelimiter; + int delimStart = i - delim.length(); + if (delimStart > 0 && line.substr(delimStart, delim.length()) == delim) + { + isInQuote = false; + isInVerbatimQuote = false; + } + } + else if (isSharpStyle()) + { + if (peekNextChar(line, i) == '"') // check consecutive quotes + i++; + else + { + isInQuote = false; + isInVerbatimQuote = false; + } + } + } + else if (quoteChar == ch) + { + isInQuote = false; + isInStatement = true; + continue; + } + } + if (isInQuote) + continue; + + // handle comments + + if (!(isInComment || isInLineComment) && line.compare(i, 2, "//") == 0) + { + // if there is a 'case' statement after these comments unindent by 1 + if (isCaseHeaderCommentIndent) + --indentCount; + // isElseHeaderIndent is set by ASFormatter if shouldBreakElseIfs is requested + // if there is an 'else' after these comments a tempStacks indent is required + if (isElseHeaderIndent && lineOpensWithLineComment && !tempStacks->empty()) + indentCount += adjustIndentCountForBreakElseIfComments(); + isInLineComment = true; + i++; + continue; + } + else if (!(isInComment || isInLineComment) && line.compare(i, 2, "/*") == 0) + { + // if there is a 'case' statement after these comments unindent by 1 + if (isCaseHeaderCommentIndent && lineOpensWithComment) + --indentCount; + // isElseHeaderIndent is set by ASFormatter if shouldBreakElseIfs is requested + // if there is an 'else' after these comments a tempStacks indent is required + if (isElseHeaderIndent && lineOpensWithComment && !tempStacks->empty()) + indentCount += adjustIndentCountForBreakElseIfComments(); + isInComment = true; + i++; + if (!lineOpensWithComment) // does line start with comment? + blockCommentNoIndent = true; // if no, cannot indent continuation lines + continue; + } + else if ((isInComment || isInLineComment) && line.compare(i, 2, "*/") == 0) + { + size_t firstText = line.find_first_not_of(" \t"); + // if there is a 'case' statement after these comments unindent by 1 + // only if the ending comment is the first entry on the line + if (isCaseHeaderCommentIndent && firstText == i) + --indentCount; + // if this comment close starts the line, must check for else-if indent + // isElseHeaderIndent is set by ASFormatter if shouldBreakElseIfs is requested + // if there is an 'else' after these comments a tempStacks indent is required + if (firstText == i) + { + if (isElseHeaderIndent && !lineOpensWithComment && !tempStacks->empty()) + indentCount += adjustIndentCountForBreakElseIfComments(); + } + isInComment = false; + i++; + blockCommentNoIndent = false; // ok to indent next comment + continue; + } + // treat indented preprocessor lines as a line comment + else if (line[0] == '#' && isIndentedPreprocessor(line, i)) + { + isInLineComment = true; + } + + if (isInLineComment) + { + // bypass rest of the comment up to the comment end + while (i + 1 < line.length()) + i++; + + continue; + } + if (isInComment) + { + // if there is a 'case' statement after these comments unindent by 1 + if (!lineOpensWithComment && isCaseHeaderCommentIndent) + --indentCount; + // isElseHeaderIndent is set by ASFormatter if shouldBreakElseIfs is requested + // if there is an 'else' after these comments a tempStacks indent is required + if (!lineOpensWithComment && isElseHeaderIndent && !tempStacks->empty()) + indentCount += adjustIndentCountForBreakElseIfComments(); + // bypass rest of the comment up to the comment end + while (i + 1 < line.length() + && line.compare(i + 1, 2, "*/") != 0) + i++; + + continue; + } + + // if we have reached this far then we are NOT in a comment or string of special character... + + if (probationHeader != NULL) + { + if ((probationHeader == &AS_STATIC && ch == '{') + || (probationHeader == &AS_SYNCHRONIZED && ch == '(')) + { + // insert the probation header as a new header + isInHeader = true; + headerStack->push_back(probationHeader); + + // handle the specific probation header + isInConditional = (probationHeader == &AS_SYNCHRONIZED); + + isInStatement = false; + // if the probation comes from the previous line, then indent by 1 tab count. + if (previousLineProbation + && ch == '{' + && !(blockIndent && probationHeader == &AS_STATIC)) + { + ++indentCount; + previousLineProbationTab = true; + } + previousLineProbation = false; + } + + // dismiss the probation header + probationHeader = NULL; + } + + prevNonSpaceCh = currentNonSpaceCh; + currentNonSpaceCh = ch; + if (!isLegalNameChar(ch) && ch != ',' && ch != ';') + { + prevNonLegalCh = currentNonLegalCh; + currentNonLegalCh = ch; + } + + if (isInHeader) + { + isInHeader = false; + currentHeader = headerStack->back(); + } + else + currentHeader = NULL; + + if (isCStyle() && isInTemplate + && (ch == '<' || ch == '>') + && !(line.length() > i + 1 && line.compare(i, 2, ">=") == 0)) + { + if (ch == '<') + { + ++templateDepth; + inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size()); + registerInStatementIndent(line, i, spaceIndentCount, tabIncrementIn, 0, true); + } + else if (ch == '>') + { + popLastInStatementIndent(); + if (--templateDepth <= 0) + { + ch = ';'; + isInTemplate = false; + templateDepth = 0; + } + } + } + + // handle parentheses + if (ch == '(' || ch == '[' || ch == ')' || ch == ']') + { + if (ch == '(' || ch == '[') + { + isInOperator = false; + // if have a struct header, this is a declaration not a definition + if (ch == '(' + && !headerStack->empty() + && headerStack->back() == &AS_STRUCT) + { + headerStack->pop_back(); + isInClassHeader = false; + if (line.find(AS_STRUCT, 0) > i) // if not on this line + indentCount -= classInitializerIndents; + if (indentCount < 0) + indentCount = 0; + } + + if (parenDepth == 0) + { + parenStatementStack->push_back(isInStatement); + isInStatement = true; + } + parenDepth++; + if (ch == '[') + ++squareBracketCount; + + inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size()); + + if (currentHeader != NULL) + registerInStatementIndent(line, i, spaceIndentCount, tabIncrementIn, minConditionalIndent/*indentLength*2*/, true); + else + registerInStatementIndent(line, i, spaceIndentCount, tabIncrementIn, 0, true); + } + else if (ch == ')' || ch == ']') + { + if (ch == ']') + --squareBracketCount; + if (squareBracketCount < 0) + squareBracketCount = 0; + foundPreCommandHeader = false; + parenDepth--; + if (parenDepth == 0) + { + if (!parenStatementStack->empty()) // in case of unmatched closing parens + { + isInStatement = parenStatementStack->back(); + parenStatementStack->pop_back(); + } + isInAsm = false; + isInConditional = false; + } + + if (!inStatementIndentStackSizeStack->empty()) + { + popLastInStatementIndent(); + + if (!parenIndentStack->empty()) + { + int poppedIndent = parenIndentStack->back(); + parenIndentStack->pop_back(); + + if (i == 0) + spaceIndentCount = poppedIndent; + } + } + } + continue; + } + + if (ch == '{') + { + // first, check if '{' is a block-opener or a static-array opener + bool isBlockOpener = ((prevNonSpaceCh == '{' && bracketBlockStateStack->back()) + || prevNonSpaceCh == '}' + || prevNonSpaceCh == ')' + || prevNonSpaceCh == ';' + || peekNextChar(line, i) == '{' + || foundPreCommandHeader + || foundPreCommandMacro + || isInClassHeader + || (isInClassInitializer && !isLegalNameChar(prevNonSpaceCh)) + || isNonInStatementArray + || isInObjCMethodDefinition + || isInObjCInterface + || isSharpAccessor + || isSharpDelegate + || isInExternC + || isInAsmBlock + || getNextWord(line, i) == AS_NEW + || (isInDefine + && (prevNonSpaceCh == '(' + || isLegalNameChar(prevNonSpaceCh)))); + + if (isInObjCMethodDefinition) + isImmediatelyPostObjCMethodDefinition = true; + + if (!isBlockOpener && !isInStatement && !isInClassInitializer && !isInEnum) + { + if (headerStack->empty()) + isBlockOpener = true; + else if (headerStack->back() == &AS_NAMESPACE + || headerStack->back() == &AS_CLASS + || headerStack->back() == &AS_INTERFACE + || headerStack->back() == &AS_STRUCT + || headerStack->back() == &AS_UNION) + isBlockOpener = true; + } + + if (!isBlockOpener && currentHeader != NULL) + { + for (size_t n = 0; n < nonParenHeaders->size(); n++) + if (currentHeader == (*nonParenHeaders)[n]) + { + isBlockOpener = true; + break; + } + } + + bracketBlockStateStack->push_back(isBlockOpener); + + if (!isBlockOpener) + { + inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size()); + registerInStatementIndent(line, i, spaceIndentCount, tabIncrementIn, 0, true); + parenDepth++; + if (i == 0) + shouldIndentBrackettedLine = false; + isInEnumTypeID = false; + + continue; + } + + // this bracket is a block opener... + + ++lineOpeningBlocksNum; + + if (isInClassInitializer || isInEnumTypeID) + { + // decrease tab count if bracket is broken + if (lineBeginsWithOpenBracket) + { + indentCount -= classInitializerIndents; + // decrease one more if an empty class + if (!headerStack->empty() + && (*headerStack).back() == &AS_CLASS) + { + int nextChar = getNextProgramCharDistance(line, i); + if ((int) line.length() > nextChar && line[nextChar] == '}') + --indentCount; + } + } + } + + if (isInObjCInterface) + { + isInObjCInterface = false; + if (lineBeginsWithOpenBracket) + --indentCount; + } + + if (bracketIndent && !namespaceIndent && !headerStack->empty() + && (*headerStack).back() == &AS_NAMESPACE) + { + shouldIndentBrackettedLine = false; + --indentCount; + } + + // an indentable struct is treated like a class in the header stack + if (!headerStack->empty() + && (*headerStack).back() == &AS_STRUCT + && isInIndentableStruct) + (*headerStack).back() = &AS_CLASS; + + blockParenDepthStack->push_back(parenDepth); + blockStatementStack->push_back(isInStatement); + + if (!inStatementIndentStack->empty()) + { + // completely purge the inStatementIndentStack + while (!inStatementIndentStack->empty()) + popLastInStatementIndent(); + if (isInClassInitializer || isInClassHeaderTab) + { + if (lineBeginsWithOpenBracket || lineBeginsWithComma) + spaceIndentCount = 0; + } + else + spaceIndentCount = 0; + } + + blockTabCount += (isInStatement ? 1 : 0); + if (g_preprocessorCppExternCBracket == 3) + ++g_preprocessorCppExternCBracket; + parenDepth = 0; + isInClassHeader = false; + isInClassHeaderTab = false; + isInClassInitializer = false; + isInEnumTypeID = false; + isInStatement = false; + isInQuestion = false; + isInLet = false; + foundPreCommandHeader = false; + foundPreCommandMacro = false; + isInExternC = false; + + tempStacks->push_back(new vector); + headerStack->push_back(&AS_OPEN_BRACKET); + lastLineHeader = &AS_OPEN_BRACKET; + + continue; + } // end '{' + + //check if a header has been reached + bool isPotentialHeader = isCharPotentialHeader(line, i); + + if (isPotentialHeader && !squareBracketCount) + { + const string* newHeader = findHeader(line, i, headers); + + // Qt headers may be variables in C++ + if (isCStyle() + && (newHeader == &AS_FOREVER || newHeader == &AS_FOREACH)) + { + if (line.find_first_of("=;", i) != string::npos) + newHeader = NULL; + } + else if (newHeader == &AS_USING + && ASBeautifier::peekNextChar(line, i + (*newHeader).length() - 1) != '(') + newHeader = NULL; + + if (newHeader != NULL) + { + // if we reached here, then this is a header... + bool isIndentableHeader = true; + + isInHeader = true; + + vector* lastTempStack; + if (tempStacks->empty()) + lastTempStack = NULL; + else + lastTempStack = tempStacks->back(); + + // if a new block is opened, push a new stack into tempStacks to hold the + // future list of headers in the new block. + + // take care of the special case: 'else if (...)' + if (newHeader == &AS_IF && lastLineHeader == &AS_ELSE) + { + headerStack->pop_back(); + } + + // take care of 'else' + else if (newHeader == &AS_ELSE) + { + if (lastTempStack != NULL) + { + int indexOfIf = indexOf(*lastTempStack, &AS_IF); + if (indexOfIf != -1) + { + // recreate the header list in headerStack up to the previous 'if' + // from the temporary snapshot stored in lastTempStack. + int restackSize = lastTempStack->size() - indexOfIf - 1; + for (int r = 0; r < restackSize; r++) + { + headerStack->push_back(lastTempStack->back()); + lastTempStack->pop_back(); + } + if (!closingBracketReached) + indentCount += restackSize; + } + /* + * If the above if is not true, i.e. no 'if' before the 'else', + * then nothing beautiful will come out of this... + * I should think about inserting an Exception here to notify the caller of this... + */ + } + } + + // check if 'while' closes a previous 'do' + else if (newHeader == &AS_WHILE) + { + if (lastTempStack != NULL) + { + int indexOfDo = indexOf(*lastTempStack, &AS_DO); + if (indexOfDo != -1) + { + // recreate the header list in headerStack up to the previous 'do' + // from the temporary snapshot stored in lastTempStack. + int restackSize = lastTempStack->size() - indexOfDo - 1; + for (int r = 0; r < restackSize; r++) + { + headerStack->push_back(lastTempStack->back()); + lastTempStack->pop_back(); + } + if (!closingBracketReached) + indentCount += restackSize; + } + } + } + // check if 'catch' closes a previous 'try' or 'catch' + else if (newHeader == &AS_CATCH || newHeader == &AS_FINALLY) + { + if (lastTempStack != NULL) + { + int indexOfTry = indexOf(*lastTempStack, &AS_TRY); + if (indexOfTry == -1) + indexOfTry = indexOf(*lastTempStack, &AS_CATCH); + if (indexOfTry != -1) + { + // recreate the header list in headerStack up to the previous 'try' + // from the temporary snapshot stored in lastTempStack. + int restackSize = lastTempStack->size() - indexOfTry - 1; + for (int r = 0; r < restackSize; r++) + { + headerStack->push_back(lastTempStack->back()); + lastTempStack->pop_back(); + } + + if (!closingBracketReached) + indentCount += restackSize; + } + } + } + else if (newHeader == &AS_CASE) + { + isInCase = true; + if (!haveCaseIndent) + { + haveCaseIndent = true; + if (!lineBeginsWithOpenBracket) + --indentCount; + } + } + else if (newHeader == &AS_DEFAULT) + { + isInCase = true; + --indentCount; + } + else if (newHeader == &AS_STATIC + || newHeader == &AS_SYNCHRONIZED) + { + if (!headerStack->empty() + && (headerStack->back() == &AS_STATIC + || headerStack->back() == &AS_SYNCHRONIZED)) + { + isIndentableHeader = false; + } + else + { + isIndentableHeader = false; + probationHeader = newHeader; + } + } + else if (newHeader == &AS_TEMPLATE) + { + isInTemplate = true; + isIndentableHeader = false; + } + + if (isIndentableHeader) + { + headerStack->push_back(newHeader); + isInStatement = false; + if (indexOf(*nonParenHeaders, newHeader) == -1) + { + isInConditional = true; + } + lastLineHeader = newHeader; + } + else + isInHeader = false; + + i += newHeader->length() - 1; + + continue; + } // newHeader != NULL + + if (findHeader(line, i, preCommandHeaders)) + foundPreCommandHeader = true; + + // Objective-C NSException macros are preCommandHeaders + if (isCStyle() && findKeyword(line, i, AS_NS_DURING)) + foundPreCommandMacro = true; + if (isCStyle() && findKeyword(line, i, AS_NS_HANDLER)) + foundPreCommandMacro = true; + + if (parenDepth == 0 && findKeyword(line, i, AS_ENUM)) + isInEnum = true; + + if (isSharpStyle() && findKeyword(line, i, AS_LET)) + isInLet = true; + + } // isPotentialHeader + + if (ch == '?') + isInQuestion = true; + + // special handling of colons + if (ch == ':') + { + if (line.length() > i + 1 && line[i + 1] == ':') // look for :: + { + ++i; + continue; + } + else if (isInQuestion) + { + // do nothing special + } + else if (parenDepth > 0) + { + // found a 'for' loop or an objective-C statement + // so do nothing special + } + else if (isInEnum) + { + // found an enum with a base-type + isInEnumTypeID = true; + if (i == 0) + indentCount += classInitializerIndents; + } + else if (isCStyle() + && !isInCase + && (prevNonSpaceCh == ')' || foundPreCommandHeader)) + { + // found a 'class' c'tor initializer + isInClassInitializer = true; + registerInStatementIndentColon(line, i, tabIncrementIn); + if (i == 0) + indentCount += classInitializerIndents; + } + else if (isInClassHeader || isInObjCInterface) + { + // is in a 'class A : public B' definition + isInClassHeaderTab = true; + registerInStatementIndentColon(line, i, tabIncrementIn); + } + else if (isInAsm || isInAsmOneLine || isInAsmBlock) + { + // do nothing special + } + else if (isDigit(peekNextChar(line, i))) + { + // found a bit field - do nothing special + } + else if (isCStyle() && isInClass && prevNonSpaceCh != ')') + { + // found a 'private:' or 'public:' inside a class definition + --indentCount; + if (modifierIndent) + spaceIndentCount += (indentLength / 2); + } + else if (isCStyle() && !isInClass + && headerStack->size() >= 2 + && (*headerStack)[headerStack->size() - 2] == &AS_CLASS + && (*headerStack)[headerStack->size() - 1] == &AS_OPEN_BRACKET) + { + // found a 'private:' or 'public:' inside a class definition + // and on the same line as the class opening bracket + // do nothing + } + else if (isJavaStyle() && lastLineHeader == &AS_FOR) + { + // found a java for-each statement + // so do nothing special + } + else + { + currentNonSpaceCh = ';'; // so that brackets after the ':' will appear as block-openers + char peekedChar = peekNextChar(line, i); + if (isInCase) + { + isInCase = false; + ch = ';'; // from here on, treat char as ';' + } + else if (isCStyle() || (isSharpStyle() && peekedChar == ';')) + { + // is in a label (e.g. 'label1:') + if (labelIndent) + --indentCount; // unindent label by one indent + else if (!lineBeginsWithOpenBracket) + indentCount = 0; // completely flush indent to left + } + } + } + + if ((ch == ';' || (parenDepth > 0 && ch == ',')) && !inStatementIndentStackSizeStack->empty()) + while ((int) inStatementIndentStackSizeStack->back() + (parenDepth > 0 ? 1 : 0) + < (int) inStatementIndentStack->size()) + inStatementIndentStack->pop_back(); + + else if (ch == ',' && isInEnum && isNonInStatementArray && !inStatementIndentStack->empty()) + inStatementIndentStack->pop_back(); + + // handle commas + // previous "isInStatement" will be from an assignment operator or class initializer + if (ch == ',' && parenDepth == 0 && !isInStatement && !isNonInStatementArray) + { + // is comma at end of line + size_t nextChar = line.find_first_not_of(" \t", i + 1); + if (nextChar != string::npos) + { + if (line.compare(nextChar, 2, "//") == 0 + || line.compare(nextChar, 2, "/*") == 0) + nextChar = string::npos; + } + // register indent + if (nextChar == string::npos) + { + // register indent at previous word + if (isJavaStyle() && isInClassHeader) + { + // do nothing for now + } + // register indent at second word on the line + else if (!isInTemplate && !isInClassHeaderTab && !isInClassInitializer) + { + int prevWord = getInStatementIndentComma(line, i); + int inStatementIndent = prevWord + spaceIndentCount + tabIncrementIn; + inStatementIndentStack->push_back(inStatementIndent); + isInStatement = true; + } + } + } + // handle comma first initializers + if (ch == ',' && parenDepth == 0 && lineBeginsWithComma + && (isInClassInitializer || isInClassHeaderTab)) + spaceIndentCount = 0; + + // handle ends of statements + if ((ch == ';' && parenDepth == 0) || ch == '}') + { + if (ch == '}') + { + // first check if this '}' closes a previous block, or a static array... + if (bracketBlockStateStack->size() > 1) + { + bool bracketBlockState = bracketBlockStateStack->back(); + bracketBlockStateStack->pop_back(); + if (!bracketBlockState) + { + if (!inStatementIndentStackSizeStack->empty()) + { + // this bracket is a static array + popLastInStatementIndent(); + parenDepth--; + if (i == 0) + shouldIndentBrackettedLine = false; + + if (!parenIndentStack->empty()) + { + int poppedIndent = parenIndentStack->back(); + parenIndentStack->pop_back(); + if (i == 0) + spaceIndentCount = poppedIndent; + } + } + continue; + } + } + + // this bracket is block closer... + + ++lineClosingBlocksNum; + + if (!inStatementIndentStackSizeStack->empty()) + popLastInStatementIndent(); + + if (!blockParenDepthStack->empty()) + { + parenDepth = blockParenDepthStack->back(); + blockParenDepthStack->pop_back(); + isInStatement = blockStatementStack->back(); + blockStatementStack->pop_back(); + + if (isInStatement) + blockTabCount--; + } + + closingBracketReached = true; + if (i == 0) + spaceIndentCount = 0; + isInAsmBlock = false; + isInAsm = isInAsmOneLine = isInQuote = false; // close these just in case + + int headerPlace = indexOf(*headerStack, &AS_OPEN_BRACKET); + if (headerPlace != -1) + { + const string* popped = headerStack->back(); + while (popped != &AS_OPEN_BRACKET) + { + headerStack->pop_back(); + popped = headerStack->back(); + } + headerStack->pop_back(); + + if (headerStack->empty()) + g_preprocessorCppExternCBracket = 0; + + // do not indent namespace bracket unless namespaces are indented + if (!namespaceIndent && !headerStack->empty() + && (*headerStack).back() == &AS_NAMESPACE + && i == 0) // must be the first bracket on the line + shouldIndentBrackettedLine = false; + + if (!tempStacks->empty()) + { + vector* temp = tempStacks->back(); + tempStacks->pop_back(); + delete temp; + } + } + + ch = ' '; // needed due to cases such as '}else{', so that headers ('else' in this case) will be identified... + } // ch == '}' + + /* + * Create a temporary snapshot of the current block's header-list in the + * uppermost inner stack in tempStacks, and clear the headerStack up to + * the beginning of the block. + * Thus, the next future statement will think it comes one indent past + * the block's '{' unless it specifically checks for a companion-header + * (such as a previous 'if' for an 'else' header) within the tempStacks, + * and recreates the temporary snapshot by manipulating the tempStacks. + */ + if (!tempStacks->back()->empty()) + while (!tempStacks->back()->empty()) + tempStacks->back()->pop_back(); + while (!headerStack->empty() && headerStack->back() != &AS_OPEN_BRACKET) + { + tempStacks->back()->push_back(headerStack->back()); + headerStack->pop_back(); + } + + if (parenDepth == 0 && ch == ';') + isInStatement = false; + if (isInObjCMethodDefinition) + isImmediatelyPostObjCMethodDefinition = true; + + previousLastLineHeader = NULL; + isInClassHeader = false; // for 'friend' class + isInEnum = false; + isInQuestion = false; + isInObjCInterface = false; + foundPreCommandHeader = false; + foundPreCommandMacro = false; + squareBracketCount = 0; + + continue; + } + + if (isPotentialHeader) + { + // check for preBlockStatements in C/C++ ONLY if not within parentheses + // (otherwise 'struct XXX' statements would be wrongly interpreted...) + if (!isInTemplate && !(isCStyle() && parenDepth > 0)) + { + const string* newHeader = findHeader(line, i, preBlockStatements); + if (newHeader != NULL + && !(isCStyle() && newHeader == &AS_CLASS && isInEnum)) // is not 'enum class' + { + if (!isSharpStyle()) + headerStack->push_back(newHeader); + // do not need 'where' in the headerStack + // do not need second 'class' statement in a row + else if (!(newHeader == &AS_WHERE + || (newHeader == &AS_CLASS + && !headerStack->empty() + && headerStack->back() == &AS_CLASS))) + headerStack->push_back(newHeader); + + if (!headerStack->empty()) + { + if ((*headerStack).back() == &AS_CLASS + || (*headerStack).back() == &AS_STRUCT + || (*headerStack).back() == &AS_INTERFACE) + { + isInClassHeader = true; + } + else if ((*headerStack).back() == &AS_NAMESPACE) + { + // remove inStatementIndent from namespace + if (!inStatementIndentStack->empty()) + inStatementIndentStack->pop_back(); + isInStatement = false; + } + } + + i += newHeader->length() - 1; + continue; + } + } + const string* foundIndentableHeader = findHeader(line, i, indentableHeaders); + + if (foundIndentableHeader != NULL) + { + // must bypass the header before registering the in statement + i += foundIndentableHeader->length() - 1; + if (!isInOperator && !isInTemplate && !isNonInStatementArray) + { + registerInStatementIndent(line, i, spaceIndentCount, tabIncrementIn, 0, false); + isInStatement = true; + } + continue; + } + + if (isCStyle() && findKeyword(line, i, AS_OPERATOR)) + isInOperator = true; + + if (g_preprocessorCppExternCBracket == 1 && findKeyword(line, i, AS_EXTERN)) + ++g_preprocessorCppExternCBracket; + + if (g_preprocessorCppExternCBracket == 3) // extern "C" is not followed by a '{' + g_preprocessorCppExternCBracket = 0; + + // "new" operator is a pointer, not a calculation + if (findKeyword(line, i, AS_NEW)) + { + if (isInStatement && !inStatementIndentStack->empty() && prevNonSpaceCh == '=' ) + inStatementIndentStack->back() = 0; + } + + if (isCStyle()) + { + if (findKeyword(line, i, AS_ASM) + || findKeyword(line, i, AS__ASM__)) + { + isInAsm = true; + } + else if (findKeyword(line, i, AS_MS_ASM) // microsoft specific + || findKeyword(line, i, AS_MS__ASM)) + { + int index = 4; + if (peekNextChar(line, i) == '_') // check for __asm + index = 5; + + char peekedChar = ASBase::peekNextChar(line, i + index); + if (peekedChar == '{' || peekedChar == ' ') + isInAsmBlock = true; + else + isInAsmOneLine = true; + } + } + + // bypass the entire name for all others + string name = getCurrentWord(line, i); + i += name.length() - 1; + continue; + } + + // Handle Objective-C statements + + if (ch == '@' + && isCharPotentialHeader(line, i + 1)) + { + string curWord = getCurrentWord(line, i + 1); + if (curWord == AS_INTERFACE && headerStack->empty()) + { + isInObjCInterface = true; + string name = '@' + curWord; + i += name.length() - 1; + continue; + } + else if (curWord == AS_PUBLIC + || curWord == AS_PRIVATE + || curWord == AS_PROTECTED) + { + --indentCount; + if (modifierIndent) + spaceIndentCount += (indentLength / 2); + string name = '@' + curWord; + i += name.length() - 1; + continue; + } + else if (curWord == AS_END) + { + popLastInStatementIndent(); + spaceIndentCount = 0; + if (isInObjCInterface) + --indentCount; + isInObjCInterface = false; + isInObjCMethodDefinition = false; + string name = '@' + curWord; + i += name.length() - 1; + continue; + } + } + else if ((ch == '-' || ch == '+') + && peekNextChar(line, i) == '(' + && headerStack->empty() + && line.find_first_not_of(" \t") == i) + { + if (isInObjCInterface) + --indentCount; + isInObjCInterface = false; + isInObjCMethodDefinition = true; + continue; + } + + // Handle operators + + bool isPotentialOperator = isCharPotentialOperator(ch); + + if (isPotentialOperator) + { + // Check if an operator has been reached. + const string* foundAssignmentOp = findOperator(line, i, assignmentOperators); + const string* foundNonAssignmentOp = findOperator(line, i, nonAssignmentOperators); + + if (foundNonAssignmentOp == &AS_LAMBDA) + foundPreCommandHeader = true; + + if (isInTemplate && foundNonAssignmentOp == &AS_GR_GR) + foundNonAssignmentOp = NULL; + + // Since findHeader's boundary checking was not used above, it is possible + // that both an assignment op and a non-assignment op where found, + // e.g. '>>' and '>>='. If this is the case, treat the LONGER one as the + // found operator. + if (foundAssignmentOp != NULL && foundNonAssignmentOp != NULL) + { + if (foundAssignmentOp->length() < foundNonAssignmentOp->length()) + foundAssignmentOp = NULL; + else + foundNonAssignmentOp = NULL; + } + + if (foundNonAssignmentOp != NULL) + { + if (foundNonAssignmentOp->length() > 1) + i += foundNonAssignmentOp->length() - 1; + + // For C++ input/output, operator<< and >> should be + // aligned, if we are not in a statement already and + // also not in the "operator<<(...)" header line + if (!isInOperator + && inStatementIndentStack->empty() + && isCStyle() + && (foundNonAssignmentOp == &AS_GR_GR + || foundNonAssignmentOp == &AS_LS_LS)) + { + // this will be true if the line begins with the operator + if (i < 2 && spaceIndentCount == 0) + spaceIndentCount += 2 * indentLength; + // align to the beginning column of the operator + registerInStatementIndent(line, i - foundNonAssignmentOp->length(), spaceIndentCount, tabIncrementIn, 0, false); + } + } + + else if (foundAssignmentOp != NULL) + { + foundPreCommandHeader = false; // clears this for array assignments + foundPreCommandMacro = false; + + if (foundAssignmentOp->length() > 1) + i += foundAssignmentOp->length() - 1; + + if (!isInOperator && !isInTemplate && (!isNonInStatementArray || isInEnum)) + { + // if multiple assignments, align on the previous word + if (foundAssignmentOp == &AS_ASSIGN + && prevNonSpaceCh != ']' // an array + && statementEndsWithComma(line, i)) + { + if (!haveAssignmentThisLine) // only one assignment indent per line + { + // register indent at previous word + haveAssignmentThisLine = true; + int prevWordIndex = getInStatementIndentAssign(line, i); + int inStatementIndent = prevWordIndex + spaceIndentCount + tabIncrementIn; + inStatementIndentStack->push_back(inStatementIndent); + isInStatement = true; + } + } + // don't indent an assignment if 'let' + else if (isInLet) + { + isInLet = false; + } + else + { + if (i == 0 && spaceIndentCount == 0) + spaceIndentCount += indentLength; + registerInStatementIndent(line, i, spaceIndentCount, tabIncrementIn, 0, false); + isInStatement = true; + } + } + } + } + } // end of for loop * end of for loop * end of for loop * end of for loop * end of for loop * +} + +} // end namespace astyle diff --git a/External/Tools/AStyle/src/ASEnhancer.cpp b/External/Tools/AStyle/src/ASEnhancer.cpp new file mode 100644 index 0000000000..dae0d1b3cf --- /dev/null +++ b/External/Tools/AStyle/src/ASEnhancer.cpp @@ -0,0 +1,796 @@ +// ASEnhancer.cpp +// Copyright (c) 2016 by Jim Pattee . +// Licensed under the MIT license. +// License.txt describes the conditions under which this software may be distributed. + +//----------------------------------------------------------------------------- +// headers +//----------------------------------------------------------------------------- + +#include "astyle.h" + +//----------------------------------------------------------------------------- +// astyle namespace +//----------------------------------------------------------------------------- + +namespace astyle { +// +//----------------------------------------------------------------------------- +// ASEnhancer class +//----------------------------------------------------------------------------- + +/** + * ASEnhancer constructor + */ +ASEnhancer::ASEnhancer() +{ +} + +/** + * Destructor of ASEnhancer + */ +ASEnhancer::~ASEnhancer() +{ +} + +/** + * initialize the ASEnhancer. + * + * init() is called each time an ASFormatter object is initialized. + */ +void ASEnhancer::init(int _fileType, + int _indentLength, + int _tabLength, + bool _useTabs, + bool _forceTab, + bool _namespaceIndent, + bool _caseIndent, + bool _preprocBlockIndent, + bool _preprocDefineIndent, + bool _emptyLineFill, + vector* >* _indentableMacros) +{ + // formatting variables from ASFormatter and ASBeautifier + ASBase::init(_fileType); + indentLength = _indentLength; + tabLength = _tabLength; + useTabs = _useTabs; + forceTab = _forceTab; + namespaceIndent = _namespaceIndent; + caseIndent = _caseIndent; + preprocBlockIndent = _preprocBlockIndent; + preprocDefineIndent = _preprocDefineIndent; + emptyLineFill = _emptyLineFill; + indentableMacros = _indentableMacros; + quoteChar = '\''; + + // unindent variables + lineNumber = 0; + bracketCount = 0; + isInComment = false; + isInQuote = false; + switchDepth = 0; + eventPreprocDepth = 0; + lookingForCaseBracket = false; + unindentNextLine = false; + shouldUnindentLine = false; + shouldUnindentComment = false; + + // switch struct and vector + sw.switchBracketCount = 0; + sw.unindentDepth = 0; + sw.unindentCase = false; + switchStack.clear(); + + // other variables + nextLineIsEventIndent = false; + isInEventTable = false; + nextLineIsDeclareIndent = false; + isInDeclareSection = false; +} + +/** + * additional formatting for line of source code. + * every line of source code in a source code file should be sent + * one after the other to this function. + * indents event tables + * unindents the case blocks + * + * @param line the original formatted line will be updated if necessary. + */ +void ASEnhancer::enhance(string& line, bool isInNamespace, bool isInPreprocessor, bool isInSQL) +{ + shouldUnindentLine = true; + shouldUnindentComment = false; + lineNumber++; + + // check for beginning of event table + if (nextLineIsEventIndent) + { + isInEventTable = true; + nextLineIsEventIndent = false; + } + + // check for beginning of SQL declare section + if (nextLineIsDeclareIndent) + { + isInDeclareSection = true; + nextLineIsDeclareIndent = false; + } + + if (line.length() == 0 + && !isInEventTable + && !isInDeclareSection + && !emptyLineFill) + return; + + // test for unindent on attached brackets + if (unindentNextLine) + { + sw.unindentDepth++; + sw.unindentCase = true; + unindentNextLine = false; + } + + // parse characters in the current line + parseCurrentLine(line, isInPreprocessor, isInSQL); + + // check for SQL indentable lines + if (isInDeclareSection) + { + size_t firstText = line.find_first_not_of(" \t"); + if (firstText == string::npos || line[firstText] != '#') + indentLine(line, 1); + } + + // check for event table indentable lines + if (isInEventTable + && (eventPreprocDepth == 0 + || (namespaceIndent && isInNamespace))) + { + size_t firstText = line.find_first_not_of(" \t"); + if (firstText == string::npos || line[firstText] != '#') + indentLine(line, 1); + } + + if (shouldUnindentComment && sw.unindentDepth > 0) + unindentLine(line, sw.unindentDepth - 1); + else if (shouldUnindentLine && sw.unindentDepth > 0) + unindentLine(line, sw.unindentDepth); +} + +/** + * convert a force-tab indent to spaces + * + * @param line a reference to the line that will be converted. + */ +void ASEnhancer::convertForceTabIndentToSpaces(string& line) const +{ + // replace tab indents with spaces + for (size_t i = 0; i < line.length(); i++) + { + if (!isWhiteSpace(line[i])) + break; + if (line[i] == '\t') + { + line.erase(i, 1); + line.insert(i, tabLength, ' '); + i += tabLength - 1; + } + } +} + +/** + * convert a space indent to force-tab + * + * @param line a reference to the line that will be converted. + */ +void ASEnhancer::convertSpaceIndentToForceTab(string& line) const +{ + assert(tabLength > 0); + + // replace leading spaces with tab indents + size_t newSpaceIndentLength = line.find_first_not_of(" \t"); + size_t tabCount = newSpaceIndentLength / tabLength; // truncate extra spaces + line.replace(0U, tabCount * tabLength, tabCount, '\t'); +} + +/** + * find the colon following a 'case' statement + * + * @param line a reference to the line. + * @param caseIndex the line index of the case statement. + * @return the line index of the colon. + */ +size_t ASEnhancer::findCaseColon(string& line, size_t caseIndex) const +{ + size_t i = caseIndex; + bool isInQuote_ = false; + char quoteChar_ = ' '; + for (; i < line.length(); i++) + { + if (isInQuote_) + { + if (line[i] == '\\') + { + i++; + continue; + } + else if (line[i] == quoteChar_) // check ending quote + { + isInQuote_ = false; + quoteChar_ = ' '; + continue; + } + else + { + continue; // must close quote before continuing + } + } + if (line[i] == '"' // check opening quote + || (line[i] == '\'' && !isDigitSeparator(line, i))) + { + isInQuote_ = true; + quoteChar_ = line[i]; + continue; + } + if (line[i] == ':') + { + if ((i + 1 < line.length()) && (line[i + 1] == ':')) + i++; // bypass scope resolution operator + else + break; // found it + } + } + return i; +} + +/** +* indent a line by a given number of tabsets + * by inserting leading whitespace to the line argument. + * + * @param line a reference to the line to indent. + * @param indent the number of tabsets to insert. + * @return the number of characters inserted. + */ +int ASEnhancer::indentLine(string& line, int indent) const +{ + if (line.length() == 0 + && !emptyLineFill) + return 0; + + size_t charsToInsert = 0; + + if (forceTab && indentLength != tabLength) + { + // replace tab indents with spaces + convertForceTabIndentToSpaces(line); + // insert the space indents + charsToInsert = indent * indentLength; + line.insert(line.begin(), charsToInsert, ' '); + // replace leading spaces with tab indents + convertSpaceIndentToForceTab(line); + } + else if (useTabs) + { + charsToInsert = indent; + line.insert(line.begin(), charsToInsert, '\t'); + } + else // spaces + { + charsToInsert = indent * indentLength; + line.insert(line.begin(), charsToInsert, ' '); + } + + return charsToInsert; +} + +/** + * check for SQL "BEGIN DECLARE SECTION". + * must compare case insensitive and allow any spacing between words. + * + * @param line a reference to the line to indent. + * @param index the current line index. + * @return true if a hit. + */ +bool ASEnhancer::isBeginDeclareSectionSQL(string& line, size_t index) const +{ + string word; + size_t hits = 0; + size_t i; + for (i = index; i < line.length(); i++) + { + i = line.find_first_not_of(" \t", i); + if (i == string::npos) + return false; + if (line[i] == ';') + break; + if (!isCharPotentialHeader(line, i)) + continue; + word = getCurrentWord(line, i); + for (size_t j = 0; j < word.length(); j++) + word[j] = (char) toupper(word[j]); + if (word == "EXEC" || word == "SQL") + { + i += word.length() - 1; + continue; + } + if (word == "DECLARE" || word == "SECTION") + { + hits++; + i += word.length() - 1; + continue; + } + if (word == "BEGIN") + { + hits++; + i += word.length() - 1; + continue; + } + return false; + } + if (hits == 3) + return true; + return false; +} + +/** + * check for SQL "END DECLARE SECTION". + * must compare case insensitive and allow any spacing between words. + * + * @param line a reference to the line to indent. + * @param index the current line index. + * @return true if a hit. + */ +bool ASEnhancer::isEndDeclareSectionSQL(string& line, size_t index) const +{ + string word; + size_t hits = 0; + size_t i; + for (i = index; i < line.length(); i++) + { + i = line.find_first_not_of(" \t", i); + if (i == string::npos) + return false; + if (line[i] == ';') + break; + if (!isCharPotentialHeader(line, i)) + continue; + word = getCurrentWord(line, i); + for (size_t j = 0; j < word.length(); j++) + word[j] = (char) toupper(word[j]); + if (word == "EXEC" || word == "SQL") + { + i += word.length() - 1; + continue; + } + if (word == "DECLARE" || word == "SECTION") + { + hits++; + i += word.length() - 1; + continue; + } + if (word == "END") + { + hits++; + i += word.length() - 1; + continue; + } + return false; + } + if (hits == 3) + return true; + return false; +} + +/** + * check if a one-line bracket has been reached, + * i.e. if the currently reached '{' character is closed + * with a complimentary '}' elsewhere on the current line, + *. + * @return false = one-line bracket has not been reached. + * true = one-line bracket has been reached. + */ +bool ASEnhancer::isOneLineBlockReached(string& line, int startChar) const +{ + assert(line[startChar] == '{'); + + bool isInComment_ = false; + bool isInQuote_ = false; + int _bracketCount = 1; + int lineLength = line.length(); + char quoteChar_ = ' '; + char ch = ' '; + + for (int i = startChar + 1; i < lineLength; ++i) + { + ch = line[i]; + + if (isInComment_) + { + if (line.compare(i, 2, "*/") == 0) + { + isInComment_ = false; + ++i; + } + continue; + } + + if (ch == '\\') + { + ++i; + continue; + } + + if (isInQuote_) + { + if (ch == quoteChar_) + isInQuote_ = false; + continue; + } + + if (ch == '"' + || (ch == '\'' && !isDigitSeparator(line, i))) + { + isInQuote_ = true; + quoteChar_ = ch; + continue; + } + + if (line.compare(i, 2, "//") == 0) + break; + + if (line.compare(i, 2, "/*") == 0) + { + isInComment_ = true; + ++i; + continue; + } + + if (ch == '{') + ++_bracketCount; + else if (ch == '}') + --_bracketCount; + + if (_bracketCount == 0) + return true; + } + + return false; +} + +/** + * parse characters in the current line to determine if an indent + * or unindent is needed. + */ +void ASEnhancer::parseCurrentLine(string& line, bool isInPreprocessor, bool isInSQL) +{ + bool isSpecialChar = false; // is a backslash escape character + + for (size_t i = 0; i < line.length(); i++) + { + char ch = line[i]; + + // bypass whitespace + if (isWhiteSpace(ch)) + continue; + + // handle special characters (i.e. backslash+character such as \n, \t, ...) + if (isSpecialChar) + { + isSpecialChar = false; + continue; + } + if (!(isInComment) && line.compare(i, 2, "\\\\") == 0) + { + i++; + continue; + } + if (!(isInComment) && ch == '\\') + { + isSpecialChar = true; + continue; + } + + // handle quotes (such as 'x' and "Hello Dolly") + if (!isInComment + && (ch == '"' + || (ch == '\'' && !isDigitSeparator(line, i)))) + { + if (!isInQuote) + { + quoteChar = ch; + isInQuote = true; + } + else if (quoteChar == ch) + { + isInQuote = false; + continue; + } + } + + if (isInQuote) + continue; + + // handle comments + + if (!(isInComment) && line.compare(i, 2, "//") == 0) + { + // check for windows line markers + if (line.compare(i + 2, 1, "\xf0") > 0) + lineNumber--; + // unindent if not in case brackets + if (line.find_first_not_of(" \t") == i + && sw.switchBracketCount == 1 + && sw.unindentCase) + shouldUnindentComment = true; + break; // finished with the line + } + else if (!(isInComment) && line.compare(i, 2, "/*") == 0) + { + // unindent if not in case brackets + if (sw.switchBracketCount == 1 && sw.unindentCase) + shouldUnindentComment = true; + isInComment = true; + size_t commentEnd = line.find("*/", i); + if (commentEnd == string::npos) + i = line.length() - 1; + else + i = commentEnd - 1; + continue; + } + else if ((isInComment) && line.compare(i, 2, "*/") == 0) + { + // unindent if not in case brackets + if (sw.switchBracketCount == 1 && sw.unindentCase) + shouldUnindentComment = true; + isInComment = false; + i++; + continue; + } + + if (isInComment) + { + // unindent if not in case brackets + if (sw.switchBracketCount == 1 && sw.unindentCase) + shouldUnindentComment = true; + size_t commentEnd = line.find("*/", i); + if (commentEnd == string::npos) + i = line.length() - 1; + else + i = commentEnd - 1; + continue; + } + + // if we have reached this far then we are NOT in a comment or string of special characters + + if (line[i] == '{') + bracketCount++; + + if (line[i] == '}') + bracketCount--; + + // check for preprocessor within an event table + if (isInEventTable && line[i] == '#' && preprocBlockIndent) + { + string preproc; + preproc = line.substr(i + 1); + if (preproc.substr(0, 2) == "if") // #if, #ifdef, #ifndef) + eventPreprocDepth += 1; + if (preproc.substr(0, 3) == "end" && eventPreprocDepth > 0) // #endif, #end + eventPreprocDepth -= 1; + } + + bool isPotentialKeyword = isCharPotentialHeader(line, i); + + // ---------------- wxWidgets and MFC macros ---------------------------------- + + if (isPotentialKeyword) + { + for (size_t j = 0; j < indentableMacros->size(); j++) + { + // 'first' is the beginning macro + if (findKeyword(line, i, indentableMacros->at(j)->first)) + { + nextLineIsEventIndent = true; + break; + } + } + for (size_t j = 0; j < indentableMacros->size(); j++) + { + // 'second' is the ending macro + if (findKeyword(line, i, indentableMacros->at(j)->second)) + { + isInEventTable = false; + eventPreprocDepth = 0; + break; + } + } + } + + // ---------------- process SQL ----------------------------------------------- + + if (isInSQL) + { + if (isBeginDeclareSectionSQL(line, i)) + nextLineIsDeclareIndent = true; + if (isEndDeclareSectionSQL(line, i)) + isInDeclareSection = false; + break; + } + + // ---------------- process switch statements --------------------------------- + + if (isPotentialKeyword && findKeyword(line, i, "switch")) + { + switchDepth++; + switchStack.push_back(sw); // save current variables + sw.switchBracketCount = 0; + sw.unindentCase = false; // don't clear case until end of switch + i += 5; // bypass switch statement + continue; + } + + // just want unindented case statements from this point + + if (caseIndent + || switchDepth == 0 + || (isInPreprocessor && !preprocDefineIndent)) + { + // bypass the entire word + if (isPotentialKeyword) + { + string name = getCurrentWord(line, i); + i += name.length() - 1; + } + continue; + } + + i = processSwitchBlock(line, i); + + } // end of for loop * end of for loop * end of for loop * end of for loop +} + +/** + * process the character at the current index in a switch block. + * + * @param line a reference to the line to indent. + * @param index the current line index. + * @return the new line index. + */ +size_t ASEnhancer::processSwitchBlock(string& line, size_t index) +{ + size_t i = index; + bool isPotentialKeyword = isCharPotentialHeader(line, i); + + if (line[i] == '{') + { + sw.switchBracketCount++; + if (lookingForCaseBracket) // if 1st after case statement + { + sw.unindentCase = true; // unindenting this case + sw.unindentDepth++; + lookingForCaseBracket = false; // not looking now + } + return i; + } + lookingForCaseBracket = false; // no opening bracket, don't indent + + if (line[i] == '}') + { + sw.switchBracketCount--; + assert(sw.switchBracketCount <= bracketCount); + if (sw.switchBracketCount == 0) // if end of switch statement + { + int lineUnindent = sw.unindentDepth; + if (line.find_first_not_of(" \t") == i + && !switchStack.empty()) + lineUnindent = switchStack[switchStack.size() - 1].unindentDepth; + if (shouldUnindentLine) + { + if (lineUnindent > 0) + i -= unindentLine(line, lineUnindent); + shouldUnindentLine = false; + } + switchDepth--; + sw = switchStack.back(); + switchStack.pop_back(); + } + return i; + } + + if (isPotentialKeyword + && (findKeyword(line, i, "case") || findKeyword(line, i, "default"))) + { + if (sw.unindentCase) // if unindented last case + { + sw.unindentCase = false; // stop unindenting previous case + sw.unindentDepth--; + } + + i = findCaseColon(line, i); + + i++; + for (; i < line.length(); i++) // bypass whitespace + { + if (!isWhiteSpace(line[i])) + break; + } + if (i < line.length()) + { + if (line[i] == '{') + { + bracketCount++; + sw.switchBracketCount++; + if (!isOneLineBlockReached(line, i)) + unindentNextLine = true; + return i; + } + } + lookingForCaseBracket = true; + i--; // need to process this char + return i; + } + if (isPotentialKeyword) + { + string name = getCurrentWord(line, i); // bypass the entire name + i += name.length() - 1; + } + return i; +} + +/** + * unindent a line by a given number of tabsets + * by erasing the leading whitespace from the line argument. + * + * @param line a reference to the line to unindent. + * @param unindent the number of tabsets to erase. + * @return the number of characters erased. + */ +int ASEnhancer::unindentLine(string& line, int unindent) const +{ + size_t whitespace = line.find_first_not_of(" \t"); + + if (whitespace == string::npos) // if line is blank + whitespace = line.length(); // must remove padding, if any + + if (whitespace == 0) + return 0; + + size_t charsToErase = 0; + + if (forceTab && indentLength != tabLength) + { + // replace tab indents with spaces + convertForceTabIndentToSpaces(line); + // remove the space indents + size_t spaceIndentLength = line.find_first_not_of(" \t"); + charsToErase = unindent * indentLength; + if (charsToErase <= spaceIndentLength) + line.erase(0, charsToErase); + else + charsToErase = 0; + // replace leading spaces with tab indents + convertSpaceIndentToForceTab(line); + } + else if (useTabs) + { + charsToErase = unindent; + if (charsToErase <= whitespace) + line.erase(0, charsToErase); + else + charsToErase = 0; + } + else // spaces + { + charsToErase = unindent * indentLength; + if (charsToErase <= whitespace) + line.erase(0, charsToErase); + else + charsToErase = 0; + } + + return charsToErase; +} + +} // end namespace astyle diff --git a/External/Tools/AStyle/src/ASFormatter.cpp b/External/Tools/AStyle/src/ASFormatter.cpp new file mode 100644 index 0000000000..d417bd0be6 --- /dev/null +++ b/External/Tools/AStyle/src/ASFormatter.cpp @@ -0,0 +1,7263 @@ +// ASFormatter.cpp +// Copyright (c) 2016 by Jim Pattee . +// Licensed under the MIT license. +// License.txt describes the conditions under which this software may be distributed. + +//----------------------------------------------------------------------------- +// headers +//----------------------------------------------------------------------------- + +#include "astyle.h" + +#include +#include + +//----------------------------------------------------------------------------- +// astyle namespace +//----------------------------------------------------------------------------- + +namespace astyle { +// +//----------------------------------------------------------------------------- +// ASFormatter class +//----------------------------------------------------------------------------- + +/** + * Constructor of ASFormatter + */ +ASFormatter::ASFormatter() +{ + sourceIterator = NULL; + enhancer = new ASEnhancer; + preBracketHeaderStack = NULL; + bracketTypeStack = NULL; + parenStack = NULL; + structStack = NULL; + questionMarkStack = NULL; + lineCommentNoIndent = false; + formattingStyle = STYLE_NONE; + bracketFormatMode = NONE_MODE; + pointerAlignment = PTR_ALIGN_NONE; + referenceAlignment = REF_SAME_AS_PTR; + objCColonPadMode = COLON_PAD_NO_CHANGE; + lineEnd = LINEEND_DEFAULT; + maxCodeLength = string::npos; + shouldPadCommas = false; + shouldPadOperators = false; + shouldPadParensOutside = false; + shouldPadFirstParen = false; + shouldPadParensInside = false; + shouldPadHeader = false; + shouldStripCommentPrefix = false; + shouldUnPadParens = false; + attachClosingBracketMode = false; + shouldBreakOneLineBlocks = true; + shouldBreakOneLineStatements = true; + shouldConvertTabs = false; + shouldIndentCol1Comments = false; + shouldIndentPreprocBlock = false; + shouldCloseTemplates = false; + shouldAttachExternC = false; + shouldAttachNamespace = false; + shouldAttachClass = false; + shouldAttachInline = false; + shouldBreakBlocks = false; + shouldBreakClosingHeaderBlocks = false; + shouldBreakClosingHeaderBrackets = false; + shouldDeleteEmptyLines = false; + shouldBreakElseIfs = false; + shouldBreakLineAfterLogical = false; + shouldAddBrackets = false; + shouldAddOneLineBrackets = false; + shouldRemoveBrackets = false; + shouldPadMethodColon = false; + shouldPadMethodPrefix = false; + shouldUnPadMethodPrefix = false; + shouldPadReturnType = false; + shouldUnPadReturnType = false; + + // initialize ASFormatter member vectors + formatterFileType = 9; // reset to an invalid type + headers = new vector; + nonParenHeaders = new vector; + preDefinitionHeaders = new vector; + preCommandHeaders = new vector; + operators = new vector; + assignmentOperators = new vector; + castOperators = new vector; + + // initialize ASEnhancer member vectors + indentableMacros = new vector* >; +} + +/** + * Destructor of ASFormatter + */ +ASFormatter::~ASFormatter() +{ + // delete ASFormatter stack vectors + deleteContainer(preBracketHeaderStack); + deleteContainer(bracketTypeStack); + deleteContainer(parenStack); + deleteContainer(structStack); + deleteContainer(questionMarkStack); + + // delete ASFormatter member vectors + formatterFileType = 9; // reset to an invalid type + delete headers; + delete nonParenHeaders; + delete preDefinitionHeaders; + delete preCommandHeaders; + delete operators; + delete assignmentOperators; + delete castOperators; + + // delete ASEnhancer member vectors + delete indentableMacros; + + // delete ASBeautifier member vectors + // must be done when the ASFormatter object is deleted (not ASBeautifier) + ASBeautifier::deleteBeautifierVectors(); + + delete enhancer; +} + +/** + * initialize the ASFormatter. + * + * init() should be called every time a ASFormatter object is to start + * formatting a NEW source file. + * init() receives a pointer to a ASSourceIterator object that will be + * used to iterate through the source code. + * + * @param si a pointer to the ASSourceIterator or ASStreamIterator object. + */ +void ASFormatter::init(ASSourceIterator* si) +{ + buildLanguageVectors(); + fixOptionVariableConflicts(); + ASBeautifier::init(si); + sourceIterator = si; + + enhancer->init(getFileType(), + getIndentLength(), + getTabLength(), + getIndentString() == "\t" ? true : false, + getForceTabIndentation(), + getNamespaceIndent(), + getCaseIndent(), + shouldIndentPreprocBlock, + getPreprocDefineIndent(), + getEmptyLineFill(), + indentableMacros); + + initContainer(preBracketHeaderStack, new vector); + initContainer(parenStack, new vector); + initContainer(structStack, new vector); + initContainer(questionMarkStack, new vector); + parenStack->push_back(0); // parenStack must contain this default entry + initContainer(bracketTypeStack, new vector); + bracketTypeStack->push_back(NULL_TYPE); // bracketTypeStack must contain this default entry + clearFormattedLineSplitPoints(); + + currentHeader = NULL; + currentLine = ""; + readyFormattedLine = ""; + formattedLine = ""; + verbatimDelimiter = ""; + currentChar = ' '; + previousChar = ' '; + previousCommandChar = ' '; + previousNonWSChar = ' '; + quoteChar = '"'; + preprocBlockEnd = 0; + charNum = 0; + checksumIn = 0; + checksumOut = 0; + currentLineFirstBracketNum = string::npos; + formattedLineCommentNum = 0; + leadingSpaces = 0; + previousReadyFormattedLineLength = string::npos; + preprocBracketTypeStackSize = 0; + spacePadNum = 0; + nextLineSpacePadNum = 0; + objCColonAlign = 0; + templateDepth = 0; + squareBracketCount = 0; + horstmannIndentChars = 0; + tabIncrementIn = 0; + previousBracketType = NULL_TYPE; + previousOperator = NULL; + + isVirgin = true; + isInLineComment = false; + isInComment = false; + isInCommentStartLine = false; + noTrimCommentContinuation = false; + isInPreprocessor = false; + isInPreprocessorBeautify = false; + doesLineStartComment = false; + lineEndsInCommentOnly = false; + lineIsCommentOnly = false; + lineIsLineCommentOnly = false; + lineIsEmpty = false; + isImmediatelyPostCommentOnly = false; + isImmediatelyPostEmptyLine = false; + isInClassInitializer = false; + isInQuote = false; + isInVerbatimQuote = false; + haveLineContinuationChar = false; + isInQuoteContinuation = false; + isHeaderInMultiStatementLine = false; + isSpecialChar = false; + isNonParenHeader = false; + foundNamespaceHeader = false; + foundClassHeader = false; + foundStructHeader = false; + foundInterfaceHeader = false; + foundPreDefinitionHeader = false; + foundPreCommandHeader = false; + foundPreCommandMacro = false; + foundCastOperator = false; + foundQuestionMark = false; + isInLineBreak = false; + endOfAsmReached = false; + endOfCodeReached = false; + isFormattingModeOff = false; + isInEnum = false; + isInExecSQL = false; + isInAsm = false; + isInAsmOneLine = false; + isInAsmBlock = false; + isLineReady = false; + elseHeaderFollowsComments = false; + caseHeaderFollowsComments = false; + isPreviousBracketBlockRelated = false; + isInPotentialCalculation = false; + shouldReparseCurrentChar = false; + needHeaderOpeningBracket = false; + shouldBreakLineAtNextChar = false; + shouldKeepLineUnbroken = false; + passedSemicolon = false; + passedColon = false; + isImmediatelyPostNonInStmt = false; + isCharImmediatelyPostNonInStmt = false; + isInTemplate = false; + isImmediatelyPostComment = false; + isImmediatelyPostLineComment = false; + isImmediatelyPostEmptyBlock = false; + isImmediatelyPostObjCMethodPrefix = false; + isImmediatelyPostPreprocessor = false; + isImmediatelyPostReturn = false; + isImmediatelyPostThrow = false; + isImmediatelyPostOperator = false; + isImmediatelyPostTemplate = false; + isImmediatelyPostPointerOrReference = false; + isCharImmediatelyPostReturn = false; + isCharImmediatelyPostThrow = false; + isCharImmediatelyPostOperator = false; + isCharImmediatelyPostComment = false; + isPreviousCharPostComment = false; + isCharImmediatelyPostLineComment = false; + isCharImmediatelyPostOpenBlock = false; + isCharImmediatelyPostCloseBlock = false; + isCharImmediatelyPostTemplate = false; + isCharImmediatelyPostPointerOrReference = false; + isInObjCInterface = false; + isInObjCMethodDefinition = false; + isInObjCReturnType = false; + isInObjCSelector = false; + breakCurrentOneLineBlock = false; + shouldRemoveNextClosingBracket = false; + isInHorstmannRunIn = false; + currentLineBeginsWithBracket = false; + isPrependPostBlockEmptyLineRequested = false; + isAppendPostBlockEmptyLineRequested = false; + isIndentableProprocessor = false; + isIndentableProprocessorBlock = false; + prependEmptyLine = false; + appendOpeningBracket = false; + foundClosingHeader = false; + isImmediatelyPostHeader = false; + isInHeader = false; + isInCase = false; + isFirstPreprocConditional = false; + processedFirstConditional = false; + isJavaStaticConstructor = false; +} + +/** + * build vectors for each programing language + * depending on the file extension. + */ +void ASFormatter::buildLanguageVectors() +{ + if (getFileType() == formatterFileType) // don't build unless necessary + return; + + formatterFileType = getFileType(); + + headers->clear(); + nonParenHeaders->clear(); + preDefinitionHeaders->clear(); + preCommandHeaders->clear(); + operators->clear(); + assignmentOperators->clear(); + castOperators->clear(); + indentableMacros->clear(); // ASEnhancer + + ASResource::buildHeaders(headers, getFileType()); + ASResource::buildNonParenHeaders(nonParenHeaders, getFileType()); + ASResource::buildPreDefinitionHeaders(preDefinitionHeaders, getFileType()); + ASResource::buildPreCommandHeaders(preCommandHeaders, getFileType()); + ASResource::buildOperators(operators, getFileType()); + ASResource::buildAssignmentOperators(assignmentOperators); + ASResource::buildCastOperators(castOperators); + ASResource::buildIndentableMacros(indentableMacros); //ASEnhancer +} + +/** + * set the variables for each predefined style. + * this will override any previous settings. + */ +void ASFormatter::fixOptionVariableConflicts() +{ + if (formattingStyle == STYLE_ALLMAN) + { + setBracketFormatMode(BREAK_MODE); + } + else if (formattingStyle == STYLE_JAVA) + { + setBracketFormatMode(ATTACH_MODE); + } + else if (formattingStyle == STYLE_KR) + { + setBracketFormatMode(LINUX_MODE); + } + else if (formattingStyle == STYLE_STROUSTRUP) + { + setBracketFormatMode(STROUSTRUP_MODE); + } + else if (formattingStyle == STYLE_WHITESMITH) + { + setBracketFormatMode(BREAK_MODE); + setBracketIndent(true); + setClassIndent(true); // avoid hanging indent with access modifiers + setSwitchIndent(true); // avoid hanging indent with case statements + } + else if (formattingStyle == STYLE_VTK) + { + // the unindented class bracket does NOT cause a hanging indent like Whitesmith + setBracketFormatMode(BREAK_MODE); + setBracketIndentVtk(true); // sets both bracketIndent and bracketIndentVtk + setSwitchIndent(true); // avoid hanging indent with case statements + } + else if (formattingStyle == STYLE_BANNER) + { + // attached brackets can have hanging indents with the closing bracket + setBracketFormatMode(ATTACH_MODE); + setBracketIndent(true); + setClassIndent(true); // avoid hanging indent with access modifiers + setSwitchIndent(true); // avoid hanging indent with case statements + } + else if (formattingStyle == STYLE_GNU) + { + setBracketFormatMode(BREAK_MODE); + setBlockIndent(true); + } + else if (formattingStyle == STYLE_LINUX) + { + setBracketFormatMode(LINUX_MODE); + // always for Linux style + setMinConditionalIndentOption(MINCOND_ONEHALF); + } + else if (formattingStyle == STYLE_HORSTMANN) + { + setBracketFormatMode(RUN_IN_MODE); + setSwitchIndent(true); + } + else if (formattingStyle == STYLE_1TBS) + { + setBracketFormatMode(LINUX_MODE); + setAddBracketsMode(true); + setRemoveBracketsMode(false); + } + else if (formattingStyle == STYLE_GOOGLE) + { + setBracketFormatMode(ATTACH_MODE); + setModifierIndent(true); + setClassIndent(false); + } + else if (formattingStyle == STYLE_PICO) + { + setBracketFormatMode(RUN_IN_MODE); + setAttachClosingBracketMode(true); + setSwitchIndent(true); + setBreakOneLineBlocksMode(false); + setSingleStatementsMode(false); + // add-brackets won't work for pico, but it could be fixed if necessary + // both options should be set to true + if (shouldAddBrackets) + shouldAddOneLineBrackets = true; + } + else if (formattingStyle == STYLE_LISP) + { + setBracketFormatMode(ATTACH_MODE); + setAttachClosingBracketMode(true); + setSingleStatementsMode(false); + // add-one-line-brackets won't work for lisp + // only shouldAddBrackets should be set to true + if (shouldAddOneLineBrackets) + { + shouldAddBrackets = true; + shouldAddOneLineBrackets = false; + } + } + setMinConditionalIndentLength(); + // if not set by indent=force-tab-x set equal to indentLength + if (!getTabLength()) + setDefaultTabLength(); + // add-one-line-brackets implies keep-one-line-blocks + if (shouldAddOneLineBrackets) + setBreakOneLineBlocksMode(false); + // don't allow add-brackets and remove-brackets + if (shouldAddBrackets || shouldAddOneLineBrackets) + setRemoveBracketsMode(false); + // don't allow indent-classes and indent-modifiers + if (getClassIndent()) + setModifierIndent(false); +} + +/** + * get the next formatted line. + * + * @return formatted line. + */ +string ASFormatter::nextLine() +{ + const string* newHeader = NULL; + bool isInVirginLine = isVirgin; + isCharImmediatelyPostComment = false; + isPreviousCharPostComment = false; + isCharImmediatelyPostLineComment = false; + isCharImmediatelyPostOpenBlock = false; + isCharImmediatelyPostCloseBlock = false; + isCharImmediatelyPostTemplate = false; + + while (!isLineReady) + { + if (shouldReparseCurrentChar) + shouldReparseCurrentChar = false; + else if (!getNextChar()) + { + breakLine(); + continue; + } + else // stuff to do when reading a new character... + { + // make sure that a virgin '{' at the beginning of the file will be treated as a block... + if (isInVirginLine && currentChar == '{' + && currentLineBeginsWithBracket + && previousCommandChar == ' ') + previousCommandChar = '{'; + if (isInClassInitializer + && isBracketType(bracketTypeStack->back(), COMMAND_TYPE)) + isInClassInitializer = false; + if (isInHorstmannRunIn) + isInLineBreak = false; + if (!isWhiteSpace(currentChar)) + isInHorstmannRunIn = false; + isPreviousCharPostComment = isCharImmediatelyPostComment; + isCharImmediatelyPostComment = false; + isCharImmediatelyPostTemplate = false; + isCharImmediatelyPostReturn = false; + isCharImmediatelyPostThrow = false; + isCharImmediatelyPostOperator = false; + isCharImmediatelyPostPointerOrReference = false; + isCharImmediatelyPostOpenBlock = false; + isCharImmediatelyPostCloseBlock = false; + } + + if ((lineIsLineCommentOnly || lineIsCommentOnly) + && currentLine.find("*INDENT-ON*", charNum) != string::npos + && isFormattingModeOff) + { + isFormattingModeOff = false; + breakLine(); + formattedLine = currentLine; + charNum = (int) currentLine.length() - 1; + continue; + } + if (isFormattingModeOff) + { + breakLine(); + formattedLine = currentLine; + charNum = (int) currentLine.length() - 1; + continue; + } + if ((lineIsLineCommentOnly || lineIsCommentOnly) + && currentLine.find("*INDENT-OFF*", charNum) != string::npos) + { + isFormattingModeOff = true; + if (isInLineBreak) // is true if not the first line + breakLine(); + formattedLine = currentLine; + charNum = (int)currentLine.length() - 1; + continue; + } + + if (shouldBreakLineAtNextChar) + { + if (isWhiteSpace(currentChar) && !lineIsEmpty) + continue; + isInLineBreak = true; + shouldBreakLineAtNextChar = false; + } + + if (isInExecSQL && !passedSemicolon) + { + if (currentChar == ';') + passedSemicolon = true; + appendCurrentChar(); + continue; + } + + if (isInLineComment) + { + formatLineCommentBody(); + continue; + } + else if (isInComment) + { + formatCommentBody(); + continue; + } + + else if (isInQuote) + { + formatQuoteBody(); + continue; + } + + // not in quote or comment or line comment + + if (isSequenceReached("//")) + { + formatLineCommentOpener(); + testForTimeToSplitFormattedLine(); + continue; + } + else if (isSequenceReached("/*")) + { + formatCommentOpener(); + testForTimeToSplitFormattedLine(); + continue; + } + else if (currentChar == '"' + || (currentChar == '\'' && !isDigitSeparator(currentLine, charNum))) + { + formatQuoteOpener(); + testForTimeToSplitFormattedLine(); + continue; + } + // treat these preprocessor statements as a line comment + else if (currentChar == '#' + && currentLine.find_first_not_of(" \t") == (size_t) charNum) + { + string preproc = trim(currentLine.c_str() + charNum + 1); + if (preproc.length() > 0 + && isCharPotentialHeader(preproc, 0) + && (findKeyword(preproc, 0, "region") + || findKeyword(preproc, 0, "endregion") + || findKeyword(preproc, 0, "error") + || findKeyword(preproc, 0, "warning") + || findKeyword(preproc, 0, "line"))) + { + currentLine = rtrim(currentLine); // trim the end only + // check for horstmann run-in + if (formattedLine.length() > 0 && formattedLine[0] == '{') + { + isInLineBreak = true; + isInHorstmannRunIn = false; + } + if (previousCommandChar == '}') + currentHeader = NULL; + isInLineComment = true; + appendCurrentChar(); + continue; + } + } + + if (isInPreprocessor) + { + appendCurrentChar(); + continue; + } + + if (isInTemplate && shouldCloseTemplates) + { + if (previousCommandChar == '<' && isWhiteSpace(currentChar)) + continue; + if (isWhiteSpace(currentChar) && peekNextChar() == '>') + continue; + } + + if (shouldRemoveNextClosingBracket && currentChar == '}') + { + currentLine[charNum] = currentChar = ' '; + shouldRemoveNextClosingBracket = false; + assert(adjustChecksumIn(-'}')); + // if the line is empty, delete it + if (currentLine.find_first_not_of(" \t")) + continue; + } + + // handle white space - needed to simplify the rest. + if (isWhiteSpace(currentChar)) + { + appendCurrentChar(); + continue; + } + + /* not in MIDDLE of quote or comment or SQL or white-space of any type ... */ + + // check if in preprocessor + // ** isInPreprocessor will be automatically reset at the beginning + // of a new line in getnextChar() + if (currentChar == '#') + { + isInPreprocessor = true; + // check for horstmann run-in + if (formattedLine.length() > 0 && formattedLine[0] == '{') + { + isInLineBreak = true; + isInHorstmannRunIn = false; + } + processPreprocessor(); + // if top level it is potentially indentable + if (shouldIndentPreprocBlock + && (isBracketType(bracketTypeStack->back(), NULL_TYPE) + || isBracketType(bracketTypeStack->back(), NAMESPACE_TYPE)) + && !foundClassHeader + && !isInClassInitializer + && sourceIterator->tellg() > preprocBlockEnd) + { + // indent the #if preprocessor blocks + string preproc = ASBeautifier::extractPreprocessorStatement(currentLine); + if (preproc.length() >= 2 && preproc.substr(0, 2) == "if") // #if, #ifdef, #ifndef + { + if (isImmediatelyPostPreprocessor) + breakLine(); + isIndentableProprocessorBlock = isIndentablePreprocessorBlock(currentLine, charNum); + isIndentableProprocessor = isIndentableProprocessorBlock; + } + } + if (isIndentableProprocessorBlock + && charNum < (int) currentLine.length() - 1 + && isWhiteSpace(currentLine[charNum + 1])) + { + size_t nextText = currentLine.find_first_not_of(" \t", charNum + 1); + if (nextText != string::npos) + currentLine.erase(charNum + 1, nextText - charNum - 1); + } + if (isIndentableProprocessorBlock + && sourceIterator->tellg() >= preprocBlockEnd) + isIndentableProprocessorBlock = false; + // need to fall thru here to reset the variables + } + + /* not in preprocessor ... */ + + if (isImmediatelyPostComment) + { + caseHeaderFollowsComments = false; + isImmediatelyPostComment = false; + isCharImmediatelyPostComment = true; + } + + if (isImmediatelyPostLineComment) + { + caseHeaderFollowsComments = false; + isImmediatelyPostLineComment = false; + isCharImmediatelyPostLineComment = true; + } + + if (isImmediatelyPostReturn) + { + isImmediatelyPostReturn = false; + isCharImmediatelyPostReturn = true; + } + + if (isImmediatelyPostThrow) + { + isImmediatelyPostThrow = false; + isCharImmediatelyPostThrow = true; + } + + if (isImmediatelyPostOperator) + { + isImmediatelyPostOperator = false; + isCharImmediatelyPostOperator = true; + } + if (isImmediatelyPostTemplate) + { + isImmediatelyPostTemplate = false; + isCharImmediatelyPostTemplate = true; + } + if (isImmediatelyPostPointerOrReference) + { + isImmediatelyPostPointerOrReference = false; + isCharImmediatelyPostPointerOrReference = true; + } + + // reset isImmediatelyPostHeader information + if (isImmediatelyPostHeader) + { + // should brackets be added + if (currentChar != '{' && shouldAddBrackets) + { + bool bracketsAdded = addBracketsToStatement(); + if (bracketsAdded && !shouldAddOneLineBrackets) + { + size_t firstText = currentLine.find_first_not_of(" \t"); + assert(firstText != string::npos); + if ((int) firstText == charNum) + breakCurrentOneLineBlock = true; + } + } + // should brackets be removed + else if (currentChar == '{' && shouldRemoveBrackets) + { + bool bracketsRemoved = removeBracketsFromStatement(); + if (bracketsRemoved) + { + shouldRemoveNextClosingBracket = true; + if (isBeforeAnyLineEndComment(charNum)) + spacePadNum--; + else if (shouldBreakOneLineBlocks + || (currentLineBeginsWithBracket + && currentLine.find_first_not_of(" \t") != string::npos)) + shouldBreakLineAtNextChar = true; + continue; + } + } + + // break 'else-if' if shouldBreakElseIfs is requested + if (shouldBreakElseIfs + && currentHeader == &AS_ELSE + && isOkToBreakBlock(bracketTypeStack->back()) + && !isBeforeAnyComment() + && (shouldBreakOneLineStatements || !isHeaderInMultiStatementLine)) + { + string nextText = peekNextText(currentLine.substr(charNum)); + if (nextText.length() > 0 + && isCharPotentialHeader(nextText, 0) + && ASBeautifier::findHeader(nextText, 0, headers) == &AS_IF) + { + isInLineBreak = true; + } + } + + isImmediatelyPostHeader = false; + } + + if (passedSemicolon) // need to break the formattedLine + { + passedSemicolon = false; + if (parenStack->back() == 0 && !isCharImmediatelyPostComment && currentChar != ';') // allow ;; + { + // does a one-line block have ending comments? + if (isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)) + { + size_t blockEnd = currentLine.rfind(AS_CLOSE_BRACKET); + assert(blockEnd != string::npos); + // move ending comments to this formattedLine + if (isBeforeAnyLineEndComment(blockEnd)) + { + size_t commentStart = currentLine.find_first_not_of(" \t", blockEnd + 1); + assert(commentStart != string::npos); + assert((currentLine.compare(commentStart, 2, "//") == 0) + || (currentLine.compare(commentStart, 2, "/*") == 0)); + size_t commentLength = currentLine.length() - commentStart; + formattedLine.append(getIndentLength() - 1, ' '); + formattedLine.append(currentLine, commentStart, commentLength); + currentLine.erase(commentStart, commentLength); + testForTimeToSplitFormattedLine(); + } + } + isInExecSQL = false; + shouldReparseCurrentChar = true; + if (formattedLine.find_first_not_of(" \t") != string::npos) + isInLineBreak = true; + if (needHeaderOpeningBracket) + { + isCharImmediatelyPostCloseBlock = true; + needHeaderOpeningBracket = false; + } + continue; + } + } + + if (passedColon) + { + passedColon = false; + if (parenStack->back() == 0 + && !isBeforeAnyComment() + && (formattedLine.find_first_not_of(" \t") != string::npos)) + { + shouldReparseCurrentChar = true; + isInLineBreak = true; + continue; + } + } + + // Check if in template declaration, e.g. foo or foo + if (!isInTemplate && currentChar == '<') + { + checkIfTemplateOpener(); + } + + // handle parens + if (currentChar == '(' || currentChar == '[' || (isInTemplate && currentChar == '<')) + { + questionMarkStack->push_back(foundQuestionMark); + foundQuestionMark = false; + parenStack->back()++; + if (currentChar == '[') + ++squareBracketCount; + } + else if (currentChar == ')' || currentChar == ']' || (isInTemplate && currentChar == '>')) + { + foundPreCommandHeader = false; + parenStack->back()--; + // this can happen in preprocessor directives + if (parenStack->back() < 0) + parenStack->back() = 0; + if (!questionMarkStack->empty()) + { + foundQuestionMark = questionMarkStack->back(); + questionMarkStack->pop_back(); + } + if (isInTemplate && currentChar == '>') + { + templateDepth--; + if (templateDepth == 0) + { + isInTemplate = false; + isImmediatelyPostTemplate = true; + } + } + + // check if this parenthesis closes a header, e.g. if (...), while (...) + if (isInHeader && parenStack->back() == 0) + { + isInHeader = false; + isImmediatelyPostHeader = true; + foundQuestionMark = false; + } + if (currentChar == ']') + { + --squareBracketCount; + if (squareBracketCount < 0) + squareBracketCount = 0; + } + if (currentChar == ')') + { + foundCastOperator = false; + if (parenStack->back() == 0) + endOfAsmReached = true; + } + } + + // handle brackets + if (currentChar == '{' || currentChar == '}') + { + // if appendOpeningBracket this was already done for the original bracket + if (currentChar == '{' && !appendOpeningBracket) + { + BracketType newBracketType = getBracketType(); + foundNamespaceHeader = false; + foundClassHeader = false; + foundStructHeader = false; + foundInterfaceHeader = false; + foundPreDefinitionHeader = false; + foundPreCommandHeader = false; + foundPreCommandMacro = false; + isInPotentialCalculation = false; + isInObjCMethodDefinition = false; + isInObjCInterface = false; + isInEnum = false; + isJavaStaticConstructor = false; + isCharImmediatelyPostNonInStmt = false; + needHeaderOpeningBracket = false; + shouldKeepLineUnbroken = false; + objCColonAlign = 0; + + isPreviousBracketBlockRelated = !isBracketType(newBracketType, ARRAY_TYPE); + bracketTypeStack->push_back(newBracketType); + preBracketHeaderStack->push_back(currentHeader); + currentHeader = NULL; + structStack->push_back(isInIndentableStruct); + if (isBracketType(newBracketType, STRUCT_TYPE) && isCStyle()) + isInIndentableStruct = isStructAccessModified(currentLine, charNum); + else + isInIndentableStruct = false; + } + + // this must be done before the bracketTypeStack is popped + BracketType bracketType = bracketTypeStack->back(); + bool isOpeningArrayBracket = (isBracketType(bracketType, ARRAY_TYPE) + && bracketTypeStack->size() >= 2 + && !isBracketType((*bracketTypeStack)[bracketTypeStack->size() - 2], ARRAY_TYPE) + ); + + if (currentChar == '}') + { + // if a request has been made to append a post block empty line, + // but the block exists immediately before a closing bracket, + // then there is no need for the post block empty line. + isAppendPostBlockEmptyLineRequested = false; + breakCurrentOneLineBlock = false; + if (isInAsm) + endOfAsmReached = true; + isInAsmOneLine = isInQuote = false; + shouldKeepLineUnbroken = false; + squareBracketCount = 0; + + if (bracketTypeStack->size() > 1) + { + previousBracketType = bracketTypeStack->back(); + bracketTypeStack->pop_back(); + isPreviousBracketBlockRelated = !isBracketType(bracketType, ARRAY_TYPE); + } + else + { + previousBracketType = NULL_TYPE; + isPreviousBracketBlockRelated = false; + } + + if (!preBracketHeaderStack->empty()) + { + currentHeader = preBracketHeaderStack->back(); + preBracketHeaderStack->pop_back(); + } + else + currentHeader = NULL; + + if (!structStack->empty()) + { + isInIndentableStruct = structStack->back(); + structStack->pop_back(); + } + else + isInIndentableStruct = false; + + if (isNonInStatementArray + && (!isBracketType(bracketTypeStack->back(), ARRAY_TYPE) // check previous bracket + || peekNextChar() == ';')) // check for "};" added V2.01 + isImmediatelyPostNonInStmt = true; + } + + // format brackets + appendOpeningBracket = false; + if (isBracketType(bracketType, ARRAY_TYPE)) + { + formatArrayBrackets(bracketType, isOpeningArrayBracket); + } + else + { + if (currentChar == '{') + formatOpeningBracket(bracketType); + else + formatClosingBracket(bracketType); + } + continue; + } + + if ((((previousCommandChar == '{' && isPreviousBracketBlockRelated) + || ((previousCommandChar == '}' + && !isImmediatelyPostEmptyBlock + && isPreviousBracketBlockRelated + && !isPreviousCharPostComment // Fixes wrongly appended newlines after '}' immediately after comments + && peekNextChar() != ' ' + && !isBracketType(previousBracketType, DEFINITION_TYPE)) + && !isBracketType(bracketTypeStack->back(), DEFINITION_TYPE))) + && isOkToBreakBlock(bracketTypeStack->back())) + // check for array + || (previousCommandChar == '{' // added 9/30/2010 + && isBracketType(bracketTypeStack->back(), ARRAY_TYPE) + && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE) + && isNonInStatementArray)) + { + isCharImmediatelyPostOpenBlock = (previousCommandChar == '{'); + isCharImmediatelyPostCloseBlock = (previousCommandChar == '}'); + + if (isCharImmediatelyPostOpenBlock + && !isCharImmediatelyPostComment + && !isCharImmediatelyPostLineComment) + { + previousCommandChar = ' '; + + if (bracketFormatMode == NONE_MODE) + { + if (shouldBreakOneLineBlocks + && isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)) + isInLineBreak = true; + else if (currentLineBeginsWithBracket) + formatRunIn(); + else + breakLine(); + } + else if (bracketFormatMode == RUN_IN_MODE + && currentChar != '#') + formatRunIn(); + else + isInLineBreak = true; + } + else if (isCharImmediatelyPostCloseBlock + && shouldBreakOneLineStatements + && (isLegalNameChar(currentChar) && currentChar != '.') + && !isCharImmediatelyPostComment) + { + previousCommandChar = ' '; + isInLineBreak = true; + } + } + + // reset block handling flags + isImmediatelyPostEmptyBlock = false; + + // look for headers + bool isPotentialHeader = isCharPotentialHeader(currentLine, charNum); + + if (isPotentialHeader && !isInTemplate && !squareBracketCount) + { + isNonParenHeader = false; + foundClosingHeader = false; + newHeader = findHeader(headers); + + // Qt headers may be variables in C++ + if (isCStyle() + && (newHeader == &AS_FOREVER || newHeader == &AS_FOREACH)) + { + if (currentLine.find_first_of("=;", charNum) != string::npos) + newHeader = NULL; + } + else if (newHeader == &AS_USING + && ASBeautifier::peekNextChar(currentLine, + charNum + (*newHeader).length() - 1) != '(') + newHeader = NULL; + + if (newHeader != NULL) + { + // recognize closing headers of do..while, if..else, try..catch..finally + if ((newHeader == &AS_ELSE && currentHeader == &AS_IF) + || (newHeader == &AS_WHILE && currentHeader == &AS_DO) + || (newHeader == &AS_CATCH && currentHeader == &AS_TRY) + || (newHeader == &AS_CATCH && currentHeader == &AS_CATCH) + || (newHeader == &AS_FINALLY && currentHeader == &AS_TRY) + || (newHeader == &AS_FINALLY && currentHeader == &AS_CATCH) + || (newHeader == &_AS_FINALLY && currentHeader == &_AS_TRY) + || (newHeader == &_AS_EXCEPT && currentHeader == &_AS_TRY) + || (newHeader == &AS_SET && currentHeader == &AS_GET) + || (newHeader == &AS_REMOVE && currentHeader == &AS_ADD)) + foundClosingHeader = true; + + const string* previousHeader = currentHeader; + currentHeader = newHeader; + needHeaderOpeningBracket = true; + + // is the previous statement on the same line? + if ((previousNonWSChar == ';' || previousNonWSChar == ':') + && !isInLineBreak + && isOkToBreakBlock(bracketTypeStack->back())) + { + // if breaking lines, break the line at the header + // except for multiple 'case' statements on a line + if (maxCodeLength != string::npos + && previousHeader != &AS_CASE) + isInLineBreak = true; + else + isHeaderInMultiStatementLine = true; + } + + if (foundClosingHeader && previousNonWSChar == '}') + { + if (isOkToBreakBlock(bracketTypeStack->back())) + isLineBreakBeforeClosingHeader(); + + // get the adjustment for a comment following the closing header + if (isInLineBreak) + nextLineSpacePadNum = getNextLineCommentAdjustment(); + else + spacePadNum = getCurrentLineCommentAdjustment(); + } + + // check if the found header is non-paren header + isNonParenHeader = findHeader(nonParenHeaders) != NULL; + + // join 'else if' statements + if (currentHeader == &AS_IF + && previousHeader == &AS_ELSE + && isInLineBreak + && !shouldBreakElseIfs + && !isCharImmediatelyPostLineComment + && !isImmediatelyPostPreprocessor) + { + // 'else' must be last thing on the line + size_t start = formattedLine.length() >= 6 ? formattedLine.length() - 6 : 0; + if (formattedLine.find(AS_ELSE, start) != string::npos) + { + appendSpacePad(); + isInLineBreak = false; + } + } + + appendSequence(*currentHeader); + goForward(currentHeader->length() - 1); + // if a paren-header is found add a space after it, if needed + // this checks currentLine, appendSpacePad() checks formattedLine + // in 'case' and C# 'catch' can be either a paren or non-paren header + if (shouldPadHeader + && (!isNonParenHeader + || (currentHeader == &AS_CASE && peekNextChar() == '(') + || (currentHeader == &AS_CATCH && peekNextChar() == '(')) + && charNum < (int) currentLine.length() - 1 && !isWhiteSpace(currentLine[charNum + 1])) + appendSpacePad(); + + // Signal that a header has been reached + // *** But treat a closing while() (as in do...while) + // as if it were NOT a header since a closing while() + // should never have a block after it! + if (currentHeader != &AS_CASE && currentHeader != &AS_DEFAULT + && !(foundClosingHeader && currentHeader == &AS_WHILE)) + { + isInHeader = true; + + // in C# 'catch' and 'delegate' can be a paren or non-paren header + if (isNonParenHeader && !isSharpStyleWithParen(currentHeader)) + { + isImmediatelyPostHeader = true; + isInHeader = false; + } + } + + if (shouldBreakBlocks + && isOkToBreakBlock(bracketTypeStack->back()) + && !isHeaderInMultiStatementLine) + { + if (previousHeader == NULL + && !foundClosingHeader + && !isCharImmediatelyPostOpenBlock + && !isImmediatelyPostCommentOnly) + { + isPrependPostBlockEmptyLineRequested = true; + } + + if (currentHeader == &AS_ELSE + || currentHeader == &AS_CATCH + || currentHeader == &AS_FINALLY + || foundClosingHeader) + { + isPrependPostBlockEmptyLineRequested = false; + } + + if (shouldBreakClosingHeaderBlocks + && isCharImmediatelyPostCloseBlock + && !isImmediatelyPostCommentOnly + && currentHeader != &AS_WHILE) // closing do-while block + { + isPrependPostBlockEmptyLineRequested = true; + } + } + + if (currentHeader == &AS_CASE + || currentHeader == &AS_DEFAULT) + isInCase = true; + + continue; + } + else if ((newHeader = findHeader(preDefinitionHeaders)) != NULL + && parenStack->back() == 0 + && !isInEnum) // not C++11 enum class + { + if (newHeader == &AS_NAMESPACE) + foundNamespaceHeader = true; + if (newHeader == &AS_CLASS) + foundClassHeader = true; + if (newHeader == &AS_STRUCT) + foundStructHeader = true; + if (newHeader == &AS_INTERFACE) + foundInterfaceHeader = true; + foundPreDefinitionHeader = true; + appendSequence(*newHeader); + goForward(newHeader->length() - 1); + + continue; + } + else if ((newHeader = findHeader(preCommandHeaders)) != NULL) + { + // a 'const' variable is not a preCommandHeader + if (previousNonWSChar == ')') + foundPreCommandHeader = true; + } + else if ((newHeader = findHeader(castOperators)) != NULL) + { + foundCastOperator = true; + appendSequence(*newHeader); + goForward(newHeader->length() - 1); + continue; + } + } // (isPotentialHeader && !isInTemplate) + + if (isInLineBreak) // OK to break line here + { + breakLine(); + if (isInVirginLine) // adjust for the first line + { + lineCommentNoBeautify = lineCommentNoIndent; + lineCommentNoIndent = false; + if (isImmediatelyPostPreprocessor) + { + isInIndentablePreproc = isIndentableProprocessor; + isIndentableProprocessor = false; + } + } + } + + if (previousNonWSChar == '}' || currentChar == ';') + { + if (currentChar == ';') + { + squareBracketCount = 0; + + if (((shouldBreakOneLineStatements + || isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)) + && isOkToBreakBlock(bracketTypeStack->back())) + && !(attachClosingBracketMode && peekNextChar() == '}')) + { + passedSemicolon = true; + } + + // append post block empty line for unbracketed header + if (shouldBreakBlocks + && currentHeader != NULL + && currentHeader != &AS_CASE + && currentHeader != &AS_DEFAULT + && !isHeaderInMultiStatementLine + && parenStack->back() == 0) + { + isAppendPostBlockEmptyLineRequested = true; + } + } + if (currentChar != ';' + || (needHeaderOpeningBracket && parenStack->back() == 0)) + currentHeader = NULL; + resetEndOfStatement(); + } + + if (currentChar == ':' + && previousChar != ':' // not part of '::' + && peekNextChar() != ':') // not part of '::' + { + if (isInCase) + { + isInCase = false; + if (shouldBreakOneLineStatements) + passedColon = true; + } + else if (isCStyle() // for C/C++ only + && isOkToBreakBlock(bracketTypeStack->back()) + && shouldBreakOneLineStatements + && !foundQuestionMark // not in a ?: sequence + && !foundPreDefinitionHeader // not in a definition block (e.g. class foo : public bar + && previousCommandChar != ')' // not immediately after closing paren of a method header, e.g. ASFormatter::ASFormatter(...) : ASBeautifier(...) + && !foundPreCommandHeader // not after a 'noexcept' + && !squareBracketCount // not in objC method call + && !isInObjCMethodDefinition // not objC '-' or '+' method + && !isInObjCInterface // not objC @interface + && !isInObjCSelector // not objC @selector + && !isDigit(peekNextChar()) // not a bit field + && !isInEnum // not an enum with a base type + && !isInAsm // not in extended assembler + && !isInAsmOneLine // not in extended assembler + && !isInAsmBlock) // not in extended assembler + { + passedColon = true; + } + + if (isCStyle() + && shouldPadMethodColon + && (squareBracketCount > 0 || isInObjCMethodDefinition || isInObjCSelector) + && !foundQuestionMark) // not in a ?: sequence + padObjCMethodColon(); + + if (isInObjCInterface) + { + appendSpacePad(); + if ((int) currentLine.length() > charNum + 1 && !isWhiteSpace(currentLine[charNum + 1])) + currentLine.insert(charNum + 1, " "); + } + + if (isClassInitializer()) + isInClassInitializer = true; + } + + if (currentChar == '?') + foundQuestionMark = true; + + if (isPotentialHeader && !isInTemplate) + { + if (findKeyword(currentLine, charNum, AS_NEW)) + isInPotentialCalculation = false; + + if (findKeyword(currentLine, charNum, AS_RETURN)) + { + isInPotentialCalculation = true; // return is the same as an = sign + isImmediatelyPostReturn = true; + } + + if (findKeyword(currentLine, charNum, AS_OPERATOR)) + isImmediatelyPostOperator = true; + + if (findKeyword(currentLine, charNum, AS_ENUM)) + { + size_t firstNum = currentLine.find_first_of("(){},/"); + if (firstNum == string::npos + || currentLine[firstNum] == '{' + || currentLine[firstNum] == '/') + isInEnum = true; + } + + if (isCStyle() + && findKeyword(currentLine, charNum, AS_THROW) + && previousCommandChar != ')' + && !foundPreCommandHeader) // 'const' throw() + isImmediatelyPostThrow = true; + + if (isCStyle() && findKeyword(currentLine, charNum, AS_EXTERN) && isExternC()) + isInExternC = true; + + // Objective-C NSException macros are preCommandHeaders + if (isCStyle() && findKeyword(currentLine, charNum, AS_NS_DURING)) + foundPreCommandMacro = true; + if (isCStyle() && findKeyword(currentLine, charNum, AS_NS_HANDLER)) + foundPreCommandMacro = true; + + if (isCStyle() && isExecSQL(currentLine, charNum)) + isInExecSQL = true; + + if (isCStyle()) + { + if (findKeyword(currentLine, charNum, AS_ASM) + || findKeyword(currentLine, charNum, AS__ASM__)) + { + isInAsm = true; + } + else if (findKeyword(currentLine, charNum, AS_MS_ASM) // microsoft specific + || findKeyword(currentLine, charNum, AS_MS__ASM)) + { + int index = 4; + if (peekNextChar() == '_') // check for __asm + index = 5; + + char peekedChar = ASBase::peekNextChar(currentLine, charNum + index); + if (peekedChar == '{' || peekedChar == ' ') + isInAsmBlock = true; + else + isInAsmOneLine = true; + } + } + + if (isJavaStyle() + && (findKeyword(currentLine, charNum, AS_STATIC) + && isNextCharOpeningBracket(charNum + 6))) + isJavaStaticConstructor = true; + + if (isSharpStyle() + && (findKeyword(currentLine, charNum, AS_DELEGATE) + || findKeyword(currentLine, charNum, AS_UNCHECKED))) + isSharpDelegate = true; + + // append the entire name + string name = getCurrentWord(currentLine, charNum); + // must pad the 'and' and 'or' operators if required + if (name == "and" || name == "or") + { + if (shouldPadOperators && previousNonWSChar != ':') + { + appendSpacePad(); + appendOperator(name); + goForward(name.length() - 1); + if (!isBeforeAnyComment() + && !(currentLine.compare(charNum + 1, 1, AS_SEMICOLON) == 0) + && !(currentLine.compare(charNum + 1, 2, AS_SCOPE_RESOLUTION) == 0)) + appendSpaceAfter(); + } + else + { + appendOperator(name); + goForward(name.length() - 1); + } + } + else + { + appendSequence(name); + goForward(name.length() - 1); + } + + continue; + + } // (isPotentialHeader && !isInTemplate) + + // determine if this is an Objective-C statement + + if (currentChar == '@' + && isCharPotentialHeader(currentLine, charNum + 1) + && findKeyword(currentLine, charNum + 1, AS_INTERFACE) + && isBracketType(bracketTypeStack->back(), NULL_TYPE)) + { + isInObjCInterface = true; + string name = '@' + AS_INTERFACE; + appendSequence(name); + goForward(name.length() - 1); + continue; + } + else if (currentChar == '@' + && isCharPotentialHeader(currentLine, charNum + 1) + && findKeyword(currentLine, charNum + 1, AS_SELECTOR)) + { + isInObjCSelector = true; + string name = '@' + AS_SELECTOR; + appendSequence(name); + goForward(name.length() - 1); + continue; + } + else if ((currentChar == '-' || currentChar == '+') + && charNum == 0 + && peekNextChar() == '(' + && isBracketType(bracketTypeStack->back(), NULL_TYPE) + && !isInPotentialCalculation) + { + isInObjCMethodDefinition = true; + isImmediatelyPostObjCMethodPrefix = true; + isInObjCInterface = false; + if (getAlignMethodColon()) + objCColonAlign = findObjCColonAlignment(); + appendCurrentChar(); + continue; + } + + // determine if this is a potential calculation + + bool isPotentialOperator = isCharPotentialOperator(currentChar); + newHeader = NULL; + + if (isPotentialOperator) + { + newHeader = findOperator(operators); + + // check for Java ? wildcard + if (newHeader == &AS_GCC_MIN_ASSIGN && isJavaStyle() && isInTemplate) + newHeader = NULL; + + if (newHeader != NULL) + { + if (newHeader == &AS_LAMBDA) + foundPreCommandHeader = true; + + // correct mistake of two >> closing a template + if (isInTemplate && (newHeader == &AS_GR_GR || newHeader == &AS_GR_GR_GR)) + newHeader = &AS_GR; + + if (!isInPotentialCalculation) + { + // must determine if newHeader is an assignment operator + // do NOT use findOperator!!! + if (find(assignmentOperators->begin(), assignmentOperators->end(), newHeader) + != assignmentOperators->end()) + { + foundPreCommandHeader = false; + char peekedChar = peekNextChar(); + isInPotentialCalculation = !(newHeader == &AS_EQUAL && peekedChar == '*') + && !(newHeader == &AS_EQUAL && peekedChar == '&') + && !isCharImmediatelyPostOperator; + } + } + } + } + + // process pointers and references + // check newHeader to eliminate things like '&&' sequence + if (!isJavaStyle() + && (newHeader == &AS_MULT + || newHeader == &AS_BIT_AND + || newHeader == &AS_BIT_XOR + || newHeader == &AS_AND) + && isPointerOrReference()) + { + if (!isDereferenceOrAddressOf() && !isOperatorPaddingDisabled()) + formatPointerOrReference(); + else + { + appendOperator(*newHeader); + goForward(newHeader->length() - 1); + } + isImmediatelyPostPointerOrReference = true; + continue; + } + + if (shouldPadOperators && newHeader != NULL && !isOperatorPaddingDisabled()) + { + padOperators(newHeader); + continue; + } + + // remove spaces before commas + if (currentChar == ',') + { + const size_t len = formattedLine.length(); + size_t lastText = formattedLine.find_last_not_of(' '); + if (lastText != string::npos && lastText < len - 1) + { + formattedLine.resize(lastText + 1); + int size_diff = len - (lastText + 1); + spacePadNum -= size_diff; + } + } + + // pad commas and semi-colons + if (currentChar == ';' + || (currentChar == ',' && (shouldPadOperators || shouldPadCommas))) + { + char nextChar = ' '; + if (charNum + 1 < (int) currentLine.length()) + nextChar = currentLine[charNum + 1]; + if (!isWhiteSpace(nextChar) + && nextChar != '}' + && nextChar != ')' + && nextChar != ']' + && nextChar != '>' + && nextChar != ';' + && !isBeforeAnyComment() + /* && !(isBracketType(bracketTypeStack->back(), ARRAY_TYPE)) */ + ) + { + appendCurrentChar(); + appendSpaceAfter(); + continue; + } + } + + // pad parens + if (currentChar == '(' || currentChar == ')') + { + if (currentChar == '(') + { + if (shouldPadHeader + && (isCharImmediatelyPostReturn || isCharImmediatelyPostThrow)) + appendSpacePad(); + } + + if (shouldPadParensOutside || shouldPadParensInside || shouldUnPadParens || shouldPadFirstParen) + padParens(); + else + appendCurrentChar(); + + if (currentChar == '(' + && isImmediatelyPostObjCMethodPrefix + && (shouldPadMethodPrefix || shouldUnPadMethodPrefix)) + padParenObjC(); + if (currentChar == ')' + && isInObjCReturnType + && (shouldPadReturnType || shouldUnPadReturnType)) + padParenObjC(); + + if (currentChar == '(' && isImmediatelyPostObjCMethodPrefix) + { + isImmediatelyPostObjCMethodPrefix = false; + isInObjCReturnType = true; + } + else if (currentChar == ')' && isInObjCReturnType) + isInObjCReturnType = false; + + continue; + } + + // bypass the entire operator + if (newHeader != NULL) + { + appendOperator(*newHeader); + goForward(newHeader->length() - 1); + continue; + } + + appendCurrentChar(); + + } // end of while loop * end of while loop * end of while loop * end of while loop + + // return a beautified (i.e. correctly indented) line. + + string beautifiedLine; + size_t readyFormattedLineLength = trim(readyFormattedLine).length(); + bool isInNamespace = isBracketType(bracketTypeStack->back(), NAMESPACE_TYPE); + + if (prependEmptyLine // prepend a blank line before this formatted line + && readyFormattedLineLength > 0 + && previousReadyFormattedLineLength > 0) + { + isLineReady = true; // signal a waiting readyFormattedLine + beautifiedLine = beautify(""); + previousReadyFormattedLineLength = 0; + // call the enhancer for new empty lines + enhancer->enhance(beautifiedLine, isInNamespace, isInPreprocessorBeautify, isInBeautifySQL); + } + else // format the current formatted line + { + isLineReady = false; + horstmannIndentInStatement = horstmannIndentChars; + beautifiedLine = beautify(readyFormattedLine); + previousReadyFormattedLineLength = readyFormattedLineLength; + // the enhancer is not called for no-indent line comments + if (!lineCommentNoBeautify && !isFormattingModeOff) + enhancer->enhance(beautifiedLine, isInNamespace, isInPreprocessorBeautify, isInBeautifySQL); + horstmannIndentChars = 0; + lineCommentNoBeautify = lineCommentNoIndent; + lineCommentNoIndent = false; + isInIndentablePreproc = isIndentableProprocessor; + isIndentableProprocessor = false; + isElseHeaderIndent = elseHeaderFollowsComments; + isCaseHeaderCommentIndent = caseHeaderFollowsComments; + objCColonAlignSubsequent = objCColonAlign; + if (isCharImmediatelyPostNonInStmt) + { + isNonInStatementArray = false; + isCharImmediatelyPostNonInStmt = false; + } + isInPreprocessorBeautify = isInPreprocessor; // used by ASEnhancer + isInBeautifySQL = isInExecSQL; // used by ASEnhancer + } + + prependEmptyLine = false; + assert(computeChecksumOut(beautifiedLine)); + return beautifiedLine; +} + +/** + * check if there are any indented lines ready to be read by nextLine() + * + * @return are there any indented lines ready? + */ +bool ASFormatter::hasMoreLines() const +{ + return !endOfCodeReached; +} + +/** + * comparison function for BracketType enum + */ +bool ASFormatter::isBracketType(BracketType a, BracketType b) const +{ + if (a == NULL_TYPE || b == NULL_TYPE) + return (a == b); + return ((a & b) == b); +} + +/** + * set the formatting style. + * + * @param style the formatting style. + */ +void ASFormatter::setFormattingStyle(FormatStyle style) +{ + formattingStyle = style; +} + +/** + * set the add brackets mode. + * options: + * true brackets added to headers for single line statements. + * false brackets NOT added to headers for single line statements. + * + * @param state the add brackets state. + */ +void ASFormatter::setAddBracketsMode(bool state) +{ + shouldAddBrackets = state; +} + +/** + * set the add one line brackets mode. + * options: + * true one line brackets added to headers for single line statements. + * false one line brackets NOT added to headers for single line statements. + * + * @param state the add one line brackets state. + */ +void ASFormatter::setAddOneLineBracketsMode(bool state) +{ + shouldAddBrackets = state; + shouldAddOneLineBrackets = state; +} + +/** + * set the remove brackets mode. + * options: + * true brackets removed from headers for single line statements. + * false brackets NOT removed from headers for single line statements. + * + * @param state the remove brackets state. + */ +void ASFormatter::setRemoveBracketsMode(bool state) +{ + shouldRemoveBrackets = state; +} + +/** + * set the bracket formatting mode. + * options: + * + * @param mode the bracket formatting mode. + */ +void ASFormatter::setBracketFormatMode(BracketMode mode) +{ + bracketFormatMode = mode; +} + +/** + * set 'break after' mode for maximum code length + * + * @param state the 'break after' mode. + */ +void ASFormatter::setBreakAfterMode(bool state) +{ + shouldBreakLineAfterLogical = state; +} + +/** + * set closing header bracket breaking mode + * options: + * true brackets just before closing headers (e.g. 'else', 'catch') + * will be broken, even if standard brackets are attached. + * false closing header brackets will be treated as standard brackets. + * + * @param state the closing header bracket breaking mode. + */ +void ASFormatter::setBreakClosingHeaderBracketsMode(bool state) +{ + shouldBreakClosingHeaderBrackets = state; +} + +/** + * set 'else if()' breaking mode + * options: + * true 'else' headers will be broken from their succeeding 'if' headers. + * false 'else' headers will be attached to their succeeding 'if' headers. + * + * @param state the 'else if()' breaking mode. + */ +void ASFormatter::setBreakElseIfsMode(bool state) +{ + shouldBreakElseIfs = state; +} + +/** +* set comma padding mode. +* options: +* true statement commas and semicolons will be padded with spaces around them. +* false statement commas and semicolons will not be padded. +* +* @param state the padding mode. +*/ +void ASFormatter::setCommaPaddingMode(bool state) +{ + shouldPadCommas = state; +} + +/** + * set maximum code length + * + * @param max the maximum code length. + */ +void ASFormatter::setMaxCodeLength(int max) +{ + maxCodeLength = max; +} + +/** + * set operator padding mode. + * options: + * true statement operators will be padded with spaces around them. + * false statement operators will not be padded. + * + * @param state the padding mode. + */ +void ASFormatter::setOperatorPaddingMode(bool state) +{ + shouldPadOperators = state; +} + +/** + * set parenthesis outside padding mode. + * options: + * true statement parentheses will be padded with spaces around them. + * false statement parentheses will not be padded. + * + * @param state the padding mode. + */ +void ASFormatter::setParensOutsidePaddingMode(bool state) +{ + shouldPadParensOutside = state; +} + +/** + * set parenthesis inside padding mode. + * options: + * true statement parenthesis will be padded with spaces around them. + * false statement parenthesis will not be padded. + * + * @param state the padding mode. + */ +void ASFormatter::setParensInsidePaddingMode(bool state) +{ + shouldPadParensInside = state; +} + +/** + * set padding mode before one or more open parentheses. + * options: + * true first open parenthesis will be padded with a space before. + * false first open parenthesis will not be padded. + * + * @param state the padding mode. + */ +void ASFormatter::setParensFirstPaddingMode(bool state) +{ + shouldPadFirstParen = state; +} + +/** + * set header padding mode. + * options: + * true headers will be padded with spaces around them. + * false headers will not be padded. + * + * @param state the padding mode. + */ +void ASFormatter::setParensHeaderPaddingMode(bool state) +{ + shouldPadHeader = state; +} + +/** + * set parenthesis unpadding mode. + * options: + * true statement parenthesis will be unpadded with spaces removed around them. + * false statement parenthesis will not be unpadded. + * + * @param state the padding mode. + */ +void ASFormatter::setParensUnPaddingMode(bool state) +{ + shouldUnPadParens = state; +} + +/** +* set the state of the preprocessor indentation option. +* If true, #ifdef blocks at level 0 will be indented. +* +* @param state state of option. +*/ +void ASFormatter::setPreprocBlockIndent(bool state) +{ + shouldIndentPreprocBlock = state; +} + +/** + * Set strip comment prefix mode. + * options: + * true strip leading '*' in a comment. + * false leading '*' in a comment will be left unchanged. + * + * @param state the strip comment prefix mode. + */ +void ASFormatter::setStripCommentPrefix(bool state) +{ + shouldStripCommentPrefix = state; +} + +/** + * set objective-c '-' or '+' class prefix padding mode. + * options: + * true class prefix will be padded a spaces after them. + * false class prefix will be left unchanged. + * + * @param state the padding mode. + */ +void ASFormatter::setMethodPrefixPaddingMode(bool state) +{ + shouldPadMethodPrefix = state; +} + +/** + * set objective-c '-' or '+' class prefix unpadding mode. + * options: + * true class prefix will be unpadded with spaces after them removed. + * false class prefix will left unchanged. + * + * @param state the unpadding mode. + */ +void ASFormatter::setMethodPrefixUnPaddingMode(bool state) +{ + shouldUnPadMethodPrefix = state; +} + +// set objective-c '-' or '+' return type padding mode. +void ASFormatter::setReturnTypePaddingMode(bool state) +{ + shouldPadReturnType = state; +} + +// set objective-c '-' or '+' return type unpadding mode. +void ASFormatter::setReturnTypeUnPaddingMode(bool state) +{ + shouldUnPadReturnType = state; +} + +/** + * set objective-c method colon padding mode. + * + * @param mode objective-c colon padding mode. + */ +void ASFormatter::setObjCColonPaddingMode(ObjCColonPad mode) +{ + shouldPadMethodColon = true; + objCColonPadMode = mode; +} + +/** + * set option to attach closing brackets + * + * @param state true = attach, false = don't attach. + */ +void ASFormatter::setAttachClosingBracketMode(bool state) +{ + attachClosingBracketMode = state; +} + +/** + * set option to attach class brackets + * + * @param state true = attach, false = use style default. + */ +void ASFormatter::setAttachClass(bool state) +{ + shouldAttachClass = state; +} + +/** + * set option to attach extern "C" brackets + * + * @param state true = attach, false = use style default. + */ +void ASFormatter::setAttachExternC(bool state) +{ + shouldAttachExternC = state; +} + +/** + * set option to attach namespace brackets + * + * @param state true = attach, false = use style default. + */ +void ASFormatter::setAttachNamespace(bool state) +{ + shouldAttachNamespace = state; +} + +/** + * set option to attach inline brackets + * + * @param state true = attach, false = use style default. + */ +void ASFormatter::setAttachInline(bool state) +{ + shouldAttachInline = state; +} + +/** + * set option to break/not break one-line blocks + * + * @param state true = break, false = don't break. + */ +void ASFormatter::setBreakOneLineBlocksMode(bool state) +{ + shouldBreakOneLineBlocks = state; +} + +void ASFormatter::setCloseTemplatesMode(bool state) +{ + shouldCloseTemplates = state; +} + +/** + * set option to break/not break lines consisting of multiple statements. + * + * @param state true = break, false = don't break. + */ +void ASFormatter::setSingleStatementsMode(bool state) +{ + shouldBreakOneLineStatements = state; +} + +/** + * set option to convert tabs to spaces. + * + * @param state true = convert, false = don't convert. + */ +void ASFormatter::setTabSpaceConversionMode(bool state) +{ + shouldConvertTabs = state; +} + +/** + * set option to indent comments in column 1. + * + * @param state true = indent, false = don't indent. + */ +void ASFormatter::setIndentCol1CommentsMode(bool state) +{ + shouldIndentCol1Comments = state; +} + +/** + * set option to force all line ends to a particular style. + * + * @param fmt format enum value + */ +void ASFormatter::setLineEndFormat(LineEndFormat fmt) +{ + lineEnd = fmt; +} + +/** + * set option to break unrelated blocks of code with empty lines. + * + * @param state true = convert, false = don't convert. + */ +void ASFormatter::setBreakBlocksMode(bool state) +{ + shouldBreakBlocks = state; +} + +/** + * set option to break closing header blocks of code (such as 'else', 'catch', ...) with empty lines. + * + * @param state true = convert, false = don't convert. + */ +void ASFormatter::setBreakClosingHeaderBlocksMode(bool state) +{ + shouldBreakClosingHeaderBlocks = state; +} + +/** + * set option to delete empty lines. + * + * @param state true = delete, false = don't delete. + */ +void ASFormatter::setDeleteEmptyLinesMode(bool state) +{ + shouldDeleteEmptyLines = state; +} + +/** + * set the pointer alignment. + * + * @param alignment the pointer alignment. + */ +void ASFormatter::setPointerAlignment(PointerAlign alignment) +{ + pointerAlignment = alignment; +} + +void ASFormatter::setReferenceAlignment(ReferenceAlign alignment) +{ + referenceAlignment = alignment; +} + +/** + * jump over several characters. + * + * @param i the number of characters to jump over. + */ +void ASFormatter::goForward(int i) +{ + while (--i >= 0) + getNextChar(); +} + +/** + * peek at the next unread character. + * + * @return the next unread character. + */ +char ASFormatter::peekNextChar() const +{ + char ch = ' '; + size_t peekNum = currentLine.find_first_not_of(" \t", charNum + 1); + + if (peekNum == string::npos) + return ch; + + ch = currentLine[peekNum]; + + return ch; +} + +/** + * check if current placement is before a comment + * + * @return is before a comment. + */ +bool ASFormatter::isBeforeComment() const +{ + bool foundComment = false; + size_t peekNum = currentLine.find_first_not_of(" \t", charNum + 1); + + if (peekNum == string::npos) + return foundComment; + + foundComment = (currentLine.compare(peekNum, 2, "/*") == 0); + + return foundComment; +} + +/** + * check if current placement is before a comment or line-comment + * + * @return is before a comment or line-comment. + */ +bool ASFormatter::isBeforeAnyComment() const +{ + bool foundComment = false; + size_t peekNum = currentLine.find_first_not_of(" \t", charNum + 1); + + if (peekNum == string::npos) + return foundComment; + + foundComment = (currentLine.compare(peekNum, 2, "/*") == 0 + || currentLine.compare(peekNum, 2, "//") == 0); + + return foundComment; +} + +/** + * check if current placement is before a comment or line-comment + * if a block comment it must be at the end of the line + * + * @return is before a comment or line-comment. + */ +bool ASFormatter::isBeforeAnyLineEndComment(int startPos) const +{ + bool foundLineEndComment = false; + size_t peekNum = currentLine.find_first_not_of(" \t", startPos + 1); + + if (peekNum != string::npos) + { + if (currentLine.compare(peekNum, 2, "//") == 0) + foundLineEndComment = true; + else if (currentLine.compare(peekNum, 2, "/*") == 0) + { + // comment must be closed on this line with nothing after it + size_t endNum = currentLine.find("*/", peekNum + 2); + if (endNum != string::npos) + { + size_t nextChar = currentLine.find_first_not_of(" \t", endNum + 2); + if (nextChar == string::npos) + foundLineEndComment = true; + } + } + } + return foundLineEndComment; +} + +/** + * check if current placement is before a comment followed by a line-comment + * + * @return is before a multiple line-end comment. + */ +bool ASFormatter::isBeforeMultipleLineEndComments(int startPos) const +{ + bool foundMultipleLineEndComment = false; + size_t peekNum = currentLine.find_first_not_of(" \t", startPos + 1); + + if (peekNum != string::npos) + { + if (currentLine.compare(peekNum, 2, "/*") == 0) + { + // comment must be closed on this line with nothing after it + size_t endNum = currentLine.find("*/", peekNum + 2); + if (endNum != string::npos) + { + size_t nextChar = currentLine.find_first_not_of(" \t", endNum + 2); + if (nextChar != string::npos + && currentLine.compare(nextChar, 2, "//") == 0) + foundMultipleLineEndComment = true; + } + } + } + return foundMultipleLineEndComment; +} + +/** + * get the next character, increasing the current placement in the process. + * the new character is inserted into the variable currentChar. + * + * @return whether succeeded to receive the new character. + */ +bool ASFormatter::getNextChar() +{ + isInLineBreak = false; + previousChar = currentChar; + + if (!isWhiteSpace(currentChar)) + { + previousNonWSChar = currentChar; + if (!isInComment && !isInLineComment && !isInQuote + && !isImmediatelyPostComment + && !isImmediatelyPostLineComment + && !isInPreprocessor + && !isSequenceReached("/*") + && !isSequenceReached("//")) + previousCommandChar = currentChar; + } + + if (charNum + 1 < (int) currentLine.length() + && (!isWhiteSpace(peekNextChar()) || isInComment || isInLineComment)) + { + currentChar = currentLine[++charNum]; + + if (currentChar == '\t' && shouldConvertTabs) + convertTabToSpaces(); + + return true; + } + + // end of line has been reached + return getNextLine(); +} + +/** + * get the next line of input, increasing the current placement in the process. + * + * @param emptyLineWasDeleted an empty line was deleted. + * @return whether succeeded in reading the next line. + */ +bool ASFormatter::getNextLine(bool emptyLineWasDeleted /*false*/) +{ + if (sourceIterator->hasMoreLines()) + { + if (appendOpeningBracket) + currentLine = "{"; // append bracket that was removed from the previous line + else + { + currentLine = sourceIterator->nextLine(emptyLineWasDeleted); + assert(computeChecksumIn(currentLine)); + } + // reset variables for new line + inLineNumber++; + if (endOfAsmReached) + endOfAsmReached = isInAsmBlock = isInAsm = false; + shouldKeepLineUnbroken = false; + isInCommentStartLine = false; + isInCase = false; + isInAsmOneLine = false; + isHeaderInMultiStatementLine = false; + isInQuoteContinuation = isInVerbatimQuote | haveLineContinuationChar; + haveLineContinuationChar = false; + isImmediatelyPostEmptyLine = lineIsEmpty; + previousChar = ' '; + + if (currentLine.length() == 0) + currentLine = string(" "); // a null is inserted if this is not done + + // unless reading in the first line of the file, break a new line. + if (!isVirgin) + isInLineBreak = true; + else + isVirgin = false; + + if (isImmediatelyPostNonInStmt) + { + isCharImmediatelyPostNonInStmt = true; + isImmediatelyPostNonInStmt = false; + } + + // check if is in preprocessor before line trimming + // a blank line after a \ will remove the flag + isImmediatelyPostPreprocessor = isInPreprocessor; + if (!isInComment + && (previousNonWSChar != '\\' + || isEmptyLine(currentLine))) + isInPreprocessor = false; + + if (passedSemicolon) + isInExecSQL = false; + initNewLine(); + + currentChar = currentLine[charNum]; + if (isInHorstmannRunIn && previousNonWSChar == '{' && !isInComment) + isInLineBreak = false; + isInHorstmannRunIn = false; + + if (currentChar == '\t' && shouldConvertTabs) + convertTabToSpaces(); + + // check for an empty line inside a command bracket. + // if yes then read the next line (calls getNextLine recursively). + // must be after initNewLine. + if (shouldDeleteEmptyLines + && lineIsEmpty + && isBracketType((*bracketTypeStack)[bracketTypeStack->size() - 1], COMMAND_TYPE)) + { + if (!shouldBreakBlocks || previousNonWSChar == '{' || !commentAndHeaderFollows()) + { + isInPreprocessor = isImmediatelyPostPreprocessor; // restore + lineIsEmpty = false; + return getNextLine(true); + } + } + return true; + } + else + { + endOfCodeReached = true; + return false; + } +} + +/** + * jump over the leading white space in the current line, + * IF the line does not begin a comment or is in a preprocessor definition. + */ +void ASFormatter::initNewLine() +{ + size_t len = currentLine.length(); + size_t tabSize = getTabLength(); + charNum = 0; + + // don't trim these + if (isInQuoteContinuation + || (isInPreprocessor && !getPreprocDefineIndent())) + return; + + // SQL continuation lines must be adjusted so the leading spaces + // is equivalent to the opening EXEC SQL + if (isInExecSQL) + { + // replace leading tabs with spaces + // so that continuation indent will be spaces + size_t tabCount_ = 0; + size_t i; + for (i = 0; i < currentLine.length(); i++) + { + if (!isWhiteSpace(currentLine[i])) // stop at first text + break; + if (currentLine[i] == '\t') + { + size_t numSpaces = tabSize - ((tabCount_ + i) % tabSize); + currentLine.replace(i, 1, numSpaces, ' '); + tabCount_++; + i += tabSize - 1; + } + } + // this will correct the format if EXEC SQL is not a hanging indent + trimContinuationLine(); + return; + } + + // comment continuation lines must be adjusted so the leading spaces + // is equivalent to the opening comment + if (isInComment) + { + if (noTrimCommentContinuation) + leadingSpaces = tabIncrementIn = 0; + trimContinuationLine(); + return; + } + + // compute leading spaces + isImmediatelyPostCommentOnly = lineIsLineCommentOnly || lineEndsInCommentOnly; + lineIsCommentOnly = false; + lineIsLineCommentOnly = false; + lineEndsInCommentOnly = false; + doesLineStartComment = false; + currentLineBeginsWithBracket = false; + lineIsEmpty = false; + currentLineFirstBracketNum = string::npos; + tabIncrementIn = 0; + + // bypass whitespace at the start of a line + // preprocessor tabs are replaced later in the program + for (charNum = 0; isWhiteSpace(currentLine[charNum]) && charNum + 1 < (int) len; charNum++) + { + if (currentLine[charNum] == '\t' && !isInPreprocessor) + tabIncrementIn += tabSize - 1 - ((tabIncrementIn + charNum) % tabSize); + } + leadingSpaces = charNum + tabIncrementIn; + + if (isSequenceReached("/*")) + { + doesLineStartComment = true; + if ((int) currentLine.length() > charNum + 2 + && currentLine.find("*/", charNum + 2) != string::npos) + lineIsCommentOnly = true; + } + else if (isSequenceReached("//")) + { + lineIsLineCommentOnly = true; + } + else if (isSequenceReached("{")) + { + currentLineBeginsWithBracket = true; + currentLineFirstBracketNum = charNum; + size_t firstText = currentLine.find_first_not_of(" \t", charNum + 1); + if (firstText != string::npos) + { + if (currentLine.compare(firstText, 2, "//") == 0) + lineIsLineCommentOnly = true; + else if (currentLine.compare(firstText, 2, "/*") == 0 + || isExecSQL(currentLine, firstText)) + { + // get the extra adjustment + size_t j; + for (j = charNum + 1; j < firstText && isWhiteSpace(currentLine[j]); j++) + { + if (currentLine[j] == '\t') + tabIncrementIn += tabSize - 1 - ((tabIncrementIn + j) % tabSize); + } + leadingSpaces = j + tabIncrementIn; + if (currentLine.compare(firstText, 2, "/*") == 0) + doesLineStartComment = true; + } + } + } + else if (isWhiteSpace(currentLine[charNum]) && !(charNum + 1 < (int) currentLine.length())) + { + lineIsEmpty = true; + } + + // do not trim indented preprocessor define (except for comment continuation lines) + if (isInPreprocessor) + { + if (!doesLineStartComment) + leadingSpaces = 0; + charNum = 0; + } +} + +/** + * Append a character to the current formatted line. + * The formattedLine split points are updated. + * + * @param ch the character to append. + * @param canBreakLine if true, a registered line-break + */ +void ASFormatter::appendChar(char ch, bool canBreakLine) +{ + if (canBreakLine && isInLineBreak) + breakLine(); + + formattedLine.append(1, ch); + isImmediatelyPostCommentOnly = false; + if (maxCodeLength != string::npos) + { + // These compares reduce the frequency of function calls. + if (isOkToSplitFormattedLine()) + updateFormattedLineSplitPoints(ch); + if (formattedLine.length() > maxCodeLength) + testForTimeToSplitFormattedLine(); + } +} + +/** + * Append a string sequence to the current formatted line. + * The formattedLine split points are NOT updated. + * But the formattedLine is checked for time to split. + * + * @param sequence the sequence to append. + * @param canBreakLine if true, a registered line-break + */ +void ASFormatter::appendSequence(const string& sequence, bool canBreakLine) +{ + if (canBreakLine && isInLineBreak) + breakLine(); + formattedLine.append(sequence); + if (formattedLine.length() > maxCodeLength) + testForTimeToSplitFormattedLine(); +} + +/** + * Append an operator sequence to the current formatted line. + * The formattedLine split points are updated. + * + * @param sequence the sequence to append. + * @param canBreakLine if true, a registered line-break + */ +void ASFormatter::appendOperator(const string& sequence, bool canBreakLine) +{ + if (canBreakLine && isInLineBreak) + breakLine(); + formattedLine.append(sequence); + if (maxCodeLength != string::npos) + { + // These compares reduce the frequency of function calls. + if (isOkToSplitFormattedLine()) + updateFormattedLineSplitPointsOperator(sequence); + if (formattedLine.length() > maxCodeLength) + testForTimeToSplitFormattedLine(); + } +} + +/** + * append a space to the current formattedline, UNLESS the + * last character is already a white-space character. + */ +void ASFormatter::appendSpacePad() +{ + int len = formattedLine.length(); + if (len > 0 && !isWhiteSpace(formattedLine[len - 1])) + { + formattedLine.append(1, ' '); + spacePadNum++; + if (maxCodeLength != string::npos) + { + // These compares reduce the frequency of function calls. + if (isOkToSplitFormattedLine()) + updateFormattedLineSplitPoints(' '); + if (formattedLine.length() > maxCodeLength) + testForTimeToSplitFormattedLine(); + } + } +} + +/** + * append a space to the current formattedline, UNLESS the + * next character is already a white-space character. + */ +void ASFormatter::appendSpaceAfter() +{ + int len = currentLine.length(); + if (charNum + 1 < len && !isWhiteSpace(currentLine[charNum + 1])) + { + formattedLine.append(1, ' '); + spacePadNum++; + if (maxCodeLength != string::npos) + { + // These compares reduce the frequency of function calls. + if (isOkToSplitFormattedLine()) + updateFormattedLineSplitPoints(' '); + if (formattedLine.length() > maxCodeLength) + testForTimeToSplitFormattedLine(); + } + } +} + +/** + * register a line break for the formatted line. + */ +void ASFormatter::breakLine(bool isSplitLine /*false*/) +{ + isLineReady = true; + isInLineBreak = false; + spacePadNum = nextLineSpacePadNum; + nextLineSpacePadNum = 0; + readyFormattedLine = formattedLine; + formattedLine.erase(); + // queue an empty line prepend request if one exists + prependEmptyLine = isPrependPostBlockEmptyLineRequested; + + if (!isSplitLine) + { + formattedLineCommentNum = string::npos; + clearFormattedLineSplitPoints(); + + if (isAppendPostBlockEmptyLineRequested) + { + isAppendPostBlockEmptyLineRequested = false; + isPrependPostBlockEmptyLineRequested = true; + } + else + isPrependPostBlockEmptyLineRequested = false; + } +} + +/** + * check if the currently reached open-bracket (i.e. '{') + * opens a: + * - a definition type block (such as a class or namespace), + * - a command block (such as a method block) + * - a static array + * this method takes for granted that the current character + * is an opening bracket. + * + * @return the type of the opened block. + */ +BracketType ASFormatter::getBracketType() +{ + assert(currentChar == '{'); + + BracketType returnVal = NULL_TYPE; + + if ((previousNonWSChar == '=' + || isBracketType(bracketTypeStack->back(), ARRAY_TYPE)) + && previousCommandChar != ')') + returnVal = ARRAY_TYPE; + else if (foundPreDefinitionHeader && previousCommandChar != ')') + { + returnVal = DEFINITION_TYPE; + if (foundNamespaceHeader) + returnVal = (BracketType)(returnVal | NAMESPACE_TYPE); + else if (foundClassHeader) + returnVal = (BracketType)(returnVal | CLASS_TYPE); + else if (foundStructHeader) + returnVal = (BracketType)(returnVal | STRUCT_TYPE); + else if (foundInterfaceHeader) + returnVal = (BracketType)(returnVal | INTERFACE_TYPE); + } + else if (isInEnum) + { + returnVal = (BracketType)(ARRAY_TYPE | ENUM_TYPE); + } + else + { + bool isCommandType = (foundPreCommandHeader + || foundPreCommandMacro + || (currentHeader != NULL && isNonParenHeader) + || (previousCommandChar == ')') + || (previousCommandChar == ':' && !foundQuestionMark) + || (previousCommandChar == ';') + || ((previousCommandChar == '{' || previousCommandChar == '}') + && isPreviousBracketBlockRelated) + || (isInClassInitializer + && (!isLegalNameChar(previousNonWSChar) || foundPreCommandHeader)) + || isInObjCMethodDefinition + || isInObjCInterface + || isJavaStaticConstructor + || isSharpDelegate); + + // C# methods containing 'get', 'set', 'add', and 'remove' do NOT end with parens + if (!isCommandType && isSharpStyle() && isNextWordSharpNonParenHeader(charNum + 1)) + { + isCommandType = true; + isSharpAccessor = true; + } + + if (isInExternC) + returnVal = (isCommandType ? COMMAND_TYPE : EXTERN_TYPE); + else + returnVal = (isCommandType ? COMMAND_TYPE : ARRAY_TYPE); + } + + int foundOneLineBlock = isOneLineBlockReached(currentLine, charNum); + // this assumes each array definition is on a single line + // (foundOneLineBlock == 2) is a one line block followed by a comma + if (foundOneLineBlock == 2 && returnVal == COMMAND_TYPE) + returnVal = ARRAY_TYPE; + + if (foundOneLineBlock > 0) // found one line block + returnVal = (BracketType)(returnVal | SINGLE_LINE_TYPE); + + if (isBracketType(returnVal, ARRAY_TYPE)) + { + if (isNonInStatementArrayBracket()) + { + returnVal = (BracketType)(returnVal | ARRAY_NIS_TYPE); + isNonInStatementArray = true; + isImmediatelyPostNonInStmt = false; // in case of "},{" + nonInStatementBracket = formattedLine.length() - 1; + } + if (isUniformInitializerBracket()) + returnVal = (BracketType)(returnVal | INIT_TYPE); + } + + return returnVal; +} + +/** +* check if a colon is a class initializer separator +* +* @return whether it is a class initializer separator +*/ +bool ASFormatter::isClassInitializer() const +{ + assert(currentChar == ':'); + assert(previousChar != ':' && peekNextChar() != ':'); // not part of '::' + + // this should be similar to ASBeautifier::parseCurrentLine() + bool foundClassInitializer = false; + + if (foundQuestionMark) + { + // do nothing special + } + else if (parenStack->back() > 0) + { + // found a 'for' loop or an objective-C statement + // so do nothing special + } + else if (isInEnum) + { + // found an enum with a base-type + } + else if (isCStyle() + && !isInCase + && (previousCommandChar == ')' || foundPreCommandHeader)) + { + // found a 'class' c'tor initializer + foundClassInitializer = true; + } + return foundClassInitializer; +} + +/** + * check if a line is empty + * + * @return whether line is empty + */ +bool ASFormatter::isEmptyLine(const string& line) const +{ + return line.find_first_not_of(" \t") == string::npos; +} + +/** + * Check if the following text is "C" as in extern "C". + * + * @return whether the statement is extern "C" + */ +bool ASFormatter::isExternC() const +{ + // charNum should be at 'extern' + assert(!isWhiteSpace(currentLine[charNum])); + size_t startQuote = currentLine.find_first_of(" \t\"", charNum); + if (startQuote == string::npos) + return false; + startQuote = currentLine.find_first_not_of(" \t", startQuote); + if (startQuote == string::npos) + return false; + if (currentLine.compare(startQuote, 3, "\"C\"") != 0) + return false; + return true; +} + +/** + * Check if the currently reached '*', '&' or '^' character is + * a pointer-or-reference symbol, or another operator. + * A pointer dereference (*) or an "address of" character (&) + * counts as a pointer or reference because it is not an + * arithmetic operator. + * + * @return whether current character is a reference-or-pointer + */ +bool ASFormatter::isPointerOrReference() const +{ + assert(currentChar == '*' || currentChar == '&' || currentChar == '^'); + + if (isJavaStyle()) + return false; + + if (isCharImmediatelyPostOperator) + return false; + + // get the last legal word (may be a number) + string lastWord = getPreviousWord(currentLine, charNum); + if (lastWord.empty()) + lastWord = " "; + + // check for preceding or following numeric values + string nextText = peekNextText(currentLine.substr(charNum + 1)); + if (nextText.length() == 0) + nextText = " "; + char nextChar = nextText[0]; + if (isDigit(lastWord[0]) + || isDigit(nextChar) + || nextChar == '!' + || nextChar == '~') + return false; + + // check for multiply then a dereference (a * *b) + if (currentChar == '*' + && charNum < (int) currentLine.length() - 1 + && isWhiteSpace(currentLine[charNum + 1]) + && nextChar == '*') + return false; + + if ((foundCastOperator && nextChar == '>') + || isPointerOrReferenceVariable(lastWord)) + return true; + + if (isInClassInitializer + && previousNonWSChar != '(' + && previousNonWSChar != '{' + && previousCommandChar != ',' + && nextChar != ')' + && nextChar != '}') + return false; + + //check for rvalue reference + if (currentChar == '&' && nextChar == '&') + { + string followingText = peekNextText(currentLine.substr(charNum + 2)); + if (followingText.length() > 0 && followingText[0] == ')') + return true; + if (currentHeader != NULL || isInPotentialCalculation) + return false; + if (parenStack->back() > 0 && isBracketType(bracketTypeStack->back(), COMMAND_TYPE)) + return false; + return true; + } + if (nextChar == '*' + || previousNonWSChar == '=' + || previousNonWSChar == '(' + || previousNonWSChar == '[' + || isCharImmediatelyPostReturn + || isInTemplate + || isCharImmediatelyPostTemplate + || currentHeader == &AS_CATCH + || currentHeader == &AS_FOREACH + || currentHeader == &AS_QFOREACH) + return true; + + if (isBracketType(bracketTypeStack->back(), ARRAY_TYPE) + && isLegalNameChar(lastWord[0]) + && isLegalNameChar(nextChar) + && previousNonWSChar != ')') + { + if (isArrayOperator()) + return false; + } + + // checks on operators in parens + if (parenStack->back() > 0 + && isLegalNameChar(lastWord[0]) + && isLegalNameChar(nextChar)) + { + // if followed by an assignment it is a pointer or reference + // if followed by semicolon it is a pointer or reference in range-based for + const string* followingOperator = getFollowingOperator(); + if (followingOperator + && followingOperator != &AS_MULT + && followingOperator != &AS_BIT_AND) + { + if (followingOperator == &AS_ASSIGN || followingOperator == &AS_COLON) + return true; + else + return false; + } + + if (isBracketType(bracketTypeStack->back(), COMMAND_TYPE) + || squareBracketCount > 0) + return false; + else + return true; + } + + // checks on operators in parens with following '(' + if (parenStack->back() > 0 + && nextChar == '(' + && previousNonWSChar != ',' + && previousNonWSChar != '(' + && previousNonWSChar != '!' + && previousNonWSChar != '&' + && previousNonWSChar != '*' + && previousNonWSChar != '|') + return false; + + if (nextChar == '-' + || nextChar == '+') + { + size_t nextNum = currentLine.find_first_not_of(" \t", charNum + 1); + if (nextNum != string::npos) + { + if (currentLine.compare(nextNum, 2, "++") != 0 + && currentLine.compare(nextNum, 2, "--") != 0) + return false; + } + } + + bool isPR = (!isInPotentialCalculation + || (!isLegalNameChar(previousNonWSChar) + && !(previousNonWSChar == ')' && nextChar == '(') + && !(previousNonWSChar == ')' && currentChar == '*' && !isImmediatelyPostCast()) + && previousNonWSChar != ']') + || (!isWhiteSpace(nextChar) + && nextChar != '-' + && nextChar != '(' + && nextChar != '[' + && !isLegalNameChar(nextChar)) + ); + + return isPR; +} + +/** + * Check if the currently reached '*' or '&' character is + * a dereferenced pointer or "address of" symbol. + * NOTE: this MUST be a pointer or reference as determined by + * the function isPointerOrReference(). + * + * @return whether current character is a dereference or address of + */ +bool ASFormatter::isDereferenceOrAddressOf() const +{ + assert(currentChar == '*' || currentChar == '&' || currentChar == '^'); + + if (isCharImmediatelyPostTemplate) + return false; + + if (previousNonWSChar == '=' + || previousNonWSChar == ',' + || previousNonWSChar == '.' + || previousNonWSChar == '{' + || previousNonWSChar == '>' + || previousNonWSChar == '<' + || previousNonWSChar == '?' + || isCharImmediatelyPostLineComment + || isCharImmediatelyPostComment + || isCharImmediatelyPostReturn) + return true; + + char nextChar = peekNextChar(); + if (currentChar == '*' && nextChar == '*') + { + if (previousNonWSChar == '(') + return true; + if ((int) currentLine.length() < charNum + 2) + return true; + return false; + } + if (currentChar == '&' && nextChar == '&') + { + if (previousNonWSChar == '(' || isInTemplate) + return true; + if ((int) currentLine.length() < charNum + 2) + return true; + return false; + } + + // check first char on the line + if (charNum == (int) currentLine.find_first_not_of(" \t") + && (isBracketType(bracketTypeStack->back(), COMMAND_TYPE) + || parenStack->back() != 0)) + return true; + + string nextText = peekNextText(currentLine.substr(charNum + 1)); + if (nextText.length() > 0) + { + if (nextText[0] == ')' || nextText[0] == '>' + || nextText[0] == ',' || nextText[0] == '=') + return false; + if (nextText[0] == ';') + return true; + } + + // check for reference to a pointer *& (cannot have &*) + if ((currentChar == '*' && nextChar == '&') + || (previousNonWSChar == '*' && currentChar == '&')) + return false; + + if (!isBracketType(bracketTypeStack->back(), COMMAND_TYPE) + && parenStack->back() == 0) + return false; + + string lastWord = getPreviousWord(currentLine, charNum); + if (lastWord == "else" || lastWord == "delete") + return true; + + if (isPointerOrReferenceVariable(lastWord)) + return false; + + bool isDA = (!(isLegalNameChar(previousNonWSChar) || previousNonWSChar == '>') + || (nextText.length() > 0 && !isLegalNameChar(nextText[0]) && nextText[0] != '/') + || (ispunct((unsigned char)previousNonWSChar) && previousNonWSChar != '.') + || isCharImmediatelyPostReturn); + + return isDA; +} + +/** + * Check if the currently reached '*' or '&' character is + * centered with one space on each side. + * Only spaces are checked, not tabs. + * If true then a space will be deleted on the output. + * + * @return whether current character is centered. + */ +bool ASFormatter::isPointerOrReferenceCentered() const +{ + assert(currentChar == '*' || currentChar == '&' || currentChar == '^'); + + int prNum = charNum; + int lineLength = (int) currentLine.length(); + + // check for end of line + if (peekNextChar() == ' ') + return false; + + // check space before + if (prNum < 1 + || currentLine[prNum - 1] != ' ') + return false; + + // check no space before that + if (prNum < 2 + || currentLine[prNum - 2] == ' ') + return false; + + // check for ** or && + if (prNum + 1 < lineLength + && (currentLine[prNum + 1] == '*' || currentLine[prNum + 1] == '&')) + prNum++; + + // check space after + if (prNum + 1 <= lineLength + && currentLine[prNum + 1] != ' ') + return false; + + // check no space after that + if (prNum + 2 < lineLength + && currentLine[prNum + 2] == ' ') + return false; + + return true; +} + +/** + * Check if a word is a pointer or reference variable type. + * + * @return whether word is a pointer or reference variable. + */ +bool ASFormatter::isPointerOrReferenceVariable(string& word) const +{ + if (word == "char" + || word == "int" + || word == "void" + || (word.length() >= 6 // check end of word for _t + && word.compare(word.length() - 2, 2, "_t") == 0) + || word == "INT" + || word == "VOID") + return true; + return false; +} + +/** + * check if the currently reached '+' or '-' character is a unary operator + * this method takes for granted that the current character + * is a '+' or '-'. + * + * @return whether the current '+' or '-' is a unary operator. + */ +bool ASFormatter::isUnaryOperator() const +{ + assert(currentChar == '+' || currentChar == '-'); + + return ((isCharImmediatelyPostReturn || !isLegalNameChar(previousCommandChar)) + && previousCommandChar != '.' + && previousCommandChar != '\"' + && previousCommandChar != '\'' + && previousCommandChar != ')' + && previousCommandChar != ']'); +} + +/** + * check if the currently reached comment is in a 'switch' statement + * + * @return whether the current '+' or '-' is in an exponent. + */ +bool ASFormatter::isInSwitchStatement() const +{ + assert(isInLineComment || isInComment); + if (preBracketHeaderStack->size() > 0) + for (size_t i = 1; i < preBracketHeaderStack->size(); i++) + if (preBracketHeaderStack->at(i) == &AS_SWITCH) + return true; + return false; +} + +/** + * check if the currently reached '+' or '-' character is + * part of an exponent, i.e. 0.2E-5. + * + * @return whether the current '+' or '-' is in an exponent. + */ +bool ASFormatter::isInExponent() const +{ + assert(currentChar == '+' || currentChar == '-'); + + int formattedLineLength = formattedLine.length(); + if (formattedLineLength >= 2) + { + char prevPrevFormattedChar = formattedLine[formattedLineLength - 2]; + char prevFormattedChar = formattedLine[formattedLineLength - 1]; + + return ((prevFormattedChar == 'e' || prevFormattedChar == 'E') + && (prevPrevFormattedChar == '.' || isDigit(prevPrevFormattedChar))); + } + else + return false; +} + +/** + * check if an array bracket should NOT have an in-statement indent + * + * @return the array is non in-statement + */ +bool ASFormatter::isNonInStatementArrayBracket() const +{ + bool returnVal = false; + char nextChar = peekNextChar(); + // if this opening bracket begins the line there will be no inStatement indent + if (currentLineBeginsWithBracket + && charNum == (int) currentLineFirstBracketNum + && nextChar != '}') + returnVal = true; + // if an opening bracket ends the line there will be no inStatement indent + if (isWhiteSpace(nextChar) + || isBeforeAnyLineEndComment(charNum) + || nextChar == '{') + returnVal = true; + + // Java "new Type [] {...}" IS an inStatement indent + if (isJavaStyle() && previousNonWSChar == ']') + returnVal = false; + + return returnVal; +} + +/** + * check if a one-line bracket has been reached, + * i.e. if the currently reached '{' character is closed + * with a complimentary '}' elsewhere on the current line, + *. + * @return 0 = one-line bracket has not been reached. + * 1 = one-line bracket has been reached. + * 2 = one-line bracket has been reached and is followed by a comma. + */ +int ASFormatter::isOneLineBlockReached(string& line, int startChar) const +{ + assert(line[startChar] == '{'); + + bool isInComment_ = false; + bool isInQuote_ = false; + int bracketCount = 1; + int lineLength = line.length(); + char quoteChar_ = ' '; + char ch = ' '; + char prevCh = ' '; + + for (int i = startChar + 1; i < lineLength; ++i) + { + ch = line[i]; + + if (isInComment_) + { + if (line.compare(i, 2, "*/") == 0) + { + isInComment_ = false; + ++i; + } + continue; + } + + if (ch == '\\') + { + ++i; + continue; + } + + if (isInQuote_) + { + if (ch == quoteChar_) + isInQuote_ = false; + continue; + } + + if (ch == '"' + || (ch == '\'' && !isDigitSeparator(line, i))) + { + isInQuote_ = true; + quoteChar_ = ch; + continue; + } + + if (line.compare(i, 2, "//") == 0) + break; + + if (line.compare(i, 2, "/*") == 0) + { + isInComment_ = true; + ++i; + continue; + } + + if (ch == '{') + ++bracketCount; + else if (ch == '}') + --bracketCount; + + if (bracketCount == 0) + { + // is this an array? + if (parenStack->back() == 0 && prevCh != '}') + { + size_t peekNum = line.find_first_not_of(" \t", i + 1); + if (peekNum != string::npos && line[peekNum] == ',') + return 2; + } + return 1; + } + if (!isWhiteSpace(ch)) + prevCh = ch; + } + + return 0; +} + +/** + * peek at the next word to determine if it is a C# non-paren header. + * will look ahead in the input file if necessary. + * + * @param startChar position on currentLine to start the search + * @return true if the next word is get or set. + */ +bool ASFormatter::isNextWordSharpNonParenHeader(int startChar) const +{ + // look ahead to find the next non-comment text + string nextText = peekNextText(currentLine.substr(startChar)); + if (nextText.length() == 0) + return false; + if (nextText[0] == '[') + return true; + if (!isCharPotentialHeader(nextText, 0)) + return false; + if (findKeyword(nextText, 0, AS_GET) || findKeyword(nextText, 0, AS_SET) + || findKeyword(nextText, 0, AS_ADD) || findKeyword(nextText, 0, AS_REMOVE)) + return true; + return false; +} + +/** + * peek at the next char to determine if it is an opening bracket. + * will look ahead in the input file if necessary. + * this determines a java static constructor. + * + * @param startChar position on currentLine to start the search + * @return true if the next word is an opening bracket. + */ +bool ASFormatter::isNextCharOpeningBracket(int startChar) const +{ + bool retVal = false; + string nextText = peekNextText(currentLine.substr(startChar)); + if (nextText.length() > 0 + && nextText.compare(0, 1, "{") == 0) + retVal = true; + return retVal; +} + +/** +* Check if operator and, pointer, and reference padding is disabled. +* Disabling is done thru a NOPAD tag in an ending comment. +* +* @return true if the formatting on this line is disabled. +*/ +bool ASFormatter::isOperatorPaddingDisabled() const +{ + size_t commentStart = currentLine.find("//", charNum); + if (commentStart == string::npos) + { + commentStart = currentLine.find("/*", charNum); + // comment must end on this line + if (commentStart != string::npos) + { + size_t commentEnd = currentLine.find("*/", commentStart + 2); + if (commentEnd == string::npos) + commentStart = string::npos; + } + } + if (commentStart == string::npos) + return false; + size_t noPadStart = currentLine.find("*NOPAD*", commentStart); + if (noPadStart == string::npos) + return false; + return true; +} + +/** +* Determine if an opening array-type bracket should have a leading space pad. +* This is to identify C++11 uniform initializers. +*/ +bool ASFormatter::isUniformInitializerBracket() const +{ + if (isCStyle() && !isInEnum && !isImmediatelyPostPreprocessor) + { + if (isInClassInitializer + || isLegalNameChar(previousNonWSChar)) + return true; + } + return false; +} + +/** + * get the next non-whitespace substring on following lines, bypassing all comments. + * + * @param firstLine the first line to check + * @return the next non-whitespace substring. + */ +string ASFormatter::peekNextText(const string& firstLine, bool endOnEmptyLine /*false*/, bool shouldReset /*false*/) const +{ + bool isFirstLine = true; + bool needReset = shouldReset; + string nextLine_ = firstLine; + size_t firstChar = string::npos; + + // find the first non-blank text, bypassing all comments. + bool isInComment_ = false; + while (sourceIterator->hasMoreLines() || isFirstLine) + { + if (isFirstLine) + isFirstLine = false; + else + { + nextLine_ = sourceIterator->peekNextLine(); + needReset = true; + } + + firstChar = nextLine_.find_first_not_of(" \t"); + if (firstChar == string::npos) + { + if (endOnEmptyLine && !isInComment_) + break; + continue; + } + + if (nextLine_.compare(firstChar, 2, "/*") == 0) + { + firstChar += 2; + isInComment_ = true; + } + + if (isInComment_) + { + firstChar = nextLine_.find("*/", firstChar); + if (firstChar == string::npos) + continue; + firstChar += 2; + isInComment_ = false; + firstChar = nextLine_.find_first_not_of(" \t", firstChar); + if (firstChar == string::npos) + continue; + } + + if (nextLine_.compare(firstChar, 2, "//") == 0) + continue; + + // found the next text + break; + } + + if (firstChar == string::npos) + nextLine_ = ""; + else + nextLine_ = nextLine_.substr(firstChar); + if (needReset) + sourceIterator->peekReset(); + return nextLine_; +} + +/** + * adjust comment position because of adding or deleting spaces + * the spaces are added or deleted to formattedLine + * spacePadNum contains the adjustment + */ +void ASFormatter::adjustComments(void) +{ + assert(spacePadNum != 0); + assert(currentLine.compare(charNum, 2, "//") == 0 + || currentLine.compare(charNum, 2, "/*") == 0); + + // block comment must be closed on this line with nothing after it + if (currentLine.compare(charNum, 2, "/*") == 0) + { + size_t endNum = currentLine.find("*/", charNum + 2); + if (endNum == string::npos) + return; + if (currentLine.find_first_not_of(" \t", endNum + 2) != string::npos) + return; + } + + size_t len = formattedLine.length(); + // don't adjust a tab + if (formattedLine[len - 1] == '\t') + return; + // if spaces were removed, need to add spaces before the comment + if (spacePadNum < 0) + { + int adjust = -spacePadNum; // make the number positive + formattedLine.append(adjust, ' '); + } + // if spaces were added, need to delete extra spaces before the comment + // if cannot be done put the comment one space after the last text + else if (spacePadNum > 0) + { + int adjust = spacePadNum; + size_t lastText = formattedLine.find_last_not_of(' '); + if (lastText != string::npos + && lastText < len - adjust - 1) + formattedLine.resize(len - adjust); + else if (len > lastText + 2) + formattedLine.resize(lastText + 2); + else if (len < lastText + 2) + formattedLine.append(len - lastText, ' '); + } +} + +/** + * append the current bracket inside the end of line comments + * currentChar contains the bracket, it will be appended to formattedLine + * formattedLineCommentNum is the comment location on formattedLine + */ +void ASFormatter::appendCharInsideComments(void) +{ + if (formattedLineCommentNum == string::npos) // does the comment start on the previous line? + { + appendCurrentChar(); // don't attach + return; + } + assert(formattedLine.compare(formattedLineCommentNum, 2, "//") == 0 + || formattedLine.compare(formattedLineCommentNum, 2, "/*") == 0); + + // find the previous non space char + size_t end = formattedLineCommentNum; + size_t beg = formattedLine.find_last_not_of(" \t", end - 1); + if (beg == string::npos) + { + appendCurrentChar(); // don't attach + return; + } + beg++; + + // insert the bracket + if (end - beg < 3) // is there room to insert? + formattedLine.insert(beg, 3 - end + beg, ' '); + if (formattedLine[beg] == '\t') // don't pad with a tab + formattedLine.insert(beg, 1, ' '); + formattedLine[beg + 1] = currentChar; + testForTimeToSplitFormattedLine(); + + if (isBeforeComment()) + breakLine(); + else if (isCharImmediatelyPostLineComment) + shouldBreakLineAtNextChar = true; + return; +} + +/** + * add or remove space padding to operators + * the operators and necessary padding will be appended to formattedLine + * the calling function should have a continue statement after calling this method + * + * @param newOperator the operator to be padded + */ +void ASFormatter::padOperators(const string* newOperator) +{ + assert(shouldPadOperators); + assert(newOperator != NULL); + + bool shouldPad = (newOperator != &AS_SCOPE_RESOLUTION + && newOperator != &AS_PLUS_PLUS + && newOperator != &AS_MINUS_MINUS + && newOperator != &AS_NOT + && newOperator != &AS_BIT_NOT + && newOperator != &AS_ARROW + && !(newOperator == &AS_COLON && !foundQuestionMark // objC methods + && (isInObjCMethodDefinition || isInObjCInterface + || isInObjCSelector || squareBracketCount)) + && !(newOperator == &AS_MINUS && isInExponent()) + && !((newOperator == &AS_PLUS || newOperator == &AS_MINUS) // check for unary plus or minus + && (previousNonWSChar == '(' + || previousNonWSChar == '[' + || previousNonWSChar == '=' + || previousNonWSChar == ',')) + && !(newOperator == &AS_PLUS && isInExponent()) + && !isCharImmediatelyPostOperator +//? // commented out in release 2.05.1 - doesn't seem to do anything??? +//x && !((newOperator == &AS_MULT || newOperator == &AS_BIT_AND || newOperator == &AS_AND) +//x && isPointerOrReference()) + && !(newOperator == &AS_MULT + && (previousNonWSChar == '.' + || previousNonWSChar == '>')) // check for -> + && !((isInTemplate || isImmediatelyPostTemplate) + && (newOperator == &AS_LS || newOperator == &AS_GR)) + && !(newOperator == &AS_GCC_MIN_ASSIGN + && ASBase::peekNextChar(currentLine, charNum + 1) == '>') + && !(newOperator == &AS_GR && previousNonWSChar == '?') + && !(newOperator == &AS_QUESTION // check for Java wildcard + && (previousNonWSChar == '<' + || ASBase::peekNextChar(currentLine, charNum) == '>' + || ASBase::peekNextChar(currentLine, charNum) == '.')) + && !isInCase + && !isInAsm + && !isInAsmOneLine + && !isInAsmBlock + ); + + // pad before operator + if (shouldPad + && !(newOperator == &AS_COLON + && (!foundQuestionMark && !isInEnum) && currentHeader != &AS_FOR) + && !(newOperator == &AS_QUESTION && isSharpStyle() // check for C# nullable type (e.g. int?) + && currentLine.find(':', charNum + 1) == string::npos) + ) + appendSpacePad(); + appendOperator(*newOperator); + goForward(newOperator->length() - 1); + + currentChar = (*newOperator)[newOperator->length() - 1]; + // pad after operator + // but do not pad after a '-' that is a unary-minus. + if (shouldPad + && !isBeforeAnyComment() + && !(newOperator == &AS_PLUS && isUnaryOperator()) + && !(newOperator == &AS_MINUS && isUnaryOperator()) + && !(currentLine.compare(charNum + 1, 1, AS_SEMICOLON) == 0) + && !(currentLine.compare(charNum + 1, 2, AS_SCOPE_RESOLUTION) == 0) + && !(peekNextChar() == ',') + && !(newOperator == &AS_QUESTION && isSharpStyle() // check for C# nullable type (e.g. int?) + && peekNextChar() == '[') + ) + appendSpaceAfter(); + + previousOperator = newOperator; + return; +} + +/** + * format pointer or reference + * currentChar contains the pointer or reference + * the symbol and necessary padding will be appended to formattedLine + * the calling function should have a continue statement after calling this method + * + * NOTE: Do NOT use appendCurrentChar() in this method. The line should not be + * broken once the calculation starts. + */ +void ASFormatter::formatPointerOrReference(void) +{ + assert(currentChar == '*' || currentChar == '&' || currentChar == '^'); + assert(!isJavaStyle()); + + int pa = pointerAlignment; + int ra = referenceAlignment; + int itemAlignment = (currentChar == '*' || currentChar == '^') ? pa : ((ra == REF_SAME_AS_PTR) ? pa : ra); + + // check for ** and && + char peekedChar = peekNextChar(); + if ((currentChar == '*' && peekedChar == '*') + || (currentChar == '&' && peekedChar == '&')) + { + size_t nextChar = currentLine.find_first_not_of(" \t", charNum + 2); + if (nextChar == string::npos) + peekedChar = ' '; + else + peekedChar = currentLine[nextChar]; + } + // check for cast + if (peekedChar == ')' || peekedChar == '>' || peekedChar == ',') + { + formatPointerOrReferenceCast(); + return; + } + + // check for a padded space and remove it + if (charNum > 0 + && !isWhiteSpace(currentLine[charNum - 1]) + && formattedLine.length() > 0 + && isWhiteSpace(formattedLine[formattedLine.length() - 1])) + { + formattedLine.erase(formattedLine.length() - 1); + spacePadNum--; + } + + if (itemAlignment == PTR_ALIGN_TYPE) + { + formatPointerOrReferenceToType(); + } + else if (itemAlignment == PTR_ALIGN_MIDDLE) + { + formatPointerOrReferenceToMiddle(); + } + else if (itemAlignment == PTR_ALIGN_NAME) + { + formatPointerOrReferenceToName(); + } + else // pointerAlignment == PTR_ALIGN_NONE + { + formattedLine.append(1, currentChar); + } +} + +/** + * format pointer or reference with align to type + */ +void ASFormatter::formatPointerOrReferenceToType() +{ + assert(currentChar == '*' || currentChar == '&' || currentChar == '^'); + assert(!isJavaStyle()); + + // do this before bumping charNum + bool isOldPRCentered = isPointerOrReferenceCentered(); + + size_t prevCh = formattedLine.find_last_not_of(" \t"); + if (prevCh == string::npos) + prevCh = 0; + if (formattedLine.length() == 0 || prevCh == formattedLine.length() - 1) + formattedLine.append(1, currentChar); + else + { + // exchange * or & with character following the type + // this may not work every time with a tab character + string charSave = formattedLine.substr(prevCh + 1, 1); + formattedLine[prevCh + 1] = currentChar; + formattedLine.append(charSave); + } + if (isSequenceReached("**") || isSequenceReached("&&")) + { + if (formattedLine.length() == 1) + formattedLine.append(1, currentChar); + else + formattedLine.insert(prevCh + 2, 1, currentChar); + goForward(1); + } + // if no space after then add one + if (charNum < (int) currentLine.length() - 1 + && !isWhiteSpace(currentLine[charNum + 1]) + && currentLine[charNum + 1] != ')') + appendSpacePad(); + // if old pointer or reference is centered, remove a space + if (isOldPRCentered + && isWhiteSpace(formattedLine[formattedLine.length() - 1])) + { + formattedLine.erase(formattedLine.length() - 1, 1); + spacePadNum--; + } + // update the formattedLine split point + if (maxCodeLength != string::npos) + { + size_t index = formattedLine.length() - 1; + if (isWhiteSpace(formattedLine[index])) + { + updateFormattedLineSplitPointsPointerOrReference(index); + testForTimeToSplitFormattedLine(); + } + } +} + +/** + * format pointer or reference with align in the middle + */ +void ASFormatter::formatPointerOrReferenceToMiddle() +{ + assert(currentChar == '*' || currentChar == '&' || currentChar == '^'); + assert(!isJavaStyle()); + + // compute current whitespace before + size_t wsBefore = currentLine.find_last_not_of(" \t", charNum - 1); + if (wsBefore == string::npos) + wsBefore = 0; + else + wsBefore = charNum - wsBefore - 1; + string sequenceToInsert(1, currentChar); + if (isSequenceReached("**")) + { + sequenceToInsert = "**"; + goForward(1); + } + else if (isSequenceReached("&&")) + { + sequenceToInsert = "&&"; + goForward(1); + } + // if reference to a pointer check for conflicting alignment + else if (currentChar == '*' && peekNextChar() == '&' + && (referenceAlignment == REF_ALIGN_TYPE + || referenceAlignment == REF_ALIGN_MIDDLE + || referenceAlignment == REF_SAME_AS_PTR)) + { + sequenceToInsert = "*&"; + goForward(1); + for (size_t i = charNum; i < currentLine.length() - 1 && isWhiteSpace(currentLine[i]); i++) + goForward(1); + } + // if a comment follows don't align, just space pad + if (isBeforeAnyComment()) + { + appendSpacePad(); + formattedLine.append(sequenceToInsert); + appendSpaceAfter(); + return; + } + // do this before goForward() + bool isAfterScopeResolution = previousNonWSChar == ':'; + size_t charNumSave = charNum; + // if this is the last thing on the line + if (currentLine.find_first_not_of(" \t", charNum + 1) == string::npos) + { + if (wsBefore == 0 && !isAfterScopeResolution) + formattedLine.append(1, ' '); + formattedLine.append(sequenceToInsert); + return; + } + // goForward() to convert tabs to spaces, if necessary, + // and move following characters to preceding characters + // this may not work every time with tab characters + for (size_t i = charNum + 1; i < currentLine.length() && isWhiteSpace(currentLine[i]); i++) + { + goForward(1); + if (formattedLine.length() > 0) + formattedLine.append(1, currentLine[i]); + else + spacePadNum--; + } + // find space padding after + size_t wsAfter = currentLine.find_first_not_of(" \t", charNumSave + 1); + if (wsAfter == string::npos || isBeforeAnyComment()) + wsAfter = 0; + else + wsAfter = wsAfter - charNumSave - 1; + // don't pad before scope resolution operator, but pad after + if (isAfterScopeResolution) + { + size_t lastText = formattedLine.find_last_not_of(" \t"); + formattedLine.insert(lastText + 1, sequenceToInsert); + appendSpacePad(); + } + else if (formattedLine.length() > 0) + { + // whitespace should be at least 2 chars to center + if (wsBefore + wsAfter < 2) + { + size_t charsToAppend = (2 - (wsBefore + wsAfter)); + formattedLine.append(charsToAppend, ' '); + spacePadNum += charsToAppend; + if (wsBefore == 0) wsBefore++; + if (wsAfter == 0) wsAfter++; + } + // insert the pointer or reference char + size_t padAfter = (wsBefore + wsAfter) / 2; + size_t index = formattedLine.length() - padAfter; + formattedLine.insert(index, sequenceToInsert); + } + else // formattedLine.length() == 0 + { + formattedLine.append(sequenceToInsert); + if (wsAfter == 0) + wsAfter++; + formattedLine.append(wsAfter, ' '); + spacePadNum += wsAfter; + } + // update the formattedLine split point after the pointer + if (maxCodeLength != string::npos && formattedLine.length() > 0) + { + size_t index = formattedLine.find_last_not_of(" \t"); + if (index != string::npos && (index < formattedLine.length() - 1)) + { + index++; + updateFormattedLineSplitPointsPointerOrReference(index); + testForTimeToSplitFormattedLine(); + } + } +} + +/** + * format pointer or reference with align to name + */ +void ASFormatter::formatPointerOrReferenceToName() +{ + assert(currentChar == '*' || currentChar == '&' || currentChar == '^'); + assert(!isJavaStyle()); + + // do this before bumping charNum + bool isOldPRCentered = isPointerOrReferenceCentered(); + + size_t startNum = formattedLine.find_last_not_of(" \t"); + if (startNum == string::npos) + startNum = 0; + string sequenceToInsert(1, currentChar); + if (isSequenceReached("**")) + { + sequenceToInsert = "**"; + goForward(1); + } + else if (isSequenceReached("&&")) + { + sequenceToInsert = "&&"; + goForward(1); + } + // if reference to a pointer align both to name + else if (currentChar == '*' && peekNextChar() == '&') + { + sequenceToInsert = "*&"; + goForward(1); + for (size_t i = charNum; i < currentLine.length() - 1 && isWhiteSpace(currentLine[i]); i++) + goForward(1); + } + char peekedChar = peekNextChar(); + bool isAfterScopeResolution = previousNonWSChar == ':'; // check for :: + // if this is not the last thing on the line + if (!isBeforeAnyComment() + && (int) currentLine.find_first_not_of(" \t", charNum + 1) > charNum) + { + // goForward() to convert tabs to spaces, if necessary, + // and move following characters to preceding characters + // this may not work every time with tab characters + for (size_t i = charNum + 1; i < currentLine.length() && isWhiteSpace(currentLine[i]); i++) + { + // if a padded paren follows don't move + if (shouldPadParensOutside && peekedChar == '(' && !isOldPRCentered) + { + // empty parens don't count + size_t start = currentLine.find_first_not_of("( \t", charNum + 1); + if (start != string::npos && currentLine[start] != ')') + break; + } + goForward(1); + if (formattedLine.length() > 0) + formattedLine.append(1, currentLine[i]); + else + spacePadNum--; + } + } + // don't pad before scope resolution operator + if (isAfterScopeResolution) + { + size_t lastText = formattedLine.find_last_not_of(" \t"); + if (lastText != string::npos && lastText + 1 < formattedLine.length()) + formattedLine.erase(lastText + 1); + } + // if no space before * then add one + else if (formattedLine.length() > 0 + && (formattedLine.length() <= startNum + 1 + || !isWhiteSpace(formattedLine[startNum + 1]))) + { + formattedLine.insert(startNum + 1, 1, ' '); + spacePadNum++; + } + appendSequence(sequenceToInsert, false); + // if old pointer or reference is centered, remove a space + if (isOldPRCentered + && formattedLine.length() > startNum + 1 + && isWhiteSpace(formattedLine[startNum + 1]) + && !isBeforeAnyComment()) + { + formattedLine.erase(startNum + 1, 1); + spacePadNum--; + } + // don't convert to *= or &= + if (peekedChar == '=') + { + appendSpaceAfter(); + // if more than one space before, delete one + if (formattedLine.length() > startNum + && isWhiteSpace(formattedLine[startNum + 1]) + && isWhiteSpace(formattedLine[startNum + 2])) + { + formattedLine.erase(startNum + 1, 1); + spacePadNum--; + } + } + // update the formattedLine split point + if (maxCodeLength != string::npos) + { + size_t index = formattedLine.find_last_of(" \t"); + if (index != string::npos + && index < formattedLine.length() - 1 + && (formattedLine[index + 1] == '*' + || formattedLine[index + 1] == '&' + || formattedLine[index + 1] == '^')) + { + updateFormattedLineSplitPointsPointerOrReference(index); + testForTimeToSplitFormattedLine(); + } + } +} + +/** + * format pointer or reference cast + * currentChar contains the pointer or reference + * NOTE: the pointers and references in function definitions + * are processed as a cast (e.g. void foo(void*, void*)) + * is processed here. + */ +void ASFormatter::formatPointerOrReferenceCast(void) +{ + assert(currentChar == '*' || currentChar == '&' || currentChar == '^'); + assert(!isJavaStyle()); + + int pa = pointerAlignment; + int ra = referenceAlignment; + int itemAlignment = (currentChar == '*' || currentChar == '^') ? pa : ((ra == REF_SAME_AS_PTR) ? pa : ra); + + string sequenceToInsert(1, currentChar); + if (isSequenceReached("**") || isSequenceReached("&&")) + { + goForward(1); + sequenceToInsert.append(1, currentLine[charNum]); + } + if (itemAlignment == PTR_ALIGN_NONE) + { + appendSequence(sequenceToInsert, false); + return; + } + // remove preceding whitespace + char prevCh = ' '; + size_t prevNum = formattedLine.find_last_not_of(" \t"); + if (prevNum != string::npos) + { + prevCh = formattedLine[prevNum]; + if (prevNum + 1 < formattedLine.length() + && isWhiteSpace(formattedLine[prevNum + 1]) + && prevCh != '(') + { + spacePadNum -= (formattedLine.length() - 1 - prevNum); + formattedLine.erase(prevNum + 1); + } + } + bool isAfterScopeResolution = previousNonWSChar == ':'; + if ((itemAlignment == PTR_ALIGN_MIDDLE || itemAlignment == PTR_ALIGN_NAME) + && !isAfterScopeResolution && prevCh != '(') + { + appendSpacePad(); + // in this case appendSpacePad may or may not update the split point + if (maxCodeLength != string::npos && formattedLine.length() > 0) + updateFormattedLineSplitPointsPointerOrReference(formattedLine.length() - 1); + appendSequence(sequenceToInsert, false); + } + else + appendSequence(sequenceToInsert, false); +} + +/** + * add or remove space padding to parens + * currentChar contains the paren + * the parens and necessary padding will be appended to formattedLine + * the calling function should have a continue statement after calling this method + */ +void ASFormatter::padParens(void) +{ + assert(currentChar == '(' || currentChar == ')'); + assert(shouldPadParensOutside || shouldPadParensInside || shouldUnPadParens || shouldPadFirstParen); + + int spacesOutsideToDelete = 0; + int spacesInsideToDelete = 0; + + if (currentChar == '(') + { + spacesOutsideToDelete = formattedLine.length() - 1; + spacesInsideToDelete = 0; + + // compute spaces outside the opening paren to delete + if (shouldUnPadParens) + { + char lastChar = ' '; + bool prevIsParenHeader = false; + size_t i = formattedLine.find_last_not_of(" \t"); + if (i != string::npos) + { + // if last char is a bracket the previous whitespace is an indent + if (formattedLine[i] == '{') + spacesOutsideToDelete = 0; + else if (isCharImmediatelyPostPointerOrReference) + spacesOutsideToDelete = 0; + else + { + spacesOutsideToDelete -= i; + lastChar = formattedLine[i]; + // if previous word is a header, it will be a paren header + string prevWord = getPreviousWord(formattedLine, formattedLine.length()); + const string* prevWordH = NULL; + if (shouldPadHeader + && prevWord.length() > 0 + && isCharPotentialHeader(prevWord, 0)) + prevWordH = ASBeautifier::findHeader(prevWord, 0, headers); + if (prevWordH != NULL) + prevIsParenHeader = true; + else if (prevWord == "return") // don't unpad + prevIsParenHeader = true; + else if (isCStyle() && prevWord == "throw" && shouldPadHeader) // don't unpad + prevIsParenHeader = true; + else if (prevWord == "and" || prevWord == "or") // don't unpad + prevIsParenHeader = true; + // don't unpad variables + else if (prevWord == "bool" + || prevWord == "int" + || prevWord == "void" + || prevWord == "void*" + || prevWord == "char" + || prevWord == "long" + || prevWord == "double" + || prevWord == "float" + || (prevWord.length() >= 4 // check end of word for _t + && prevWord.compare(prevWord.length() - 2, 2, "_t") == 0) + || prevWord == "Int32" + || prevWord == "UInt32" + || prevWord == "Int64" + || prevWord == "UInt64" + || prevWord == "BOOL" + || prevWord == "DWORD" + || prevWord == "HWND" + || prevWord == "INT" + || prevWord == "LPSTR" + || prevWord == "VOID" + || prevWord == "LPVOID" + ) + { + prevIsParenHeader = true; + } + } + } + // do not unpad operators, but leave them if already padded + if (shouldPadParensOutside || prevIsParenHeader) + spacesOutsideToDelete--; + else if (lastChar == '|' // check for || + || lastChar == '&' // check for && + || lastChar == ',' + || (lastChar == '(' && shouldPadParensInside) + || (lastChar == '>' && !foundCastOperator) + || lastChar == '<' + || lastChar == '?' + || lastChar == ':' + || lastChar == ';' + || lastChar == '=' + || lastChar == '+' + || lastChar == '-' + || lastChar == '*' + || lastChar == '/' + || lastChar == '%' + || lastChar == '^' + ) + spacesOutsideToDelete--; + + if (spacesOutsideToDelete > 0) + { + formattedLine.erase(i + 1, spacesOutsideToDelete); + spacePadNum -= spacesOutsideToDelete; + } + } + + // pad open paren outside + char peekedCharOutside = peekNextChar(); + if (shouldPadFirstParen && previousChar != '(' && peekedCharOutside != ')') + appendSpacePad(); + else if (shouldPadParensOutside) + { + if (!(currentChar == '(' && peekedCharOutside == ')')) + appendSpacePad(); + } + + appendCurrentChar(); + + // unpad open paren inside + if (shouldUnPadParens) + { + size_t j = currentLine.find_first_not_of(" \t", charNum + 1); + if (j != string::npos) + spacesInsideToDelete = j - charNum - 1; + if (shouldPadParensInside) + spacesInsideToDelete--; + if (spacesInsideToDelete > 0) + { + currentLine.erase(charNum + 1, spacesInsideToDelete); + spacePadNum -= spacesInsideToDelete; + } + // convert tab to space if requested + if (shouldConvertTabs + && (int) currentLine.length() > charNum + 1 + && currentLine[charNum + 1] == '\t') + currentLine[charNum + 1] = ' '; + } + + // pad open paren inside + char peekedCharInside = peekNextChar(); + if (shouldPadParensInside) + if (!(currentChar == '(' && peekedCharInside == ')')) + appendSpaceAfter(); + } + else if (currentChar == ')') + { + // unpad close paren inside + if (shouldUnPadParens) + { + spacesInsideToDelete = formattedLine.length(); + size_t i = formattedLine.find_last_not_of(" \t"); + if (i != string::npos) + spacesInsideToDelete = formattedLine.length() - 1 - i; + if (shouldPadParensInside) + spacesInsideToDelete--; + if (spacesInsideToDelete > 0) + { + formattedLine.erase(i + 1, spacesInsideToDelete); + spacePadNum -= spacesInsideToDelete; + } + } + + // pad close paren inside + if (shouldPadParensInside) + if (!(previousChar == '(' && currentChar == ')')) + appendSpacePad(); + + appendCurrentChar(); + + // unpad close paren outside + // close parens outside are left unchanged + if (shouldUnPadParens) + { + //spacesOutsideToDelete = 0; + //size_t j = currentLine.find_first_not_of(" \t", charNum + 1); + //if (j != string::npos) + // spacesOutsideToDelete = j - charNum - 1; + //if (shouldPadParensOutside) + // spacesOutsideToDelete--; + + //if (spacesOutsideToDelete > 0) + //{ + // currentLine.erase(charNum + 1, spacesOutsideToDelete); + // spacePadNum -= spacesOutsideToDelete; + //} + } + + // pad close paren outside + char peekedCharOutside = peekNextChar(); + if (shouldPadParensOutside) + if (peekedCharOutside != ';' + && peekedCharOutside != ',' + && peekedCharOutside != '.' + && peekedCharOutside != '+' // check for ++ + && peekedCharOutside != '-' // check for -- + && peekedCharOutside != ']') + appendSpaceAfter(); + } + return; +} + +/** +* add or remove space padding to objective-c parens +* these options have precedence over the padParens methods +* the padParens method has already been called, this method adjusts +*/ +void ASFormatter::padParenObjC(void) +{ + // the paren was previously been written to formattedLine + assert(formattedLine[0] == '+' || formattedLine[0] == '-'); + assert(formattedLine.find('(') != string::npos + || formattedLine.find(')') != string::npos); + assert(isImmediatelyPostObjCMethodPrefix || isInObjCReturnType); + assert(shouldPadMethodPrefix || shouldUnPadMethodPrefix + || shouldPadReturnType || shouldUnPadReturnType); + + if (isImmediatelyPostObjCMethodPrefix) + { + size_t prefix = formattedLine.find_first_of("+-"); + if (prefix == string::npos) + return; + size_t paren = formattedLine.find_first_of("("); + if (paren == string::npos) + return; + int spaces = paren - prefix - 1; + if (shouldPadMethodPrefix) + { + if (spaces == 0) + { + formattedLine.insert(prefix + 1, 1, ' '); + spacePadNum += 1; + } + else if (spaces > 1) + { + formattedLine.erase(prefix + 1, spaces - 1); + spacePadNum -= spaces - 1; + } + } + // this option will be ignored if used with pad-method-prefix + else if (shouldUnPadMethodPrefix) + { + if (spaces > 0) + { + formattedLine.erase(prefix + 1, spaces); + spacePadNum -= spaces; + } + } + } + + if (isInObjCReturnType) + { + size_t nextText = currentLine.find_first_not_of(" \t", charNum + 1); + if (nextText == string::npos) + return; + int spaces = nextText - charNum - 1; + if (shouldPadReturnType) + { + if (spaces == 0) + { + // this will already be padded if pad-paren is used + if (formattedLine[formattedLine.length() - 1] != ' ') + { + formattedLine.append(" "); + spacePadNum += 1; + } + } + else if (spaces > 1) + { + // do not use goForward here + currentLine.erase(charNum + 1, spaces - 1); + spacePadNum -= spaces - 1; + } + } + // this option will be ignored if used with pad-return-type + else if (shouldUnPadReturnType) + { + // this will already be padded if pad-paren is used + if (formattedLine[formattedLine.length() - 1] == ' ') + { + spacePadNum -= formattedLine.length() - 1 - nextText; + int lastText = formattedLine.find_last_not_of(" \t"); + formattedLine.resize(lastText + 1); + } + if (spaces > 0) + { + // do not use goForward here + currentLine.erase(charNum + 1, spaces); + spacePadNum -= spaces; + } + } + } +} + +/** + * format opening bracket as attached or broken + * currentChar contains the bracket + * the brackets will be appended to the current formattedLine or a new formattedLine as necessary + * the calling function should have a continue statement after calling this method + * + * @param bracketType the type of bracket to be formatted. + */ +void ASFormatter::formatOpeningBracket(BracketType bracketType) +{ + assert(!isBracketType(bracketType, ARRAY_TYPE)); + assert(currentChar == '{'); + + parenStack->push_back(0); + + bool breakBracket = isCurrentBracketBroken(); + + if (breakBracket) + { + if (isBeforeAnyComment() && isOkToBreakBlock(bracketType)) + { + // if comment is at line end leave the comment on this line + if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBracket) + { + currentChar = ' '; // remove bracket from current line + if (parenStack->size() > 1) + parenStack->pop_back(); + currentLine[charNum] = currentChar; + appendOpeningBracket = true; // append bracket to following line + } + // else put comment after the bracket + else if (!isBeforeMultipleLineEndComments(charNum)) + breakLine(); + } + else if (!isBracketType(bracketType, SINGLE_LINE_TYPE)) + breakLine(); + else if (shouldBreakOneLineBlocks && peekNextChar() != '}') + breakLine(); + else if (!isInLineBreak) + appendSpacePad(); + + appendCurrentChar(); + + // should a following comment break from the bracket? + // must break the line AFTER the bracket + if (isBeforeComment() + && formattedLine.length() > 0 + && formattedLine[0] == '{' + && isOkToBreakBlock(bracketType) + && (bracketFormatMode == BREAK_MODE + || bracketFormatMode == LINUX_MODE + || bracketFormatMode == STROUSTRUP_MODE)) + { + shouldBreakLineAtNextChar = true; + } + } + else // attach bracket + { + // are there comments before the bracket? + if (isCharImmediatelyPostComment || isCharImmediatelyPostLineComment) + { + if (isOkToBreakBlock(bracketType) + && !(isCharImmediatelyPostComment && isCharImmediatelyPostLineComment) // don't attach if two comments on the line + && !isImmediatelyPostPreprocessor +// && peekNextChar() != '}' // don't attach { } // removed release 2.03 + && previousCommandChar != '{' // don't attach { { + && previousCommandChar != '}' // don't attach } { + && previousCommandChar != ';') // don't attach ; { + { + appendCharInsideComments(); + } + else + { + appendCurrentChar(); // don't attach + } + } + else if (previousCommandChar == '{' + || (previousCommandChar == '}' && !isInClassInitializer) + || previousCommandChar == ';') // '}' , ';' chars added for proper handling of '{' immediately after a '}' or ';' + { + appendCurrentChar(); // don't attach + } + else + { + // if a blank line precedes this don't attach + if (isEmptyLine(formattedLine)) + appendCurrentChar(); // don't attach + else if (isOkToBreakBlock(bracketType) + && !(isImmediatelyPostPreprocessor + && currentLineBeginsWithBracket)) + { + if (peekNextChar() != '}') + { + appendSpacePad(); + appendCurrentChar(false); // OK to attach + testForTimeToSplitFormattedLine(); // line length will have changed + // should a following comment attach with the bracket? + // insert spaces to reposition the comment + if (isBeforeComment() + && !isBeforeMultipleLineEndComments(charNum) + && (!isBeforeAnyLineEndComment(charNum) || currentLineBeginsWithBracket)) + { + shouldBreakLineAtNextChar = true; + currentLine.insert(charNum + 1, charNum + 1, ' '); + } + else if (!isBeforeAnyComment()) // added in release 2.03 + { + shouldBreakLineAtNextChar = true; + } + } + else + { + if (currentLineBeginsWithBracket && charNum == (int) currentLineFirstBracketNum) + { + appendSpacePad(); + appendCurrentChar(false); // attach + shouldBreakLineAtNextChar = true; + } + else + { + appendSpacePad(); + appendCurrentChar(); // don't attach + } + } + } + else + { + if (!isInLineBreak) + appendSpacePad(); + appendCurrentChar(); // don't attach + } + } + } +} + +/** + * format closing bracket + * currentChar contains the bracket + * the calling function should have a continue statement after calling this method + * + * @param bracketType the type of the opening bracket for this closing bracket. + */ +void ASFormatter::formatClosingBracket(BracketType bracketType) +{ + assert(!isBracketType(bracketType, ARRAY_TYPE)); + assert(currentChar == '}'); + + // parenStack must contain one entry + if (parenStack->size() > 1) + parenStack->pop_back(); + + // mark state of immediately after empty block + // this state will be used for locating brackets that appear immediately AFTER an empty block (e.g. '{} \n}'). + if (previousCommandChar == '{') + isImmediatelyPostEmptyBlock = true; + + if (attachClosingBracketMode) + { + // for now, namespaces and classes will be attached. Uncomment the lines below to break. + if ((isEmptyLine(formattedLine) // if a blank line precedes this + || isCharImmediatelyPostLineComment + || isCharImmediatelyPostComment + || (isImmediatelyPostPreprocessor && (int) currentLine.find_first_not_of(" \t") == charNum) +// || (isBracketType(bracketType, CLASS_TYPE) && isOkToBreakBlock(bracketType) && previousNonWSChar != '{') +// || (isBracketType(bracketType, NAMESPACE_TYPE) && isOkToBreakBlock(bracketType) && previousNonWSChar != '{') + ) + && (!isBracketType(bracketType, SINGLE_LINE_TYPE) || isOkToBreakBlock(bracketType))) + { + breakLine(); + appendCurrentChar(); // don't attach + } + else + { + if (previousNonWSChar != '{' + && (!isBracketType(bracketType, SINGLE_LINE_TYPE) || isOkToBreakBlock(bracketType))) + appendSpacePad(); + appendCurrentChar(false); // attach + } + } + else if ((!(previousCommandChar == '{' && isPreviousBracketBlockRelated)) // this '}' does not close an empty block + && isOkToBreakBlock(bracketType)) // astyle is allowed to break one line blocks + { + breakLine(); + appendCurrentChar(); + } + else + { + appendCurrentChar(); + } + + // if a declaration follows a definition, space pad + if (isLegalNameChar(peekNextChar())) + appendSpaceAfter(); + + if (shouldBreakBlocks + && currentHeader != NULL + && !isHeaderInMultiStatementLine + && parenStack->back() == 0) + { + if (currentHeader == &AS_CASE || currentHeader == &AS_DEFAULT) + { + // do not yet insert a line if "break" statement is outside the brackets + string nextText = peekNextText(currentLine.substr(charNum + 1)); + if (nextText.length() > 0 + && nextText.substr(0, 5) != "break") + isAppendPostBlockEmptyLineRequested = true; + } + else + isAppendPostBlockEmptyLineRequested = true; + } +} + +/** + * format array brackets as attached or broken + * determine if the brackets can have an inStatement indent + * currentChar contains the bracket + * the brackets will be appended to the current formattedLine or a new formattedLine as necessary + * the calling function should have a continue statement after calling this method + * + * @param bracketType the type of bracket to be formatted, must be an ARRAY_TYPE. + * @param isOpeningArrayBracket indicates if this is the opening bracket for the array block. + */ +void ASFormatter::formatArrayBrackets(BracketType bracketType, bool isOpeningArrayBracket) +{ + assert(isBracketType(bracketType, ARRAY_TYPE)); + assert(currentChar == '{' || currentChar == '}'); + + if (currentChar == '{') + { + // is this the first opening bracket in the array? + if (isOpeningArrayBracket) + { + if (bracketFormatMode == ATTACH_MODE + || bracketFormatMode == LINUX_MODE + || bracketFormatMode == STROUSTRUP_MODE) + { + // don't attach to a preprocessor directive or '\' line + if ((isImmediatelyPostPreprocessor + || (formattedLine.length() > 0 + && formattedLine[formattedLine.length() - 1] == '\\')) + && currentLineBeginsWithBracket) + { + isInLineBreak = true; + appendCurrentChar(); // don't attach + } + else if (isCharImmediatelyPostComment) + { + // TODO: attach bracket to line-end comment + appendCurrentChar(); // don't attach + } + else if (isCharImmediatelyPostLineComment && !isBracketType(bracketType, SINGLE_LINE_TYPE)) + { + appendCharInsideComments(); + } + else + { + // if a blank line precedes this don't attach + if (isEmptyLine(formattedLine)) + appendCurrentChar(); // don't attach + else + { + // if bracket is broken or not an assignment + if (currentLineBeginsWithBracket + && !isBracketType(bracketType, SINGLE_LINE_TYPE)) + { + appendSpacePad(); + appendCurrentChar(false); // OK to attach + // TODO: debug the following line + testForTimeToSplitFormattedLine(); // line length will have changed + + if (currentLineBeginsWithBracket + && (int) currentLineFirstBracketNum == charNum) + shouldBreakLineAtNextChar = true; + } + else + { + if (previousNonWSChar != '(') + { + // don't space pad C++11 uniform initialization + if (!isBracketType(bracketType, INIT_TYPE)) + appendSpacePad(); + } + appendCurrentChar(); + } + } + } + } + else if (bracketFormatMode == BREAK_MODE) + { + if (isWhiteSpace(peekNextChar())) + breakLine(); + else if (isBeforeAnyComment()) + { + // do not break unless comment is at line end + if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBracket) + { + currentChar = ' '; // remove bracket from current line + appendOpeningBracket = true; // append bracket to following line + } + } + if (!isInLineBreak && previousNonWSChar != '(') + { + // don't space pad C++11 uniform initialization + if (!isBracketType(bracketType, INIT_TYPE)) + appendSpacePad(); + } + appendCurrentChar(); + + if (currentLineBeginsWithBracket + && (int) currentLineFirstBracketNum == charNum + && !isBracketType(bracketType, SINGLE_LINE_TYPE)) + shouldBreakLineAtNextChar = true; + } + else if (bracketFormatMode == RUN_IN_MODE) + { + if (isWhiteSpace(peekNextChar())) + breakLine(); + else if (isBeforeAnyComment()) + { + // do not break unless comment is at line end + if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBracket) + { + currentChar = ' '; // remove bracket from current line + appendOpeningBracket = true; // append bracket to following line + } + } + if (!isInLineBreak && previousNonWSChar != '(') + { + // don't space pad C++11 uniform initialization + if (!isBracketType(bracketType, INIT_TYPE)) + appendSpacePad(); + } + appendCurrentChar(); + } + else if (bracketFormatMode == NONE_MODE) + { + if (currentLineBeginsWithBracket + && charNum == (int) currentLineFirstBracketNum) + { + appendCurrentChar(); // don't attach + } + else + { + if (previousNonWSChar != '(') + { + // don't space pad C++11 uniform initialization + if (!isBracketType(bracketType, INIT_TYPE)) + appendSpacePad(); + } + appendCurrentChar(false); // OK to attach + } + } + } + else // not the first opening bracket + { + if (bracketFormatMode == RUN_IN_MODE) + { + if (previousNonWSChar == '{' + && bracketTypeStack->size() > 2 + && !isBracketType((*bracketTypeStack)[bracketTypeStack->size() - 2], SINGLE_LINE_TYPE)) + formatArrayRunIn(); + } + else if (!isInLineBreak + && !isWhiteSpace(peekNextChar()) + && previousNonWSChar == '{' + && bracketTypeStack->size() > 2 + && !isBracketType((*bracketTypeStack)[bracketTypeStack->size() - 2], SINGLE_LINE_TYPE)) + formatArrayRunIn(); + + appendCurrentChar(); + } + } + else if (currentChar == '}') + { + if (attachClosingBracketMode) + { + if (isEmptyLine(formattedLine) // if a blank line precedes this + || isImmediatelyPostPreprocessor + || isCharImmediatelyPostLineComment + || isCharImmediatelyPostComment) + appendCurrentChar(); // don't attach + else + { + appendSpacePad(); + appendCurrentChar(false); // attach + } + } + else + { + // does this close the first opening bracket in the array? + // must check if the block is still a single line because of anonymous statements + if (!isBracketType(bracketType, INIT_TYPE) + && (!isBracketType(bracketType, SINGLE_LINE_TYPE) + || formattedLine.find('{') == string::npos)) + breakLine(); + appendCurrentChar(); + } + + // if a declaration follows an enum definition, space pad + char peekedChar = peekNextChar(); + if (isLegalNameChar(peekedChar) + || peekedChar == '[') + appendSpaceAfter(); + } +} + +/** + * determine if a run-in can be attached. + * if it can insert the indents in formattedLine and reset the current line break. + */ +void ASFormatter::formatRunIn() +{ + assert(bracketFormatMode == RUN_IN_MODE || bracketFormatMode == NONE_MODE); + + // keep one line blocks returns true without indenting the run-in + if (!isOkToBreakBlock(bracketTypeStack->back())) + return; // true; + + // make sure the line begins with a bracket + size_t lastText = formattedLine.find_last_not_of(" \t"); + if (lastText == string::npos || formattedLine[lastText] != '{') + return; // false; + + // make sure the bracket is broken + if (formattedLine.find_first_not_of(" \t{") != string::npos) + return; // false; + + if (isBracketType(bracketTypeStack->back(), NAMESPACE_TYPE)) + return; // false; + + bool extraIndent = false; + bool extraHalfIndent = false; + isInLineBreak = true; + + // cannot attach a class modifier without indent-classes + if (isCStyle() + && isCharPotentialHeader(currentLine, charNum) + && (isBracketType(bracketTypeStack->back(), CLASS_TYPE) + || (isBracketType(bracketTypeStack->back(), STRUCT_TYPE) + && isInIndentableStruct))) + { + if (findKeyword(currentLine, charNum, AS_PUBLIC) + || findKeyword(currentLine, charNum, AS_PRIVATE) + || findKeyword(currentLine, charNum, AS_PROTECTED)) + { + if (getModifierIndent()) + extraHalfIndent = true; + else if (!getClassIndent()) + return; // false; + } + else if (getClassIndent()) + extraIndent = true; + } + + // cannot attach a 'case' statement without indent-switches + if (!getSwitchIndent() + && isCharPotentialHeader(currentLine, charNum) + && (findKeyword(currentLine, charNum, AS_CASE) + || findKeyword(currentLine, charNum, AS_DEFAULT))) + return; // false; + + // extra indent for switch statements + if (getSwitchIndent() + && !preBracketHeaderStack->empty() + && preBracketHeaderStack->back() == &AS_SWITCH + && ((isLegalNameChar(currentChar) + && !findKeyword(currentLine, charNum, AS_CASE)))) + extraIndent = true; + + isInLineBreak = false; + // remove for extra whitespace + if (formattedLine.length() > lastText + 1 + && formattedLine.find_first_not_of(" \t", lastText + 1) == string::npos) + formattedLine.erase(lastText + 1); + + if (extraHalfIndent) + { + int indentLength_ = getIndentLength(); + horstmannIndentChars = indentLength_ / 2; + formattedLine.append(horstmannIndentChars - 1, ' '); + } + else if (getForceTabIndentation() && getIndentLength() != getTabLength()) + { + // insert the space indents + string indent; + int indentLength_ = getIndentLength(); + int tabLength_ = getTabLength(); + indent.append(indentLength_, ' '); + if (extraIndent) + indent.append(indentLength_, ' '); + // replace spaces indents with tab indents + size_t tabCount = indent.length() / tabLength_; // truncate extra spaces + indent.replace(0U, tabCount * tabLength_, tabCount, '\t'); + horstmannIndentChars = indentLength_; + if (indent[0] == ' ') // allow for bracket + indent.erase(0, 1); + formattedLine.append(indent); + } + else if (getIndentString() == "\t") + { + appendChar('\t', false); + horstmannIndentChars = 2; // one for { and one for tab + if (extraIndent) + { + appendChar('\t', false); + horstmannIndentChars++; + } + } + else // spaces + { + int indentLength_ = getIndentLength(); + formattedLine.append(indentLength_ - 1, ' '); + horstmannIndentChars = indentLength_; + if (extraIndent) + { + formattedLine.append(indentLength_, ' '); + horstmannIndentChars += indentLength_; + } + } + isInHorstmannRunIn = true; +} + +/** + * remove whitespace and add indentation for an array run-in. + */ +void ASFormatter::formatArrayRunIn() +{ + assert(isBracketType(bracketTypeStack->back(), ARRAY_TYPE)); + + // make sure the bracket is broken + if (formattedLine.find_first_not_of(" \t{") != string::npos) + return; + + size_t lastText = formattedLine.find_last_not_of(" \t"); + if (lastText == string::npos || formattedLine[lastText] != '{') + return; + + // check for extra whitespace + if (formattedLine.length() > lastText + 1 + && formattedLine.find_first_not_of(" \t", lastText + 1) == string::npos) + formattedLine.erase(lastText + 1); + + if (getIndentString() == "\t") + { + appendChar('\t', false); + horstmannIndentChars = 2; // one for { and one for tab + } + else + { + int indent = getIndentLength(); + formattedLine.append(indent - 1, ' '); + horstmannIndentChars = indent; + } + isInHorstmannRunIn = true; + isInLineBreak = false; +} + +/** + * delete a bracketTypeStack vector object + * BracketTypeStack did not work with the DeleteContainer template + */ +void ASFormatter::deleteContainer(vector*& container) +{ + if (container != NULL) + { + container->clear(); + delete (container); + container = NULL; + } +} + +/** + * delete a vector object + * T is the type of vector + * used for all vectors except bracketTypeStack + */ +template +void ASFormatter::deleteContainer(T& container) +{ + if (container != NULL) + { + container->clear(); + delete (container); + container = NULL; + } +} + +/** + * initialize a BracketType vector object + * BracketType did not work with the DeleteContainer template + */ +void ASFormatter::initContainer(vector*& container, vector* value) +{ + if (container != NULL) + deleteContainer(container); + container = value; +} + +/** + * initialize a vector object + * T is the type of vector + * used for all vectors except bracketTypeStack + */ +template +void ASFormatter::initContainer(T& container, T value) +{ + // since the ASFormatter object is never deleted, + // the existing vectors must be deleted before creating new ones + if (container != NULL) + deleteContainer(container); + container = value; +} + +/** + * convert a tab to spaces. + * charNum points to the current character to convert to spaces. + * tabIncrementIn is the increment that must be added for tab indent characters + * to get the correct column for the current tab. + * replaces the tab in currentLine with the required number of spaces. + * replaces the value of currentChar. + */ +void ASFormatter::convertTabToSpaces() +{ + assert(currentChar == '\t'); + + // do NOT replace if in quotes + if (isInQuote || isInQuoteContinuation) + return; + + size_t tabSize = getTabLength(); + size_t numSpaces = tabSize - ((tabIncrementIn + charNum) % tabSize); + currentLine.replace(charNum, 1, numSpaces, ' '); + currentChar = currentLine[charNum]; +} + +/** +* is it ok to break this block? +*/ +bool ASFormatter::isOkToBreakBlock(BracketType bracketType) const +{ + // Actually, there should not be an ARRAY_TYPE bracket here. + // But this will avoid breaking a one line block when there is. + // Otherwise they will be formatted differently on consecutive runs. + if (isBracketType(bracketType, ARRAY_TYPE) + && isBracketType(bracketType, SINGLE_LINE_TYPE)) + return false; + if (!isBracketType(bracketType, SINGLE_LINE_TYPE) + || shouldBreakOneLineBlocks + || breakCurrentOneLineBlock) + return true; + return false; +} + +/** +* check if a sharp header is a paren or non-paren header +*/ +bool ASFormatter::isSharpStyleWithParen(const string* header) const +{ + if (isSharpStyle() && peekNextChar() == '(' + && (header == &AS_CATCH + || header == &AS_DELEGATE)) + return true; + return false; +} + +/** + * Check for a following header when a comment is reached. + * firstLine must contain the start of the comment. + * return value is a pointer to the header or NULL. + */ +const string* ASFormatter::checkForHeaderFollowingComment(const string& firstLine) const +{ + assert(isInComment || isInLineComment); + assert(shouldBreakElseIfs || shouldBreakBlocks || isInSwitchStatement()); + // look ahead to find the next non-comment text + bool endOnEmptyLine = (currentHeader == NULL); + if (isInSwitchStatement()) + endOnEmptyLine = false; + string nextText = peekNextText(firstLine, endOnEmptyLine); + + if (nextText.length() == 0 || !isCharPotentialHeader(nextText, 0)) + return NULL; + + return ASBeautifier::findHeader(nextText, 0, headers); +} + +/** + * process preprocessor statements. + * charNum should be the index of the #. + * + * delete bracketTypeStack entries added by #if if a #else is found. + * prevents double entries in the bracketTypeStack. + */ +void ASFormatter::processPreprocessor() +{ + assert(currentChar == '#'); + + const size_t preproc = currentLine.find_first_not_of(" \t", charNum + 1); + + if (preproc == string::npos) + return; + + if (currentLine.compare(preproc, 2, "if") == 0) + { + preprocBracketTypeStackSize = bracketTypeStack->size(); + } + else if (currentLine.compare(preproc, 4, "else") == 0) + { + // delete stack entries added in #if + // should be replaced by #else + if (preprocBracketTypeStackSize > 0) + { + int addedPreproc = bracketTypeStack->size() - preprocBracketTypeStackSize; + for (int i = 0; i < addedPreproc; i++) + bracketTypeStack->pop_back(); + } + } +} + +/** + * determine if the next line starts a comment + * and a header follows the comment or comments. + */ +bool ASFormatter::commentAndHeaderFollows() +{ + // called ONLY IF shouldDeleteEmptyLines and shouldBreakBlocks are TRUE. + assert(shouldDeleteEmptyLines && shouldBreakBlocks); + + // is the next line a comment + if (!sourceIterator->hasMoreLines()) + return false; + string nextLine_ = sourceIterator->peekNextLine(); + size_t firstChar = nextLine_.find_first_not_of(" \t"); + if (firstChar == string::npos + || !(nextLine_.compare(firstChar, 2, "//") == 0 + || nextLine_.compare(firstChar, 2, "/*") == 0)) + { + sourceIterator->peekReset(); + return false; + } + + // find the next non-comment text, and reset + string nextText = peekNextText(nextLine_, false, true); + if (nextText.length() == 0 || !isCharPotentialHeader(nextText, 0)) + return false; + + const string* newHeader = ASBeautifier::findHeader(nextText, 0, headers); + + if (newHeader == NULL) + return false; + + // if a closing header, reset break unless break is requested + if (isClosingHeader(newHeader) && !shouldBreakClosingHeaderBlocks) + { + isAppendPostBlockEmptyLineRequested = false; + return false; + } + + return true; +} + +/** + * determine if a bracket should be attached or broken + * uses brackets in the bracketTypeStack + * the last bracket in the bracketTypeStack is the one being formatted + * returns true if the bracket should be broken + */ +bool ASFormatter::isCurrentBracketBroken() const +{ + assert(bracketTypeStack->size() > 1); + + bool breakBracket = false; + size_t stackEnd = bracketTypeStack->size() - 1; + + // check bracket modifiers + if (shouldAttachExternC + && isBracketType((*bracketTypeStack)[stackEnd], EXTERN_TYPE)) + { + return false; + } + if (shouldAttachNamespace + && isBracketType((*bracketTypeStack)[stackEnd], NAMESPACE_TYPE)) + { + return false; + } + else if (shouldAttachClass + && (isBracketType((*bracketTypeStack)[stackEnd], CLASS_TYPE) + || isBracketType((*bracketTypeStack)[stackEnd], INTERFACE_TYPE))) + { + return false; + } + else if (shouldAttachInline + && isCStyle() // for C++ only + && bracketFormatMode != RUN_IN_MODE + && isBracketType((*bracketTypeStack)[stackEnd], COMMAND_TYPE)) + { + size_t i; + for (i = 1; i < bracketTypeStack->size(); i++) + if (isBracketType((*bracketTypeStack)[i], CLASS_TYPE) + || isBracketType((*bracketTypeStack)[i], STRUCT_TYPE)) + return false; + } + + // check brackets + if (isBracketType((*bracketTypeStack)[stackEnd], EXTERN_TYPE)) + { + if (currentLineBeginsWithBracket + || bracketFormatMode == RUN_IN_MODE) + breakBracket = true; + } + else if (bracketFormatMode == NONE_MODE) + { + if (currentLineBeginsWithBracket + && (int) currentLineFirstBracketNum == charNum) + breakBracket = true; + } + else if (bracketFormatMode == BREAK_MODE || bracketFormatMode == RUN_IN_MODE) + { + breakBracket = true; + } + else if (bracketFormatMode == LINUX_MODE || bracketFormatMode == STROUSTRUP_MODE) + { + // break a namespace, class, or interface if Linux + if (isBracketType((*bracketTypeStack)[stackEnd], NAMESPACE_TYPE) + || isBracketType((*bracketTypeStack)[stackEnd], CLASS_TYPE) + || isBracketType((*bracketTypeStack)[stackEnd], INTERFACE_TYPE)) + { + if (bracketFormatMode == LINUX_MODE) + breakBracket = true; + } + // break the first bracket if a function + else if (isBracketType((*bracketTypeStack)[stackEnd], COMMAND_TYPE)) + { + if (stackEnd == 1) + { + breakBracket = true; + } + else if (stackEnd > 1) + { + // break the first bracket after these if a function + if (isBracketType((*bracketTypeStack)[stackEnd - 1], NAMESPACE_TYPE) + || isBracketType((*bracketTypeStack)[stackEnd - 1], CLASS_TYPE) + || isBracketType((*bracketTypeStack)[stackEnd - 1], ARRAY_TYPE) + || isBracketType((*bracketTypeStack)[stackEnd - 1], STRUCT_TYPE) + || isBracketType((*bracketTypeStack)[stackEnd - 1], EXTERN_TYPE)) + { + breakBracket = true; + } + } + } + } + return breakBracket; +} + +/** + * format comment body + * the calling function should have a continue statement after calling this method + */ +void ASFormatter::formatCommentBody() +{ + assert(isInComment); + + // append the comment + while (charNum < (int) currentLine.length()) + { + currentChar = currentLine[charNum]; + if (currentLine.compare(charNum, 2, "*/") == 0) + { + formatCommentCloser(); + break; + } + if (currentChar == '\t' && shouldConvertTabs) + convertTabToSpaces(); + appendCurrentChar(); + ++charNum; + } + if (shouldStripCommentPrefix) + stripCommentPrefix(); +} + +/** + * format a comment opener + * the comment opener will be appended to the current formattedLine or a new formattedLine as necessary + * the calling function should have a continue statement after calling this method + */ +void ASFormatter::formatCommentOpener() +{ + assert(isSequenceReached("/*")); + + isInComment = isInCommentStartLine = true; + isImmediatelyPostLineComment = false; + if (previousNonWSChar == '}') + resetEndOfStatement(); + + // Check for a following header. + // For speed do not check multiple comment lines more than once. + // For speed do not check shouldBreakBlocks if previous line is empty, a comment, or a '{'. + const string* followingHeader = NULL; + if ((doesLineStartComment + && !isImmediatelyPostCommentOnly + && isBracketType(bracketTypeStack->back(), COMMAND_TYPE)) + && (shouldBreakElseIfs + || isInSwitchStatement() + || (shouldBreakBlocks + && !isImmediatelyPostEmptyLine + && previousCommandChar != '{'))) + followingHeader = checkForHeaderFollowingComment(currentLine.substr(charNum)); + + if (spacePadNum != 0 && !isInLineBreak) + adjustComments(); + formattedLineCommentNum = formattedLine.length(); + + // must be done BEFORE appendSequence + if (previousCommandChar == '{' + && !isImmediatelyPostComment + && !isImmediatelyPostLineComment) + { + if (bracketFormatMode == NONE_MODE) + { + // should a run-in statement be attached? + if (currentLineBeginsWithBracket) + formatRunIn(); + } + else if (bracketFormatMode == ATTACH_MODE) + { + // if the bracket was not attached? + if (formattedLine.length() > 0 && formattedLine[0] == '{' + && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)) + isInLineBreak = true; + } + else if (bracketFormatMode == RUN_IN_MODE) + { + // should a run-in statement be attached? + if (formattedLine.length() > 0 && formattedLine[0] == '{') + formatRunIn(); + } + } + else if (!doesLineStartComment) + noTrimCommentContinuation = true; + + // ASBeautifier needs to know the following statements + if (shouldBreakElseIfs && followingHeader == &AS_ELSE) + elseHeaderFollowsComments = true; + if (followingHeader == &AS_CASE || followingHeader == &AS_DEFAULT) + caseHeaderFollowsComments = true; + + // appendSequence will write the previous line + appendSequence(AS_OPEN_COMMENT); + goForward(1); + + // must be done AFTER appendSequence + + // Break before the comment if a header follows the line comment. + // But not break if previous line is empty, a comment, or a '{'. + if (shouldBreakBlocks + && followingHeader != NULL + && !isImmediatelyPostEmptyLine + && previousCommandChar != '{') + { + if (isClosingHeader(followingHeader)) + { + if (!shouldBreakClosingHeaderBlocks) + isPrependPostBlockEmptyLineRequested = false; + } + // if an opening header, break before the comment + else + isPrependPostBlockEmptyLineRequested = true; + } + + if (previousCommandChar == '}') + currentHeader = NULL; +} + +/** + * format a comment closer + * the comment closer will be appended to the current formattedLine + */ +void ASFormatter::formatCommentCloser() +{ + isInComment = false; + noTrimCommentContinuation = false; + isImmediatelyPostComment = true; + appendSequence(AS_CLOSE_COMMENT); + goForward(1); + if (doesLineStartComment + && (currentLine.find_first_not_of(" \t", charNum + 1) == string::npos)) + lineEndsInCommentOnly = true; + if (peekNextChar() == '}' + && previousCommandChar != ';' + && !isBracketType(bracketTypeStack->back(), ARRAY_TYPE) + && !isInPreprocessor + && isOkToBreakBlock(bracketTypeStack->back())) + { + isInLineBreak = true; + shouldBreakLineAtNextChar = true; + } +} + +/** + * format a line comment body + * the calling function should have a continue statement after calling this method + */ +void ASFormatter::formatLineCommentBody() +{ + assert(isInLineComment); + + // append the comment + while (charNum < (int) currentLine.length()) +// && !isLineReady // commented out in release 2.04, unnecessary + { + currentChar = currentLine[charNum]; + if (currentChar == '\t' && shouldConvertTabs) + convertTabToSpaces(); + appendCurrentChar(); + ++charNum; + } + + // explicitly break a line when a line comment's end is found. + if (charNum == (int) currentLine.length()) + { + isInLineBreak = true; + isInLineComment = false; + isImmediatelyPostLineComment = true; + currentChar = 0; //make sure it is a neutral char. + } +} + +/** + * format a line comment opener + * the line comment opener will be appended to the current formattedLine or a new formattedLine as necessary + * the calling function should have a continue statement after calling this method + */ +void ASFormatter::formatLineCommentOpener() +{ + assert(isSequenceReached("//")); + + if ((int) currentLine.length() > charNum + 2 + && currentLine[charNum + 2] == '\xf2') // check for windows line marker + isAppendPostBlockEmptyLineRequested = false; + + isInLineComment = true; + isCharImmediatelyPostComment = false; + if (previousNonWSChar == '}') + resetEndOfStatement(); + + // Check for a following header. + // For speed do not check multiple comment lines more than once. + // For speed do not check shouldBreakBlocks if previous line is empty, a comment, or a '{'. + const string* followingHeader = NULL; + if ((lineIsLineCommentOnly + && !isImmediatelyPostCommentOnly + && isBracketType(bracketTypeStack->back(), COMMAND_TYPE)) + && (shouldBreakElseIfs + || isInSwitchStatement() + || (shouldBreakBlocks + && !isImmediatelyPostEmptyLine + && previousCommandChar != '{'))) + followingHeader = checkForHeaderFollowingComment(currentLine.substr(charNum)); + + // do not indent if in column 1 or 2 + // or in a namespace before the opening bracket + if ((!shouldIndentCol1Comments && !lineCommentNoIndent) + || foundNamespaceHeader) + { + if (charNum == 0) + lineCommentNoIndent = true; + else if (charNum == 1 && currentLine[0] == ' ') + lineCommentNoIndent = true; + } + // move comment if spaces were added or deleted + if (lineCommentNoIndent == false && spacePadNum != 0 && !isInLineBreak) + adjustComments(); + formattedLineCommentNum = formattedLine.length(); + + // must be done BEFORE appendSequence + // check for run-in statement + if (previousCommandChar == '{' + && !isImmediatelyPostComment + && !isImmediatelyPostLineComment) + { + if (bracketFormatMode == NONE_MODE) + { + if (currentLineBeginsWithBracket) + formatRunIn(); + } + else if (bracketFormatMode == RUN_IN_MODE) + { + if (!lineCommentNoIndent) + formatRunIn(); + else + isInLineBreak = true; + } + else if (bracketFormatMode == BREAK_MODE) + { + if (formattedLine.length() > 0 && formattedLine[0] == '{') + isInLineBreak = true; + } + else + { + if (currentLineBeginsWithBracket) + isInLineBreak = true; + } + } + + // ASBeautifier needs to know the following statements + if (shouldBreakElseIfs && followingHeader == &AS_ELSE) + elseHeaderFollowsComments = true; + if (followingHeader == &AS_CASE || followingHeader == &AS_DEFAULT) + caseHeaderFollowsComments = true; + + // appendSequence will write the previous line + appendSequence(AS_OPEN_LINE_COMMENT); + goForward(1); + + // must be done AFTER appendSequence + + // Break before the comment if a header follows the line comment. + // But do not break if previous line is empty, a comment, or a '{'. + if (shouldBreakBlocks + && followingHeader != NULL + && !isImmediatelyPostEmptyLine + && previousCommandChar != '{') + { + if (isClosingHeader(followingHeader)) + { + if (!shouldBreakClosingHeaderBlocks) + isPrependPostBlockEmptyLineRequested = false; + } + // if an opening header, break before the comment + else + isPrependPostBlockEmptyLineRequested = true; + } + + if (previousCommandChar == '}') + currentHeader = NULL; + + // if tabbed input don't convert the immediately following tabs to spaces + if (getIndentString() == "\t" && lineCommentNoIndent) + { + while (charNum + 1 < (int) currentLine.length() + && currentLine[charNum + 1] == '\t') + { + currentChar = currentLine[++charNum]; + appendCurrentChar(); + } + } + + // explicitly break a line when a line comment's end is found. + if (charNum + 1 == (int) currentLine.length()) + { + isInLineBreak = true; + isInLineComment = false; + isImmediatelyPostLineComment = true; + currentChar = 0; //make sure it is a neutral char. + } +} + +/** + * format quote body + * the calling function should have a continue statement after calling this method + */ +void ASFormatter::formatQuoteBody() +{ + assert(isInQuote); + + if (isSpecialChar) + { + isSpecialChar = false; + } + else if (currentChar == '\\' && !isInVerbatimQuote) + { + if (peekNextChar() == ' ') // is this '\' at end of line + haveLineContinuationChar = true; + else + isSpecialChar = true; + } + else if (isInVerbatimQuote && currentChar == '"') + { + if (isCStyle()) + { + string delim = ')' + verbatimDelimiter; + int delimStart = charNum - delim.length(); + if (delimStart > 0 && currentLine.substr(delimStart, delim.length()) == delim) + { + isInQuote = false; + isInVerbatimQuote = false; + } + } + else if (isSharpStyle()) + { + if (peekNextChar() == '"') // check consecutive quotes + { + appendSequence("\"\""); + goForward(1); + return; + } + else + { + isInQuote = false; + isInVerbatimQuote = false; + } + } + } + else if (quoteChar == currentChar) + { + isInQuote = false; + } + + appendCurrentChar(); + + // append the text to the ending quoteChar or an escape sequence + // tabs in quotes are NOT changed by convert-tabs + if (isInQuote && currentChar != '\\') + { + while (charNum + 1 < (int) currentLine.length() + && currentLine[charNum + 1] != quoteChar + && currentLine[charNum + 1] != '\\') + { + currentChar = currentLine[++charNum]; + appendCurrentChar(); + } + } +} + +/** + * format a quote opener + * the quote opener will be appended to the current formattedLine or a new formattedLine as necessary + * the calling function should have a continue statement after calling this method + */ +void ASFormatter::formatQuoteOpener() +{ + assert(currentChar == '"' + || (currentChar == '\'' && !isDigitSeparator(currentLine, charNum))); + + isInQuote = true; + quoteChar = currentChar; + if (isCStyle() && previousChar == 'R') + { + int parenPos = currentLine.find('(', charNum); + if (parenPos != -1) + { + isInVerbatimQuote = true; + verbatimDelimiter = currentLine.substr(charNum + 1, parenPos - charNum - 1); + } + } + else if (isSharpStyle() && previousChar == '@') + isInVerbatimQuote = true; + + // a quote following a bracket is an array + if (previousCommandChar == '{' + && !isImmediatelyPostComment + && !isImmediatelyPostLineComment + && isNonInStatementArray + && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE) + && !isWhiteSpace(peekNextChar())) + { + if (bracketFormatMode == NONE_MODE) + { + if (currentLineBeginsWithBracket) + formatRunIn(); + } + else if (bracketFormatMode == RUN_IN_MODE) + { + formatRunIn(); + } + else if (bracketFormatMode == BREAK_MODE) + { + if (formattedLine.length() > 0 && formattedLine[0] == '{') + isInLineBreak = true; + } + else + { + if (currentLineBeginsWithBracket) + isInLineBreak = true; + } + } + previousCommandChar = ' '; + appendCurrentChar(); +} + +/** + * get the next line comment adjustment that results from breaking a closing bracket. + * the bracket must be on the same line as the closing header. + * i.e "} else" changed to "} else". + */ +int ASFormatter::getNextLineCommentAdjustment() +{ + assert(foundClosingHeader && previousNonWSChar == '}'); + if (charNum < 1) // "else" is in column 1 + return 0; + size_t lastBracket = currentLine.rfind('}', charNum - 1); + if (lastBracket != string::npos) + return (lastBracket - charNum); // return a negative number + return 0; +} + +// for console build only +LineEndFormat ASFormatter::getLineEndFormat() const +{ + return lineEnd; +} + +/** + * get the current line comment adjustment that results from attaching + * a closing header to a closing bracket. + * the bracket must be on the line previous to the closing header. + * the adjustment is 2 chars, one for the bracket and one for the space. + * i.e "} else" changed to "} else". + */ +int ASFormatter::getCurrentLineCommentAdjustment() +{ + assert(foundClosingHeader && previousNonWSChar == '}'); + if (charNum < 1) + return 2; + size_t lastBracket = currentLine.rfind('}', charNum - 1); + if (lastBracket == string::npos) + return 2; + return 0; +} + +/** + * get the previous word on a line + * the argument 'currPos' must point to the current position. + * + * @return is the previous word or an empty string if none found. + */ +string ASFormatter::getPreviousWord(const string& line, int currPos) const +{ + // get the last legal word (may be a number) + if (currPos == 0) + return string(); + + size_t end = line.find_last_not_of(" \t", currPos - 1); + if (end == string::npos || !isLegalNameChar(line[end])) + return string(); + + int start; // start of the previous word + for (start = end; start > -1; start--) + { + if (!isLegalNameChar(line[start]) || line[start] == '.') + break; + } + start++; + + return (line.substr(start, end - start + 1)); +} + +/** + * check if a line break is needed when a closing bracket + * is followed by a closing header. + * the break depends on the bracketFormatMode and other factors. + */ +void ASFormatter::isLineBreakBeforeClosingHeader() +{ + assert(foundClosingHeader && previousNonWSChar == '}'); + if (bracketFormatMode == BREAK_MODE + || bracketFormatMode == RUN_IN_MODE + || attachClosingBracketMode) + { + isInLineBreak = true; + } + else if (bracketFormatMode == NONE_MODE) + { + if (shouldBreakClosingHeaderBrackets + || getBracketIndent() || getBlockIndent()) + { + isInLineBreak = true; + } + else + { + appendSpacePad(); + // is closing bracket broken? + size_t i = currentLine.find_first_not_of(" \t"); + if (i != string::npos && currentLine[i] == '}') + isInLineBreak = false; + + if (shouldBreakBlocks) + isAppendPostBlockEmptyLineRequested = false; + } + } + // bracketFormatMode == ATTACH_MODE, LINUX_MODE, STROUSTRUP_MODE + else + { + if (shouldBreakClosingHeaderBrackets + || getBracketIndent() || getBlockIndent()) + { + isInLineBreak = true; + } + else + { + // if a blank line does not precede this + // or last line is not a one line block, attach header + bool previousLineIsEmpty = isEmptyLine(formattedLine); + int previousLineIsOneLineBlock = 0; + size_t firstBracket = findNextChar(formattedLine, '{'); + if (firstBracket != string::npos) + previousLineIsOneLineBlock = isOneLineBlockReached(formattedLine, firstBracket); + if (!previousLineIsEmpty + && previousLineIsOneLineBlock == 0) + { + isInLineBreak = false; + appendSpacePad(); + spacePadNum = 0; // don't count as comment padding + } + + if (shouldBreakBlocks) + isAppendPostBlockEmptyLineRequested = false; + } + } +} + +/** + * Add brackets to a single line statement following a header. + * Brackets are not added if the proper conditions are not met. + * Brackets are added to the currentLine. + */ +bool ASFormatter::addBracketsToStatement() +{ + assert(isImmediatelyPostHeader); + + if (currentHeader != &AS_IF + && currentHeader != &AS_ELSE + && currentHeader != &AS_FOR + && currentHeader != &AS_WHILE + && currentHeader != &AS_DO + && currentHeader != &AS_FOREACH + && currentHeader != &AS_QFOREACH + && currentHeader != &AS_QFOREVER + && currentHeader != &AS_FOREVER) + return false; + + if (currentHeader == &AS_WHILE && foundClosingHeader) // do-while + return false; + + // do not bracket an empty statement + if (currentChar == ';') + return false; + + // do not add if a header follows + if (isCharPotentialHeader(currentLine, charNum)) + if (findHeader(headers) != NULL) + return false; + + // find the next semi-colon + size_t nextSemiColon = charNum; + if (currentChar != ';') + nextSemiColon = findNextChar(currentLine, ';', charNum + 1); + if (nextSemiColon == string::npos) + return false; + + // add closing bracket before changing the line length + if (nextSemiColon == currentLine.length() - 1) + currentLine.append(" }"); + else + currentLine.insert(nextSemiColon + 1, " }"); + // add opening bracket + currentLine.insert(charNum, "{ "); + assert(computeChecksumIn("{}")); + currentChar = '{'; + // remove extra spaces + if (!shouldAddOneLineBrackets) + { + size_t lastText = formattedLine.find_last_not_of(" \t"); + if ((formattedLine.length() - 1) - lastText > 1) + formattedLine.erase(lastText + 1); + } + return true; +} + +/** + * Remove brackets from a single line statement following a header. + * Brackets are not removed if the proper conditions are not met. + * The first bracket is replaced by a space. + */ +bool ASFormatter::removeBracketsFromStatement() +{ + assert(isImmediatelyPostHeader); + assert(currentChar == '{'); + + if (currentHeader != &AS_IF + && currentHeader != &AS_ELSE + && currentHeader != &AS_FOR + && currentHeader != &AS_WHILE + && currentHeader != &AS_FOREACH) + return false; + + if (currentHeader == &AS_WHILE && foundClosingHeader) // do-while + return false; + + bool isFirstLine = true; + bool needReset = false; + string nextLine_; + // leave nextLine_ empty if end of line comment follows + if (!isBeforeAnyLineEndComment(charNum) || currentLineBeginsWithBracket) + nextLine_ = currentLine.substr(charNum + 1); + size_t nextChar = 0; + + // find the first non-blank text + while (sourceIterator->hasMoreLines() || isFirstLine) + { + if (isFirstLine) + isFirstLine = false; + else + { + nextLine_ = sourceIterator->peekNextLine(); + nextChar = 0; + needReset = true; + } + + nextChar = nextLine_.find_first_not_of(" \t", nextChar); + if (nextChar != string::npos) + break; + } + + // don't remove if comments or a header follow the bracket + if ((nextLine_.compare(nextChar, 2, "/*") == 0) + || (nextLine_.compare(nextChar, 2, "//") == 0) + || (isCharPotentialHeader(nextLine_, nextChar) + && ASBeautifier::findHeader(nextLine_, nextChar, headers) != NULL)) + { + if (needReset) + sourceIterator->peekReset(); + return false; + } + + // find the next semi-colon + size_t nextSemiColon = nextChar; + if (nextLine_[nextChar] != ';') + nextSemiColon = findNextChar(nextLine_, ';', nextChar + 1); + if (nextSemiColon == string::npos) + { + if (needReset) + sourceIterator->peekReset(); + return false; + } + + // find the closing bracket + isFirstLine = true; + nextChar = nextSemiColon + 1; + while (sourceIterator->hasMoreLines() || isFirstLine) + { + if (isFirstLine) + isFirstLine = false; + else + { + nextLine_ = sourceIterator->peekNextLine(); + nextChar = 0; + needReset = true; + } + nextChar = nextLine_.find_first_not_of(" \t", nextChar); + if (nextChar != string::npos) + break; + } + if (nextLine_.length() == 0 || nextLine_[nextChar] != '}') + { + if (needReset) + sourceIterator->peekReset(); + return false; + } + + // remove opening bracket + currentLine[charNum] = currentChar = ' '; + assert(adjustChecksumIn(-'{')); + if (needReset) + sourceIterator->peekReset(); + return true; +} + +/** + * Find the next character that is not in quotes or a comment. + * + * @param line the line to be searched. + * @param searchChar the char to find. + * @param searchStart the start position on the line (default is 0). + * @return the position on the line or string::npos if not found. + */ +size_t ASFormatter::findNextChar(string& line, char searchChar, int searchStart /*0*/) const +{ + // find the next searchChar + size_t i; + for (i = searchStart; i < line.length(); i++) + { + if (line.compare(i, 2, "//") == 0) + return string::npos; + if (line.compare(i, 2, "/*") == 0) + { + size_t endComment = line.find("*/", i + 2); + if (endComment == string::npos) + return string::npos; + i = endComment + 2; + if (i >= line.length()) + return string::npos; + } + if (line[i] == '"' + || (line[i] == '\'' && !isDigitSeparator(line, i))) + { + char quote = line[i]; + while (i < line.length()) + { + size_t endQuote = line.find(quote, i + 1); + if (endQuote == string::npos) + return string::npos; + i = endQuote; + if (line[endQuote - 1] != '\\') // check for '\"' + break; + if (line[endQuote - 2] == '\\') // check for '\\' + break; + } + } + + if (line[i] == searchChar) + break; + + // for now don't process C# 'delegate' brackets + // do this last in case the search char is a '{' + if (line[i] == '{') + return string::npos; + } + if (i >= line.length()) // didn't find searchChar + return string::npos; + + return i; +} + +/** + * Look ahead in the file to see if a struct has access modifiers. + * + * @param firstLine a reference to the line to indent. + * @param index the current line index. + * @return true if the struct has access modifiers. + */ +bool ASFormatter::isStructAccessModified(string& firstLine, size_t index) const +{ + assert(firstLine[index] == '{'); + assert(isCStyle()); + + bool isFirstLine = true; + bool needReset = false; + size_t bracketCount = 1; + string nextLine_ = firstLine.substr(index + 1); + + // find the first non-blank text, bypassing all comments and quotes. + bool isInComment_ = false; + bool isInQuote_ = false; + char quoteChar_ = ' '; + while (sourceIterator->hasMoreLines() || isFirstLine) + { + if (isFirstLine) + isFirstLine = false; + else + { + nextLine_ = sourceIterator->peekNextLine(); + needReset = true; + } + // parse the line + for (size_t i = 0; i < nextLine_.length(); i++) + { + if (isWhiteSpace(nextLine_[i])) + continue; + if (nextLine_.compare(i, 2, "/*") == 0) + isInComment_ = true; + if (isInComment_) + { + if (nextLine_.compare(i, 2, "*/") == 0) + { + isInComment_ = false; + ++i; + } + continue; + } + if (nextLine_[i] == '\\') + { + ++i; + continue; + } + + if (isInQuote_) + { + if (nextLine_[i] == quoteChar_) + isInQuote_ = false; + continue; + } + + if (nextLine_[i] == '"' + || (nextLine_[i] == '\'' && !isDigitSeparator(nextLine_, i))) + { + isInQuote_ = true; + quoteChar_ = nextLine_[i]; + continue; + } + if (nextLine_.compare(i, 2, "//") == 0) + { + i = nextLine_.length(); + continue; + } + // handle brackets + if (nextLine_[i] == '{') + ++bracketCount; + if (nextLine_[i] == '}') + --bracketCount; + if (bracketCount == 0) + { + if (needReset) + sourceIterator->peekReset(); + return false; + } + // check for access modifiers + if (isCharPotentialHeader(nextLine_, i)) + { + if (findKeyword(nextLine_, i, AS_PUBLIC) + || findKeyword(nextLine_, i, AS_PRIVATE) + || findKeyword(nextLine_, i, AS_PROTECTED)) + { + if (needReset) + sourceIterator->peekReset(); + return true; + } + string name = getCurrentWord(nextLine_, i); + i += name.length() - 1; + } + } // end of for loop + } // end of while loop + + if (needReset) + sourceIterator->peekReset(); + return false; +} + +/** +* Look ahead in the file to see if a preprocessor block is indentable. +* +* @param firstLine a reference to the line to indent. +* @param index the current line index. +* @return true if the block is indentable. +*/ +bool ASFormatter::isIndentablePreprocessorBlock(string& firstLine, size_t index) +{ + assert(firstLine[index] == '#'); + + bool isFirstLine = true; + bool needReset = false; + bool isInIndentableBlock = false; + bool blockContainsBrackets = false; + bool blockContainsDefineContinuation = false; + bool isInClassConstructor = false; + int numBlockIndents = 0; + int lineParenCount = 0; + string nextLine_ = firstLine.substr(index); + + // find end of the block, bypassing all comments and quotes. + bool isInComment_ = false; + bool isInQuote_ = false; + char quoteChar_ = ' '; + while (sourceIterator->hasMoreLines() || isFirstLine) + { + if (isFirstLine) + isFirstLine = false; + else + { + nextLine_ = sourceIterator->peekNextLine(); + needReset = true; + } + // parse the line + for (size_t i = 0; i < nextLine_.length(); i++) + { + if (isWhiteSpace(nextLine_[i])) + continue; + if (nextLine_.compare(i, 2, "/*") == 0) + isInComment_ = true; + if (isInComment_) + { + if (nextLine_.compare(i, 2, "*/") == 0) + { + isInComment_ = false; + ++i; + } + continue; + } + if (nextLine_[i] == '\\') + { + ++i; + continue; + } + if (isInQuote_) + { + if (nextLine_[i] == quoteChar_) + isInQuote_ = false; + continue; + } + + if (nextLine_[i] == '"' + || (nextLine_[i] == '\'' && !isDigitSeparator(nextLine_, i))) + { + isInQuote_ = true; + quoteChar_ = nextLine_[i]; + continue; + } + if (nextLine_.compare(i, 2, "//") == 0) + { + i = nextLine_.length(); + continue; + } + // handle preprocessor statement + if (nextLine_[i] == '#') + { + string preproc = ASBeautifier::extractPreprocessorStatement(nextLine_); + if (preproc.length() >= 2 && preproc.substr(0, 2) == "if") // #if, #ifdef, #ifndef + { + numBlockIndents += 1; + isInIndentableBlock = true; + // flag first preprocessor conditional for header include guard check + if (!processedFirstConditional) + { + processedFirstConditional = true; + isFirstPreprocConditional = true; + } + } + else if (preproc == "endif" || preproc == "end") + { + if (numBlockIndents > 0) + numBlockIndents -= 1; + // must exit BOTH loops + if (numBlockIndents == 0) + goto EndOfWhileLoop; + } + else if (preproc == "define" && nextLine_[nextLine_.length() - 1] == '\\') + { + blockContainsDefineContinuation = true; + } + i = nextLine_.length(); + continue; + } + // handle exceptions + if (nextLine_[i] == '{' || nextLine_[i] == '}') + blockContainsBrackets = true; + else if (nextLine_[i] == '(') + ++lineParenCount; + else if (nextLine_[i] == ')') + --lineParenCount; + else if (nextLine_[i] == ':') + { + // check for '::' + if (nextLine_.length() > i && nextLine_[i + 1] == ':') + ++i; + else + isInClassConstructor = true; + } + // bypass unnecessary parsing - must exit BOTH loops + if (blockContainsBrackets || isInClassConstructor || blockContainsDefineContinuation) + goto EndOfWhileLoop; + } // end of for loop, end of line + if (lineParenCount != 0) + break; + } // end of while loop +EndOfWhileLoop: + preprocBlockEnd = sourceIterator->tellg(); + if (preprocBlockEnd < 0) + preprocBlockEnd = sourceIterator->getStreamLength(); + if (blockContainsBrackets + || isInClassConstructor + || blockContainsDefineContinuation + || lineParenCount != 0 + || numBlockIndents != 0) + isInIndentableBlock = false; + // find next executable instruction + // this WILL RESET the get pointer + string nextText = peekNextText("", false, needReset); + // bypass header include guards, with an exception for small test files + if (isFirstPreprocConditional) + { + isFirstPreprocConditional = false; + if (nextText.empty() && sourceIterator->getStreamLength() > 250) + { + isInIndentableBlock = false; + preprocBlockEnd = 0; + } + } + // this allows preprocessor blocks within this block to be indented + if (!isInIndentableBlock) + preprocBlockEnd = 0; + // peekReset() is done by previous peekNextText() + return isInIndentableBlock; +} + +/** + * Check to see if this is an EXEC SQL statement. + * + * @param line a reference to the line to indent. + * @param index the current line index. + * @return true if the statement is EXEC SQL. + */ +bool ASFormatter::isExecSQL(string& line, size_t index) const +{ + if (line[index] != 'e' && line[index] != 'E') // quick check to reject most + return false; + string word; + if (isCharPotentialHeader(line, index)) + word = getCurrentWord(line, index); + for (size_t i = 0; i < word.length(); i++) + word[i] = (char) toupper(word[i]); + if (word != "EXEC") + return false; + size_t index2 = index + word.length(); + index2 = line.find_first_not_of(" \t", index2); + if (index2 == string::npos) + return false; + word.erase(); + if (isCharPotentialHeader(line, index2)) + word = getCurrentWord(line, index2); + for (size_t i = 0; i < word.length(); i++) + word[i] = (char) toupper(word[i]); + if (word != "SQL") + return false; + return true; +} + +/** + * The continuation lines must be adjusted so the leading spaces + * is equivalent to the text on the opening line. + * + * Updates currentLine and charNum. + */ +void ASFormatter::trimContinuationLine() +{ + size_t len = currentLine.length(); + size_t tabSize = getTabLength(); + charNum = 0; + + if (leadingSpaces > 0 && len > 0) + { + size_t i; + size_t continuationIncrementIn = 0; + for (i = 0; (i < len) && (i + continuationIncrementIn < leadingSpaces); i++) + { + if (!isWhiteSpace(currentLine[i])) // don't delete any text + { + if (i < continuationIncrementIn) + leadingSpaces = i + tabIncrementIn; + continuationIncrementIn = tabIncrementIn; + break; + } + if (currentLine[i] == '\t') + continuationIncrementIn += tabSize - 1 - ((continuationIncrementIn + i) % tabSize); + } + + if ((int) continuationIncrementIn == tabIncrementIn) + charNum = i; + else + { + // build a new line with the equivalent leading chars + string newLine; + int leadingChars = 0; + if ((int) leadingSpaces > tabIncrementIn) + leadingChars = leadingSpaces - tabIncrementIn; + newLine.append(leadingChars, ' '); + newLine.append(currentLine, i, len - i); + currentLine = newLine; + charNum = leadingChars; + if (currentLine.length() == 0) + currentLine = string(" "); // a null is inserted if this is not done + } + if (i >= len) + charNum = 0; + } + return; +} + +/** + * Determine if a header is a closing header + * + * @return true if the header is a closing header. + */ +bool ASFormatter::isClosingHeader(const string* header) const +{ + return (header == &AS_ELSE + || header == &AS_CATCH + || header == &AS_FINALLY); +} + +/** + * Determine if a * following a closing paren is immediately. + * after a cast. If so it is a deference and not a multiply. + * e.g. "(int*) *ptr" is a deference. + */ +bool ASFormatter::isImmediatelyPostCast() const +{ + assert(previousNonWSChar == ')' && currentChar == '*'); + // find preceding closing paren on currentLine or readyFormattedLine + string line; // currentLine or readyFormattedLine + size_t paren = currentLine.rfind(")", charNum); + if (paren != string::npos) + line = currentLine; + // if not on currentLine it must be on the previous line + else + { + line = readyFormattedLine; + paren = line.rfind(")"); + if (paren == string::npos) + return false; + } + if (paren == 0) + return false; + + // find character preceding the closing paren + size_t lastChar = line.find_last_not_of(" \t", paren - 1); + if (lastChar == string::npos) + return false; + // check for pointer cast + if (line[lastChar] == '*') + return true; + return false; +} + +/** + * Determine if a < is a template definition or instantiation. + * Sets the class variables isInTemplate and templateDepth. + */ +void ASFormatter::checkIfTemplateOpener() +{ + assert(!isInTemplate && currentChar == '<'); + + // find first char after the '<' operators + size_t firstChar = currentLine.find_first_not_of("< \t", charNum); + if (firstChar == string::npos + || currentLine[firstChar] == '=') + { + // this is not a template -> leave... + isInTemplate = false; + return; + } + + bool isFirstLine = true; + bool needReset = false; + int parenDepth_ = 0; + int maxTemplateDepth = 0; + templateDepth = 0; + string nextLine_ = currentLine.substr(charNum); + + // find the angle brackets, bypassing all comments and quotes. + bool isInComment_ = false; + bool isInQuote_ = false; + char quoteChar_ = ' '; + while (sourceIterator->hasMoreLines() || isFirstLine) + { + if (isFirstLine) + isFirstLine = false; + else + { + nextLine_ = sourceIterator->peekNextLine(); + needReset = true; + } + // parse the line + for (size_t i = 0; i < nextLine_.length(); i++) + { + char currentChar_ = nextLine_[i]; + if (isWhiteSpace(currentChar_)) + continue; + if (nextLine_.compare(i, 2, "/*") == 0) + isInComment_ = true; + if (isInComment_) + { + if (nextLine_.compare(i, 2, "*/") == 0) + { + isInComment_ = false; + ++i; + } + continue; + } + if (currentChar_ == '\\') + { + ++i; + continue; + } + + if (isInQuote_) + { + if (currentChar_ == quoteChar_) + isInQuote_ = false; + continue; + } + + if (currentChar_ == '"' + || (currentChar_ == '\'' && !isDigitSeparator(nextLine_, i))) + { + isInQuote_ = true; + quoteChar_ = currentChar_; + continue; + } + if (nextLine_.compare(i, 2, "//") == 0) + { + i = nextLine_.length(); + continue; + } + + // not in a comment or quote + if (currentChar_ == '<') + { + ++templateDepth; + ++maxTemplateDepth; + continue; + } + else if (currentChar_ == '>') + { + --templateDepth; + if (templateDepth == 0) + { + if (parenDepth_ == 0) + { + // this is a template! + isInTemplate = true; + templateDepth = maxTemplateDepth; + } + goto exitFromSearch; + } + continue; + } + else if (currentChar_ == '(' || currentChar_ == ')') + { + if (currentChar_ == '(') + ++parenDepth_; + else + --parenDepth_; + if (parenDepth_ >= 0) + continue; + // this is not a template -> leave... + isInTemplate = false; + goto exitFromSearch; + } + else if (nextLine_.compare(i, 2, AS_AND) == 0 + || nextLine_.compare(i, 2, AS_OR) == 0) + { + // this is not a template -> leave... + isInTemplate = false; + goto exitFromSearch; + } + else if (currentChar_ == ',' // comma, e.g. A + || currentChar_ == '&' // reference, e.g. A + || currentChar_ == '*' // pointer, e.g. A + || currentChar_ == '^' // C++/CLI managed pointer, e.g. A + || currentChar_ == ':' // ::, e.g. std::string + || currentChar_ == '=' // assign e.g. default parameter + || currentChar_ == '[' // [] e.g. string[] + || currentChar_ == ']' // [] e.g. string[] + || currentChar_ == '(' // (...) e.g. function definition + || currentChar_ == ')' // (...) e.g. function definition + || (isJavaStyle() && currentChar_ == '?') // Java wildcard + ) + { + continue; + } + else if (!isLegalNameChar(currentChar_)) + { + // this is not a template -> leave... + isInTemplate = false; + templateDepth = 0; + goto exitFromSearch; + } + string name = getCurrentWord(nextLine_, i); + i += name.length() - 1; + } // end of for loop + } // end of while loop + + // goto needed to exit from two loops +exitFromSearch: + if (needReset) + sourceIterator->peekReset(); +} + +void ASFormatter::updateFormattedLineSplitPoints(char appendedChar) +{ + assert(maxCodeLength != string::npos); + assert(formattedLine.length() > 0); + + if (!isOkToSplitFormattedLine()) + return; + + char nextChar = peekNextChar(); + + // don't split before an end of line comment + if (nextChar == '/') + return; + + // don't split before or after a bracket + if (appendedChar == '{' || appendedChar == '}' + || previousNonWSChar == '{' || previousNonWSChar == '}' + || nextChar == '{' || nextChar == '}' + || currentChar == '{' || currentChar == '}') // currentChar tests for an appended bracket + return; + + // don't split before or after a block paren + if (appendedChar == '[' || appendedChar == ']' + || previousNonWSChar == '[' + || nextChar == '[' || nextChar == ']') + return; + + if (isWhiteSpace(appendedChar)) + { + if (nextChar != ')' // space before a closing paren + && nextChar != '(' // space before an opening paren + && nextChar != '/' // space before a comment + && nextChar != ':' // space before a colon + && currentChar != ')' // appended space before and after a closing paren + && currentChar != '(' // appended space before and after a opening paren + && previousNonWSChar != '(' // decided at the '(' + // don't break before a pointer or reference aligned to type + && !(nextChar == '*' + && !isCharPotentialOperator(previousNonWSChar) + && pointerAlignment == PTR_ALIGN_TYPE) + && !(nextChar == '&' + && !isCharPotentialOperator(previousNonWSChar) + && (referenceAlignment == REF_ALIGN_TYPE + || (referenceAlignment == REF_SAME_AS_PTR && pointerAlignment == PTR_ALIGN_TYPE))) + ) + { + if (formattedLine.length() - 1 <= maxCodeLength) + maxWhiteSpace = formattedLine.length() - 1; + else + maxWhiteSpacePending = formattedLine.length() - 1; + } + } + // unpadded closing parens may split after the paren (counts as whitespace) + else if (appendedChar == ')') + { + if (nextChar != ')' + && nextChar != ' ' + && nextChar != ';' + && nextChar != ',' + && nextChar != '.' + && !(nextChar == '-' && pointerSymbolFollows())) // check for -> + { + if (formattedLine.length() <= maxCodeLength) + maxWhiteSpace = formattedLine.length(); + else + maxWhiteSpacePending = formattedLine.length(); + } + } + // unpadded commas may split after the comma + else if (appendedChar == ',') + { + if (formattedLine.length() <= maxCodeLength) + maxComma = formattedLine.length(); + else + maxCommaPending = formattedLine.length(); + } + else if (appendedChar == '(') + { + if (nextChar != ')' && nextChar != '(' && nextChar != '"' && nextChar != '\'') + { + // if follows an operator break before + size_t parenNum; + if (isCharPotentialOperator(previousNonWSChar)) + parenNum = formattedLine.length() - 1 ; + else + parenNum = formattedLine.length(); + if (formattedLine.length() <= maxCodeLength) + maxParen = parenNum; + else + maxParenPending = parenNum; + } + } + else if (appendedChar == ';') + { + if (nextChar != ' ' && nextChar != '}' && nextChar != '/') // check for following comment + { + if (formattedLine.length() <= maxCodeLength) + maxSemi = formattedLine.length(); + else + maxSemiPending = formattedLine.length(); + } + } +} + +void ASFormatter::updateFormattedLineSplitPointsOperator(const string& sequence) +{ + assert(maxCodeLength != string::npos); + assert(formattedLine.length() > 0); + + if (!isOkToSplitFormattedLine()) + return; + + char nextChar = peekNextChar(); + + // don't split before an end of line comment + if (nextChar == '/') + return; + + // check for logical conditional + if (sequence == "||" || sequence == "&&" || sequence == "or" || sequence == "and") + { + if (shouldBreakLineAfterLogical) + { + if (formattedLine.length() <= maxCodeLength) + maxAndOr = formattedLine.length(); + else + maxAndOrPending = formattedLine.length(); + } + else + { + // adjust for leading space in the sequence + size_t sequenceLength = sequence.length(); + if (formattedLine.length() > sequenceLength + && isWhiteSpace(formattedLine[formattedLine.length() - sequenceLength - 1])) + sequenceLength++; + if (formattedLine.length() - sequenceLength <= maxCodeLength) + maxAndOr = formattedLine.length() - sequenceLength; + else + maxAndOrPending = formattedLine.length() - sequenceLength; + } + } + // comparison operators will split after the operator (counts as whitespace) + else if (sequence == "==" || sequence == "!=" || sequence == ">=" || sequence == "<=") + { + if (formattedLine.length() <= maxCodeLength) + maxWhiteSpace = formattedLine.length(); + else + maxWhiteSpacePending = formattedLine.length(); + } + // unpadded operators that will split BEFORE the operator (counts as whitespace) + else if (sequence == "+" || sequence == "-" || sequence == "?") + { + if (charNum > 0 + && (isLegalNameChar(currentLine[charNum - 1]) + || currentLine[charNum - 1] == ')' + || currentLine[charNum - 1] == ']' + || currentLine[charNum - 1] == '\"')) + { + if (formattedLine.length() - 1 <= maxCodeLength) + maxWhiteSpace = formattedLine.length() - 1; + else + maxWhiteSpacePending = formattedLine.length() - 1; + } + } + // unpadded operators that will USUALLY split AFTER the operator (counts as whitespace) + else if (sequence == "=" || sequence == ":") + { + // split BEFORE if the line is too long + // do NOT use <= here, must allow for a bracket attached to an array + size_t splitPoint = 0; + if (formattedLine.length() < maxCodeLength) + splitPoint = formattedLine.length(); + else + splitPoint = formattedLine.length() - 1; + // padded or unpadded arrays + if (previousNonWSChar == ']') + { + if (formattedLine.length() - 1 <= maxCodeLength) + maxWhiteSpace = splitPoint; + else + maxWhiteSpacePending = splitPoint; + } + else if (charNum > 0 + && (isLegalNameChar(currentLine[charNum - 1]) + || currentLine[charNum - 1] == ')' + || currentLine[charNum - 1] == ']')) + { + if (formattedLine.length() <= maxCodeLength) + maxWhiteSpace = splitPoint; + else + maxWhiteSpacePending = splitPoint; + } + } +} + +/** + * Update the split point when a pointer or reference is formatted. + * The argument is the maximum index of the last whitespace character. + */ +void ASFormatter::updateFormattedLineSplitPointsPointerOrReference(size_t index) +{ + assert(maxCodeLength != string::npos); + assert(formattedLine.length() > 0); + assert(index < formattedLine.length()); + + if (!isOkToSplitFormattedLine()) + return; + + if (index < maxWhiteSpace) // just in case + return; + + if (index <= maxCodeLength) + maxWhiteSpace = index; + else + maxWhiteSpacePending = index; +} + +bool ASFormatter::isOkToSplitFormattedLine() +{ + assert(maxCodeLength != string::npos); + // Is it OK to split the line? + if (shouldKeepLineUnbroken + || isInLineComment + || isInComment + || isInQuote + || isInCase + || isInPreprocessor + || isInExecSQL + || isInAsm || isInAsmOneLine || isInAsmBlock + || isInTemplate) + return false; + + if (!isOkToBreakBlock(bracketTypeStack->back()) && currentChar != '{') + { + shouldKeepLineUnbroken = true; + clearFormattedLineSplitPoints(); + return false; + } + else if (isBracketType(bracketTypeStack->back(), ARRAY_TYPE)) + { + shouldKeepLineUnbroken = true; + if (!isBracketType(bracketTypeStack->back(), ARRAY_NIS_TYPE)) + clearFormattedLineSplitPoints(); + return false; + } + return true; +} + +/* This is called if the option maxCodeLength is set. + */ +void ASFormatter::testForTimeToSplitFormattedLine() +{ + // DO NOT ASSERT maxCodeLength HERE + // should the line be split + if (formattedLine.length() > maxCodeLength && !isLineReady) + { + size_t splitPoint = findFormattedLineSplitPoint(); + if (splitPoint > 0 && splitPoint < formattedLine.length()) + { + string splitLine = formattedLine.substr(splitPoint); + formattedLine = formattedLine.substr(0, splitPoint); + breakLine(true); + formattedLine = splitLine; + // if break-blocks is requested and this is a one-line statement + string nextWord = ASBeautifier::getNextWord(currentLine, charNum - 1); + if (isAppendPostBlockEmptyLineRequested + && (nextWord == "break" || nextWord == "continue")) + { + isAppendPostBlockEmptyLineRequested = false; + isPrependPostBlockEmptyLineRequested = true; + } + else + isPrependPostBlockEmptyLineRequested = false; + // adjust max split points + maxAndOr = (maxAndOr > splitPoint) ? (maxAndOr - splitPoint) : 0; + maxSemi = (maxSemi > splitPoint) ? (maxSemi - splitPoint) : 0; + maxComma = (maxComma > splitPoint) ? (maxComma - splitPoint) : 0; + maxParen = (maxParen > splitPoint) ? (maxParen - splitPoint) : 0; + maxWhiteSpace = (maxWhiteSpace > splitPoint) ? (maxWhiteSpace - splitPoint) : 0; + if (maxSemiPending > 0) + { + maxSemi = (maxSemiPending > splitPoint) ? (maxSemiPending - splitPoint) : 0; + maxSemiPending = 0; + } + if (maxAndOrPending > 0) + { + maxAndOr = (maxAndOrPending > splitPoint) ? (maxAndOrPending - splitPoint) : 0; + maxAndOrPending = 0; + } + if (maxCommaPending > 0) + { + maxComma = (maxCommaPending > splitPoint) ? (maxCommaPending - splitPoint) : 0; + maxCommaPending = 0; + } + if (maxParenPending > 0) + { + maxParen = (maxParenPending > splitPoint) ? (maxParenPending - splitPoint) : 0; + maxParenPending = 0; + } + if (maxWhiteSpacePending > 0) + { + maxWhiteSpace = (maxWhiteSpacePending > splitPoint) ? (maxWhiteSpacePending - splitPoint) : 0; + maxWhiteSpacePending = 0; + } + // don't allow an empty formatted line + size_t firstText = formattedLine.find_first_not_of(" \t"); + if (firstText == string::npos && formattedLine.length() > 0) + { + formattedLine.erase(); + clearFormattedLineSplitPoints(); + if (isWhiteSpace(currentChar)) + for (size_t i = charNum + 1; i < currentLine.length() && isWhiteSpace(currentLine[i]); i++) + goForward(1); + } + else if (firstText > 0) + { + formattedLine.erase(0, firstText); + maxSemi = (maxSemi > firstText) ? (maxSemi - firstText) : 0; + maxAndOr = (maxAndOr > firstText) ? (maxAndOr - firstText) : 0; + maxComma = (maxComma > firstText) ? (maxComma - firstText) : 0; + maxParen = (maxParen > firstText) ? (maxParen - firstText) : 0; + maxWhiteSpace = (maxWhiteSpace > firstText) ? (maxWhiteSpace - firstText) : 0; + } + // reset formattedLineCommentNum + if (formattedLineCommentNum != string::npos) + { + formattedLineCommentNum = formattedLine.find("//"); + if (formattedLineCommentNum == string::npos) + formattedLineCommentNum = formattedLine.find("/*"); + } + } + } +} + +size_t ASFormatter::findFormattedLineSplitPoint() const +{ + assert(maxCodeLength != string::npos); + // determine where to split + size_t minCodeLength = 10; + size_t splitPoint = 0; + splitPoint = maxSemi; + if (maxAndOr >= minCodeLength) + splitPoint = maxAndOr; + if (splitPoint < minCodeLength) + { + splitPoint = maxWhiteSpace; + // use maxParen instead if it is long enough + if (maxParen > splitPoint + || maxParen >= maxCodeLength * .7) + splitPoint = maxParen; + // use maxComma instead if it is long enough + // increasing the multiplier causes more splits at whitespace + if (maxComma > splitPoint + || maxComma >= maxCodeLength * .3) + splitPoint = maxComma; + } + // replace split point with first available break point + if (splitPoint < minCodeLength) + { + splitPoint = string::npos; + if (maxSemiPending > 0 && maxSemiPending < splitPoint) + splitPoint = maxSemiPending; + if (maxAndOrPending > 0 && maxAndOrPending < splitPoint) + splitPoint = maxAndOrPending; + if (maxCommaPending > 0 && maxCommaPending < splitPoint) + splitPoint = maxCommaPending; + if (maxParenPending > 0 && maxParenPending < splitPoint) + splitPoint = maxParenPending; + if (maxWhiteSpacePending > 0 && maxWhiteSpacePending < splitPoint) + splitPoint = maxWhiteSpacePending; + if (splitPoint == string::npos) + splitPoint = 0; + } + // if remaining line after split is too long + else if (formattedLine.length() - splitPoint > maxCodeLength) + { + // if end of the currentLine, find a new split point + size_t newCharNum; + if (isCharPotentialHeader(currentLine, charNum)) + newCharNum = getCurrentWord(currentLine, charNum).length() + charNum; + else + newCharNum = charNum + 2; + if (newCharNum + 1 > currentLine.length()) + { + // don't move splitPoint from before a conditional to after + if (maxWhiteSpace > splitPoint + 3) + splitPoint = maxWhiteSpace; + if (maxParen > splitPoint) + splitPoint = maxParen; + } + } + + return splitPoint; +} + +void ASFormatter::clearFormattedLineSplitPoints() +{ + maxSemi = 0; + maxAndOr = 0; + maxComma = 0; + maxParen = 0; + maxWhiteSpace = 0; + maxSemiPending = 0; + maxAndOrPending = 0; + maxCommaPending = 0; + maxParenPending = 0; + maxWhiteSpacePending = 0; +} + +/** + * Check if a pointer symbol (->) follows on the currentLine. + */ +bool ASFormatter::pointerSymbolFollows() const +{ + size_t peekNum = currentLine.find_first_not_of(" \t", charNum + 1); + if (peekNum == string::npos || currentLine.compare(peekNum, 2, "->") != 0) + return false; + return true; +} + +/** + * Compute the input checksum. + * This is called as an assert so it for is debug config only + */ +bool ASFormatter::computeChecksumIn(const string& currentLine_) +{ + for (size_t i = 0; i < currentLine_.length(); i++) + if (!isWhiteSpace(currentLine_[i])) + checksumIn += currentLine_[i]; + return true; +} + +/** + * Adjust the input checksum for deleted chars. + * This is called as an assert so it for is debug config only + */ +bool ASFormatter::adjustChecksumIn(int adjustment) +{ + checksumIn += adjustment; + return true; +} + +/** + * get the value of checksumIn for unit testing + * + * @return checksumIn. + */ +size_t ASFormatter::getChecksumIn() const +{ + return checksumIn; +} + +/** + * Compute the output checksum. + * This is called as an assert so it is for debug config only + */ +bool ASFormatter::computeChecksumOut(const string& beautifiedLine) +{ + for (size_t i = 0; i < beautifiedLine.length(); i++) + if (!isWhiteSpace(beautifiedLine[i])) + checksumOut += beautifiedLine[i]; + return true; +} + +/** + * Return isLineReady for the final check at end of file. + */ +bool ASFormatter::getIsLineReady() const +{ + return isLineReady; +} + +/** + * get the value of checksumOut for unit testing + * + * @return checksumOut. + */ +size_t ASFormatter::getChecksumOut() const +{ + return checksumOut; +} + +/** + * Return the difference in checksums. + * If zero all is okay. + */ +int ASFormatter::getChecksumDiff() const +{ + return checksumOut - checksumIn; +} + +// for unit testing +int ASFormatter::getFormatterFileType() const +{ + return formatterFileType; +} + +// Check if an operator follows the next word. +// The next word must be a legal name. +const string* ASFormatter::getFollowingOperator() const +{ + // find next word + size_t nextNum = currentLine.find_first_not_of(" \t", charNum + 1); + if (nextNum == string::npos) + return NULL; + + if (!isLegalNameChar(currentLine[nextNum])) + return NULL; + + // bypass next word and following spaces + while (nextNum < currentLine.length()) + { + if (!isLegalNameChar(currentLine[nextNum]) + && !isWhiteSpace(currentLine[nextNum])) + break; + nextNum++; + } + + if (nextNum >= currentLine.length() + || !isCharPotentialOperator(currentLine[nextNum]) + || currentLine[nextNum] == '/') // comment + return NULL; + + const string* newOperator = ASBeautifier::findOperator(currentLine, nextNum, operators); + return newOperator; +} + +// Check following data to determine if the current character is an array operator. +bool ASFormatter::isArrayOperator() const +{ + assert(currentChar == '*' || currentChar == '&' || currentChar == '^'); + assert(isBracketType(bracketTypeStack->back(), ARRAY_TYPE)); + + // find next word + size_t nextNum = currentLine.find_first_not_of(" \t", charNum + 1); + if (nextNum == string::npos) + return false; + + if (!isLegalNameChar(currentLine[nextNum])) + return false; + + // bypass next word and following spaces + while (nextNum < currentLine.length()) + { + if (!isLegalNameChar(currentLine[nextNum]) + && !isWhiteSpace(currentLine[nextNum])) + break; + nextNum++; + } + + // check for characters that indicate an operator + if (currentLine[nextNum] == ',' + || currentLine[nextNum] == '}' + || currentLine[nextNum] == ')' + || currentLine[nextNum] == '(') + return true; + return false; +} + +// Reset the flags that indicate various statement information. +void ASFormatter::resetEndOfStatement() +{ + foundQuestionMark = false; + foundNamespaceHeader = false; + foundClassHeader = false; + foundStructHeader = false; + foundInterfaceHeader = false; + foundPreDefinitionHeader = false; + foundPreCommandHeader = false; + foundPreCommandMacro = false; + foundCastOperator = false; + isInPotentialCalculation = false; + isSharpAccessor = false; + isSharpDelegate = false; + isInObjCMethodDefinition = false; + isInObjCInterface = false; + isInObjCSelector = false; + isInEnum = false; + isInExternC = false; + elseHeaderFollowsComments = false; + nonInStatementBracket = 0; + while (!questionMarkStack->empty()) + questionMarkStack->pop_back(); +} + +// Find the colon alignment for an Objective-C method definition. +int ASFormatter::findObjCColonAlignment() const +{ + assert(currentChar == '+' || currentChar == '-'); + assert(getAlignMethodColon()); + + bool isFirstLine = true; + bool haveFirstColon = false; + bool needReset = false; + bool isInComment_ = false; + bool isInQuote_ = false; + char quoteChar_ = ' '; + int colonAdjust = 0; + int colonAlign = 0; + string nextLine_ = currentLine; + + // peek next line + while (sourceIterator->hasMoreLines() || isFirstLine) + { + if (!isFirstLine) + { + nextLine_ = sourceIterator->peekNextLine(); + needReset = true; + } + // parse the line + haveFirstColon = false; + nextLine_ = ASBeautifier::trim(nextLine_); + for (size_t i = 0; i < nextLine_.length(); i++) + { + if (isWhiteSpace(nextLine_[i])) + continue; + if (nextLine_.compare(i, 2, "/*") == 0) + isInComment_ = true; + if (isInComment_) + { + if (nextLine_.compare(i, 2, "*/") == 0) + { + isInComment_ = false; + ++i; + } + continue; + } + if (nextLine_[i] == '\\') + { + ++i; + continue; + } + if (isInQuote_) + { + if (nextLine_[i] == quoteChar_) + isInQuote_ = false; + continue; + } + + if (nextLine_[i] == '"' + || (nextLine_[i] == '\'' && !isDigitSeparator(nextLine_, i))) + { + isInQuote_ = true; + quoteChar_ = nextLine_[i]; + continue; + } + if (nextLine_.compare(i, 2, "//") == 0) + { + i = nextLine_.length(); + continue; + } + // process the current char + if (nextLine_[i] == '{' || nextLine_[i] == ';') + goto EndOfWhileLoop; + if (isFirstLine) // colon align does not include the first line + continue; + if (haveFirstColon) + continue; + // compute colon adjustment + if (nextLine_[i] == ':') + { + haveFirstColon = true; + if (shouldPadMethodColon) + { + int spacesStart; + for (spacesStart = i; spacesStart > 0; spacesStart--) + if (!isWhiteSpace(nextLine_[spacesStart - 1])) + break; + int spaces = i - spacesStart; + if (objCColonPadMode == COLON_PAD_ALL || objCColonPadMode == COLON_PAD_BEFORE) + colonAdjust = 1 - spaces; + else if (objCColonPadMode == COLON_PAD_NONE || objCColonPadMode == COLON_PAD_AFTER) + colonAdjust = 0 - spaces; + } + // compute alignment + int colonPosition = i + colonAdjust; + if (colonPosition > colonAlign) + colonAlign = colonPosition; + } + } // end of for loop + isFirstLine = false; + } // end of while loop +EndOfWhileLoop: + if (needReset) + sourceIterator->peekReset(); + return colonAlign; +} + +// pad an Objective-C method colon +void ASFormatter::padObjCMethodColon() +{ + assert(currentChar == ':'); + int commentAdjust = 0; + char nextChar = peekNextChar(); + if (objCColonPadMode == COLON_PAD_NONE + || objCColonPadMode == COLON_PAD_AFTER + || nextChar == ')') + { + // remove spaces before + for (int i = formattedLine.length() - 1; (i > -1) && isWhiteSpace(formattedLine[i]); i--) + { + formattedLine.erase(i); + --commentAdjust; + } + } + else + { + // pad space before + for (int i = formattedLine.length() - 1; (i > 0) && isWhiteSpace(formattedLine[i]); i--) + if (isWhiteSpace(formattedLine[i - 1])) + { + formattedLine.erase(i); + --commentAdjust; + } + appendSpacePad(); + } + if (objCColonPadMode == COLON_PAD_NONE + || objCColonPadMode == COLON_PAD_BEFORE + || nextChar == ')') + { + // remove spaces after + int nextText = currentLine.find_first_not_of(" \t", charNum + 1); + if (nextText == (int)string::npos) + nextText = currentLine.length(); + int spaces = nextText - charNum - 1; + if (spaces > 0) + { + // do not use goForward here + currentLine.erase(charNum + 1, spaces); + spacePadNum -= spaces; + } + } + else + { + // pad space after + int nextText = currentLine.find_first_not_of(" \t", charNum + 1); + if (nextText == (int)string::npos) + nextText = currentLine.length(); + int spaces = nextText - charNum - 1; + if (spaces == 0) + { + currentLine.insert(charNum + 1, 1, ' '); + spacePadNum += 1; + } + else if (spaces > 1) + { + // do not use goForward here + currentLine.erase(charNum + 1, spaces - 1); + spacePadNum -= spaces - 1; + } + } + spacePadNum += commentAdjust; +} + +// Remove the leading '*' from a comment line and indent to the next tab. +void ASFormatter::stripCommentPrefix() +{ + int firstChar = formattedLine.find_first_not_of(" \t"); + if (firstChar < 0) + return; + + if (isInCommentStartLine) + { + // comment opener must begin the line + if (formattedLine.compare(firstChar, 2, "/*") != 0) + return; + int commentOpener = firstChar; + // ignore single line comments + int commentEnd = formattedLine.find("*/", firstChar + 2); + if (commentEnd != -1) + return; + // first char after the comment opener must be at least one indent + int followingText = formattedLine.find_first_not_of(" \t", commentOpener + 2); + if (followingText < 0) + return; + if (formattedLine[followingText] == '*' || formattedLine[followingText] == '!') + followingText = formattedLine.find_first_not_of(" \t", followingText + 1); + if (followingText < 0) + return; + if (formattedLine[followingText] == '*') + return; + int indentLen = getIndentLength(); + int followingTextIndent = followingText - commentOpener; + if (followingTextIndent < indentLen) + { + string stringToInsert(indentLen - followingTextIndent, ' '); + formattedLine.insert(followingText, stringToInsert); + } + return; + } + // comment body including the closer + else if (formattedLine[firstChar] == '*') + { + if (formattedLine.compare(firstChar, 2, "*/") == 0) + { + // line starts with an end comment + formattedLine = "*/"; + } + else + { + // build a new line with one indent + int secondChar = formattedLine.find_first_not_of(" \t", firstChar + 1); + if (secondChar < 0) + { + adjustChecksumIn(-'*'); + formattedLine.erase(); + return; + } + if (formattedLine[secondChar] == '*') + return; + // replace the leading '*' + int indentLen = getIndentLength(); + adjustChecksumIn(-'*'); + // second char must be at least one indent + if (formattedLine.substr(0, secondChar).find('\t') != string::npos) + { + formattedLine.erase(firstChar, 1); + } + else + { + int spacesToInsert = 0; + if (secondChar >= indentLen) + spacesToInsert = secondChar; + else + spacesToInsert = indentLen; + formattedLine = string(spacesToInsert, ' ') + formattedLine.substr(secondChar); + } + // remove a trailing '*' + int lastChar = formattedLine.find_last_not_of(" \t"); + if (lastChar > -1 && formattedLine[lastChar] == '*') + { + adjustChecksumIn(-'*'); + formattedLine[lastChar] = ' '; + } + } + } + else + { + // first char not a '*' + // first char must be at least one indent + if (formattedLine.substr(0, firstChar).find('\t') == string::npos) + { + int indentLen = getIndentLength(); + if (firstChar < indentLen) + { + string stringToInsert(indentLen, ' '); + formattedLine = stringToInsert + formattedLine.substr(firstChar); + } + } + } +} + +} // end namespace astyle diff --git a/External/Tools/AStyle/src/ASLocalizer.cpp b/External/Tools/AStyle/src/ASLocalizer.cpp new file mode 100644 index 0000000000..aac76a95bf --- /dev/null +++ b/External/Tools/AStyle/src/ASLocalizer.cpp @@ -0,0 +1,881 @@ +// FILE ENCODING IS UTF-8 WITHOUT A BOM. +// русский 中文(简体) 日本 한국의 +// +// ASLocalizer.cpp +// Copyright (c) 2016 by Jim Pattee . +// Licensed under the MIT license. + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * To add a new language: + * + * Add a new translation class to ASLocalizer.h. + * Add the Add the English-Translation pair to the constructor in ASLocalizer.cpp. + * Update the WinLangCode array, if necessary. + * Add the language code to the function setTranslationClass(). + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ + +//---------------------------------------------------------------------------- +// headers +//---------------------------------------------------------------------------- + +#include "ASLocalizer.h" + +#ifdef _WIN32 + #include +#endif + +#ifdef __DMC__ + // digital mars doesn't have these + const size_t SUBLANG_CHINESE_MACAU = 5; + const size_t LANG_HINDI = 57; +#endif + +#ifdef __VMS + #define __USE_STD_IOSTREAM 1 + #include +#else + #include +#endif + +#include +#include +#include // needed by some compilers +#include +#include + +#ifdef _MSC_VER + #pragma warning(disable: 4996) // secure version deprecation warnings +#endif + +#ifdef __BORLANDC__ + #pragma warn -8104 // Local Static with constructor dangerous for multi-threaded apps +#endif + +#ifdef __INTEL_COMPILER + #pragma warning(disable: 383) // value copied to temporary, reference to temporary used + #pragma warning(disable: 981) // operands are evaluated in unspecified order +#endif + +#ifdef __clang__ + #pragma clang diagnostic ignored "-Wdeprecated-declarations" // wcstombs +#endif + +namespace astyle { + +#ifndef ASTYLE_LIB + +//---------------------------------------------------------------------------- +// ASLocalizer class methods. +//---------------------------------------------------------------------------- + +ASLocalizer::ASLocalizer() +// Set the locale information. +{ + // set language default values to english (ascii) + // this will be used if a locale or a language cannot be found + m_localeName = "UNKNOWN"; + m_langID = "en"; + m_lcid = 0; + m_subLangID.clear(); + m_translation = NULL; + + // Not all compilers support the C++ function locale::global(locale("")); + // For testing on Windows change the "Region and Language" settings or use AppLocale. + // For testing on Linux change the LANG environment variable: LANG=fr_FR.UTF-8. + // setlocale() will use the LANG environment variable on Linux. + + char* localeName = setlocale(LC_ALL, ""); + if (localeName == NULL) // use the english (ascii) defaults + { + fprintf(stderr, "\n%s\n\n", "Cannot set native locale, reverting to English"); + setTranslationClass(); + return; + } + // set the class variables +#ifdef _WIN32 + size_t lcid = GetUserDefaultLCID(); + setLanguageFromLCID(lcid); +#else + setLanguageFromName(localeName); +#endif +} + +ASLocalizer::~ASLocalizer() +// Delete dynamically allocated memory. +{ + delete m_translation; +} + +#ifdef _WIN32 + +struct WinLangCode +{ + size_t winLang; + char canonicalLang[3]; +}; + +static WinLangCode wlc[] = +// primary language identifier http://msdn.microsoft.com/en-us/library/aa912554.aspx +// sublanguage identifier http://msdn.microsoft.com/en-us/library/aa913256.aspx +// language ID http://msdn.microsoft.com/en-us/library/ee797784%28v=cs.20%29.aspx +{ + { LANG_CHINESE, "zh" }, + { LANG_DUTCH, "nl" }, + { LANG_ENGLISH, "en" }, + { LANG_FINNISH, "fi" }, + { LANG_FRENCH, "fr" }, + { LANG_GERMAN, "de" }, + { LANG_HINDI, "hi" }, + { LANG_ITALIAN, "it" }, + { LANG_JAPANESE, "ja" }, + { LANG_KOREAN, "ko" }, + { LANG_POLISH, "pl" }, + { LANG_PORTUGUESE, "pt" }, + { LANG_RUSSIAN, "ru" }, + { LANG_SPANISH, "es" }, + { LANG_SWEDISH, "sv" }, + { LANG_UKRAINIAN, "uk" }, +}; + +void ASLocalizer::setLanguageFromLCID(size_t lcid) +// Windows get the language to use from the user locale. +// NOTE: GetUserDefaultLocaleName() gets nearly the same name as Linux. +// But it needs Windows Vista or higher. +// Same with LCIDToLocaleName(). +{ + m_lcid = lcid; + m_langID = "en"; // default to english + + size_t lang = PRIMARYLANGID(LANGIDFROMLCID(m_lcid)); + size_t sublang = SUBLANGID(LANGIDFROMLCID(m_lcid)); + // find language in the wlc table + size_t count = sizeof(wlc) / sizeof(wlc[0]); + for (size_t i = 0; i < count; i++) + { + if (wlc[i].winLang == lang) + { + m_langID = wlc[i].canonicalLang; + break; + } + } + if (m_langID == "zh") + { + if (sublang == SUBLANG_CHINESE_SIMPLIFIED || sublang == SUBLANG_CHINESE_SINGAPORE) + m_subLangID = "CHS"; + else + m_subLangID = "CHT"; // default + } + setTranslationClass(); +} + +#endif // _win32 + +string ASLocalizer::getLanguageID() const +// Returns the language ID in m_langID. +{ + return m_langID; +} + +const Translation* ASLocalizer::getTranslationClass() const +// Returns the name of the translation class in m_translation. Used for testing. +{ + assert(m_translation); + return m_translation; +} + +void ASLocalizer::setLanguageFromName(const char* langID) +// Linux set the language to use from the langID. +// +// the language string has the following form +// +// lang[_LANG][.encoding][@modifier] +// +// (see environ(5) in the Open Unix specification) +// +// where lang is the primary language, LANG is a sublang/territory, +// encoding is the charset to use and modifier "allows the user to select +// a specific instance of localization data within a single category" +// +// for example, the following strings are valid: +// fr +// fr_FR +// de_DE.iso88591 +// de_DE@euro +// de_DE.iso88591@euro +{ + // the constants describing the format of lang_LANG locale string + static const size_t LEN_LANG = 2; + + m_lcid = 0; + string langStr = langID; + m_langID = langStr.substr(0, LEN_LANG); + + // need the sublang for chinese + if (m_langID == "zh" && langStr[LEN_LANG] == '_') + { + string subLang = langStr.substr(LEN_LANG + 1, LEN_LANG); + if (subLang == "CN" || subLang == "SG") + m_subLangID = "CHS"; + else + m_subLangID = "CHT"; // default + } + setTranslationClass(); +} + +const char* ASLocalizer::settext(const char* textIn) const +// Call the settext class and return the value. +{ + assert(m_translation); + const string stringIn = textIn; + return m_translation->translate(stringIn).c_str(); +} + +void ASLocalizer::setTranslationClass() +// Return the required translation class. +// Sets the class variable m_translation from the value of m_langID. +// Get the language ID at http://msdn.microsoft.com/en-us/library/ee797784%28v=cs.20%29.aspx +{ + assert(m_langID.length()); + // delete previously set (--ascii option) + if (m_translation) + { + delete m_translation; + m_translation = NULL; + } + if (m_langID == "zh" && m_subLangID == "CHS") + m_translation = new ChineseSimplified; + else if (m_langID == "zh" && m_subLangID == "CHT") + m_translation = new ChineseTraditional; + else if (m_langID == "nl") + m_translation = new Dutch; + else if (m_langID == "en") + m_translation = new English; + else if (m_langID == "fi") + m_translation = new Finnish; + else if (m_langID == "fr") + m_translation = new French; + else if (m_langID == "de") + m_translation = new German; + else if (m_langID == "hi") + m_translation = new Hindi; + else if (m_langID == "it") + m_translation = new Italian; + else if (m_langID == "ja") + m_translation = new Japanese; + else if (m_langID == "ko") + m_translation = new Korean; + else if (m_langID == "pl") + m_translation = new Polish; + else if (m_langID == "pt") + m_translation = new Portuguese; + else if (m_langID == "ru") + m_translation = new Russian; + else if (m_langID == "es") + m_translation = new Spanish; + else if (m_langID == "sv") + m_translation = new Swedish; + else if (m_langID == "uk") + m_translation = new Ukrainian; + else // default + m_translation = new English; +} + +//---------------------------------------------------------------------------- +// Translation base class methods. +//---------------------------------------------------------------------------- + +void Translation::addPair(const string& english, const wstring& translated) +// Add a string pair to the translation vector. +{ + pair entry(english, translated); + m_translation.push_back(entry); +} + +string Translation::convertToMultiByte(const wstring& wideStr) const +// Convert wchar_t to a multibyte string using the currently assigned locale. +// Return an empty string if an error occurs. +{ + static bool msgDisplayed = false; + // get length of the output excluding the NULL and validate the parameters + size_t mbLen = wcstombs(NULL, wideStr.c_str(), 0); + if (mbLen == string::npos) + { + if (!msgDisplayed) + { + fprintf(stderr, "\n%s\n\n", "Cannot convert to multi-byte string, reverting to English"); + msgDisplayed = true; + } + return ""; + } + // convert the characters + char* mbStr = new(nothrow) char[mbLen + 1]; + if (mbStr == NULL) + { + if (!msgDisplayed) + { + fprintf(stderr, "\n%s\n\n", "Bad memory alloc for multi-byte string, reverting to English"); + msgDisplayed = true; + } + return ""; + } + wcstombs(mbStr, wideStr.c_str(), mbLen + 1); + // return the string + string mbTranslation = mbStr; + delete [] mbStr; + return mbTranslation; +} + +size_t Translation::getTranslationVectorSize() const +// Return the translation vector size. Used for testing. +{ + return m_translation.size(); +} + +bool Translation::getWideTranslation(const string& stringIn, wstring& wideOut) const +// Get the wide translation string. Used for testing. +{ + for (size_t i = 0; i < m_translation.size(); i++) + { + if (m_translation[i].first == stringIn) + { + wideOut = m_translation[i].second; + return true; + } + } + // not found + wideOut = L""; + return false; +} + +string& Translation::translate(const string& stringIn) const +// Translate a string. +// Return a static string instead of a member variable so the method can have a "const" designation. +// This allows "settext" to be called from a "const" method. +{ + static string mbTranslation; + mbTranslation.clear(); + for (size_t i = 0; i < m_translation.size(); i++) + { + if (m_translation[i].first == stringIn) + { + mbTranslation = convertToMultiByte(m_translation[i].second); + break; + } + } + // not found, return english + if (mbTranslation.empty()) + mbTranslation = stringIn; + return mbTranslation; +} + +//---------------------------------------------------------------------------- +// Translation class methods. +// These classes have only a constructor which builds the language vector. +//---------------------------------------------------------------------------- + +ChineseSimplified::ChineseSimplified() // 中文(简体) +{ + addPair("Formatted %s\n", L"格式化 %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"未改变 %s\n"); // should align with formatted + addPair("Directory %s\n", L"目录 %s\n"); + addPair("Exclude %s\n", L"排除 %s\n"); + addPair("Exclude (unmatched) %s\n", L"排除(无匹配项) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s 格式化 %s 未改变 "); + addPair(" seconds ", L" 秒 "); + addPair("%d min %d sec ", L"%d 分 %d 秒 "); + addPair("%s lines\n", L"%s 行\n"); + addPair("Using default options file %s\n", L"使用默认配置文件 %s\n"); + addPair("Opening HTML documentation %s\n", L"打开HTML文档 %s\n"); + addPair("Invalid option file options:", L"无效的配置文件选项:"); + addPair("Invalid command line options:", L"无效的命令行选项:"); + addPair("For help on options type 'astyle -h'", L"输入 'astyle -h' 以获得有关命令行的帮助"); + addPair("Cannot open options file", L"无法打开配置文件"); + addPair("Cannot open directory", L"无法打开目录"); + addPair("Cannot open HTML file %s\n", L"无法打开HTML文件 %s\n"); + addPair("Command execute failure", L"执行命令失败"); + addPair("Command is not installed", L"未安装命令"); + addPair("Missing filename in %s\n", L"在%s缺少文件名\n"); + addPair("Recursive option with no wildcard", L"递归选项没有通配符"); + addPair("Did you intend quote the filename", L"你打算引用文件名"); + addPair("No file to process %s\n", L"没有文件可处理 %s\n"); + addPair("Did you intend to use --recursive", L"你打算使用 --recursive"); + addPair("Cannot process UTF-32 encoding", L"不能处理UTF-32编码"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style 已经终止运行"); +} + +ChineseTraditional::ChineseTraditional() // 中文(繁體) +{ + addPair("Formatted %s\n", L"格式化 %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"未改變 %s\n"); // should align with formatted + addPair("Directory %s\n", L"目錄 %s\n"); + addPair("Exclude %s\n", L"排除 %s\n"); + addPair("Exclude (unmatched) %s\n", L"排除(無匹配項) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s 格式化 %s 未改變 "); + addPair(" seconds ", L" 秒 "); + addPair("%d min %d sec ", L"%d 分 %d 秒 "); + addPair("%s lines\n", L"%s 行\n"); + addPair("Using default options file %s\n", L"使用默認配置文件 %s\n"); + addPair("Opening HTML documentation %s\n", L"打開HTML文檔 %s\n"); + addPair("Invalid option file options:", L"無效的配置文件選項:"); + addPair("Invalid command line options:", L"無效的命令行選項:"); + addPair("For help on options type 'astyle -h'", L"輸入'astyle -h'以獲得有關命令行的幫助:"); + addPair("Cannot open options file", L"無法打開配置文件"); + addPair("Cannot open directory", L"無法打開目錄"); + addPair("Cannot open HTML file %s\n", L"無法打開HTML文件 %s\n"); + addPair("Command execute failure", L"執行命令失敗"); + addPair("Command is not installed", L"未安裝命令"); + addPair("Missing filename in %s\n", L"在%s缺少文件名\n"); + addPair("Recursive option with no wildcard", L"遞歸選項沒有通配符"); + addPair("Did you intend quote the filename", L"你打算引用文件名"); + addPair("No file to process %s\n", L"沒有文件可處理 %s\n"); + addPair("Did you intend to use --recursive", L"你打算使用 --recursive"); + addPair("Cannot process UTF-32 encoding", L"不能處理UTF-32編碼"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style 已經終止運行"); +} + +Dutch::Dutch() // Nederlandse +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Geformatteerd %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Onveranderd %s\n"); // should align with formatted + addPair("Directory %s\n", L"Directory %s\n"); + addPair("Exclude %s\n", L"Uitsluiten %s\n"); + addPair("Exclude (unmatched) %s\n", L"Uitgesloten (ongeëvenaarde) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s geformatteerd %s onveranderd "); + addPair(" seconds ", L" seconden "); + addPair("%d min %d sec ", L"%d min %d sec "); + addPair("%s lines\n", L"%s lijnen\n"); + addPair("Using default options file %s\n", L"Met behulp van standaard opties bestand %s\n"); + addPair("Opening HTML documentation %s\n", L"Het openen van HTML-documentatie %s\n"); + addPair("Invalid option file options:", L"Ongeldige optie file opties:"); + addPair("Invalid command line options:", L"Ongeldige command line opties:"); + addPair("For help on options type 'astyle -h'", L"Voor hulp bij 'astyle-h' opties het type"); + addPair("Cannot open options file", L"Kan niet worden geopend options bestand"); + addPair("Cannot open directory", L"Kan niet open directory"); + addPair("Cannot open HTML file %s\n", L"Kan HTML-bestand niet openen %s\n"); + addPair("Command execute failure", L"Voeren commando falen"); + addPair("Command is not installed", L"Command is niet geïnstalleerd"); + addPair("Missing filename in %s\n", L"Ontbrekende bestandsnaam in %s\n"); + addPair("Recursive option with no wildcard", L"Recursieve optie met geen wildcard"); + addPair("Did you intend quote the filename", L"Heeft u van plan citaat van de bestandsnaam"); + addPair("No file to process %s\n", L"Geen bestand te verwerken %s\n"); + addPair("Did you intend to use --recursive", L"Hebt u van plan bent te gebruiken --recursive"); + addPair("Cannot process UTF-32 encoding", L"Kan niet verwerken UTF-32 codering"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style heeft beëindigd"); +} + +English::English() +// this class is NOT translated +{} + +Finnish::Finnish() // Suomeksi +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Muotoiltu %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Ennallaan %s\n"); // should align with formatted + addPair("Directory %s\n", L"Directory %s\n"); + addPair("Exclude %s\n", L"Sulkea %s\n"); + addPair("Exclude (unmatched) %s\n", L"Sulkea (verraton) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s muotoiltu %s ennallaan "); + addPair(" seconds ", L" sekuntia "); + addPair("%d min %d sec ", L"%d min %d sek "); + addPair("%s lines\n", L"%s linjat\n"); + addPair("Using default options file %s\n", L"Käyttämällä oletusasetuksia tiedosto %s\n"); + addPair("Opening HTML documentation %s\n", L"Avaaminen HTML asiakirjat %s\n"); + addPair("Invalid option file options:", L"Virheellinen vaihtoehto tiedosto vaihtoehtoja:"); + addPair("Invalid command line options:", L"Virheellinen komentorivin:"); + addPair("For help on options type 'astyle -h'", L"Apua vaihtoehdoista tyyppi 'astyle -h'"); + addPair("Cannot open options file", L"Ei voi avata vaihtoehtoja tiedostoa"); + addPair("Cannot open directory", L"Ei Open Directory"); + addPair("Cannot open HTML file %s\n", L"Ei voi avata HTML-tiedoston %s\n"); + addPair("Command execute failure", L"Suorita komento vika"); + addPair("Command is not installed", L"Komento ei ole asennettu"); + addPair("Missing filename in %s\n", L"Puuttuvat tiedostonimi %s\n"); + addPair("Recursive option with no wildcard", L"Rekursiivinen vaihtoehto ilman wildcard"); + addPair("Did you intend quote the filename", L"Oletko aio lainata tiedostonimi"); + addPair("No file to process %s\n", L"Ei tiedostoa käsitellä %s\n"); + addPair("Did you intend to use --recursive", L"Oliko aiot käyttää --recursive"); + addPair("Cannot process UTF-32 encoding", L"Ei voi käsitellä UTF-32 koodausta"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style on päättynyt"); +} + +French::French() // Française +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Formaté %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Inchangée %s\n"); // should align with formatted + addPair("Directory %s\n", L"Répertoire %s\n"); + addPair("Exclude %s\n", L"Exclure %s\n"); + addPair("Exclude (unmatched) %s\n", L"Exclure (non appariés) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s formaté %s inchangée "); + addPair(" seconds ", L" seconde "); + addPair("%d min %d sec ", L"%d min %d sec "); + addPair("%s lines\n", L"%s lignes\n"); + addPair("Using default options file %s\n", L"Options par défaut utilisation du fichier %s\n"); + addPair("Opening HTML documentation %s\n", L"Ouverture documentation HTML %s\n"); + addPair("Invalid option file options:", L"Options Blancs option du fichier:"); + addPair("Invalid command line options:", L"Blancs options ligne de commande:"); + addPair("For help on options type 'astyle -h'", L"Pour de l'aide sur les options tapez 'astyle -h'"); + addPair("Cannot open options file", L"Impossible d'ouvrir le fichier d'options"); + addPair("Cannot open directory", L"Impossible d'ouvrir le répertoire"); + addPair("Cannot open HTML file %s\n", L"Impossible d'ouvrir le fichier HTML %s\n"); + addPair("Command execute failure", L"Exécuter échec de la commande"); + addPair("Command is not installed", L"Commande n'est pas installé"); + addPair("Missing filename in %s\n", L"Nom de fichier manquant dans %s\n"); + addPair("Recursive option with no wildcard", L"Option récursive sans joker"); + addPair("Did you intend quote the filename", L"Avez-vous l'intention de citer le nom de fichier"); + addPair("No file to process %s\n", L"Aucun fichier à traiter %s\n"); + addPair("Did you intend to use --recursive", L"Avez-vous l'intention d'utiliser --recursive"); + addPair("Cannot process UTF-32 encoding", L"Impossible de traiter codage UTF-32"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style a mis fin"); +} + +German::German() // Deutsch +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Formatiert %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Unverändert %s\n"); // should align with formatted + addPair("Directory %s\n", L"Verzeichnis %s\n"); + addPair("Exclude %s\n", L"Ausschließen %s\n"); + addPair("Exclude (unmatched) %s\n", L"Ausschließen (unerreichte) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s formatiert %s unverändert "); + addPair(" seconds ", L" sekunden "); + addPair("%d min %d sec ", L"%d min %d sek "); + addPair("%s lines\n", L"%s linien\n"); + addPair("Using default options file %s\n", L"Mit Standard-Optionen Dat %s\n"); + addPair("Opening HTML documentation %s\n", L"Öffnen HTML-Dokumentation %s\n"); + addPair("Invalid option file options:", L"Ungültige Option Datei-Optionen:"); + addPair("Invalid command line options:", L"Ungültige Kommandozeilen-Optionen:"); + addPair("For help on options type 'astyle -h'", L"Für Hilfe zu den Optionen geben Sie 'astyle -h'"); + addPair("Cannot open options file", L"Kann nicht geöffnet werden Optionsdatei"); + addPair("Cannot open directory", L"Kann nicht geöffnet werden Verzeichnis"); + addPair("Cannot open HTML file %s\n", L"Kann nicht öffnen HTML-Datei %s\n"); + addPair("Command execute failure", L"Execute Befehl Scheitern"); + addPair("Command is not installed", L"Befehl ist nicht installiert"); + addPair("Missing filename in %s\n", L"Missing in %s Dateiname\n"); + addPair("Recursive option with no wildcard", L"Rekursive Option ohne Wildcard"); + addPair("Did you intend quote the filename", L"Haben Sie die Absicht Inhalte der Dateiname"); + addPair("No file to process %s\n", L"Keine Datei zu verarbeiten %s\n"); + addPair("Did you intend to use --recursive", L"Haben Sie verwenden möchten --recursive"); + addPair("Cannot process UTF-32 encoding", L"Nicht verarbeiten kann UTF-32 Codierung"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style ist beendet"); +} + +Hindi::Hindi() // हिन्दी +// build the translation vector in the Translation base class +{ + // NOTE: Scintilla based editors (CodeBlocks) cannot always edit Hindi. + // Use Visual Studio instead. + addPair("Formatted %s\n", L"स्वरूपित किया %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"अपरिवर्तित %s\n"); // should align with formatted + addPair("Directory %s\n", L"निर्देशिका %s\n"); + addPair("Exclude %s\n", L"निकालना %s\n"); + addPair("Exclude (unmatched) %s\n", L"अपवर्जित (बेजोड़) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s स्वरूपित किया %s अपरिवर्तित "); + addPair(" seconds ", L" सेकंड "); + addPair("%d min %d sec ", L"%d मिनट %d सेकंड "); + addPair("%s lines\n", L"%s लाइनों\n"); + addPair("Using default options file %s\n", L"डिफ़ॉल्ट विकल्प का उपयोग कर फ़ाइल %s\n"); + addPair("Opening HTML documentation %s\n", L"एचटीएमएल प्रलेखन खोलना %s\n"); + addPair("Invalid option file options:", L"अवैध विकल्प फ़ाइल विकल्प हैं:"); + addPair("Invalid command line options:", L"कमांड लाइन विकल्प अवैध:"); + addPair("For help on options type 'astyle -h'", L"विकल्पों पर मदद के लिए प्रकार 'astyle -h'"); + addPair("Cannot open options file", L"विकल्प फ़ाइल नहीं खोल सकता है"); + addPair("Cannot open directory", L"निर्देशिका नहीं खोल सकता"); + addPair("Cannot open HTML file %s\n", L"HTML फ़ाइल नहीं खोल सकता %s\n"); + addPair("Command execute failure", L"आदेश विफलता निष्पादित"); + addPair("Command is not installed", L"कमान स्थापित नहीं है"); + addPair("Missing filename in %s\n", L"लापता में फ़ाइलनाम %s\n"); + addPair("Recursive option with no wildcard", L"कोई वाइल्डकार्ड साथ पुनरावर्ती विकल्प"); + addPair("Did you intend quote the filename", L"क्या आप बोली फ़ाइलनाम का इरादा"); + addPair("No file to process %s\n", L"कोई फ़ाइल %s प्रक्रिया के लिए\n"); + addPair("Did you intend to use --recursive", L"क्या आप उपयोग करना चाहते हैं --recursive"); + addPair("Cannot process UTF-32 encoding", L"UTF-32 कूटबन्धन प्रक्रिया नहीं कर सकते"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style समाप्त किया है"); +} + +Italian::Italian() // Italiano +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Formattata %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Immutato %s\n"); // should align with formatted + addPair("Directory %s\n", L"Elenco %s\n"); + addPair("Exclude %s\n", L"Escludere %s\n"); + addPair("Exclude (unmatched) %s\n", L"Escludere (senza pari) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s ormattata %s immutato "); + addPair(" seconds ", L" secondo "); + addPair("%d min %d sec ", L"%d min %d seg "); + addPair("%s lines\n", L"%s linee\n"); + addPair("Using default options file %s\n", L"Utilizzando file delle opzioni di default %s\n"); + addPair("Opening HTML documentation %s\n", L"Apertura di documenti HTML %s\n"); + addPair("Invalid option file options:", L"Opzione non valida file delle opzioni:"); + addPair("Invalid command line options:", L"Opzioni della riga di comando non valido:"); + addPair("For help on options type 'astyle -h'", L"Per informazioni sulle opzioni di tipo 'astyle-h'"); + addPair("Cannot open options file", L"Impossibile aprire il file opzioni"); + addPair("Cannot open directory", L"Impossibile aprire la directory"); + addPair("Cannot open HTML file %s\n", L"Impossibile aprire il file HTML %s\n"); + addPair("Command execute failure", L"Esegui fallimento comando"); + addPair("Command is not installed", L"Il comando non è installato"); + addPair("Missing filename in %s\n", L"Nome del file mancante in %s\n"); + addPair("Recursive option with no wildcard", L"Opzione ricorsiva senza jolly"); + addPair("Did you intend quote the filename", L"Avete intenzione citare il nome del file"); + addPair("No file to process %s\n", L"Nessun file al processo %s\n"); + addPair("Did you intend to use --recursive", L"Hai intenzione di utilizzare --recursive"); + addPair("Cannot process UTF-32 encoding", L"Non è possibile processo di codifica UTF-32"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style ha terminato"); +} + +Japanese::Japanese() // 日本 +{ + addPair("Formatted %s\n", L"フォーマット %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"変更 %s\n"); // should align with formatted + addPair("Directory %s\n", L"ディレクトリ %s\n"); + addPair("Exclude %s\n", L"除外する %s\n"); + addPair("Exclude (unmatched) %s\n", L"除外(マッチせず) %s\n"); + addPair(" %s formatted %s unchanged ", L" %sフォーマット %s 変更 "); + addPair(" seconds ", L" 秒 "); + addPair("%d min %d sec ", L"%d 分 %d 秒 "); + addPair("%s lines\n", L"%s の行\n"); + addPair("Using default options file %s\n", L"デフォルトの設定ファイルを使用してください %s\n"); + addPair("Opening HTML documentation %s\n", L"HTML文書を開く %s\n"); + addPair("Invalid option file options:", L"無効なコンフィギュレーションファイルオプション:"); + addPair("Invalid command line options:", L"無効なコマンドラインオプション:"); + addPair("For help on options type 'astyle -h'", L"コマンドラインについてのヘルプは'astyle- h'を入力してください"); + addPair("Cannot open options file", L"コンフィギュレーションファイルを開くことができません"); + addPair("Cannot open directory", L"ディレクトリのオープンに失敗しました"); + addPair("Cannot open HTML file %s\n", L"HTMLファイルを開くことができません %s\n"); + addPair("Command execute failure", L"コマンドの失敗を実行"); + addPair("Command is not installed", L"コマンドがインストールされていません"); + addPair("Missing filename in %s\n", L"%s はファイル名で欠落しています\n"); + addPair("Recursive option with no wildcard", L"再帰的なオプションではワイルドカードではない"); + addPair("Did you intend quote the filename", L"あなたは、ファイル名を参照するつもり"); + addPair("No file to process %s\n", L"いいえファイルは処理できません %s\n"); + addPair("Did you intend to use --recursive", L"あなたが使用する予定 --recursive"); + addPair("Cannot process UTF-32 encoding", L"UTF- 32エンコーディングを処理できない"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style 実行が終了しました"); +} + +Korean::Korean() // 한국의 +{ + addPair("Formatted %s\n", L"수정됨 %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"변경없음 %s\n"); // should align with formatted + addPair("Directory %s\n", L"디렉토리 %s\n"); + addPair("Exclude %s\n", L"제외됨 %s\n"); + addPair("Exclude (unmatched) %s\n", L"제외 (NO 일치) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s 수정됨 %s 변경없음 "); + addPair(" seconds ", L" 초 "); + addPair("%d min %d sec ", L"%d 분 %d 초 "); + addPair("%s lines\n", L"%s 라인\n"); + addPair("Using default options file %s\n", L"기본 구성 파일을 사용 %s\n"); + addPair("Opening HTML documentation %s\n", L"HTML 문서를 열기 %s\n"); + addPair("Invalid option file options:", L"잘못된 구성 파일 옵션 :"); + addPair("Invalid command line options:", L"잘못된 명령줄 옵션 :"); + addPair("For help on options type 'astyle -h'", L"도움말을 보려면 옵션 유형 'astyle - H'를 사용합니다"); + addPair("Cannot open options file", L"구성 파일을 열 수 없습니다"); + addPair("Cannot open directory", L"디렉토리를 열지 못했습니다"); + addPair("Cannot open HTML file %s\n", L"HTML 파일을 열 수 없습니다 %s\n"); + addPair("Command execute failure", L"명령 실패를 실행"); + addPair("Command is not installed", L"명령이 설치되어 있지 않습니다"); + addPair("Missing filename in %s\n", L"%s 에서 누락된 파일 이름\n"); + addPair("Recursive option with no wildcard", L"와일드 카드없이 재귀 옵션"); + addPair("Did you intend quote the filename", L"당신은 파일 이름을 인용하고자하나요"); + addPair("No file to process %s\n", L"처리할 파일이 없습니다 %s\n"); + addPair("Did you intend to use --recursive", L"--recursive 를 사용하고자 하십니까"); + addPair("Cannot process UTF-32 encoding", L"UTF-32 인코딩을 처리할 수 없습니다"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style를 종료합니다"); +} + +Polish::Polish() // Polski +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Sformatowany %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Niezmienione %s\n"); // should align with formatted + addPair("Directory %s\n", L"Katalog %s\n"); + addPair("Exclude %s\n", L"Wykluczać %s\n"); + addPair("Exclude (unmatched) %s\n", L"Wyklucz (niezrównany) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s sformatowany %s niezmienione "); + addPair(" seconds ", L" sekund "); + addPair("%d min %d sec ", L"%d min %d sek "); + addPair("%s lines\n", L"%s linii\n"); + addPair("Using default options file %s\n", L"Korzystanie z domyślnej opcji %s plik\n"); + addPair("Opening HTML documentation %s\n", L"Otwarcie dokumentacji HTML %s\n"); + addPair("Invalid option file options:", L"Nieprawidłowy opcji pliku opcji:"); + addPair("Invalid command line options:", L"Nieprawidłowe opcje wiersza polecenia:"); + addPair("For help on options type 'astyle -h'", L"Aby uzyskać pomoc od rodzaju opcji 'astyle -h'"); + addPair("Cannot open options file", L"Nie można otworzyć pliku opcji"); + addPair("Cannot open directory", L"Nie można otworzyć katalogu"); + addPair("Cannot open HTML file %s\n", L"Nie można otworzyć pliku HTML %s\n"); + addPair("Command execute failure", L"Wykonaj polecenia niepowodzenia"); + addPair("Command is not installed", L"Polecenie nie jest zainstalowany"); + addPair("Missing filename in %s\n", L"Brakuje pliku w %s\n"); + addPair("Recursive option with no wildcard", L"Rekurencyjne opcja bez symboli"); + addPair("Did you intend quote the filename", L"Czy zamierza Pan podać nazwę pliku"); + addPair("No file to process %s\n", L"Brak pliku do procesu %s\n"); + addPair("Did you intend to use --recursive", L"Czy masz zamiar używać --recursive"); + addPair("Cannot process UTF-32 encoding", L"Nie można procesu kodowania UTF-32"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style został zakończony"); +} + +Portuguese::Portuguese() // Português +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Formatado %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Inalterado %s\n"); // should align with formatted + addPair("Directory %s\n", L"Diretório %s\n"); + addPair("Exclude %s\n", L"Excluir %s\n"); + addPair("Exclude (unmatched) %s\n", L"Excluir (incomparável) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s formatado %s inalterado "); + addPair(" seconds ", L" segundo "); + addPair("%d min %d sec ", L"%d min %d seg "); + addPair("%s lines\n", L"%s linhas\n"); + addPair("Using default options file %s\n", L"Usando o arquivo de opções padrão %s\n"); + addPair("Opening HTML documentation %s\n", L"Abrindo a documentação HTML %s\n"); + addPair("Invalid option file options:", L"Opções de arquivo inválido opção:"); + addPair("Invalid command line options:", L"Opções de linha de comando inválida:"); + addPair("For help on options type 'astyle -h'", L"Para obter ajuda sobre as opções de tipo 'astyle -h'"); + addPair("Cannot open options file", L"Não é possível abrir arquivo de opções"); + addPair("Cannot open directory", L"Não é possível abrir diretório"); + addPair("Cannot open HTML file %s\n", L"Não é possível abrir arquivo HTML %s\n"); + addPair("Command execute failure", L"Executar falha de comando"); + addPair("Command is not installed", L"Comando não está instalado"); + addPair("Missing filename in %s\n", L"Filename faltando em %s\n"); + addPair("Recursive option with no wildcard", L"Opção recursiva sem curinga"); + addPair("Did you intend quote the filename", L"Será que você pretende citar o nome do arquivo"); + addPair("No file to process %s\n", L"Nenhum arquivo para processar %s\n"); + addPair("Did you intend to use --recursive", L"Será que você pretende usar --recursive"); + addPair("Cannot process UTF-32 encoding", L"Não pode processar a codificação UTF-32"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style terminou"); +} + +Russian::Russian() // русский +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Форматированный %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"без изменений %s\n"); // should align with formatted + addPair("Directory %s\n", L"каталог %s\n"); + addPair("Exclude %s\n", L"исключать %s\n"); + addPair("Exclude (unmatched) %s\n", L"Исключить (непревзойденный) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s Форматированный %s без изменений "); + addPair(" seconds ", L" секунды "); + addPair("%d min %d sec ", L"%d мин %d сек "); + addPair("%s lines\n", L"%s линий\n"); + addPair("Using default options file %s\n", L"Использование опции по умолчанию файл %s\n"); + addPair("Opening HTML documentation %s\n", L"Открытие HTML документации %s\n"); + addPair("Invalid option file options:", L"Недопустимый файл опций опцию:"); + addPair("Invalid command line options:", L"Недопустимые параметры командной строки:"); + addPair("For help on options type 'astyle -h'", L"Для получения справки по 'astyle -h' опций типа"); + addPair("Cannot open options file", L"Не удается открыть файл параметров"); + addPair("Cannot open directory", L"Не могу открыть каталог"); + addPair("Cannot open HTML file %s\n", L"Не удается открыть файл HTML %s\n"); + addPair("Command execute failure", L"Выполнить команду недостаточности"); + addPair("Command is not installed", L"Не установлен Команда"); + addPair("Missing filename in %s\n", L"Отсутствует имя файла в %s\n"); + addPair("Recursive option with no wildcard", L"Рекурсивный вариант без каких-либо шаблона"); + addPair("Did you intend quote the filename", L"Вы намерены цитатой файла"); + addPair("No file to process %s\n", L"Нет файлов для обработки %s\n"); + addPair("Did you intend to use --recursive", L"Неужели вы собираетесь использовать --recursive"); + addPair("Cannot process UTF-32 encoding", L"Не удается обработать UTF-32 кодировке"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style прекратил"); +} + +Spanish::Spanish() // Español +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Formato %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Inalterado %s\n"); // should align with formatted + addPair("Directory %s\n", L"Directorio %s\n"); + addPair("Exclude %s\n", L"Excluir %s\n"); + addPair("Exclude (unmatched) %s\n", L"Excluir (incomparable) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s formato %s inalterado "); + addPair(" seconds ", L" segundo "); + addPair("%d min %d sec ", L"%d min %d seg "); + addPair("%s lines\n", L"%s líneas\n"); + addPair("Using default options file %s\n", L"Uso de las opciones por defecto del archivo %s\n"); + addPair("Opening HTML documentation %s\n", L"Apertura de documentación HTML %s\n"); + addPair("Invalid option file options:", L"Opción no válida opciones de archivo:"); + addPair("Invalid command line options:", L"No válido opciones de línea de comando:"); + addPair("For help on options type 'astyle -h'", L"Para obtener ayuda sobre las opciones tipo 'astyle -h'"); + addPair("Cannot open options file", L"No se puede abrir el archivo de opciones"); + addPair("Cannot open directory", L"No se puede abrir el directorio"); + addPair("Cannot open HTML file %s\n", L"No se puede abrir el archivo HTML %s\n"); + addPair("Command execute failure", L"Ejecutar el fracaso de comandos"); + addPair("Command is not installed", L"El comando no está instalado"); + addPair("Missing filename in %s\n", L"Falta nombre del archivo en %s\n"); + addPair("Recursive option with no wildcard", L"Recursiva opción sin comodín"); + addPair("Did you intend quote the filename", L"Se tiene la intención de citar el nombre de archivo"); + addPair("No file to process %s\n", L"No existe el fichero a procesar %s\n"); + addPair("Did you intend to use --recursive", L"Se va a utilizar --recursive"); + addPair("Cannot process UTF-32 encoding", L"No se puede procesar la codificación UTF-32"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style ha terminado"); +} + +Swedish::Swedish() // Svenska +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Formaterade %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Oförändrade %s\n"); // should align with formatted + addPair("Directory %s\n", L"Katalog %s\n"); + addPair("Exclude %s\n", L"Uteslut %s\n"); + addPair("Exclude (unmatched) %s\n", L"Uteslut (oöverträffad) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s formaterade %s oförändrade "); + addPair(" seconds ", L" sekunder "); + addPair("%d min %d sec ", L"%d min %d sek "); + addPair("%s lines\n", L"%s linjer\n"); + addPair("Using default options file %s\n", L"Använda standardalternativ fil %s\n"); + addPair("Opening HTML documentation %s\n", L"Öppna HTML-dokumentation %s\n"); + addPair("Invalid option file options:", L"Ogiltigt alternativ fil alternativ:"); + addPair("Invalid command line options:", L"Ogiltig kommandoraden alternativ:"); + addPair("For help on options type 'astyle -h'", L"För hjälp om alternativ typ 'astyle -h'"); + addPair("Cannot open options file", L"Kan inte öppna inställningsfilen"); + addPair("Cannot open directory", L"Kan inte öppna katalog"); + addPair("Cannot open HTML file %s\n", L"Kan inte öppna HTML-filen %s\n"); + addPair("Command execute failure", L"Utför kommando misslyckande"); + addPair("Command is not installed", L"Kommandot är inte installerat"); + addPair("Missing filename in %s\n", L"Saknade filnamn i %s\n"); + addPair("Recursive option with no wildcard", L"Rekursiva alternativ utan jokertecken"); + addPair("Did you intend quote the filename", L"Visste du tänker citera filnamnet"); + addPair("No file to process %s\n", L"Ingen fil att bearbeta %s\n"); + addPair("Did you intend to use --recursive", L"Har du för avsikt att använda --recursive"); + addPair("Cannot process UTF-32 encoding", L"Kan inte hantera UTF-32 kodning"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style har upphört"); +} + +Ukrainian::Ukrainian() // Український +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"форматований %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"без змін %s\n"); // should align with formatted + addPair("Directory %s\n", L"Каталог %s\n"); + addPair("Exclude %s\n", L"Виключити %s\n"); + addPair("Exclude (unmatched) %s\n", L"Виключити (неперевершений) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s відформатований %s без змін "); + addPair(" seconds ", L" секунди "); + addPair("%d min %d sec ", L"%d хви %d cek "); + addPair("%s lines\n", L"%s ліній\n"); + addPair("Using default options file %s\n", L"Використання файлів опцій за замовчуванням %s\n"); + addPair("Opening HTML documentation %s\n", L"Відкриття HTML документації %s\n"); + addPair("Invalid option file options:", L"Неприпустимий файл опцій опцію:"); + addPair("Invalid command line options:", L"Неприпустима параметри командного рядка:"); + addPair("For help on options type 'astyle -h'", L"Для отримання довідки по 'astyle -h' опцій типу"); + addPair("Cannot open options file", L"Не вдається відкрити файл параметрів"); + addPair("Cannot open directory", L"Не можу відкрити каталог"); + addPair("Cannot open HTML file %s\n", L"Не вдається відкрити файл HTML %s\n"); + addPair("Command execute failure", L"Виконати команду недостатності"); + addPair("Command is not installed", L"Не встановлений Команда"); + addPair("Missing filename in %s\n", L"Відсутня назва файлу в %s\n"); + addPair("Recursive option with no wildcard", L"Рекурсивний варіант без будь-яких шаблону"); + addPair("Did you intend quote the filename", L"Ви маєте намір цитатою файлу"); + addPair("No file to process %s\n", L"Немає файлів для обробки %s\n"); + addPair("Did you intend to use --recursive", L"Невже ви збираєтеся використовувати --recursive"); + addPair("Cannot process UTF-32 encoding", L"Не вдається обробити UTF-32 кодуванні"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style припинив"); +} + + +#endif // ASTYLE_LIB + +} // end of namespace astyle + diff --git a/External/Tools/AStyle/src/ASLocalizer.h b/External/Tools/AStyle/src/ASLocalizer.h new file mode 100644 index 0000000000..eb6a9f3b4c --- /dev/null +++ b/External/Tools/AStyle/src/ASLocalizer.h @@ -0,0 +1,189 @@ +// ASLocalizer.h +// Copyright (c) 2016 by Jim Pattee . +// Licensed under the MIT license. +// License.txt describes the conditions under which this software may be distributed. + + +#ifndef ASLOCALIZER_H +#define ASLOCALIZER_H + +#include +#include + +namespace astyle { + +using namespace std; + +#ifndef ASTYLE_LIB + +//----------------------------------------------------------------------------- +// ASLocalizer class for console build. +// This class encapsulates all language-dependent settings and is a +// generalization of the C locale concept. +//----------------------------------------------------------------------------- +class Translation; + +class ASLocalizer +{ +public: // functions + ASLocalizer(); + virtual ~ASLocalizer(); + string getLanguageID() const; + const Translation* getTranslationClass() const; +#ifdef _WIN32 + void setLanguageFromLCID(size_t lcid); +#endif + void setLanguageFromName(const char* langID); + const char* settext(const char* textIn) const; + +private: // functions + void setTranslationClass(); + +private: // variables + Translation* m_translation; // pointer to a polymorphic Translation class + string m_langID; // language identifier from the locale + string m_subLangID; // sub language identifier, if needed + string m_localeName; // name of the current locale (Linux only) + size_t m_lcid; // LCID of the user locale (Windows only) +}; + +//---------------------------------------------------------------------------- +// Translation base class. +//---------------------------------------------------------------------------- + +class Translation +// This base class is inherited by the language translation classes. +// Polymorphism is used to call the correct language translator. +// This class contains the translation vector and settext translation method. +// The language vector is built by the language sub classes. +// NOTE: This class must have virtual methods for typeid() to work. +// typeid() is used by AStyleTestI18n_Localizer.cpp. +{ +public: + Translation() {} + virtual ~Translation() {} + string convertToMultiByte(const wstring& wideStr) const; + size_t getTranslationVectorSize() const; + bool getWideTranslation(const string& stringIn, wstring& wideOut) const; + string& translate(const string& stringIn) const; + +protected: + void addPair(const string& english, const wstring& translated); + // variables + vector > m_translation; // translation vector +}; + +//---------------------------------------------------------------------------- +// Translation classes +// One class for each language. +// These classes have only a constructor which builds the language vector. +//---------------------------------------------------------------------------- + +class ChineseSimplified : public Translation +{ +public: + ChineseSimplified(); +}; + +class ChineseTraditional : public Translation +{ +public: + ChineseTraditional(); +}; + +class Dutch : public Translation +{ +public: + Dutch(); +}; + +class English : public Translation +{ +public: + English(); +}; + +class Finnish : public Translation +{ +public: + Finnish(); +}; + +class French : public Translation +{ +public: + French(); +}; + +class German : public Translation +{ +public: + German(); +}; + +class Hindi : public Translation +{ +public: + Hindi(); +}; + +class Italian : public Translation +{ +public: + Italian(); +}; + +class Japanese : public Translation +{ +public: + Japanese(); +}; + +class Korean : public Translation +{ +public: + Korean(); +}; + +class Polish : public Translation +{ +public: + Polish(); +}; + +class Portuguese : public Translation +{ +public: + Portuguese(); +}; + +class Russian : public Translation +{ +public: + Russian(); +}; + +class Spanish : public Translation +{ +public: + Spanish(); +}; + +class Swedish : public Translation +{ +public: + Swedish(); +}; + +class Ukrainian : public Translation +{ +public: + Ukrainian(); +}; + + +#endif // ASTYLE_LIB + +} // namespace astyle + +#endif // ASLOCALIZER_H diff --git a/External/Tools/AStyle/src/ASResource.cpp b/External/Tools/AStyle/src/ASResource.cpp new file mode 100644 index 0000000000..012d2dba41 --- /dev/null +++ b/External/Tools/AStyle/src/ASResource.cpp @@ -0,0 +1,667 @@ +// ASResource.cpp +// Copyright (c) 2016 by Jim Pattee . +// Licensed under the MIT license. +// License.txt describes the conditions under which this software may be distributed. + +//----------------------------------------------------------------------------- +// headers +//----------------------------------------------------------------------------- + +#include "astyle.h" +#include + +//----------------------------------------------------------------------------- +// astyle namespace +//----------------------------------------------------------------------------- + +namespace astyle { +// +const string ASResource::AS_IF = string("if"); +const string ASResource::AS_ELSE = string("else"); +const string ASResource::AS_FOR = string("for"); +const string ASResource::AS_DO = string("do"); +const string ASResource::AS_WHILE = string("while"); +const string ASResource::AS_SWITCH = string("switch"); +const string ASResource::AS_CASE = string("case"); +const string ASResource::AS_DEFAULT = string("default"); +const string ASResource::AS_CLASS = string("class"); +const string ASResource::AS_VOLATILE = string("volatile"); +const string ASResource::AS_INTERRUPT = string("interrupt"); +const string ASResource::AS_NOEXCEPT = string("noexcept"); +const string ASResource::AS_AUTORELEASEPOOL = string("autoreleasepool"); +const string ASResource::AS_STRUCT = string("struct"); +const string ASResource::AS_UNION = string("union"); +const string ASResource::AS_INTERFACE = string("interface"); +const string ASResource::AS_NAMESPACE = string("namespace"); +const string ASResource::AS_END = string("end"); +const string ASResource::AS_SELECTOR = string("selector"); +const string ASResource::AS_EXTERN = string("extern"); +const string ASResource::AS_ENUM = string("enum"); +const string ASResource::AS_PUBLIC = string("public"); +const string ASResource::AS_PROTECTED = string("protected"); +const string ASResource::AS_PRIVATE = string("private"); +const string ASResource::AS_STATIC = string("static"); +const string ASResource::AS_SYNCHRONIZED = string("synchronized"); +const string ASResource::AS_OPERATOR = string("operator"); +const string ASResource::AS_TEMPLATE = string("template"); +const string ASResource::AS_TRY = string("try"); +const string ASResource::AS_CATCH = string("catch"); +const string ASResource::AS_THROW = string("throw"); +const string ASResource::AS_FINALLY = string("finally"); +const string ASResource::AS_USING = string("using"); +const string ASResource::_AS_TRY = string("__try"); +const string ASResource::_AS_FINALLY = string("__finally"); +const string ASResource::_AS_EXCEPT = string("__except"); +const string ASResource::AS_THROWS = string("throws"); +const string ASResource::AS_CONST = string("const"); +const string ASResource::AS_SEALED = string("sealed"); +const string ASResource::AS_OVERRIDE = string("override"); +const string ASResource::AS_WHERE = string("where"); +const string ASResource::AS_LET = string("let"); +const string ASResource::AS_NEW = string("new"); + +const string ASResource::AS_ASM = string("asm"); +const string ASResource::AS__ASM__ = string("__asm__"); +const string ASResource::AS_MS_ASM = string("_asm"); +const string ASResource::AS_MS__ASM = string("__asm"); + +const string ASResource::AS_BAR_DEFINE = string("#define"); +const string ASResource::AS_BAR_INCLUDE = string("#include"); +const string ASResource::AS_BAR_IF = string("#if"); +const string ASResource::AS_BAR_EL = string("#el"); +const string ASResource::AS_BAR_ENDIF = string("#endif"); + +const string ASResource::AS_OPEN_BRACKET = string("{"); +const string ASResource::AS_CLOSE_BRACKET = string("}"); +const string ASResource::AS_OPEN_LINE_COMMENT = string("//"); +const string ASResource::AS_OPEN_COMMENT = string("/*"); +const string ASResource::AS_CLOSE_COMMENT = string("*/"); + +const string ASResource::AS_ASSIGN = string("="); +const string ASResource::AS_PLUS_ASSIGN = string("+="); +const string ASResource::AS_MINUS_ASSIGN = string("-="); +const string ASResource::AS_MULT_ASSIGN = string("*="); +const string ASResource::AS_DIV_ASSIGN = string("/="); +const string ASResource::AS_MOD_ASSIGN = string("%="); +const string ASResource::AS_OR_ASSIGN = string("|="); +const string ASResource::AS_AND_ASSIGN = string("&="); +const string ASResource::AS_XOR_ASSIGN = string("^="); +const string ASResource::AS_GR_GR_ASSIGN = string(">>="); +const string ASResource::AS_LS_LS_ASSIGN = string("<<="); +const string ASResource::AS_GR_GR_GR_ASSIGN = string(">>>="); +const string ASResource::AS_LS_LS_LS_ASSIGN = string("<<<="); +const string ASResource::AS_GCC_MIN_ASSIGN = string("?"); + +const string ASResource::AS_RETURN = string("return"); +const string ASResource::AS_CIN = string("cin"); +const string ASResource::AS_COUT = string("cout"); +const string ASResource::AS_CERR = string("cerr"); + +const string ASResource::AS_EQUAL = string("=="); +const string ASResource::AS_PLUS_PLUS = string("++"); +const string ASResource::AS_MINUS_MINUS = string("--"); +const string ASResource::AS_NOT_EQUAL = string("!="); +const string ASResource::AS_GR_EQUAL = string(">="); +const string ASResource::AS_GR_GR = string(">>"); +const string ASResource::AS_GR_GR_GR = string(">>>"); +const string ASResource::AS_LS_EQUAL = string("<="); +const string ASResource::AS_LS_LS = string("<<"); +const string ASResource::AS_LS_LS_LS = string("<<<"); +const string ASResource::AS_QUESTION_QUESTION = string("??"); +const string ASResource::AS_LAMBDA = string("=>"); // C# lambda expression arrow +const string ASResource::AS_ARROW = string("->"); +const string ASResource::AS_AND = string("&&"); +const string ASResource::AS_OR = string("||"); +const string ASResource::AS_SCOPE_RESOLUTION = string("::"); + +const string ASResource::AS_PLUS = string("+"); +const string ASResource::AS_MINUS = string("-"); +const string ASResource::AS_MULT = string("*"); +const string ASResource::AS_DIV = string("/"); +const string ASResource::AS_MOD = string("%"); +const string ASResource::AS_GR = string(">"); +const string ASResource::AS_LS = string("<"); +const string ASResource::AS_NOT = string("!"); +const string ASResource::AS_BIT_OR = string("|"); +const string ASResource::AS_BIT_AND = string("&"); +const string ASResource::AS_BIT_NOT = string("~"); +const string ASResource::AS_BIT_XOR = string("^"); +const string ASResource::AS_QUESTION = string("?"); +const string ASResource::AS_COLON = string(":"); +const string ASResource::AS_COMMA = string(","); +const string ASResource::AS_SEMICOLON = string(";"); + +const string ASResource::AS_QFOREACH = string("Q_FOREACH"); +const string ASResource::AS_QFOREVER = string("Q_FOREVER"); +const string ASResource::AS_FOREVER = string("forever"); +const string ASResource::AS_FOREACH = string("foreach"); +const string ASResource::AS_LOCK = string("lock"); +const string ASResource::AS_UNSAFE = string("unsafe"); +const string ASResource::AS_FIXED = string("fixed"); +const string ASResource::AS_GET = string("get"); +const string ASResource::AS_SET = string("set"); +const string ASResource::AS_ADD = string("add"); +const string ASResource::AS_REMOVE = string("remove"); +const string ASResource::AS_DELEGATE = string("delegate"); +const string ASResource::AS_UNCHECKED = string("unchecked"); + +const string ASResource::AS_CONST_CAST = string("const_cast"); +const string ASResource::AS_DYNAMIC_CAST = string("dynamic_cast"); +const string ASResource::AS_REINTERPRET_CAST = string("reinterpret_cast"); +const string ASResource::AS_STATIC_CAST = string("static_cast"); + +const string ASResource::AS_NS_DURING = string("NS_DURING"); +const string ASResource::AS_NS_HANDLER = string("NS_HANDLER"); + +/** + * Sort comparison function. + * Compares the length of the value of pointers in the vectors. + * The LONGEST strings will be first in the vector. + * + * @param a and b, the string pointers to be compared. + */ +bool sortOnLength(const string* a, const string* b) +{ + return (*a).length() > (*b).length(); +} + +/** + * Sort comparison function. + * Compares the value of pointers in the vectors. + * + * @param a and b, the string pointers to be compared. + */ +bool sortOnName(const string* a, const string* b) +{ + return *a < *b; +} + +/** + * Build the vector of assignment operators. + * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp + * + * @param assignmentOperators a reference to the vector to be built. + */ +void ASResource::buildAssignmentOperators(vector* assignmentOperators) +{ + assignmentOperators->push_back(&AS_ASSIGN); + assignmentOperators->push_back(&AS_PLUS_ASSIGN); + assignmentOperators->push_back(&AS_MINUS_ASSIGN); + assignmentOperators->push_back(&AS_MULT_ASSIGN); + assignmentOperators->push_back(&AS_DIV_ASSIGN); + assignmentOperators->push_back(&AS_MOD_ASSIGN); + assignmentOperators->push_back(&AS_OR_ASSIGN); + assignmentOperators->push_back(&AS_AND_ASSIGN); + assignmentOperators->push_back(&AS_XOR_ASSIGN); + + // Java + assignmentOperators->push_back(&AS_GR_GR_GR_ASSIGN); + assignmentOperators->push_back(&AS_GR_GR_ASSIGN); + assignmentOperators->push_back(&AS_LS_LS_ASSIGN); + + // Unknown + assignmentOperators->push_back(&AS_LS_LS_LS_ASSIGN); + + sort(assignmentOperators->begin(), assignmentOperators->end(), sortOnLength); +} + +/** + * Build the vector of C++ cast operators. + * Used by ONLY ASFormatter.cpp + * + * @param castOperators a reference to the vector to be built. + */ +void ASResource::buildCastOperators(vector* castOperators) +{ + castOperators->push_back(&AS_CONST_CAST); + castOperators->push_back(&AS_DYNAMIC_CAST); + castOperators->push_back(&AS_REINTERPRET_CAST); + castOperators->push_back(&AS_STATIC_CAST); +} + +/** + * Build the vector of header words. + * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp + * + * @param headers a reference to the vector to be built. + */ +void ASResource::buildHeaders(vector* headers, int fileType, bool beautifier) +{ + headers->push_back(&AS_IF); + headers->push_back(&AS_ELSE); + headers->push_back(&AS_FOR); + headers->push_back(&AS_WHILE); + headers->push_back(&AS_DO); + headers->push_back(&AS_SWITCH); + headers->push_back(&AS_CASE); + headers->push_back(&AS_DEFAULT); + headers->push_back(&AS_TRY); + headers->push_back(&AS_CATCH); + headers->push_back(&AS_QFOREACH); // QT + headers->push_back(&AS_QFOREVER); // QT + headers->push_back(&AS_FOREACH); // QT & C# + headers->push_back(&AS_FOREVER); // Qt & Boost + + if (fileType == C_TYPE) + { + headers->push_back(&_AS_TRY); // __try + headers->push_back(&_AS_FINALLY); // __finally + headers->push_back(&_AS_EXCEPT); // __except + } + if (fileType == JAVA_TYPE) + { + headers->push_back(&AS_FINALLY); + headers->push_back(&AS_SYNCHRONIZED); + } + + if (fileType == SHARP_TYPE) + { + headers->push_back(&AS_FINALLY); + headers->push_back(&AS_LOCK); + headers->push_back(&AS_FIXED); + headers->push_back(&AS_GET); + headers->push_back(&AS_SET); + headers->push_back(&AS_ADD); + headers->push_back(&AS_REMOVE); + headers->push_back(&AS_USING); + } + + if (beautifier) + { + if (fileType == C_TYPE) + { + headers->push_back(&AS_TEMPLATE); + } + + if (fileType == JAVA_TYPE) + { + headers->push_back(&AS_STATIC); // for static constructor + } + } + sort(headers->begin(), headers->end(), sortOnName); +} + +/** + * Build the vector of indentable headers. + * Used by ONLY ASBeautifier.cpp + * + * @param indentableHeaders a reference to the vector to be built. + */ +void ASResource::buildIndentableHeaders(vector* indentableHeaders) +{ + indentableHeaders->push_back(&AS_RETURN); + + sort(indentableHeaders->begin(), indentableHeaders->end(), sortOnName); +} + +/** +* Build the vector of indentable macros pairs. +* Initialized by ASFormatter, used by ONLY ASEnhancer.cpp +* +* @param indentableMacros a reference to the vector to be built. +*/ +void ASResource::buildIndentableMacros(vector* >* indentableMacros) +{ + typedef pair macro_pair; + + // the pairs must be retained in memory + static const macro_pair macros[] = + { + // wxWidgets + macro_pair("BEGIN_EVENT_TABLE", "END_EVENT_TABLE"), + macro_pair("wxBEGIN_EVENT_TABLE", "wxEND_EVENT_TABLE"), + // MFC + macro_pair("BEGIN_DISPATCH_MAP", "END_DISPATCH_MAP"), + macro_pair("BEGIN_EVENT_MAP", "END_EVENT_MAP"), + macro_pair("BEGIN_MESSAGE_MAP", "END_MESSAGE_MAP"), + macro_pair("BEGIN_PROPPAGEIDS", "END_PROPPAGEIDS"), + }; + + size_t elements = sizeof(macros) / sizeof(macros[0]); + for (size_t i = 0; i < elements; i++) + indentableMacros->push_back(¯os[i]); +} + +/** + * Build the vector of non-assignment operators. + * Used by ONLY ASBeautifier.cpp + * + * @param nonAssignmentOperators a reference to the vector to be built. + */ +void ASResource::buildNonAssignmentOperators(vector* nonAssignmentOperators) +{ + nonAssignmentOperators->push_back(&AS_EQUAL); + nonAssignmentOperators->push_back(&AS_PLUS_PLUS); + nonAssignmentOperators->push_back(&AS_MINUS_MINUS); + nonAssignmentOperators->push_back(&AS_NOT_EQUAL); + nonAssignmentOperators->push_back(&AS_GR_EQUAL); + nonAssignmentOperators->push_back(&AS_GR_GR_GR); + nonAssignmentOperators->push_back(&AS_GR_GR); + nonAssignmentOperators->push_back(&AS_LS_EQUAL); + nonAssignmentOperators->push_back(&AS_LS_LS_LS); + nonAssignmentOperators->push_back(&AS_LS_LS); + nonAssignmentOperators->push_back(&AS_ARROW); + nonAssignmentOperators->push_back(&AS_AND); + nonAssignmentOperators->push_back(&AS_OR); + nonAssignmentOperators->push_back(&AS_LAMBDA); + + sort(nonAssignmentOperators->begin(), nonAssignmentOperators->end(), sortOnLength); +} + +/** + * Build the vector of header non-paren headers. + * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp. + * NOTE: Non-paren headers should also be included in the headers vector. + * + * @param nonParenHeaders a reference to the vector to be built. + */ +void ASResource::buildNonParenHeaders(vector* nonParenHeaders, int fileType, bool beautifier) +{ + nonParenHeaders->push_back(&AS_ELSE); + nonParenHeaders->push_back(&AS_DO); + nonParenHeaders->push_back(&AS_TRY); + nonParenHeaders->push_back(&AS_CATCH); // can be paren or non-paren + nonParenHeaders->push_back(&AS_CASE); // can be paren or non-paren + nonParenHeaders->push_back(&AS_DEFAULT); + nonParenHeaders->push_back(&AS_QFOREVER); // QT + nonParenHeaders->push_back(&AS_FOREVER); // Boost + + if (fileType == C_TYPE) + { + nonParenHeaders->push_back(&_AS_TRY); // __try + nonParenHeaders->push_back(&_AS_FINALLY); // __finally + } + if (fileType == JAVA_TYPE) + { + nonParenHeaders->push_back(&AS_FINALLY); + } + + if (fileType == SHARP_TYPE) + { + nonParenHeaders->push_back(&AS_FINALLY); + nonParenHeaders->push_back(&AS_GET); + nonParenHeaders->push_back(&AS_SET); + nonParenHeaders->push_back(&AS_ADD); + nonParenHeaders->push_back(&AS_REMOVE); + } + + if (beautifier) + { + if (fileType == C_TYPE) + { + nonParenHeaders->push_back(&AS_TEMPLATE); + } + if (fileType == JAVA_TYPE) + { + nonParenHeaders->push_back(&AS_STATIC); + } + } + sort(nonParenHeaders->begin(), nonParenHeaders->end(), sortOnName); +} + +/** + * Build the vector of operators. + * Used by ONLY ASFormatter.cpp + * + * @param operators a reference to the vector to be built. + */ +void ASResource::buildOperators(vector* operators, int fileType) +{ + operators->push_back(&AS_PLUS_ASSIGN); + operators->push_back(&AS_MINUS_ASSIGN); + operators->push_back(&AS_MULT_ASSIGN); + operators->push_back(&AS_DIV_ASSIGN); + operators->push_back(&AS_MOD_ASSIGN); + operators->push_back(&AS_OR_ASSIGN); + operators->push_back(&AS_AND_ASSIGN); + operators->push_back(&AS_XOR_ASSIGN); + operators->push_back(&AS_EQUAL); + operators->push_back(&AS_PLUS_PLUS); + operators->push_back(&AS_MINUS_MINUS); + operators->push_back(&AS_NOT_EQUAL); + operators->push_back(&AS_GR_EQUAL); + operators->push_back(&AS_GR_GR_GR_ASSIGN); + operators->push_back(&AS_GR_GR_ASSIGN); + operators->push_back(&AS_GR_GR_GR); + operators->push_back(&AS_GR_GR); + operators->push_back(&AS_LS_EQUAL); + operators->push_back(&AS_LS_LS_LS_ASSIGN); + operators->push_back(&AS_LS_LS_ASSIGN); + operators->push_back(&AS_LS_LS_LS); + operators->push_back(&AS_LS_LS); + operators->push_back(&AS_QUESTION_QUESTION); + operators->push_back(&AS_LAMBDA); + operators->push_back(&AS_ARROW); + operators->push_back(&AS_AND); + operators->push_back(&AS_OR); + operators->push_back(&AS_SCOPE_RESOLUTION); + operators->push_back(&AS_PLUS); + operators->push_back(&AS_MINUS); + operators->push_back(&AS_MULT); + operators->push_back(&AS_DIV); + operators->push_back(&AS_MOD); + operators->push_back(&AS_QUESTION); + operators->push_back(&AS_COLON); + operators->push_back(&AS_ASSIGN); + operators->push_back(&AS_LS); + operators->push_back(&AS_GR); + operators->push_back(&AS_NOT); + operators->push_back(&AS_BIT_OR); + operators->push_back(&AS_BIT_AND); + operators->push_back(&AS_BIT_NOT); + operators->push_back(&AS_BIT_XOR); + if (fileType == C_TYPE) + { + operators->push_back(&AS_GCC_MIN_ASSIGN); + operators->push_back(&AS_GCC_MAX_ASSIGN); + } + sort(operators->begin(), operators->end(), sortOnLength); +} + +/** + * Build the vector of pre-block statements. + * Used by ONLY ASBeautifier.cpp + * NOTE: Cannot be both a header and a preBlockStatement. + * + * @param preBlockStatements a reference to the vector to be built. + */ +void ASResource::buildPreBlockStatements(vector* preBlockStatements, int fileType) +{ + preBlockStatements->push_back(&AS_CLASS); + if (fileType == C_TYPE) + { + preBlockStatements->push_back(&AS_STRUCT); + preBlockStatements->push_back(&AS_UNION); + preBlockStatements->push_back(&AS_NAMESPACE); + } + if (fileType == JAVA_TYPE) + { + preBlockStatements->push_back(&AS_INTERFACE); + preBlockStatements->push_back(&AS_THROWS); + } + if (fileType == SHARP_TYPE) + { + preBlockStatements->push_back(&AS_INTERFACE); + preBlockStatements->push_back(&AS_NAMESPACE); + preBlockStatements->push_back(&AS_WHERE); + preBlockStatements->push_back(&AS_STRUCT); + } + sort(preBlockStatements->begin(), preBlockStatements->end(), sortOnName); +} + +/** + * Build the vector of pre-command headers. + * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp. + * NOTE: Cannot be both a header and a preCommandHeader. + * + * A preCommandHeader is in a function definition between + * the closing paren and the opening bracket. + * e.g. in "void foo() const {}", "const" is a preCommandHeader. + */ +void ASResource::buildPreCommandHeaders(vector* preCommandHeaders, int fileType) +{ + if (fileType == C_TYPE) + { + preCommandHeaders->push_back(&AS_CONST); + preCommandHeaders->push_back(&AS_VOLATILE); + preCommandHeaders->push_back(&AS_INTERRUPT); + preCommandHeaders->push_back(&AS_NOEXCEPT); + preCommandHeaders->push_back(&AS_OVERRIDE); + preCommandHeaders->push_back(&AS_SEALED); // Visual C only + preCommandHeaders->push_back(&AS_AUTORELEASEPOOL); // Obj-C only + } + + if (fileType == JAVA_TYPE) + { + preCommandHeaders->push_back(&AS_THROWS); + } + + if (fileType == SHARP_TYPE) + { + preCommandHeaders->push_back(&AS_WHERE); + } + + sort(preCommandHeaders->begin(), preCommandHeaders->end(), sortOnName); +} + +/** + * Build the vector of pre-definition headers. + * Used by ONLY ASFormatter.cpp + * NOTE: Do NOT add 'enum' here. It is an array type bracket. + * NOTE: Do NOT add 'extern' here. Do not want an extra indent. + * + * @param preDefinitionHeaders a reference to the vector to be built. + */ +void ASResource::buildPreDefinitionHeaders(vector* preDefinitionHeaders, int fileType) +{ + preDefinitionHeaders->push_back(&AS_CLASS); + if (fileType == C_TYPE) + { + preDefinitionHeaders->push_back(&AS_STRUCT); + preDefinitionHeaders->push_back(&AS_UNION); + preDefinitionHeaders->push_back(&AS_NAMESPACE); + } + if (fileType == JAVA_TYPE) + { + preDefinitionHeaders->push_back(&AS_INTERFACE); + } + if (fileType == SHARP_TYPE) + { + preDefinitionHeaders->push_back(&AS_STRUCT); + preDefinitionHeaders->push_back(&AS_INTERFACE); + preDefinitionHeaders->push_back(&AS_NAMESPACE); + } + sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * ASBase Functions + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// check if a specific line position contains a keyword. +bool ASBase::findKeyword(const string& line, int i, const string& keyword) const +{ + assert(isCharPotentialHeader(line, i)); + // check the word + const size_t keywordLength = keyword.length(); + const size_t wordEnd = i + keywordLength; + if (wordEnd > line.length()) + return false; + if (line.compare(i, keywordLength, keyword) != 0) + return false; + // check that this is not part of a longer word + if (wordEnd == line.length()) + return true; + if (isLegalNameChar(line[wordEnd])) + return false; + // is not a keyword if part of a definition + const char peekChar = peekNextChar(line, wordEnd - 1); + if (peekChar == ',' || peekChar == ')') + return false; + return true; +} + +// get the current word on a line +// index must point to the beginning of the word +string ASBase::getCurrentWord(const string& line, size_t index) const +{ + assert(isCharPotentialHeader(line, index)); + size_t lineLength = line.length(); + size_t i; + for (i = index; i < lineLength; i++) + { + if (!isLegalNameChar(line[i])) + break; + } + return line.substr(index, i - index); +} + +// check if a specific character can be used in a legal variable/method/class name +bool ASBase::isLegalNameChar(char ch) const +{ + if (isWhiteSpace(ch)) return false; + if ((unsigned) ch > 127) return false; + return (isalnum((unsigned char) ch) + || ch == '.' || ch == '_' + || (isJavaStyle() && ch == '$') + || (isSharpStyle() && ch == '@')); // may be used as a prefix +} + +// check if a specific character can be part of a header +bool ASBase::isCharPotentialHeader(const string& line, size_t i) const +{ + assert(!isWhiteSpace(line[i])); + char prevCh = ' '; + if (i > 0) prevCh = line[i - 1]; + if (!isLegalNameChar(prevCh) && isLegalNameChar(line[i])) + return true; + return false; +} + +// check if a specific character can be part of an operator +bool ASBase::isCharPotentialOperator(char ch) const +{ + assert(!isWhiteSpace(ch)); + if ((unsigned) ch > 127) return false; + return (ispunct((unsigned char) ch) + && ch != '{' && ch != '}' + && ch != '(' && ch != ')' + && ch != '[' && ch != ']' + && ch != ';' && ch != ',' + && ch != '#' && ch != '\\' + && ch != '\'' && ch != '\"'); +} + +// check if a specific character is a digit +// NOTE: Visual C isdigit() gives assert error if char > 256 +bool ASBase::isDigit(char ch) const +{ + return (ch >= '0' && ch <= '9'); +} + +// check if a specific character is a digit separator +bool ASBase::isDigitSeparator(const string& line, int i) const +{ + assert(line[i] == '\''); + // casting to (unsigned char) eliminates negative characters + // will get a "Debug Assertion Failed" if not cast + bool foundDigitSeparator = i > 0 + && isxdigit((unsigned char) line[i - 1]) + && i < (int) line.length() - 1 + && isxdigit((unsigned char) line[i + 1]); + return foundDigitSeparator; +} + +// peek at the next unread character. +char ASBase::peekNextChar(const string& line, int i) const +{ + char ch = ' '; + size_t peekNum = line.find_first_not_of(" \t", i + 1); + if (peekNum == string::npos) + return ch; + ch = line[peekNum]; + return ch; +} + +} // end namespace astyle diff --git a/External/Tools/AStyle/src/astyle.h b/External/Tools/AStyle/src/astyle.h new file mode 100644 index 0000000000..2c667a3cfb --- /dev/null +++ b/External/Tools/AStyle/src/astyle.h @@ -0,0 +1,996 @@ +// astyle.h +// Copyright (c) 2016 by Jim Pattee . +// Licensed under the MIT license. +// License.txt describes the conditions under which this software may be distributed. + +#ifndef ASTYLE_H +#define ASTYLE_H + +//----------------------------------------------------------------------------- +// headers +//----------------------------------------------------------------------------- + +#ifdef __VMS + #define __USE_STD_IOSTREAM 1 + #include +#else + #include +#endif + +#include +#include // for cout +#include +#include + +//----------------------------------------------------------------------------- +// declarations +//----------------------------------------------------------------------------- + +#ifdef __GNUC__ + #include // need both string and string.h for GCC +#endif + +#ifdef _MSC_VER + #pragma warning(disable: 4267) // conversion from size_t to int + #pragma warning(disable: 4996) // secure version deprecation warnings +#endif + +#ifdef __BORLANDC__ + #pragma warn -8004 // variable is assigned a value that is never used +#endif + +#ifdef __INTEL_COMPILER + #pragma warning(disable: 383) // value copied to temporary, reference to temporary used + #pragma warning(disable: 981) // operands are evaluated in unspecified order +#endif + +#ifdef __clang__ + #pragma clang diagnostic ignored "-Wdeprecated-declarations" // strcpy, getenv + #pragma clang diagnostic ignored "-Wshorten-64-to-32" +#endif + +//----------------------------------------------------------------------------- +// astyle namespace +//----------------------------------------------------------------------------- + +namespace astyle { +// +using namespace std; + +//---------------------------------------------------------------------------- +// definitions +//---------------------------------------------------------------------------- + +enum FileType { C_TYPE = 0, JAVA_TYPE = 1, SHARP_TYPE = 2 }; + +/* The enums below are not recognized by 'vectors' in Microsoft Visual C++ + V5 when they are part of a namespace!!! Use Visual C++ V6 or higher. +*/ +enum FormatStyle +{ + STYLE_NONE, + STYLE_ALLMAN, + STYLE_JAVA, + STYLE_KR, + STYLE_STROUSTRUP, + STYLE_WHITESMITH, + STYLE_VTK, + STYLE_BANNER, + STYLE_GNU, + STYLE_LINUX, + STYLE_HORSTMANN, + STYLE_1TBS, + STYLE_GOOGLE, + STYLE_PICO, + STYLE_LISP +}; + +enum BracketMode +{ + NONE_MODE, + ATTACH_MODE, + BREAK_MODE, + LINUX_MODE, + STROUSTRUP_MODE, + RUN_IN_MODE +}; + +enum BracketType +{ + NULL_TYPE = 0, + NAMESPACE_TYPE = 1, // also a DEFINITION_TYPE + CLASS_TYPE = 2, // also a DEFINITION_TYPE + STRUCT_TYPE = 4, // also a DEFINITION_TYPE + INTERFACE_TYPE = 8, // also a DEFINITION_TYPE + DEFINITION_TYPE = 16, + COMMAND_TYPE = 32, + ARRAY_NIS_TYPE = 64, // also an ARRAY_TYPE + ENUM_TYPE = 128, // also an ARRAY_TYPE + INIT_TYPE = 256, // also an ARRAY_TYPE + ARRAY_TYPE = 512, + EXTERN_TYPE = 1024, // extern "C", not a command type extern + SINGLE_LINE_TYPE = 2048 +}; + +enum MinConditional +{ + MINCOND_ZERO, + MINCOND_ONE, + MINCOND_TWO, + MINCOND_ONEHALF, + MINCOND_END +}; + +enum ObjCColonPad +{ + COLON_PAD_NO_CHANGE, + COLON_PAD_NONE, + COLON_PAD_ALL, + COLON_PAD_AFTER, + COLON_PAD_BEFORE +}; + +enum PointerAlign +{ + PTR_ALIGN_NONE, + PTR_ALIGN_TYPE, + PTR_ALIGN_MIDDLE, + PTR_ALIGN_NAME +}; + +enum ReferenceAlign +{ + REF_ALIGN_NONE = PTR_ALIGN_NONE, + REF_ALIGN_TYPE = PTR_ALIGN_TYPE, + REF_ALIGN_MIDDLE = PTR_ALIGN_MIDDLE, + REF_ALIGN_NAME = PTR_ALIGN_NAME, + REF_SAME_AS_PTR +}; + +enum FileEncoding +{ + ENCODING_8BIT, + UTF_16BE, + UTF_16LE, // Windows default + UTF_32BE, + UTF_32LE +}; + +enum LineEndFormat +{ + LINEEND_DEFAULT, // Use line break that matches most of the file + LINEEND_WINDOWS, + LINEEND_LINUX, + LINEEND_MACOLD, + LINEEND_CRLF = LINEEND_WINDOWS, + LINEEND_LF = LINEEND_LINUX, + LINEEND_CR = LINEEND_MACOLD +}; + +//----------------------------------------------------------------------------- +// Class ASSourceIterator +// A pure virtual class is used by ASFormatter and ASBeautifier instead of +// ASStreamIterator. This allows programs using AStyle as a plug-in to define +// their own ASStreamIterator. The ASStreamIterator class must inherit +// this class. +//----------------------------------------------------------------------------- + +class ASSourceIterator +{ +public: + ASSourceIterator() {} + virtual ~ASSourceIterator() {} + virtual int getStreamLength() const = 0; + virtual bool hasMoreLines() const = 0; + virtual string nextLine(bool emptyLineWasDeleted = false) = 0; + virtual string peekNextLine() = 0; + virtual void peekReset() = 0; + virtual streamoff tellg() = 0; +}; + +//----------------------------------------------------------------------------- +// Class ASResource +//----------------------------------------------------------------------------- + +class ASResource +{ +public: + ASResource() {} + virtual ~ASResource() {} + void buildAssignmentOperators(vector* assignmentOperators); + void buildCastOperators(vector* castOperators); + void buildHeaders(vector* headers, int fileType, bool beautifier = false); + void buildIndentableMacros(vector* >* indentableMacros); + void buildIndentableHeaders(vector* indentableHeaders); + void buildNonAssignmentOperators(vector* nonAssignmentOperators); + void buildNonParenHeaders(vector* nonParenHeaders, int fileType, bool beautifier = false); + void buildOperators(vector* operators, int fileType); + void buildPreBlockStatements(vector* preBlockStatements, int fileType); + void buildPreCommandHeaders(vector* preCommandHeaders, int fileType); + void buildPreDefinitionHeaders(vector* preDefinitionHeaders, int fileType); + +public: + static const string AS_IF, AS_ELSE; + static const string AS_DO, AS_WHILE; + static const string AS_FOR; + static const string AS_SWITCH, AS_CASE, AS_DEFAULT; + static const string AS_TRY, AS_CATCH, AS_THROW, AS_THROWS, AS_FINALLY, AS_USING; + static const string _AS_TRY, _AS_FINALLY, _AS_EXCEPT; + static const string AS_PUBLIC, AS_PROTECTED, AS_PRIVATE; + static const string AS_CLASS, AS_STRUCT, AS_UNION, AS_INTERFACE, AS_NAMESPACE; + static const string AS_END; + static const string AS_SELECTOR; + static const string AS_EXTERN, AS_ENUM; + static const string AS_STATIC, AS_CONST, AS_SEALED, AS_OVERRIDE, AS_VOLATILE, AS_NEW; + static const string AS_NOEXCEPT, AS_INTERRUPT, AS_AUTORELEASEPOOL; + static const string AS_WHERE, AS_LET, AS_SYNCHRONIZED; + static const string AS_OPERATOR, AS_TEMPLATE; + static const string AS_OPEN_BRACKET, AS_CLOSE_BRACKET; + static const string AS_OPEN_LINE_COMMENT, AS_OPEN_COMMENT, AS_CLOSE_COMMENT; + static const string AS_BAR_DEFINE, AS_BAR_INCLUDE, AS_BAR_IF, AS_BAR_EL, AS_BAR_ENDIF; + static const string AS_RETURN; + static const string AS_CIN, AS_COUT, AS_CERR; + static const string AS_ASSIGN, AS_PLUS_ASSIGN, AS_MINUS_ASSIGN, AS_MULT_ASSIGN; + static const string AS_DIV_ASSIGN, AS_MOD_ASSIGN, AS_XOR_ASSIGN, AS_OR_ASSIGN, AS_AND_ASSIGN; + static const string AS_GR_GR_ASSIGN, AS_LS_LS_ASSIGN, AS_GR_GR_GR_ASSIGN, AS_LS_LS_LS_ASSIGN; + static const string AS_GCC_MIN_ASSIGN, AS_GCC_MAX_ASSIGN; + static const string AS_EQUAL, AS_PLUS_PLUS, AS_MINUS_MINUS, AS_NOT_EQUAL, AS_GR_EQUAL, AS_GR_GR_GR, AS_GR_GR; + static const string AS_LS_EQUAL, AS_LS_LS_LS, AS_LS_LS; + static const string AS_QUESTION_QUESTION, AS_LAMBDA; + static const string AS_ARROW, AS_AND, AS_OR; + static const string AS_SCOPE_RESOLUTION; + static const string AS_PLUS, AS_MINUS, AS_MULT, AS_DIV, AS_MOD, AS_GR, AS_LS; + static const string AS_NOT, AS_BIT_XOR, AS_BIT_OR, AS_BIT_AND, AS_BIT_NOT; + static const string AS_QUESTION, AS_COLON, AS_SEMICOLON, AS_COMMA; + static const string AS_ASM, AS__ASM__, AS_MS_ASM, AS_MS__ASM; + static const string AS_QFOREACH, AS_QFOREVER, AS_FOREVER; + static const string AS_FOREACH, AS_LOCK, AS_UNSAFE, AS_FIXED; + static const string AS_GET, AS_SET, AS_ADD, AS_REMOVE; + static const string AS_DELEGATE, AS_UNCHECKED; + static const string AS_CONST_CAST, AS_DYNAMIC_CAST, AS_REINTERPRET_CAST, AS_STATIC_CAST; + static const string AS_NS_DURING, AS_NS_HANDLER; +}; // Class ASResource + +//----------------------------------------------------------------------------- +// Class ASBase +// Functions definitions are at the end of ASResource.cpp. +//----------------------------------------------------------------------------- + +class ASBase +{ +private: + // all variables should be set by the "init" function + int baseFileType; // a value from enum FileType + +protected: + ASBase() : baseFileType(C_TYPE) { } + +protected: // inline functions + void init(int fileTypeArg) { baseFileType = fileTypeArg; } + bool isCStyle() const { return (baseFileType == C_TYPE); } + bool isJavaStyle() const { return (baseFileType == JAVA_TYPE); } + bool isSharpStyle() const { return (baseFileType == SHARP_TYPE); } + bool isWhiteSpace(char ch) const { return (ch == ' ' || ch == '\t'); } + +protected: // functions definitions are at the end of ASResource.cpp + bool findKeyword(const string& line, int i, const string& keyword) const; + string getCurrentWord(const string& line, size_t index) const; + bool isDigit(char ch) const; + bool isLegalNameChar(char ch) const; + bool isCharPotentialHeader(const string& line, size_t i) const; + bool isCharPotentialOperator(char ch) const; + bool isDigitSeparator(const string& line, int i) const; + char peekNextChar(const string& line, int i) const; + +}; // Class ASBase + +//----------------------------------------------------------------------------- +// Class ASBeautifier +//----------------------------------------------------------------------------- + +class ASBeautifier : protected ASResource, protected ASBase +{ +public: + ASBeautifier(); + virtual ~ASBeautifier(); + virtual void init(ASSourceIterator* iter); + virtual string beautify(const string& line); + void setCaseIndent(bool state); + void setClassIndent(bool state); + void setCStyle(); + void setDefaultTabLength(); + void setEmptyLineFill(bool state); + void setForceTabXIndentation(int length); + void setJavaStyle(); + void setLabelIndent(bool state); + void setMaxInStatementIndentLength(int max); + void setMinConditionalIndentOption(int min); + void setMinConditionalIndentLength(); + void setModeManuallySet(bool state); + void setModifierIndent(bool state); + void setNamespaceIndent(bool state); + void setAlignMethodColon(bool state); + void setSharpStyle(); + void setSpaceIndentation(int length = 4); + void setSwitchIndent(bool state); + void setTabIndentation(int length = 4, bool forceTabs = false); + void setPreprocDefineIndent(bool state); + void setPreprocConditionalIndent(bool state); + int getBeautifierFileType() const; + int getFileType() const; + int getIndentLength(void) const; + int getTabLength(void) const; + string getIndentString(void) const; + string getNextWord(const string& line, size_t currPos) const; + bool getAlignMethodColon(void) const; + bool getBracketIndent(void) const; + bool getBlockIndent(void) const; + bool getCaseIndent(void) const; + bool getClassIndent(void) const; + bool getEmptyLineFill(void) const; + bool getForceTabIndentation(void) const; + bool getModeManuallySet(void) const; + bool getModifierIndent(void) const; + bool getNamespaceIndent(void) const; + bool getPreprocDefineIndent(void) const; + bool getSwitchIndent(void) const; + +protected: + void deleteBeautifierVectors(); + const string* findHeader(const string& line, int i, + const vector* possibleHeaders) const; + const string* findOperator(const string& line, int i, + const vector* possibleOperators) const; + int getNextProgramCharDistance(const string& line, int i) const; + int indexOf(vector& container, const string* element) const; + void setBlockIndent(bool state); + void setBracketIndent(bool state); + void setBracketIndentVtk(bool state); + string extractPreprocessorStatement(const string& line) const; + string trim(const string& str) const; + string rtrim(const string& str) const; + + // variables set by ASFormatter - must be updated in activeBeautifierStack + int inLineNumber; + int horstmannIndentInStatement; + int nonInStatementBracket; + int objCColonAlignSubsequent; // for subsequent lines not counting indent + bool lineCommentNoBeautify; + bool isElseHeaderIndent; + bool isCaseHeaderCommentIndent; + bool isNonInStatementArray; + bool isSharpAccessor; + bool isSharpDelegate; + bool isInExternC; + bool isInBeautifySQL; + bool isInIndentableStruct; + bool isInIndentablePreproc; + +private: // functions + ASBeautifier(const ASBeautifier& copy); // inline functions + ASBeautifier& operator=(ASBeautifier&); // not to be implemented + + void adjustParsedLineIndentation(size_t iPrelim, bool isInExtraHeaderIndent); + void computePreliminaryIndentation(); + void parseCurrentLine(const string& line); + void popLastInStatementIndent(); + void processPreprocessor(const string& preproc, const string& line); + void registerInStatementIndent(const string& line, int i, int spaceIndentCount, + int tabIncrementIn, int minIndent, bool updateParenStack); + void registerInStatementIndentColon(const string& line, int i, int tabIncrementIn); + void initVectors(); + void initTempStacksContainer(vector*>*& container, + vector*>* value); + void clearObjCMethodDefinitionAlignment(); + void deleteBeautifierContainer(vector*& container); + void deleteTempStacksContainer(vector*>*& container); + int adjustIndentCountForBreakElseIfComments() const; + int computeObjCColonAlignment(string& line, int colonAlignPosition) const; + int convertTabToSpaces(int i, int tabIncrementIn) const; + int getInStatementIndentAssign(const string& line, size_t currPos) const; + int getInStatementIndentComma(const string& line, size_t currPos) const; + bool isIndentedPreprocessor(const string& line, size_t currPos) const; + bool isLineEndComment(const string& line, int startPos) const; + bool isPreprocessorConditionalCplusplus(const string& line) const; + bool isInPreprocessorUnterminatedComment(const string& line); + bool statementEndsWithComma(const string& line, int index) const; + string& getIndentedLineReturn(string& newLine, const string& originalLine) const; + string preLineWS(int lineIndentCount, int lineSpaceIndentCount) const; + template void deleteContainer(T& container); + template void initContainer(T& container, T value); + vector*>* copyTempStacks(const ASBeautifier& other) const; + pair computePreprocessorIndent(); + +private: // variables + int beautifierFileType; + vector* headers; + vector* nonParenHeaders; + vector* preBlockStatements; + vector* preCommandHeaders; + vector* assignmentOperators; + vector* nonAssignmentOperators; + vector* indentableHeaders; + + vector* waitingBeautifierStack; + vector* activeBeautifierStack; + vector* waitingBeautifierStackLengthStack; + vector* activeBeautifierStackLengthStack; + vector* headerStack; + vector* >* tempStacks; + vector* blockParenDepthStack; + vector* blockStatementStack; + vector* parenStatementStack; + vector* bracketBlockStateStack; + vector* inStatementIndentStack; + vector* inStatementIndentStackSizeStack; + vector* parenIndentStack; + vector >* preprocIndentStack; + + ASSourceIterator* sourceIterator; + const string* currentHeader; + const string* previousLastLineHeader; + const string* probationHeader; + const string* lastLineHeader; + string indentString; + string verbatimDelimiter; + bool isInQuote; + bool isInVerbatimQuote; + bool haveLineContinuationChar; + bool isInAsm; + bool isInAsmOneLine; + bool isInAsmBlock; + bool isInComment; + bool isInPreprocessorComment; + bool isInHorstmannComment; + bool isInCase; + bool isInQuestion; + bool isInStatement; + bool isInHeader; + bool isInTemplate; + bool isInDefine; + bool isInDefineDefinition; + bool classIndent; + bool isIndentModeOff; + bool isInClassHeader; // is in a class before the opening bracket + bool isInClassHeaderTab; // is in an indentable class header line + bool isInClassInitializer; // is in a class after the ':' initializer + bool isInClass; // is in a class after the opening bracket + bool isInObjCMethodDefinition; + bool isImmediatelyPostObjCMethodDefinition; + bool isInIndentablePreprocBlock; + bool isInObjCInterface; + bool isInEnum; + bool isInEnumTypeID; + bool isInLet; + bool modifierIndent; + bool switchIndent; + bool caseIndent; + bool namespaceIndent; + bool bracketIndent; + bool bracketIndentVtk; + bool blockIndent; + bool labelIndent; + bool shouldIndentPreprocDefine; + bool isInConditional; + bool isModeManuallySet; + bool shouldForceTabIndentation; + bool emptyLineFill; + bool backslashEndsPrevLine; + bool lineOpensWithLineComment; + bool lineOpensWithComment; + bool lineStartsInComment; + bool blockCommentNoIndent; + bool blockCommentNoBeautify; + bool previousLineProbationTab; + bool lineBeginsWithOpenBracket; + bool lineBeginsWithCloseBracket; + bool lineBeginsWithComma; + bool lineIsCommentOnly; + bool lineIsLineCommentOnly; + bool shouldIndentBrackettedLine; + bool isInSwitch; + bool foundPreCommandHeader; + bool foundPreCommandMacro; + bool shouldAlignMethodColon; + bool shouldIndentPreprocConditional; + int indentCount; + int spaceIndentCount; + int spaceIndentObjCMethodDefinition; + int colonIndentObjCMethodDefinition; + int lineOpeningBlocksNum; + int lineClosingBlocksNum; + int fileType; + int minConditionalOption; + int minConditionalIndent; + int parenDepth; + int indentLength; + int tabLength; + int blockTabCount; + int maxInStatementIndent; + int classInitializerIndents; + int templateDepth; + int squareBracketCount; + int prevFinalLineSpaceIndentCount; + int prevFinalLineIndentCount; + int defineIndentCount; + int preprocBlockIndent; + char quoteChar; + char prevNonSpaceCh; + char currentNonSpaceCh; + char currentNonLegalCh; + char prevNonLegalCh; +}; // Class ASBeautifier + +//----------------------------------------------------------------------------- +// Class ASEnhancer +//----------------------------------------------------------------------------- + +class ASEnhancer : protected ASBase +{ +public: // functions + ASEnhancer(); + virtual ~ASEnhancer(); + void init(int, int, int, bool, bool, bool, bool, bool, bool, bool, + vector* >*); + void enhance(string& line, bool isInNamespace, bool isInPreprocessor, bool isInSQL); + +private: // functions + void convertForceTabIndentToSpaces(string& line) const; + void convertSpaceIndentToForceTab(string& line) const; + size_t findCaseColon(string& line, size_t caseIndex) const; + int indentLine(string& line, int indent) const; + bool isBeginDeclareSectionSQL(string& line, size_t index) const; + bool isEndDeclareSectionSQL(string& line, size_t index) const; + bool isOneLineBlockReached(string& line, int startChar) const; + void parseCurrentLine(string& line, bool isInPreprocessor, bool isInSQL); + size_t processSwitchBlock(string& line, size_t index); + int unindentLine(string& line, int unindent) const; + +private: + // options from command line or options file + int indentLength; + int tabLength; + bool useTabs; + bool forceTab; + bool namespaceIndent; + bool caseIndent; + bool preprocBlockIndent; + bool preprocDefineIndent; + bool emptyLineFill; + + // parsing variables + int lineNumber; + bool isInQuote; + bool isInComment; + char quoteChar; + + // unindent variables + int bracketCount; + int switchDepth; + int eventPreprocDepth; + bool lookingForCaseBracket; + bool unindentNextLine; + bool shouldUnindentLine; + bool shouldUnindentComment; + + // struct used by ParseFormattedLine function + // contains variables used to unindent the case blocks + struct switchVariables + { + int switchBracketCount; + int unindentDepth; + bool unindentCase; + }; + + switchVariables sw; // switch variables struct + vector switchStack; // stack vector of switch variables + + // event table variables + bool nextLineIsEventIndent; // begin event table indent is reached + bool isInEventTable; // need to indent an event table + vector* >* indentableMacros; + + // SQL variables + bool nextLineIsDeclareIndent; // begin declare section indent is reached + bool isInDeclareSection; // need to indent a declare section + +}; // Class ASEnhancer + +//----------------------------------------------------------------------------- +// Class ASFormatter +//----------------------------------------------------------------------------- + +class ASFormatter : public ASBeautifier +{ +public: // functions + ASFormatter(); + virtual ~ASFormatter(); + virtual void init(ASSourceIterator* iter); + virtual bool hasMoreLines() const; + virtual string nextLine(); + LineEndFormat getLineEndFormat() const; + bool getIsLineReady() const; + void setFormattingStyle(FormatStyle style); + void setAddBracketsMode(bool state); + void setAddOneLineBracketsMode(bool state); + void setRemoveBracketsMode(bool state); + void setAttachClass(bool state); + void setAttachExternC(bool state); + void setAttachNamespace(bool state); + void setAttachInline(bool state); + void setBracketFormatMode(BracketMode mode); + void setBreakAfterMode(bool state); + void setBreakClosingHeaderBracketsMode(bool state); + void setBreakBlocksMode(bool state); + void setBreakClosingHeaderBlocksMode(bool state); + void setBreakElseIfsMode(bool state); + void setBreakOneLineBlocksMode(bool state); + void setMethodPrefixPaddingMode(bool state); + void setMethodPrefixUnPaddingMode(bool state); + void setReturnTypePaddingMode(bool state); + void setReturnTypeUnPaddingMode(bool state); + void setCloseTemplatesMode(bool state); + void setCommaPaddingMode(bool state); + void setDeleteEmptyLinesMode(bool state); + void setIndentCol1CommentsMode(bool state); + void setLineEndFormat(LineEndFormat fmt); + void setMaxCodeLength(int max); + void setObjCColonPaddingMode(ObjCColonPad mode); + void setOperatorPaddingMode(bool mode); + void setParensOutsidePaddingMode(bool mode); + void setParensFirstPaddingMode(bool mode); + void setParensInsidePaddingMode(bool mode); + void setParensHeaderPaddingMode(bool mode); + void setParensUnPaddingMode(bool state); + void setPointerAlignment(PointerAlign alignment); + void setPreprocBlockIndent(bool state); + void setReferenceAlignment(ReferenceAlign alignment); + void setSingleStatementsMode(bool state); + void setStripCommentPrefix(bool state); + void setTabSpaceConversionMode(bool state); + size_t getChecksumIn() const; + size_t getChecksumOut() const; + int getChecksumDiff() const; + int getFormatterFileType() const; + +private: // functions + ASFormatter(const ASFormatter& copy); // not to be implemented + ASFormatter& operator=(ASFormatter&); // not to be implemented + template void deleteContainer(T& container); + template void initContainer(T& container, T value); + char peekNextChar() const; + BracketType getBracketType(); + bool adjustChecksumIn(int adjustment); + bool computeChecksumIn(const string& currentLine_); + bool computeChecksumOut(const string& beautifiedLine); + bool addBracketsToStatement(); + bool removeBracketsFromStatement(); + bool commentAndHeaderFollows(); + bool getNextChar(); + bool getNextLine(bool emptyLineWasDeleted = false); + bool isArrayOperator() const; + bool isBeforeComment() const; + bool isBeforeAnyComment() const; + bool isBeforeAnyLineEndComment(int startPos) const; + bool isBeforeMultipleLineEndComments(int startPos) const; + bool isBracketType(BracketType a, BracketType b) const; + bool isClassInitializer() const; + bool isClosingHeader(const string* header) const; + bool isCurrentBracketBroken() const; + bool isDereferenceOrAddressOf() const; + bool isExecSQL(string& line, size_t index) const; + bool isEmptyLine(const string& line) const; + bool isExternC() const; + bool isNextWordSharpNonParenHeader(int startChar) const; + bool isNonInStatementArrayBracket() const; + bool isOkToSplitFormattedLine(); + bool isPointerOrReference() const; + bool isPointerOrReferenceCentered() const; + bool isPointerOrReferenceVariable(string& word) const; + bool isSharpStyleWithParen(const string* header) const; + bool isStructAccessModified(string& firstLine, size_t index) const; + bool isIndentablePreprocessorBlock(string& firstLine, size_t index); + bool isUnaryOperator() const; + bool isUniformInitializerBracket() const; + bool isImmediatelyPostCast() const; + bool isInExponent() const; + bool isInSwitchStatement() const; + bool isNextCharOpeningBracket(int startChar) const; + bool isOkToBreakBlock(BracketType bracketType) const; + bool isOperatorPaddingDisabled() const; + bool pointerSymbolFollows() const; + int findObjCColonAlignment() const; + int getCurrentLineCommentAdjustment(); + int getNextLineCommentAdjustment(); + int isOneLineBlockReached(string& line, int startChar) const; + void adjustComments(); + void appendChar(char ch, bool canBreakLine); + void appendCharInsideComments(); + void appendOperator(const string& sequence, bool canBreakLine = true); + void appendSequence(const string& sequence, bool canBreakLine = true); + void appendSpacePad(); + void appendSpaceAfter(); + void breakLine(bool isSplitLine = false); + void buildLanguageVectors(); + void updateFormattedLineSplitPoints(char appendedChar); + void updateFormattedLineSplitPointsOperator(const string& sequence); + void checkIfTemplateOpener(); + void clearFormattedLineSplitPoints(); + void convertTabToSpaces(); + void deleteContainer(vector*& container); + void formatArrayRunIn(); + void formatRunIn(); + void formatArrayBrackets(BracketType bracketType, bool isOpeningArrayBracket); + void formatClosingBracket(BracketType bracketType); + void formatCommentBody(); + void formatCommentOpener(); + void formatCommentCloser(); + void formatLineCommentBody(); + void formatLineCommentOpener(); + void formatOpeningBracket(BracketType bracketType); + void formatQuoteBody(); + void formatQuoteOpener(); + void formatPointerOrReference(); + void formatPointerOrReferenceCast(); + void formatPointerOrReferenceToMiddle(); + void formatPointerOrReferenceToName(); + void formatPointerOrReferenceToType(); + void fixOptionVariableConflicts(); + void goForward(int i); + void isLineBreakBeforeClosingHeader(); + void initContainer(vector*& container, vector* value); + void initNewLine(); + void padObjCMethodColon(); + void padOperators(const string* newOperator); + void padParens(); + void padParenObjC(void); + void processPreprocessor(); + void resetEndOfStatement(); + void setAttachClosingBracketMode(bool state); + void stripCommentPrefix(); + void testForTimeToSplitFormattedLine(); + void trimContinuationLine(); + void updateFormattedLineSplitPointsPointerOrReference(size_t index); + size_t findFormattedLineSplitPoint() const; + size_t findNextChar(string& line, char searchChar, int searchStart = 0) const; + const string* checkForHeaderFollowingComment(const string& firstLine) const; + const string* getFollowingOperator() const; + string getPreviousWord(const string& line, int currPos) const; + string peekNextText(const string& firstLine, bool endOnEmptyLine = false, bool shouldReset = false) const; + +private: // variables + int formatterFileType; + vector* headers; + vector* nonParenHeaders; + vector* preDefinitionHeaders; + vector* preCommandHeaders; + vector* operators; + vector* assignmentOperators; + vector* castOperators; + vector* >* indentableMacros; // for ASEnhancer + + ASSourceIterator* sourceIterator; + ASEnhancer* enhancer; + + vector* preBracketHeaderStack; + vector* bracketTypeStack; + vector* parenStack; + vector* structStack; + vector* questionMarkStack; + + string currentLine; + string formattedLine; + string readyFormattedLine; + string verbatimDelimiter; + const string* currentHeader; + const string* previousOperator; // used ONLY by pad-oper + char currentChar; + char previousChar; + char previousNonWSChar; + char previousCommandChar; + char quoteChar; + streamoff preprocBlockEnd; + int charNum; + int horstmannIndentChars; + int nextLineSpacePadNum; + int objCColonAlign; + int preprocBracketTypeStackSize; + int spacePadNum; + int tabIncrementIn; + int templateDepth; + int squareBracketCount; + size_t checksumIn; + size_t checksumOut; + size_t currentLineFirstBracketNum; // first bracket location on currentLine + size_t formattedLineCommentNum; // comment location on formattedLine + size_t leadingSpaces; + size_t maxCodeLength; + + // possible split points + size_t maxSemi; // probably a 'for' statement + size_t maxAndOr; // probably an 'if' statement + size_t maxComma; + size_t maxParen; + size_t maxWhiteSpace; + size_t maxSemiPending; + size_t maxAndOrPending; + size_t maxCommaPending; + size_t maxParenPending; + size_t maxWhiteSpacePending; + + size_t previousReadyFormattedLineLength; + FormatStyle formattingStyle; + BracketMode bracketFormatMode; + BracketType previousBracketType; + PointerAlign pointerAlignment; + ReferenceAlign referenceAlignment; + ObjCColonPad objCColonPadMode; + LineEndFormat lineEnd; + bool isVirgin; + bool shouldPadCommas; + bool shouldPadOperators; + bool shouldPadParensOutside; + bool shouldPadFirstParen; + bool shouldPadParensInside; + bool shouldPadHeader; + bool shouldStripCommentPrefix; + bool shouldUnPadParens; + bool shouldConvertTabs; + bool shouldIndentCol1Comments; + bool shouldIndentPreprocBlock; + bool shouldCloseTemplates; + bool shouldAttachExternC; + bool shouldAttachNamespace; + bool shouldAttachClass; + bool shouldAttachInline; + bool isInLineComment; + bool isInComment; + bool isInCommentStartLine; + bool noTrimCommentContinuation; + bool isInPreprocessor; + bool isInPreprocessorBeautify; + bool isInTemplate; + bool doesLineStartComment; + bool lineEndsInCommentOnly; + bool lineIsCommentOnly; + bool lineIsLineCommentOnly; + bool lineIsEmpty; + bool isImmediatelyPostCommentOnly; + bool isImmediatelyPostEmptyLine; + bool isInClassInitializer; + bool isInQuote; + bool isInVerbatimQuote; + bool haveLineContinuationChar; + bool isInQuoteContinuation; + bool isHeaderInMultiStatementLine; + bool isSpecialChar; + bool isNonParenHeader; + bool foundQuestionMark; + bool foundPreDefinitionHeader; + bool foundNamespaceHeader; + bool foundClassHeader; + bool foundStructHeader; + bool foundInterfaceHeader; + bool foundPreCommandHeader; + bool foundPreCommandMacro; + bool foundCastOperator; + bool isInLineBreak; + bool endOfAsmReached; + bool endOfCodeReached; + bool lineCommentNoIndent; + bool isFormattingModeOff; + bool isInEnum; + bool isInExecSQL; + bool isInAsm; + bool isInAsmOneLine; + bool isInAsmBlock; + bool isLineReady; + bool elseHeaderFollowsComments; + bool caseHeaderFollowsComments; + bool isPreviousBracketBlockRelated; + bool isInPotentialCalculation; + bool isCharImmediatelyPostComment; + bool isPreviousCharPostComment; + bool isCharImmediatelyPostLineComment; + bool isCharImmediatelyPostOpenBlock; + bool isCharImmediatelyPostCloseBlock; + bool isCharImmediatelyPostTemplate; + bool isCharImmediatelyPostReturn; + bool isCharImmediatelyPostThrow; + bool isCharImmediatelyPostOperator; + bool isCharImmediatelyPostPointerOrReference; + bool isInObjCMethodDefinition; + bool isInObjCInterface; + bool isInObjCReturnType; + bool isInObjCSelector; + bool breakCurrentOneLineBlock; + bool shouldRemoveNextClosingBracket; + bool isInHorstmannRunIn; + bool currentLineBeginsWithBracket; + bool attachClosingBracketMode; + bool shouldBreakOneLineBlocks; + bool shouldReparseCurrentChar; + bool shouldBreakOneLineStatements; + bool shouldBreakClosingHeaderBrackets; + bool shouldBreakElseIfs; + bool shouldBreakLineAfterLogical; + bool shouldAddBrackets; + bool shouldAddOneLineBrackets; + bool shouldRemoveBrackets; + bool shouldPadMethodColon; + bool shouldPadMethodPrefix; + bool shouldUnPadMethodPrefix; + bool shouldPadReturnType; + bool shouldUnPadReturnType; + bool shouldDeleteEmptyLines; + bool needHeaderOpeningBracket; + bool shouldBreakLineAtNextChar; + bool shouldKeepLineUnbroken; + bool passedSemicolon; + bool passedColon; + bool isImmediatelyPostNonInStmt; + bool isCharImmediatelyPostNonInStmt; + bool isImmediatelyPostComment; + bool isImmediatelyPostLineComment; + bool isImmediatelyPostEmptyBlock; + bool isImmediatelyPostObjCMethodPrefix; + bool isImmediatelyPostPreprocessor; + bool isImmediatelyPostReturn; + bool isImmediatelyPostThrow; + bool isImmediatelyPostOperator; + bool isImmediatelyPostTemplate; + bool isImmediatelyPostPointerOrReference; + bool shouldBreakBlocks; + bool shouldBreakClosingHeaderBlocks; + bool isPrependPostBlockEmptyLineRequested; + bool isAppendPostBlockEmptyLineRequested; + bool isIndentableProprocessor; + bool isIndentableProprocessorBlock; + bool prependEmptyLine; + bool appendOpeningBracket; + bool foundClosingHeader; + bool isInHeader; + bool isImmediatelyPostHeader; + bool isInCase; + bool isFirstPreprocConditional; + bool processedFirstConditional; + bool isJavaStaticConstructor; + +private: // inline functions + // append the CURRENT character (curentChar) to the current formatted line. + void appendCurrentChar(bool canBreakLine = true) + { + appendChar(currentChar, canBreakLine); + } + + // check if a specific sequence exists in the current placement of the current line + bool isSequenceReached(const char* sequence) const + { + return currentLine.compare(charNum, strlen(sequence), sequence) == 0; + } + + // call ASBase::findHeader for the current character + const string* findHeader(const vector* headers_) + { + return ASBeautifier::findHeader(currentLine, charNum, headers_); + } + + // call ASBase::findOperator for the current character + const string* findOperator(const vector* headers_) + { + return ASBeautifier::findOperator(currentLine, charNum, headers_); + } +}; // Class ASFormatter + +//----------------------------------------------------------------------------- +// astyle namespace global declarations +//----------------------------------------------------------------------------- +// sort comparison functions for ASResource +bool sortOnLength(const string* a, const string* b); +bool sortOnName(const string* a, const string* b); + +} // end of astyle namespace + +// end of astyle namespace -------------------------------------------------- + +#endif // closes ASTYLE_H diff --git a/External/Tools/AStyle/src/astyle_main.cpp b/External/Tools/AStyle/src/astyle_main.cpp new file mode 100644 index 0000000000..1adc3cd18f --- /dev/null +++ b/External/Tools/AStyle/src/astyle_main.cpp @@ -0,0 +1,3792 @@ +// astyle_main.cpp +// Copyright (c) 2016 by Jim Pattee . +// Licensed under the MIT license. +// License.txt describes the conditions under which this software may be distributed. + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * AStyle_main source file map. + * This source file contains several classes. + * They are arranged as follows. + * --------------------------------------- + * namespace astyle { + * ASStreamIterator methods + * ASConsole methods + * // Windows specific + * // Linux specific + * ASLibrary methods + * // Windows specific + * // Linux specific + * ASOptions methods + * Utf8_16 methods + * } // end of astyle namespace + * Global Area --------------------------- + * Java Native Interface functions + * AStyleMainUtf16 entry point + * AStyleMain entry point + * AStyleGetVersion entry point + * main entry point + * --------------------------------------- + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ + +//----------------------------------------------------------------------------- +// headers +//----------------------------------------------------------------------------- + +#include "astyle_main.h" + +#include +#include +#include +#include +#include // needed by some compilers +#include + +// includes for recursive getFileNames() function +#ifdef _WIN32 + #undef UNICODE // use ASCII windows functions + #include +#else + #include + #include + #include + #ifdef __VMS + #include + #include + #include + #include + #include + #include + #endif /* __VMS */ +#endif + +//----------------------------------------------------------------------------- +// declarations +//----------------------------------------------------------------------------- + +// turn off MinGW automatic file globbing +// this CANNOT be in the astyle namespace +#ifndef ASTYLE_LIB + int _CRT_glob = 0; +#endif + +//---------------------------------------------------------------------------- +// astyle namespace +//---------------------------------------------------------------------------- + +namespace astyle { +// +// console build variables +#ifndef ASTYLE_LIB + ASConsole* g_console = NULL; // class to encapsulate console variables + ostream* _err = &cerr; // direct error messages to cerr + #ifdef _WIN32 + char g_fileSeparator = '\\'; // Windows file separator + bool g_isCaseSensitive = false; // Windows IS case sensitive + #else + char g_fileSeparator = '/'; // Linux file separator + bool g_isCaseSensitive = true; // Linux IS NOT case sensitive + #endif // _WIN32 +#endif // ASTYLE_LIB + +// java library build variables +#ifdef ASTYLE_JNI + JNIEnv* g_env; + jobject g_obj; + jmethodID g_mid; +#endif + +const char* g_version = "2.06 beta"; + +//----------------------------------------------------------------------------- +// ASStreamIterator class +// typename will be istringstream for GUI and istream otherwise +//----------------------------------------------------------------------------- + +template +ASStreamIterator::ASStreamIterator(T* in) +{ + inStream = in; + buffer.reserve(200); + eolWindows = 0; + eolLinux = 0; + eolMacOld = 0; + outputEOL[0] = '\0'; + peekStart = 0; + prevLineDeleted = false; + checkForEmptyLine = false; + // get length of stream + inStream->seekg(0, inStream->end); + streamLength = inStream->tellg(); + inStream->seekg(0, inStream->beg); +} + +template +ASStreamIterator::~ASStreamIterator() +{ +} + +/** +* get the length of the input stream. +* streamLength variable is set by the constructor. +* +* @return length of the input file stream, converted to an int. +*/ +template +int ASStreamIterator::getStreamLength() const +{ + return static_cast(streamLength); +} + +/** + * read the input stream, delete any end of line characters, + * and build a string that contains the input line. + * + * @return string containing the next input line minus any end of line characters + */ +template +string ASStreamIterator::nextLine(bool emptyLineWasDeleted) +{ + // verify that the current position is correct + assert(peekStart == 0); + + // a deleted line may be replaced if break-blocks is requested + // this sets up the compare to check for a replaced empty line + if (prevLineDeleted) + { + prevLineDeleted = false; + checkForEmptyLine = true; + } + if (!emptyLineWasDeleted) + prevBuffer = buffer; + else + prevLineDeleted = true; + + // read the next record + buffer.clear(); + char ch; + inStream->get(ch); + + while (!inStream->eof() && ch != '\n' && ch != '\r') + { + buffer.append(1, ch); + inStream->get(ch); + } + + if (inStream->eof()) + { + return buffer; + } + + int peekCh = inStream->peek(); + + // find input end-of-line characters + if (!inStream->eof()) + { + if (ch == '\r') // CR+LF is windows otherwise Mac OS 9 + { + if (peekCh == '\n') + { + inStream->get(); + eolWindows++; + } + else + eolMacOld++; + } + else // LF is Linux, allow for improbable LF/CR + { + if (peekCh == '\r') + { + inStream->get(); + eolWindows++; + } + else + eolLinux++; + } + } + else + { + inStream->clear(); + } + + // set output end of line characters + if (eolWindows >= eolLinux) + { + if (eolWindows >= eolMacOld) + strcpy(outputEOL, "\r\n"); // Windows (CR+LF) + else + strcpy(outputEOL, "\r"); // MacOld (CR) + } + else if (eolLinux >= eolMacOld) + strcpy(outputEOL, "\n"); // Linux (LF) + else + strcpy(outputEOL, "\r"); // MacOld (CR) + + return buffer; +} + +// save the current position and get the next line +// this can be called for multiple reads +// when finished peeking you MUST call peekReset() +// call this function from ASFormatter ONLY +template +string ASStreamIterator::peekNextLine() +{ + assert(hasMoreLines()); + string nextLine_; + char ch; + + if (peekStart == 0) + peekStart = inStream->tellg(); + + // read the next record + inStream->get(ch); + while (!inStream->eof() && ch != '\n' && ch != '\r') + { + nextLine_.append(1, ch); + inStream->get(ch); + } + + if (inStream->eof()) + { + return nextLine_; + } + + int peekCh = inStream->peek(); + + // remove end-of-line characters + if (!inStream->eof()) + { + if ((peekCh == '\n' || peekCh == '\r') && peekCh != ch) + inStream->get(); + } + + return nextLine_; +} + +// reset current position and EOF for peekNextLine() +template +void ASStreamIterator::peekReset() +{ + assert(peekStart != 0); + inStream->clear(); + inStream->seekg(peekStart); + peekStart = 0; +} + +// save the last input line after input has reached EOF +template +void ASStreamIterator::saveLastInputLine() +{ + assert(inStream->eof()); + prevBuffer = buffer; +} + +// return position of the get pointer +template +streamoff ASStreamIterator::tellg() +{ + return inStream->tellg(); +} + +// check for a change in line ends +template +bool ASStreamIterator::getLineEndChange(int lineEndFormat) const +{ + assert(lineEndFormat == LINEEND_DEFAULT + || lineEndFormat == LINEEND_WINDOWS + || lineEndFormat == LINEEND_LINUX + || lineEndFormat == LINEEND_MACOLD); + + bool lineEndChange = false; + if (lineEndFormat == LINEEND_WINDOWS) + lineEndChange = (eolLinux + eolMacOld != 0); + else if (lineEndFormat == LINEEND_LINUX) + lineEndChange = (eolWindows + eolMacOld != 0); + else if (lineEndFormat == LINEEND_MACOLD) + lineEndChange = (eolWindows + eolLinux != 0); + else + { + if (eolWindows > 0) + lineEndChange = (eolLinux + eolMacOld != 0); + else if (eolLinux > 0) + lineEndChange = (eolWindows + eolMacOld != 0); + else if (eolMacOld > 0) + lineEndChange = (eolWindows + eolLinux != 0); + } + return lineEndChange; +} + +//----------------------------------------------------------------------------- +// ASConsole class +// main function will be included only in the console build +//----------------------------------------------------------------------------- + +#ifndef ASTYLE_LIB + +// rewrite a stringstream converting the line ends +void ASConsole::convertLineEnds(ostringstream& out, int lineEnd) +{ + assert(lineEnd == LINEEND_WINDOWS || lineEnd == LINEEND_LINUX || lineEnd == LINEEND_MACOLD); + const string& inStr = out.str(); // avoids strange looking syntax + string outStr; // the converted output + int inLength = inStr.length(); + for (int pos = 0; pos < inLength; pos++) + { + if (inStr[pos] == '\r') + { + if (inStr[pos + 1] == '\n') + { + // CRLF + if (lineEnd == LINEEND_CR) + { + outStr += inStr[pos]; // Delete the LF + pos++; + continue; + } + else if (lineEnd == LINEEND_LF) + { + outStr += inStr[pos + 1]; // Delete the CR + pos++; + continue; + } + else + { + outStr += inStr[pos]; // Do not change + outStr += inStr[pos + 1]; + pos++; + continue; + } + } + else + { + // CR + if (lineEnd == LINEEND_CRLF) + { + outStr += inStr[pos]; // Insert the CR + outStr += '\n'; // Insert the LF + continue; + } + else if (lineEnd == LINEEND_LF) + { + outStr += '\n'; // Insert the LF + continue; + } + else + { + outStr += inStr[pos]; // Do not change + continue; + } + } + } + else if (inStr[pos] == '\n') + { + // LF + if (lineEnd == LINEEND_CRLF) + { + outStr += '\r'; // Insert the CR + outStr += inStr[pos]; // Insert the LF + continue; + } + else if (lineEnd == LINEEND_CR) + { + outStr += '\r'; // Insert the CR + continue; + } + else + { + outStr += inStr[pos]; // Do not change + continue; + } + } + else + { + outStr += inStr[pos]; // Write the current char + } + } + // replace the stream + out.str(outStr); +} + +void ASConsole::correctMixedLineEnds(ostringstream& out) +{ + LineEndFormat lineEndFormat = LINEEND_DEFAULT; + if (strcmp(outputEOL, "\r\n") == 0) + lineEndFormat = LINEEND_WINDOWS; + if (strcmp(outputEOL, "\n") == 0) + lineEndFormat = LINEEND_LINUX; + if (strcmp(outputEOL, "\r") == 0) + lineEndFormat = LINEEND_MACOLD; + convertLineEnds(out, lineEndFormat); +} + +// check files for 16 or 32 bit encoding +// the file must have a Byte Order Mark (BOM) +// NOTE: some string functions don't work with NULLs (e.g. length()) +FileEncoding ASConsole::detectEncoding(const char* data, size_t dataSize) const +{ + FileEncoding encoding = ENCODING_8BIT; + + if (dataSize >= 4 && memcmp(data, "\x00\x00\xFE\xFF", 4) == 0) + encoding = UTF_32BE; + else if (dataSize >= 4 && memcmp(data, "\xFF\xFE\x00\x00", 4) == 0) + encoding = UTF_32LE; + else if (dataSize >= 2 && memcmp(data, "\xFE\xFF", 2) == 0) + encoding = UTF_16BE; + else if (dataSize >= 2 && memcmp(data, "\xFF\xFE", 2) == 0) + encoding = UTF_16LE; + + return encoding; +} + +// error exit without a message +void ASConsole::error() const +{ + (*_err) << _("\nArtistic Style has terminated") << endl; + exit(EXIT_FAILURE); +} + +// error exit with a message +void ASConsole::error(const char* why, const char* what) const +{ + (*_err) << why << ' ' << what << endl; + error(); +} + +/** + * If no files have been given, use cin for input and cout for output. + * + * This is used to format text for text editors like TextWrangler (Mac). + * Do NOT display any console messages when this function is used. + */ +void ASConsole::formatCinToCout() +{ + // Using cin.tellg() causes problems with both Windows and Linux. + // The Windows problem occurs when the input is not Windows line-ends. + // The tellg() will be out of sequence with the get() statements. + // The Linux cin.tellg() will return -1 (invalid). + // Copying the input sequentially to a stringstream before + // formatting solves the problem for both. + istream* inStream = &cin; + stringstream outStream; + char ch; + inStream->get(ch); + while (!inStream->eof()) + { + outStream.put(ch); + inStream->get(ch); + } + ASStreamIterator streamIterator(&outStream); + // Windows pipe or redirection always outputs Windows line-ends. + // Linux pipe or redirection will output any line end. + LineEndFormat lineEndFormat = formatter.getLineEndFormat(); + initializeOutputEOL(lineEndFormat); + formatter.init(&streamIterator); + + while (formatter.hasMoreLines()) + { + cout << formatter.nextLine(); + if (formatter.hasMoreLines()) + { + setOutputEOL(lineEndFormat, streamIterator.getOutputEOL()); + cout << outputEOL; + } + else + { + // this can happen if the file if missing a closing bracket and break-blocks is requested + if (formatter.getIsLineReady()) + { + setOutputEOL(lineEndFormat, streamIterator.getOutputEOL()); + cout << outputEOL; + cout << formatter.nextLine(); + } + } + } + cout.flush(); +} + +/** + * Open input file, format it, and close the output. + * + * @param fileName_ The path and name of the file to be processed. + */ +void ASConsole::formatFile(const string& fileName_) +{ + stringstream in; + ostringstream out; + FileEncoding encoding = readFile(fileName_, in); + + // Unless a specific language mode has been set, set the language mode + // according to the file's suffix. + if (!formatter.getModeManuallySet()) + { + if (stringEndsWith(fileName_, string(".java"))) + formatter.setJavaStyle(); + else if (stringEndsWith(fileName_, string(".cs"))) + formatter.setSharpStyle(); + else + formatter.setCStyle(); + } + + // set line end format + string nextLine; // next output line + filesAreIdentical = true; // input and output files are identical + LineEndFormat lineEndFormat = formatter.getLineEndFormat(); + initializeOutputEOL(lineEndFormat); + // do this AFTER setting the file mode + ASStreamIterator streamIterator(&in); + formatter.init(&streamIterator); + + // format the file + while (formatter.hasMoreLines()) + { + nextLine = formatter.nextLine(); + out << nextLine; + linesOut++; + if (formatter.hasMoreLines()) + { + setOutputEOL(lineEndFormat, streamIterator.getOutputEOL()); + out << outputEOL; + } + else + { + streamIterator.saveLastInputLine(); // to compare the last input line + // this can happen if the file if missing a closing bracket and break-blocks is requested + if (formatter.getIsLineReady()) + { + setOutputEOL(lineEndFormat, streamIterator.getOutputEOL()); + out << outputEOL; + nextLine = formatter.nextLine(); + out << nextLine; + linesOut++; + streamIterator.saveLastInputLine(); + } + } + + if (filesAreIdentical) + { + if (streamIterator.checkForEmptyLine) + { + if (nextLine.find_first_not_of(" \t") != string::npos) + filesAreIdentical = false; + } + else if (!streamIterator.compareToInputBuffer(nextLine)) + filesAreIdentical = false; + streamIterator.checkForEmptyLine = false; + } + } + // correct for mixed line ends + if (lineEndsMixed) + { + correctMixedLineEnds(out); + filesAreIdentical = false; + } + + // remove targetDirectory from filename if required by print + string displayName; + if (hasWildcard) + displayName = fileName_.substr(targetDirectory.length() + 1); + else + displayName = fileName_; + + // if file has changed, write the new file + if (!filesAreIdentical || streamIterator.getLineEndChange(lineEndFormat)) + { + if (!isDryRun) + writeFile(fileName_, encoding, out); + printMsg(_("Formatted %s\n"), displayName); + filesFormatted++; + } + else + { + if (!isFormattedOnly) + printMsg(_("Unchanged %s\n"), displayName); + filesUnchanged++; + } + + assert(formatter.getChecksumDiff() == 0); +} + +// build a vector of argv options +// the program path argv[0] is excluded +vector ASConsole::getArgvOptions(int argc, char** argv) const +{ + vector argvOptions; + for (int i = 1; i < argc; i++) + { + argvOptions.push_back(string(argv[i])); + } + return argvOptions; +} + +// for unit testing +vector ASConsole::getExcludeHitsVector() const +{ return excludeHitsVector; } + +// for unit testing +vector ASConsole::getExcludeVector() const +{ return excludeVector; } + +// for unit testing +vector ASConsole::getFileName() const +{ return fileName; } + +// for unit testing +vector ASConsole::getFileNameVector() const +{ return fileNameVector; } + +// for unit testing +vector ASConsole::getFileOptionsVector() const +{ return fileOptionsVector; } + +// for unit testing +bool ASConsole::getFilesAreIdentical() const +{ return filesAreIdentical; } + +// for unit testing +int ASConsole::getFilesFormatted() const +{ return filesFormatted; } + +// for unit testing +bool ASConsole::getIgnoreExcludeErrors() const +{ return ignoreExcludeErrors; } + +// for unit testing +bool ASConsole::getIgnoreExcludeErrorsDisplay() const +{ return ignoreExcludeErrorsDisplay; } + +// for unit testing +bool ASConsole::getIsDryRun() const +{ return isDryRun; } + +// for unit testing +bool ASConsole::getIsFormattedOnly() const +{ return isFormattedOnly; } + +// for unit testing +string ASConsole::getLanguageID() const +{ return localizer.getLanguageID(); } + +// for unit testing +bool ASConsole::getIsQuiet() const +{ return isQuiet; } + +// for unit testing +bool ASConsole::getIsRecursive() const +{ return isRecursive; } + +// for unit testing +bool ASConsole::getIsVerbose() const +{ return isVerbose; } + +// for unit testing +bool ASConsole::getLineEndsMixed() const +{ return lineEndsMixed; } + +// for unit testing +bool ASConsole::getNoBackup() const +{ return noBackup; } + +// for unit testing +string ASConsole::getOptionsFileName() const +{ return optionsFileName; } + +// for unit testing +vector ASConsole::getOptionsVector() const +{ return optionsVector; } + +// for unit testing +string ASConsole::getOrigSuffix() const +{ return origSuffix; } + +// for unit testing +bool ASConsole::getPreserveDate() const +{ return preserveDate; } + +// for unit testing +void ASConsole::setBypassBrowserOpen(bool state) +{ bypassBrowserOpen = state; } + +string ASConsole::getParam(const string& arg, const char* op) +{ + return arg.substr(strlen(op)); +} + +// initialize output end of line +void ASConsole::initializeOutputEOL(LineEndFormat lineEndFormat) +{ + assert(lineEndFormat == LINEEND_DEFAULT + || lineEndFormat == LINEEND_WINDOWS + || lineEndFormat == LINEEND_LINUX + || lineEndFormat == LINEEND_MACOLD); + + outputEOL[0] = '\0'; // current line end + prevEOL[0] = '\0'; // previous line end + lineEndsMixed = false; // output has mixed line ends, LINEEND_DEFAULT only + + if (lineEndFormat == LINEEND_WINDOWS) + strcpy(outputEOL, "\r\n"); + else if (lineEndFormat == LINEEND_LINUX) + strcpy(outputEOL, "\n"); + else if (lineEndFormat == LINEEND_MACOLD) + strcpy(outputEOL, "\r"); + else + outputEOL[0] = '\0'; +} + +FileEncoding ASConsole::readFile(const string& fileName_, stringstream& in) const +{ + const int blockSize = 65536; // 64 KB + ifstream fin(fileName_.c_str(), ios::binary); + if (!fin) + error("Cannot open input file", fileName_.c_str()); + char* data = new(nothrow) char[blockSize]; + if (!data) + error("Cannot allocate memory for input file", fileName_.c_str()); + fin.read(data, blockSize); + if (fin.bad()) + error("Cannot read input file", fileName_.c_str()); + size_t dataSize = static_cast(fin.gcount()); + FileEncoding encoding = detectEncoding(data, dataSize); + if (encoding == UTF_32BE || encoding == UTF_32LE) + error(_("Cannot process UTF-32 encoding"), fileName_.c_str()); + bool firstBlock = true; + bool isBigEndian = (encoding == UTF_16BE); + while (dataSize) + { + if (encoding == UTF_16LE || encoding == UTF_16BE) + { + // convert utf-16 to utf-8 + size_t utf8Size = utf8_16.Utf8LengthFromUtf16(data, dataSize, isBigEndian); + char* utf8Out = new(nothrow) char[utf8Size]; + if (!utf8Out) + error("Cannot allocate memory for utf-8 conversion", fileName_.c_str()); + size_t utf8Len = utf8_16.Utf16ToUtf8(data, dataSize, isBigEndian, firstBlock, utf8Out); + assert(utf8Len == utf8Size); + in << string(utf8Out, utf8Len); + delete [] utf8Out; + } + else + in << string(data, dataSize); + fin.read(data, blockSize); + if (fin.bad()) + error("Cannot read input file", fileName_.c_str()); + dataSize = static_cast(fin.gcount()); + firstBlock = false; + } + fin.close(); + delete [] data; + return encoding; +} + +void ASConsole::setIgnoreExcludeErrors(bool state) +{ ignoreExcludeErrors = state; } + +void ASConsole::setIgnoreExcludeErrorsAndDisplay(bool state) +{ ignoreExcludeErrors = state; ignoreExcludeErrorsDisplay = state; } + +void ASConsole::setIsFormattedOnly(bool state) +{ isFormattedOnly = state; } + +void ASConsole::setIsQuiet(bool state) +{ isQuiet = state; } + +void ASConsole::setIsRecursive(bool state) +{ isRecursive = state; } + +void ASConsole::setIsDryRun(bool state) +{ isDryRun = state; } + +void ASConsole::setIsVerbose(bool state) +{ isVerbose = state; } + +void ASConsole::setNoBackup(bool state) +{ noBackup = state; } + +void ASConsole::setOptionsFileName(string name) +{ optionsFileName = name; } + +void ASConsole::setOrigSuffix(string suffix) +{ origSuffix = suffix; } + +void ASConsole::setPreserveDate(bool state) +{ preserveDate = state; } + +// set outputEOL variable +void ASConsole::setOutputEOL(LineEndFormat lineEndFormat, const char* currentEOL) +{ + if (lineEndFormat == LINEEND_DEFAULT) + { + strcpy(outputEOL, currentEOL); + if (strlen(prevEOL) == 0) + strcpy(prevEOL, outputEOL); + if (strcmp(prevEOL, outputEOL) != 0) + { + lineEndsMixed = true; + filesAreIdentical = false; + strcpy(prevEOL, outputEOL); + } + } + else + { + strcpy(prevEOL, currentEOL); + if (strcmp(prevEOL, outputEOL) != 0) + filesAreIdentical = false; + } +} + +#ifdef _WIN32 // Windows specific + +/** + * WINDOWS function to display the last system error. + */ +void ASConsole::displayLastError() +{ + LPSTR msgBuf; + DWORD lastError = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + lastError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPSTR) &msgBuf, + 0, + NULL + ); + // Display the string. + (*_err) << "Error (" << lastError << ") " << msgBuf << endl; + // Free the buffer. + LocalFree(msgBuf); +} + +/** + * WINDOWS function to get the current directory. + * NOTE: getenv("CD") does not work for Windows Vista. + * The Windows function GetCurrentDirectory is used instead. + * + * @return The path of the current directory + */ +string ASConsole::getCurrentDirectory(const string& fileName_) const +{ + char currdir[MAX_PATH]; + currdir[0] = '\0'; + if (!GetCurrentDirectory(sizeof(currdir), currdir)) + error("Cannot find file", fileName_.c_str()); + return string(currdir); +} + +/** + * WINDOWS function to resolve wildcards and recurse into sub directories. + * The fileName vector is filled with the path and names of files to process. + * + * @param directory The path of the directory to be processed. + * @param wildcard The wildcard to be processed (e.g. *.cpp). + */ +void ASConsole::getFileNames(const string& directory, const string& wildcard) +{ + vector subDirectory; // sub directories of directory + WIN32_FIND_DATA findFileData; // for FindFirstFile and FindNextFile + + // Find the first file in the directory + // Find will get at least "." and "..". + string firstFile = directory + "\\*"; + HANDLE hFind = FindFirstFile(firstFile.c_str(), &findFileData); + + if (hFind == INVALID_HANDLE_VALUE) + { + // Error (3) The system cannot find the path specified. + // Error (123) The filename, directory name, or volume label syntax is incorrect. + // ::FindClose(hFind); before exiting + displayLastError(); + error(_("Cannot open directory"), directory.c_str()); + } + + // save files and sub directories + do + { + // skip hidden or read only + if (findFileData.cFileName[0] == '.' + || (findFileData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) + || (findFileData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + continue; + + // is this a sub directory + if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (!isRecursive) + continue; + // if a sub directory and recursive, save sub directory + string subDirectoryPath = directory + g_fileSeparator + findFileData.cFileName; + if (isPathExclued(subDirectoryPath)) + printMsg(_("Exclude %s\n"), subDirectoryPath.substr(mainDirectoryLength)); + else + subDirectory.push_back(subDirectoryPath); + continue; + } + + // save the file name + string filePathName = directory + g_fileSeparator + findFileData.cFileName; + // check exclude before wildcmp to avoid "unmatched exclude" error + bool isExcluded = isPathExclued(filePathName); + // save file name if wildcard match + if (wildcmp(wildcard.c_str(), findFileData.cFileName)) + { + if (isExcluded) + printMsg(_("Exclude %s\n"), filePathName.substr(mainDirectoryLength)); + else + fileName.push_back(filePathName); + } + } + while (FindNextFile(hFind, &findFileData) != 0); + + // check for processing error + ::FindClose(hFind); + DWORD dwError = GetLastError(); + if (dwError != ERROR_NO_MORE_FILES) + error("Error processing directory", directory.c_str()); + + // recurse into sub directories + // if not doing recursive subDirectory is empty + for (unsigned i = 0; i < subDirectory.size(); i++) + getFileNames(subDirectory[i], wildcard); + + return; +} + +/** + * WINDOWS function to format a number according to the current locale. + * This formats positive integers only, no float. + * + * @param num The number to be formatted. + * @param lcid The LCID of the locale to be used for testing. + * @return The formatted number. + */ +string ASConsole::getNumberFormat(int num, size_t lcid) const +{ +#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__BORLANDC__) || defined(__GNUC__) + // Compilers that don't support C++ locales should still support this assert. + // The C locale should be set but not the C++. + // This function is not necessary if the C++ locale is set. + // The locale().name() return value is not portable to all compilers. + assert(locale().name() == "C"); +#endif + // convert num to a string + stringstream alphaNum; + alphaNum << num; + string number = alphaNum.str(); + if (useAscii) + return number; + + // format the number using the Windows API + if (lcid == 0) + lcid = LOCALE_USER_DEFAULT; + int outSize = ::GetNumberFormat(lcid, 0, number.c_str(), NULL, NULL, 0); + char* outBuf = new(nothrow) char[outSize]; + if (outBuf == NULL) + return number; + ::GetNumberFormat(lcid, 0, number.c_str(), NULL, outBuf, outSize); + string formattedNum(outBuf); + delete [] outBuf; + // remove the decimal + int decSize = ::GetLocaleInfo(lcid, LOCALE_SDECIMAL, NULL, 0); + char* decBuf = new(nothrow) char[decSize]; + if (decBuf == NULL) + return number; + ::GetLocaleInfo(lcid, LOCALE_SDECIMAL, decBuf, decSize); + size_t i = formattedNum.rfind(decBuf); + delete [] decBuf; + if (i != string::npos) + formattedNum.erase(i); + if (!formattedNum.length()) + formattedNum = "0"; + return formattedNum; +} + +/** + * WINDOWS function to open a HTML file in the default browser. + */ +void ASConsole::launchDefaultBrowser(const char* filePathIn /*NULL*/) const +{ + struct stat statbuf; + const char* envPaths[] = { "PROGRAMFILES(X86)", "PROGRAMFILES" }; + size_t pathsLen = sizeof(envPaths) / sizeof(envPaths[0]); + string htmlDefaultPath; + for (size_t i = 0; i < pathsLen; i++) + { + const char* envPath = getenv(envPaths[i]); + if (envPath == NULL) + continue; + htmlDefaultPath = envPath; + if (htmlDefaultPath.length() > 0 + && htmlDefaultPath[htmlDefaultPath.length() - 1] == g_fileSeparator) + htmlDefaultPath.erase(htmlDefaultPath.length() - 1); + htmlDefaultPath.append("\\AStyle\\doc"); + if (stat(htmlDefaultPath.c_str(), &statbuf) == 0 && statbuf.st_mode & S_IFDIR) + break; + } + htmlDefaultPath.append("\\"); + + // build file path + string htmlFilePath; + if (filePathIn == NULL) + htmlFilePath = htmlDefaultPath + "astyle.html"; + else + { + if (strpbrk(filePathIn, "\\/") == NULL) + htmlFilePath = htmlDefaultPath + filePathIn; + else + htmlFilePath = filePathIn; + } + standardizePath(htmlFilePath); + if (stat(htmlFilePath.c_str(), &statbuf) != 0 || !(statbuf.st_mode & S_IFREG)) + { + printf(_("Cannot open HTML file %s\n"), htmlFilePath.c_str()); + return; + } + + SHELLEXECUTEINFO sei = { sizeof(sei), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + sei.fMask = SEE_MASK_FLAG_NO_UI; + sei.lpVerb = "open"; + sei.lpFile = htmlFilePath.c_str(); + sei.nShow = SW_SHOWNORMAL; + + // browser open will be bypassed in test programs + printf(_("Opening HTML documentation %s\n"), htmlFilePath.c_str()); + if (!bypassBrowserOpen) + { + int ret = ShellExecuteEx(&sei); + if (!ret) + error(_("Command execute failure"), htmlFilePath.c_str()); + } +} + +#else // Linux specific + +/** + * LINUX function to get the current directory. + * This is done if the fileName does not contain a path. + * It is probably from an editor sending a single file. + * + * @param fileName_ The filename is used only for the error message. + * @return The path of the current directory + */ +string ASConsole::getCurrentDirectory(const string& fileName_) const +{ + char* currdir = getenv("PWD"); + if (currdir == NULL) + error("Cannot find file", fileName_.c_str()); + return string(currdir); +} + +/** + * LINUX function to resolve wildcards and recurse into sub directories. + * The fileName vector is filled with the path and names of files to process. + * + * @param directory The path of the directory to be processed. + * @param wildcard The wildcard to be processed (e.g. *.cpp). + */ +void ASConsole::getFileNames(const string& directory, const string& wildcard) +{ + struct dirent* entry; // entry from readdir() + struct stat statbuf; // entry from stat() + vector subDirectory; // sub directories of this directory + + // errno is defined in and is set for errors in opendir, readdir, or stat + errno = 0; + + DIR* dp = opendir(directory.c_str()); + if (dp == NULL) + error(_("Cannot open directory"), directory.c_str()); + + // save the first fileName entry for this recursion + const unsigned firstEntry = fileName.size(); + + // save files and sub directories + while ((entry = readdir(dp)) != NULL) + { + // get file status + string entryFilepath = directory + g_fileSeparator + entry->d_name; + if (stat(entryFilepath.c_str(), &statbuf) != 0) + { + if (errno == EOVERFLOW) // file over 2 GB is OK + { + errno = 0; + continue; + } + perror("errno message"); + error("Error getting file status in directory", directory.c_str()); + } + // skip hidden or read only + if (entry->d_name[0] == '.' || !(statbuf.st_mode & S_IWUSR)) + continue; + // if a sub directory and recursive, save sub directory + if (S_ISDIR(statbuf.st_mode) && isRecursive) + { + if (isPathExclued(entryFilepath)) + printMsg(_("Exclude %s\n"), entryFilepath.substr(mainDirectoryLength)); + else + subDirectory.push_back(entryFilepath); + continue; + } + + // if a file, save file name + if (S_ISREG(statbuf.st_mode)) + { + // check exclude before wildcmp to avoid "unmatched exclude" error + bool isExcluded = isPathExclued(entryFilepath); + // save file name if wildcard match + if (wildcmp(wildcard.c_str(), entry->d_name)) + { + if (isExcluded) + printMsg(_("Exclude %s\n"), entryFilepath.substr(mainDirectoryLength)); + else + fileName.push_back(entryFilepath); + } + } + } + + if (closedir(dp) != 0) + { + perror("errno message"); + error("Error reading directory", directory.c_str()); + } + + // sort the current entries for fileName + if (firstEntry < fileName.size()) + sort(&fileName[firstEntry], &fileName[fileName.size()]); + + // recurse into sub directories + // if not doing recursive, subDirectory is empty + if (subDirectory.size() > 1) + sort(subDirectory.begin(), subDirectory.end()); + for (unsigned i = 0; i < subDirectory.size(); i++) + { + getFileNames(subDirectory[i], wildcard); + } + + return; +} + +/** + * LINUX function to get locale information and call getNumberFormat. + * This formats positive integers only, no float. + * + * @param num The number to be formatted. + * size_t is for compatibility with the Windows function. + * @return The formatted number. + */ +string ASConsole::getNumberFormat(int num, size_t) const +{ +#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__BORLANDC__) || defined(__GNUC__) + // Compilers that don't support C++ locales should still support this assert. + // The C locale should be set but not the C++. + // This function is not necessary if the C++ locale is set. + // The locale().name() return value is not portable to all compilers. + assert(locale().name() == "C"); +#endif + + // get the locale info + struct lconv* lc; + lc = localeconv(); + + // format the number + return getNumberFormat(num, lc->grouping, lc->thousands_sep); +} + +/** + * LINUX function to format a number according to the current locale. + * This formats positive integers only, no float. + * + * @param num The number to be formatted. + * @param groupingArg The grouping string from the locale. + * @param separator The thousands group separator from the locale. + * @return The formatted number. + */ +string ASConsole::getNumberFormat(int num, const char* groupingArg, const char* separator) const +{ + // convert num to a string + stringstream alphaNum; + alphaNum << num; + string number = alphaNum.str(); + // format the number from right to left + string formattedNum; + size_t ig = 0; // grouping index + int grouping = groupingArg[ig]; + int i = number.length(); + // check for no grouping + if (grouping == 0) + grouping = number.length(); + while (i > 0) + { + // extract a group of numbers + string group; + if (i < grouping) + group = number; + else + group = number.substr(i - grouping); + // update formatted number + formattedNum.insert(0, group); + i -= grouping; + if (i < 0) + i = 0; + if (i > 0) + formattedNum.insert(0, separator); + number.erase(i); + // update grouping + if (groupingArg[ig] != '\0' + && groupingArg[ig + 1] != '\0') + grouping = groupingArg[++ig]; + } + return formattedNum; +} + +/** + * LINUX function to open a HTML file in the default browser. + * Use xdg-open from freedesktop.org cross-desktop compatibility suite xdg-utils. + * see http://portland.freedesktop.org/wiki/ + * This is installed on most modern distributions. + */ +void ASConsole::launchDefaultBrowser(const char* filePathIn /*NULL*/) const +{ + struct stat statbuf; + string htmlDefaultPath = "/usr/share/doc/astyle/html/"; + string htmlDefaultFile = "astyle.html"; + + // build file path + string htmlFilePath; + if (filePathIn == NULL) + htmlFilePath = htmlDefaultPath + htmlDefaultFile; + else + { + if (strpbrk(filePathIn, "\\/") == NULL) + htmlFilePath = htmlDefaultPath + filePathIn; + else + htmlFilePath = filePathIn; + } + standardizePath(htmlFilePath); + if (stat(htmlFilePath.c_str(), &statbuf) != 0 || !(statbuf.st_mode & S_IFREG)) + { + printf(_("Cannot open HTML file %s\n"), htmlFilePath.c_str()); + return; + } + + // get search paths + const char* envPaths = getenv("PATH"); + if (envPaths == NULL) + envPaths = "?"; + size_t envlen = strlen(envPaths); + char* paths = new char[envlen + 1]; + strcpy(paths, envPaths); + // find xdg-open (usually in /usr/bin) + // Mac uses open instead +#ifdef __APPLE__ + const char* FILE_OPEN = "open"; +#else + const char* FILE_OPEN = "xdg-open"; +#endif + string searchPath; + char* searchDir = strtok(paths, ":"); + while (searchDir != NULL) + { + searchPath = searchDir; + if (searchPath.length() > 0 + && searchPath[searchPath.length() - 1] != g_fileSeparator) + searchPath.append(string(1, g_fileSeparator)); + searchPath.append(FILE_OPEN); + if (stat(searchPath.c_str(), &statbuf) == 0 && (statbuf.st_mode & S_IFREG)) + break; + searchDir = strtok(NULL, ":"); + } + delete[] paths; + if (searchDir == NULL) + error(_("Command is not installed"), FILE_OPEN); + + // browser open will be bypassed in test programs + printf(_("Opening HTML documentation %s\n"), htmlFilePath.c_str()); + if (!bypassBrowserOpen) + { + execlp(FILE_OPEN, FILE_OPEN, htmlFilePath.c_str(), NULL); + // execlp will NOT return if successful + error(_("Command execute failure"), FILE_OPEN); + } +} + +#endif // _WIN32 + +// get individual file names from the command-line file path +void ASConsole::getFilePaths(string& filePath) +{ + fileName.clear(); + targetDirectory = string(); + targetFilename = string(); + + // separate directory and file name + size_t separator = filePath.find_last_of(g_fileSeparator); + if (separator == string::npos) + { + // if no directory is present, use the currently active directory + targetDirectory = getCurrentDirectory(filePath); + targetFilename = filePath; + mainDirectoryLength = targetDirectory.length() + 1; // +1 includes trailing separator + } + else + { + targetDirectory = filePath.substr(0, separator); + targetFilename = filePath.substr(separator + 1); + mainDirectoryLength = targetDirectory.length() + 1; // +1 includes trailing separator + } + + if (targetFilename.length() == 0) + { + fprintf(stderr, _("Missing filename in %s\n"), filePath.c_str()); + error(); + } + + // check filename for wildcards + hasWildcard = false; + if (targetFilename.find_first_of("*?") != string::npos) + hasWildcard = true; + + // clear exclude hits vector + for (size_t ix = 0; ix < excludeHitsVector.size(); ix++) + excludeHitsVector[ix] = false; + + // If the filename is not quoted on Linux, bash will replace the + // wildcard instead of passing it to the program. + if (isRecursive && !hasWildcard) + { + fprintf(stderr, "%s\n", _("Recursive option with no wildcard")); +#ifndef _WIN32 + fprintf(stderr, "%s\n", _("Did you intend quote the filename")); +#endif + error(); + } + + // display directory name for wildcard processing + if (hasWildcard) + { + printSeparatingLine(); + printMsg(_("Directory %s\n"), targetDirectory + g_fileSeparator + targetFilename); + } + + // create a vector of paths and file names to process + if (hasWildcard || isRecursive) + getFileNames(targetDirectory, targetFilename); + else + { + // verify a single file is not a directory (needed on Linux) + string entryFilepath = targetDirectory + g_fileSeparator + targetFilename; + struct stat statbuf; + if (stat(entryFilepath.c_str(), &statbuf) == 0 && (statbuf.st_mode & S_IFREG)) + fileName.push_back(entryFilepath); + } + + // check for unprocessed excludes + bool excludeErr = false; + for (size_t ix = 0; ix < excludeHitsVector.size(); ix++) + { + if (excludeHitsVector[ix] == false) + { + excludeErr = true; + if (!ignoreExcludeErrorsDisplay) + { + if (ignoreExcludeErrors) + printMsg(_("Exclude (unmatched) %s\n"), excludeVector[ix]); + else + fprintf(stderr, _("Exclude (unmatched) %s\n"), excludeVector[ix].c_str()); + } + else + { + if (!ignoreExcludeErrors) + fprintf(stderr, _("Exclude (unmatched) %s\n"), excludeVector[ix].c_str()); + } + } + } + + if (excludeErr && !ignoreExcludeErrors) + { + if (hasWildcard && !isRecursive) + fprintf(stderr, "%s\n", _("Did you intend to use --recursive")); + error(); + } + + // check if files were found (probably an input error if not) + if (fileName.empty()) + { + fprintf(stderr, _("No file to process %s\n"), filePath.c_str()); + if (hasWildcard && !isRecursive) + fprintf(stderr, "%s\n", _("Did you intend to use --recursive")); + error(); + } + + if (hasWildcard) + printSeparatingLine(); +} + +bool ASConsole::fileNameVectorIsEmpty() const +{ + return fileNameVector.empty(); +} + +bool ASConsole::isOption(const string& arg, const char* op) +{ + return arg.compare(op) == 0; +} + +bool ASConsole::isOption(const string& arg, const char* a, const char* b) +{ + return (isOption(arg, a) || isOption(arg, b)); +} + +bool ASConsole::isParamOption(const string& arg, const char* option) +{ + bool retVal = arg.compare(0, strlen(option), option) == 0; + // if comparing for short option, 2nd char of arg must be numeric + if (retVal && strlen(option) == 1 && arg.length() > 1) + if (!isdigit((unsigned char)arg[1])) + retVal = false; + return retVal; +} + +// compare a path to the exclude vector +// used for both directories and filenames +// updates the g_excludeHitsVector +// return true if a match +bool ASConsole::isPathExclued(const string& subPath) +{ + bool retVal = false; + + // read the exclude vector checking for a match + for (size_t i = 0; i < excludeVector.size(); i++) + { + string exclude = excludeVector[i]; + + if (subPath.length() < exclude.length()) + continue; + + size_t compareStart = subPath.length() - exclude.length(); + // subPath compare must start with a directory name + if (compareStart > 0) + { + char lastPathChar = subPath[compareStart - 1]; + if (lastPathChar != g_fileSeparator) + continue; + } + + string compare = subPath.substr(compareStart); + if (!g_isCaseSensitive) + { + // make it case insensitive for Windows + for (size_t j = 0; j < compare.length(); j++) + compare[j] = (char)tolower(compare[j]); + for (size_t j = 0; j < exclude.length(); j++) + exclude[j] = (char)tolower(exclude[j]); + } + // compare sub directory to exclude data - must check them all + if (compare == exclude) + { + excludeHitsVector[i] = true; + retVal = true; + break; + } + } + return retVal; +} + +void ASConsole::printHelp() const +{ + cout << endl; + cout << " Artistic Style " << g_version << endl; + cout << " Maintained by: Jim Pattee\n"; + cout << " Original Author: Tal Davidson\n"; + cout << endl; + cout << "Usage:\n"; + cout << "------\n"; + cout << " astyle [OPTIONS] File1 File2 File3 [...]\n"; + cout << endl; + cout << " astyle [OPTIONS] < Original > Beautified\n"; + cout << endl; + cout << " When indenting a specific file, the resulting indented file RETAINS\n"; + cout << " the original file-name. The original pre-indented file is renamed,\n"; + cout << " with a suffix of \'.orig\' added to the original filename.\n"; + cout << endl; + cout << " Wildcards (* and ?) may be used in the filename.\n"; + cout << " A \'recursive\' option can process directories recursively.\n"; + cout << endl; + cout << " By default, astyle is set up to indent with four spaces per indent,\n"; + cout << " a maximal indentation of 40 spaces inside continuous statements,\n"; + cout << " a minimum indentation of eight spaces inside conditional statements,\n"; + cout << " and NO formatting options.\n"; + cout << endl; + cout << "Options:\n"; + cout << "--------\n"; + cout << " This program follows the usual GNU command line syntax.\n"; + cout << " Long options (starting with '--') must be written one at a time.\n"; + cout << " Short options (starting with '-') may be appended together.\n"; + cout << " Thus, -bps4 is the same as -b -p -s4.\n"; + cout << endl; + cout << "Options File:\n"; + cout << "-------------\n"; + cout << " Artistic Style looks for a default options file in the\n"; + cout << " following order:\n"; + cout << " 1. The contents of the ARTISTIC_STYLE_OPTIONS environment\n"; + cout << " variable if it exists.\n"; + cout << " 2. The file called .astylerc in the directory pointed to by the\n"; + cout << " HOME environment variable ( i.e. $HOME/.astylerc ).\n"; + cout << " 3. The file called astylerc in the directory pointed to by the\n"; + cout << " USERPROFILE environment variable (i.e. %USERPROFILE%\\astylerc).\n"; + cout << " If a default options file is found, the options in this file will\n"; + cout << " be parsed BEFORE the command-line options.\n"; + cout << " Long options within the default option file may be written without\n"; + cout << " the preliminary '--'.\n"; + cout << endl; + cout << "Disable Formatting:\n"; + cout << "----------------------\n"; + cout << " Disable Block\n"; + cout << " Blocks of code can be disabled with the comment tags *INDENT-OFF*\n"; + cout << " and *INDENT-ON*. It must be contained in a one-line comment.\n"; + cout << endl; + cout << " Disable Line\n"; + cout << " Padding of operators can be disabled on a single line using the\n"; + cout << " comment tag *NOPAD*. It must be contained in a line-end comment.\n"; + cout << endl; + cout << "Bracket Style Options:\n"; + cout << "----------------------\n"; + cout << " default bracket style\n"; + cout << " If no bracket style is requested, the opening brackets will not be\n"; + cout << " changed and closing brackets will be broken from the preceding line.\n"; + cout << endl; + cout << " --style=allman OR --style=bsd OR --style=break OR -A1\n"; + cout << " Allman style formatting/indenting.\n"; + cout << " Broken brackets.\n"; + cout << endl; + cout << " --style=java OR --style=attach OR -A2\n"; + cout << " Java style formatting/indenting.\n"; + cout << " Attached brackets.\n"; + cout << endl; + cout << " --style=kr OR --style=k&r OR --style=k/r OR -A3\n"; + cout << " Kernighan & Ritchie style formatting/indenting.\n"; + cout << " Linux brackets.\n"; + cout << endl; + cout << " --style=stroustrup OR -A4\n"; + cout << " Stroustrup style formatting/indenting.\n"; + cout << " Stroustrup brackets.\n"; + cout << endl; + cout << " --style=whitesmith OR -A5\n"; + cout << " Whitesmith style formatting/indenting.\n"; + cout << " Broken, indented brackets.\n"; + cout << " Indented class blocks and switch blocks.\n"; + cout << endl; + cout << " --style=vtk OR -A15\n"; + cout << " VTK style formatting/indenting.\n"; + cout << " Broken, indented brackets, except for opening brackets.\n"; + cout << endl; + cout << " --style=banner OR -A6\n"; + cout << " Banner style formatting/indenting.\n"; + cout << " Attached, indented brackets.\n"; + cout << endl; + cout << " --style=gnu OR -A7\n"; + cout << " GNU style formatting/indenting.\n"; + cout << " Broken brackets, indented blocks.\n"; + cout << endl; + cout << " --style=linux OR --style=knf OR -A8\n"; + cout << " Linux style formatting/indenting.\n"; + cout << " Linux brackets, minimum conditional indent is one-half indent.\n"; + cout << endl; + cout << " --style=horstmann OR -A9\n"; + cout << " Horstmann style formatting/indenting.\n"; + cout << " Run-in brackets, indented switches.\n"; + cout << endl; + cout << " --style=1tbs OR --style=otbs OR -A10\n"; + cout << " One True Brace Style formatting/indenting.\n"; + cout << " Linux brackets, add brackets to all conditionals.\n"; + cout << endl; + cout << " --style=google OR -A14\n"; + cout << " Google style formatting/indenting.\n"; + cout << " Attached brackets, indented class modifiers.\n"; + cout << endl; + cout << " --style=pico OR -A11\n"; + cout << " Pico style formatting/indenting.\n"; + cout << " Run-in opening brackets and attached closing brackets.\n"; + cout << " Uses keep one line blocks and keep one line statements.\n"; + cout << endl; + cout << " --style=lisp OR -A12\n"; + cout << " Lisp style formatting/indenting.\n"; + cout << " Attached opening brackets and attached closing brackets.\n"; + cout << " Uses keep one line statements.\n"; + cout << endl; + cout << "Tab Options:\n"; + cout << "------------\n"; + cout << " default indent option\n"; + cout << " If no indentation option is set, the default\n"; + cout << " option of 4 spaces per indent will be used.\n"; + cout << endl; + cout << " --indent=spaces=# OR -s#\n"; + cout << " Indent using # spaces per indent. Not specifying #\n"; + cout << " will result in a default of 4 spaces per indent.\n"; + cout << endl; + cout << " --indent=tab OR --indent=tab=# OR -t OR -t#\n"; + cout << " Indent using tab characters, assuming that each\n"; + cout << " indent is # spaces long. Not specifying # will result\n"; + cout << " in a default assumption of 4 spaces per indent.\n"; + cout << endl; + cout << " --indent=force-tab=# OR -T#\n"; + cout << " Indent using tab characters, assuming that each\n"; + cout << " indent is # spaces long. Force tabs to be used in areas\n"; + cout << " AStyle would prefer to use spaces.\n"; + cout << endl; + cout << " --indent=force-tab-x=# OR -xT#\n"; + cout << " Allows the tab length to be set to a length that is different\n"; + cout << " from the indent length. This may cause the indentation to be\n"; + cout << " a mix of both spaces and tabs. This option sets the tab length.\n"; + cout << endl; + cout << "Bracket Modify Options:\n"; + cout << "-----------------------\n"; + cout << " --attach-namespaces OR -xn\n"; + cout << " Attach brackets to a namespace statement.\n"; + cout << endl; + cout << " --attach-classes OR -xc\n"; + cout << " Attach brackets to a class statement.\n"; + cout << endl; + cout << " --attach-inlines OR -xl\n"; + cout << " Attach brackets to class inline function definitions.\n"; + cout << endl; + cout << " --attach-extern-c OR -xk\n"; + cout << " Attach brackets to an extern \"C\" statement.\n"; + cout << endl; + cout << "Indentation Options:\n"; + cout << "--------------------\n"; + cout << " --indent-classes OR -C\n"; + cout << " Indent 'class' blocks so that the entire block is indented.\n"; + cout << endl; + cout << " --indent-modifiers OR -xG\n"; + cout << " Indent 'class' access modifiers, 'public:', 'protected:' or\n"; + cout << " 'private:', one half indent. The rest of the class is not\n"; + cout << " indented. \n"; + cout << endl; + cout << " --indent-switches OR -S\n"; + cout << " Indent 'switch' blocks, so that the inner 'case XXX:'\n"; + cout << " headers are indented in relation to the switch block.\n"; + cout << endl; + cout << " --indent-cases OR -K\n"; + cout << " Indent case blocks from the 'case XXX:' headers.\n"; + cout << " Case statements not enclosed in blocks are NOT indented.\n"; + cout << endl; + cout << " --indent-namespaces OR -N\n"; + cout << " Indent the contents of namespace blocks.\n"; + cout << endl; + cout << " --indent-labels OR -L\n"; + cout << " Indent labels so that they appear one indent less than\n"; + cout << " the current indentation level, rather than being\n"; + cout << " flushed completely to the left (which is the default).\n"; + cout << endl; + cout << " --indent-preproc-block OR -xW\n"; + cout << " Indent preprocessor blocks at bracket level 0.\n"; + cout << " Without this option the preprocessor block is not indented.\n"; + cout << endl; + cout << " --indent-preproc-cond OR -xw\n"; + cout << " Indent preprocessor conditional statements #if/#else/#endif\n"; + cout << " to the same level as the source code.\n"; + cout << endl; + cout << " --indent-preproc-define OR -w\n"; + cout << " Indent multi-line preprocessor #define statements.\n"; + cout << endl; + cout << " --indent-col1-comments OR -Y\n"; + cout << " Indent line comments that start in column one.\n"; + cout << endl; + cout << " --min-conditional-indent=# OR -m#\n"; + cout << " Indent a minimal # spaces in a continuous conditional\n"; + cout << " belonging to a conditional header.\n"; + cout << " The valid values are:\n"; + cout << " 0 - no minimal indent.\n"; + cout << " 1 - indent at least one additional indent.\n"; + cout << " 2 - indent at least two additional indents.\n"; + cout << " 3 - indent at least one-half an additional indent.\n"; + cout << " The default value is 2, two additional indents.\n"; + cout << endl; + cout << " --max-instatement-indent=# OR -M#\n"; + cout << " Indent a maximal # spaces in a continuous statement,\n"; + cout << " relative to the previous line.\n"; + cout << " The valid values are 40 thru 120.\n"; + cout << " The default value is 40.\n"; + cout << endl; + cout << "Padding Options:\n"; + cout << "----------------\n"; + cout << " --break-blocks OR -f\n"; + cout << " Insert empty lines around unrelated blocks, labels, classes, ...\n"; + cout << endl; + cout << " --break-blocks=all OR -F\n"; + cout << " Like --break-blocks, except also insert empty lines \n"; + cout << " around closing headers (e.g. 'else', 'catch', ...).\n"; + cout << endl; + cout << " --pad-oper OR -p\n"; + cout << " Insert space padding around operators.\n"; + cout << endl; + cout << " --pad-comma OR -xg\n"; + cout << " Insert space padding around commas and semicolons.\n"; + cout << endl; + cout << " --pad-paren OR -P\n"; + cout << " Insert space padding around parenthesis on both the outside\n"; + cout << " and the inside.\n"; + cout << endl; + cout << " --pad-paren-out OR -d\n"; + cout << " Insert space padding around parenthesis on the outside only.\n"; + cout << endl; + cout << " --pad-first-paren-out OR -xd\n"; + cout << " Insert space padding around first parenthesis in a series on\n"; + cout << " the outside only.\n"; + cout << endl; + cout << " --pad-paren-in OR -D\n"; + cout << " Insert space padding around parenthesis on the inside only.\n"; + cout << endl; + cout << " --pad-header OR -H\n"; + cout << " Insert space padding after paren headers (e.g. 'if', 'for'...).\n"; + cout << endl; + cout << " --unpad-paren OR -U\n"; + cout << " Remove unnecessary space padding around parenthesis. This\n"; + cout << " can be used in combination with the 'pad' options above.\n"; + cout << endl; + cout << " --delete-empty-lines OR -xd\n"; + cout << " Delete empty lines within a function or method.\n"; + cout << " It will NOT delete lines added by the break-blocks options.\n"; + cout << endl; + cout << " --fill-empty-lines OR -E\n"; + cout << " Fill empty lines with the white space of their\n"; + cout << " previous lines.\n"; + cout << endl; + cout << " --align-pointer=type OR -k1\n"; + cout << " --align-pointer=middle OR -k2\n"; + cout << " --align-pointer=name OR -k3\n"; + cout << " Attach a pointer or reference operator (*, &, or ^) to either\n"; + cout << " the operator type (left), middle, or operator name (right).\n"; + cout << " To align the reference separately use --align-reference.\n"; + cout << endl; + cout << " --align-reference=none OR -W0\n"; + cout << " --align-reference=type OR -W1\n"; + cout << " --align-reference=middle OR -W2\n"; + cout << " --align-reference=name OR -W3\n"; + cout << " Attach a reference operator (&) to either\n"; + cout << " the operator type (left), middle, or operator name (right).\n"; + cout << " If not set, follow pointer alignment.\n"; + cout << endl; + cout << "Formatting Options:\n"; + cout << "-------------------\n"; + cout << " --break-closing-brackets OR -y\n"; + cout << " Break brackets before closing headers (e.g. 'else', 'catch', ...).\n"; + cout << " Use with --style=java, --style=kr, --style=stroustrup,\n"; + cout << " --style=linux, or --style=1tbs.\n"; + cout << endl; + cout << " --break-elseifs OR -e\n"; + cout << " Break 'else if()' statements into two different lines.\n"; + cout << endl; + cout << " --add-brackets OR -j\n"; + cout << " Add brackets to unbracketed one line conditional statements.\n"; + cout << endl; + cout << " --add-one-line-brackets OR -J\n"; + cout << " Add one line brackets to unbracketed one line conditional\n"; + cout << " statements.\n"; + cout << endl; + cout << " --remove-brackets OR -xj\n"; + cout << " Remove brackets from a bracketed one line conditional statements.\n"; + cout << endl; + cout << " --keep-one-line-blocks OR -O\n"; + cout << " Don't break blocks residing completely on one line.\n"; + cout << endl; + cout << " --keep-one-line-statements OR -o\n"; + cout << " Don't break lines containing multiple statements into\n"; + cout << " multiple single-statement lines.\n"; + cout << endl; + cout << " --convert-tabs OR -c\n"; + cout << " Convert tabs to the appropriate number of spaces.\n"; + cout << endl; + cout << " --close-templates OR -xy\n"; + cout << " Close ending angle brackets on template definitions.\n"; + cout << endl; + cout << " --remove-comment-prefix OR -xp\n"; + cout << " Remove the leading '*' prefix on multi-line comments and\n"; + cout << " indent the comment text one indent.\n"; + cout << endl; + cout << " --max-code-length=# OR -xC#\n"; + cout << " --break-after-logical OR -xL\n"; + cout << " max-code-length=# will break the line if it exceeds more than\n"; + cout << " # characters. The valid values are 50 thru 200.\n"; + cout << " If the line contains logical conditionals they will be placed\n"; + cout << " first on the new line. The option break-after-logical will\n"; + cout << " cause the logical conditional to be placed last on the\n"; + cout << " previous line.\n"; + cout << endl; + cout << " --mode=c\n"; + cout << " Indent a C or C++ source file (this is the default).\n"; + cout << endl; + cout << " --mode=java\n"; + cout << " Indent a Java source file.\n"; + cout << endl; + cout << " --mode=cs\n"; + cout << " Indent a C# source file.\n"; + cout << endl; + cout << "Objective-C Options:\n"; + cout << "--------------------\n"; + cout << " --pad-method-prefix OR -xQ\n"; + cout << " Insert space padding after the '-' or '+' Objective-C\n"; + cout << " method prefix.\n"; + cout << endl; + cout << " --unpad-method-prefix OR -xR\n"; + cout << " Remove all space padding after the '-' or '+' Objective-C\n"; + cout << " method prefix.\n"; + cout << endl; + cout << " --pad-return-type OR -xq\n"; + cout << " Insert space padding after the Objective-C return type.\n"; + cout << endl; + cout << " --unpad-return-type OR -xr\n"; + cout << " Remove all space padding after the Objective-C return type.\n"; + cout << endl; + cout << " --align-method-colon OR -xM\n"; + cout << " Align the colons in an Objective-C method definition.\n"; + cout << endl; + cout << " --pad-method-colon=none OR -xP\n"; + cout << " --pad-method-colon=all OR -xP1\n"; + cout << " --pad-method-colon=after OR -xP2\n"; + cout << " --pad-method-colon=before OR -xP3\n"; + cout << " Add or remove space padding before or after the colons in an\n"; + cout << " Objective-C method call.\n"; + cout << endl; + cout << "Other Options:\n"; + cout << "--------------\n"; + cout << " --suffix=####\n"; + cout << " Append the suffix #### instead of '.orig' to original filename.\n"; + cout << endl; + cout << " --suffix=none OR -n\n"; + cout << " Do not retain a backup of the original file.\n"; + cout << endl; + cout << " --recursive OR -r OR -R\n"; + cout << " Process subdirectories recursively.\n"; + cout << endl; + cout << " --dry-run\n"; + cout << " Perform a trial run with no changes made to check for formatting.\n"; + cout << endl; + cout << " --exclude=####\n"; + cout << " Specify a file or directory #### to be excluded from processing.\n"; + cout << endl; + cout << " --ignore-exclude-errors OR -i\n"; + cout << " Allow processing to continue if there are errors in the exclude=####\n"; + cout << " options. It will display the unmatched excludes.\n"; + cout << endl; + cout << " --ignore-exclude-errors-x OR -xi\n"; + cout << " Allow processing to continue if there are errors in the exclude=####\n"; + cout << " options. It will NOT display the unmatched excludes.\n"; + cout << endl; + cout << " --errors-to-stdout OR -X\n"; + cout << " Print errors and help information to standard-output rather than\n"; + cout << " to standard-error.\n"; + cout << endl; + cout << " --preserve-date OR -Z\n"; + cout << " Preserve the original file's date and time modified. The time\n"; + cout << " modified will be changed a few micro seconds to force a compile.\n"; + cout << endl; + cout << " --verbose OR -v\n"; + cout << " Verbose mode. Extra informational messages will be displayed.\n"; + cout << endl; + cout << " --formatted OR -Q\n"; + cout << " Formatted display mode. Display only the files that have been\n"; + cout << " formatted.\n"; + cout << endl; + cout << " --quiet OR -q\n"; + cout << " Quiet mode. Suppress all output except error messages.\n"; + cout << endl; + cout << " --lineend=windows OR -z1\n"; + cout << " --lineend=linux OR -z2\n"; + cout << " --lineend=macold OR -z3\n"; + cout << " Force use of the specified line end style. Valid options\n"; + cout << " are windows (CRLF), linux (LF), and macold (CR).\n"; + cout << endl; + cout << "Command Line Only:\n"; + cout << "------------------\n"; + cout << " --options=####\n"; + cout << " Specify an options file #### to read and use.\n"; + cout << endl; + cout << " --options=none\n"; + cout << " Disable the default options file.\n"; + cout << " Only the command-line parameters will be used.\n"; + cout << endl; + cout << " --ascii OR -I\n"; + cout << " The displayed output will be ascii characters only.\n"; + cout << endl; + cout << " --version OR -V\n"; + cout << " Print version number.\n"; + cout << endl; + cout << " --help OR -h OR -?\n"; + cout << " Print this help message.\n"; + cout << endl; + cout << " --html OR -!\n"; + cout << " Open the HTML help file \"astyle.html\" in the default browser.\n"; + cout << " The documentation must be installed in the standard install path.\n"; + cout << endl; + cout << " --html=####\n"; + cout << " Open a HTML help file in the default browser using the file path\n"; + cout << " ####. The path may include a directory path and a file name, or a\n"; + cout << " file name only. Paths containing spaces must be enclosed in quotes.\n"; + cout << endl; + cout << endl; +} + +/** + * Process files in the fileNameVector. + */ +void ASConsole::processFiles() +{ + if (isVerbose) + printVerboseHeader(); + + clock_t startTime = clock(); // start time of file formatting + + // loop thru input fileNameVector and process the files + for (size_t i = 0; i < fileNameVector.size(); i++) + { + getFilePaths(fileNameVector[i]); + + // loop thru fileName vector formatting the files + for (size_t j = 0; j < fileName.size(); j++) + formatFile(fileName[j]); + } + + // files are processed, display stats + if (isVerbose) + printVerboseStats(startTime); +} + +// process options from the command line and options file +// build the vectors fileNameVector, excludeVector, optionsVector, and fileOptionsVector +void ASConsole::processOptions(vector& argvOptions) +{ + string arg; + bool ok = true; + bool shouldParseOptionsFile = true; + + // get command line options + for (size_t i = 0; i < argvOptions.size(); i++) + { + arg = argvOptions[i]; + + if ( isOption(arg, "-I" ) + || isOption(arg, "--ascii") ) + { + useAscii = true; + setlocale(LC_ALL, "C"); // use English decimal indicator + localizer.setLanguageFromName("en"); + } + else if ( isOption(arg, "--options=none") ) + { + shouldParseOptionsFile = false; + } + else if ( isParamOption(arg, "--options=") ) + { + optionsFileName = getParam(arg, "--options="); + optionsFileRequired = true; + if (optionsFileName.compare("") == 0) + setOptionsFileName(" "); + } + else if ( isOption(arg, "-h") + || isOption(arg, "--help") + || isOption(arg, "-?") ) + { + printHelp(); + exit(EXIT_SUCCESS); + } + else if ( isOption(arg, "-!") + || isOption(arg, "--html") ) + { + launchDefaultBrowser(); + exit(EXIT_SUCCESS); + } + else if ( isParamOption(arg, "--html=") ) + { + string htmlFilePath = getParam(arg, "--html="); + launchDefaultBrowser(htmlFilePath.c_str()); + exit(EXIT_SUCCESS); + } + else if ( isOption(arg, "-V" ) + || isOption(arg, "--version") ) + { + printf("Artistic Style Version %s\n", g_version); + exit(EXIT_SUCCESS); + } + else if (arg[0] == '-') + { + optionsVector.push_back(arg); + } + else // file-name + { + standardizePath(arg); + fileNameVector.push_back(arg); + } + } + + // get options file path and name + if (shouldParseOptionsFile) + { + if (optionsFileName.compare("") == 0) + { + char* env = getenv("ARTISTIC_STYLE_OPTIONS"); + if (env != NULL) + setOptionsFileName(env); + } + if (optionsFileName.compare("") == 0) + { + char* env = getenv("HOME"); + if (env != NULL) + setOptionsFileName(string(env) + "/.astylerc"); + } + if (optionsFileName.compare("") == 0) + { + char* env = getenv("USERPROFILE"); + if (env != NULL) + setOptionsFileName(string(env) + "/astylerc"); + } + if (optionsFileName.compare("") != 0) + standardizePath(optionsFileName); + } + + // create the options file vector and parse the options for errors + ASOptions options(formatter); + if (optionsFileName.compare("") != 0) + { + ifstream optionsIn(optionsFileName.c_str()); + if (optionsIn) + { + options.importOptions(optionsIn, fileOptionsVector); + ok = options.parseOptions(fileOptionsVector, + string(_("Invalid option file options:"))); + } + else + { + if (optionsFileRequired) + error(_("Cannot open options file"), optionsFileName.c_str()); + optionsFileName.clear(); + } + optionsIn.close(); + } + if (!ok) + { + (*_err) << options.getOptionErrors() << endl; + (*_err) << _("For help on options type 'astyle -h'") << endl; + error(); + } + + // parse the command line options vector for errors + ok = options.parseOptions(optionsVector, + string(_("Invalid command line options:"))); + if (!ok) + { + (*_err) << options.getOptionErrors() << endl; + (*_err) << _("For help on options type 'astyle -h'") << endl; + error(); + } +} + +// remove a file and check for an error +void ASConsole::removeFile(const char* fileName_, const char* errMsg) const +{ + if (remove(fileName_)) + { + if (errno == ENOENT) // no file is OK + errno = 0; + if (errno) + { + perror("errno message"); + error(errMsg, fileName_); + } + } +} + +// rename a file and check for an error +void ASConsole::renameFile(const char* oldFileName, const char* newFileName, const char* errMsg) const +{ + int result = rename(oldFileName, newFileName); + if (result != 0) + { + // if file still exists the remove needs more time - retry + if (errno == EEXIST) + { + errno = 0; + waitForRemove(newFileName); + result = rename(oldFileName, newFileName); + } + if (result != 0) + { + perror("errno message"); + error(errMsg, oldFileName); + } + } +} + +// make sure file separators are correct type (Windows or Linux) +// remove ending file separator +// remove beginning file separator if requested and NOT a complete file path +void ASConsole::standardizePath(string& path, bool removeBeginningSeparator /*false*/) const +{ +#ifdef __VMS + struct FAB fab; + struct NAML naml; + char less[NAML$C_MAXRSS]; + char sess[NAM$C_MAXRSS]; + int r0_status; + + // If we are on a VMS system, translate VMS style filenames to unix + // style. + fab = cc$rms_fab; + fab.fab$l_fna = (char*) - 1; + fab.fab$b_fns = 0; + fab.fab$l_naml = &naml; + naml = cc$rms_naml; + strcpy(sess, path.c_str()); + naml.naml$l_long_filename = (char*)sess; + naml.naml$l_long_filename_size = path.length(); + naml.naml$l_long_expand = less; + naml.naml$l_long_expand_alloc = sizeof(less); + naml.naml$l_esa = sess; + naml.naml$b_ess = sizeof(sess); + naml.naml$v_no_short_upcase = 1; + r0_status = sys$parse(&fab); + if (r0_status == RMS$_SYN) + { + error("File syntax error", path.c_str()); + } + else + { + if (!$VMS_STATUS_SUCCESS(r0_status)) + { + (void)lib$signal (r0_status); + } + } + less[naml.naml$l_long_expand_size - naml.naml$b_ver] = '\0'; + sess[naml.naml$b_esl - naml.naml$b_ver] = '\0'; + if (naml.naml$l_long_expand_size > naml.naml$b_esl) + { + path = decc$translate_vms (less); + } + else + { + path = decc$translate_vms(sess); + } +#endif /* __VMS */ + + // make sure separators are correct type (Windows or Linux) + for (size_t i = 0; i < path.length(); i++) + { + i = path.find_first_of("/\\", i); + if (i == string::npos) + break; + path[i] = g_fileSeparator; + } + // remove beginning separator if requested + if (removeBeginningSeparator && (path[0] == g_fileSeparator)) + path.erase(0, 1); +} + +void ASConsole::printMsg(const char* msg, const string& data) const +{ + if (isQuiet) + return; + printf(msg, data.c_str()); +} + +void ASConsole::printSeparatingLine() const +{ + string line; + for (size_t i = 0; i < 60; i++) + line.append("-"); + printMsg("%s\n", line); +} + +void ASConsole::printVerboseHeader() const +{ + assert(isVerbose); + if (isQuiet) + return; + // get the date + struct tm* ptr; + time_t lt; + char str[20]; + lt = time(NULL); + ptr = localtime(<); + strftime(str, 20, "%x", ptr); + // print the header + printf("Artistic Style %s %s\n", g_version, str); + // print options file + if (!optionsFileName.empty()) + printf(_("Using default options file %s\n"), optionsFileName.c_str()); +} + +void ASConsole::printVerboseStats(clock_t startTime) const +{ + assert(isVerbose); + if (isQuiet) + return; + if (hasWildcard) + printSeparatingLine(); + string formatted = getNumberFormat(filesFormatted); + string unchanged = getNumberFormat(filesUnchanged); + printf(_(" %s formatted %s unchanged "), formatted.c_str(), unchanged.c_str()); + + // show processing time + clock_t stopTime = clock(); + float secs = (stopTime - startTime) / float (CLOCKS_PER_SEC); + if (secs < 60) + { + if (secs < 2.0) + printf("%.2f", secs); + else if (secs < 20.0) + printf("%.1f", secs); + else + printf("%.0f", secs); + printf("%s", _(" seconds ")); + } + else + { + // show minutes and seconds if time is greater than one minute + int min = (int) secs / 60; + secs -= min * 60; + int minsec = int (secs + .5); + printf(_("%d min %d sec "), min, minsec); + } + + string lines = getNumberFormat(linesOut); + printf(_("%s lines\n"), lines.c_str()); +} + +void ASConsole::sleep(int seconds) const +{ + clock_t endwait; + endwait = clock_t (clock () + seconds * CLOCKS_PER_SEC); + while (clock() < endwait) {} +} + +bool ASConsole::stringEndsWith(const string& str, const string& suffix) const +{ + int strIndex = (int) str.length() - 1; + int suffixIndex = (int) suffix.length() - 1; + + while (strIndex >= 0 && suffixIndex >= 0) + { + if (tolower(str[strIndex]) != tolower(suffix[suffixIndex])) + return false; + + --strIndex; + --suffixIndex; + } + // suffix longer than string + if (strIndex < 0 && suffixIndex >= 0) + return false; + return true; +} + +void ASConsole::updateExcludeVector(string suffixParam) +{ + excludeVector.push_back(suffixParam); + standardizePath(excludeVector.back(), true); + excludeHitsVector.push_back(false); +} + +int ASConsole::waitForRemove(const char* newFileName) const +{ + struct stat stBuf; + int seconds; + // sleep a max of 20 seconds for the remove + for (seconds = 1; seconds <= 20; seconds++) + { + sleep(1); + if (stat(newFileName, &stBuf) != 0) + break; + } + errno = 0; + return seconds; +} + +// From The Code Project http://www.codeproject.com/string/wildcmp.asp +// Written by Jack Handy - jakkhandy@hotmail.com +// Modified to compare case insensitive for Windows +int ASConsole::wildcmp(const char* wild, const char* data) const +{ + const char* cp = NULL, *mp = NULL; + bool cmpval; + + while ((*data) && (*wild != '*')) + { + if (!g_isCaseSensitive) + cmpval = (tolower(*wild) != tolower(*data)) && (*wild != '?'); + else + cmpval = (*wild != *data) && (*wild != '?'); + + if (cmpval) + { + return 0; + } + wild++; + data++; + } + + while (*data) + { + if (*wild == '*') + { + if (!*++wild) + { + return 1; + } + mp = wild; + cp = data + 1; + } + else + { + if (!g_isCaseSensitive) + cmpval = (tolower(*wild) == tolower(*data) || (*wild == '?')); + else + cmpval = (*wild == *data) || (*wild == '?'); + + if (cmpval) + { + wild++; + data++; + } + else + { + wild = mp; + data = cp++; + } + } + } + + while (*wild == '*') + { + wild++; + } + return !*wild; +} + +void ASConsole::writeFile(const string& fileName_, FileEncoding encoding, ostringstream& out) const +{ + // save date accessed and date modified of original file + struct stat stBuf; + bool statErr = false; + if (stat(fileName_.c_str(), &stBuf) == -1) + statErr = true; + + // create a backup + if (!noBackup) + { + string origFileName = fileName_ + origSuffix; + removeFile(origFileName.c_str(), "Cannot remove pre-existing backup file"); + renameFile(fileName_.c_str(), origFileName.c_str(), "Cannot create backup file"); + } + + // write the output file + ofstream fout(fileName_.c_str(), ios::binary | ios::trunc); + if (!fout) + error("Cannot open output file", fileName_.c_str()); + if (encoding == UTF_16LE || encoding == UTF_16BE) + { + // convert utf-8 to utf-16 + bool isBigEndian = (encoding == UTF_16BE); + size_t utf16Size = utf8_16.Utf16LengthFromUtf8(out.str().c_str(), out.str().length()); + char* utf16Out = new char[utf16Size]; + size_t utf16Len = utf8_16.Utf8ToUtf16(const_cast(out.str().c_str()), + out.str().length(), isBigEndian, utf16Out); + assert(utf16Len == utf16Size); + fout << string(utf16Out, utf16Len); + delete [] utf16Out; + } + else + fout << out.str(); + + fout.close(); + + // change date modified to original file date + // Embarcadero must be linked with cw32mt not cw32 + if (preserveDate) + { + if (!statErr) + { + struct utimbuf outBuf; + outBuf.actime = stBuf.st_atime; + // add ticks so 'make' will recognize a change + // Visual Studio 2008 needs more than 1 + outBuf.modtime = stBuf.st_mtime + 10; + if (utime(fileName_.c_str(), &outBuf) == -1) + statErr = true; + } + if (statErr) + { + perror("errno message"); + (*_err) << "********* Cannot preserve file date" << endl; + } + } +} + +//----------------------------------------------------------------------------- +// ASLibrary class +// used by shared object (DLL) calls +//----------------------------------------------------------------------------- + +#else // ASTYLE_LIB + +utf16_t* ASLibrary::formatUtf16(const utf16_t* pSourceIn, // the source to be formatted + const utf16_t* pOptions, // AStyle options + fpError fpErrorHandler, // error handler function + fpAlloc fpMemoryAlloc) const // memory allocation function) +{ + const char* utf8In = convertUtf16ToUtf8(pSourceIn); + if (utf8In == NULL) + { + fpErrorHandler(121, "Cannot convert input utf-16 to utf-8."); + return NULL; + } + const char* utf8Options = convertUtf16ToUtf8(pOptions); + if (utf8Options == NULL) + { + delete [] utf8In; + fpErrorHandler(122, "Cannot convert options utf-16 to utf-8."); + return NULL; + } + // call the Artistic Style formatting function + // cannot use the callers memory allocation here + char* utf8Out = AStyleMain(utf8In, + utf8Options, + fpErrorHandler, + ASLibrary::tempMemoryAllocation); + // finished with these + delete [] utf8In; + delete [] utf8Options; + utf8In = NULL; + utf8Options = NULL; + // AStyle error has already been sent + if (utf8Out == NULL) + return NULL; + // convert text to wide char and return it + utf16_t* utf16Out = convertUtf8ToUtf16(utf8Out, fpMemoryAlloc); + delete [] utf8Out; + utf8Out = NULL; + if (utf16Out == NULL) + { + fpErrorHandler(123, "Cannot convert output utf-8 to utf-16."); + return NULL; + } + return utf16Out; +} + +// STATIC method to allocate temporary memory for AStyle formatting. +// The data will be converted before being returned to the calling program. +char* STDCALL ASLibrary::tempMemoryAllocation(unsigned long memoryNeeded) +{ + char* buffer = new(nothrow) char[memoryNeeded]; + return buffer; +} + +/** + * Convert utf-8 strings to utf16 strings. + * Memory is allocated by the calling program memory allocation function. + * The calling function must check for errors. + */ +utf16_t* ASLibrary::convertUtf8ToUtf16(const char* utf8In, fpAlloc fpMemoryAlloc) const +{ + if (utf8In == NULL) + return NULL; + char* data = const_cast(utf8In); + size_t dataSize = strlen(utf8In); + bool isBigEndian = utf8_16.getBigEndian(); + // return size is in number of CHARs, not utf16_t + size_t utf16Size = (utf8_16.Utf16LengthFromUtf8(data, dataSize) + sizeof(utf16_t)); + char* utf16Out = fpMemoryAlloc(utf16Size); + if (utf16Out == NULL) + return NULL; +#ifdef NDEBUG + utf8_16.Utf8ToUtf16(data, dataSize + 1, isBigEndian, utf16Out); +#else + size_t utf16Len = utf8_16.Utf8ToUtf16(data, dataSize + 1, isBigEndian, utf16Out); + assert(utf16Len == utf16Size); +#endif + assert(utf16Size == (utf8_16.utf16len(reinterpret_cast(utf16Out)) + 1) * sizeof(utf16_t)); + return reinterpret_cast(utf16Out); +} + +/** + * Convert utf16 strings to utf-8. + * The calling function must check for errors and delete the + * allocated memory. + */ +char* ASLibrary::convertUtf16ToUtf8(const utf16_t* utf16In) const +{ + if (utf16In == NULL) + return NULL; + char* data = reinterpret_cast(const_cast(utf16In)); + // size must be in chars + size_t dataSize = utf8_16.utf16len(utf16In) * sizeof(utf16_t); + bool isBigEndian = utf8_16.getBigEndian(); + size_t utf8Size = utf8_16.Utf8LengthFromUtf16(data, dataSize, isBigEndian) + 1; + char* utf8Out = new(nothrow) char[utf8Size]; + if (utf8Out == NULL) + return NULL; +#ifdef NDEBUG + utf8_16.Utf16ToUtf8(data, dataSize + 1, isBigEndian, true, utf8Out); +#else + size_t utf8Len = utf8_16.Utf16ToUtf8(data, dataSize + 1, isBigEndian, true, utf8Out); + assert(utf8Len == utf8Size); +#endif + assert(utf8Size == strlen(utf8Out) + 1); + return utf8Out; +} + +#endif // ASTYLE_LIB + +//----------------------------------------------------------------------------- +// ASOptions class +// used by both console and library builds +//----------------------------------------------------------------------------- + +/** + * parse the options vector + * optionsVector can be either a fileOptionsVector (options file) or an optionsVector (command line) + * + * @return true if no errors, false if errors + */ +bool ASOptions::parseOptions(vector& optionsVector, const string& errorInfo) +{ + vector::iterator option; + string arg, subArg; + optionErrors.clear(); + + for (option = optionsVector.begin(); option != optionsVector.end(); ++option) + { + arg = *option; + + if (arg.compare(0, 2, "--") == 0) + parseOption(arg.substr(2), errorInfo); + else if (arg[0] == '-') + { + size_t i; + + for (i = 1; i < arg.length(); ++i) + { + if (i > 1 + && isalpha((unsigned char)arg[i]) + && arg[i - 1] != 'x') + { + // parse the previous option in subArg + parseOption(subArg, errorInfo); + subArg = ""; + } + // append the current option to subArg + subArg.append(1, arg[i]); + } + // parse the last option + parseOption(subArg, errorInfo); + subArg = ""; + } + else + { + parseOption(arg, errorInfo); + subArg = ""; + } + } + if (optionErrors.str().length() > 0) + return false; + return true; +} + +void ASOptions::parseOption(const string& arg, const string& errorInfo) +{ + if ( isOption(arg, "style=allman") || isOption(arg, "style=bsd") || isOption(arg, "style=break") ) + { + formatter.setFormattingStyle(STYLE_ALLMAN); + } + else if ( isOption(arg, "style=java") || isOption(arg, "style=attach") ) + { + formatter.setFormattingStyle(STYLE_JAVA); + } + else if ( isOption(arg, "style=k&r") || isOption(arg, "style=kr") || isOption(arg, "style=k/r") ) + { + formatter.setFormattingStyle(STYLE_KR); + } + else if ( isOption(arg, "style=stroustrup") ) + { + formatter.setFormattingStyle(STYLE_STROUSTRUP); + } + else if ( isOption(arg, "style=whitesmith") ) + { + formatter.setFormattingStyle(STYLE_WHITESMITH); + } + else if ( isOption(arg, "style=vtk") ) + { + formatter.setFormattingStyle(STYLE_VTK); + } + else if ( isOption(arg, "style=banner") ) + { + formatter.setFormattingStyle(STYLE_BANNER); + } + else if ( isOption(arg, "style=gnu") ) + { + formatter.setFormattingStyle(STYLE_GNU); + } + else if ( isOption(arg, "style=linux") || isOption(arg, "style=knf") ) + { + formatter.setFormattingStyle(STYLE_LINUX); + } + else if ( isOption(arg, "style=horstmann") ) + { + formatter.setFormattingStyle(STYLE_HORSTMANN); + } + else if ( isOption(arg, "style=1tbs") || isOption(arg, "style=otbs") ) + { + formatter.setFormattingStyle(STYLE_1TBS); + } + else if ( isOption(arg, "style=google") ) + { + formatter.setFormattingStyle(STYLE_GOOGLE); + } + else if ( isOption(arg, "style=pico") ) + { + formatter.setFormattingStyle(STYLE_PICO); + } + else if ( isOption(arg, "style=lisp") || isOption(arg, "style=python") ) + { + formatter.setFormattingStyle(STYLE_LISP); + } + else if ( isParamOption(arg, "A") ) + { + int style = 0; + string styleParam = getParam(arg, "A"); + if (styleParam.length() > 0) + style = atoi(styleParam.c_str()); + if (style == 1) + formatter.setFormattingStyle(STYLE_ALLMAN); + else if (style == 2) + formatter.setFormattingStyle(STYLE_JAVA); + else if (style == 3) + formatter.setFormattingStyle(STYLE_KR); + else if (style == 4) + formatter.setFormattingStyle(STYLE_STROUSTRUP); + else if (style == 5) + formatter.setFormattingStyle(STYLE_WHITESMITH); + else if (style == 6) + formatter.setFormattingStyle(STYLE_BANNER); + else if (style == 7) + formatter.setFormattingStyle(STYLE_GNU); + else if (style == 8) + formatter.setFormattingStyle(STYLE_LINUX); + else if (style == 9) + formatter.setFormattingStyle(STYLE_HORSTMANN); + else if (style == 10) + formatter.setFormattingStyle(STYLE_1TBS); + else if (style == 11) + formatter.setFormattingStyle(STYLE_PICO); + else if (style == 12) + formatter.setFormattingStyle(STYLE_LISP); + else if (style == 14) + formatter.setFormattingStyle(STYLE_GOOGLE); + else if (style == 15) + formatter.setFormattingStyle(STYLE_VTK); + else + isOptionError(arg, errorInfo); + } + // must check for mode=cs before mode=c !!! + else if ( isOption(arg, "mode=cs") ) + { + formatter.setSharpStyle(); + formatter.setModeManuallySet(true); + } + else if ( isOption(arg, "mode=c") ) + { + formatter.setCStyle(); + formatter.setModeManuallySet(true); + } + else if ( isOption(arg, "mode=java") ) + { + formatter.setJavaStyle(); + formatter.setModeManuallySet(true); + } + else if ( isParamOption(arg, "t", "indent=tab=") ) + { + int spaceNum = 4; + string spaceNumParam = getParam(arg, "t", "indent=tab="); + if (spaceNumParam.length() > 0) + spaceNum = atoi(spaceNumParam.c_str()); + if (spaceNum < 2 || spaceNum > 20) + isOptionError(arg, errorInfo); + else + { + formatter.setTabIndentation(spaceNum, false); + } + } + else if ( isOption(arg, "indent=tab") ) + { + formatter.setTabIndentation(4); + } + else if ( isParamOption(arg, "T", "indent=force-tab=") ) + { + int spaceNum = 4; + string spaceNumParam = getParam(arg, "T", "indent=force-tab="); + if (spaceNumParam.length() > 0) + spaceNum = atoi(spaceNumParam.c_str()); + if (spaceNum < 2 || spaceNum > 20) + isOptionError(arg, errorInfo); + else + { + formatter.setTabIndentation(spaceNum, true); + } + } + else if ( isOption(arg, "indent=force-tab") ) + { + formatter.setTabIndentation(4, true); + } + else if ( isParamOption(arg, "xT", "indent=force-tab-x=") ) + { + int tabNum = 8; + string tabNumParam = getParam(arg, "xT", "indent=force-tab-x="); + if (tabNumParam.length() > 0) + tabNum = atoi(tabNumParam.c_str()); + if (tabNum < 2 || tabNum > 20) + isOptionError(arg, errorInfo); + else + { + formatter.setForceTabXIndentation(tabNum); + } + } + else if ( isOption(arg, "indent=force-tab-x") ) + { + formatter.setForceTabXIndentation(8); + } + else if ( isParamOption(arg, "s", "indent=spaces=") ) + { + int spaceNum = 4; + string spaceNumParam = getParam(arg, "s", "indent=spaces="); + if (spaceNumParam.length() > 0) + spaceNum = atoi(spaceNumParam.c_str()); + if (spaceNum < 2 || spaceNum > 20) + isOptionError(arg, errorInfo); + else + { + formatter.setSpaceIndentation(spaceNum); + } + } + else if ( isOption(arg, "indent=spaces") ) + { + formatter.setSpaceIndentation(4); + } + else if ( isParamOption(arg, "m", "min-conditional-indent=") ) + { + int minIndent = MINCOND_TWO; + string minIndentParam = getParam(arg, "m", "min-conditional-indent="); + if (minIndentParam.length() > 0) + minIndent = atoi(minIndentParam.c_str()); + if (minIndent >= MINCOND_END) + isOptionError(arg, errorInfo); + else + formatter.setMinConditionalIndentOption(minIndent); + } + else if ( isParamOption(arg, "M", "max-instatement-indent=") ) + { + int maxIndent = 40; + string maxIndentParam = getParam(arg, "M", "max-instatement-indent="); + if (maxIndentParam.length() > 0) + maxIndent = atoi(maxIndentParam.c_str()); + if (maxIndent < 40) + isOptionError(arg, errorInfo); + else if (maxIndent > 120) + isOptionError(arg, errorInfo); + else + formatter.setMaxInStatementIndentLength(maxIndent); + } + else if ( isOption(arg, "N", "indent-namespaces") ) + { + formatter.setNamespaceIndent(true); + } + else if ( isOption(arg, "C", "indent-classes") ) + { + formatter.setClassIndent(true); + } + else if ( isOption(arg, "xG", "indent-modifiers") ) + { + formatter.setModifierIndent(true); + } + else if ( isOption(arg, "S", "indent-switches") ) + { + formatter.setSwitchIndent(true); + } + else if ( isOption(arg, "K", "indent-cases") ) + { + formatter.setCaseIndent(true); + } + else if ( isOption(arg, "L", "indent-labels") ) + { + formatter.setLabelIndent(true); + } + else if (isOption(arg, "xW", "indent-preproc-block")) + { + formatter.setPreprocBlockIndent(true); + } + else if ( isOption(arg, "w", "indent-preproc-define") ) + { + formatter.setPreprocDefineIndent(true); + } + else if ( isOption(arg, "xw", "indent-preproc-cond") ) + { + formatter.setPreprocConditionalIndent(true); + } + else if ( isOption(arg, "y", "break-closing-brackets") ) + { + formatter.setBreakClosingHeaderBracketsMode(true); + } + else if ( isOption(arg, "O", "keep-one-line-blocks") ) + { + formatter.setBreakOneLineBlocksMode(false); + } + else if ( isOption(arg, "o", "keep-one-line-statements") ) + { + formatter.setSingleStatementsMode(false); + } + else if ( isOption(arg, "P", "pad-paren") ) + { + formatter.setParensOutsidePaddingMode(true); + formatter.setParensInsidePaddingMode(true); + } + else if ( isOption(arg, "d", "pad-paren-out") ) + { + formatter.setParensOutsidePaddingMode(true); + } + else if ( isOption(arg, "xd", "pad-first-paren-out") ) + { + formatter.setParensFirstPaddingMode(true); + } + else if ( isOption(arg, "D", "pad-paren-in") ) + { + formatter.setParensInsidePaddingMode(true); + } + else if ( isOption(arg, "H", "pad-header") ) + { + formatter.setParensHeaderPaddingMode(true); + } + else if ( isOption(arg, "U", "unpad-paren") ) + { + formatter.setParensUnPaddingMode(true); + } + else if ( isOption(arg, "p", "pad-oper") ) + { + formatter.setOperatorPaddingMode(true); + } + else if (isOption(arg, "xg", "pad-comma")) + { + formatter.setCommaPaddingMode(true); + } + else if ( isOption(arg, "xe", "delete-empty-lines") ) + { + formatter.setDeleteEmptyLinesMode(true); + } + else if ( isOption(arg, "E", "fill-empty-lines") ) + { + formatter.setEmptyLineFill(true); + } + else if ( isOption(arg, "c", "convert-tabs") ) + { + formatter.setTabSpaceConversionMode(true); + } + else if ( isOption(arg, "xy", "close-templates") ) + { + formatter.setCloseTemplatesMode(true); + } + else if ( isOption(arg, "F", "break-blocks=all") ) + { + formatter.setBreakBlocksMode(true); + formatter.setBreakClosingHeaderBlocksMode(true); + } + else if ( isOption(arg, "f", "break-blocks") ) + { + formatter.setBreakBlocksMode(true); + } + else if ( isOption(arg, "e", "break-elseifs") ) + { + formatter.setBreakElseIfsMode(true); + } + else if ( isOption(arg, "j", "add-brackets") ) + { + formatter.setAddBracketsMode(true); + } + else if ( isOption(arg, "J", "add-one-line-brackets") ) + { + formatter.setAddOneLineBracketsMode(true); + } + else if ( isOption(arg, "xj", "remove-brackets") ) + { + formatter.setRemoveBracketsMode(true); + } + else if ( isOption(arg, "Y", "indent-col1-comments") ) + { + formatter.setIndentCol1CommentsMode(true); + } + else if ( isOption(arg, "align-pointer=type") ) + { + formatter.setPointerAlignment(PTR_ALIGN_TYPE); + } + else if ( isOption(arg, "align-pointer=middle") ) + { + formatter.setPointerAlignment(PTR_ALIGN_MIDDLE); + } + else if ( isOption(arg, "align-pointer=name") ) + { + formatter.setPointerAlignment(PTR_ALIGN_NAME); + } + else if ( isParamOption(arg, "k") ) + { + int align = 0; + string styleParam = getParam(arg, "k"); + if (styleParam.length() > 0) + align = atoi(styleParam.c_str()); + if (align < 1 || align > 3) + isOptionError(arg, errorInfo); + else if (align == 1) + formatter.setPointerAlignment(PTR_ALIGN_TYPE); + else if (align == 2) + formatter.setPointerAlignment(PTR_ALIGN_MIDDLE); + else if (align == 3) + formatter.setPointerAlignment(PTR_ALIGN_NAME); + } + else if ( isOption(arg, "align-reference=none") ) + { + formatter.setReferenceAlignment(REF_ALIGN_NONE); + } + else if ( isOption(arg, "align-reference=type") ) + { + formatter.setReferenceAlignment(REF_ALIGN_TYPE); + } + else if ( isOption(arg, "align-reference=middle") ) + { + formatter.setReferenceAlignment(REF_ALIGN_MIDDLE); + } + else if ( isOption(arg, "align-reference=name") ) + { + formatter.setReferenceAlignment(REF_ALIGN_NAME); + } + else if ( isParamOption(arg, "W") ) + { + int align = 0; + string styleParam = getParam(arg, "W"); + if (styleParam.length() > 0) + align = atoi(styleParam.c_str()); + if (align < 0 || align > 3) + isOptionError(arg, errorInfo); + else if (align == 0) + formatter.setReferenceAlignment(REF_ALIGN_NONE); + else if (align == 1) + formatter.setReferenceAlignment(REF_ALIGN_TYPE); + else if (align == 2) + formatter.setReferenceAlignment(REF_ALIGN_MIDDLE); + else if (align == 3) + formatter.setReferenceAlignment(REF_ALIGN_NAME); + } + else if ( isParamOption(arg, "max-code-length=") ) + { + int maxLength = 50; + string maxLengthParam = getParam(arg, "max-code-length="); + if (maxLengthParam.length() > 0) + maxLength = atoi(maxLengthParam.c_str()); + if (maxLength < 50) + isOptionError(arg, errorInfo); + else if (maxLength > 200) + isOptionError(arg, errorInfo); + else + formatter.setMaxCodeLength(maxLength); + } + else if ( isParamOption(arg, "xC") ) + { + int maxLength = 50; + string maxLengthParam = getParam(arg, "xC"); + if (maxLengthParam.length() > 0) + maxLength = atoi(maxLengthParam.c_str()); + if (maxLength > 200) + isOptionError(arg, errorInfo); + else + formatter.setMaxCodeLength(maxLength); + } + else if ( isOption(arg, "xL", "break-after-logical") ) + { + formatter.setBreakAfterMode(true); + } + else if ( isOption(arg, "xc", "attach-classes") ) + { + formatter.setAttachClass(true); + } + else if ( isOption(arg, "xk", "attach-extern-c") ) + { + formatter.setAttachExternC(true); + } + else if ( isOption(arg, "xn", "attach-namespaces") ) + { + formatter.setAttachNamespace(true); + } + else if ( isOption(arg, "xl", "attach-inlines") ) + { + formatter.setAttachInline(true); + } + else if ( isOption(arg, "xp", "remove-comment-prefix") ) + { + formatter.setStripCommentPrefix(true); + } + // Objective-C options + else if ( isOption(arg, "xQ", "pad-method-prefix") ) + { + formatter.setMethodPrefixPaddingMode(true); + } + else if ( isOption(arg, "xR", "unpad-method-prefix") ) + { + formatter.setMethodPrefixUnPaddingMode(true); + } + else if (isOption(arg, "xq", "pad-return-type")) + { + formatter.setReturnTypePaddingMode(true); + } + else if (isOption(arg, "xr", "unpad-return-type")) + { + formatter.setReturnTypeUnPaddingMode(true); + } + else if (isOption(arg, "xM", "align-method-colon")) + { + formatter.setAlignMethodColon(true); + } + else if ( isOption(arg, "xP0", "pad-method-colon=none") ) + { + formatter.setObjCColonPaddingMode(COLON_PAD_NONE); + } + else if ( isOption(arg, "xP1", "pad-method-colon=all") ) + { + formatter.setObjCColonPaddingMode(COLON_PAD_ALL); + } + else if ( isOption(arg, "xP2", "pad-method-colon=after") ) + { + formatter.setObjCColonPaddingMode(COLON_PAD_AFTER); + } + else if ( isOption(arg, "xP3", "pad-method-colon=before") ) + { + formatter.setObjCColonPaddingMode(COLON_PAD_BEFORE); + } + // depreciated options //////////////////////////////////////////////////////////////////////////////////////////// + else if ( isOption(arg, "indent-preprocessor") ) // depreciated release 2.04 + { + formatter.setPreprocDefineIndent(true); + } + else if ( isOption(arg, "style=ansi") ) // depreciated release 2.05 + { + formatter.setFormattingStyle(STYLE_ALLMAN); + } +// NOTE: Removed in release 2.04. +// else if ( isOption(arg, "b", "brackets=break") ) +// { +// formatter.setBracketFormatMode(BREAK_MODE); +// } +// else if ( isOption(arg, "a", "brackets=attach") ) +// { +// formatter.setBracketFormatMode(ATTACH_MODE); +// } +// else if ( isOption(arg, "l", "brackets=linux") ) +// { +// formatter.setBracketFormatMode(LINUX_MODE); +// } +// else if ( isOption(arg, "u", "brackets=stroustrup") ) +// { +// formatter.setBracketFormatMode(STROUSTRUP_MODE); +// } +// else if ( isOption(arg, "g", "brackets=run-in") ) +// { +// formatter.setBracketFormatMode(RUN_IN_MODE); +// } + // end depreciated options //////////////////////////////////////////////////////////////////////////////////////// +#ifdef ASTYLE_LIB + // End of options used by GUI ///////////////////////////////////////////////////////////////////////////////////// + else + isOptionError(arg, errorInfo); +#else + // Options used by only console /////////////////////////////////////////////////////////////////////////////////// + else if ( isOption(arg, "n", "suffix=none") ) + { + g_console->setNoBackup(true); + } + else if ( isParamOption(arg, "suffix=") ) + { + string suffixParam = getParam(arg, "suffix="); + if (suffixParam.length() > 0) + { + g_console->setOrigSuffix(suffixParam); + } + } + else if ( isParamOption(arg, "exclude=") ) + { + string suffixParam = getParam(arg, "exclude="); + if (suffixParam.length() > 0) + g_console->updateExcludeVector(suffixParam); + } + else if ( isOption(arg, "r", "R") || isOption(arg, "recursive") ) + { + g_console->setIsRecursive(true); + } + else if (isOption(arg, "dry-run")) + { + g_console->setIsDryRun(true); + } + else if ( isOption(arg, "Z", "preserve-date") ) + { + g_console->setPreserveDate(true); + } + else if ( isOption(arg, "v", "verbose") ) + { + g_console->setIsVerbose(true); + } + else if ( isOption(arg, "Q", "formatted") ) + { + g_console->setIsFormattedOnly(true); + } + else if ( isOption(arg, "q", "quiet") ) + { + g_console->setIsQuiet(true); + } + else if ( isOption(arg, "i", "ignore-exclude-errors") ) + { + g_console->setIgnoreExcludeErrors(true); + } + else if ( isOption(arg, "xi", "ignore-exclude-errors-x") ) + { + g_console->setIgnoreExcludeErrorsAndDisplay(true); + } + else if ( isOption(arg, "X", "errors-to-stdout") ) + { + _err = &cout; + } + else if ( isOption(arg, "lineend=windows") ) + { + formatter.setLineEndFormat(LINEEND_WINDOWS); + } + else if ( isOption(arg, "lineend=linux") ) + { + formatter.setLineEndFormat(LINEEND_LINUX); + } + else if ( isOption(arg, "lineend=macold") ) + { + formatter.setLineEndFormat(LINEEND_MACOLD); + } + else if ( isParamOption(arg, "z") ) + { + int lineendType = 0; + string lineendParam = getParam(arg, "z"); + if (lineendParam.length() > 0) + lineendType = atoi(lineendParam.c_str()); + if (lineendType < 1 || lineendType > 3) + isOptionError(arg, errorInfo); + else if (lineendType == 1) + formatter.setLineEndFormat(LINEEND_WINDOWS); + else if (lineendType == 2) + formatter.setLineEndFormat(LINEEND_LINUX); + else if (lineendType == 3) + formatter.setLineEndFormat(LINEEND_MACOLD); + } + else + isOptionError(arg, errorInfo); +#endif +} // End of parseOption function + +// Parse options from the options file. +void ASOptions::importOptions(istream& in, vector& optionsVector) +{ + char ch; + bool isInQuote = false; + char quoteChar = ' '; + string currentToken; + + while (in) + { + currentToken = ""; + do + { + in.get(ch); + if (in.eof()) + break; + // treat '#' as line comments + if (ch == '#') + while (in) + { + in.get(ch); + if (ch == '\n' || ch == '\r') + break; + } + + // break options on new-lines, tabs, commas, or spaces + // remove quotes from output + if (in.eof() || ch == '\n' || ch == '\r' || ch == '\t' || ch == ',') + break; + if (ch == ' ' && !isInQuote) + break; + if (ch == quoteChar && isInQuote) + break; + if (ch == '"' || ch == '\'') + { + isInQuote = true; + quoteChar = ch; + continue; + } + currentToken.append(1, ch); + } + while (in); + + if (currentToken.length() != 0) + optionsVector.push_back(currentToken); + isInQuote = false; + } +} + +string ASOptions::getOptionErrors() const +{ + return optionErrors.str(); +} + +string ASOptions::getParam(const string& arg, const char* op) +{ + return arg.substr(strlen(op)); +} + +string ASOptions::getParam(const string& arg, const char* op1, const char* op2) +{ + return isParamOption(arg, op1) ? getParam(arg, op1) : getParam(arg, op2); +} + +bool ASOptions::isOption(const string& arg, const char* op) +{ + return arg.compare(op) == 0; +} + +bool ASOptions::isOption(const string& arg, const char* op1, const char* op2) +{ + return (isOption(arg, op1) || isOption(arg, op2)); +} + +void ASOptions::isOptionError(const string& arg, const string& errorInfo) +{ + if (optionErrors.str().length() == 0) + optionErrors << errorInfo << endl; // need main error message + optionErrors << arg << endl; +} + +bool ASOptions::isParamOption(const string& arg, const char* option) +{ + bool retVal = arg.compare(0, strlen(option), option) == 0; + // if comparing for short option, 2nd char of arg must be numeric + if (retVal && strlen(option) == 1 && arg.length() > 1) + if (!isdigit((unsigned char)arg[1])) + retVal = false; + return retVal; +} + +bool ASOptions::isParamOption(const string& arg, const char* option1, const char* option2) +{ + return isParamOption(arg, option1) || isParamOption(arg, option2); +} + +//---------------------------------------------------------------------------- +// Utf8_16 class +//---------------------------------------------------------------------------- + +// Return true if an int is big endian. +bool Utf8_16::getBigEndian() const +{ + short int word = 0x0001; + char* byte = (char*) &word; + return (byte[0] ? false : true); +} + +// Swap the two low order bytes of a 16 bit integer value. +int Utf8_16::swap16bit(int value) const +{ + return ( ((value & 0xff) << 8) | ((value & 0xff00) >> 8) ); +} + +// Return the length of a utf-16 C string. +// The length is in number of utf16_t. +size_t Utf8_16::utf16len(const utf16* utf16In) const +{ + size_t length = 0; + while (*utf16In++ != '\0') + length++; + return length; +} + +// Adapted from SciTE UniConversion.cxx. +// Copyright 1998-2001 by Neil Hodgson +// Modified for Artistic Style by Jim Pattee. +// Compute the length of an output utf-8 file given a utf-16 file. +// Input inLen is the size in BYTES (not wchar_t). +size_t Utf8_16::Utf8LengthFromUtf16(const char* utf16In, size_t inLen, bool isBigEndian) const +{ + size_t len = 0; + size_t wcharLen = inLen / 2; + const short* uptr = reinterpret_cast(utf16In); + for (size_t i = 0; i < wcharLen && uptr[i];) + { + size_t uch = isBigEndian ? swap16bit(uptr[i]) : uptr[i]; + if (uch < 0x80) + len++; + else if (uch < 0x800) + len += 2; + else if ((uch >= SURROGATE_LEAD_FIRST) && (uch <= SURROGATE_TRAIL_LAST)) + { + len += 4; + i++; + } + else + len += 3; + i++; + } + return len; +} + +// Adapted from SciTE Utf8_16.cxx. +// Copyright (C) 2002 Scott Kirkwood. +// Modified for Artistic Style by Jim Pattee. +// Convert a utf-8 file to utf-16. +size_t Utf8_16::Utf8ToUtf16(char* utf8In, size_t inLen, bool isBigEndian, char* utf16Out) const +{ + int nCur = 0; + ubyte* pRead = reinterpret_cast(utf8In); + utf16* pCur = reinterpret_cast(utf16Out); + const ubyte* pEnd = pRead + inLen; + const utf16* pCurStart = pCur; + eState state = eStart; + + // the BOM will automatically be converted to utf-16 + while (pRead < pEnd) + { + switch (state) + { + case eStart: + if ((0xF0 & *pRead) == 0xF0) + { + nCur = (0x7 & *pRead) << 18; + state = eSecondOf4Bytes; + } + else if ((0xE0 & *pRead) == 0xE0) + { + nCur = (~0xE0 & *pRead) << 12; + state = ePenultimate; + } + else if ((0xC0 & *pRead) == 0xC0) + { + nCur = (~0xC0 & *pRead) << 6; + state = eFinal; + } + else + { + nCur = *pRead; + state = eStart; + } + break; + case eSecondOf4Bytes: + nCur |= (0x3F & *pRead) << 12; + state = ePenultimate; + break; + case ePenultimate: + nCur |= (0x3F & *pRead) << 6; + state = eFinal; + break; + case eFinal: + nCur |= (0x3F & *pRead); + state = eStart; + break; + // no default case is needed + } + ++pRead; + + if (state == eStart) + { + int codePoint = nCur; + if (codePoint >= SURROGATE_FIRST_VALUE) + { + codePoint -= SURROGATE_FIRST_VALUE; + int lead = (codePoint >> 10) + SURROGATE_LEAD_FIRST; + *pCur++ = static_cast(isBigEndian ? swap16bit(lead) : lead); + int trail = (codePoint & 0x3ff) + SURROGATE_TRAIL_FIRST; + *pCur++ = static_cast(isBigEndian ? swap16bit(trail) : trail); + } + else + *pCur++ = static_cast(isBigEndian ? swap16bit(codePoint) : codePoint); + } + } + // return value is the output length in BYTES (not wchar_t) + return (pCur - pCurStart) * 2; +} + +// Adapted from SciTE UniConversion.cxx. +// Copyright 1998-2001 by Neil Hodgson +// Modified for Artistic Style by Jim Pattee. +// Compute the length of an output utf-16 file given a utf-8 file. +// Return value is the size in BYTES (not wchar_t). +size_t Utf8_16::Utf16LengthFromUtf8(const char* utf8In, size_t len) const +{ + size_t ulen = 0; + size_t charLen; + for (size_t i = 0; i < len;) + { + unsigned char ch = static_cast(utf8In[i]); + if (ch < 0x80) + charLen = 1; + else if (ch < 0x80 + 0x40 + 0x20) + charLen = 2; + else if (ch < 0x80 + 0x40 + 0x20 + 0x10) + charLen = 3; + else + { + charLen = 4; + ulen++; + } + i += charLen; + ulen++; + } + // return value is the length in bytes (not wchar_t) + return ulen * 2; +} + +// Adapted from SciTE Utf8_16.cxx. +// Copyright (C) 2002 Scott Kirkwood. +// Modified for Artistic Style by Jim Pattee. +// Convert a utf-16 file to utf-8. +size_t Utf8_16::Utf16ToUtf8(char* utf16In, size_t inLen, bool isBigEndian, + bool firstBlock, char* utf8Out) const +{ + int nCur16 = 0; + int nCur = 0; + ubyte* pRead = reinterpret_cast(utf16In); + ubyte* pCur = reinterpret_cast(utf8Out); + const ubyte* pEnd = pRead + inLen; + const ubyte* pCurStart = pCur; + static eState state = eStart; // state is retained for subsequent blocks + if (firstBlock) + state = eStart; + + // the BOM will automatically be converted to utf-8 + while (pRead < pEnd) + { + switch (state) + { + case eStart: + if (pRead >= pEnd) + { + ++pRead; + break; + } + if (isBigEndian) + { + nCur16 = static_cast(*pRead++ << 8); + nCur16 |= static_cast(*pRead); + } + else + { + nCur16 = *pRead++; + nCur16 |= static_cast(*pRead << 8); + } + if (nCur16 >= SURROGATE_LEAD_FIRST && nCur16 <= SURROGATE_LEAD_LAST) + { + ++pRead; + int trail; + if (isBigEndian) + { + trail = static_cast(*pRead++ << 8); + trail |= static_cast(*pRead); + } + else + { + trail = *pRead++; + trail |= static_cast(*pRead << 8); + } + nCur16 = (((nCur16 & 0x3ff) << 10) | (trail & 0x3ff)) + SURROGATE_FIRST_VALUE; + } + ++pRead; + + if (nCur16 < 0x80) + { + nCur = static_cast(nCur16 & 0xFF); + state = eStart; + } + else if (nCur16 < 0x800) + { + nCur = static_cast(0xC0 | (nCur16 >> 6)); + state = eFinal; + } + else if (nCur16 < SURROGATE_FIRST_VALUE) + { + nCur = static_cast(0xE0 | (nCur16 >> 12)); + state = ePenultimate; + } + else + { + nCur = static_cast(0xF0 | (nCur16 >> 18)); + state = eSecondOf4Bytes; + } + break; + case eSecondOf4Bytes: + nCur = static_cast(0x80 | ((nCur16 >> 12) & 0x3F)); + state = ePenultimate; + break; + case ePenultimate: + nCur = static_cast(0x80 | ((nCur16 >> 6) & 0x3F)); + state = eFinal; + break; + case eFinal: + nCur = static_cast(0x80 | (nCur16 & 0x3F)); + state = eStart; + break; + // no default case is needed + } + *pCur++ = static_cast(nCur); + } + return pCur - pCurStart; +} + +//---------------------------------------------------------------------------- + +} // end of astyle namespace + +//---------------------------------------------------------------------------- + +using namespace astyle; + +//---------------------------------------------------------------------------- +// ASTYLE_JNI functions for Java library builds +//---------------------------------------------------------------------------- + +#ifdef ASTYLE_JNI + +// called by a java program to get the version number +// the function name is constructed from method names in the calling java program +extern "C" EXPORT +jstring STDCALL Java_AStyleInterface_AStyleGetVersion(JNIEnv* env, jclass) +{ + return env->NewStringUTF(g_version); +} + +// called by a java program to format the source code +// the function name is constructed from method names in the calling java program +extern "C" EXPORT +jstring STDCALL Java_AStyleInterface_AStyleMain(JNIEnv* env, + jobject obj, + jstring textInJava, + jstring optionsJava) +{ + g_env = env; // make object available globally + g_obj = obj; // make object available globally + + jstring textErr = env->NewStringUTF(""); // zero length text returned if an error occurs + + // get the method ID + jclass cls = env->GetObjectClass(obj); + g_mid = env->GetMethodID(cls, "ErrorHandler", "(ILjava/lang/String;)V"); + if (g_mid == 0) + { + cout << "Cannot find java method ErrorHandler" << endl; + return textErr; + } + + // convert jstring to char* + const char* textIn = env->GetStringUTFChars(textInJava, NULL); + const char* options = env->GetStringUTFChars(optionsJava, NULL); + + // call the C++ formatting function + char* textOut = AStyleMain(textIn, options, javaErrorHandler, javaMemoryAlloc); + // if an error message occurred it was displayed by errorHandler + if (textOut == NULL) + return textErr; + + // release memory + jstring textOutJava = env->NewStringUTF(textOut); + delete [] textOut; + env->ReleaseStringUTFChars(textInJava, textIn); + env->ReleaseStringUTFChars(optionsJava, options); + + return textOutJava; +} + +// Call the Java error handler +void STDCALL javaErrorHandler(int errorNumber, const char* errorMessage) +{ + jstring errorMessageJava = g_env->NewStringUTF(errorMessage); + g_env->CallVoidMethod(g_obj, g_mid, errorNumber, errorMessageJava); +} + +// Allocate memory for the formatted text +char* STDCALL javaMemoryAlloc(unsigned long memoryNeeded) +{ + // error condition is checked after return from AStyleMain + char* buffer = new(nothrow) char[memoryNeeded]; + return buffer; +} +#endif // ASTYLE_JNI + +//---------------------------------------------------------------------------- +// Entry point for AStyleMainUtf16 library builds +//---------------------------------------------------------------------------- + +#ifdef ASTYLE_LIB + +extern "C" EXPORT utf16_t* STDCALL AStyleMainUtf16(const utf16_t* pSourceIn, // the source to be formatted + const utf16_t* pOptions, // AStyle options + fpError fpErrorHandler, // error handler function + fpAlloc fpMemoryAlloc) // memory allocation function +{ + if (fpErrorHandler == NULL) // cannot display a message if no error handler + return NULL; + + if (pSourceIn == NULL) + { + fpErrorHandler(101, "No pointer to source input."); + return NULL; + } + if (pOptions == NULL) + { + fpErrorHandler(102, "No pointer to AStyle options."); + return NULL; + } + if (fpMemoryAlloc == NULL) + { + fpErrorHandler(103, "No pointer to memory allocation function."); + return NULL; + } +#ifndef _WIN32 + // check size of utf16_t on Linux + int sizeCheck = 2; + if (sizeof(utf16_t) != sizeCheck) + { + fpErrorHandler(104, "Unsigned short is not the correct size."); + return NULL; + } +#endif + + ASLibrary library; + utf16_t* utf16Out = library.formatUtf16(pSourceIn, pOptions, fpErrorHandler, fpMemoryAlloc); + return utf16Out; +} + +//---------------------------------------------------------------------------- +// ASTYLE_LIB entry point for library builds +//---------------------------------------------------------------------------- +/* + * IMPORTANT VC DLL linker for WIN32 must have the parameter /EXPORT:AStyleMain=_AStyleMain@16 + * /EXPORT:AStyleGetVersion=_AStyleGetVersion@0 + * No /EXPORT is required for x64 + */ +extern "C" EXPORT char* STDCALL AStyleMain(const char* pSourceIn, // the source to be formatted + const char* pOptions, // AStyle options + fpError fpErrorHandler, // error handler function + fpAlloc fpMemoryAlloc) // memory allocation function +{ + if (fpErrorHandler == NULL) // cannot display a message if no error handler + return NULL; + + if (pSourceIn == NULL) + { + fpErrorHandler(101, "No pointer to source input."); + return NULL; + } + if (pOptions == NULL) + { + fpErrorHandler(102, "No pointer to AStyle options."); + return NULL; + } + if (fpMemoryAlloc == NULL) + { + fpErrorHandler(103, "No pointer to memory allocation function."); + return NULL; + } + + ASFormatter formatter; + ASOptions options(formatter); + + vector optionsVector; + istringstream opt(pOptions); + + options.importOptions(opt, optionsVector); + + bool ok = options.parseOptions(optionsVector, "Invalid Artistic Style options:"); + if (!ok) + fpErrorHandler(130, options.getOptionErrors().c_str()); + + istringstream in(pSourceIn); + ASStreamIterator streamIterator(&in); + ostringstream out; + formatter.init(&streamIterator); + + while (formatter.hasMoreLines()) + { + out << formatter.nextLine(); + if (formatter.hasMoreLines()) + out << streamIterator.getOutputEOL(); + else + { + // this can happen if the file if missing a closing bracket and break-blocks is requested + if (formatter.getIsLineReady()) + { + out << streamIterator.getOutputEOL(); + out << formatter.nextLine(); + } + } + } + + unsigned long textSizeOut = out.str().length(); + char* pTextOut = fpMemoryAlloc(textSizeOut + 1); // call memory allocation function + if (pTextOut == NULL) + { + fpErrorHandler(120, "Allocation failure on output."); + return NULL; + } + + strcpy(pTextOut, out.str().c_str()); +#ifndef NDEBUG + // The checksum is an assert in the console build and ASFormatter. + // This error returns the incorrectly formatted file to the editor. + // This is done to allow the file to be saved for debugging purposes. + if (formatter.getChecksumDiff() != 0) + fpErrorHandler(220, + "Checksum error.\n" + "The incorrectly formatted file will be returned for debugging."); +#endif + return pTextOut; +} + +extern "C" EXPORT const char* STDCALL AStyleGetVersion(void) +{ + return g_version; +} + +// ASTYLECON_LIB is defined to exclude "main" from the test programs +#elif !defined(ASTYLECON_LIB) + +//---------------------------------------------------------------------------- +// main function for ASConsole build +//---------------------------------------------------------------------------- + +int main(int argc, char** argv) +{ + // create objects + ASFormatter formatter; + g_console = new ASConsole(formatter); + + // process command line and options file + // build the vectors fileNameVector, optionsVector, and fileOptionsVector + vector argvOptions; + argvOptions = g_console->getArgvOptions(argc, argv); + g_console->processOptions(argvOptions); + + // if no files have been given, use cin for input and cout for output + if (g_console->fileNameVectorIsEmpty()) + { + g_console->formatCinToCout(); + return EXIT_SUCCESS; + } + + // process entries in the fileNameVector + g_console->processFiles(); + + delete g_console; + return EXIT_SUCCESS; +} + +#endif // ASTYLE_LIB diff --git a/External/Tools/AStyle/src/astyle_main.h b/External/Tools/AStyle/src/astyle_main.h new file mode 100644 index 0000000000..2da42c0280 --- /dev/null +++ b/External/Tools/AStyle/src/astyle_main.h @@ -0,0 +1,440 @@ +// astyle_main.h +// Copyright (c) 2016 by Jim Pattee . +// Licensed under the MIT license. +// License.txt describes the conditions under which this software may be distributed. + +#ifndef ASTYLE_MAIN_H +#define ASTYLE_MAIN_H + +//---------------------------------------------------------------------------- +// headers +//---------------------------------------------------------------------------- + +#include "astyle.h" + +#include +#include + +#if defined(__BORLANDC__) && __BORLANDC__ < 0x0650 + // Embarcadero needs this for the following utime.h + // otherwise "struct utimbuf" gets an error on time_t + // 0x0650 for C++Builder XE3 + using std::time_t; +#endif + +#if defined(_MSC_VER) || defined(__DMC__) + #include + #include +#else + #include + #include +#endif // end compiler checks + +#ifdef ASTYLE_JNI + #include + #ifndef ASTYLE_LIB // ASTYLE_LIB must be defined for ASTYLE_JNI + #define ASTYLE_LIB + #endif +#endif // ASTYLE_JNI + +#ifndef ASTYLE_LIB + // for console build only + #include "ASLocalizer.h" + #define _(a) localizer.settext(a) +#endif // ASTYLE_LIB + +//----------------------------------------------------------------------------- +// declarations +//----------------------------------------------------------------------------- + +// for G++ implementation of string.compare: +#if defined(__GNUC__) && __GNUC__ < 3 + #error - Use GNU C compiler release 3 or higher +#endif + +// for namespace problem in version 5.0 +#if defined(_MSC_VER) && _MSC_VER < 1200 // check for V6.0 + #error - Use Microsoft compiler version 6 or higher +#endif + +// for mingw BOM, UTF-16, and Unicode functions +#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) + #if (__MINGW32_MAJOR_VERSION > 3) || ((__MINGW32_MAJOR_VERSION == 3) && (__MINGW32_MINOR_VERSION < 16)) + #error - Use MinGW compiler version 4 or higher + #endif +#endif + +#ifdef ASTYLE_LIB + + // define STDCALL and EXPORT for Windows + // MINGW defines STDCALL in Windows.h (actually windef.h) + // EXPORT has no value if ASTYLE_NO_EXPORT is defined + #ifdef _WIN32 + #ifndef STDCALL + #define STDCALL __stdcall + #endif + // define this to prevent compiler warning and error messages + #ifdef ASTYLE_NO_EXPORT + #define EXPORT + #else + #define EXPORT __declspec(dllexport) + #endif + // define STDCALL and EXPORT for non-Windows + // visibility attribute allows "-fvisibility=hidden" compiler option + #else + #define STDCALL + #if __GNUC__ >= 4 + #define EXPORT __attribute__ ((visibility ("default"))) + #else + #define EXPORT + #endif + #endif // #ifdef _WIN32 + + // define utf-16 bit text for the platform + typedef unsigned short utf16_t; + // define pointers to callback error handler and memory allocation + typedef void (STDCALL* fpError)(int errorNumber, const char* errorMessage); + typedef char* (STDCALL* fpAlloc)(unsigned long memoryNeeded); + +#endif // #ifdef ASTYLE_LIB + +//---------------------------------------------------------------------------- +// astyle namespace +//---------------------------------------------------------------------------- + +namespace astyle { +// +//---------------------------------------------------------------------------- +// ASStreamIterator class +// typename will be istringstream for GUI and istream otherwise +// ASSourceIterator is an abstract class defined in astyle.h +//---------------------------------------------------------------------------- + +template +class ASStreamIterator : public ASSourceIterator +{ +public: + bool checkForEmptyLine; + + // function declarations + explicit ASStreamIterator(T* in); + virtual ~ASStreamIterator(); + bool getLineEndChange(int lineEndFormat) const; + int getStreamLength() const; + string nextLine(bool emptyLineWasDeleted); + string peekNextLine(); + void peekReset(); + void saveLastInputLine(); + streamoff tellg(); + +private: + ASStreamIterator(const ASStreamIterator& copy); // copy constructor not to be implemented + ASStreamIterator& operator=(ASStreamIterator&); // assignment operator not to be implemented + T* inStream; // pointer to the input stream + string buffer; // current input line + string prevBuffer; // previous input line + int eolWindows; // number of Windows line endings, CRLF + int eolLinux; // number of Linux line endings, LF + int eolMacOld; // number of old Mac line endings. CR + char outputEOL[4]; // next output end of line char + streamoff streamLength; // length of the input file stream + streamoff peekStart; // starting position for peekNextLine + bool prevLineDeleted; // the previous input line was deleted + +public: // inline functions + bool compareToInputBuffer(const string& nextLine_) const + { return (nextLine_ == prevBuffer); } + const char* getOutputEOL() const { return outputEOL; } + bool hasMoreLines() const { return !inStream->eof(); } +}; + +//---------------------------------------------------------------------------- +// Utf8_16 class for utf8/16 conversions +//---------------------------------------------------------------------------- + +class Utf8_16 +{ +private: + typedef unsigned short utf16; // 16 bits + typedef unsigned char utf8; // 8 bits + typedef unsigned char ubyte; // 8 bits + enum { SURROGATE_LEAD_FIRST = 0xD800 }; + enum { SURROGATE_LEAD_LAST = 0xDBFF }; + enum { SURROGATE_TRAIL_FIRST = 0xDC00 }; + enum { SURROGATE_TRAIL_LAST = 0xDFFF }; + enum { SURROGATE_FIRST_VALUE = 0x10000 }; + enum eState { eStart, eSecondOf4Bytes, ePenultimate, eFinal }; + +public: + bool getBigEndian() const; + int swap16bit(int value) const; + size_t utf16len(const utf16* utf16In) const; + size_t Utf8LengthFromUtf16(const char* utf16In, size_t inLen, bool isBigEndian) const; + size_t Utf8ToUtf16(char* utf8In, size_t inLen, bool isBigEndian, char* utf16Out) const; + size_t Utf16LengthFromUtf8(const char* utf8In, size_t inLen) const; + size_t Utf16ToUtf8(char* utf16In, size_t inLen, bool isBigEndian, + bool firstBlock, char* utf8Out) const; +}; + +//---------------------------------------------------------------------------- +// ASOptions class for options processing +// used by both console and library builds +//---------------------------------------------------------------------------- + +class ASOptions +{ +public: + ASOptions(ASFormatter& formatterArg) : formatter(formatterArg) {} + string getOptionErrors() const; + void importOptions(istream& in, vector& optionsVector); + bool parseOptions(vector& optionsVector, const string& errorInfo); + +private: + // variables + ASFormatter& formatter; // reference to the ASFormatter object + stringstream optionErrors; // option error messages + + // functions + ASOptions(const ASOptions&); // copy constructor not to be implemented + ASOptions& operator=(ASOptions&); // assignment operator not to be implemented + string getParam(const string& arg, const char* op); + string getParam(const string& arg, const char* op1, const char* op2); + bool isOption(const string& arg, const char* op); + bool isOption(const string& arg, const char* op1, const char* op2); + void isOptionError(const string& arg, const string& errorInfo); + bool isParamOption(const string& arg, const char* option); + bool isParamOption(const string& arg, const char* option1, const char* option2); + void parseOption(const string& arg, const string& errorInfo); +}; + +#ifndef ASTYLE_LIB + +//---------------------------------------------------------------------------- +// ASConsole class for console build +//---------------------------------------------------------------------------- + +class ASConsole +{ +private: // variables + ASFormatter& formatter; // reference to the ASFormatter object + ASLocalizer localizer; // ASLocalizer object + // command line options + bool isRecursive; // recursive option + bool isDryRun; // dry-run option + bool noBackup; // suffix=none option + bool preserveDate; // preserve-date option + bool isVerbose; // verbose option + bool isQuiet; // quiet option + bool isFormattedOnly; // formatted lines only option + bool ignoreExcludeErrors; // don't abort on unmatched excludes + bool ignoreExcludeErrorsDisplay; // don't display unmatched excludes + bool optionsFileRequired; // options= option + bool useAscii; // ascii option + // other variables + bool bypassBrowserOpen; // don't open the browser on html options + bool hasWildcard; // file name includes a wildcard + size_t mainDirectoryLength; // directory length to be excluded in displays + bool filesAreIdentical; // input and output files are identical + int filesFormatted; // number of files formatted + int filesUnchanged; // number of files unchanged + bool lineEndsMixed; // output has mixed line ends + int linesOut; // number of output lines + char outputEOL[4]; // current line end + char prevEOL[4]; // previous line end + + Utf8_16 utf8_16; // utf8/16 conversion methods + + string optionsFileName; // file path and name of the options file to use + string origSuffix; // suffix= option + string targetDirectory; // path to the directory being processed + string targetFilename; // file name being processed + + vector excludeVector; // exclude from wildcard hits + vector excludeHitsVector; // exclude flags for error reporting + vector fileNameVector; // file paths and names from the command line + vector optionsVector; // options from the command line + vector fileOptionsVector; // options from the options file + vector fileName; // files to be processed including path + +public: // variables + ASConsole(ASFormatter& formatterArg) : formatter(formatterArg) + { + // command line options + isRecursive = false; + isDryRun = false; + noBackup = false; + preserveDate = false; + isVerbose = false; + isQuiet = false; + isFormattedOnly = false; + ignoreExcludeErrors = false; + ignoreExcludeErrorsDisplay = false; + optionsFileRequired = false; + useAscii = false; + // other variables + bypassBrowserOpen = false; + hasWildcard = false; + filesAreIdentical = true; + lineEndsMixed = false; + outputEOL[0] = '\0'; + prevEOL[0] = '\0'; + origSuffix = ".orig"; + mainDirectoryLength = 0; + filesFormatted = 0; + filesUnchanged = 0; + linesOut = 0; + } + +public: // functions + void convertLineEnds(ostringstream& out, int lineEnd); + FileEncoding detectEncoding(const char* data, size_t dataSize) const; + void error() const; + void error(const char* why, const char* what) const; + void formatCinToCout(); + vector getArgvOptions(int argc, char** argv) const; + bool fileNameVectorIsEmpty() const; + bool getFilesAreIdentical() const; + int getFilesFormatted() const; + bool getIgnoreExcludeErrors() const; + bool getIgnoreExcludeErrorsDisplay() const; + bool getIsDryRun() const; + bool getIsFormattedOnly() const; + bool getIsQuiet() const; + bool getIsRecursive() const; + bool getIsVerbose() const; + bool getLineEndsMixed() const; + bool getNoBackup() const; + bool getPreserveDate() const; + string getLanguageID() const; + string getNumberFormat(int num, size_t = 0) const; + string getNumberFormat(int num, const char* groupingArg, const char* separator) const; + string getOptionsFileName() const; + string getOrigSuffix() const; + void processFiles(); + void processOptions(vector& argvOptions); + void setBypassBrowserOpen(bool state); + void setIgnoreExcludeErrors(bool state); + void setIgnoreExcludeErrorsAndDisplay(bool state); + void setIsDryRun(bool state); + void setIsFormattedOnly(bool state); + void setIsQuiet(bool state); + void setIsRecursive(bool state); + void setIsVerbose(bool state); + void setNoBackup(bool state); + void setOptionsFileName(string name); + void setOrigSuffix(string suffix); + void setPreserveDate(bool state); + void standardizePath(string& path, bool removeBeginningSeparator = false) const; + bool stringEndsWith(const string& str, const string& suffix) const; + void updateExcludeVector(string suffixParam); + vector getExcludeVector() const; + vector getExcludeHitsVector() const; + vector getFileNameVector() const; + vector getOptionsVector() const; + vector getFileOptionsVector() const; + vector getFileName() const; + +private: // functions + ASConsole& operator=(ASConsole&); // not to be implemented + void correctMixedLineEnds(ostringstream& out); + void formatFile(const string& fileName_); + string getCurrentDirectory(const string& fileName_) const; + void getFileNames(const string& directory, const string& wildcard); + void getFilePaths(string& filePath); + string getParam(const string& arg, const char* op); + void initializeOutputEOL(LineEndFormat lineEndFormat); + bool isOption(const string& arg, const char* op); + bool isOption(const string& arg, const char* op1, const char* op2); + bool isParamOption(const string& arg, const char* option); + bool isPathExclued(const string& subPath); + void launchDefaultBrowser(const char* filePathIn = NULL) const; + void printHelp() const; + void printMsg(const char* msg, const string& data) const; + void printSeparatingLine() const; + void printVerboseHeader() const; + void printVerboseStats(clock_t startTime) const; + FileEncoding readFile(const string& fileName_, stringstream& in) const; + void removeFile(const char* fileName_, const char* errMsg) const; + void renameFile(const char* oldFileName, const char* newFileName, const char* errMsg) const; + void setOutputEOL(LineEndFormat lineEndFormat, const char* currentEOL); + void sleep(int seconds) const; + int waitForRemove(const char* oldFileName) const; + int wildcmp(const char* wild, const char* data) const; + void writeFile(const string& fileName_, FileEncoding encoding, ostringstream& out) const; +#ifdef _WIN32 + void displayLastError(); +#endif +}; +#else // ASTYLE_LIB + +//---------------------------------------------------------------------------- +// ASLibrary class for library build +//---------------------------------------------------------------------------- + +class ASLibrary +{ +public: + ASLibrary() {} + virtual ~ASLibrary() {} + // virtual functions are mocked in testing + utf16_t* formatUtf16(const utf16_t*, const utf16_t*, fpError, fpAlloc) const; + virtual utf16_t* convertUtf8ToUtf16(const char* utf8In, fpAlloc fpMemoryAlloc) const; + virtual char* convertUtf16ToUtf8(const utf16_t* pSourceIn) const; + +private: + static char* STDCALL tempMemoryAllocation(unsigned long memoryNeeded); + +private: + Utf8_16 utf8_16; // utf8/16 conversion methods +}; + +#endif // ASTYLE_LIB + +//---------------------------------------------------------------------------- + +} // end of namespace astyle + +//---------------------------------------------------------------------------- +// declarations for java native interface (JNI) build +// they are called externally and are NOT part of the namespace +//---------------------------------------------------------------------------- +#ifdef ASTYLE_JNI +void STDCALL javaErrorHandler(int errorNumber, const char* errorMessage); +char* STDCALL javaMemoryAlloc(unsigned long memoryNeeded); +// the following function names are constructed from method names in the calling java program +extern "C" EXPORT +jstring STDCALL Java_AStyleInterface_AStyleGetVersion(JNIEnv* env, jclass); +extern "C" EXPORT +jstring STDCALL Java_AStyleInterface_AStyleMain(JNIEnv* env, + jobject obj, + jstring textInJava, + jstring optionsJava); +#endif // ASTYLE_JNI + +//---------------------------------------------------------------------------- +// declarations for UTF-16 interface +// they are called externally and are NOT part of the namespace +//---------------------------------------------------------------------------- +#ifdef ASTYLE_LIB +extern "C" EXPORT +utf16_t* STDCALL AStyleMainUtf16(const utf16_t* pSourceIn, + const utf16_t* pOptions, + fpError fpErrorHandler, + fpAlloc fpMemoryAlloc); +#endif // ASTYLE_LIB + +//----------------------------------------------------------------------------- +// declarations for standard DLL interface +// they are called externally and are NOT part of the namespace +//----------------------------------------------------------------------------- +#ifdef ASTYLE_LIB +extern "C" EXPORT char* STDCALL AStyleMain(const char* sourceIn, + const char* optionsIn, + fpError errorHandler, + fpAlloc memoryAlloc); +extern "C" EXPORT const char* STDCALL AStyleGetVersion(void); +#endif // ASTYLE_LIB + +//----------------------------------------------------------------------------- + +#endif // closes ASTYLE_MAIN_H diff --git a/FlashDevelop/Bin/Debug/AStyle.dll b/FlashDevelop/Bin/Debug/AStyle.dll new file mode 100644 index 0000000000..1d437213e6 Binary files /dev/null and b/FlashDevelop/Bin/Debug/AStyle.dll differ diff --git a/FlashDevelop/Bin/Debug/AStyle64.dll b/FlashDevelop/Bin/Debug/AStyle64.dll new file mode 100644 index 0000000000..2d60bffa0c Binary files /dev/null and b/FlashDevelop/Bin/Debug/AStyle64.dll differ diff --git a/FlashDevelop/Bin/Debug/Docs/index.html b/FlashDevelop/Bin/Debug/Docs/index.html index 224948874b..68a2c921ec 100644 --- a/FlashDevelop/Bin/Debug/Docs/index.html +++ b/FlashDevelop/Bin/Debug/Docs/index.html @@ -34,8 +34,8 @@

Used Tools

  • SwfOp library by Florian Kruesch (code library)
  • AS2API documentation tool by David Holroyd (console application)
  • Motion-Twin ActionScript Compiler by Motion-Twin (console application)
  • +
  • Flex PMD tool by Apache Software Foundation (console application)
  • Swfmill XML/SWF processor by Daniel Fischer (console application)
  • -
  • Flex PMD tool by Adobe Systems Inc. (console application)
  • Components

    @@ -50,6 +50,7 @@

    Components

  • Aga controls by Andrey Gliznetsov
  • CSScriptLibrary by Oleg Shilo
  • SharpZipLib by ISharpCode
  • +
  • Artistic Style by Jim Pattee
  • Licence

    diff --git a/PluginCore/PluginCore/Resources/de_DE.resX b/PluginCore/PluginCore/Resources/de_DE.resX index a58a109d21..7e0301e4e3 100644 --- a/PluginCore/PluginCore/Resources/de_DE.resX +++ b/PluginCore/PluginCore/Resources/de_DE.resX @@ -4442,8 +4442,8 @@ Eigene Sprachumgebungen müssen eine Erweiterung der Standard-Sprachumgebung sei Added after 3.3.1 - Fügt eine MXML und ActionScript Code-Formatierung hinzu. - Added after 3.3.1 + Adds multiple code formatters to FlashDevelop. + Modifed after 5.1.0 Code-&Formatierung @@ -5988,6 +5988,14 @@ Eigene Sprachumgebungen müssen eine Erweiterung der Standard-Sprachumgebung sei Search: (Start the filter with * to view custom only, and ? to view conflicts only.) Added after 5.0.2 + + Manual options for the CPP language, read more: http://astyle.sourceforge.net/astyle.html + Added after 5.1.0 + + + Manual options for other C like languages, read more: http://astyle.sourceforge.net/astyle.html + Added after 5.1.0 + Connection failed. Default socket port '{0}' is already in use. Added after 5.1.0 diff --git a/PluginCore/PluginCore/Resources/en_US.resX b/PluginCore/PluginCore/Resources/en_US.resX index c304655b4e..f4e3202156 100644 --- a/PluginCore/PluginCore/Resources/en_US.resX +++ b/PluginCore/PluginCore/Resources/en_US.resX @@ -4459,8 +4459,8 @@ Custom locales must be an extension of a default locale, e.g. en-US. Added after 3.3.1 - Adds an MXML and ActionScript code formatter to FlashDevelop. - Added after 3.3.1 + Adds multiple code formatters to FlashDevelop. + Modified after 5.1.0 Code &Formatter @@ -6002,6 +6002,14 @@ Custom locales must be an extension of a default locale, e.g. en-US. Search: (Start the filter with * to view custom only, and ? to view conflicts only.) Added after 5.0.2 + + Manual options for the CPP language, read more: http://astyle.sourceforge.net/astyle.html + Added after 5.1.0 + + + Manual options for other C like languages, read more: http://astyle.sourceforge.net/astyle.html + Added after 5.1.0 + Connection failed. Default socket port '{0}' is already in use. Added after 5.1.0 diff --git a/PluginCore/PluginCore/Resources/eu_ES.resX b/PluginCore/PluginCore/Resources/eu_ES.resX index 4ef865d6ed..cfb6f6a00c 100644 --- a/PluginCore/PluginCore/Resources/eu_ES.resX +++ b/PluginCore/PluginCore/Resources/eu_ES.resX @@ -4439,8 +4439,8 @@ Lokalizazio pertsonalizatuek lehenetsiaren luzapen bat izan behar dute, adb. en- Added after 3.3.1 - MXML eta ActionScript kode formateatzaile bat gehitzen dio FlashDevelop-i. - Added after 3.3.1 + Adds multiple code formatters to FlashDevelop. + Modifed after 5.1.0 Kode &Formateatzailea @@ -5985,6 +5985,14 @@ Lokalizazio pertsonalizatuek lehenetsiaren luzapen bat izan behar dute, adb. en- Search: (Start the filter with * to view custom only, and ? to view conflicts only.) Added after 5.0.2 + + Manual options for the CPP language, read more: http://astyle.sourceforge.net/astyle.html + Added after 5.1.0 + + + Manual options for other C like languages, read more: http://astyle.sourceforge.net/astyle.html + Added after 5.1.0 + Connection failed. Default socket port '{0}' is already in use. Added after 5.1.0 diff --git a/PluginCore/PluginCore/Resources/ja_JP.resX b/PluginCore/PluginCore/Resources/ja_JP.resX index e6cbb8ef23..36ef46e355 100644 --- a/PluginCore/PluginCore/Resources/ja_JP.resX +++ b/PluginCore/PluginCore/Resources/ja_JP.resX @@ -4465,8 +4465,8 @@ AfterSimilarAccessorMethod: 同様のアクセサメソッドの後に配置。" Added after 3.3.1 - FlashDevelop に MXML と ActionScript のコードフォーマッターを追加します。 - Added after 3.3.1 + Adds multiple code formatters to FlashDevelop. + Modifed after 5.1.0 コードの整形(&F) @@ -6046,6 +6046,14 @@ UseData:" Search: (Start the filter with * to view custom only, and ? to view conflicts only.) Added after 5.0.2 + + Manual options for the CPP language, read more: http://astyle.sourceforge.net/astyle.html + Added after 5.1.0 + + + Manual options for other C like languages, read more: http://astyle.sourceforge.net/astyle.html + Added after 5.1.0 + Connection failed. Default socket port '{0}' is already in use. Added after 5.1.0 diff --git a/PluginCore/PluginCore/Resources/ko_KR.resX b/PluginCore/PluginCore/Resources/ko_KR.resX index e4fe4d1dca..2733fd3f58 100644 --- a/PluginCore/PluginCore/Resources/ko_KR.resX +++ b/PluginCore/PluginCore/Resources/ko_KR.resX @@ -4460,8 +4460,8 @@ Never - 시작 페이지는 프로그램 시작시 열리지 않습니다.Added after 3.3.1 - FlashDevelop에 MXML 및 ActionScript 코드 포맷터를 추가합니다. - Added after 3.3.1 + Adds multiple code formatters to FlashDevelop. + Modifed after 5.1.0 코드 포맷터 (&F) @@ -6005,6 +6005,14 @@ Complete: 현재 파일, 프로젝트 파일 및 수동 새로 고침. 검색: (필터를 *로 시작하면 수정된 항목만, ?로 시작하면 충돌하는 항목만 검색할 수 있습니다.) Added after 5.0.2 + + Manual options for the CPP language, read more: http://astyle.sourceforge.net/astyle.html + Added after 5.1.0 + + + Manual options for other C like languages, read more: http://astyle.sourceforge.net/astyle.html + Added after 5.1.0 + Connection failed. Default socket port '{0}' is already in use. Added after 5.1.0 diff --git a/PluginCore/PluginCore/Resources/zh_CN.resx b/PluginCore/PluginCore/Resources/zh_CN.resx index 634dfb24c8..6d71ae2ece 100644 --- a/PluginCore/PluginCore/Resources/zh_CN.resx +++ b/PluginCore/PluginCore/Resources/zh_CN.resx @@ -4448,8 +4448,8 @@ Added after 3.3.1 - 向 FlashDevelop 添加一个 MXML 和 ActionScript 代码格式. - Added after 3.3.1 + Adds multiple code formatters to FlashDevelop. + Modifed after 5.1.0 代码格式化(&F) @@ -5998,6 +5998,14 @@ Search: (Start the filter with * to view custom only, and ? to view conflicts only.) Added after 5.0.2 + + Manual options for the CPP language, read more: http://astyle.sourceforge.net/astyle.html + Added after 5.1.0 + + + Manual options for other C like languages, read more: http://astyle.sourceforge.net/astyle.html + Added after 5.1.0 + Connection failed. Default socket port '{0}' is already in use. Added after 5.1.0 diff --git a/PluginCore/ScintillaNet/ScintillaControl.cs b/PluginCore/ScintillaNet/ScintillaControl.cs index 76683f7e34..c5d03f61c9 100644 --- a/PluginCore/ScintillaNet/ScintillaControl.cs +++ b/PluginCore/ScintillaNet/ScintillaControl.cs @@ -229,8 +229,7 @@ private void RemoveScrollBars(ScintillaControl sender) #region Scintilla Main - public ScintillaControl() - : this(IntPtr.Size == 4 ? "SciLexer.dll" : "SciLexer64.dll") + public ScintillaControl() : this(IntPtr.Size == 4 ? "SciLexer.dll" : "SciLexer64.dll") { if (Win32.ShouldUseWin32()) DragAcceptFiles(this.Handle, 1); } @@ -245,19 +244,13 @@ public ScintillaControl(string fullpath) hwndScintilla = CreateWindowEx(0, "Scintilla", "", WS_CHILD_VISIBLE_TABSTOP, 0, 0, this.Width, this.Height, this.Handle, 0, new IntPtr(0), null); directPointer = (IntPtr)SlowPerform(2185, 0, 0); IntPtr sciFunctionPointer = GetProcAddress(new HandleRef(null, lib), "Scintilla_DirectFunction"); - if (sciFunctionPointer == IntPtr.Zero) - sciFunctionPointer = GetProcAddress(new HandleRef(null, lib), "_Scintilla_DirectFunction@16"); - + if (sciFunctionPointer == IntPtr.Zero) sciFunctionPointer = GetProcAddress(new HandleRef(null, lib), "_Scintilla_DirectFunction@16"); if (sciFunctionPointer == IntPtr.Zero) { string msg = "The Scintilla module has no export for the 'Scintilla_DirectFunction' procedure."; throw new Win32Exception(msg, new Win32Exception(Marshal.GetLastWin32Error())); } - - _sciFunction = (Perform)Marshal.GetDelegateForFunctionPointer( - sciFunctionPointer, - typeof(Perform)); - + _sciFunction = (Perform)Marshal.GetDelegateForFunctionPointer(sciFunctionPointer, typeof(Perform)); directPointer = DirectPointer; } UpdateUI += new UpdateUIHandler(OnUpdateUI); @@ -5296,11 +5289,7 @@ public ShortcutOverride(Keys keys, Action action) [DllImport("shell32.dll")] public static extern void DragAcceptFiles(IntPtr hwnd, int accept); - public delegate IntPtr Perform( - IntPtr sci, - int iMessage, - IntPtr wParam, - IntPtr lParam); + public delegate IntPtr Perform(IntPtr sci, int iMessage, IntPtr wParam, IntPtr lParam); public UInt32 SlowPerform(UInt32 message, UInt32 wParam, UInt32 lParam) {