diff --git a/plugins/astyle/3rdparty/libastyle/ASBeautifier.cpp b/plugins/astyle/3rdparty/libastyle/ASBeautifier.cpp index 176cd7be0e..10317ddf49 100644 --- a/plugins/astyle/3rdparty/libastyle/ASBeautifier.cpp +++ b/plugins/astyle/3rdparty/libastyle/ASBeautifier.cpp @@ -1,3674 +1,3744 @@ // ASBeautifier.cpp -// Copyright (c) 2016 by Jim Pattee . +// Copyright (c) 2018 by Jim Pattee . // This code is licensed under the MIT License. -// License.txt describes the conditions under which this software may be distributed. +// License.md 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; +static int g_preprocessorCppExternCBrace; //----------------------------------------------------------------------------- // 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; + waitingBeautifierStack = nullptr; + activeBeautifierStack = nullptr; + waitingBeautifierStackLengthStack = nullptr; + activeBeautifierStackLengthStack = nullptr; + + headerStack = nullptr; + tempStacks = nullptr; + parenDepthStack = nullptr; + blockStatementStack = nullptr; + parenStatementStack = nullptr; + braceBlockStateStack = nullptr; + continuationIndentStack = nullptr; + continuationIndentStackSizeStack = nullptr; + parenIndentStack = nullptr; + preprocIndentStack = nullptr; + sourceIterator = nullptr; isModeManuallySet = false; shouldForceTabIndentation = false; setSpaceIndentation(4); setContinuationIndentation(1); setMinConditionalIndentOption(MINCOND_TWO); - setMaxInStatementIndentLength(40); + setMaxContinuationIndentLength(40); classInitializerIndents = 1; tabLength = 0; setClassIndent(false); setModifierIndent(false); setSwitchIndent(false); setCaseIndent(false); setBlockIndent(false); - setBracketIndent(false); - setBracketIndentVtk(false); + setBraceIndent(false); + setBraceIndentVtk(false); setNamespaceIndent(false); + setAfterParenIndent(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; + waitingBeautifierStack = nullptr; + activeBeautifierStack = nullptr; + waitingBeautifierStackLengthStack = nullptr; + activeBeautifierStackLengthStack = nullptr; // 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; + parenDepthStack = new vector; + *parenDepthStack = *other.parenDepthStack; blockStatementStack = new vector; *blockStatementStack = *other.blockStatementStack; parenStatementStack = new vector; *parenStatementStack = *other.parenStatementStack; - bracketBlockStateStack = new vector; - *bracketBlockStateStack = *other.bracketBlockStateStack; + braceBlockStateStack = new vector; + *braceBlockStateStack = *other.braceBlockStateStack; - inStatementIndentStack = new vector; - *inStatementIndentStack = *other.inStatementIndentStack; + continuationIndentStack = new vector; + *continuationIndentStack = *other.continuationIndentStack; - inStatementIndentStackSizeStack = new vector; - *inStatementIndentStackSizeStack = *other.inStatementIndentStackSizeStack; + continuationIndentStackSizeStack = new vector; + *continuationIndentStackSizeStack = *other.continuationIndentStackSizeStack; 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; + runInIndentContinuation = other.runInIndentContinuation; + nonInStatementBrace = other.nonInStatementBrace; 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; + isInRunInComment = other.isInRunInComment; isInCase = other.isInCase; isInQuestion = other.isInQuestion; - isInStatement = other.isInStatement; + isContinuation = other.isContinuation; 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; isInObjCMethodCall = other.isInObjCMethodCall; isInObjCMethodCallFirst = other.isInObjCMethodCallFirst; isImmediatelyPostObjCMethodDefinition = other.isImmediatelyPostObjCMethodDefinition; isImmediatelyPostObjCMethodCall = other.isImmediatelyPostObjCMethodCall; isInIndentablePreprocBlock = other.isInIndentablePreprocBlock; isInObjCInterface = other.isInObjCInterface; isInEnum = other.isInEnum; isInEnumTypeID = other.isInEnumTypeID; isInLet = other.isInLet; + isInTrailingReturnType = other.isInTrailingReturnType; modifierIndent = other.modifierIndent; switchIndent = other.switchIndent; caseIndent = other.caseIndent; namespaceIndent = other.namespaceIndent; - bracketIndent = other.bracketIndent; - bracketIndentVtk = other.bracketIndentVtk; + braceIndent = other.braceIndent; + braceIndentVtk = other.braceIndentVtk; blockIndent = other.blockIndent; + shouldIndentAfterParen = other.shouldIndentAfterParen; 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; + lineBeginsWithOpenBrace = other.lineBeginsWithOpenBrace; + lineBeginsWithCloseBrace = other.lineBeginsWithCloseBrace; lineBeginsWithComma = other.lineBeginsWithComma; lineIsCommentOnly = other.lineIsCommentOnly; lineIsLineCommentOnly = other.lineIsLineCommentOnly; - shouldIndentBrackettedLine = other.shouldIndentBrackettedLine; + shouldIndentBracedLine = other.shouldIndentBracedLine; isInSwitch = other.isInSwitch; foundPreCommandHeader = other.foundPreCommandHeader; foundPreCommandMacro = other.foundPreCommandMacro; shouldAlignMethodColon = other.shouldAlignMethodColon; shouldIndentPreprocDefine = other.shouldIndentPreprocDefine; shouldIndentPreprocConditional = other.shouldIndentPreprocConditional; indentCount = other.indentCount; spaceIndentCount = other.spaceIndentCount; spaceIndentObjCMethodAlignment = other.spaceIndentObjCMethodAlignment; - bracketPosObjCMethodAlignment = other.bracketPosObjCMethodAlignment; + bracePosObjCMethodAlignment = other.bracePosObjCMethodAlignment; colonIndentObjCMethodAlignment = other.colonIndentObjCMethodAlignment; lineOpeningBlocksNum = other.lineOpeningBlocksNum; lineClosingBlocksNum = other.lineClosingBlocksNum; fileType = other.fileType; minConditionalOption = other.minConditionalOption; minConditionalIndent = other.minConditionalIndent; parenDepth = other.parenDepth; indentLength = other.indentLength; tabLength = other.tabLength; continuationIndent = other.continuationIndent; blockTabCount = other.blockTabCount; - maxInStatementIndent = other.maxInStatementIndent; + maxContinuationIndent = other.maxContinuationIndent; classInitializerIndents = other.classInitializerIndents; templateDepth = other.templateDepth; - blockParenCount = other.blockParenCount; + 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(parenDepthStack); deleteContainer(blockStatementStack); deleteContainer(parenStatementStack); - deleteContainer(bracketBlockStateStack); - deleteContainer(inStatementIndentStack); - deleteContainer(inStatementIndentStackSizeStack); + deleteContainer(braceBlockStateStack); + deleteContainer(continuationIndentStack); + deleteContainer(continuationIndentStackSizeStack); 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; + g_preprocessorCppExternCBrace = 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); + tempStacks->emplace_back(new vector); - initContainer(blockParenDepthStack, new vector); + initContainer(parenDepthStack, 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(braceBlockStateStack, new vector); + braceBlockStateStack->push_back(true); + initContainer(continuationIndentStack, new vector); + initContainer(continuationIndentStackSizeStack, new vector); + continuationIndentStackSizeStack->emplace_back(0); initContainer(parenIndentStack, new vector); initContainer(preprocIndentStack, new vector >); - previousLastLineHeader = NULL; - currentHeader = NULL; + previousLastLineHeader = nullptr; + currentHeader = nullptr; isInQuote = false; isInVerbatimQuote = false; haveLineContinuationChar = false; isInAsm = false; isInAsmOneLine = false; isInAsmBlock = false; isInComment = false; isInPreprocessorComment = false; - isInHorstmannComment = false; - isInStatement = false; + isInRunInComment = false; + isContinuation = false; isInCase = false; isInQuestion = false; isIndentModeOff = false; isInClassHeader = false; isInClassHeaderTab = false; isInClassInitializer = false; isInClass = false; isInObjCMethodDefinition = false; isInObjCMethodCall = false; isInObjCMethodCallFirst = false; isImmediatelyPostObjCMethodDefinition = false; isImmediatelyPostObjCMethodCall = false; isInIndentablePreprocBlock = false; isInObjCInterface = false; isInEnum = false; isInEnumTypeID = false; isInLet = false; isInHeader = false; isInTemplate = false; isInConditional = false; + isInTrailingReturnType = false; indentCount = 0; spaceIndentCount = 0; spaceIndentObjCMethodAlignment = 0; - bracketPosObjCMethodAlignment = 0; + bracePosObjCMethodAlignment = 0; colonIndentObjCMethodAlignment = 0; lineOpeningBlocksNum = 0; lineClosingBlocksNum = 0; templateDepth = 0; - blockParenCount = 0; + squareBracketCount = 0; parenDepth = 0; blockTabCount = 0; prevFinalLineSpaceIndentCount = 0; prevFinalLineIndentCount = 0; defineIndentCount = 0; preprocBlockIndent = 0; prevNonSpaceCh = '{'; currentNonSpaceCh = '{'; prevNonLegalCh = '{'; currentNonLegalCh = '{'; quoteChar = ' '; - probationHeader = NULL; - lastLineHeader = NULL; + probationHeader = nullptr; + lastLineHeader = nullptr; 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; + lineBeginsWithOpenBrace = false; + lineBeginsWithCloseBrace = false; lineBeginsWithComma = false; lineIsCommentOnly = false; lineIsLineCommentOnly = false; - shouldIndentBrackettedLine = true; + shouldIndentBracedLine = 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; + runInIndentContinuation = 0; + nonInStatementBrace = 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; } /** * indent continuation lines using a number of indents. * * @param indent number of indents per line. */ void ASBeautifier::setContinuationIndentation(int indent) { continuationIndent = indent; } /** * set the maximum indentation between two lines in a multi-line statement. * * @param max maximum indentation length. */ +void ASBeautifier::setMaxContinuationIndentLength(int max) +{ + maxContinuationIndent = max; +} + +// retained for compatibility with release 2.06 +// "MaxInStatementIndent" has been changed to "MaxContinuationIndent" in 3.0 +// it is referenced only by the old "MaxInStatementIndent" options void ASBeautifier::setMaxInStatementIndentLength(int max) { - maxInStatementIndent = max; + setMaxContinuationIndentLength(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 + * set the state of the brace indent option. If true, braces will * be indented one additional indent. * * @param state state of option. */ -void ASBeautifier::setBracketIndent(bool state) +void ASBeautifier::setBraceIndent(bool state) { - bracketIndent = state; + braceIndent = state; } /** -* set the state of the bracket indent VTK option. If true, brackets will -* be indented one additional indent, except for the opening bracket. +* set the state of the brace indent VTK option. If true, braces will +* be indented one additional indent, except for the opening brace. * * @param state state of option. */ -void ASBeautifier::setBracketIndentVtk(bool state) +void ASBeautifier::setBraceIndentVtk(bool state) { // need to set both of these - setBracketIndent(state); - bracketIndentVtk = state; + setBraceIndent(state); + braceIndentVtk = 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 indent after parens option. +* +* @param state state of option. +*/ +void ASBeautifier::setAfterParenIndent(bool state) +{ + shouldIndentAfterParen = 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() const { return indentLength; } /** * get the char used for indentation, space or tab * * @return the char used for indentation. */ string ASBeautifier::getIndentString() 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() const { return shouldForceTabIndentation; } /** * Get the state of the Objective-C align method colon option. * * @return state of shouldAlignMethodColon option. */ bool ASBeautifier::getAlignMethodColon() const { return shouldAlignMethodColon; } /** * get the state of the block indentation option. * * @return state of blockIndent option. */ bool ASBeautifier::getBlockIndent() const { return blockIndent; } /** - * get the state of the bracket indentation option. + * get the state of the brace indentation option. * - * @return state of bracketIndent option. + * @return state of braceIndent option. */ -bool ASBeautifier::getBracketIndent() const +bool ASBeautifier::getBraceIndent() const { - return bracketIndent; + return braceIndent; } /** * 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() 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() 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() 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() 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() 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() 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() const { return shouldIndentPreprocDefine; } /** * get the length of the tab indentation option. * * @return length of tab indent option. */ int ASBeautifier::getTabLength() 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; + currentHeader = nullptr; + lastLineHeader = nullptr; blockCommentNoBeautify = blockCommentNoIndent; isInClass = false; isInSwitch = false; - lineBeginsWithOpenBracket = false; - lineBeginsWithCloseBracket = false; + lineBeginsWithOpenBrace = false; + lineBeginsWithCloseBrace = false; lineBeginsWithComma = false; lineIsCommentOnly = false; lineIsLineCommentOnly = false; - shouldIndentBrackettedLine = true; + shouldIndentBracedLine = true; isInAsmOneLine = false; lineOpensWithLineComment = false; lineOpensWithComment = false; lineStartsInComment = isInComment; previousLineProbationTab = false; lineOpeningBlocksNum = 0; lineClosingBlocksNum = 0; if (isImmediatelyPostObjCMethodDefinition) clearObjCMethodDefinitionAlignment(); if (isImmediatelyPostObjCMethodCall) { isImmediatelyPostObjCMethodCall = false; isInObjCMethodCall = false; objCColonAlignSubsequent = 0; } // 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 + // does a brace open the line size_t firstChar = line.find_first_not_of(" \t"); if (firstChar != string::npos) { if (line[firstChar] == '{') - lineBeginsWithOpenBracket = true; + lineBeginsWithOpenBrace = true; else if (line[firstChar] == '}') - lineBeginsWithCloseBracket = true; + lineBeginsWithCloseBrace = true; else if (line[firstChar] == ',') lineBeginsWithComma = true; } } else { line = trim(originalLine); if (line.length() > 0) { if (line[0] == '{') - lineBeginsWithOpenBracket = true; + lineBeginsWithOpenBrace = true; else if (line[0] == '}') - lineBeginsWithCloseBracket = true; + lineBeginsWithCloseBrace = 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; + isInRunInComment = 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; + isInRunInComment = 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; + // check if this line ends a multi-line #define + // if so, remove the #define's cloned beautifier from the active + // beautifier stack and delete it. + if (isInDefineDefinition && !isInDefine) + { + isInDefineDefinition = false; + if (!activeBeautifierStack->empty()) + { + ASBeautifier* defineBeautifier = activeBeautifierStack->back(); + activeBeautifierStack->pop_back(); + delete defineBeautifier; + } + } } if (emptyLineFill && !isInQuoteContinuation) { if (isInIndentablePreprocBlock) return preLineWS(preprocBlockIndent, 0); 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); } 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") { indentedLine = preLineWS(preprocBlockIndent - 1, 0) + line; } else if (preproc == "endif") { 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()) + if (!isInDefine && activeBeautifierStack != nullptr && !activeBeautifierStack->empty()) entry = activeBeautifierStack->back()->computePreprocessorIndent(); else entry = computePreprocessorIndent(); - preprocIndentStack->push_back(entry); + preprocIndentStack->emplace_back(entry); indentedLine = preLineWS(preprocIndentStack->back().first, preprocIndentStack->back().second) + line; return getIndentedLineReturn(indentedLine, originalLine); } if (preproc == "else" || preproc == "elif") { if (!preprocIndentStack->empty()) // if no entry don't indent { indentedLine = preLineWS(preprocIndentStack->back().first, preprocIndentStack->back().second) + line; return getIndentedLineReturn(indentedLine, originalLine); } } else if (preproc == "endif") { if (!preprocIndentStack->empty()) // 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; + // this could happen with invalid input + if (activeBeautifierStack->empty()) + return originalLine; 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()) + if (!isInDefine && activeBeautifierStack != nullptr && !activeBeautifierStack->empty()) { activeBeautifierStack->back()->inLineNumber = inLineNumber; - activeBeautifierStack->back()->horstmannIndentInStatement = horstmannIndentInStatement; - activeBeautifierStack->back()->nonInStatementBracket = nonInStatementBracket; + activeBeautifierStack->back()->runInIndentContinuation = runInIndentContinuation; + activeBeautifierStack->back()->nonInStatementBrace = nonInStatementBrace; 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)) + && lineBeginsWithOpenBrace + && (headerStack->back() != &AS_OPEN_BRACE + || probationHeader != nullptr)) 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); if (isInObjCMethodDefinition) adjustObjCMethodDefinitionIndentation(line); if (isInObjCMethodCall) adjustObjCMethodCallIndentation(line); 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) + if (!continuationIndentStack->empty() + && continuationIndentStack->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) + if (lastLineHeader != nullptr) 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 +const string& ASBeautifier::getIndentedLineReturn(const string& newLine, const string& originalLine) const { if (isIndentModeOff) - return const_cast(originalLine); + return 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. + * register a continuation indent. */ -void ASBeautifier::registerInStatementIndent(const string& line, int i, int spaceIndentCount_, - int tabIncrementIn, int minIndent, bool updateParenStack) +void ASBeautifier::registerContinuationIndent(const string& line, int i, int spaceIndentCount_, + int tabIncrementIn, int minIndent, bool updateParenStack) { + assert(i >= -1); int remainingCharNum = line.length() - i; int nextNonWSChar = getNextProgramCharDistance(line, i); - // if indent is around the last char in the line, indent with the continuation indent - if (nextNonWSChar == remainingCharNum) + // if indent is around the last char in the line OR indent-after-paren is requested, + // indent with the continuation indent + if (nextNonWSChar == remainingCharNum || shouldIndentAfterParen) { int previousIndent = spaceIndentCount_; - if (!inStatementIndentStack->empty()) - previousIndent = inStatementIndentStack->back(); + if (!continuationIndentStack->empty()) + previousIndent = continuationIndentStack->back(); int currIndent = continuationIndent * indentLength + previousIndent; - if (currIndent > maxInStatementIndent - && line[i] != '{') + if (currIndent > maxContinuationIndent && line[i] != '{') currIndent = indentLength * 2 + spaceIndentCount_; - inStatementIndentStack->push_back(currIndent); + continuationIndentStack->emplace_back(currIndent); if (updateParenStack) - parenIndentStack->push_back(previousIndent); + parenIndentStack->emplace_back(previousIndent); return; } if (updateParenStack) - parenIndentStack->push_back(i + spaceIndentCount_ - horstmannIndentInStatement); + { + parenIndentStack->emplace_back(i + spaceIndentCount_ - runInIndentContinuation); + if (parenIndentStack->back() < 0) + parenIndentStack->back() = 0; + } 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 + spaceIndentCount_ + tabIncrement; + int continuationIndentCount = i + nextNonWSChar + spaceIndentCount_ + tabIncrement; // check for run-in statement if (i > 0 && line[0] == '{') - inStatementIndent -= indentLength; + continuationIndentCount -= indentLength; - if (inStatementIndent < minIndent) - inStatementIndent = minIndent + spaceIndentCount_; + if (continuationIndentCount < minIndent) + continuationIndentCount = minIndent + spaceIndentCount_; // this is not done for an in-statement array - if (inStatementIndent > maxInStatementIndent + if (continuationIndentCount > maxContinuationIndent && !(prevNonLegalCh == '=' && currentNonLegalCh == '{')) - inStatementIndent = indentLength * 2 + spaceIndentCount_; + continuationIndentCount = indentLength * 2 + spaceIndentCount_; - if (!inStatementIndentStack->empty() - && inStatementIndent < inStatementIndentStack->back()) - inStatementIndent = inStatementIndentStack->back(); + if (!continuationIndentStack->empty() + && continuationIndentCount < continuationIndentStack->back()) + continuationIndentCount = continuationIndentStack->back(); // the block opener is not indented for a NonInStatementArray - if (isNonInStatementArray && !isInEnum && !bracketBlockStateStack->empty() && bracketBlockStateStack->back()) - inStatementIndent = 0; + if ((isNonInStatementArray && i >= 0 && line[i] == '{') + && !isInEnum && !braceBlockStateStack->empty() && braceBlockStateStack->back()) + continuationIndentCount = 0; - inStatementIndentStack->push_back(inStatementIndent); + continuationIndentStack->emplace_back(continuationIndentCount); } /** -* Register an in-statement indent for a class header or a class initializer colon. +* Register a continuation indent for a class header or a class initializer colon. */ -void ASBeautifier::registerInStatementIndentColon(const string& line, int i, int tabIncrementIn) +void ASBeautifier::registerContinuationIndentColon(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) + if (firstWord != string::npos) { - int inStatementIndent = firstWord + spaceIndentCount + tabIncrementIn; - inStatementIndentStack->push_back(inStatementIndent); - isInStatement = true; + int continuationIndentCount = firstWord + spaceIndentCount + tabIncrementIn; + continuationIndentStack->emplace_back(continuationIndentCount); + isContinuation = 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; 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 +int ASBeautifier::indexOf(const vector& container, const string* element) const { vector::const_iterator where; where = find(container.begin(), container.end(), element); if (where == container.end()) return -1; 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); + tempStacksNew->emplace_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) + if (container != nullptr) { container->clear(); delete (container); - container = NULL; + container = nullptr; } } /** * 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) + if (container != nullptr) { vector::iterator iter = container->begin(); while (iter < container->end()) { delete *iter; ++iter; } container->clear(); delete (container); - container = NULL; + container = nullptr; } } /** * 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) + if (container != nullptr) { vector*>::iterator iter = container->begin(); while (iter < container->end()) { delete *iter; ++iter; } container->clear(); delete (container); - container = NULL; + container = nullptr; } } /** * 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) + if (container != nullptr) 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) + if (container != nullptr) 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 +int ASBeautifier::getContinuationIndentAssign(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] == '.') + if (!isLegalNameChar(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 +int ASBeautifier::getContinuationIndentComma(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) + if (charNum != string::npos && preproc.compare(charNum, 7, "defined") == 0) { charNum += 7; charNum = preproc.find_first_not_of(" \t", charNum); - if (preproc.compare(charNum, 1, "(") == 0) + if (charNum != string::npos && preproc.compare(charNum, 1, "(") == 0) { ++charNum; charNum = preproc.find_first_not_of(" \t", charNum); - if (preproc.compare(charNum, 11, "__cplusplus") == 0) + if (charNum != string::npos && 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() +void ASBeautifier::popLastContinuationIndent() { - assert(!inStatementIndentStackSizeStack->empty()); - int previousIndentStackSize = inStatementIndentStackSizeStack->back(); - if (inStatementIndentStackSizeStack->size() > 1) - inStatementIndentStackSizeStack->pop_back(); - while (previousIndentStackSize < (int) inStatementIndentStack->size()) - inStatementIndentStack->pop_back(); + assert(!continuationIndentStackSizeStack->empty()); + int previousIndentStackSize = continuationIndentStackSizeStack->back(); + if (continuationIndentStackSizeStack->size() > 1) + continuationIndentStackSizeStack->pop_back(); + while (previousIndentStackSize < (int) continuationIndentStack->size()) + continuationIndentStack->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); + activeBeautifierStack->emplace_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; + if (isPreprocessorConditionalCplusplus(line) && !g_preprocessorCppExternCBrace) + g_preprocessorCppExternCBrace = 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)); + waitingBeautifierStack->emplace_back(new ASBeautifier(*this)); else - waitingBeautifierStack->push_back(new ASBeautifier(*activeBeautifierStack->back())); + waitingBeautifierStack->emplace_back(new ASBeautifier(*activeBeautifierStack->back())); } else if (preproc == "else") { - if (waitingBeautifierStack && !waitingBeautifierStack->empty()) + if ((waitingBeautifierStack != nullptr) && !waitingBeautifierStack->empty()) { // MOVE current waiting beautifier to active stack. - activeBeautifierStack->push_back(waitingBeautifierStack->back()); + activeBeautifierStack->emplace_back(waitingBeautifierStack->back()); waitingBeautifierStack->pop_back(); } } else if (preproc == "elif") { - if (waitingBeautifierStack && !waitingBeautifierStack->empty()) + if ((waitingBeautifierStack != nullptr) && !waitingBeautifierStack->empty()) { // append a COPY current waiting beautifier to active stack, WITHOUT deleting the original. - activeBeautifierStack->push_back(new ASBeautifier(*(waitingBeautifierStack->back()))); + activeBeautifierStack->emplace_back(new ASBeautifier(*(waitingBeautifierStack->back()))); } } else if (preproc == "endif") { int stackLength = 0; - ASBeautifier* beautifier = NULL; + ASBeautifier* beautifier = nullptr; - if (waitingBeautifierStackLengthStack != NULL && !waitingBeautifierStackLengthStack->empty()) + if (waitingBeautifierStackLengthStack != nullptr && !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()) - spaceIndentObjCMethodAlignment = inStatementIndentStack->back(); + if (isInObjCMethodDefinition && !continuationIndentStack->empty()) + spaceIndentObjCMethodAlignment = continuationIndentStack->back(); - if (!inStatementIndentStack->empty()) - spaceIndentCount = inStatementIndentStack->back(); + if (!continuationIndentStack->empty()) + spaceIndentCount = continuationIndentStack->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_MODULE || (*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)) + else if (!(i > 0 && (*headerStack)[i - 1] != &AS_OPEN_BRACE + && (*headerStack)[i] == &AS_OPEN_BRACE)) ++indentCount; if (!isJavaStyle() && !namespaceIndent && i > 0 && ((*headerStack)[i - 1] == &AS_NAMESPACE || (*headerStack)[i - 1] == &AS_MODULE) - && (*headerStack)[i] == &AS_OPEN_BRACKET) + && (*headerStack)[i] == &AS_OPEN_BRACE) --indentCount; if (isCStyle() && i >= 1 && (*headerStack)[i - 1] == &AS_CLASS - && (*headerStack)[i] == &AS_OPEN_BRACKET) + && (*headerStack)[i] == &AS_OPEN_BRACE) { 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) + && (*headerStack)[i] == &AS_OPEN_BRACE) { ++indentCount; isInSwitch = true; } } // end of for loop if (isInClassHeader) { if (!isJavaStyle()) isInClassHeaderTab = true; if (lineOpensWithLineComment || lineStartsInComment || lineOpensWithComment) { - if (!lineBeginsWithOpenBracket) + if (!lineBeginsWithOpenBrace) --indentCount; - if (!inStatementIndentStack->empty()) - spaceIndentCount -= inStatementIndentStack->back(); + if (!continuationIndentStack->empty()) + spaceIndentCount -= continuationIndentStack->back(); } else if (blockIndent) { - if (!lineBeginsWithOpenBracket) + if (!lineBeginsWithOpenBrace) ++indentCount; } } if (isInClassInitializer || isInEnumTypeID) { indentCount += classInitializerIndents; } - if (isInEnum && lineBeginsWithComma && !inStatementIndentStack->empty()) + if (isInEnum && lineBeginsWithComma && !continuationIndentStack->empty()) { // unregister '=' indent from the previous line - inStatementIndentStack->pop_back(); - isInStatement = false; + continuationIndentStack->pop_back(); + isContinuation = false; spaceIndentCount = 0; } // Objective-C interface continuation line if (isInObjCInterface) ++indentCount; - // unindent a class closing bracket... + // unindent a class closing brace... if (!lineStartsInComment && isCStyle() && isInClass && classIndent && headerStack->size() >= 2 && (*headerStack)[headerStack->size() - 2] == &AS_CLASS - && (*headerStack)[headerStack->size() - 1] == &AS_OPEN_BRACKET - && lineBeginsWithCloseBracket - && bracketBlockStateStack->back()) + && (*headerStack)[headerStack->size() - 1] == &AS_OPEN_BRACE + && lineBeginsWithCloseBrace + && braceBlockStateStack->back()) --indentCount; - // unindent an indented switch closing bracket... + // unindent an indented switch closing brace... else if (!lineStartsInComment && isInSwitch && switchIndent && headerStack->size() >= 2 && (*headerStack)[headerStack->size() - 2] == &AS_SWITCH - && (*headerStack)[headerStack->size() - 1] == &AS_OPEN_BRACKET - && lineBeginsWithCloseBracket) + && (*headerStack)[headerStack->size() - 1] == &AS_OPEN_BRACE + && lineBeginsWithCloseBrace) --indentCount; - // handle special case of horstmann comment in an indented class statement + // handle special case of run-in comment in an indented class statement if (isInClass && classIndent - && isInHorstmannComment + && isInRunInComment && !lineOpensWithComment && headerStack->size() > 1 && (*headerStack)[headerStack->size() - 2] == &AS_CLASS) --indentCount; if (isInConditional) --indentCount; - if (g_preprocessorCppExternCBracket >= 4) + if (g_preprocessorCppExternCBrace >= 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 + && lineBeginsWithOpenBrace && headerStack->size() < iPrelim && isInExtraHeaderIndent && (lineOpeningBlocksNum > 0 && lineOpeningBlocksNum <= lineClosingBlocksNum) - && shouldIndentBrackettedLine) + && shouldIndentBracedLine) --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 + && lineBeginsWithOpenBrace && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum <= lineClosingBlocksNum) - && (headerStack->size() > 1 && (*headerStack)[headerStack->size() - 2] != &AS_OPEN_BRACKET) - && shouldIndentBrackettedLine) + && (headerStack->size() > 1 && (*headerStack)[headerStack->size() - 2] != &AS_OPEN_BRACE) + && shouldIndentBracedLine) --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 + && lineBeginsWithOpenBrace && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum <= lineClosingBlocksNum) - && (headerStack->size() > 2 && (*headerStack)[headerStack->size() - 3] != &AS_OPEN_BRACKET) - && shouldIndentBrackettedLine) + && (headerStack->size() > 2 && (*headerStack)[headerStack->size() - 3] != &AS_OPEN_BRACE) + && shouldIndentBracedLine) --indentCount; - // unindent a closing bracket... - else if (lineBeginsWithCloseBracket - && shouldIndentBrackettedLine) + // unindent a closing brace... + else if (lineBeginsWithCloseBrace + && shouldIndentBracedLine) --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... + // take care of extra brace indentation option... if (!lineStartsInComment - && bracketIndent - && shouldIndentBrackettedLine - && (lineBeginsWithOpenBracket || lineBeginsWithCloseBracket)) + && braceIndent + && shouldIndentBracedLine + && (lineBeginsWithOpenBrace || lineBeginsWithCloseBrace)) { - if (!bracketIndentVtk) + if (!braceIndentVtk) ++indentCount; else { - // determine if a style VTK bracket is indented - bool haveUnindentedBracket = false; + // determine if a style VTK brace is indented + bool haveUnindentedBrace = false; for (size_t i = 0; i < headerStack->size(); i++) { if (((*headerStack)[i] == &AS_NAMESPACE || (*headerStack)[i] == &AS_MODULE || (*headerStack)[i] == &AS_CLASS || (*headerStack)[i] == &AS_STRUCT) && i + 1 < headerStack->size() - && (*headerStack)[i + 1] == &AS_OPEN_BRACKET) + && (*headerStack)[i + 1] == &AS_OPEN_BRACE) i++; - else if (lineBeginsWithOpenBracket) + else if (lineBeginsWithOpenBrace) { - // don't double count the current bracket + // don't double count the current brace if (i + 1 < headerStack->size() - && (*headerStack)[i] == &AS_OPEN_BRACKET) - haveUnindentedBracket = true; + && (*headerStack)[i] == &AS_OPEN_BRACE) + haveUnindentedBrace = true; } - else if ((*headerStack)[i] == &AS_OPEN_BRACKET) - haveUnindentedBracket = true; + else if ((*headerStack)[i] == &AS_OPEN_BRACE) + haveUnindentedBrace = true; } // end of for loop - if (haveUnindentedBracket) + if (haveUnindentedBrace) ++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) + if (lastTempStack != nullptr) { 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; } void ASBeautifier::adjustObjCMethodDefinitionIndentation(const string& line_) { // register indent for Objective-C continuation line if (line_.length() > 0 && (line_[0] == '-' || line_[0] == '+')) { if (shouldAlignMethodColon && objCColonAlignSubsequent != -1) { string convertedLine = getIndentedSpaceEquivalent(line_); - colonIndentObjCMethodAlignment = convertedLine.find(':'); + colonIndentObjCMethodAlignment = findObjCColonAlignment(convertedLine); int objCColonAlignSubsequentIndent = objCColonAlignSubsequent + indentLength; if (objCColonAlignSubsequentIndent > colonIndentObjCMethodAlignment) colonIndentObjCMethodAlignment = objCColonAlignSubsequentIndent; } - else if (inStatementIndentStack->empty() - || inStatementIndentStack->back() == 0) + else if (continuationIndentStack->empty() + || continuationIndentStack->back() == 0) { - inStatementIndentStack->push_back(indentLength); - isInStatement = true; + continuationIndentStack->emplace_back(indentLength); + isContinuation = true; } } // set indent for last definition line - else if (!lineBeginsWithOpenBracket) + else if (!lineBeginsWithOpenBrace) { if (shouldAlignMethodColon) spaceIndentCount = computeObjCColonAlignment(line_, colonIndentObjCMethodAlignment); - else if (inStatementIndentStack->empty()) + else if (continuationIndentStack->empty()) spaceIndentCount = spaceIndentObjCMethodAlignment; } } void ASBeautifier::adjustObjCMethodCallIndentation(const string& line_) { static int keywordIndentObjCMethodAlignment = 0; if (shouldAlignMethodColon && objCColonAlignSubsequent != -1) { if (isInObjCMethodCallFirst) { isInObjCMethodCallFirst = false; string convertedLine = getIndentedSpaceEquivalent(line_); - bracketPosObjCMethodAlignment = convertedLine.find('['); + bracePosObjCMethodAlignment = convertedLine.find('['); keywordIndentObjCMethodAlignment = - getObjCFollowingKeyword(convertedLine, bracketPosObjCMethodAlignment); - colonIndentObjCMethodAlignment = convertedLine.find(':'); + getObjCFollowingKeyword(convertedLine, bracePosObjCMethodAlignment); + colonIndentObjCMethodAlignment = findObjCColonAlignment(convertedLine); if (colonIndentObjCMethodAlignment >= 0) { int objCColonAlignSubsequentIndent = objCColonAlignSubsequent + indentLength; if (objCColonAlignSubsequentIndent > colonIndentObjCMethodAlignment) colonIndentObjCMethodAlignment = objCColonAlignSubsequentIndent; - if (lineBeginsWithOpenBracket) + if (lineBeginsWithOpenBrace) colonIndentObjCMethodAlignment -= indentLength; } } else { - if (line_.find(':') != string::npos) + if (findObjCColonAlignment(line_) != -1) { if (colonIndentObjCMethodAlignment < 0) spaceIndentCount += computeObjCColonAlignment(line_, objCColonAlignSubsequent); else if (objCColonAlignSubsequent > colonIndentObjCMethodAlignment) spaceIndentCount = computeObjCColonAlignment(line_, objCColonAlignSubsequent); else spaceIndentCount = computeObjCColonAlignment(line_, colonIndentObjCMethodAlignment); } else { if (spaceIndentCount < colonIndentObjCMethodAlignment) spaceIndentCount += keywordIndentObjCMethodAlignment; } } } else // align keywords instead of colons { if (isInObjCMethodCallFirst) { isInObjCMethodCallFirst = false; string convertedLine = getIndentedSpaceEquivalent(line_); - bracketPosObjCMethodAlignment = convertedLine.find('['); + bracePosObjCMethodAlignment = convertedLine.find('['); keywordIndentObjCMethodAlignment = - getObjCFollowingKeyword(convertedLine, bracketPosObjCMethodAlignment); + getObjCFollowingKeyword(convertedLine, bracePosObjCMethodAlignment); } else { - if (spaceIndentCount < keywordIndentObjCMethodAlignment + bracketPosObjCMethodAlignment) + if (spaceIndentCount < keywordIndentObjCMethodAlignment + bracePosObjCMethodAlignment) spaceIndentCount += keywordIndentObjCMethodAlignment; } } } /** * Clear the variables used to align the Objective-C method definitions. */ void ASBeautifier::clearObjCMethodDefinitionAlignment() { assert(isImmediatelyPostObjCMethodDefinition); spaceIndentCount = 0; spaceIndentObjCMethodAlignment = 0; colonIndentObjCMethodAlignment = 0; isInObjCMethodDefinition = false; isImmediatelyPostObjCMethodDefinition = false; - if (!inStatementIndentStack->empty()) - inStatementIndentStack->pop_back(); + if (!continuationIndentStack->empty()) + continuationIndentStack->pop_back(); +} + +/** + * Find the first alignment colon on a line. + * Ternary operators (?) are bypassed. + */ +int ASBeautifier::findObjCColonAlignment(const string& line) const +{ + bool haveTernary = false; + for (size_t i = 0; i < line.length(); i++) + { + i = line.find_first_of(":?", i); + if (i == string::npos) + break; + + if (line[i] == '?') + { + haveTernary = true; + continue; + } + if (haveTernary) + { + haveTernary = false; + continue; + } + return i; + } + return -1; } /** * 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(const string& line, int colonAlignPosition) const { - int colonPosition = line.find(':'); + int colonPosition = findObjCColonAlignment(line); if (colonPosition < 0 || colonPosition > colonAlignPosition) return indentLength; return (colonAlignPosition - colonPosition); } /* - * Compute postition of the keyword following the method call object. + * Compute position of the keyword following the method call object. + * This is oversimplified to find unusual method calls. + * Use for now and see what happens. + * Most programmers will probably use align-method-colon anyway. */ -int ASBeautifier::getObjCFollowingKeyword(const string& line, int bracketPos) const +int ASBeautifier::getObjCFollowingKeyword(const string& line, int bracePos) const { - assert(line[bracketPos] == '['); - size_t firstText = line.find_first_not_of(" \t", bracketPos + 1); + assert(line[bracePos] == '['); + size_t firstText = line.find_first_not_of(" \t", bracePos + 1); if (firstText == string::npos) return -(indentCount * indentLength - 1); size_t searchBeg = firstText; size_t objectEnd = 0; // end of object text if (line[searchBeg] == '[') { objectEnd = line.find(']', searchBeg + 1); if (objectEnd == string::npos) return 0; } else { if (line[searchBeg] == '(') { searchBeg = line.find(')', searchBeg + 1); if (searchBeg == string::npos) return 0; } // bypass the object name objectEnd = line.find_first_of(" \t", searchBeg + 1); if (objectEnd == string::npos) return 0; --objectEnd; } size_t keyPos = line.find_first_not_of(" \t", objectEnd + 1); if (keyPos == string::npos) return 0; return keyPos - firstText; } /** * Get a line using the current space indent with all tabs replaced by spaces. * The indentCount is NOT included * Needed to compute an accurate alignment. */ string ASBeautifier::getIndentedSpaceEquivalent(const string& line_) const { string spaceIndent; spaceIndent.append(spaceIndentCount, ' '); string convertedLine = spaceIndent + line_; for (size_t i = spaceIndent.length(); i < convertedLine.length(); i++) { if (convertedLine[i] == '\t') { size_t numSpaces = indentLength - (i % indentLength); convertedLine.replace(i, 1, numSpaces, ' '); i += indentLength - 1; } } return convertedLine; } +/** + * Determine if an item is at a top level. + */ +bool ASBeautifier::isTopLevel() const +{ + if (headerStack->empty()) + return true; + else if (headerStack->back() == &AS_OPEN_BRACE + && headerStack->size() >= 2) + { + if ((*headerStack)[headerStack->size() - 2] == &AS_NAMESPACE + || (*headerStack)[headerStack->size() - 2] == &AS_MODULE + || (*headerStack)[headerStack->size() - 2] == &AS_CLASS + || (*headerStack)[headerStack->size() - 2] == &AS_INTERFACE + || (*headerStack)[headerStack->size() - 2] == &AS_STRUCT + || (*headerStack)[headerStack->size() - 2] == &AS_UNION) + return true; + } + else if (headerStack->back() == &AS_NAMESPACE + || headerStack->back() == &AS_MODULE + || headerStack->back() == &AS_CLASS + || headerStack->back() == &AS_INTERFACE + || headerStack->back() == &AS_STRUCT + || headerStack->back() == &AS_UNION) + return true; + return false; +} + /** * 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); + bool closingBraceReached = false; + bool previousLineProbation = (probationHeader != nullptr); char ch = ' '; int tabIncrementIn = 0; if (isInQuote && !haveLineContinuationChar && !isInVerbatimQuote && !isInAsm) isInQuote = false; // missing closing quote haveLineContinuationChar = false; for (size_t i = 0; i < line.length(); i++) { ch = line[i]; if (isInBeautifySQL) 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; // bypass whitespace here if (isWhiteSpace(ch)) { if (ch == '\t') tabIncrementIn += convertTabToSpaces(i, tabIncrementIn); 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 (g_preprocessorCppExternCBrace == 2 && line.compare(i, 3, "\"C\"") == 0) + ++g_preprocessorCppExternCBrace; } 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 (line.compare(i, 2, "\"\"") == 0) i++; else { isInQuote = false; isInVerbatimQuote = false; continue; } } } else if (quoteChar == ch) { isInQuote = false; - isInStatement = true; + isContinuation = 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 != nullptr) { if ((probationHeader == &AS_STATIC && ch == '{') || (probationHeader == &AS_SYNCHRONIZED && ch == '(')) { // insert the probation header as a new header isInHeader = true; - headerStack->push_back(probationHeader); + headerStack->emplace_back(probationHeader); // handle the specific probation header isInConditional = (probationHeader == &AS_SYNCHRONIZED); - isInStatement = false; + isContinuation = 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; + probationHeader = nullptr; } prevNonSpaceCh = currentNonSpaceCh; currentNonSpaceCh = ch; if (!isLegalNameChar(ch) && ch != ',' && ch != ';') { prevNonLegalCh = currentNonLegalCh; currentNonLegalCh = ch; } if (isInHeader) { isInHeader = false; currentHeader = headerStack->back(); } else - currentHeader = NULL; + currentHeader = nullptr; 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); + continuationIndentStackSizeStack->push_back(continuationIndentStack->size()); + registerContinuationIndent(line, i, spaceIndentCount, tabIncrementIn, 0, true); } else if (ch == '>') { - popLastInStatementIndent(); + popLastContinuationIndent(); 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; + parenStatementStack->push_back(isContinuation); + isContinuation = true; } parenDepth++; if (ch == '[') { - ++blockParenCount; - if (blockParenCount == 1 && isCStyle()) + ++squareBracketCount; + if (squareBracketCount == 1 && isCStyle()) { isInObjCMethodCall = true; isInObjCMethodCallFirst = true; } } - inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size()); + continuationIndentStackSizeStack->push_back(continuationIndentStack->size()); - if (currentHeader != NULL) - registerInStatementIndent(line, i, spaceIndentCount, tabIncrementIn, minConditionalIndent/*indentLength*2*/, true); - else - registerInStatementIndent(line, i, spaceIndentCount, tabIncrementIn, 0, true); + if (currentHeader != nullptr) + registerContinuationIndent(line, i, spaceIndentCount, tabIncrementIn, minConditionalIndent, true); + else if (!isInObjCMethodDefinition) + registerContinuationIndent(line, i, spaceIndentCount, tabIncrementIn, 0, true); } else if (ch == ')' || ch == ']') { if (ch == ']') - --blockParenCount; - if (blockParenCount <= 0) + --squareBracketCount; + if (squareBracketCount <= 0) { - blockParenCount = 0; + squareBracketCount = 0; if (isInObjCMethodCall) isImmediatelyPostObjCMethodCall = true; } foundPreCommandHeader = false; parenDepth--; if (parenDepth == 0) { if (!parenStatementStack->empty()) // in case of unmatched closing parens { - isInStatement = parenStatementStack->back(); + isContinuation = parenStatementStack->back(); parenStatementStack->pop_back(); } isInAsm = false; isInConditional = false; } - if (!inStatementIndentStackSizeStack->empty()) + if (!continuationIndentStackSizeStack->empty()) { - popLastInStatementIndent(); + popLastContinuationIndent(); 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()) + bool isBlockOpener = ((prevNonSpaceCh == '{' && braceBlockStateStack->back()) || prevNonSpaceCh == '}' || prevNonSpaceCh == ')' || prevNonSpaceCh == ';' || peekNextChar(line, i) == '{' + || isInTrailingReturnType || foundPreCommandHeader || foundPreCommandMacro || isInClassHeader || (isInClassInitializer && !isLegalNameChar(prevNonSpaceCh)) || isNonInStatementArray || isInObjCMethodDefinition || isInObjCInterface || isSharpAccessor || isSharpDelegate || isInExternC || isInAsmBlock || getNextWord(line, i) == AS_NEW || (isInDefine && (prevNonSpaceCh == '(' || isLegalNameChar(prevNonSpaceCh)))); if (isInObjCMethodDefinition) { objCColonAlignSubsequent = 0; isImmediatelyPostObjCMethodDefinition = true; - if (lineBeginsWithOpenBracket) // for horstmann brackets + if (lineBeginsWithOpenBrace) // for run-in braces clearObjCMethodDefinitionAlignment(); } - if (!isBlockOpener && !isInStatement && !isInClassInitializer && !isInEnum) + if (!isBlockOpener && !isContinuation && !isInClassInitializer && !isInEnum) { - if (headerStack->empty()) - isBlockOpener = true; - else if (headerStack->back() == &AS_NAMESPACE - || headerStack->back() == &AS_MODULE - || headerStack->back() == &AS_CLASS - || headerStack->back() == &AS_INTERFACE - || headerStack->back() == &AS_STRUCT - || headerStack->back() == &AS_UNION) + if (isTopLevel()) isBlockOpener = true; } - if (!isBlockOpener && currentHeader != NULL) + if (!isBlockOpener && currentHeader != nullptr) { for (size_t n = 0; n < nonParenHeaders->size(); n++) if (currentHeader == (*nonParenHeaders)[n]) { isBlockOpener = true; break; } } - bracketBlockStateStack->push_back(isBlockOpener); + braceBlockStateStack->push_back(isBlockOpener); if (!isBlockOpener) { - inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size()); - registerInStatementIndent(line, i, spaceIndentCount, tabIncrementIn, 0, true); + continuationIndentStackSizeStack->push_back(continuationIndentStack->size()); + registerContinuationIndent(line, i, spaceIndentCount, tabIncrementIn, 0, true); parenDepth++; if (i == 0) - shouldIndentBrackettedLine = false; + shouldIndentBracedLine = false; isInEnumTypeID = false; continue; } - // this bracket is a block opener... + // this brace is a block opener... ++lineOpeningBlocksNum; if (isInClassInitializer || isInEnumTypeID) { - // decrease tab count if bracket is broken - if (lineBeginsWithOpenBracket) + // decrease tab count if brace is broken + if (lineBeginsWithOpenBrace) { 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) + if (lineBeginsWithOpenBrace) --indentCount; } - if (bracketIndent && !namespaceIndent && !headerStack->empty() + if (braceIndent && !namespaceIndent && !headerStack->empty() && ((*headerStack).back() == &AS_NAMESPACE || (*headerStack).back() == &AS_MODULE)) { - shouldIndentBrackettedLine = false; + shouldIndentBracedLine = 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); + // is a brace inside a paren? + parenDepthStack->emplace_back(parenDepth); + blockStatementStack->push_back(isContinuation); - if (!inStatementIndentStack->empty()) + if (!continuationIndentStack->empty()) { - // completely purge the inStatementIndentStack - while (!inStatementIndentStack->empty()) - popLastInStatementIndent(); + // completely purge the continuationIndentStack + while (!continuationIndentStack->empty()) + popLastContinuationIndent(); if (isInClassInitializer || isInClassHeaderTab) { - if (lineBeginsWithOpenBracket || lineBeginsWithComma) + if (lineBeginsWithOpenBrace || lineBeginsWithComma) spaceIndentCount = 0; } else spaceIndentCount = 0; } - blockTabCount += (isInStatement ? 1 : 0); - if (g_preprocessorCppExternCBracket == 3) - ++g_preprocessorCppExternCBracket; + blockTabCount += (isContinuation ? 1 : 0); + if (g_preprocessorCppExternCBrace == 3) + ++g_preprocessorCppExternCBrace; parenDepth = 0; + isInTrailingReturnType = false; isInClassHeader = false; isInClassHeaderTab = false; isInClassInitializer = false; isInEnumTypeID = false; - isInStatement = false; + isContinuation = 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; + tempStacks->emplace_back(new vector); + headerStack->emplace_back(&AS_OPEN_BRACE); + lastLineHeader = &AS_OPEN_BRACE; continue; } // end '{' //check if a header has been reached bool isPotentialHeader = isCharPotentialHeader(line, i); - if (isPotentialHeader && !blockParenCount) + if (isPotentialHeader && squareBracketCount == 0) { const string* newHeader = findHeader(line, i, headers); + // java can have a 'default' not in a switch + if (newHeader == &AS_DEFAULT + && peekNextChar(line, (i + (*newHeader).length() - 1)) != ':') + newHeader = nullptr; // 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; + newHeader = nullptr; + } + else if (isSharpStyle() + && (newHeader == &AS_GET || newHeader == &AS_SET)) + { + if (getNextWord(line, i + (*newHeader).length()) == "is") + newHeader = nullptr; } else if (newHeader == &AS_USING - && ASBeautifier::peekNextChar(line, i + (*newHeader).length() - 1) != '(') - newHeader = NULL; + && peekNextChar(line, i + (*newHeader).length() - 1) != '(') + newHeader = nullptr; - if (newHeader != NULL) + if (newHeader != nullptr) { // if we reached here, then this is a header... bool isIndentableHeader = true; isInHeader = true; - vector* lastTempStack = NULL;; + vector* lastTempStack = nullptr;; if (!tempStacks->empty()) 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(); + if (!headerStack->empty()) + headerStack->pop_back(); } // take care of 'else' else if (newHeader == &AS_ELSE) { - if (lastTempStack != NULL) + if (lastTempStack != nullptr) { 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()); + headerStack->emplace_back(lastTempStack->back()); lastTempStack->pop_back(); } - if (!closingBracketReached) + if (!closingBraceReached) 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) + if (lastTempStack != nullptr) { 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()); + headerStack->emplace_back(lastTempStack->back()); lastTempStack->pop_back(); } - if (!closingBracketReached) + if (!closingBraceReached) indentCount += restackSize; } } } // check if 'catch' closes a previous 'try' or 'catch' else if (newHeader == &AS_CATCH || newHeader == &AS_FINALLY) { - if (lastTempStack != NULL) + if (lastTempStack != nullptr) { 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()); + headerStack->emplace_back(lastTempStack->back()); lastTempStack->pop_back(); } - if (!closingBracketReached) + if (!closingBraceReached) indentCount += restackSize; } } } else if (newHeader == &AS_CASE) { isInCase = true; if (!haveCaseIndent) { haveCaseIndent = true; - if (!lineBeginsWithOpenBracket) + if (!lineBeginsWithOpenBrace) --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; + headerStack->emplace_back(newHeader); + isContinuation = false; if (indexOf(*nonParenHeaders, newHeader) == -1) { isInConditional = true; } lastLineHeader = newHeader; } else isInHeader = false; i += newHeader->length() - 1; continue; - } // newHeader != NULL + } // newHeader != nullptr - if (findHeader(line, i, preCommandHeaders)) - foundPreCommandHeader = true; + if (findHeader(line, i, preCommandHeaders) != nullptr) + // must be after function arguments + if (prevNonSpaceCh == ')') + 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() + else if ((isCStyle() || isSharpStyle()) && !isInCase && (prevNonSpaceCh == ')' || foundPreCommandHeader)) { // found a 'class' c'tor initializer isInClassInitializer = true; - registerInStatementIndentColon(line, i, tabIncrementIn); + registerContinuationIndentColon(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); + registerContinuationIndentColon(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) + && (*headerStack)[headerStack->size() - 1] == &AS_OPEN_BRACE) { // found a 'private:' or 'public:' inside a class definition - // and on the same line as the class opening bracket + // and on the same line as the class opening brace // 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 + currentNonSpaceCh = ';'; // so that braces 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) + else if (!lineBeginsWithOpenBrace) 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(); + if ((ch == ';' || (parenDepth > 0 && ch == ',')) && !continuationIndentStackSizeStack->empty()) + while ((int) continuationIndentStackSizeStack->back() + (parenDepth > 0 ? 1 : 0) + < (int) continuationIndentStack->size()) + continuationIndentStack->pop_back(); - else if (ch == ',' && isInEnum && isNonInStatementArray && !inStatementIndentStack->empty()) - inStatementIndentStack->pop_back(); + else if (ch == ',' && isInEnum && isNonInStatementArray && !continuationIndentStack->empty()) + continuationIndentStack->pop_back(); // handle commas // previous "isInStatement" will be from an assignment operator or class initializer - if (ch == ',' && parenDepth == 0 && !isInStatement && !isNonInStatementArray) + if (ch == ',' && parenDepth == 0 && !isContinuation && !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; + int prevWord = getContinuationIndentComma(line, i); + int continuationIndentCount = prevWord + spaceIndentCount + tabIncrementIn; + continuationIndentStack->emplace_back(continuationIndentCount); + isContinuation = 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) + if (braceBlockStateStack->size() > 1) { - bool bracketBlockState = bracketBlockStateStack->back(); - bracketBlockStateStack->pop_back(); - if (!bracketBlockState) + bool braceBlockState = braceBlockStateStack->back(); + braceBlockStateStack->pop_back(); + if (!braceBlockState) { - if (!inStatementIndentStackSizeStack->empty()) + if (!continuationIndentStackSizeStack->empty()) { - // this bracket is a static array - popLastInStatementIndent(); + // this brace is a static array + popLastContinuationIndent(); parenDepth--; if (i == 0) - shouldIndentBrackettedLine = false; + shouldIndentBracedLine = false; if (!parenIndentStack->empty()) { int poppedIndent = parenIndentStack->back(); parenIndentStack->pop_back(); if (i == 0) spaceIndentCount = poppedIndent; } } continue; } } - // this bracket is block closer... + // this brace is block closer... ++lineClosingBlocksNum; - if (!inStatementIndentStackSizeStack->empty()) - popLastInStatementIndent(); + if (!continuationIndentStackSizeStack->empty()) + popLastContinuationIndent(); - if (!blockParenDepthStack->empty()) + if (!parenDepthStack->empty()) { - parenDepth = blockParenDepthStack->back(); - blockParenDepthStack->pop_back(); - isInStatement = blockStatementStack->back(); + parenDepth = parenDepthStack->back(); + parenDepthStack->pop_back(); + isContinuation = blockStatementStack->back(); blockStatementStack->pop_back(); - if (isInStatement) + if (isContinuation) blockTabCount--; } - closingBracketReached = true; + closingBraceReached = true; if (i == 0) spaceIndentCount = 0; isInAsmBlock = false; isInAsm = isInAsmOneLine = isInQuote = false; // close these just in case - int headerPlace = indexOf(*headerStack, &AS_OPEN_BRACKET); + int headerPlace = indexOf(*headerStack, &AS_OPEN_BRACE); if (headerPlace != -1) { const string* popped = headerStack->back(); - while (popped != &AS_OPEN_BRACKET) + while (popped != &AS_OPEN_BRACE) { headerStack->pop_back(); popped = headerStack->back(); } headerStack->pop_back(); if (headerStack->empty()) - g_preprocessorCppExternCBracket = 0; + g_preprocessorCppExternCBrace = 0; - // do not indent namespace bracket unless namespaces are indented + // do not indent namespace brace unless namespaces are indented if (!namespaceIndent && !headerStack->empty() && ((*headerStack).back() == &AS_NAMESPACE || (*headerStack).back() == &AS_MODULE) - && i == 0) // must be the first bracket on the line - shouldIndentBrackettedLine = false; + && i == 0) // must be the first brace on the line + shouldIndentBracedLine = 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) + while (!headerStack->empty() && headerStack->back() != &AS_OPEN_BRACE) { - tempStacks->back()->push_back(headerStack->back()); + tempStacks->back()->emplace_back(headerStack->back()); headerStack->pop_back(); } if (parenDepth == 0 && ch == ';') - isInStatement = false; + { + isContinuation = false; + isInClassInitializer = false; + } if (isInObjCMethodDefinition) { objCColonAlignSubsequent = 0; isImmediatelyPostObjCMethodDefinition = true; } - previousLastLineHeader = NULL; + previousLastLineHeader = nullptr; isInClassHeader = false; // for 'friend' class isInEnum = false; isInEnumTypeID = false; isInQuestion = false; isInTemplate = false; isInObjCInterface = false; foundPreCommandHeader = false; foundPreCommandMacro = false; - blockParenCount = 0; + 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); - // handle CORBA IDL module + // CORBA IDL module if (newHeader == &AS_MODULE) { char nextChar = peekNextChar(line, i + newHeader->length() - 1); if (prevNonSpaceCh == ')' || !isalpha(nextChar)) - newHeader = NULL; + newHeader = nullptr; } - if (newHeader != NULL - && !(isCStyle() && newHeader == &AS_CLASS && isInEnum)) // is not 'enum class' + if (newHeader != nullptr + && !(isCStyle() && newHeader == &AS_CLASS && isInEnum) // is not 'enum class' + && !(isCStyle() && newHeader == &AS_INTERFACE // CORBA IDL interface + && (headerStack->empty() + || headerStack->back() != &AS_OPEN_BRACE))) { if (!isSharpStyle()) - headerStack->push_back(newHeader); + headerStack->emplace_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 + || ((newHeader == &AS_CLASS || newHeader == &AS_STRUCT) && !headerStack->empty() - && headerStack->back() == &AS_CLASS))) - headerStack->push_back(newHeader); + && (headerStack->back() == &AS_CLASS + || headerStack->back() == &AS_STRUCT)))) + headerStack->emplace_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 || (*headerStack).back() == &AS_MODULE) { - // remove inStatementIndent from namespace - if (!inStatementIndentStack->empty()) - inStatementIndentStack->pop_back(); - isInStatement = false; + // remove continuationIndent from namespace + if (!continuationIndentStack->empty()) + continuationIndentStack->pop_back(); + isContinuation = false; } } i += newHeader->length() - 1; continue; } } const string* foundIndentableHeader = findHeader(line, i, indentableHeaders); - if (foundIndentableHeader != NULL) + if (foundIndentableHeader != nullptr) { // 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; + registerContinuationIndent(line, i, spaceIndentCount, tabIncrementIn, 0, false); + isContinuation = true; } continue; } if (isCStyle() && findKeyword(line, i, AS_OPERATOR)) isInOperator = true; - if (g_preprocessorCppExternCBracket == 1 && findKeyword(line, i, AS_EXTERN)) - ++g_preprocessorCppExternCBracket; + if (g_preprocessorCppExternCBrace == 1 && findKeyword(line, i, AS_EXTERN)) + ++g_preprocessorCppExternCBrace; - if (g_preprocessorCppExternCBracket == 3) // extern "C" is not followed by a '{' - g_preprocessorCppExternCBracket = 0; + if (g_preprocessorCppExternCBrace == 3) // extern "C" is not followed by a '{' + g_preprocessorCppExternCBrace = 0; // "new" operator is a pointer, not a calculation if (findKeyword(line, i, AS_NEW)) { - if (isInStatement && !inStatementIndentStack->empty() && prevNonSpaceCh == '=') - inStatementIndentStack->back() = 0; + if (isContinuation && !continuationIndentStack->empty() && prevNonSpaceCh == '=') + continuationIndentStack->back() = 0; + } + + if (isCStyle() && findKeyword(line, i, AS_AUTO) && isTopLevel()) + { + isInTrailingReturnType = true; } 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 = 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 == '@' && !isWhiteSpace(line[i + 1]) + if (ch == '@' + && line.length() > i + 1 + && !isWhiteSpace(line[i + 1]) && isCharPotentialHeader(line, i + 1)) { string curWord = getCurrentWord(line, i + 1); - if (curWord == AS_INTERFACE && headerStack->empty()) + if (curWord == AS_INTERFACE) { isInObjCInterface = true; string name = '@' + curWord; i += name.length() - 1; continue; } else if (isInObjCInterface) { --indentCount; isInObjCInterface = false; } 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(); + popLastContinuationIndent(); spaceIndentCount = 0; isInObjCMethodDefinition = false; string name = '@' + curWord; i += name.length() - 1; continue; } } else if ((ch == '-' || ch == '+') - && peekNextChar(line, i) == '(' - && headerStack->empty() + && (prevNonSpaceCh == ';' || prevNonSpaceCh == '{' + || headerStack->empty() || isInObjCInterface) + && ASBase::peekNextChar(line, i) != '-' + && ASBase::peekNextChar(line, i) != '+' && 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; + if (foundNonAssignmentOp != nullptr) + { + if (foundNonAssignmentOp == &AS_LAMBDA) + foundPreCommandHeader = true; + if (isInTemplate && foundNonAssignmentOp == &AS_GR_GR) + foundNonAssignmentOp = nullptr; + } // 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 != nullptr && foundNonAssignmentOp != nullptr) { if (foundAssignmentOp->length() < foundNonAssignmentOp->length()) - foundAssignmentOp = NULL; + foundAssignmentOp = nullptr; else - foundNonAssignmentOp = NULL; + foundNonAssignmentOp = nullptr; } - if (foundNonAssignmentOp != NULL) + if (foundNonAssignmentOp != nullptr) { 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() + && continuationIndentStack->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) + if (i < foundNonAssignmentOp->length() && spaceIndentCount == 0) spaceIndentCount += 2 * indentLength; // align to the beginning column of the operator - registerInStatementIndent(line, i - foundNonAssignmentOp->length(), spaceIndentCount, tabIncrementIn, 0, false); + registerContinuationIndent(line, i - foundNonAssignmentOp->length(), spaceIndentCount, tabIncrementIn, 0, false); } } - else if (foundAssignmentOp != NULL) + else if (foundAssignmentOp != nullptr) { 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; + int prevWordIndex = getContinuationIndentAssign(line, i); + int continuationIndentCount = prevWordIndex + spaceIndentCount + tabIncrementIn; + continuationIndentStack->emplace_back(continuationIndentCount); + isContinuation = true; } } // don't indent an assignment if 'let' else if (isInLet) { isInLet = false; } else if (!lineBeginsWithComma) { if (i == 0 && spaceIndentCount == 0) spaceIndentCount += indentLength; - registerInStatementIndent(line, i, spaceIndentCount, tabIncrementIn, 0, false); - isInStatement = true; + registerContinuationIndent(line, i, spaceIndentCount, tabIncrementIn, 0, false); + isContinuation = 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/plugins/astyle/3rdparty/libastyle/ASEnhancer.cpp b/plugins/astyle/3rdparty/libastyle/ASEnhancer.cpp index 5ef12396da..cb197a9e4b 100644 --- a/plugins/astyle/3rdparty/libastyle/ASEnhancer.cpp +++ b/plugins/astyle/3rdparty/libastyle/ASEnhancer.cpp @@ -1,796 +1,796 @@ // ASEnhancer.cpp -// Copyright (c) 2016 by Jim Pattee . +// Copyright (c) 2018 by Jim Pattee . // This code is licensed under the MIT License. -// License.txt describes the conditions under which this software may be distributed. +// License.md 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; + braceCount = 0; isInComment = false; isInQuote = false; switchDepth = 0; eventPreprocDepth = 0; - lookingForCaseBracket = false; + lookingForCaseBrace = false; unindentNextLine = false; shouldUnindentLine = false; shouldUnindentComment = false; // switch struct and vector - sw.switchBracketCount = 0; + sw.switchBraceCount = 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 + // test for unindent on attached braces 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 ASEnhancer::findCaseColon(const 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 +bool ASEnhancer::isBeginDeclareSectionSQL(const 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 +bool ASEnhancer::isEndDeclareSectionSQL(const 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, + * check if a one-line brace 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. + * @return false = one-line brace has not been reached. + * true = one-line brace has been reached. */ bool ASEnhancer::isOneLineBlockReached(const string& line, int startChar) const { assert(line[startChar] == '{'); bool isInComment_ = false; bool isInQuote_ = false; - int _bracketCount = 1; + int _braceCount = 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; + ++_braceCount; else if (ch == '}') - --_bracketCount; + --_braceCount; - if (_bracketCount == 0) + if (_braceCount == 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 + // unindent if not in case braces if (line.find_first_not_of(" \t") == i - && sw.switchBracketCount == 1 + && sw.switchBraceCount == 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) + // unindent if not in case braces + if (sw.switchBraceCount == 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) + // unindent if not in case braces + if (sw.switchBraceCount == 1 && sw.unindentCase) shouldUnindentComment = true; isInComment = false; i++; continue; } if (isInComment) { - // unindent if not in case brackets - if (sw.switchBracketCount == 1 && sw.unindentCase) + // unindent if not in case braces + if (sw.switchBraceCount == 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++; + braceCount++; if (line[i] == '}') - bracketCount--; + braceCount--; // 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, 5) == "endif" && eventPreprocDepth > 0) 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")) + if (isPotentialKeyword && findKeyword(line, i, ASResource::AS_SWITCH)) { switchDepth++; - switchStack.push_back(sw); // save current variables - sw.switchBracketCount = 0; + switchStack.emplace_back(sw); // save current variables + sw.switchBraceCount = 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.switchBraceCount++; + if (lookingForCaseBrace) // if 1st after case statement { sw.unindentCase = true; // unindenting this case sw.unindentDepth++; - lookingForCaseBracket = false; // not looking now + lookingForCaseBrace = false; // not looking now } return i; } - lookingForCaseBracket = false; // no opening bracket, don't indent + lookingForCaseBrace = false; // no opening brace, don't indent if (line[i] == '}') { - sw.switchBracketCount--; - assert(sw.switchBracketCount <= bracketCount); - if (sw.switchBracketCount == 0) // if end of switch statement + sw.switchBraceCount--; + if (sw.switchBraceCount == 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"))) + && (findKeyword(line, i, ASResource::AS_CASE) + || findKeyword(line, i, ASResource::AS_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++; + braceCount++; + sw.switchBraceCount++; if (!isOneLineBlockReached(line, i)) unindentNextLine = true; return i; } } - lookingForCaseBracket = true; + lookingForCaseBrace = 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/plugins/astyle/3rdparty/libastyle/ASFormatter.cpp b/plugins/astyle/3rdparty/libastyle/ASFormatter.cpp index 7f6bf23f3d..bd1a004422 100644 --- a/plugins/astyle/3rdparty/libastyle/ASFormatter.cpp +++ b/plugins/astyle/3rdparty/libastyle/ASFormatter.cpp @@ -1,7659 +1,8245 @@ // ASFormatter.cpp -// Copyright (c) 2016 by Jim Pattee . +// Copyright (c) 2018 by Jim Pattee . // This code is licensed under the MIT License. -// License.txt describes the conditions under which this software may be distributed. +// License.md 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; + sourceIterator = nullptr; enhancer = new ASEnhancer; - preBracketHeaderStack = NULL; - bracketTypeStack = NULL; - parenStack = NULL; - structStack = NULL; - questionMarkStack = NULL; + preBraceHeaderStack = nullptr; + braceTypeStack = nullptr; + parenStack = nullptr; + structStack = nullptr; + questionMarkStack = nullptr; lineCommentNoIndent = false; formattingStyle = STYLE_NONE; - bracketFormatMode = NONE_MODE; + braceFormatMode = 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; + attachClosingBraceMode = false; shouldBreakOneLineBlocks = true; shouldBreakOneLineHeaders = false; shouldBreakOneLineStatements = true; shouldConvertTabs = false; shouldIndentCol1Comments = false; shouldIndentPreprocBlock = false; shouldCloseTemplates = false; shouldAttachExternC = false; shouldAttachNamespace = false; shouldAttachClass = false; + shouldAttachClosingWhile = false; shouldAttachInline = false; shouldBreakBlocks = false; shouldBreakClosingHeaderBlocks = false; - shouldBreakClosingHeaderBrackets = false; + shouldBreakClosingHeaderBraces = false; shouldDeleteEmptyLines = false; + shouldBreakReturnType = false; + shouldBreakReturnTypeDecl = false; + shouldAttachReturnType = false; + shouldAttachReturnTypeDecl = false; shouldBreakElseIfs = false; shouldBreakLineAfterLogical = false; - shouldAddBrackets = false; - shouldAddOneLineBrackets = false; - shouldRemoveBrackets = false; + shouldAddBraces = false; + shouldAddOneLineBraces = false; + shouldRemoveBraces = false; shouldPadMethodColon = false; shouldPadMethodPrefix = false; shouldUnPadMethodPrefix = false; shouldPadReturnType = false; shouldUnPadReturnType = false; shouldPadParamType = false; shouldUnPadParamType = 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(preBraceHeaderStack); + deleteContainer(braceTypeStack); 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) + // delete ASBeautifier member vectors 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", getForceTabIndentation(), getNamespaceIndent(), getCaseIndent(), shouldIndentPreprocBlock, getPreprocDefineIndent(), getEmptyLineFill(), indentableMacros); - initContainer(preBracketHeaderStack, new vector); + initContainer(preBraceHeaderStack, 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 + parenStack->emplace_back(0); // parenStack must contain this default entry + initContainer(braceTypeStack, new vector); + braceTypeStack->emplace_back(NULL_TYPE); // braceTypeStack must contain this default entry clearFormattedLineSplitPoints(); - currentHeader = NULL; + currentHeader = nullptr; currentLine = ""; readyFormattedLine = ""; formattedLine = ""; verbatimDelimiter = ""; currentChar = ' '; previousChar = ' '; previousCommandChar = ' '; - previousNonWSChar = ' '; + previousNonWSChar = ','; // not a potential name or operator quoteChar = '"'; preprocBlockEnd = 0; charNum = 0; checksumIn = 0; checksumOut = 0; - currentLineFirstBracketNum = string::npos; + currentLineFirstBraceNum = string::npos; formattedLineCommentNum = 0; leadingSpaces = 0; previousReadyFormattedLineLength = string::npos; - preprocBracketTypeStackSize = 0; + preprocBraceTypeStackSize = 0; spacePadNum = 0; + methodAttachCharNum = string::npos; + methodAttachLineNum = 0; + methodBreakCharNum = string::npos; + methodBreakLineNum = 0; nextLineSpacePadNum = 0; objCColonAlign = 0; templateDepth = 0; - blockParenCount = 0; - horstmannIndentChars = 0; + squareBracketCount = 0; + runInIndentChars = 0; tabIncrementIn = 0; - previousBracketType = NULL_TYPE; - previousOperator = NULL; + previousBraceType = NULL_TYPE; isVirgin = true; isInVirginLine = 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; + foundTrailingReturnType = 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; + isPreviousBraceBlockRelated = false; isInPotentialCalculation = false; - needHeaderOpeningBracket = false; + needHeaderOpeningBrace = false; shouldBreakLineAtNextChar = false; shouldKeepLineUnbroken = false; shouldReparseCurrentChar = 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; isImmediatelyPostNewDelete = false; isImmediatelyPostOperator = false; isImmediatelyPostTemplate = false; isImmediatelyPostPointerOrReference = false; isCharImmediatelyPostReturn = false; isCharImmediatelyPostThrow = false; isCharImmediatelyPostNewDelete = false; isCharImmediatelyPostOperator = false; isCharImmediatelyPostComment = false; isPreviousCharPostComment = false; isCharImmediatelyPostLineComment = false; isCharImmediatelyPostOpenBlock = false; isCharImmediatelyPostCloseBlock = false; isCharImmediatelyPostTemplate = false; isCharImmediatelyPostPointerOrReference = false; isInObjCInterface = false; isInObjCMethodDefinition = false; isInObjCReturnType = false; + isInObjCParam = false; isInObjCSelector = false; breakCurrentOneLineBlock = false; - shouldRemoveNextClosingBracket = false; - isInBracketRunIn = false; - currentLineBeginsWithBracket = false; + shouldRemoveNextClosingBrace = false; + isInBraceRunIn = false; + returnTypeChecked = false; + currentLineBeginsWithBrace = false; isPrependPostBlockEmptyLineRequested = false; isAppendPostBlockEmptyLineRequested = false; isIndentableProprocessor = false; isIndentableProprocessorBlock = false; prependEmptyLine = false; - appendOpeningBracket = false; + appendOpeningBrace = 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); + setBraceFormatMode(BREAK_MODE); } else if (formattingStyle == STYLE_JAVA) { - setBracketFormatMode(ATTACH_MODE); + setBraceFormatMode(ATTACH_MODE); } else if (formattingStyle == STYLE_KR) { - setBracketFormatMode(LINUX_MODE); + setBraceFormatMode(LINUX_MODE); } else if (formattingStyle == STYLE_STROUSTRUP) { - setBracketFormatMode(LINUX_MODE); + setBraceFormatMode(LINUX_MODE); + setBreakClosingHeaderBracesMode(true); } else if (formattingStyle == STYLE_WHITESMITH) { - setBracketFormatMode(BREAK_MODE); - setBracketIndent(true); + setBraceFormatMode(BREAK_MODE); + setBraceIndent(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 + // the unindented class brace does NOT cause a hanging indent like Whitesmith + setBraceFormatMode(BREAK_MODE); + setBraceIndentVtk(true); // sets both braceIndent and braceIndentVtk setSwitchIndent(true); // avoid hanging indent with case statements } - else if (formattingStyle == STYLE_BANNER) + else if (formattingStyle == STYLE_RATLIFF) { - // attached brackets can have hanging indents with the closing bracket - setBracketFormatMode(ATTACH_MODE); - setBracketIndent(true); + // attached braces can have hanging indents with the closing brace + setBraceFormatMode(ATTACH_MODE); + setBraceIndent(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); + setBraceFormatMode(BREAK_MODE); setBlockIndent(true); } else if (formattingStyle == STYLE_LINUX) { - setBracketFormatMode(LINUX_MODE); + setBraceFormatMode(LINUX_MODE); // always for Linux style setMinConditionalIndentOption(MINCOND_ONEHALF); } else if (formattingStyle == STYLE_HORSTMANN) { - setBracketFormatMode(RUN_IN_MODE); + setBraceFormatMode(RUN_IN_MODE); setSwitchIndent(true); } else if (formattingStyle == STYLE_1TBS) { - setBracketFormatMode(LINUX_MODE); - setAddBracketsMode(true); - setRemoveBracketsMode(false); + setBraceFormatMode(LINUX_MODE); + setAddBracesMode(true); + setRemoveBracesMode(false); } else if (formattingStyle == STYLE_GOOGLE) { - setBracketFormatMode(ATTACH_MODE); + setBraceFormatMode(ATTACH_MODE); setModifierIndent(true); setClassIndent(false); } else if (formattingStyle == STYLE_MOZILLA) { - setBracketFormatMode(LINUX_MODE); + setBraceFormatMode(LINUX_MODE); } else if (formattingStyle == STYLE_PICO) { - setBracketFormatMode(RUN_IN_MODE); - setAttachClosingBracketMode(true); + setBraceFormatMode(RUN_IN_MODE); + setAttachClosingBraceMode(true); setSwitchIndent(true); setBreakOneLineBlocksMode(false); setBreakOneLineStatementsMode(false); - // add-brackets won't work for pico, but it could be fixed if necessary + // add-braces won't work for pico, but it could be fixed if necessary // both options should be set to true - if (shouldAddBrackets) - shouldAddOneLineBrackets = true; + if (shouldAddBraces) + shouldAddOneLineBraces = true; } else if (formattingStyle == STYLE_LISP) { - setBracketFormatMode(ATTACH_MODE); - setAttachClosingBracketMode(true); + setBraceFormatMode(ATTACH_MODE); + setAttachClosingBraceMode(true); setBreakOneLineStatementsMode(false); - // add-one-line-brackets won't work for lisp - // only shouldAddBrackets should be set to true - if (shouldAddOneLineBrackets) + // add-one-line-braces won't work for lisp + // only shouldAddBraces should be set to true + if (shouldAddOneLineBraces) { - shouldAddBrackets = true; - shouldAddOneLineBrackets = false; + shouldAddBraces = true; + shouldAddOneLineBraces = false; } } setMinConditionalIndentLength(); // if not set by indent=force-tab-x set equal to indentLength - if (!getTabLength()) + if (getTabLength() == 0) setDefaultTabLength(); - // add-one-line-brackets implies keep-one-line-blocks - if (shouldAddOneLineBrackets) + // add-one-line-braces implies keep-one-line-blocks + if (shouldAddOneLineBraces) setBreakOneLineBlocksMode(false); - // don't allow add-brackets and remove-brackets - if (shouldAddBrackets || shouldAddOneLineBrackets) - setRemoveBracketsMode(false); + // don't allow add-braces and remove-braces + if (shouldAddBraces || shouldAddOneLineBraces) + setRemoveBracesMode(false); + // don't allow break-return-type and attach-return-type + if (shouldBreakReturnType) + shouldAttachReturnType = false; + if (shouldBreakReturnTypeDecl) + shouldAttachReturnTypeDecl = 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; + const string* newHeader = nullptr; 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 + && currentLineBeginsWithBrace && previousCommandChar == ' ') previousCommandChar = '{'; if (isInClassInitializer - && isBracketType(bracketTypeStack->back(), COMMAND_TYPE)) + && isBraceType(braceTypeStack->back(), COMMAND_TYPE)) isInClassInitializer = false; - if (isInBracketRunIn) + if (isInBraceRunIn) isInLineBreak = false; if (!isWhiteSpace(currentChar)) - isInBracketRunIn = false; + isInBraceRunIn = false; isPreviousCharPostComment = isCharImmediatelyPostComment; isCharImmediatelyPostComment = false; isCharImmediatelyPostTemplate = false; isCharImmediatelyPostReturn = false; isCharImmediatelyPostThrow = false; isCharImmediatelyPostNewDelete = 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; + 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 + // check for run-in if (formattedLine.length() > 0 && formattedLine[0] == '{') { isInLineBreak = true; - isInBracketRunIn = false; + isInBraceRunIn = false; } if (previousCommandChar == '}') - currentHeader = NULL; + currentHeader = nullptr; isInLineComment = true; appendCurrentChar(); continue; } } if (isInPreprocessor) { appendCurrentChar(); continue; } if (isInTemplate && shouldCloseTemplates) { if (previousNonWSChar == '>' && isWhiteSpace(currentChar) && peekNextChar() == '>') continue; } - if (shouldRemoveNextClosingBracket && currentChar == '}') + if (shouldRemoveNextClosingBrace && currentChar == '}') { currentLine[charNum] = currentChar = ' '; - shouldRemoveNextClosingBracket = false; + shouldRemoveNextClosingBrace = false; assert(adjustChecksumIn(-'}')); if (isEmptyLine(currentLine)) 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 == '#') + if (currentChar == '#' + && currentLine.find_first_not_of(" \t") == (size_t) charNum + && !isBraceType(braceTypeStack->back(), SINGLE_LINE_TYPE)) { isInPreprocessor = true; - // check for horstmann run-in + // check for run-in if (formattedLine.length() > 0 && formattedLine[0] == '{') { isInLineBreak = true; - isInBracketRunIn = false; + isInBraceRunIn = false; } processPreprocessor(); // if top level it is potentially indentable if (shouldIndentPreprocBlock - && (isBracketType(bracketTypeStack->back(), NULL_TYPE) - || isBracketType(bracketTypeStack->back(), NAMESPACE_TYPE)) + && (isBraceType(braceTypeStack->back(), NULL_TYPE) + || isBraceType(braceTypeStack->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 (isImmediatelyPostNewDelete) { isImmediatelyPostNewDelete = false; isCharImmediatelyPostNewDelete = 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 + // should braces be added if (currentChar != '{' - && shouldAddBrackets + && shouldAddBraces + && currentChar != '#' // don't add to preprocessor && (shouldBreakOneLineStatements || !isHeaderInMultiStatementLine) - && isOkToBreakBlock(bracketTypeStack->back())) + && isOkToBreakBlock(braceTypeStack->back())) { - bool bracketsAdded = addBracketsToStatement(); - if (bracketsAdded && !shouldAddOneLineBrackets) + bool bracesAdded = addBracesToStatement(); + if (bracesAdded && !shouldAddOneLineBraces) { size_t firstText = currentLine.find_first_not_of(" \t"); assert(firstText != string::npos); if ((int) firstText == charNum || shouldBreakOneLineHeaders) breakCurrentOneLineBlock = true; } } - // should brackets be removed - else if (currentChar == '{' && shouldRemoveBrackets) + // should braces be removed + else if (currentChar == '{' && shouldRemoveBraces) { - bool bracketsRemoved = removeBracketsFromStatement(); - if (bracketsRemoved) + bool bracesRemoved = removeBracesFromStatement(); + if (bracesRemoved) { - shouldRemoveNextClosingBracket = true; + shouldRemoveNextClosingBrace = true; if (isBeforeAnyLineEndComment(charNum)) spacePadNum--; else if (shouldBreakOneLineBlocks - || (currentLineBeginsWithBracket + || (currentLineBeginsWithBrace && 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()) + && isOkToBreakBlock(braceTypeStack->back()) && !isBeforeAnyComment() && (shouldBreakOneLineStatements || !isHeaderInMultiStatementLine)) { string nextText = peekNextText(currentLine.substr(charNum)); if (nextText.length() > 0 && isCharPotentialHeader(nextText, 0) - && ASBeautifier::findHeader(nextText, 0, headers) == &AS_IF) + && ASBase::findHeader(nextText, 0, headers) == &AS_IF) { isInLineBreak = true; } } // break a header (e.g. if, while, else) from the following statement if (shouldBreakOneLineHeaders && peekNextChar() != ' ' && (shouldBreakOneLineStatements || (!isHeaderInMultiStatementLine && !isMultiStatementLine())) - && isOkToBreakBlock(bracketTypeStack->back()) + && isOkToBreakBlock(braceTypeStack->back()) && !isBeforeAnyComment()) { if (currentChar == '{') { - if (!currentLineBeginsWithBracket) + if (!currentLineBeginsWithBrace) { if (isOneLineBlockReached(currentLine, charNum) == 3) isInLineBreak = false; else breakCurrentOneLineBlock = true; } } else if (currentHeader == &AS_ELSE) { string nextText = peekNextText(currentLine.substr(charNum), true); if (nextText.length() > 0 && ((isCharPotentialHeader(nextText, 0) - && ASBeautifier::findHeader(nextText, 0, headers) != &AS_IF) + && ASBase::findHeader(nextText, 0, headers) != &AS_IF) || nextText[0] == '{')) isInLineBreak = true; } else { 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)) + if (isBraceType(braceTypeStack->back(), SINGLE_LINE_TYPE)) { - size_t blockEnd = currentLine.rfind(AS_CLOSE_BRACKET); + size_t blockEnd = currentLine.rfind(AS_CLOSE_BRACE); 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)); formattedLine.append(getIndentLength() - 1, ' '); // append comment int charNumSave = charNum; charNum = commentStart; while (charNum < (int) currentLine.length()) { currentChar = currentLine[charNum]; if (currentChar == '\t' && shouldConvertTabs) convertTabToSpaces(); formattedLine.append(1, currentChar); ++charNum; } size_t commentLength = currentLine.length() - commentStart; currentLine.erase(commentStart, commentLength); charNum = charNumSave; currentChar = currentLine[charNum]; testForTimeToSplitFormattedLine(); } } isInExecSQL = false; shouldReparseCurrentChar = true; if (formattedLine.find_first_not_of(" \t") != string::npos) isInLineBreak = true; - if (needHeaderOpeningBracket) + if (needHeaderOpeningBrace) { isCharImmediatelyPostCloseBlock = true; - needHeaderOpeningBracket = false; + needHeaderOpeningBrace = 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(); } + // Check for break return type + if ((size_t) charNum >= methodBreakCharNum && methodBreakLineNum == 0) + { + if ((size_t) charNum == methodBreakCharNum) + isInLineBreak = true; + methodBreakCharNum = string::npos; + methodBreakLineNum = 0; + } + // Check for attach return type + if ((size_t) charNum >= methodAttachCharNum && methodAttachLineNum == 0) + { + if ((size_t) charNum == methodAttachCharNum) + { + int pa = pointerAlignment; + int ra = referenceAlignment; + int itemAlignment = (previousNonWSChar == '*' || previousNonWSChar == '^') + ? pa : ((ra == REF_SAME_AS_PTR) ? pa : ra); + isInLineBreak = false; + if (previousNonWSChar == '*' || previousNonWSChar == '&' || previousNonWSChar == '^') + { + if (itemAlignment == REF_ALIGN_TYPE) + { + if (formattedLine.length() > 0 + && !isWhiteSpace(formattedLine[formattedLine.length() - 1])) + formattedLine.append(1, ' '); + } + else if (itemAlignment == REF_ALIGN_MIDDLE) + { + if (formattedLine.length() > 0 + && !isWhiteSpace(formattedLine[formattedLine.length() - 1])) + formattedLine.append(1, ' '); + } + else if (itemAlignment == REF_ALIGN_NAME) + { + if (formattedLine.length() > 0 + && isWhiteSpace(formattedLine[formattedLine.length() - 1])) + formattedLine.erase(formattedLine.length() - 1); + } + else + { + if (formattedLine.length() > 1 + && !isWhiteSpace(formattedLine[formattedLine.length() - 2])) + formattedLine.append(1, ' '); + } + } + else + formattedLine.append(1, ' '); + } + methodAttachCharNum = string::npos; + methodAttachLineNum = 0; + } + // handle parens if (currentChar == '(' || currentChar == '[' || (isInTemplate && currentChar == '<')) { questionMarkStack->push_back(foundQuestionMark); foundQuestionMark = false; parenStack->back()++; if (currentChar == '[') { - ++blockParenCount; - if (getAlignMethodColon() && blockParenCount == 1 && isCStyle()) + ++squareBracketCount; + if (getAlignMethodColon() && squareBracketCount == 1 && isCStyle()) objCColonAlign = findObjCColonAlignment(); } } 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 == ']') { - --blockParenCount; - if (blockParenCount <= 0) + --squareBracketCount; + if (squareBracketCount <= 0) { - blockParenCount = 0; + squareBracketCount = 0; objCColonAlign = 0; } } if (currentChar == ')') { foundCastOperator = false; if (parenStack->back() == 0) endOfAsmReached = true; } } - // handle brackets + // handle braces if (currentChar == '{' || currentChar == '}') { - // if appendOpeningBracket this was already done for the original bracket - if (currentChar == '{' && !appendOpeningBracket) + // if appendOpeningBrace this was already done for the original brace + if (currentChar == '{' && !appendOpeningBrace) { - BracketType newBracketType = getBracketType(); + BraceType newBraceType = getBraceType(); breakCurrentOneLineBlock = false; foundNamespaceHeader = false; foundClassHeader = false; foundStructHeader = false; foundInterfaceHeader = false; foundPreDefinitionHeader = false; foundPreCommandHeader = false; foundPreCommandMacro = false; + foundTrailingReturnType = false; isInPotentialCalculation = false; isInObjCMethodDefinition = false; + isImmediatelyPostObjCMethodPrefix = false; isInObjCInterface = false; isInEnum = false; isJavaStaticConstructor = false; isCharImmediatelyPostNonInStmt = false; - needHeaderOpeningBracket = false; + needHeaderOpeningBrace = false; shouldKeepLineUnbroken = false; + returnTypeChecked = false; objCColonAlign = 0; - - isPreviousBracketBlockRelated = !isBracketType(newBracketType, ARRAY_TYPE); - bracketTypeStack->push_back(newBracketType); - preBracketHeaderStack->push_back(currentHeader); - currentHeader = NULL; + //assert(methodBreakCharNum == string::npos); // comment out + //assert(methodBreakLineNum == 0); // comment out + methodBreakCharNum = string::npos; + methodBreakLineNum = 0; + methodAttachCharNum = string::npos; + methodAttachLineNum = 0; + + isPreviousBraceBlockRelated = !isBraceType(newBraceType, ARRAY_TYPE); + braceTypeStack->emplace_back(newBraceType); + preBraceHeaderStack->emplace_back(currentHeader); + currentHeader = nullptr; structStack->push_back(isInIndentableStruct); - if (isBracketType(newBracketType, STRUCT_TYPE) && isCStyle()) + if (isBraceType(newBraceType, 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) - ); + // this must be done before the braceTypeStack is popped + BraceType braceType = braceTypeStack->back(); + bool isOpeningArrayBrace = (isBraceType(braceType, ARRAY_TYPE) + && braceTypeStack->size() >= 2 + && !isBraceType((*braceTypeStack)[braceTypeStack->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, + // but the block exists immediately before a closing brace, // then there is no need for the post block empty line. isAppendPostBlockEmptyLineRequested = false; if (isInAsm) endOfAsmReached = true; isInAsmOneLine = isInQuote = false; shouldKeepLineUnbroken = false; - blockParenCount = 0; + squareBracketCount = 0; - if (bracketTypeStack->size() > 1) + if (braceTypeStack->size() > 1) { - previousBracketType = bracketTypeStack->back(); - bracketTypeStack->pop_back(); - isPreviousBracketBlockRelated = !isBracketType(bracketType, ARRAY_TYPE); + previousBraceType = braceTypeStack->back(); + braceTypeStack->pop_back(); + isPreviousBraceBlockRelated = !isBraceType(braceType, ARRAY_TYPE); } else { - previousBracketType = NULL_TYPE; - isPreviousBracketBlockRelated = false; + previousBraceType = NULL_TYPE; + isPreviousBraceBlockRelated = false; } - if (!preBracketHeaderStack->empty()) + if (!preBraceHeaderStack->empty()) { - currentHeader = preBracketHeaderStack->back(); - preBracketHeaderStack->pop_back(); + currentHeader = preBraceHeaderStack->back(); + preBraceHeaderStack->pop_back(); } else - currentHeader = NULL; + currentHeader = nullptr; 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 + && (!isBraceType(braceTypeStack->back(), ARRAY_TYPE) // check previous brace + || peekNextChar() == ';')) // check for "};" added V2.01 isImmediatelyPostNonInStmt = true; if (!shouldBreakOneLineStatements && ASBeautifier::getNextWord(currentLine, charNum) == AS_ELSE) { // handle special case of "else" at the end of line size_t nextText = currentLine.find_first_not_of(" \t", charNum + 1); if (ASBeautifier::peekNextChar(currentLine, nextText + 3) == ' ') shouldBreakLineAtNextChar = true; } } - // format brackets - appendOpeningBracket = false; - if (isBracketType(bracketType, ARRAY_TYPE)) + // format braces + appendOpeningBrace = false; + if (isBraceType(braceType, ARRAY_TYPE)) { - formatArrayBrackets(bracketType, isOpeningArrayBracket); + formatArrayBraces(braceType, isOpeningArrayBrace); } else { if (currentChar == '{') - formatOpeningBracket(bracketType); + formatOpeningBrace(braceType); else - formatClosingBracket(bracketType); + formatClosingBrace(braceType); } continue; } - if ((((previousCommandChar == '{' && isPreviousBracketBlockRelated) + if ((((previousCommandChar == '{' && isPreviousBraceBlockRelated) || ((previousCommandChar == '}' && !isImmediatelyPostEmptyBlock - && isPreviousBracketBlockRelated + && isPreviousBraceBlockRelated && !isPreviousCharPostComment // Fixes wrongly appended newlines after '}' immediately after comments && peekNextChar() != ' ' - && !isBracketType(previousBracketType, DEFINITION_TYPE)) - && !isBracketType(bracketTypeStack->back(), DEFINITION_TYPE))) - && isOkToBreakBlock(bracketTypeStack->back())) + && !isBraceType(previousBraceType, DEFINITION_TYPE)) + && !isBraceType(braceTypeStack->back(), DEFINITION_TYPE))) + && isOkToBreakBlock(braceTypeStack->back())) // check for array || (previousCommandChar == '{' // added 9/30/2010 - && isBracketType(bracketTypeStack->back(), ARRAY_TYPE) - && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE) + && isBraceType(braceTypeStack->back(), ARRAY_TYPE) + && !isBraceType(braceTypeStack->back(), SINGLE_LINE_TYPE) && isNonInStatementArray) - // check for pico one line brackets + // check for pico one line braces || (formattingStyle == STYLE_PICO - && (previousCommandChar == '{' && isPreviousBracketBlockRelated) - && isBracketType(bracketTypeStack->back(), COMMAND_TYPE) - && isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE) - && bracketFormatMode == RUN_IN_MODE) + && (previousCommandChar == '{' && isPreviousBraceBlockRelated) + && isBraceType(braceTypeStack->back(), COMMAND_TYPE) + && isBraceType(braceTypeStack->back(), SINGLE_LINE_TYPE) + && braceFormatMode == RUN_IN_MODE) ) { isCharImmediatelyPostOpenBlock = (previousCommandChar == '{'); isCharImmediatelyPostCloseBlock = (previousCommandChar == '}'); if (isCharImmediatelyPostOpenBlock && !isCharImmediatelyPostComment && !isCharImmediatelyPostLineComment) { previousCommandChar = ' '; - if (bracketFormatMode == NONE_MODE) + if (braceFormatMode == NONE_MODE) { - if (isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE) - && (isBracketType(bracketTypeStack->back(), BREAK_BLOCK_TYPE) + if (isBraceType(braceTypeStack->back(), SINGLE_LINE_TYPE) + && (isBraceType(braceTypeStack->back(), BREAK_BLOCK_TYPE) || shouldBreakOneLineBlocks)) isInLineBreak = true; - else if (currentLineBeginsWithBracket) + else if (currentLineBeginsWithBrace) formatRunIn(); else breakLine(); } - else if (bracketFormatMode == RUN_IN_MODE + else if (braceFormatMode == RUN_IN_MODE && currentChar != '#') formatRunIn(); else isInLineBreak = true; } else if (isCharImmediatelyPostCloseBlock && shouldBreakOneLineStatements - && (isLegalNameChar(currentChar) && currentChar != '.') - && !isCharImmediatelyPostComment) + && !isCharImmediatelyPostComment + && ((isLegalNameChar(currentChar) && currentChar != '.') + || currentChar == '+' + || currentChar == '-' + || currentChar == '*' + || currentChar == '&' + || currentChar == '(')) { previousCommandChar = ' '; isInLineBreak = true; } } // reset block handling flags isImmediatelyPostEmptyBlock = false; + // Objective-C method prefix with no return type + if (isImmediatelyPostObjCMethodPrefix && currentChar != '(') + { + if (shouldPadMethodPrefix || shouldUnPadMethodPrefix) + padObjCMethodPrefix(); + isImmediatelyPostObjCMethodPrefix = false; + } + // look for headers bool isPotentialHeader = isCharPotentialHeader(currentLine, charNum); - if (isPotentialHeader && !isInTemplate && !blockParenCount) + if (isPotentialHeader && !isInTemplate && squareBracketCount == 0) { isNonParenHeader = false; foundClosingHeader = false; newHeader = findHeader(headers); + // java can have a 'default' not in a switch + if (newHeader == &AS_DEFAULT + && ASBeautifier::peekNextChar( + currentLine, charNum + (*newHeader).length() - 1) != ':') + newHeader = nullptr; // 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; + newHeader = nullptr; } if (isJavaStyle() && (newHeader == &AS_SYNCHRONIZED)) { // want synchronized statements not synchronized methods - if (!isBracketType(bracketTypeStack->back(), COMMAND_TYPE)) - newHeader = NULL; + if (!isBraceType(braceTypeStack->back(), COMMAND_TYPE)) + newHeader = nullptr; } else if (newHeader == &AS_USING && ASBeautifier::peekNextChar( currentLine, charNum + (*newHeader).length() - 1) != '(') - newHeader = NULL; + newHeader = nullptr; - if (newHeader != NULL) + if (newHeader != nullptr) { foundClosingHeader = isClosingHeader(newHeader); - if (!foundClosingHeader - && ((newHeader == &AS_WHILE && currentHeader == &AS_DO) - || (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; + if (!foundClosingHeader) + { + // these are closing headers + if ((newHeader == &AS_WHILE && currentHeader == &AS_DO) + || (newHeader == &_AS_FINALLY && currentHeader == &_AS_TRY) + || (newHeader == &_AS_EXCEPT && currentHeader == &_AS_TRY)) + foundClosingHeader = true; + // don't append empty block for these related headers + else if (isSharpStyle() + && previousNonWSChar == '}' + && ((newHeader == &AS_SET && currentHeader == &AS_GET) + || (newHeader == &AS_REMOVE && currentHeader == &AS_ADD)) + && isOkToBreakBlock(braceTypeStack->back())) + isAppendPostBlockEmptyLineRequested = false; + } + + // TODO: this can be removed in a future release + // version 3.0 - break erroneous attached header from previous versions + if (isSharpStyle() + && ((newHeader == &AS_SET && currentHeader == &AS_GET) + || (newHeader == &AS_REMOVE && currentHeader == &AS_ADD)) + && !isBraceType(braceTypeStack->back(), SINGLE_LINE_TYPE) + && currentLine[currentLine.find_first_not_of(" \t")] == '}') + isInLineBreak = true; + // END TODO const string* previousHeader = currentHeader; currentHeader = newHeader; - needHeaderOpeningBracket = true; + needHeaderOpeningBrace = true; // is the previous statement on the same line? if ((previousNonWSChar == ';' || previousNonWSChar == ':') && !isInLineBreak - && isOkToBreakBlock(bracketTypeStack->back())) + && isOkToBreakBlock(braceTypeStack->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())) + if (isOkToBreakBlock(braceTypeStack->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; + isNonParenHeader = findHeader(nonParenHeaders) != nullptr; if (isNonParenHeader && (currentHeader == &AS_CATCH || currentHeader == &AS_CASE)) { int startChar = charNum + currentHeader->length() - 1; if (ASBeautifier::peekNextChar(currentLine, startChar) == '(') isNonParenHeader = false; } // 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 && 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()) + && isOkToBreakBlock(braceTypeStack->back()) && !isHeaderInMultiStatementLine) { - if (previousHeader == NULL + if (previousHeader == nullptr && !foundClosingHeader && !isCharImmediatelyPostOpenBlock && !isImmediatelyPostCommentOnly) { isPrependPostBlockEmptyLineRequested = true; } if (isClosingHeader(currentHeader) || foundClosingHeader) { isPrependPostBlockEmptyLineRequested = false; } if (shouldBreakClosingHeaderBlocks && isCharImmediatelyPostCloseBlock && !isImmediatelyPostCommentOnly && !(currentHeader == &AS_WHILE // do-while && foundClosingHeader)) { isPrependPostBlockEmptyLineRequested = true; } } if (currentHeader == &AS_CASE || currentHeader == &AS_DEFAULT) isInCase = true; continue; } - else if ((newHeader = findHeader(preDefinitionHeaders)) != NULL + else if ((newHeader = findHeader(preDefinitionHeaders)) != nullptr && parenStack->back() == 0 && !isInEnum) // not C++11 enum class { if (newHeader == &AS_NAMESPACE || newHeader == &AS_MODULE) foundNamespaceHeader = true; if (newHeader == &AS_CLASS) foundClassHeader = true; if (newHeader == &AS_STRUCT) foundStructHeader = true; - if (newHeader == &AS_INTERFACE) + if (newHeader == &AS_INTERFACE && !foundNamespaceHeader && !foundClassHeader) foundInterfaceHeader = true; foundPreDefinitionHeader = true; appendSequence(*newHeader); goForward(newHeader->length() - 1); continue; } - else if ((newHeader = findHeader(preCommandHeaders)) != NULL) + else if ((newHeader = findHeader(preCommandHeaders)) != nullptr) { - // a 'const' variable is not a preCommandHeader + // must be after function arguments if (previousNonWSChar == ')') foundPreCommandHeader = true; } - else if ((newHeader = findHeader(castOperators)) != NULL) + else if ((newHeader = findHeader(castOperators)) != nullptr) { 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 == ';') { - blockParenCount = 0; + squareBracketCount = 0; + //assert(methodBreakCharNum == string::npos); // comment out + //assert(methodBreakLineNum == 0); // comment out + methodBreakCharNum = string::npos; + methodBreakLineNum = 0; + methodAttachCharNum = string::npos; + methodAttachLineNum = 0; if (((shouldBreakOneLineStatements - || isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)) - && isOkToBreakBlock(bracketTypeStack->back())) - && !(attachClosingBracketMode && peekNextChar() == '}')) + || isBraceType(braceTypeStack->back(), SINGLE_LINE_TYPE)) + && isOkToBreakBlock(braceTypeStack->back())) + && !(attachClosingBraceMode && peekNextChar() == '}')) { passedSemicolon = true; } else if (!shouldBreakOneLineStatements && ASBeautifier::getNextWord(currentLine, charNum) == AS_ELSE) { // handle special case of "else" at the end of line size_t nextText = currentLine.find_first_not_of(" \t", charNum + 1); if (ASBeautifier::peekNextChar(currentLine, nextText + 3) == ' ') passedSemicolon = true; } if (shouldBreakBlocks - && currentHeader != NULL + && currentHeader != nullptr && currentHeader != &AS_CASE && currentHeader != &AS_DEFAULT && !isHeaderInMultiStatementLine && parenStack->back() == 0) { isAppendPostBlockEmptyLineRequested = true; } } if (currentChar != ';' - || (needHeaderOpeningBracket && parenStack->back() == 0)) - currentHeader = NULL; + || (needHeaderOpeningBrace && parenStack->back() == 0)) + currentHeader = nullptr; + 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()) + && isOkToBreakBlock(braceTypeStack->back()) && shouldBreakOneLineStatements && !foundQuestionMark // not in a ?: sequence && !foundPreDefinitionHeader // not in a definition block && previousCommandChar != ')' // not after closing paren of a method header && !foundPreCommandHeader // not after a 'noexcept' - && !blockParenCount // not in objC method call + && squareBracketCount == 0 // 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 - && (blockParenCount > 0 || isInObjCMethodDefinition || isInObjCSelector) + && (squareBracketCount > 0 || isInObjCMethodDefinition || isInObjCSelector) && !foundQuestionMark) // not in a ?: sequence - padObjCMethodColon(); + { + isImmediatelyPostObjCMethodPrefix = false; + isInObjCReturnType = false; + isInObjCParam = true; + if (shouldPadMethodColon) + 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) || findKeyword(currentLine, charNum, AS_DELETE)) { isInPotentialCalculation = false; isImmediatelyPostNewDelete = true; } if (findKeyword(currentLine, charNum, AS_RETURN)) { - isInPotentialCalculation = true; // return is the same as an = sign - isImmediatelyPostReturn = true; + isInPotentialCalculation = true; + isImmediatelyPostReturn = true; // return is the same as an = sign } 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; + if (isCStyle() && findKeyword(currentLine, charNum, AS_AUTO) + && (isBraceType(braceTypeStack->back(), NULL_TYPE) + || isBraceType(braceTypeStack->back(), DEFINITION_TYPE))) + foundTrailingReturnType = true; + + // check for break/attach return type + if (shouldBreakReturnType || shouldBreakReturnTypeDecl + || shouldAttachReturnType || shouldAttachReturnTypeDecl) + { + if ((isBraceType(braceTypeStack->back(), NULL_TYPE) + || isBraceType(braceTypeStack->back(), DEFINITION_TYPE)) + && !returnTypeChecked + && !foundNamespaceHeader + && !foundClassHeader + && !isInObjCMethodDefinition + // bypass objective-C and java @ character + && charNum == (int) currentLine.find_first_not_of(" \t") + && !(isCStyle() && isCharPotentialHeader(currentLine, charNum) + && (findKeyword(currentLine, charNum, AS_PUBLIC) + || findKeyword(currentLine, charNum, AS_PRIVATE) + || findKeyword(currentLine, charNum, AS_PROTECTED)))) + { + findReturnTypeSplitPoint(currentLine); + returnTypeChecked = 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))) + && isNextCharOpeningBrace(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 == '@' + && isCStyle() + && (int) currentLine.length() > charNum + 1 + && !isWhiteSpace(currentLine[charNum + 1]) && isCharPotentialHeader(currentLine, charNum + 1) && findKeyword(currentLine, charNum + 1, AS_INTERFACE) - && isBracketType(bracketTypeStack->back(), NULL_TYPE)) + && isBraceType(braceTypeStack->back(), NULL_TYPE)) { isInObjCInterface = true; string name = '@' + AS_INTERFACE; appendSequence(name); goForward(name.length() - 1); continue; } else if (currentChar == '@' + && isCStyle() + && (int) currentLine.length() > charNum + 1 + && !isWhiteSpace(currentLine[charNum + 1]) && 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 == '+') + && isCStyle() && (int) currentLine.find_first_not_of(" \t") == charNum - && peekNextChar() == '(' - && isBracketType(bracketTypeStack->back(), NULL_TYPE) - && !isInPotentialCalculation) + && !isInPotentialCalculation + && !isInObjCMethodDefinition + && (isBraceType(braceTypeStack->back(), NULL_TYPE) + || (isBraceType(braceTypeStack->back(), EXTERN_TYPE)))) { isInObjCMethodDefinition = true; isImmediatelyPostObjCMethodPrefix = true; + isInObjCParam = false; isInObjCInterface = false; if (getAlignMethodColon()) objCColonAlign = findObjCColonAlignment(); appendCurrentChar(); continue; } // determine if this is a potential calculation bool isPotentialOperator = isCharPotentialOperator(currentChar); - newHeader = NULL; + newHeader = nullptr; if (isPotentialOperator) { newHeader = findOperator(operators); // check for Java ? wildcard - if (newHeader == &AS_GCC_MIN_ASSIGN && isJavaStyle() && isInTemplate) - newHeader = NULL; + if (newHeader != nullptr + && newHeader == &AS_GCC_MIN_ASSIGN + && isJavaStyle() + && isInTemplate) + newHeader = nullptr; - if (newHeader != NULL) + if (newHeader != nullptr) { 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()) + // do NOT use findOperator - the length must be exact!!! + if (find(begin(*assignmentOperators), end(*assignmentOperators), newHeader) + != end(*assignmentOperators)) { 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() + if (newHeader != nullptr && !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()) + if (shouldPadOperators && newHeader != nullptr && !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)) */ + /* && !(isBraceType(braceTypeStack->back(), ARRAY_TYPE)) */ ) { appendCurrentChar(); appendSpaceAfter(); continue; } } // pad parens if (currentChar == '(' || currentChar == ')') { if (currentChar == '(') { if (shouldPadHeader && (isCharImmediatelyPostReturn || isCharImmediatelyPostThrow || isCharImmediatelyPostNewDelete)) appendSpacePad(); } if (shouldPadParensOutside || shouldPadParensInside || shouldUnPadParens || shouldPadFirstParen) padParens(); else appendCurrentChar(); if (isInObjCMethodDefinition) { if (currentChar == '(' && isImmediatelyPostObjCMethodPrefix) { if (shouldPadMethodPrefix || shouldUnPadMethodPrefix) padObjCMethodPrefix(); isImmediatelyPostObjCMethodPrefix = false; isInObjCReturnType = true; } else if (currentChar == ')' && isInObjCReturnType) { if (shouldPadReturnType || shouldUnPadReturnType) padObjCReturnType(); isInObjCReturnType = false; } - else if (shouldPadParamType || shouldUnPadParamType) + else if (isInObjCParam + && (shouldPadParamType || shouldUnPadParamType)) padObjCParamType(); } continue; } // bypass the entire operator - if (newHeader != NULL) + if (newHeader != nullptr) { 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); + bool isInNamespace = isBraceType(braceTypeStack->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; + runInIndentContinuation = runInIndentChars; 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; + runInIndentChars = 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 + * comparison function for BraceType enum */ -bool ASFormatter::isBracketType(BracketType a, BracketType b) const +bool ASFormatter::isBraceType(BraceType a, BraceType 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. + * set the add braces mode. * options: - * true brackets added to headers for single line statements. - * false brackets NOT added to headers for single line statements. + * true braces added to headers for single line statements. + * false braces NOT added to headers for single line statements. * - * @param state the add brackets state. + * @param state the add braces state. */ -void ASFormatter::setAddBracketsMode(bool state) +void ASFormatter::setAddBracesMode(bool state) { - shouldAddBrackets = state; + shouldAddBraces = state; } /** - * set the add one line brackets mode. + * set the add one line braces 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. + * true one line braces added to headers for single line statements. + * false one line braces NOT added to headers for single line statements. * - * @param state the add one line brackets state. + * @param state the add one line braces state. */ -void ASFormatter::setAddOneLineBracketsMode(bool state) +void ASFormatter::setAddOneLineBracesMode(bool state) { - shouldAddBrackets = state; - shouldAddOneLineBrackets = state; + shouldAddBraces = state; + shouldAddOneLineBraces = state; } /** - * set the remove brackets mode. + * set the remove braces mode. * options: - * true brackets removed from headers for single line statements. - * false brackets NOT removed from headers for single line statements. + * true braces removed from headers for single line statements. + * false braces NOT removed from headers for single line statements. * - * @param state the remove brackets state. + * @param state the remove braces state. */ +void ASFormatter::setRemoveBracesMode(bool state) +{ + shouldRemoveBraces = state; +} + +// retained for compatibility with release 2.06 +// "Brackets" have been changed to "Braces" in 3.0 +// it is referenced only by the old "bracket" options +void ASFormatter::setAddBracketsMode(bool state) +{ + setAddBracesMode(state); +} + +// retained for compatibility with release 2.06 +// "Brackets" have been changed to "Braces" in 3.0 +// it is referenced only by the old "bracket" options +void ASFormatter::setAddOneLineBracketsMode(bool state) +{ + setAddOneLineBracesMode(state); +} + +// retained for compatibility with release 2.06 +// "Brackets" have been changed to "Braces" in 3.0 +// it is referenced only by the old "bracket" options void ASFormatter::setRemoveBracketsMode(bool state) { - shouldRemoveBrackets = state; + setRemoveBracesMode(state); +} + +// retained for compatibility with release 2.06 +// "Brackets" have been changed to "Braces" in 3.0 +// it is referenced only by the old "bracket" options +void ASFormatter::setBreakClosingHeaderBracketsMode(bool state) +{ + setBreakClosingHeaderBracesMode(state); } /** - * set the bracket formatting mode. + * set the brace formatting mode. * options: * - * @param mode the bracket formatting mode. + * @param mode the brace formatting mode. */ -void ASFormatter::setBracketFormatMode(BracketMode mode) +void ASFormatter::setBraceFormatMode(BraceMode mode) { - bracketFormatMode = mode; + braceFormatMode = 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 + * set closing header brace 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. + * true braces just before closing headers (e.g. 'else', 'catch') + * will be broken, even if standard braces are attached. + * false closing header braces will be treated as standard braces. * - * @param state the closing header bracket breaking mode. + * @param state the closing header brace breaking mode. */ -void ASFormatter::setBreakClosingHeaderBracketsMode(bool state) +void ASFormatter::setBreakClosingHeaderBracesMode(bool state) { - shouldBreakClosingHeaderBrackets = state; + shouldBreakClosingHeaderBraces = 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 parameter type padding mode. void ASFormatter::setParamTypePaddingMode(bool state) { shouldPadParamType = state; } // set objective-c method parameter type unpadding mode. void ASFormatter::setParamTypeUnPaddingMode(bool state) { shouldUnPadParamType = 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 + * set option to attach closing braces * * @param state true = attach, false = don't attach. */ -void ASFormatter::setAttachClosingBracketMode(bool state) +void ASFormatter::setAttachClosingBraceMode(bool state) { - attachClosingBracketMode = state; + attachClosingBraceMode = state; } /** - * set option to attach class brackets + * set option to attach class braces * * @param state true = attach, false = use style default. */ void ASFormatter::setAttachClass(bool state) { shouldAttachClass = state; } /** - * set option to attach extern "C" brackets + * set option to attach extern "C" braces * * @param state true = attach, false = use style default. */ void ASFormatter::setAttachExternC(bool state) { shouldAttachExternC = state; } /** - * set option to attach namespace brackets + * set option to attach namespace braces * * @param state true = attach, false = use style default. */ void ASFormatter::setAttachNamespace(bool state) { shouldAttachNamespace = state; } /** - * set option to attach inline brackets + * set option to attach inline braces * * @param state true = attach, false = use style default. */ void ASFormatter::setAttachInline(bool state) { shouldAttachInline = state; } +void ASFormatter::setAttachClosingWhile(bool state) +{ + shouldAttachClosingWhile = 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; } /** * set one line headers breaking mode */ void ASFormatter::setBreakOneLineHeadersMode(bool state) { shouldBreakOneLineHeaders = state; } /** * set option to break/not break lines consisting of multiple statements. * * @param state true = break, false = don't break. */ void ASFormatter::setBreakOneLineStatementsMode(bool state) { shouldBreakOneLineStatements = state; } void ASFormatter::setCloseTemplatesMode(bool state) { shouldCloseTemplates = 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; } +void ASFormatter::setBreakReturnType(bool state) +{ + shouldBreakReturnType = state; +} + +void ASFormatter::setBreakReturnTypeDecl(bool state) +{ + shouldBreakReturnTypeDecl = state; +} + +void ASFormatter::setAttachReturnType(bool state) +{ + shouldAttachReturnType = state; +} + +void ASFormatter::setAttachReturnTypeDecl(bool state) +{ + shouldAttachReturnTypeDecl = 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()) { endOfCodeReached = true; return false; } - if (appendOpeningBracket) - currentLine = "{"; // append bracket that was removed from the previous line + if (appendOpeningBrace) + currentLine = "{"; // append brace 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 + if (methodBreakLineNum > 0) + --methodBreakLineNum; + if (methodAttachLineNum > 0) + --methodAttachLineNum; + // 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 (isInBracketRunIn && previousNonWSChar == '{' && !isInComment) + if (isInBraceRunIn && previousNonWSChar == '{' && !isInComment) isInLineBreak = false; - isInBracketRunIn = false; + isInBraceRunIn = false; if (currentChar == '\t' && shouldConvertTabs) convertTabToSpaces(); - // check for an empty line inside a command bracket. + // check for an empty line inside a command brace. // if yes then read the next line (calls getNextLine recursively). // must be after initNewLine. if (shouldDeleteEmptyLines && lineIsEmpty - && isBracketType((*bracketTypeStack)[bracketTypeStack->size() - 1], COMMAND_TYPE)) + && isBraceType((*braceTypeStack)[braceTypeStack->size() - 1], COMMAND_TYPE)) { if (!shouldBreakBlocks || previousNonWSChar == '{' || !commentAndHeaderFollows()) { isInPreprocessor = isImmediatelyPostPreprocessor; // restore lineIsEmpty = false; return getNextLine(true); } } return true; } /** * 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; + currentLineBeginsWithBrace = false; lineIsEmpty = false; - currentLineFirstBracketNum = string::npos; + currentLineFirstBraceNum = 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; + currentLineBeginsWithBrace = true; + currentLineFirstBraceNum = 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. '{') + * check if the currently reached open-brace (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. + * is an opening brace. * * @return the type of the opened block. */ -BracketType ASFormatter::getBracketType() +BraceType ASFormatter::getBraceType() { assert(currentChar == '{'); - BracketType returnVal = NULL_TYPE; + BraceType returnVal = NULL_TYPE; if ((previousNonWSChar == '=' - || isBracketType(bracketTypeStack->back(), ARRAY_TYPE)) + || isBraceType(braceTypeStack->back(), ARRAY_TYPE)) && previousCommandChar != ')' && !isNonParenHeader) returnVal = ARRAY_TYPE; else if (foundPreDefinitionHeader && previousCommandChar != ')') { returnVal = DEFINITION_TYPE; if (foundNamespaceHeader) - returnVal = (BracketType)(returnVal | NAMESPACE_TYPE); + returnVal = (BraceType)(returnVal | NAMESPACE_TYPE); else if (foundClassHeader) - returnVal = (BracketType)(returnVal | CLASS_TYPE); + returnVal = (BraceType)(returnVal | CLASS_TYPE); else if (foundStructHeader) - returnVal = (BracketType)(returnVal | STRUCT_TYPE); + returnVal = (BraceType)(returnVal | STRUCT_TYPE); else if (foundInterfaceHeader) - returnVal = (BracketType)(returnVal | INTERFACE_TYPE); + returnVal = (BraceType)(returnVal | INTERFACE_TYPE); } else if (isInEnum) { - returnVal = (BracketType)(ARRAY_TYPE | ENUM_TYPE); + returnVal = (BraceType)(ARRAY_TYPE | ENUM_TYPE); } else { bool isCommandType = (foundPreCommandHeader || foundPreCommandMacro - || (currentHeader != NULL && isNonParenHeader) + || (currentHeader != nullptr && isNonParenHeader) || (previousCommandChar == ')') || (previousCommandChar == ':' && !foundQuestionMark) || (previousCommandChar == ';') || ((previousCommandChar == '{' || previousCommandChar == '}') - && isPreviousBracketBlockRelated) + && isPreviousBraceBlockRelated) || (isInClassInitializer - && (!isLegalNameChar(previousNonWSChar) || foundPreCommandHeader)) + && ((!isLegalNameChar(previousNonWSChar) && previousNonWSChar != '(') + || foundPreCommandHeader)) + || foundTrailingReturnType || 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); if (foundOneLineBlock == 2 && returnVal == COMMAND_TYPE) returnVal = ARRAY_TYPE; if (foundOneLineBlock > 0) { - returnVal = (BracketType) (returnVal | SINGLE_LINE_TYPE); + returnVal = (BraceType) (returnVal | SINGLE_LINE_TYPE); if (breakCurrentOneLineBlock) - returnVal = (BracketType) (returnVal | BREAK_BLOCK_TYPE); + returnVal = (BraceType) (returnVal | BREAK_BLOCK_TYPE); if (foundOneLineBlock == 3) - returnVal = (BracketType)(returnVal | EMPTY_BLOCK_TYPE); + returnVal = (BraceType)(returnVal | EMPTY_BLOCK_TYPE); } - if (isBracketType(returnVal, ARRAY_TYPE)) + if (isBraceType(returnVal, ARRAY_TYPE)) { - if (isNonInStatementArrayBracket()) + if (isNonInStatementArrayBrace()) { - returnVal = (BracketType)(returnVal | ARRAY_NIS_TYPE); + returnVal = (BraceType)(returnVal | ARRAY_NIS_TYPE); isNonInStatementArray = true; isImmediatelyPostNonInStmt = false; // in case of "},{" - nonInStatementBracket = formattedLine.length() - 1; + nonInStatementBrace = formattedLine.length() - 1; } - if (isUniformInitializerBracket()) - returnVal = (BracketType)(returnVal | INIT_TYPE); + if (isUniformInitializerBrace()) + returnVal = (BraceType)(returnVal | INIT_TYPE); } return returnVal; } +bool ASFormatter::isNumericVariable(string word) const +{ + if (word == "bool" + || word == "int" + || word == "void" + || word == "char" + || word == "long" + || word == "short" + || word == "double" + || word == "float" + || (word.length() >= 4 // check end of word for _t + && word.compare(word.length() - 2, 2, "_t") == 0) +// removed release 3.1 +// || word == "Int32" +// || word == "UInt32" +// || word == "Int64" +// || word == "UInt64" + || word == "BOOL" + || word == "DWORD" + || word == "HWND" + || word == "INT" + || word == "LPSTR" + || word == "VOID" + || word == "LPVOID" + || word == "wxFontEncoding" + ) + return true; + return false; +} + /** * 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 == '~') + || isDigit(nextText[0]) + || nextText[0] == '!' + || nextText[0] == '~') return false; // check for multiply then a dereference (a * *b) + char nextChar = peekNextChar(); if (currentChar == '*' - && charNum < (int) currentLine.length() - 1 - && isWhiteSpace(currentLine[charNum + 1]) - && nextChar == '*') + && nextChar == '*' + && !isPointerToPointer(currentLine, charNum)) 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 == '&') { + if (lastWord == AS_AUTO) + return true; if (previousNonWSChar == '>') return true; - string followingText = peekNextText(currentLine.substr(charNum + 2)); + string followingText; + if ((int) currentLine.length() > charNum + 2) + followingText = peekNextText(currentLine.substr(charNum + 2)); if (followingText.length() > 0 && followingText[0] == ')') return true; - if (currentHeader != NULL || isInPotentialCalculation) + if (currentHeader != nullptr || isInPotentialCalculation) return false; - if (parenStack->back() > 0 && isBracketType(bracketTypeStack->back(), COMMAND_TYPE)) + if (parenStack->back() > 0 && isBraceType(braceTypeStack->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) + if (isBraceType(braceTypeStack->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 + if (followingOperator != nullptr && followingOperator != &AS_MULT && followingOperator != &AS_BIT_AND) { if (followingOperator == &AS_ASSIGN || followingOperator == &AS_COLON) return true; return false; } - if (isBracketType(bracketTypeStack->back(), COMMAND_TYPE) - || blockParenCount > 0) + if (isBraceType(braceTypeStack->back(), COMMAND_TYPE) + || squareBracketCount > 0) return false; 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) + && (isBraceType(braceTypeStack->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 &*) + // check for reference to a pointer *& if ((currentChar == '*' && nextChar == '&') || (previousNonWSChar == '*' && currentChar == '&')) return false; - if (!isBracketType(bracketTypeStack->back(), COMMAND_TYPE) + if (!isBraceType(braceTypeStack->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 +bool ASFormatter::isPointerOrReferenceVariable(const string& word) const { return (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"); } +/** + * Check if * * is a pointer to a pointer or a multiply then a dereference. + * + * @return true if a pointer *. + */ +bool ASFormatter::isPointerToPointer(const string& line, int currPos) const +{ + assert(line[currPos] == '*' && peekNextChar() == '*'); + if ((int) line.length() > currPos + 1 && line[currPos + 1] == '*') + return true; + size_t nextText = line.find_first_not_of(" \t", currPos + 1); + if (nextText == string::npos || line[nextText] != '*') + return false; + size_t nextText2 = line.find_first_not_of(" \t", nextText + 1); + if (nextText == string::npos) + return false; + if (line[nextText2] == ')' || line[nextText2] == '*') + 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 == '-'); + // does a digit follow a c-style cast + if (previousCommandChar == ')') + { + if (!isdigit(peekNextChar())) + return false; + size_t end = currentLine.rfind(')', charNum); + if (end == string::npos) + return false; + size_t lastChar = currentLine.find_last_not_of(" \t", end - 1); + if (lastChar == string::npos) + return false; + if (currentLine[lastChar] == '*') + end = lastChar; + string prevWord = getPreviousWord(currentLine, end); + if (prevWord.empty()) + return false; + if (!isNumericVariable(prevWord)) + return false; + return true; + } + 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->empty()) - for (size_t i = 1; i < preBracketHeaderStack->size(); i++) - if (preBracketHeaderStack->at(i) == &AS_SWITCH) + if (!preBraceHeaderStack->empty()) + for (size_t i = 1; i < preBraceHeaderStack->size(); i++) + if (preBraceHeaderStack->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 == '-'); if (charNum >= 2) { char prevPrevFormattedChar = currentLine[charNum - 2]; char prevFormattedChar = currentLine[charNum - 1]; return ((prevFormattedChar == 'e' || prevFormattedChar == 'E') && (prevPrevFormattedChar == '.' || isDigit(prevPrevFormattedChar))); } return false; } /** - * check if an array bracket should NOT have an in-statement indent + * check if an array brace should NOT have an in-statement indent * * @return the array is non in-statement */ -bool ASFormatter::isNonInStatementArrayBracket() const +bool ASFormatter::isNonInStatementArrayBrace() 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 + // if this opening brace begins the line there will be no inStatement indent + if (currentLineBeginsWithBrace + && (size_t) charNum == currentLineFirstBraceNum && nextChar != '}') returnVal = true; - // if an opening bracket ends the line there will be no inStatement indent + // if an opening brace 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 block has been reached, * i.e. if the currently reached '{' character is closed * with a complimentary '}' elsewhere on the current line, *. * @return 0 = one-line block has not been reached. * 1 = one-line block has been reached. * 2 = one-line block has been reached and is followed by a comma. * 3 = one-line block has been reached and is an empty block. */ int ASFormatter::isOneLineBlockReached(const string& line, int startChar) const { assert(line[startChar] == '{'); bool isInComment_ = false; bool isInQuote_ = false; bool hasText = false; - int bracketCount = 0; + int braceCount = 0; int lineLength = line.length(); char quoteChar_ = ' '; char ch = ' '; char prevCh = ' '; for (int i = startChar; 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_) + if (ch == '\\') + ++i; + else 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; + ++braceCount; continue; } if (ch == '}') { - --bracketCount; - if (bracketCount == 0) + --braceCount; + if (braceCount == 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; } if (!hasText) return 3; // is an empty block return 1; } } if (ch == ';') continue; if (!isWhiteSpace(ch)) { hasText = true; 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. + * peek at the next char to determine if it is an opening brace. * 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. + * @return true if the next word is an opening brace. */ -bool ASFormatter::isNextCharOpeningBracket(int startChar) const +bool ASFormatter::isNextCharOpeningBrace(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. +* Determine if an opening array-type brace should have a leading space pad. * This is to identify C++11 uniform initializers. */ -bool ASFormatter::isUniformInitializerBracket() const +bool ASFormatter::isUniformInitializerBrace() const { if (isCStyle() && !isInEnum && !isImmediatelyPostPreprocessor) { if (isInClassInitializer - || isLegalNameChar(previousNonWSChar)) + || isLegalNameChar(previousNonWSChar) + || previousNonWSChar == '(') return true; } return false; } /** * Determine if there is a following statement on the current line. */ bool ASFormatter::isMultiStatementLine() const { assert((isImmediatelyPostHeader || foundClosingHeader)); bool isInComment_ = false; bool isInQuote_ = false; int semiCount_ = 0; int parenCount_ = 0; - int bracketCount_ = 0; + int braceCount_ = 0; for (size_t i = 0; i < currentLine.length(); i++) { if (isInComment_) { if (currentLine.compare(i, 2, "*/") == 0) { isInComment_ = false; continue; } } if (currentLine.compare(i, 2, "/*") == 0) { isInComment_ = true; continue; } if (currentLine.compare(i, 2, "//") == 0) return false; if (isInQuote_) { if (currentLine[i] == '"' || currentLine[i] == '\'') isInQuote_ = false; continue; } if (currentLine[i] == '"' || currentLine[i] == '\'') { isInQuote_ = true; continue; } if (currentLine[i] == '(') { ++parenCount_; continue; } if (currentLine[i] == ')') { --parenCount_; continue; } if (parenCount_ > 0) continue; if (currentLine[i] == '{') { - ++bracketCount_; + ++braceCount_; } if (currentLine[i] == '}') { - --bracketCount_; + --braceCount_; } - if (bracketCount_ > 0) + if (braceCount_ > 0) continue; if (currentLine[i] == ';') { ++semiCount_; if (semiCount_ > 1) return true; continue; } } 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 +string ASFormatter::peekNextText(const string& firstLine, + bool endOnEmptyLine /*false*/, + shared_ptr streamArg /*nullptr*/) const { + assert(sourceIterator->getPeekStart() == 0 || streamArg != nullptr); // Borland may need != 0 bool isFirstLine = true; - bool needReset = shouldReset; string nextLine_ = firstLine; size_t firstChar = string::npos; + shared_ptr stream = streamArg; + if (stream == nullptr) // Borland may need == 0 + stream = make_shared(sourceIterator); // find the first non-blank text, bypassing all comments. bool isInComment_ = false; - while (sourceIterator->hasMoreLines() || isFirstLine) + while (stream->hasMoreLines() || isFirstLine) { if (isFirstLine) isFirstLine = false; else - { - nextLine_ = sourceIterator->peekNextLine(); - needReset = true; - } + nextLine_ = stream->peekNextLine(); 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() { assert(spacePadNum != 0); assert(isSequenceReached("//") || isSequenceReached("/*")); // block comment must be closed on this line with nothing after it if (isSequenceReached("/*")) { size_t endNum = currentLine.find("*/", charNum + 2); if (endNum == string::npos) return; - if (currentLine.find_first_not_of(" \t", endNum + 2) != string::npos) + // following line comments may be a tag from AStyleWx //[[)> + size_t nextNum = currentLine.find_first_not_of(" \t", endNum + 2); + if (nextNum != string::npos + && currentLine.compare(nextNum, 2, "//") != 0) 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 + * append the current brace inside the end of line comments + * currentChar contains the brace, it will be appended to formattedLine * formattedLineCommentNum is the comment location on formattedLine */ void ASFormatter::appendCharInsideComments() { if (formattedLineCommentNum == string::npos // does the comment start on the previous line? || formattedLineCommentNum == 0) { 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 + // insert the brace 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; } /** * 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); + assert(newOperator != nullptr); + char nextNonWSChar = ASBase::peekNextChar(currentLine, charNum); 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 || blockParenCount)) + || isInObjCSelector || squareBracketCount != 0)) && !(newOperator == &AS_MINUS && isInExponent()) && !(newOperator == &AS_PLUS && isInExponent()) && !((newOperator == &AS_PLUS || newOperator == &AS_MINUS) // check for unary plus or minus && (previousNonWSChar == '(' || previousNonWSChar == '[' || previousNonWSChar == '=' || previousNonWSChar == ',' || previousNonWSChar == ':' || previousNonWSChar == '{')) - && !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 -> && !(newOperator == &AS_MULT && peekNextChar() == '>') && !((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 + && isJavaStyle() && (previousNonWSChar == '<' - || ASBase::peekNextChar(currentLine, charNum) == '>' - || ASBase::peekNextChar(currentLine, charNum) == '.')) + || nextNonWSChar == '>' + || nextNonWSChar == '.')) + && !(newOperator == &AS_QUESTION // check for C# null conditional operator + && isSharpStyle() + && (nextNonWSChar == '.' + || nextNonWSChar == '[')) + && !isCharImmediatelyPostOperator && !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; } /** * 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() { assert(currentChar == '*' || currentChar == '&' || currentChar == '^'); assert(!isJavaStyle()); int pa = pointerAlignment; int ra = referenceAlignment; - int itemAlignment = (currentChar == '*' || currentChar == '^') ? pa : ((ra == REF_SAME_AS_PTR) ? pa : ra); + int itemAlignment = (currentChar == '*' || currentChar == '^') + ? pa : ((ra == REF_SAME_AS_PTR) ? pa : ra); // check for ** and && + int ptrLength = 1; char peekedChar = peekNextChar(); if ((currentChar == '*' && peekedChar == '*') || (currentChar == '&' && peekedChar == '&')) { + ptrLength = 2; 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); + formattedLine.append(currentLine.substr(charNum, ptrLength)); + if (ptrLength > 1) + goForward(ptrLength - 1); } } /** * 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 + string sequenceToInsert(1, currentChar); + // get the sequence + if (currentChar == peekNextChar()) { - // 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); + for (size_t i = charNum + 1; currentLine.length() > i; i++) + { + if (currentLine[i] == sequenceToInsert[0]) + { + sequenceToInsert.append(1, currentLine[i]); + goForward(1); + continue; + } + break; + } } - if (isSequenceReached("**") || isSequenceReached("&&")) + // append the seqence + string charSave; + size_t prevCh = formattedLine.find_last_not_of(" \t"); + if (prevCh < formattedLine.length()) { - if (formattedLine.length() == 1) - formattedLine.append(1, currentChar); - else - formattedLine.insert(prevCh + 2, 1, currentChar); - goForward(1); + charSave = formattedLine.substr(prevCh + 1); + formattedLine.resize(prevCh + 1); } + formattedLine.append(sequenceToInsert); + if (peekNextChar() != ')') + formattedLine.append(charSave); + else + spacePadNum -= charSave.length(); // 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) + if (maxCodeLength != string::npos && formattedLine.length() > 0) { 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("&&")) + if (currentChar == peekNextChar()) { - sequenceToInsert = "&&"; - goForward(1); + for (size_t i = charNum + 1; currentLine.length() > i; i++) + { + if (currentLine[i] == sequenceToInsert[0]) + { + sequenceToInsert.append(1, currentLine[i]); + goForward(1); + continue; + } + break; + } } // 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); + if (index < formattedLine.length()) + formattedLine.insert(index, sequenceToInsert); + else + formattedLine.append(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("**")) + if (currentChar == peekNextChar()) { - sequenceToInsert = "**"; - goForward(1); - } - else if (isSequenceReached("&&")) - { - sequenceToInsert = "&&"; - goForward(1); + for (size_t i = charNum + 1; currentLine.length() > i; i++) + { + if (currentLine[i] == sequenceToInsert[0]) + { + sequenceToInsert.append(1, currentLine[i]); + goForward(1); + continue; + } + break; + } } // 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() + if ((isLegalNameChar(peekedChar) || peekedChar == '(' || peekedChar == '[' || peekedChar == '=') && (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); + size_t start = currentLine.find_first_not_of("( \t", i); if (start != string::npos && currentLine[start] != ')') break; } goForward(1); if (formattedLine.length() > 0) - formattedLine.append(1, currentLine[i]); + formattedLine.append(1, currentLine[charNum]); 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]) + && peekedChar != '*' // check for '* *' && !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() { assert(currentChar == '*' || currentChar == '&' || currentChar == '^'); assert(!isJavaStyle()); int pa = pointerAlignment; int ra = referenceAlignment; - int itemAlignment = (currentChar == '*' || currentChar == '^') ? pa : ((ra == REF_SAME_AS_PTR) ? pa : ra); + 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 != '(') + if (itemAlignment == PTR_ALIGN_TYPE && currentChar == '*' && prevCh == '*') + { + // '* *' may be a multiply followed by a dereference + if (prevNum + 2 < formattedLine.length() + && isWhiteSpace(formattedLine[prevNum + 2])) + { + spacePadNum -= (formattedLine.length() - 2 - prevNum); + formattedLine.erase(prevNum + 2); + } + } + else 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() { 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 last char is a brace 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; + const string* prevWordH = nullptr; if (shouldPadHeader && prevWord.length() > 0 && isCharPotentialHeader(prevWord, 0)) - prevWordH = ASBeautifier::findHeader(prevWord, 0, headers); - if (prevWordH != NULL) - prevIsParenHeader = true; - else if (prevWord == AS_RETURN) // don't unpad - prevIsParenHeader = true; + prevWordH = ASBase::findHeader(prevWord, 0, headers); + if (prevWordH != nullptr) + prevIsParenHeader = true; // don't unpad + else if (prevWord == AS_RETURN) + prevIsParenHeader = true; // don't unpad else if ((prevWord == AS_NEW || prevWord == AS_DELETE) - && shouldPadHeader) // don't unpad - prevIsParenHeader = true; - else if (isCStyle() && prevWord == AS_THROW && shouldPadHeader) // don't unpad - prevIsParenHeader = true; - else if (prevWord == "and" || prevWord == "or") // don't unpad - prevIsParenHeader = true; + && shouldPadHeader) + prevIsParenHeader = true; // don't unpad + else if (isCStyle() && prevWord == AS_THROW && shouldPadHeader) + prevIsParenHeader = true; // don't unpad + else if (prevWord == "and" || prevWord == "or" || prevWord == "in") + prevIsParenHeader = true; // don't unpad // don't unpad variables - else if (prevWord == "bool" - || prevWord == "int" - || prevWord == "void" - || prevWord == "void*" - || prevWord == "char" - || 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; - } + else if (isNumericVariable(prevWord)) + prevIsParenHeader = true; // don't unpad } } // 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(); } } /** -* add or remove space padding to objective-c parens +* add or remove space padding to objective-c method prefix (- or +) +* if this is a '(' it begins a return type * these options have precedence over the padParens methods * the padParens method has already been called, this method adjusts */ void ASFormatter::padObjCMethodPrefix() { - assert(currentChar == '(' && isImmediatelyPostObjCMethodPrefix); + assert(isInObjCMethodDefinition && isImmediatelyPostObjCMethodPrefix); assert(shouldPadMethodPrefix || shouldUnPadMethodPrefix); 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; + size_t firstChar = formattedLine.find_first_not_of(" \t", prefix + 1); + if (firstChar == string::npos) + firstChar = formattedLine.length(); + int spaces = firstChar - prefix - 1; if (shouldPadMethodPrefix) { if (spaces == 0) { formattedLine.insert(prefix + 1, 1, ' '); spacePadNum += 1; } else if (spaces > 1) { formattedLine.erase(prefix + 1, spaces - 1); + formattedLine[prefix + 1] = ' '; // convert any tab to space 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; } } } /** * 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::padObjCReturnType() { assert(currentChar == ')' && isInObjCReturnType); assert(shouldPadReturnType || shouldUnPadReturnType); 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); + currentLine[charNum + 1] = ' '; // convert any tab to space 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"); + spacePadNum -= formattedLine.length() - lastText - 1; formattedLine.resize(lastText + 1); } - if (spaces > 0) - { - // do not use goForward here - currentLine.erase(charNum + 1, spaces); - spacePadNum -= spaces; - } + // do not use goForward here + currentLine.erase(charNum + 1, spaces); + spacePadNum -= spaces; } } /** * 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::padObjCParamType() { assert((currentChar == '(' || currentChar == ')') && isInObjCMethodDefinition); assert(!isImmediatelyPostObjCMethodPrefix && !isInObjCReturnType); assert(shouldPadParamType || shouldUnPadParamType); if (currentChar == '(') { // open paren has already been attached to formattedLine by padParen size_t paramOpen = formattedLine.rfind('('); assert(paramOpen != string::npos); size_t prevText = formattedLine.find_last_not_of(" \t", paramOpen - 1); if (prevText == string::npos) return; int spaces = paramOpen - prevText - 1; if (shouldPadParamType || objCColonPadMode == COLON_PAD_ALL || objCColonPadMode == COLON_PAD_AFTER) { if (spaces == 0) { formattedLine.insert(paramOpen, 1, ' '); spacePadNum += 1; } if (spaces > 1) { formattedLine.erase(prevText + 1, spaces - 1); + formattedLine[prevText + 1] = ' '; // convert any tab to space spacePadNum -= spaces - 1; } } // this option will be ignored if used with pad-param-type else if (shouldUnPadParamType || objCColonPadMode == COLON_PAD_NONE || objCColonPadMode == COLON_PAD_BEFORE) { if (spaces > 0) { formattedLine.erase(prevText + 1, spaces); spacePadNum -= spaces; } } } else if (currentChar == ')') { size_t nextText = currentLine.find_first_not_of(" \t", charNum + 1); if (nextText == string::npos) return; int spaces = nextText - charNum - 1; if (shouldPadParamType) { 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); + currentLine[charNum + 1] = ' '; // convert any tab to space spacePadNum -= spaces - 1; } } // this option will be ignored if used with pad-param-type else if (shouldUnPadParamType) { // this will already be padded if pad-paren is used if (formattedLine[formattedLine.length() - 1] == ' ') { spacePadNum -= 1; 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 + * format opening brace as attached or broken + * currentChar contains the brace + * the braces 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. + * @param braceType the type of brace to be formatted. */ -void ASFormatter::formatOpeningBracket(BracketType bracketType) +void ASFormatter::formatOpeningBrace(BraceType braceType) { - assert(!isBracketType(bracketType, ARRAY_TYPE)); + assert(!isBraceType(braceType, ARRAY_TYPE)); assert(currentChar == '{'); - parenStack->push_back(0); + parenStack->emplace_back(0); - bool breakBracket = isCurrentBracketBroken(); + bool breakBrace = isCurrentBraceBroken(); - if (breakBracket) + if (breakBrace) { - if (isBeforeAnyComment() && isOkToBreakBlock(bracketType)) + if (isBeforeAnyComment() && isOkToBreakBlock(braceType) && sourceIterator->hasMoreLines()) { // if comment is at line end leave the comment on this line - if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBracket) + if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBrace) { - currentChar = ' '; // remove bracket from current line + currentChar = ' '; // remove brace from current line if (parenStack->size() > 1) parenStack->pop_back(); currentLine[charNum] = currentChar; - appendOpeningBracket = true; // append bracket to following line + appendOpeningBrace = true; // append brace to following line } - // else put comment after the bracket + // else put comment after the brace else if (!isBeforeMultipleLineEndComments(charNum)) breakLine(); } - else if (!isBracketType(bracketType, SINGLE_LINE_TYPE)) + else if (!isBraceType(braceType, SINGLE_LINE_TYPE)) { formattedLine = rtrim(formattedLine); breakLine(); } - else if ((shouldBreakOneLineBlocks || isBracketType(bracketType, BREAK_BLOCK_TYPE)) - && !isBracketType(bracketType, EMPTY_BLOCK_TYPE)) + else if ((shouldBreakOneLineBlocks || isBraceType(braceType, BREAK_BLOCK_TYPE)) + && !isBraceType(braceType, EMPTY_BLOCK_TYPE)) breakLine(); else if (!isInLineBreak) appendSpacePad(); appendCurrentChar(); - // should a following comment break from the bracket? - // must break the line AFTER the bracket + // should a following comment break from the brace? + // must break the line AFTER the brace if (isBeforeComment() && formattedLine.length() > 0 && formattedLine[0] == '{' - && isOkToBreakBlock(bracketType) - && (bracketFormatMode == BREAK_MODE - || bracketFormatMode == LINUX_MODE)) + && isOkToBreakBlock(braceType) + && (braceFormatMode == BREAK_MODE + || braceFormatMode == LINUX_MODE)) { shouldBreakLineAtNextChar = true; } } - else // attach bracket + else // attach brace { - // are there comments before the bracket? + // are there comments before the brace? if (isCharImmediatelyPostComment || isCharImmediatelyPostLineComment) { - if (isOkToBreakBlock(bracketType) + if (isOkToBreakBlock(braceType) && !(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) + else if (isOkToBreakBlock(braceType) && !(isImmediatelyPostPreprocessor - && currentLineBeginsWithBracket)) + && currentLineBeginsWithBrace)) { - if (!isBracketType(bracketType, EMPTY_BLOCK_TYPE)) + if (!isBraceType(braceType, EMPTY_BLOCK_TYPE)) { appendSpacePad(); appendCurrentChar(false); // OK to attach testForTimeToSplitFormattedLine(); // line length will have changed - // should a following comment attach with the bracket? + // should a following comment attach with the brace? // insert spaces to reposition the comment if (isBeforeComment() && !isBeforeMultipleLineEndComments(charNum) - && (!isBeforeAnyLineEndComment(charNum) || currentLineBeginsWithBracket)) + && (!isBeforeAnyLineEndComment(charNum) || currentLineBeginsWithBrace)) { shouldBreakLineAtNextChar = true; currentLine.insert(charNum + 1, charNum + 1, ' '); } else if (!isBeforeAnyComment()) // added in release 2.03 { shouldBreakLineAtNextChar = true; } } else { - if (currentLineBeginsWithBracket && charNum == (int) currentLineFirstBracketNum) + if (currentLineBeginsWithBrace && (size_t) charNum == currentLineFirstBraceNum) { 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 + * format closing brace + * currentChar contains the brace * the calling function should have a continue statement after calling this method * - * @param bracketType the type of the opening bracket for this closing bracket. + * @param braceType the type of the opening brace for this closing brace. */ -void ASFormatter::formatClosingBracket(BracketType bracketType) +void ASFormatter::formatClosingBrace(BraceType braceType) { - assert(!isBracketType(bracketType, ARRAY_TYPE)); + assert(!isBraceType(braceType, 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}'). + // this state will be used for locating braces that appear immediately AFTER an empty block (e.g. '{} \n}'). if (previousCommandChar == '{') isImmediatelyPostEmptyBlock = true; - if (attachClosingBracketMode) + if (attachClosingBraceMode) { // 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 != '{') +// || (isBraceType(braceType, CLASS_TYPE) && isOkToBreakBlock(braceType) && previousNonWSChar != '{') +// || (isBraceType(braceType, NAMESPACE_TYPE) && isOkToBreakBlock(braceType) && previousNonWSChar != '{') ) - && (!isBracketType(bracketType, SINGLE_LINE_TYPE) || isOkToBreakBlock(bracketType))) + && (!isBraceType(braceType, SINGLE_LINE_TYPE) || isOkToBreakBlock(braceType))) { breakLine(); appendCurrentChar(); // don't attach } else { if (previousNonWSChar != '{' - && (!isBracketType(bracketType, SINGLE_LINE_TYPE) - || isOkToBreakBlock(bracketType))) + && (!isBraceType(braceType, SINGLE_LINE_TYPE) + || isOkToBreakBlock(braceType))) appendSpacePad(); appendCurrentChar(false); // attach } } - else if (!isBracketType(bracketType, EMPTY_BLOCK_TYPE) - && (isBracketType(bracketType, BREAK_BLOCK_TYPE) - || isOkToBreakBlock(bracketType))) + else if (!isBraceType(braceType, EMPTY_BLOCK_TYPE) + && (isBraceType(braceType, BREAK_BLOCK_TYPE) + || isOkToBreakBlock(braceType))) { breakLine(); appendCurrentChar(); } else { appendCurrentChar(); } // if a declaration follows a definition, space pad if (isLegalNameChar(peekNextChar())) appendSpaceAfter(); if (shouldBreakBlocks - && currentHeader != NULL + && currentHeader != nullptr && !isHeaderInMultiStatementLine && parenStack->back() == 0) { if (currentHeader == &AS_CASE || currentHeader == &AS_DEFAULT) { - // do not yet insert a line if "break" statement is outside the brackets + // do not yet insert a line if "break" statement is outside the braces 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 + * format array braces as attached or broken + * determine if the braces can have an inStatement indent + * currentChar contains the brace + * the braces 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. + * @param braceType the type of brace to be formatted, must be an ARRAY_TYPE. + * @param isOpeningArrayBrace indicates if this is the opening brace for the array block. */ -void ASFormatter::formatArrayBrackets(BracketType bracketType, bool isOpeningArrayBracket) +void ASFormatter::formatArrayBraces(BraceType braceType, bool isOpeningArrayBrace) { - assert(isBracketType(bracketType, ARRAY_TYPE)); + assert(isBraceType(braceType, ARRAY_TYPE)); assert(currentChar == '{' || currentChar == '}'); if (currentChar == '{') { - // is this the first opening bracket in the array? - if (isOpeningArrayBracket) + // is this the first opening brace in the array? + if (isOpeningArrayBrace) { - if (bracketFormatMode == ATTACH_MODE - || bracketFormatMode == LINUX_MODE) + if (braceFormatMode == ATTACH_MODE + || braceFormatMode == LINUX_MODE) { // break an enum if mozilla - if (isBracketType(bracketType, ENUM_TYPE) + if (isBraceType(braceType, ENUM_TYPE) && formattingStyle == STYLE_MOZILLA) { isInLineBreak = true; appendCurrentChar(); // don't attach } // don't attach to a preprocessor directive or '\' line else if ((isImmediatelyPostPreprocessor || (formattedLine.length() > 0 && formattedLine[formattedLine.length() - 1] == '\\')) - && currentLineBeginsWithBracket) + && currentLineBeginsWithBrace) { isInLineBreak = true; appendCurrentChar(); // don't attach } else if (isCharImmediatelyPostComment) { - // TODO: attach bracket to line-end comment + // TODO: attach brace to line-end comment appendCurrentChar(); // don't attach } - else if (isCharImmediatelyPostLineComment && !isBracketType(bracketType, SINGLE_LINE_TYPE)) + else if (isCharImmediatelyPostLineComment && !isBraceType(braceType, 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)) + // if brace is broken or not an assignment + if (currentLineBeginsWithBrace + && !isBraceType(braceType, 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) + if (currentLineBeginsWithBrace + && currentLineFirstBraceNum == (size_t) charNum) shouldBreakLineAtNextChar = true; } else { if (previousNonWSChar != '(') { // don't space pad C++11 uniform initialization - if (!isBracketType(bracketType, INIT_TYPE)) + if (!isBraceType(braceType, INIT_TYPE)) appendSpacePad(); } appendCurrentChar(); } } } } - else if (bracketFormatMode == BREAK_MODE) + else if (braceFormatMode == BREAK_MODE) { if (isWhiteSpace(peekNextChar()) && !isInVirginLine) breakLine(); - else if (isBeforeAnyComment()) + else if (isBeforeAnyComment() && sourceIterator->hasMoreLines()) { // do not break unless comment is at line end - if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBracket) + if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBrace) { - currentChar = ' '; // remove bracket from current line - appendOpeningBracket = true; // append bracket to following line + currentChar = ' '; // remove brace from current line + appendOpeningBrace = true; // append brace to following line } } if (!isInLineBreak && previousNonWSChar != '(') { // don't space pad C++11 uniform initialization - if (!isBracketType(bracketType, INIT_TYPE)) + if (!isBraceType(braceType, INIT_TYPE)) appendSpacePad(); } appendCurrentChar(); - if (currentLineBeginsWithBracket - && (int) currentLineFirstBracketNum == charNum - && !isBracketType(bracketType, SINGLE_LINE_TYPE)) + if (currentLineBeginsWithBrace + && currentLineFirstBraceNum == (size_t) charNum + && !isBraceType(braceType, SINGLE_LINE_TYPE)) shouldBreakLineAtNextChar = true; } - else if (bracketFormatMode == RUN_IN_MODE) + else if (braceFormatMode == RUN_IN_MODE) { if (isWhiteSpace(peekNextChar()) && !isInVirginLine) breakLine(); - else if (isBeforeAnyComment()) + else if (isBeforeAnyComment() && sourceIterator->hasMoreLines()) { // do not break unless comment is at line end - if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBracket) + if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBrace) { - currentChar = ' '; // remove bracket from current line - appendOpeningBracket = true; // append bracket to following line + currentChar = ' '; // remove brace from current line + appendOpeningBrace = true; // append brace to following line } } if (!isInLineBreak && previousNonWSChar != '(') { // don't space pad C++11 uniform initialization - if (!isBracketType(bracketType, INIT_TYPE)) + if (!isBraceType(braceType, INIT_TYPE)) appendSpacePad(); } appendCurrentChar(); } - else if (bracketFormatMode == NONE_MODE) + else if (braceFormatMode == NONE_MODE) { - if (currentLineBeginsWithBracket - && charNum == (int) currentLineFirstBracketNum) + if (currentLineBeginsWithBrace + && (size_t) charNum == currentLineFirstBraceNum) { appendCurrentChar(); // don't attach } else { if (previousNonWSChar != '(') { // don't space pad C++11 uniform initialization - if (!isBracketType(bracketType, INIT_TYPE)) + if (!isBraceType(braceType, INIT_TYPE)) appendSpacePad(); } appendCurrentChar(false); // OK to attach } } } - else // not the first opening bracket + else // not the first opening brace { - if (bracketFormatMode == RUN_IN_MODE) + if (braceFormatMode == RUN_IN_MODE) { if (previousNonWSChar == '{' - && bracketTypeStack->size() > 2 - && !isBracketType((*bracketTypeStack)[bracketTypeStack->size() - 2], - SINGLE_LINE_TYPE)) + && braceTypeStack->size() > 2 + && !isBraceType((*braceTypeStack)[braceTypeStack->size() - 2], + SINGLE_LINE_TYPE)) formatArrayRunIn(); } else if (!isInLineBreak && !isWhiteSpace(peekNextChar()) && previousNonWSChar == '{' - && bracketTypeStack->size() > 2 - && !isBracketType((*bracketTypeStack)[bracketTypeStack->size() - 2], - SINGLE_LINE_TYPE)) + && braceTypeStack->size() > 2 + && !isBraceType((*braceTypeStack)[braceTypeStack->size() - 2], + SINGLE_LINE_TYPE)) formatArrayRunIn(); appendCurrentChar(); } } else if (currentChar == '}') { - if (attachClosingBracketMode) + if (attachClosingBraceMode) { 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? + // does this close the first opening brace 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) + if (!isBraceType(braceType, INIT_TYPE) + && (!isBraceType(braceType, SINGLE_LINE_TYPE) || formattedLine.find('{') == string::npos)) breakLine(); appendCurrentChar(); } // if a declaration follows an enum definition, space pad char peekedChar = peekNextChar(); - if (isLegalNameChar(peekedChar) + if ((isLegalNameChar(peekedChar) && 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); + assert(braceFormatMode == RUN_IN_MODE || braceFormatMode == NONE_MODE); // keep one line blocks returns true without indenting the run-in if (formattingStyle != STYLE_PICO - && !isOkToBreakBlock(bracketTypeStack->back())) + && !isOkToBreakBlock(braceTypeStack->back())) return; // true; - // make sure the line begins with a bracket + // make sure the line begins with a brace size_t lastText = formattedLine.find_last_not_of(" \t"); if (lastText == string::npos || formattedLine[lastText] != '{') return; // false; - // make sure the bracket is broken + // make sure the brace is broken if (formattedLine.find_first_not_of(" \t{") != string::npos) return; // false; - if (isBracketType(bracketTypeStack->back(), NAMESPACE_TYPE)) + if (isBraceType(braceTypeStack->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) + && (isBraceType(braceTypeStack->back(), CLASS_TYPE) + || (isBraceType(braceTypeStack->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 + && !preBraceHeaderStack->empty() + && preBraceHeaderStack->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, ' '); + runInIndentChars = indentLength_ / 2; + formattedLine.append(runInIndentChars - 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 + runInIndentChars = indentLength_; + if (indent[0] == ' ') // allow for brace indent.erase(0, 1); formattedLine.append(indent); } else if (getIndentString() == "\t") { appendChar('\t', false); - horstmannIndentChars = 2; // one for { and one for tab + runInIndentChars = 2; // one for { and one for tab if (extraIndent) { appendChar('\t', false); - horstmannIndentChars++; + runInIndentChars++; } } else // spaces { int indentLength_ = getIndentLength(); formattedLine.append(indentLength_ - 1, ' '); - horstmannIndentChars = indentLength_; + runInIndentChars = indentLength_; if (extraIndent) { formattedLine.append(indentLength_, ' '); - horstmannIndentChars += indentLength_; + runInIndentChars += indentLength_; } } - isInBracketRunIn = true; + isInBraceRunIn = true; } /** * remove whitespace and add indentation for an array run-in. */ void ASFormatter::formatArrayRunIn() { - assert(isBracketType(bracketTypeStack->back(), ARRAY_TYPE)); + assert(isBraceType(braceTypeStack->back(), ARRAY_TYPE)); - // make sure the bracket is broken + // make sure the brace 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 + runInIndentChars = 2; // one for { and one for tab } else { int indent = getIndentLength(); formattedLine.append(indent - 1, ' '); - horstmannIndentChars = indent; + runInIndentChars = indent; } - isInBracketRunIn = true; + isInBraceRunIn = true; isInLineBreak = false; } /** - * delete a bracketTypeStack vector object - * BracketTypeStack did not work with the DeleteContainer template + * delete a braceTypeStack vector object + * BraceTypeStack did not work with the DeleteContainer template */ -void ASFormatter::deleteContainer(vector*& container) +void ASFormatter::deleteContainer(vector*& container) { - if (container != NULL) + if (container != nullptr) { container->clear(); delete (container); - container = NULL; + container = nullptr; } } /** * delete a vector object * T is the type of vector - * used for all vectors except bracketTypeStack + * used for all vectors except braceTypeStack */ template void ASFormatter::deleteContainer(T& container) { - if (container != NULL) + if (container != nullptr) { container->clear(); delete (container); - container = NULL; + container = nullptr; } } /** - * initialize a BracketType vector object - * BracketType did not work with the DeleteContainer template + * initialize a braceType vector object + * braceType did not work with the DeleteContainer template */ -void ASFormatter::initContainer(vector*& container, vector* value) +void ASFormatter::initContainer(vector*& container, vector* value) { - if (container != NULL) + if (container != nullptr) deleteContainer(container); container = value; } /** * initialize a vector object * T is the type of vector - * used for all vectors except bracketTypeStack + * used for all vectors except braceTypeStack */ 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) + if (container != nullptr) 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 +bool ASFormatter::isOkToBreakBlock(BraceType braceType) const { - // Actually, there should not be an ARRAY_TYPE bracket here. + // Actually, there should not be an ARRAY_TYPE brace 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)) + if (isBraceType(braceType, ARRAY_TYPE) + && isBraceType(braceType, SINGLE_LINE_TYPE)) return false; - if (isBracketType(bracketType, COMMAND_TYPE) - && isBracketType(bracketType, EMPTY_BLOCK_TYPE)) + if (isBraceType(braceType, COMMAND_TYPE) + && isBraceType(braceType, EMPTY_BLOCK_TYPE)) return false; - if (!isBracketType(bracketType, SINGLE_LINE_TYPE) - || isBracketType(bracketType, BREAK_BLOCK_TYPE) + if (!isBraceType(braceType, SINGLE_LINE_TYPE) + || isBraceType(braceType, BREAK_BLOCK_TYPE) || shouldBreakOneLineBlocks) return true; return false; } /** * check if a sharp header is a paren or non-paren header */ bool ASFormatter::isSharpStyleWithParen(const string* header) const { return (isSharpStyle() && peekNextChar() == '(' && (header == &AS_CATCH || header == &AS_DELEGATE)); } /** * 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. + * return value is a pointer to the header or nullptr. */ 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); + bool endOnEmptyLine = (currentHeader == nullptr); if (isInSwitchStatement()) endOnEmptyLine = false; string nextText = peekNextText(firstLine, endOnEmptyLine); if (nextText.length() == 0 || !isCharPotentialHeader(nextText, 0)) - return NULL; + return nullptr; - return ASBeautifier::findHeader(nextText, 0, headers); + return ASBase::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. + * delete braceTypeStack entries added by #if if a #else is found. + * prevents double entries in the braceTypeStack. */ 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(); + preprocBraceTypeStackSize = braceTypeStack->size(); } else if (currentLine.compare(preproc, 4, "else") == 0) { // delete stack entries added in #if // should be replaced by #else - if (preprocBracketTypeStackSize > 0) + if (preprocBraceTypeStackSize > 0) { - int addedPreproc = bracketTypeStack->size() - preprocBracketTypeStackSize; + int addedPreproc = braceTypeStack->size() - preprocBraceTypeStackSize; for (int i = 0; i < addedPreproc; i++) - bracketTypeStack->pop_back(); + braceTypeStack->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()) + auto stream = make_shared(sourceIterator); + if (!stream->hasMoreLines()) return false; - string nextLine_ = sourceIterator->peekNextLine(); + string nextLine_ = stream->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); + string nextText = peekNextText(nextLine_, false, stream); if (nextText.length() == 0 || !isCharPotentialHeader(nextText, 0)) return false; - const string* newHeader = ASBeautifier::findHeader(nextText, 0, headers); + const string* newHeader = ASBase::findHeader(nextText, 0, headers); - if (newHeader == NULL) + if (newHeader == nullptr) 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 + * determine if a brace should be attached or broken + * uses braces in the braceTypeStack + * the last brace in the braceTypeStack is the one being formatted + * returns true if the brace should be broken */ -bool ASFormatter::isCurrentBracketBroken() const +bool ASFormatter::isCurrentBraceBroken() const { - assert(bracketTypeStack->size() > 1); + assert(braceTypeStack->size() > 1); - bool breakBracket = false; - size_t stackEnd = bracketTypeStack->size() - 1; + bool breakBrace = false; + size_t stackEnd = braceTypeStack->size() - 1; - // check bracket modifiers + // check brace modifiers if (shouldAttachExternC - && isBracketType((*bracketTypeStack)[stackEnd], EXTERN_TYPE)) + && isBraceType((*braceTypeStack)[stackEnd], EXTERN_TYPE)) { return false; } if (shouldAttachNamespace - && isBracketType((*bracketTypeStack)[stackEnd], NAMESPACE_TYPE)) + && isBraceType((*braceTypeStack)[stackEnd], NAMESPACE_TYPE)) { return false; } if (shouldAttachClass - && (isBracketType((*bracketTypeStack)[stackEnd], CLASS_TYPE) - || isBracketType((*bracketTypeStack)[stackEnd], INTERFACE_TYPE))) + && (isBraceType((*braceTypeStack)[stackEnd], CLASS_TYPE) + || isBraceType((*braceTypeStack)[stackEnd], INTERFACE_TYPE))) { return false; } if (shouldAttachInline && isCStyle() // for C++ only - && bracketFormatMode != RUN_IN_MODE - && isBracketType((*bracketTypeStack)[stackEnd], COMMAND_TYPE)) + && braceFormatMode != RUN_IN_MODE + && !(currentLineBeginsWithBrace && peekNextChar() == '/') + && isBraceType((*braceTypeStack)[stackEnd], COMMAND_TYPE)) { size_t i; - for (i = 1; i < bracketTypeStack->size(); i++) - if (isBracketType((*bracketTypeStack)[i], CLASS_TYPE) - || isBracketType((*bracketTypeStack)[i], STRUCT_TYPE)) + for (i = 1; i < braceTypeStack->size(); i++) + if (isBraceType((*braceTypeStack)[i], CLASS_TYPE) + || isBraceType((*braceTypeStack)[i], STRUCT_TYPE)) return false; } - // check brackets - if (isBracketType((*bracketTypeStack)[stackEnd], EXTERN_TYPE)) + // check braces + if (isBraceType((*braceTypeStack)[stackEnd], EXTERN_TYPE)) { - if (currentLineBeginsWithBracket - || bracketFormatMode == RUN_IN_MODE) - breakBracket = true; + if (currentLineBeginsWithBrace + || braceFormatMode == RUN_IN_MODE) + breakBrace = true; } - else if (bracketFormatMode == NONE_MODE) + else if (braceFormatMode == NONE_MODE) { - if (currentLineBeginsWithBracket - && (int) currentLineFirstBracketNum == charNum) - breakBracket = true; + if (currentLineBeginsWithBrace + && currentLineFirstBraceNum == (size_t) charNum) + breakBrace = true; } - else if (bracketFormatMode == BREAK_MODE || bracketFormatMode == RUN_IN_MODE) + else if (braceFormatMode == BREAK_MODE || braceFormatMode == RUN_IN_MODE) { - breakBracket = true; + breakBrace = true; } - else if (bracketFormatMode == LINUX_MODE) + else if (braceFormatMode == LINUX_MODE) { // break a namespace if NOT stroustrup or mozilla - if (isBracketType((*bracketTypeStack)[stackEnd], NAMESPACE_TYPE)) + if (isBraceType((*braceTypeStack)[stackEnd], NAMESPACE_TYPE)) { if (formattingStyle != STYLE_STROUSTRUP && formattingStyle != STYLE_MOZILLA) - breakBracket = true; + breakBrace = true; } // break a class or interface if NOT stroustrup - else if (isBracketType((*bracketTypeStack)[stackEnd], CLASS_TYPE) - || isBracketType((*bracketTypeStack)[stackEnd], INTERFACE_TYPE)) + else if (isBraceType((*braceTypeStack)[stackEnd], CLASS_TYPE) + || isBraceType((*braceTypeStack)[stackEnd], INTERFACE_TYPE)) { if (formattingStyle != STYLE_STROUSTRUP) - breakBracket = true; + breakBrace = true; } - // break a struct if mozilla - an enum is processed as an array bracket - else if (isBracketType((*bracketTypeStack)[stackEnd], STRUCT_TYPE)) + // break a struct if mozilla - an enum is processed as an array brace + else if (isBraceType((*braceTypeStack)[stackEnd], STRUCT_TYPE)) { if (formattingStyle == STYLE_MOZILLA) - breakBracket = true; + breakBrace = true; } - // break the first bracket if a function - else if (isBracketType((*bracketTypeStack)[stackEnd], COMMAND_TYPE)) + // break the first brace if a function + else if (isBraceType((*braceTypeStack)[stackEnd], COMMAND_TYPE)) { if (stackEnd == 1) { - breakBracket = true; + breakBrace = 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)) + // break the first brace after these if a function + if (isBraceType((*braceTypeStack)[stackEnd - 1], NAMESPACE_TYPE) + || isBraceType((*braceTypeStack)[stackEnd - 1], CLASS_TYPE) + || isBraceType((*braceTypeStack)[stackEnd - 1], ARRAY_TYPE) + || isBraceType((*braceTypeStack)[stackEnd - 1], STRUCT_TYPE) + || isBraceType((*braceTypeStack)[stackEnd - 1], EXTERN_TYPE)) { - breakBracket = true; + breakBrace = true; } } } } - return breakBracket; + return breakBrace; } /** * 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 (isSequenceReached("*/")) { 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; + const string* followingHeader = nullptr; if ((doesLineStartComment && !isImmediatelyPostCommentOnly - && isBracketType(bracketTypeStack->back(), COMMAND_TYPE)) + && isBraceType(braceTypeStack->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 (isBracketType(bracketTypeStack->back(), NAMESPACE_TYPE)) + if (isBraceType(braceTypeStack->back(), NAMESPACE_TYPE)) { // namespace run-in is always broken. isInLineBreak = true; } - else if (bracketFormatMode == NONE_MODE) + else if (braceFormatMode == NONE_MODE) { // should a run-in statement be attached? - if (currentLineBeginsWithBracket) + if (currentLineBeginsWithBrace) formatRunIn(); } - else if (bracketFormatMode == ATTACH_MODE) + else if (braceFormatMode == ATTACH_MODE) { - // if the bracket was not attached? + // if the brace was not attached? if (formattedLine.length() > 0 && formattedLine[0] == '{' - && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)) + && !isBraceType(braceTypeStack->back(), SINGLE_LINE_TYPE)) isInLineBreak = true; } - else if (bracketFormatMode == RUN_IN_MODE) + else if (braceFormatMode == 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 + && followingHeader != nullptr && !isImmediatelyPostEmptyLine && previousCommandChar != '{') { if (isClosingHeader(followingHeader)) { if (!shouldBreakClosingHeaderBlocks) isPrependPostBlockEmptyLineRequested = false; } // if an opening header, break before the comment else isPrependPostBlockEmptyLineRequested = true; } if (previousCommandChar == '}') - currentHeader = NULL; + currentHeader = nullptr; } /** * format a comment closer * the comment closer will be appended to the current formattedLine */ void ASFormatter::formatCommentCloser() { assert(isSequenceReached("*/")); 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) + && !isBraceType(braceTypeStack->back(), ARRAY_TYPE) && !isInPreprocessor - && isOkToBreakBlock(bracketTypeStack->back())) + && isOkToBreakBlock(braceTypeStack->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; + const string* followingHeader = nullptr; if ((lineIsLineCommentOnly && !isImmediatelyPostCommentOnly - && isBracketType(bracketTypeStack->back(), COMMAND_TYPE)) + && isBraceType(braceTypeStack->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 + // or in a namespace before the opening brace 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 && 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 (braceFormatMode == NONE_MODE) { - if (currentLineBeginsWithBracket) + if (currentLineBeginsWithBrace) formatRunIn(); } - else if (bracketFormatMode == RUN_IN_MODE) + else if (braceFormatMode == RUN_IN_MODE) { if (!lineCommentNoIndent) formatRunIn(); else isInLineBreak = true; } - else if (bracketFormatMode == BREAK_MODE) + else if (braceFormatMode == BREAK_MODE) { if (formattedLine.length() > 0 && formattedLine[0] == '{') isInLineBreak = true; } else { - if (currentLineBeginsWithBracket) + if (currentLineBeginsWithBrace) 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 + && followingHeader != nullptr && !isImmediatelyPostEmptyLine && previousCommandChar != '{') { if (isClosingHeader(followingHeader)) { if (!shouldBreakClosingHeaderBlocks) isPrependPostBlockEmptyLineRequested = false; } // if an opening header, break before the comment else isPrependPostBlockEmptyLineRequested = true; } if (previousCommandChar == '}') - currentHeader = NULL; + currentHeader = nullptr; // 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 ((int) currentLine.length() > charNum + 1 && currentLine[charNum + 1] == '"') // check consecutive quotes { appendSequence("\"\""); goForward(1); return; } 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(); } } if (charNum + 1 >= (int) currentLine.length() && currentChar != '\\' && !isInVerbatimQuote) isInQuote = false; // missing closing quote } /** * 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 + // a quote following a brace is an array if (previousCommandChar == '{' && !isImmediatelyPostComment && !isImmediatelyPostLineComment && isNonInStatementArray - && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE) + && !isBraceType(braceTypeStack->back(), SINGLE_LINE_TYPE) && !isWhiteSpace(peekNextChar())) { - if (bracketFormatMode == NONE_MODE) + if (braceFormatMode == NONE_MODE) { - if (currentLineBeginsWithBracket) + if (currentLineBeginsWithBrace) formatRunIn(); } - else if (bracketFormatMode == RUN_IN_MODE) + else if (braceFormatMode == RUN_IN_MODE) { formatRunIn(); } - else if (bracketFormatMode == BREAK_MODE) + else if (braceFormatMode == BREAK_MODE) { if (formattedLine.length() > 0 && formattedLine[0] == '{') isInLineBreak = true; } else { - if (currentLineBeginsWithBracket) + if (currentLineBeginsWithBrace) 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. + * get the next line comment adjustment that results from breaking a closing brace. + * the brace 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 + size_t lastBrace = currentLine.rfind('}', charNum - 1); + if (lastBrace != string::npos) + return (lastBrace - 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. + * a closing header to a closing brace. + * the brace must be on the line previous to the closing header. + * the adjustment is 2 chars, one for the brace 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) + size_t lastBrace = currentLine.rfind('}', charNum - 1); + if (lastBrace == 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 + * check if a line break is needed when a closing brace * is followed by a closing header. - * the break depends on the bracketFormatMode and other factors. + * the break depends on the braceFormatMode and other factors. */ void ASFormatter::isLineBreakBeforeClosingHeader() { assert(foundClosingHeader && previousNonWSChar == '}'); - if (bracketFormatMode == BREAK_MODE - || bracketFormatMode == RUN_IN_MODE - || attachClosingBracketMode) + + if (currentHeader == &AS_WHILE && shouldAttachClosingWhile) + { + appendClosingHeader(); + return; + } + + if (braceFormatMode == BREAK_MODE + || braceFormatMode == RUN_IN_MODE + || attachClosingBraceMode) { isInLineBreak = true; } - else if (bracketFormatMode == NONE_MODE) + else if (braceFormatMode == NONE_MODE) { - if (shouldBreakClosingHeaderBrackets - || getBracketIndent() || getBlockIndent()) + if (shouldBreakClosingHeaderBraces + || getBraceIndent() || getBlockIndent()) { isInLineBreak = true; } else { appendSpacePad(); - // is closing bracket broken? + // is closing brace 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 + // braceFormatMode == ATTACH_MODE, LINUX_MODE else { - if (shouldBreakClosingHeaderBrackets - || getBracketIndent() || getBlockIndent()) + if (shouldBreakClosingHeaderBraces + || getBraceIndent() || 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 - } - + appendClosingHeader(); 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. + * Append a closing header to the previous closing brace, if possible */ -bool ASFormatter::addBracketsToStatement() +void ASFormatter::appendClosingHeader() +{ + // 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 firstBrace = findNextChar(formattedLine, '{'); + if (firstBrace != string::npos) + previousLineIsOneLineBlock = isOneLineBlockReached(formattedLine, firstBrace); + if (!previousLineIsEmpty + && previousLineIsOneLineBlock == 0) + { + isInLineBreak = false; + appendSpacePad(); + spacePadNum = 0; // don't count as comment padding + } +} + +/** + * Add braces to a single line statement following a header. + * braces are not added if the proper conditions are not met. + * braces are added to the currentLine. + */ +bool ASFormatter::addBracesToStatement() { 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 + // do not brace an empty statement if (currentChar == ';') return false; // do not add if a header follows if (isCharPotentialHeader(currentLine, charNum)) - if (findHeader(headers) != NULL) + if (findHeader(headers) != nullptr) 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 + // add closing brace before changing the line length if (nextSemiColon == currentLine.length() - 1) currentLine.append(" }"); else currentLine.insert(nextSemiColon + 1, " }"); - // add opening bracket + // add opening brace currentLine.insert(charNum, "{ "); assert(computeChecksumIn("{}")); currentChar = '{'; if ((int) currentLine.find_first_not_of(" \t") == charNum) - currentLineBeginsWithBracket = true; + currentLineBeginsWithBrace = true; // remove extra spaces - if (!shouldAddOneLineBrackets) + if (!shouldAddOneLineBraces) { 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. + * Remove braces from a single line statement following a header. + * braces are not removed if the proper conditions are not met. + * The first brace is replaced by a space. */ -bool ASFormatter::removeBracketsFromStatement() +bool ASFormatter::removeBracesFromStatement() { 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) + if (!isBeforeAnyLineEndComment(charNum) || currentLineBeginsWithBrace) nextLine_ = currentLine.substr(charNum + 1); size_t nextChar = 0; // find the first non-blank text - while (sourceIterator->hasMoreLines() || isFirstLine) + ASPeekStream stream(sourceIterator); + while (stream.hasMoreLines() || isFirstLine) { if (isFirstLine) isFirstLine = false; else { - nextLine_ = sourceIterator->peekNextLine(); + nextLine_ = stream.peekNextLine(); nextChar = 0; - needReset = true; } nextChar = nextLine_.find_first_not_of(" \t", nextChar); if (nextChar != string::npos) break; } + if (!stream.hasMoreLines()) + return false; - // don't remove if comments or a header follow the bracket + // don't remove if comments or a header follow the brace if ((nextLine_.compare(nextChar, 2, "/*") == 0) || (nextLine_.compare(nextChar, 2, "//") == 0) || (isCharPotentialHeader(nextLine_, nextChar) - && ASBeautifier::findHeader(nextLine_, nextChar, headers) != NULL)) - { - if (needReset) - sourceIterator->peekReset(); + && ASBase::findHeader(nextLine_, nextChar, headers) != nullptr)) 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 + // find the closing brace isFirstLine = true; nextChar = nextSemiColon + 1; - while (sourceIterator->hasMoreLines() || isFirstLine) + while (stream.hasMoreLines() || isFirstLine) { if (isFirstLine) isFirstLine = false; else { - nextLine_ = sourceIterator->peekNextLine(); + nextLine_ = stream.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 + // remove opening brace 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 +size_t ASFormatter::findNextChar(const 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 + // for now don't process C# 'delegate' braces // 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; } +/** + * Find split point for break/attach return type. + */ +void ASFormatter::findReturnTypeSplitPoint(const string& firstLine) +{ + assert((isBraceType(braceTypeStack->back(), NULL_TYPE) + || isBraceType(braceTypeStack->back(), DEFINITION_TYPE))); + assert(shouldBreakReturnType || shouldBreakReturnTypeDecl + || shouldAttachReturnType || shouldAttachReturnTypeDecl); + + bool isFirstLine = true; + bool isInComment_ = false; + bool isInQuote_ = false; + bool foundSplitPoint = false; + bool isAlreadyBroken = false; + char quoteChar_ = ' '; + char currNonWSChar = ' '; + char prevNonWSChar = ' '; + size_t parenCount = 0; + size_t squareCount = 0; + size_t angleCount = 0; + size_t breakLineNum = 0; + size_t breakCharNum = string::npos; + string line = firstLine; + + // Process the lines until a ';' or '{'. + ASPeekStream stream(sourceIterator); + while (stream.hasMoreLines() || isFirstLine) + { + if (isFirstLine) + isFirstLine = false; + else + { + if (isInQuote_) + return; + line = stream.peekNextLine(); + if (!foundSplitPoint) + ++breakLineNum; + } + size_t firstCharNum = line.find_first_not_of(" \t"); + if (firstCharNum == string::npos) + continue; + if (line[firstCharNum] == '#') + { + // don't attach to a preprocessor + if (shouldAttachReturnType || shouldAttachReturnTypeDecl) + return; + else + continue; + } + // parse the line + for (size_t i = 0; i < line.length(); i++) + { + if (!isWhiteSpace(line[i])) + { + prevNonWSChar = currNonWSChar; + currNonWSChar = line[i]; + } + else if (line[i] == '\t' && shouldConvertTabs) + { + size_t tabSize = getTabLength(); + size_t numSpaces = tabSize - ((tabIncrementIn + i) % tabSize); + line.replace(i, 1, numSpaces, ' '); + currentChar = line[i]; + } + if (line.compare(i, 2, "/*") == 0) + isInComment_ = true; + if (isInComment_) + { + if (line.compare(i, 2, "*/") == 0) + { + isInComment_ = false; + ++i; + } + continue; + } + if (line[i] == '\\') + { + ++i; + continue; + } + + if (isInQuote_) + { + if (line[i] == quoteChar_) + isInQuote_ = false; + continue; + } + + if (line[i] == '"' + || (line[i] == '\'' && !isDigitSeparator(line, i))) + { + isInQuote_ = true; + quoteChar_ = line[i]; + continue; + } + if (line.compare(i, 2, "//") == 0) + { + i = line.length(); + continue; + } + // not in quote or comment + if (!foundSplitPoint) + { + if (line[i] == '<') + { + ++angleCount; + continue; + } + if (line[i] == '>') + { + if (angleCount) + --angleCount; + if (!angleCount) + { + size_t nextCharNum = line.find_first_not_of(" \t*&", i + 1); + if (nextCharNum == string::npos) + { + breakCharNum = string::npos; + continue; + } + if (line[nextCharNum] != ':') // scope operator + breakCharNum = nextCharNum; + } + continue; + } + if (angleCount) + continue; + if (line[i] == '[') + { + ++squareCount; + continue; + } + if (line[i] == ']') + { + if (squareCount) + --squareCount; + continue; + } + // an assignment before the parens is not a function + if (line[i] == '=') + return; + if (isWhiteSpace(line[i]) || line[i] == '*' || line[i] == '&') + { + size_t nextNum = line.find_first_not_of(" \t", i + 1); + if (nextNum == string::npos) + breakCharNum = string::npos; + else + { + if (line.length() > nextNum + 1 + && line[nextNum] == ':' && line[nextNum + 1] == ':') + i = --nextNum; + else if (line[nextNum] != '(') + breakCharNum = string::npos; + } + continue; + } + if ((isLegalNameChar(line[i]) || line[i] == '~') + && breakCharNum == string::npos) + { + breakCharNum = i; + if (isLegalNameChar(line[i]) + && findKeyword(line, i, AS_OPERATOR)) + { + if (breakCharNum == firstCharNum) + isAlreadyBroken = true; + foundSplitPoint = true; + // find the operator, may be parens + size_t parenNum = + line.find_first_not_of(" \t", i + AS_OPERATOR.length()); + if (parenNum == string::npos) + return; + // find paren after the operator + parenNum = line.find('(', parenNum + 1); + if (parenNum == string::npos) + return; + i = --parenNum; + } + continue; + } + if (line[i] == ':' + && line.length() > i + 1 + && line[i + 1] == ':') + { + size_t nextCharNum = line.find_first_not_of(" \t:", i + 1); + if (nextCharNum == string::npos) + return; + + if (isLegalNameChar(line[nextCharNum]) + && findKeyword(line, nextCharNum, AS_OPERATOR)) + { + i = nextCharNum; + if (breakCharNum == firstCharNum) + isAlreadyBroken = true; + foundSplitPoint = true; + // find the operator, may be parens + size_t parenNum = + line.find_first_not_of(" \t", i + AS_OPERATOR.length()); + if (parenNum == string::npos) + return; + // find paren after the operator + parenNum = line.find('(', parenNum + 1); + if (parenNum == string::npos) + return; + i = --parenNum; + } + else + i = --nextCharNum; + continue; + } + if (line[i] == '(' && !squareCount) + { + // is line is already broken? + if (breakCharNum == firstCharNum && breakLineNum > 0) + isAlreadyBroken = true; + ++parenCount; + foundSplitPoint = true; + continue; + } + } + // end !foundSplitPoint + if (line[i] == '(') + { + // consecutive ')(' parens is probably a function pointer + if (prevNonWSChar == ')' && !parenCount) + return; + ++parenCount; + continue; + } + if (line[i] == ')') + { + if (parenCount) + --parenCount; + continue; + } + if (line[i] == '{') + { + if (shouldBreakReturnType && foundSplitPoint && !isAlreadyBroken) + { + methodBreakCharNum = breakCharNum; + methodBreakLineNum = breakLineNum; + } + if (shouldAttachReturnType && foundSplitPoint && isAlreadyBroken) + { + methodAttachCharNum = breakCharNum; + methodAttachLineNum = breakLineNum; + } + return; + } + if (line[i] == ';') + { + if (shouldBreakReturnTypeDecl && foundSplitPoint && !isAlreadyBroken) + { + methodBreakCharNum = breakCharNum; + methodBreakLineNum = breakLineNum; + } + if ((shouldAttachReturnTypeDecl && foundSplitPoint && isAlreadyBroken)) + { + methodAttachCharNum = breakCharNum; + methodAttachLineNum = breakLineNum; + } + return; + } + if (line[i] == '}') + return; + } // end of for loop + if (!foundSplitPoint) + breakCharNum = string::npos; + } // end of while loop +} + /** * 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 +bool ASFormatter::isStructAccessModified(const string& firstLine, size_t index) const { assert(firstLine[index] == '{'); assert(isCStyle()); bool isFirstLine = true; - bool needReset = false; - size_t bracketCount = 1; + size_t braceCount = 1; string nextLine_ = firstLine.substr(index + 1); + ASPeekStream stream(sourceIterator); // find the first non-blank text, bypassing all comments and quotes. bool isInComment_ = false; bool isInQuote_ = false; char quoteChar_ = ' '; - while (sourceIterator->hasMoreLines() || isFirstLine) + while (stream.hasMoreLines() || isFirstLine) { if (isFirstLine) isFirstLine = false; else - { - nextLine_ = sourceIterator->peekNextLine(); - needReset = true; - } + nextLine_ = stream.peekNextLine(); // 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 + // handle braces if (nextLine_[i] == '{') - ++bracketCount; + ++braceCount; if (nextLine_[i] == '}') - --bracketCount; - if (bracketCount == 0) - { - if (needReset) - sourceIterator->peekReset(); + --braceCount; + if (braceCount == 0) 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) +bool ASFormatter::isIndentablePreprocessorBlock(const string& firstLine, size_t index) { assert(firstLine[index] == '#'); bool isFirstLine = true; - bool needReset = false; bool isInIndentableBlock = false; - bool blockContainsBrackets = false; + bool blockContainsBraces = false; bool blockContainsDefineContinuation = false; bool isInClassConstructor = false; bool isPotentialHeaderGuard = false; // ifndef is first preproc statement bool isPotentialHeaderGuard2 = false; // define is within the first proproc int numBlockIndents = 0; int lineParenCount = 0; string nextLine_ = firstLine.substr(index); + auto stream = make_shared(sourceIterator); // find end of the block, bypassing all comments and quotes. bool isInComment_ = false; bool isInQuote_ = false; char quoteChar_ = ' '; - while (sourceIterator->hasMoreLines() || isFirstLine) + while (stream->hasMoreLines() || isFirstLine) { if (isFirstLine) isFirstLine = false; else - { - nextLine_ = sourceIterator->peekNextLine(); - needReset = true; - } + nextLine_ = stream->peekNextLine(); // 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; if (isNDefPreprocStatement(nextLine_, preproc)) isPotentialHeaderGuard = true; } } else if (preproc == "endif") { if (numBlockIndents > 0) numBlockIndents -= 1; // must exit BOTH loops if (numBlockIndents == 0) goto EndOfWhileLoop; } else if (preproc == "define") { if (nextLine_[nextLine_.length() - 1] == '\\') blockContainsDefineContinuation = true; // check for potential header include guards else if (isPotentialHeaderGuard && numBlockIndents == 1) isPotentialHeaderGuard2 = true; } i = nextLine_.length(); continue; } // handle exceptions if (nextLine_[i] == '{' || nextLine_[i] == '}') - blockContainsBrackets = true; + blockContainsBraces = true; else if (nextLine_[i] == '(') ++lineParenCount; else if (nextLine_[i] == ')') --lineParenCount; else if (nextLine_[i] == ':') { // check for '::' - if (nextLine_.length() > i && nextLine_[i + 1] == ':') + if (nextLine_.length() > i + 1 && nextLine_[i + 1] == ':') ++i; else isInClassConstructor = true; } // bypass unnecessary parsing - must exit BOTH loops - if (blockContainsBrackets || isInClassConstructor || blockContainsDefineContinuation) + if (blockContainsBraces || 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 + if (blockContainsBraces || isInClassConstructor || blockContainsDefineContinuation || lineParenCount != 0 || numBlockIndents != 0) isInIndentableBlock = false; // find next executable instruction // this WILL RESET the get pointer - string nextText = peekNextText("", false, needReset); + string nextText = peekNextText("", false, stream); // bypass header include guards if (isFirstPreprocConditional) { isFirstPreprocConditional = false; if (nextText.empty() && isPotentialHeaderGuard2) { 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; } -bool ASFormatter::isNDefPreprocStatement(string& nextLine_, string& preproc) const +bool ASFormatter::isNDefPreprocStatement(const string& nextLine_, const string& preproc) const { if (preproc == "ifndef") return true; // check for '!defined' if (preproc == "if") { size_t i = nextLine_.find('!'); if (i == string::npos) return false; i = nextLine_.find_first_not_of(" \t", ++i); if (i != string::npos && nextLine_.compare(i, 7, "defined") == 0) return true; } return false; } /** * 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 +bool ASFormatter::isExecSQL(const 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; } } /** * 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); + ASPeekStream stream(sourceIterator); - // find the angle brackets, bypassing all comments and quotes. + // find the angle braces, bypassing all comments and quotes. bool isInComment_ = false; bool isInQuote_ = false; char quoteChar_ = ' '; - while (sourceIterator->hasMoreLines() || isFirstLine) + while (stream.hasMoreLines() || isFirstLine) { if (isFirstLine) isFirstLine = false; else - { - nextLine_ = sourceIterator->peekNextLine(); - needReset = true; - } + nextLine_ = stream.peekNextLine(); // 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; + return; } continue; } else if (currentChar_ == '(' || currentChar_ == ')') { if (currentChar_ == '(') ++parenDepth_; else --parenDepth_; if (parenDepth_ >= 0) continue; // this is not a template -> leave... isInTemplate = false; - goto exitFromSearch; + templateDepth = 0; + return; } 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; + templateDepth = 0; + return; } 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; + return; } 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(); + } // end for loop + } // end while loop } 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 + // don't split before or after a brace if (appendedChar == '{' || appendedChar == '}' || previousNonWSChar == '{' || previousNonWSChar == '}' || nextChar == '{' || nextChar == '}' - || currentChar == '{' || currentChar == '}') // currentChar tests for an appended bracket + || currentChar == '{' || currentChar == '}') // currentChar tests for an appended brace 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)) + if (previousNonWSChar != ' ' && 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 - && !isInExponent() + && !(sequence == "+" && isInExponent()) + && !(sequence == "-" && isInExponent()) && (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 + // do NOT use <= here, must allow for a brace 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 != '{') + if (!isOkToBreakBlock(braceTypeStack->back()) && currentChar != '{') { shouldKeepLineUnbroken = true; clearFormattedLineSplitPoints(); return false; } - if (isBracketType(bracketTypeStack->back(), ARRAY_TYPE)) + if (isBraceType(braceTypeStack->back(), ARRAY_TYPE)) { shouldKeepLineUnbroken = true; - if (!isBracketType(bracketTypeStack->back(), ARRAY_NIS_TYPE)) + if (!isBraceType(braceTypeStack->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)) + if (!isWhiteSpace(currentChar) && 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; + return nullptr; if (!isLegalNameChar(currentLine[nextNum])) - return NULL; + return nullptr; // 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; + return nullptr; - const string* newOperator = ASBeautifier::findOperator(currentLine, nextNum, operators); + const string* newOperator = ASBase::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)); + assert(isBraceType(braceTypeStack->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; + foundTrailingReturnType = false; foundCastOperator = false; isInPotentialCalculation = false; isSharpAccessor = false; isSharpDelegate = false; isInObjCMethodDefinition = false; + isImmediatelyPostObjCMethodPrefix = false; + isInObjCReturnType = false; + isInObjCParam = false; isInObjCInterface = false; isInObjCSelector = false; isInEnum = false; isInExternC = false; elseHeaderFollowsComments = false; - nonInStatementBracket = 0; + returnTypeChecked = false; + nonInStatementBrace = 0; while (!questionMarkStack->empty()) questionMarkStack->pop_back(); } // Find the colon alignment for Objective-C method definitions and method calls. int ASFormatter::findObjCColonAlignment() const { assert(currentChar == '+' || currentChar == '-' || currentChar == '['); assert(getAlignMethodColon()); bool isFirstLine = true; bool haveFirstColon = false; bool foundMethodColon = false; - bool needReset = false; bool isInComment_ = false; bool isInQuote_ = false; + bool haveTernary = false; char quoteChar_ = ' '; int sqBracketCount = 0; int colonAdjust = 0; int colonAlign = 0; string nextLine_ = currentLine; + ASPeekStream stream(sourceIterator); // peek next line while (sourceIterator->hasMoreLines() || isFirstLine) { if (!isFirstLine) - { - nextLine_ = sourceIterator->peekNextLine(); - needReset = true; - } + nextLine_ = stream.peekNextLine(); // 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] == '{' && (currentChar == '-' || currentChar == '+')) || nextLine_[i] == ';') goto EndOfWhileLoop; // end of method definition if (nextLine_[i] == ']') { --sqBracketCount; - if (!sqBracketCount) + if (sqBracketCount == 0) goto EndOfWhileLoop; // end of method call } if (nextLine_[i] == '[') ++sqBracketCount; if (isFirstLine) // colon align does not include the first line continue; if (sqBracketCount > 1) continue; if (haveFirstColon) // multiple colons per line continue; + if (nextLine_[i] == '?') + { + haveTernary = true; + continue; + } // compute colon adjustment if (nextLine_[i] == ':') { + if (haveTernary) + { + haveTernary = false; + continue; + } haveFirstColon = true; foundMethodColon = 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 (!foundMethodColon) colonAlign = -1; - 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 (formattedLine.length() > 0) + { + appendSpacePad(); + formattedLine.back() = ' '; // convert any tab to space + } } 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) + size_t nextText = currentLine.find_first_not_of(" \t", charNum + 1); + if (nextText == 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) + size_t nextText = currentLine.find_first_not_of(" \t", charNum + 1); + if (nextText == 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); + currentLine[charNum + 1] = ' '; // convert any tab to space 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 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/plugins/astyle/3rdparty/libastyle/ASLocalizer.cpp b/plugins/astyle/3rdparty/libastyle/ASLocalizer.cpp index c905aa51f6..caece119dd 100644 --- a/plugins/astyle/3rdparty/libastyle/ASLocalizer.cpp +++ b/plugins/astyle/3rdparty/libastyle/ASLocalizer.cpp @@ -1,1098 +1,1166 @@ // ASLocalizer.cpp -// Copyright (c) 2016 by Jim Pattee . +// Copyright (c) 2018 by Jim Pattee . // This code is licensed under the MIT License. -// License.txt describes the conditions under which this software may be distributed. +// License.md describes the conditions under which this software may be distributed. // // File encoding for this file is UTF-8 WITHOUT a byte order mark (BOM). // русский 中文(简体) 日本語 한국의 // // Windows: // Add the required "Language" to the system. // The settings do NOT need to be changed to the added language. // Change the "Region" settings. // Change both the "Format" and the "Current Language..." settings. // A restart is required if the codepage has changed. // Windows problems: // Hindi - no available locale, language pack removed // Japanese - language pack install error // Ukranian - displays a ? instead of i // // Linux: // Change the LANG environment variable: LANG=fr_FR.UTF-8. // setlocale() will use the LANG environment variable on Linux. // /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * To add a new language to this source module: * * Add a new translation class to ASLocalizer.h. * Update the WinLangCode array in ASLocalizer.cpp. * Add the language code to setTranslationClass() in ASLocalizer.cpp. * Add the English-Translation pair to the constructor in ASLocalizer.cpp. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //---------------------------------------------------------------------------- // 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; + m_translation = nullptr; // Not all compilers support the C++ function locale::global(locale("")); char* localeName = setlocale(LC_ALL, ""); - if (localeName == NULL) // use the english (ascii) defaults + if (localeName == nullptr) // 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_BULGARIAN, "bg" }, // bg-BG 1251 { LANG_CHINESE, "zh" }, // zh-CHS, zh-CHT { LANG_DUTCH, "nl" }, // nl-NL 1252 { LANG_ENGLISH, "en" }, // en-US 1252 { LANG_ESTONIAN, "et" }, // et-EE { LANG_FINNISH, "fi" }, // fi-FI 1252 { LANG_FRENCH, "fr" }, // fr-FR 1252 { LANG_GERMAN, "de" }, // de-DE 1252 { LANG_GREEK, "el" }, // el-GR 1253 { LANG_HINDI, "hi" }, // hi-IN { LANG_HUNGARIAN, "hu" }, // hu-HU 1250 { LANG_ITALIAN, "it" }, // it-IT 1252 { LANG_JAPANESE, "ja" }, // ja-JP { LANG_KOREAN, "ko" }, // ko-KR { LANG_NORWEGIAN, "nn" }, // nn-NO 1252 { LANG_POLISH, "pl" }, // pl-PL 1250 { LANG_PORTUGUESE, "pt" }, // pt-PT 1252 { LANG_ROMANIAN, "ro" }, // ro-RO 1250 { LANG_RUSSIAN, "ru" }, // ru-RU 1251 { LANG_SPANISH, "es" }, // es-ES 1252 { LANG_SWEDISH, "sv" }, // sv-SE 1252 { LANG_UKRAINIAN, "uk" }, // uk-UA 1251 }; 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 +#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 m_lcid = 0; string langStr = langID; m_langID = langStr.substr(0, 2); // need the sublang for chinese if (m_langID == "zh" && langStr[2] == '_') { string subLang = langStr.substr(3, 2); 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) + if (m_translation != nullptr) { delete m_translation; - m_translation = NULL; + m_translation = nullptr; } if (m_langID == "bg") m_translation = new Bulgarian; else 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 == "et") m_translation = new Estonian; 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 == "el") m_translation = new Greek; else if (m_langID == "hi") m_translation = new Hindi; else if (m_langID == "hu") m_translation = new Hungarian; 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 == "nn") m_translation = new Norwegian; else if (m_langID == "pl") m_translation = new Polish; else if (m_langID == "pt") m_translation = new Portuguese; else if (m_langID == "ro") m_translation = new Romanian; 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); + m_translation.emplace_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); + // get length of the output excluding the nullptr and validate the parameters + size_t mbLen = wcstombs(nullptr, 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 (mbStr == nullptr) { 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; } +string Translation::getTranslationString(size_t i) const +// Return the translation ascii value. Used for testing. +{ + if (i >= m_translation.size()) + return string(); + return m_translation[i].first; +} + 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 mutable string so the method can have a "const" designation. // This allows "settext" to be called from a "const" method. { m_mbTranslation.clear(); for (size_t i = 0; i < m_translation.size(); i++) { if (m_translation[i].first == stringIn) { m_mbTranslation = convertToMultiByte(m_translation[i].second); break; } } // not found, return english if (m_mbTranslation.empty()) m_mbTranslation = stringIn; return m_mbTranslation; } //---------------------------------------------------------------------------- // Translation class methods. // These classes have only a constructor which builds the language vector. //---------------------------------------------------------------------------- Bulgarian::Bulgarian() // български // 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("Default option file %s\n", L"Файл с опции по подразбиране %s\n"); + addPair("Project option file %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 hепроменен "); 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 default options:", L"Невалидни опции по подразбиране:"); + addPair("Invalid project 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 default option file", L"Не може да се отвори файлът с опции по подразбиране"); + addPair("Cannot open project option file", L"Не може да се отвори файла с опции за проекта"); addPair("Cannot open directory", L"Не може да се отвори директория"); addPair("Cannot open HTML file %s\n", L"Не може да се отвори HTML файл %s\n"); addPair("Command execute failure", L"Command изпълни недостатъчност"); addPair("Command is not installed", L"Command не е инсталиран"); 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 е прекратено"); + addPair("Artistic Style has terminated\n", L"Artistic Style е прекратено\n"); } ChineseSimplified::ChineseSimplified() // 中文(简体) // 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("Default option file %s\n", L"默认选项文件 %s\n"); + addPair("Project option file %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 default options:", L"默认选项无效:"); + addPair("Invalid project 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 default option file", L"无法打开默认选项文件"); + addPair("Cannot open project option 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 已经终止运行"); + addPair("Artistic Style has terminated\n", L"Artistic Style 已经终止运行\n"); } ChineseTraditional::ChineseTraditional() // 中文(繁體) // 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("Default option file %s\n", L"默認選項文件 %s\n"); + addPair("Project option file %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 default options:", L"默認選項無效:"); + addPair("Invalid project 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 default option file", L"無法打開默認選項文件"); + addPair("Cannot open project option 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 已經終止運行"); + addPair("Artistic Style has terminated\n", L"Artistic Style 已經終止運行\n"); } 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("Default option file %s\n", L"Standaard optie bestand %s\n"); + addPair("Project option file %s\n", L"Project optie bestand %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 default options:", L"Ongeldige standaardopties:"); + addPair("Invalid project options:", L"Ongeldige projectopties:"); 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 default option file", L"Kan het standaardoptiesbestand niet openen"); + addPair("Cannot open project option file", L"Kan het project optie bestand niet openen"); 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"); + addPair("Artistic Style has terminated\n", L"Artistic Style heeft beëindigd\n"); } English::English() // this class is NOT translated {} Estonian::Estonian() // Eesti // build the translation vector in the Translation base class { addPair("Formatted %s\n", L"Formaadis %s\n"); // should align with unchanged addPair("Unchanged %s\n", L"Muutumatu %s\n"); // should align with formatted addPair("Directory %s\n", L"Kataloog %s\n"); + addPair("Default option file %s\n", L"Vaikefunktsioonifail %s\n"); + addPair("Project option file %s\n", L"Projekti valiku fail %s\n"); addPair("Exclude %s\n", L"Välista %s\n"); addPair("Exclude (unmatched) %s\n", L"Välista (tasakaalustamata) %s\n"); addPair(" %s formatted %s unchanged ", L" %s formaadis %s muutumatu "); addPair(" seconds ", L" sekundit "); addPair("%d min %d sec ", L"%d min %d sek "); addPair("%s lines\n", L"%s read\n"); - addPair("Using default options file %s\n", L"Kasutades selliseid vaikimisi valikuid faili %s\n"); addPair("Opening HTML documentation %s\n", L"Avamine HTML dokumentatsioon %s\n"); - addPair("Invalid option file options:", L"Vale valik faili võimalusi:"); + addPair("Invalid default options:", L"Vaikevalikud on sobimatud:"); + addPair("Invalid project options:", L"Projekti valikud on sobimatud:"); addPair("Invalid command line options:", L"Vale käsureavõtmetega:"); addPair("For help on options type 'astyle -h'", L"Abiks võimaluste tüüp 'astyle -h'"); - addPair("Cannot open options file", L"Ei saa avada võimalusi faili"); + addPair("Cannot open default option file", L"Vaikimisi valitud faili ei saa avada"); + addPair("Cannot open project option file", L"Projektivaliku faili ei saa avada"); addPair("Cannot open directory", L"Ei saa avada kataloogi"); addPair("Cannot open HTML file %s\n", L"Ei saa avada HTML-faili %s\n"); addPair("Command execute failure", L"Käsk täita rike"); addPair("Command is not installed", L"Käsk ei ole paigaldatud"); addPair("Missing filename in %s\n", L"Kadunud failinimi %s\n"); addPair("Recursive option with no wildcard", L"Rekursiivne võimalus ilma metamärgi"); addPair("Did you intend quote the filename", L"Kas te kavatsete tsiteerida failinimi"); addPair("No file to process %s\n", L"No faili töötlema %s\n"); addPair("Did you intend to use --recursive", L"Kas te kavatsete kasutada --recursive"); addPair("Cannot process UTF-32 encoding", L"Ei saa töödelda UTF-32 kodeeringus"); - addPair("\nArtistic Style has terminated", L"\nArtistic Style on lõpetatud"); + addPair("Artistic Style has terminated\n", L"Artistic Style on lõpetatud\n"); } 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("Default option file %s\n", L"Oletusasetustiedosto %s\n"); + addPair("Project option file %s\n", L"Projektin valintatiedosto %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 default options:", L"Virheelliset oletusasetukset:"); + addPair("Invalid project options:", L"Virheelliset hankevalinnat:"); 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 default option file", L"Et voi avata oletusasetustiedostoa"); + addPair("Cannot open project option file", L"Projektin asetustiedostoa ei voi avata"); 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"); + addPair("Artistic Style has terminated\n", L"Artistic Style on päättynyt\n"); } 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("Default option file %s\n", L"Fichier d'option par défaut %s\n"); + addPair("Project option file %s\n", L"Fichier d'option de projet %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 default options:", L"Options par défaut invalides:"); + addPair("Invalid project options:", L"Options de projet non valides:"); 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 default option file", L"Impossible d'ouvrir le fichier d'option par défaut"); + addPair("Cannot open project option file", L"Impossible d'ouvrir le fichier d'option de projet"); 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"); + addPair("Artistic Style has terminated\n", L"Artistic Style a mis fin\n"); } 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("Default option file %s\n", L"Standard-Optionsdatei %s\n"); + addPair("Project option file %s\n", L"Projektoptionsdatei %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 default options:", L"Ungültige Standardoptionen:"); + addPair("Invalid project options:", L"Ungültige Projektoptionen:"); 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 default option file", L"Die Standardoptionsdatei kann nicht geöffnet werden"); + addPair("Cannot open project option file", L"Die Projektoptionsdatei kann nicht geöffnet werden"); 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"); + addPair("Artistic Style has terminated\n", L"Artistic Style ist beendet\n"); } Greek::Greek() // ελληνικά // 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("Default option file %s\n", L"Προεπιλεγμένο αρχείο επιλογών %s\n"); + addPair("Project option file %s\n", L"Αρχείο επιλογής έργου %s\n"); addPair("Exclude %s\n", L"Αποκλείω %s\n"); addPair("Exclude (unmatched) %s\n", L"Ausschließen (unerreichte) %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 default options:", L"Μη έγκυρες επιλογές προεπιλογής:"); + addPair("Invalid project 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 default option file", L"Δεν είναι δυνατό να ανοίξει το προεπιλεγμένο αρχείο επιλογών"); + addPair("Cannot open project option 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 έχει λήξει"); + addPair("Artistic Style has terminated\n", L"Artistic Style έχει λήξει\n"); } 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("Default option file %s\n", L"डिफ़ॉल्ट विकल्प फ़ाइल %s\n"); + addPair("Project option file %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 default options:", L"अमान्य डिफ़ॉल्ट विकल्प:"); + addPair("Invalid project 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 default option file", L"डिफ़ॉल्ट विकल्प फ़ाइल नहीं खोल सकता"); + addPair("Cannot open project option 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 समाप्त किया है"); + addPair("Artistic Style has terminated\n", L"Artistic Style समाप्त किया है\n"); } Hungarian::Hungarian() // Magyar // build the translation vector in the Translation base class { addPair("Formatted %s\n", L"Formázott %s\n"); // should align with unchanged addPair("Unchanged %s\n", L"Változatlan %s\n"); // should align with formatted addPair("Directory %s\n", L"Címjegyzék %s\n"); + addPair("Default option file %s\n", L"Alapértelmezett beállítási fájl %s\n"); + addPair("Project option file %s\n", L"Projekt opciófájl %s\n"); addPair("Exclude %s\n", L"Kizár %s\n"); addPair("Exclude (unmatched) %s\n", L"Escludere (senza pari) %s\n"); addPair(" %s formatted %s unchanged ", L" %s formázott %s változatlan "); addPair(" seconds ", L" másodperc "); addPair("%d min %d sec ", L"%d jeg %d más "); addPair("%s lines\n", L"%s vonalak\n"); - addPair("Using default options file %s\n", L"Az alapértelmezett beállítások fájl %s\n"); addPair("Opening HTML documentation %s\n", L"Nyitó HTML dokumentáció %s\n"); - addPair("Invalid option file options:", L"Érvénytelen opció fájlbeállítást:"); + addPair("Invalid default options:", L"Érvénytelen alapértelmezett beállítások:"); + addPair("Invalid project options:", L"Érvénytelen projektbeállítások:"); addPair("Invalid command line options:", L"Érvénytelen parancssori opciók:"); addPair("For help on options type 'astyle -h'", L"Ha segítségre van lehetőség típus 'astyle-h'"); - addPair("Cannot open options file", L"Nem lehet megnyitni beállítási fájlban"); + addPair("Cannot open default option file", L"Nem lehet megnyitni az alapértelmezett beállítási fájlt"); + addPair("Cannot open project option file", L"Nem lehet megnyitni a projekt opció fájlt"); addPair("Cannot open directory", L"Nem lehet megnyitni könyvtár"); addPair("Cannot open HTML file %s\n", L"Nem lehet megnyitni a HTML fájlt %s\n"); addPair("Command execute failure", L"Command végre hiba"); addPair("Command is not installed", L"Parancs nincs telepítve"); addPair("Missing filename in %s\n", L"Hiányzó fájlnév %s\n"); addPair("Recursive option with no wildcard", L"Rekurzív kapcsolót nem wildcard"); addPair("Did you intend quote the filename", L"Esetleg kívánja idézni a fájlnév"); addPair("No file to process %s\n", L"Nincs fájl feldolgozása %s\n"); addPair("Did you intend to use --recursive", L"Esetleg a használni kívánt --recursive"); addPair("Cannot process UTF-32 encoding", L"Nem tudja feldolgozni UTF-32 kódolással"); - addPair("\nArtistic Style has terminated", L"\nArtistic Style megszűnt"); + addPair("Artistic Style has terminated\n", L"Artistic Style megszűnt\n"); } 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("Default option file %s\n", L"File di opzione predefinito %s\n"); + addPair("Project option file %s\n", L"File di opzione del progetto %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 default options:", L"Opzioni di default non valide:"); + addPair("Invalid project options:", L"Opzioni di progetto non valide:"); 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 default option file", L"Impossibile aprire il file di opzione predefinito"); + addPair("Cannot open project option file", L"Impossibile aprire il file di opzione del progetto"); 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"); + addPair("Artistic Style has terminated\n", L"Artistic Style ha terminato\n"); } Japanese::Japanese() // 日本語 // 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("Default option file %s\n", L"デフォルトオプションファイル %s\n"); + addPair("Project option file %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 default options:", L"無効なデフォルトオプション:"); + addPair("Invalid project 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 default option file", L"デフォルトのオプションファイルを開くことができません"); + addPair("Cannot open project option 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 終了しました"); + addPair("Artistic Style has terminated\n", L"Artistic Style 終了しました\n"); } Korean::Korean() // 한국의 // 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("Default option file %s\n", L"기본 옵션 파일 %s\n"); + addPair("Project option file %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 default options:", L"잘못된 기본 옵션:"); + addPair("Invalid project 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 default option file", L"기본 옵션 파일을 열 수 없습니다."); + addPair("Cannot open project option 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를 종료합니다"); + addPair("Artistic Style has terminated\n", L"Artistic Style를 종료합니다\n"); } Norwegian::Norwegian() // Norsk // build the translation vector in the Translation base class { addPair("Formatted %s\n", L"Formatert %s\n"); // should align with unchanged addPair("Unchanged %s\n", L"Uendret %s\n"); // should align with formatted addPair("Directory %s\n", L"Katalog %s\n"); + addPair("Default option file %s\n", L"Standard alternativfil %s\n"); + addPair("Project option file %s\n", L"Prosjekt opsjonsfil %s\n"); addPair("Exclude %s\n", L"Ekskluder %s\n"); addPair("Exclude (unmatched) %s\n", L"Ekskluder (uovertruffen) %s\n"); addPair(" %s formatted %s unchanged ", L" %s formatert %s uendret "); 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"Ved hjelp av standardalternativer fil %s\n"); addPair("Opening HTML documentation %s\n", L"Åpning HTML dokumentasjon %s\n"); - addPair("Invalid option file options:", L"Ugyldige alternativ filalternativer:"); + addPair("Invalid default options:", L"Ugyldige standardalternativer:"); + addPair("Invalid project options:", L"Ugyldige prosjektalternativer:"); addPair("Invalid command line options:", L"Kommandolinjevalg Ugyldige:"); addPair("For help on options type 'astyle -h'", L"For hjelp til alternativer type 'astyle -h'"); - addPair("Cannot open options file", L"Kan ikke åpne alternativer fil"); + addPair("Cannot open default option file", L"Kan ikke åpne standardvalgsfilen"); + addPair("Cannot open project option file", L"Kan ikke åpne prosjektvalgsfilen"); addPair("Cannot open directory", L"Kan ikke åpne katalog"); addPair("Cannot open HTML file %s\n", L"Kan ikke åpne HTML-fil %s\n"); addPair("Command execute failure", L"Command utføre svikt"); addPair("Command is not installed", L"Command er ikke installert"); addPair("Missing filename in %s\n", L"Mangler filnavn i %s\n"); addPair("Recursive option with no wildcard", L"Rekursiv alternativ uten wildcard"); addPair("Did you intend quote the filename", L"Har du tenkt sitere filnavnet"); addPair("No file to process %s\n", L"Ingen fil å behandle %s\n"); addPair("Did you intend to use --recursive", L"Har du tenkt å bruke --recursive"); addPair("Cannot process UTF-32 encoding", L"Kan ikke behandle UTF-32 koding"); - addPair("\nArtistic Style has terminated", L"\nArtistic Style har avsluttet"); + addPair("Artistic Style has terminated\n", L"Artistic Style har avsluttet\n"); } 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("Default option file %s\n", L"Domyślny plik opcji %s\n"); + addPair("Project option file %s\n", L"Plik opcji projektu %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 default options:", L"Nieprawidłowe opcje domyślne:"); + addPair("Invalid project options:", L"Nieprawidłowe opcje projektu:"); 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 default option file", L"Nie można otworzyć pliku opcji domyślnych"); + addPair("Cannot open project option file", L"Nie można otworzyć pliku opcji projektu"); 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"); + addPair("Artistic Style has terminated\n", L"Artistic Style został zakończony\n"); } 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("Default option file %s\n", L"Arquivo de opção padrão %s\n"); + addPair("Project option file %s\n", L"Arquivo de opção de projeto %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 default options:", L"Opções padrão inválidas:"); + addPair("Invalid project options:", L"Opções de projeto inválidas:"); 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 default option file", L"Não é possível abrir o arquivo de opção padrão"); + addPair("Cannot open project option file", L"Não é possível abrir o arquivo de opção do projeto"); 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"); + addPair("Artistic Style has terminated\n", L"Artistic Style terminou\n"); } Romanian::Romanian() // Română // build the translation vector in the Translation base class { addPair("Formatted %s\n", L"Formatat %s\n"); // should align with unchanged addPair("Unchanged %s\n", L"Neschimbat %s\n"); // should align with formatted addPair("Directory %s\n", L"Director %s\n"); + addPair("Default option file %s\n", L"Fișier opțional implicit %s\n"); + addPair("Project option file %s\n", L"Fișier opțiune proiect %s\n"); addPair("Exclude %s\n", L"Excludeți %s\n"); addPair("Exclude (unmatched) %s\n", L"Excludeți (necompensată) %s\n"); addPair(" %s formatted %s unchanged ", L" %s formatat %s neschimbat "); addPair(" seconds ", L" secunde "); addPair("%d min %d sec ", L"%d min %d sec "); addPair("%s lines\n", L"%s linii\n"); - addPair("Using default options file %s\n", L"Fișier folosind opțiunile implicite %s\n"); addPair("Opening HTML documentation %s\n", L"Documentație HTML deschidere %s\n"); - addPair("Invalid option file options:", L"Opțiuni de opțiune de fișier nevalide:"); + addPair("Invalid default options:", L"Opțiuni implicite nevalide:"); + addPair("Invalid project options:", L"Opțiunile de proiect nevalide:"); addPair("Invalid command line options:", L"Opțiuni de linie de comandă nevalide:"); addPair("For help on options type 'astyle -h'", L"Pentru ajutor cu privire la tipul de opțiuni 'astyle -h'"); - addPair("Cannot open options file", L"Nu se poate deschide fișierul de opțiuni"); + addPair("Cannot open default option file", L"Nu se poate deschide fișierul cu opțiuni implicite"); + addPair("Cannot open project option file", L"Nu se poate deschide fișierul cu opțiuni de proiect"); addPair("Cannot open directory", L"Nu se poate deschide directorul"); addPair("Cannot open HTML file %s\n", L"Nu se poate deschide fișierul HTML %s\n"); addPair("Command execute failure", L"Comandă executa eșec"); addPair("Command is not installed", L"Comanda nu este instalat"); addPair("Missing filename in %s\n", L"Lipsă nume de fișier %s\n"); addPair("Recursive option with no wildcard", L"Opțiunea recursiv cu nici un wildcard"); addPair("Did you intend quote the filename", L"V-intentionati cita numele de fișier"); addPair("No file to process %s\n", L"Nu există un fișier pentru a procesa %s\n"); addPair("Did you intend to use --recursive", L"V-ați intenționați să utilizați --recursive"); addPair("Cannot process UTF-32 encoding", L"Nu se poate procesa codificarea UTF-32"); - addPair("\nArtistic Style has terminated", L"\nArtistic Style a terminat"); + addPair("Artistic Style has terminated\n", L"Artistic Style a terminat\n"); } 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("Default option file %s\n", L"Файл с опцией по умолчанию %s\n"); + addPair("Project option file %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 default options:", L"Недействительные параметры по умолчанию:"); + addPair("Invalid project 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 default option file", L"Не удается открыть файл параметров по умолчанию"); + addPair("Cannot open project option 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 прекратил"); + addPair("Artistic Style has terminated\n", L"Artistic Style прекратил\n"); } 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("Default option file %s\n", L"Archivo de opciones predeterminado %s\n"); + addPair("Project option file %s\n", L"Archivo de opciones del proyecto %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 default options:", L"Opciones predeterminadas no válidas:"); + addPair("Invalid project options:", L"Opciones de proyecto no válidas:"); 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 default option file", L"No se puede abrir el archivo de opciones predeterminado"); + addPair("Cannot open project option file", L"No se puede abrir el archivo de opciones del proyecto"); 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"); + addPair("Artistic Style has terminated\n", L"Artistic Style ha terminado\n"); } 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("Default option file %s\n", L"Standardalternativsfil %s\n"); + addPair("Project option file %s\n", L"Projektalternativ fil %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 default options:", L"Ogiltiga standardalternativ:"); + addPair("Invalid project options:", L"Ogiltiga projektalternativ:"); 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 default option file", L"Kan inte öppna standardalternativsfilen"); + addPair("Cannot open project option file", L"Kan inte öppna projektalternativsfilen"); 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"); + addPair("Artistic Style has terminated\n", L"Artistic Style har upphört\n"); } 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("Default option file %s\n", L"Файл параметра за замовчуванням %s\n"); + addPair("Project option file %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 default options:", L"Недійсні параметри за умовчанням:"); + addPair("Invalid project 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 default option file", L"Неможливо відкрити файл параметрів за замовчуванням"); + addPair("Cannot open project option 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 припинив"); + addPair("Artistic Style has terminated\n", L"Artistic Style припинив\n"); } #endif // ASTYLE_LIB } // end of namespace astyle diff --git a/plugins/astyle/3rdparty/libastyle/ASLocalizer.h b/plugins/astyle/3rdparty/libastyle/ASLocalizer.h index 037dcb7d6d..703092b56f 100644 --- a/plugins/astyle/3rdparty/libastyle/ASLocalizer.h +++ b/plugins/astyle/3rdparty/libastyle/ASLocalizer.h @@ -1,159 +1,167 @@ // ASLocalizer.h -// Copyright (c) 2016 by Jim Pattee . +// Copyright (c) 2018 by Jim Pattee . // This code is licensed under the MIT License. -// License.txt describes the conditions under which this software may be distributed. +// License.md describes the conditions under which this software may be distributed. #ifndef ASLOCALIZER_H #define ASLOCALIZER_H #include #include +// library builds do not need ASLocalizer +#ifdef ASTYLE_JNI + #ifndef ASTYLE_LIB // ASTYLE_LIB must be defined for ASTYLE_JNI + #define ASTYLE_LIB + #endif +#endif // ASTYLE_JNI + 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; + string getTranslationString(size_t i) 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 private: mutable string m_mbTranslation; }; //---------------------------------------------------------------------------- // Translation classes // One class for each language. // These classes have only a constructor which builds the language vector. //---------------------------------------------------------------------------- class Bulgarian : public Translation { public: Bulgarian(); }; 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 Estonian : public Translation { public: Estonian(); }; class Finnish : public Translation { public: Finnish(); }; class French : public Translation { public: French(); }; class German : public Translation { public: German(); }; class Greek : public Translation { public: Greek(); }; class Hindi : public Translation { public: Hindi(); }; class Hungarian : public Translation { public: Hungarian(); }; class Italian : public Translation { public: Italian(); }; class Japanese : public Translation { public: Japanese(); }; class Korean : public Translation { public: Korean(); }; class Norwegian : public Translation { public: Norwegian(); }; class Polish : public Translation { public: Polish(); }; class Portuguese : public Translation { public: Portuguese(); }; class Romanian : public Translation { public: Romanian(); }; 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/plugins/astyle/3rdparty/libastyle/ASResource.cpp b/plugins/astyle/3rdparty/libastyle/ASResource.cpp index af6b56b83a..e2fc7724a3 100644 --- a/plugins/astyle/3rdparty/libastyle/ASResource.cpp +++ b/plugins/astyle/3rdparty/libastyle/ASResource.cpp @@ -1,677 +1,837 @@ // ASResource.cpp -// Copyright (c) 2016 by Jim Pattee . +// Copyright (c) 2018 by Jim Pattee . // This code is licensed under the MIT License. -// License.txt describes the conditions under which this software may be distributed. +// License.md 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_EXCEPT = string("__except"); +const string ASResource::_AS_FINALLY = string("__finally"); +const string ASResource::_AS_TRY = string("__try"); +const string ASResource::AS_ADD = string("add"); +const string ASResource::AS_AUTO = string("auto"); +const string ASResource::AS_AUTORELEASEPOOL = string("autoreleasepool"); const string ASResource::AS_CASE = string("case"); -const string ASResource::AS_DEFAULT = string("default"); +const string ASResource::AS_CATCH = string("catch"); 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_MODULE = string("module"); // CORBA IDL module definition +const string ASResource::AS_CONST = string("const"); +const string ASResource::AS_CONST_CAST = string("const_cast"); +const string ASResource::AS_DEFAULT = string("default"); +const string ASResource::AS_DELEGATE = string("delegate"); +const string ASResource::AS_DELETE = string("delete"); +const string ASResource::AS_DO = string("do"); +const string ASResource::AS_DYNAMIC_CAST = string("dynamic_cast"); +const string ASResource::AS_ELSE = string("else"); 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_EXTERN = string("extern"); +const string ASResource::AS_FINAL = string("final"); +const string ASResource::AS_FINALLY = string("finally"); +const string ASResource::AS_FIXED = string("fixed"); +const string ASResource::AS_FOR = string("for"); +const string ASResource::AS_FOREACH = string("foreach"); +const string ASResource::AS_FOREVER = string("forever"); +const string ASResource::AS_GET = string("get"); +const string ASResource::AS_IF = string("if"); +const string ASResource::AS_INTERFACE = string("interface"); +const string ASResource::AS_INTERRUPT = string("interrupt"); +const string ASResource::AS_LET = string("let"); +const string ASResource::AS_LOCK = string("lock"); +const string ASResource::AS_MODULE = string("module"); // CORBA IDL module definition +const string ASResource::AS_NAMESPACE = string("namespace"); +const string ASResource::AS_NEW = string("new"); +const string ASResource::AS_NOEXCEPT = string("noexcept"); +const string ASResource::AS_NS_DURING = string("NS_DURING"); +const string ASResource::AS_NS_HANDLER = string("NS_HANDLER"); +const string ASResource::AS_OPERATOR = string("operator"); +const string ASResource::AS_OVERRIDE = string("override"); const string ASResource::AS_PRIVATE = string("private"); +const string ASResource::AS_PROTECTED = string("protected"); +const string ASResource::AS_PUBLIC = string("public"); +const string ASResource::AS_QFOREACH = string("Q_FOREACH"); +const string ASResource::AS_QFOREVER = string("Q_FOREVER"); +const string ASResource::AS_REINTERPRET_CAST = string("reinterpret_cast"); +const string ASResource::AS_REMOVE = string("remove"); +const string ASResource::AS_SEALED = string("sealed"); +const string ASResource::AS_SELECTOR = string("selector"); +const string ASResource::AS_SET = string("set"); const string ASResource::AS_STATIC = string("static"); +const string ASResource::AS_STATIC_CAST = string("static_cast"); +const string ASResource::AS_STRUCT = string("struct"); +const string ASResource::AS_SWITCH = string("switch"); 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_TRY = string("try"); +const string ASResource::AS_UNCHECKED = string("unchecked"); +const string ASResource::AS_UNION = string("union"); +const string ASResource::AS_UNSAFE = string("unsafe"); +const string ASResource::AS_USING = string("using"); +const string ASResource::AS_VOLATILE = string("volatile"); 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_DELETE = string("delete"); +const string ASResource::AS_WHILE = string("while"); 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_BRACE = string("{"); +const string ASResource::AS_CLOSE_BRACE = 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); + const size_t elements = 15; + static bool reserved = false; + if (!reserved) + { + assignmentOperators->reserve(elements); + reserved = true; + } + + assignmentOperators->emplace_back(&AS_ASSIGN); + assignmentOperators->emplace_back(&AS_PLUS_ASSIGN); + assignmentOperators->emplace_back(&AS_MINUS_ASSIGN); + assignmentOperators->emplace_back(&AS_MULT_ASSIGN); + assignmentOperators->emplace_back(&AS_DIV_ASSIGN); + assignmentOperators->emplace_back(&AS_MOD_ASSIGN); + assignmentOperators->emplace_back(&AS_OR_ASSIGN); + assignmentOperators->emplace_back(&AS_AND_ASSIGN); + assignmentOperators->emplace_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); + assignmentOperators->emplace_back(&AS_GR_GR_GR_ASSIGN); + assignmentOperators->emplace_back(&AS_GR_GR_ASSIGN); + assignmentOperators->emplace_back(&AS_LS_LS_ASSIGN); // Unknown - assignmentOperators->push_back(&AS_LS_LS_LS_ASSIGN); + assignmentOperators->emplace_back(&AS_LS_LS_LS_ASSIGN); + assert(assignmentOperators->size() < elements); 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); + const size_t elements = 5; + static bool reserved = false; + if (!reserved) + { + castOperators->reserve(elements); + reserved = true; + } + + castOperators->emplace_back(&AS_CONST_CAST); + castOperators->emplace_back(&AS_DYNAMIC_CAST); + castOperators->emplace_back(&AS_REINTERPRET_CAST); + castOperators->emplace_back(&AS_STATIC_CAST); + + assert(castOperators->size() < elements); + sort(castOperators->begin(), castOperators->end(), sortOnName); } /** * 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 + const size_t elements = 25; + static bool reserved = false; + if (!reserved) + { + headers->reserve(elements); + reserved = true; + } + + headers->emplace_back(&AS_IF); + headers->emplace_back(&AS_ELSE); + headers->emplace_back(&AS_FOR); + headers->emplace_back(&AS_WHILE); + headers->emplace_back(&AS_DO); + headers->emplace_back(&AS_SWITCH); + headers->emplace_back(&AS_CASE); + headers->emplace_back(&AS_DEFAULT); + headers->emplace_back(&AS_TRY); + headers->emplace_back(&AS_CATCH); + headers->emplace_back(&AS_QFOREACH); // QT + headers->emplace_back(&AS_QFOREVER); // QT + headers->emplace_back(&AS_FOREACH); // QT & C# + headers->emplace_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 + headers->emplace_back(&_AS_TRY); // __try + headers->emplace_back(&_AS_FINALLY); // __finally + headers->emplace_back(&_AS_EXCEPT); // __except } if (fileType == JAVA_TYPE) { - headers->push_back(&AS_FINALLY); - headers->push_back(&AS_SYNCHRONIZED); + headers->emplace_back(&AS_FINALLY); + headers->emplace_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); + headers->emplace_back(&AS_FINALLY); + headers->emplace_back(&AS_LOCK); + headers->emplace_back(&AS_FIXED); + headers->emplace_back(&AS_GET); + headers->emplace_back(&AS_SET); + headers->emplace_back(&AS_ADD); + headers->emplace_back(&AS_REMOVE); + headers->emplace_back(&AS_USING); } if (beautifier) { if (fileType == C_TYPE) { - headers->push_back(&AS_TEMPLATE); + headers->emplace_back(&AS_TEMPLATE); } if (fileType == JAVA_TYPE) { - headers->push_back(&AS_STATIC); // for static constructor + headers->emplace_back(&AS_STATIC); // for static constructor } } + + assert(headers->size() < elements); 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); + indentableHeaders->emplace_back(&AS_RETURN); - sort(indentableHeaders->begin(), indentableHeaders->end(), sortOnName); +// 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; + const size_t elements = 10; + static bool reserved = false; + if (!reserved) + { + indentableMacros->reserve(elements); + reserved = true; + } // the pairs must be retained in memory because of pair pointers + typedef pair macro_pair; static const macro_pair macros[] = { // wxWidgets - macro_pair("BEGIN_EVENT_TABLE", "END_EVENT_TABLE"), + 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"), + 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]); + size_t entries = sizeof(macros) / sizeof(macros[0]); + for (size_t i = 0; i < entries; i++) + indentableMacros->emplace_back(¯os[i]); + + assert(indentableMacros->size() < elements); } /** * 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); + const size_t elements = 15; + static bool reserved = false; + if (!reserved) + { + nonAssignmentOperators->reserve(elements); + reserved = true; + } + nonAssignmentOperators->emplace_back(&AS_EQUAL); + nonAssignmentOperators->emplace_back(&AS_PLUS_PLUS); + nonAssignmentOperators->emplace_back(&AS_MINUS_MINUS); + nonAssignmentOperators->emplace_back(&AS_NOT_EQUAL); + nonAssignmentOperators->emplace_back(&AS_GR_EQUAL); + nonAssignmentOperators->emplace_back(&AS_GR_GR_GR); + nonAssignmentOperators->emplace_back(&AS_GR_GR); + nonAssignmentOperators->emplace_back(&AS_LS_EQUAL); + nonAssignmentOperators->emplace_back(&AS_LS_LS_LS); + nonAssignmentOperators->emplace_back(&AS_LS_LS); + nonAssignmentOperators->emplace_back(&AS_ARROW); + nonAssignmentOperators->emplace_back(&AS_AND); + nonAssignmentOperators->emplace_back(&AS_OR); + nonAssignmentOperators->emplace_back(&AS_LAMBDA); + + assert(nonAssignmentOperators->size() < elements); 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 + const size_t elements = 20; + static bool reserved = false; + if (!reserved) + { + nonParenHeaders->reserve(elements); + reserved = true; + } + + nonParenHeaders->emplace_back(&AS_ELSE); + nonParenHeaders->emplace_back(&AS_DO); + nonParenHeaders->emplace_back(&AS_TRY); + nonParenHeaders->emplace_back(&AS_CATCH); // can be paren or non-paren + nonParenHeaders->emplace_back(&AS_CASE); // can be paren or non-paren + nonParenHeaders->emplace_back(&AS_DEFAULT); + nonParenHeaders->emplace_back(&AS_QFOREVER); // QT + nonParenHeaders->emplace_back(&AS_FOREVER); // Boost if (fileType == C_TYPE) { - nonParenHeaders->push_back(&_AS_TRY); // __try - nonParenHeaders->push_back(&_AS_FINALLY); // __finally + nonParenHeaders->emplace_back(&_AS_TRY); // __try + nonParenHeaders->emplace_back(&_AS_FINALLY); // __finally } if (fileType == JAVA_TYPE) { - nonParenHeaders->push_back(&AS_FINALLY); + nonParenHeaders->emplace_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); + nonParenHeaders->emplace_back(&AS_FINALLY); + nonParenHeaders->emplace_back(&AS_GET); + nonParenHeaders->emplace_back(&AS_SET); + nonParenHeaders->emplace_back(&AS_ADD); + nonParenHeaders->emplace_back(&AS_REMOVE); } if (beautifier) { if (fileType == C_TYPE) { - nonParenHeaders->push_back(&AS_TEMPLATE); + nonParenHeaders->emplace_back(&AS_TEMPLATE); } if (fileType == JAVA_TYPE) { - nonParenHeaders->push_back(&AS_STATIC); + nonParenHeaders->emplace_back(&AS_STATIC); } } + + assert(nonParenHeaders->size() < elements); 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); + const size_t elements = 50; + static bool reserved = false; + if (!reserved) + { + operators->reserve(elements); + reserved = true; + } + + + operators->emplace_back(&AS_PLUS_ASSIGN); + operators->emplace_back(&AS_MINUS_ASSIGN); + operators->emplace_back(&AS_MULT_ASSIGN); + operators->emplace_back(&AS_DIV_ASSIGN); + operators->emplace_back(&AS_MOD_ASSIGN); + operators->emplace_back(&AS_OR_ASSIGN); + operators->emplace_back(&AS_AND_ASSIGN); + operators->emplace_back(&AS_XOR_ASSIGN); + operators->emplace_back(&AS_EQUAL); + operators->emplace_back(&AS_PLUS_PLUS); + operators->emplace_back(&AS_MINUS_MINUS); + operators->emplace_back(&AS_NOT_EQUAL); + operators->emplace_back(&AS_GR_EQUAL); + operators->emplace_back(&AS_GR_GR_GR_ASSIGN); + operators->emplace_back(&AS_GR_GR_ASSIGN); + operators->emplace_back(&AS_GR_GR_GR); + operators->emplace_back(&AS_GR_GR); + operators->emplace_back(&AS_LS_EQUAL); + operators->emplace_back(&AS_LS_LS_LS_ASSIGN); + operators->emplace_back(&AS_LS_LS_ASSIGN); + operators->emplace_back(&AS_LS_LS_LS); + operators->emplace_back(&AS_LS_LS); + operators->emplace_back(&AS_QUESTION_QUESTION); + operators->emplace_back(&AS_LAMBDA); + operators->emplace_back(&AS_ARROW); + operators->emplace_back(&AS_AND); + operators->emplace_back(&AS_OR); + operators->emplace_back(&AS_SCOPE_RESOLUTION); + operators->emplace_back(&AS_PLUS); + operators->emplace_back(&AS_MINUS); + operators->emplace_back(&AS_MULT); + operators->emplace_back(&AS_DIV); + operators->emplace_back(&AS_MOD); + operators->emplace_back(&AS_QUESTION); + operators->emplace_back(&AS_COLON); + operators->emplace_back(&AS_ASSIGN); + operators->emplace_back(&AS_LS); + operators->emplace_back(&AS_GR); + operators->emplace_back(&AS_NOT); + operators->emplace_back(&AS_BIT_OR); + operators->emplace_back(&AS_BIT_AND); + operators->emplace_back(&AS_BIT_NOT); + operators->emplace_back(&AS_BIT_XOR); if (fileType == C_TYPE) { - operators->push_back(&AS_GCC_MIN_ASSIGN); - operators->push_back(&AS_GCC_MAX_ASSIGN); + operators->emplace_back(&AS_GCC_MIN_ASSIGN); + operators->emplace_back(&AS_GCC_MAX_ASSIGN); } + + assert(operators->size() < elements); 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); + const size_t elements = 10; + static bool reserved = false; + if (!reserved) + { + preBlockStatements->reserve(elements); + reserved = true; + } + + preBlockStatements->emplace_back(&AS_CLASS); if (fileType == C_TYPE) { - preBlockStatements->push_back(&AS_STRUCT); - preBlockStatements->push_back(&AS_UNION); - preBlockStatements->push_back(&AS_NAMESPACE); - preBlockStatements->push_back(&AS_MODULE); // for CORBA IDL - preBlockStatements->push_back(&AS_INTERFACE); // for CORBA IDL + preBlockStatements->emplace_back(&AS_STRUCT); + preBlockStatements->emplace_back(&AS_UNION); + preBlockStatements->emplace_back(&AS_NAMESPACE); + preBlockStatements->emplace_back(&AS_MODULE); // for CORBA IDL + preBlockStatements->emplace_back(&AS_INTERFACE); // for CORBA IDL } if (fileType == JAVA_TYPE) { - preBlockStatements->push_back(&AS_INTERFACE); - preBlockStatements->push_back(&AS_THROWS); + preBlockStatements->emplace_back(&AS_INTERFACE); + preBlockStatements->emplace_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); + preBlockStatements->emplace_back(&AS_INTERFACE); + preBlockStatements->emplace_back(&AS_NAMESPACE); + preBlockStatements->emplace_back(&AS_WHERE); + preBlockStatements->emplace_back(&AS_STRUCT); } + + assert(preBlockStatements->size() < elements); 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. + * the closing paren and the opening brace. * e.g. in "void foo() const {}", "const" is a preCommandHeader. */ void ASResource::buildPreCommandHeaders(vector* preCommandHeaders, int fileType) { + const size_t elements = 10; + static bool reserved = false; + if (!reserved) + { + preCommandHeaders->reserve(elements); + reserved = true; + } + 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 + preCommandHeaders->emplace_back(&AS_CONST); + preCommandHeaders->emplace_back(&AS_FINAL); + preCommandHeaders->emplace_back(&AS_INTERRUPT); + preCommandHeaders->emplace_back(&AS_NOEXCEPT); + preCommandHeaders->emplace_back(&AS_OVERRIDE); + preCommandHeaders->emplace_back(&AS_VOLATILE); + preCommandHeaders->emplace_back(&AS_SEALED); // Visual C only + preCommandHeaders->emplace_back(&AS_AUTORELEASEPOOL); // Obj-C only } if (fileType == JAVA_TYPE) { - preCommandHeaders->push_back(&AS_THROWS); + preCommandHeaders->emplace_back(&AS_THROWS); } if (fileType == SHARP_TYPE) { - preCommandHeaders->push_back(&AS_WHERE); + preCommandHeaders->emplace_back(&AS_WHERE); } + assert(preCommandHeaders->size() < elements); 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 'enum' here. It is an array type brace. * 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); + const size_t elements = 10; + static bool reserved = false; + if (!reserved) + { + preDefinitionHeaders->reserve(elements); + reserved = true; + } + + preDefinitionHeaders->emplace_back(&AS_CLASS); if (fileType == C_TYPE) { - preDefinitionHeaders->push_back(&AS_STRUCT); - preDefinitionHeaders->push_back(&AS_UNION); - preDefinitionHeaders->push_back(&AS_NAMESPACE); - preDefinitionHeaders->push_back(&AS_MODULE); // for CORBA IDL - preDefinitionHeaders->push_back(&AS_INTERFACE); // for CORBA IDL + preDefinitionHeaders->emplace_back(&AS_STRUCT); + preDefinitionHeaders->emplace_back(&AS_UNION); + preDefinitionHeaders->emplace_back(&AS_NAMESPACE); + preDefinitionHeaders->emplace_back(&AS_MODULE); // for CORBA IDL + preDefinitionHeaders->emplace_back(&AS_INTERFACE); // for CORBA IDL } if (fileType == JAVA_TYPE) { - preDefinitionHeaders->push_back(&AS_INTERFACE); + preDefinitionHeaders->emplace_back(&AS_INTERFACE); } if (fileType == SHARP_TYPE) { - preDefinitionHeaders->push_back(&AS_STRUCT); - preDefinitionHeaders->push_back(&AS_INTERFACE); - preDefinitionHeaders->push_back(&AS_NAMESPACE); + preDefinitionHeaders->emplace_back(&AS_STRUCT); + preDefinitionHeaders->emplace_back(&AS_INTERFACE); + preDefinitionHeaders->emplace_back(&AS_NAMESPACE); } + + assert(preDefinitionHeaders->size() < elements); sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ASBase Functions * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +// check if a specific line position contains a header. +const string* ASBase::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 nullptr; +} + // 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, (int)wordEnd - 1); + const char peekChar = peekNextChar(line, (int) wordEnd - 1); if (peekChar == ',' || peekChar == ')') return false; return true; } +// check if a specific line position contains an operator. +const string* ASBase::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 nullptr; +} + // 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) + if ((unsigned char) 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 (i > 1 && line[i - 2] == '\\') + prevCh = ' '; 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/plugins/astyle/3rdparty/libastyle/README b/plugins/astyle/3rdparty/libastyle/README index 8c24c444f3..812d3d39a5 100644 --- a/plugins/astyle/3rdparty/libastyle/README +++ b/plugins/astyle/3rdparty/libastyle/README @@ -1,23 +1,23 @@ -This is a copy of the official AStyle library. +This is a copy of the official AStyle library, currently version 3.1 . See: http://astyle.sourceforge.net/ License: http://astyle.sourceforge.net/license.html You should *not* touch this code, besides rebasing it against an official Astyle release. When you find a bug, fix it upstream, see e.g. http://astyle.sourceforge.net/subversion.html When you still have to touch this code, please mark your changes explicitly, for example this would be good: ... //BEGIN KDEVELOP // see also: {link to reviewboard or bug} ... your changes here //END KDEVELOP ... This makes it easier to rebase them afterwards onto a new AStyle release. -Also make sure you add a unit test! \ No newline at end of file +Also make sure you add a unit test! diff --git a/plugins/astyle/3rdparty/libastyle/astyle.h b/plugins/astyle/3rdparty/libastyle/astyle.h index b499950bb0..d886aa6c20 100644 --- a/plugins/astyle/3rdparty/libastyle/astyle.h +++ b/plugins/astyle/3rdparty/libastyle/astyle.h @@ -1,1021 +1,1083 @@ // astyle.h -// Copyright (c) 2016 by Jim Pattee . +// Copyright (c) 2018 by Jim Pattee . // This code is licensed under the MIT License. -// License.txt describes the conditions under which this software may be distributed. +// License.md 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 #include #ifdef __GNUC__ #include // need both string and cstring for GCC #endif //----------------------------------------------------------------------------- // declarations //----------------------------------------------------------------------------- #ifdef _MSC_VER #pragma warning(disable: 4267) // conversion from size_t to int #endif #ifdef __BORLANDC__ #pragma warn -8004 // variable is assigned a value that is never used #endif +#ifdef __GNUC__ + #pragma GCC diagnostic ignored "-Wconversion" +#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 "-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_RATLIFF, STYLE_GNU, STYLE_LINUX, STYLE_HORSTMANN, STYLE_1TBS, STYLE_GOOGLE, STYLE_MOZILLA, STYLE_PICO, STYLE_LISP }; -enum BracketMode +enum BraceMode { NONE_MODE, ATTACH_MODE, BREAK_MODE, LINUX_MODE, - RUN_IN_MODE // broken brackets + RUN_IN_MODE // broken braces }; -// maximun value for int is 16,384 (total value of 32,767) -enum BracketType +// maximum value for int is 16,384 (total value of 32,767) +enum BraceType { 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 EMPTY_BLOCK_TYPE = 2048, // also a SINGLE_LINE_TYPE BREAK_BLOCK_TYPE = 4096, // also a SINGLE_LINE_TYPE SINGLE_LINE_TYPE = 8192 }; 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, + ENCODING_8BIT, // includes UTF-8 without BOM + UTF_8BOM, // UTF-8 with BOM UTF_16BE, - UTF_16LE, // Windows default + 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 streamoff getPeekStart() const = 0; 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 ASPeekStream +// A small class using RAII to peek ahead in the ASSourceIterator stream +// and to reset the ASSourceIterator pointer in the destructor. +// It enables a return from anywhere in the method. +//----------------------------------------------------------------------------- + +class ASPeekStream +{ +private: + ASSourceIterator* sourceIterator; + bool needReset; // reset sourceIterator to the original position + +public: + explicit ASPeekStream(ASSourceIterator* sourceIterator_) + { sourceIterator = sourceIterator_; needReset = false; } + + ~ASPeekStream() + { if (needReset) sourceIterator->peekReset(); } + + bool hasMoreLines() const + { return sourceIterator->hasMoreLines(); } + + string peekNextLine() + { needReset = true; return sourceIterator->peekNextLine(); } +}; + + //----------------------------------------------------------------------------- // 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_MODULE; 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, AS_DELETE; + static const string AS_FINAL, AS_OVERRIDE; + static const string AS_STATIC, AS_CONST, AS_SEALED, AS_VOLATILE, AS_NEW, AS_DELETE; 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_BRACE, AS_CLOSE_BRACE; 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_AUTO, 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; static const string AS_LS_EQUAL, AS_LS_LS_LS, AS_LS_LS, AS_GR_GR_GR, AS_GR_GR; 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 +class ASBase : protected ASResource { 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 + const string* findHeader(const string& line, int i, + const vector* possibleHeaders) const; bool findKeyword(const string& line, int i, const string& keyword) const; + const string* findOperator(const string& line, int i, + const vector* possibleOperators) 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 +class ASBeautifier : protected ASBase { public: ASBeautifier(); virtual ~ASBeautifier(); virtual void init(ASSourceIterator* iter); virtual string beautify(const string& originalLine); void setCaseIndent(bool state); void setClassIndent(bool state); void setContinuationIndentation(int indent = 1); void setCStyle(); void setDefaultTabLength(); void setEmptyLineFill(bool state); void setForceTabXIndentation(int length); + void setAfterParenIndent(bool state); void setJavaStyle(); void setLabelIndent(bool state); + void setMaxContinuationIndentLength(int max); 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() const; int getTabLength() const; string getIndentString() const; string getNextWord(const string& line, size_t currPos) const; bool getAlignMethodColon() const; - bool getBracketIndent() const; + bool getBraceIndent() const; bool getBlockIndent() const; bool getCaseIndent() const; bool getClassIndent() const; bool getEmptyLineFill() const; bool getForceTabIndentation() const; bool getModeManuallySet() const; bool getModifierIndent() const; bool getNamespaceIndent() const; bool getPreprocDefineIndent() const; bool getSwitchIndent() 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; + int indexOf(const vector& container, const string* element) const; void setBlockIndent(bool state); - void setBracketIndent(bool state); - void setBracketIndentVtk(bool state); + void setBraceIndent(bool state); + void setBraceIndentVtk(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 runInIndentContinuation; + int nonInStatementBrace; 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& other); // inline functions - ASBeautifier& operator=(ASBeautifier&); // not to be implemented + ASBeautifier& operator=(ASBeautifier&); // not to be implemented void adjustObjCMethodDefinitionIndentation(const string& line_); void adjustObjCMethodCallIndentation(const string& line_); void adjustParsedLineIndentation(size_t iPrelim, bool isInExtraHeaderIndent); void computePreliminaryIndentation(); void parseCurrentLine(const string& line); - void popLastInStatementIndent(); + void popLastContinuationIndent(); 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 registerContinuationIndent(const string& line, int i, int spaceIndentCount_, + int tabIncrementIn, int minIndent, bool updateParenStack); + void registerContinuationIndentColon(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(const 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; - int getObjCFollowingKeyword(const string& line, int BracketPos) const; + int findObjCColonAlignment(const string& line) const; + int getContinuationIndentAssign(const string& line, size_t currPos) const; + int getContinuationIndentComma(const string& line, size_t currPos) const; + int getObjCFollowingKeyword(const string& line, int bracePos) 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 isTopLevel() const; bool statementEndsWithComma(const string& line, int index) const; - string& getIndentedLineReturn(string& newLine, const string& originalLine) const; + const string& getIndentedLineReturn(const string& newLine, const string& originalLine) const; string getIndentedSpaceEquivalent(const string& line_) 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* parenDepthStack; vector* blockStatementStack; vector* parenStatementStack; - vector* bracketBlockStateStack; - vector* inStatementIndentStack; - vector* inStatementIndentStackSizeStack; + vector* braceBlockStateStack; + vector* continuationIndentStack; + vector* continuationIndentStackSizeStack; 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 isInRunInComment; bool isInCase; bool isInQuestion; - bool isInStatement; + bool isContinuation; bool isInHeader; bool isInTemplate; bool isInDefine; bool isInDefineDefinition; bool classIndent; bool isIndentModeOff; - bool isInClassHeader; // is in a class before the opening bracket + bool isInClassHeader; // is in a class before the opening brace 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 isInClass; // is in a class after the opening brace bool isInObjCMethodDefinition; bool isInObjCMethodCall; bool isInObjCMethodCallFirst; bool isImmediatelyPostObjCMethodDefinition; bool isImmediatelyPostObjCMethodCall; bool isInIndentablePreprocBlock; bool isInObjCInterface; bool isInEnum; bool isInEnumTypeID; bool isInLet; + bool isInTrailingReturnType; bool modifierIndent; bool switchIndent; bool caseIndent; bool namespaceIndent; - bool bracketIndent; - bool bracketIndentVtk; bool blockIndent; + bool braceIndent; + bool braceIndentVtk; + bool shouldIndentAfterParen; 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 lineBeginsWithOpenBrace; + bool lineBeginsWithCloseBrace; bool lineBeginsWithComma; bool lineIsCommentOnly; bool lineIsLineCommentOnly; - bool shouldIndentBrackettedLine; + bool shouldIndentBracedLine; bool isInSwitch; bool foundPreCommandHeader; bool foundPreCommandMacro; bool shouldAlignMethodColon; bool shouldIndentPreprocConditional; int indentCount; int spaceIndentCount; int spaceIndentObjCMethodAlignment; - int bracketPosObjCMethodAlignment; + int bracePosObjCMethodAlignment; int colonIndentObjCMethodAlignment; int lineOpeningBlocksNum; int lineClosingBlocksNum; int fileType; int minConditionalOption; int minConditionalIndent; int parenDepth; int indentLength; int tabLength; int continuationIndent; int blockTabCount; - int maxInStatementIndent; + int maxContinuationIndent; int classInitializerIndents; int templateDepth; - int blockParenCount; + 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(const 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; + void convertForceTabIndentToSpaces(string& line) const; + void convertSpaceIndentToForceTab(string& line) const; + size_t findCaseColon(const string& line, size_t caseIndex) const; + int indentLine(string& line, int indent) const; + bool isBeginDeclareSectionSQL(const string& line, size_t index) const; + bool isEndDeclareSectionSQL(const string& line, size_t index) const; + bool isOneLineBlockReached(const 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 braceCount; int switchDepth; int eventPreprocDepth; - bool lookingForCaseBracket; + bool lookingForCaseBrace; bool unindentNextLine; bool shouldUnindentLine; bool shouldUnindentComment; // struct used by ParseFormattedLine function // contains variables used to unindent the case blocks struct SwitchVariables { - int switchBracketCount; + int switchBraceCount; 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* si); 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 setAddBracesMode(bool state); + void setAddOneLineBracesMode(bool state); + void setRemoveBracesMode(bool state); void setAttachClass(bool state); + void setAttachClosingWhile(bool state); void setAttachExternC(bool state); void setAttachNamespace(bool state); void setAttachInline(bool state); - void setBracketFormatMode(BracketMode mode); + void setBraceFormatMode(BraceMode mode); void setBreakAfterMode(bool state); - void setBreakClosingHeaderBracketsMode(bool state); + void setBreakClosingHeaderBracesMode(bool state); void setBreakBlocksMode(bool state); void setBreakClosingHeaderBlocksMode(bool state); void setBreakElseIfsMode(bool state); void setBreakOneLineBlocksMode(bool state); void setBreakOneLineHeadersMode(bool state); void setBreakOneLineStatementsMode(bool state); void setMethodPrefixPaddingMode(bool state); void setMethodPrefixUnPaddingMode(bool state); void setReturnTypePaddingMode(bool state); void setReturnTypeUnPaddingMode(bool state); void setParamTypePaddingMode(bool state); void setParamTypeUnPaddingMode(bool state); void setCloseTemplatesMode(bool state); void setCommaPaddingMode(bool state); void setDeleteEmptyLinesMode(bool state); + void setBreakReturnType(bool state); + void setBreakReturnTypeDecl(bool state); + void setAttachReturnType(bool state); + void setAttachReturnTypeDecl(bool state); void setIndentCol1CommentsMode(bool state); void setLineEndFormat(LineEndFormat fmt); void setMaxCodeLength(int max); void setObjCColonPaddingMode(ObjCColonPad mode); void setOperatorPaddingMode(bool state); void setParensOutsidePaddingMode(bool state); void setParensFirstPaddingMode(bool state); void setParensInsidePaddingMode(bool state); void setParensHeaderPaddingMode(bool state); void setParensUnPaddingMode(bool state); void setPointerAlignment(PointerAlign alignment); void setPreprocBlockIndent(bool state); void setReferenceAlignment(ReferenceAlign alignment); void setStripCommentPrefix(bool state); void setTabSpaceConversionMode(bool state); size_t getChecksumIn() const; size_t getChecksumOut() const; int getChecksumDiff() const; int getFormatterFileType() const; + // retained for compatibility with release 2.06 + // "Brackets" have been changed to "Braces" in 3.0 + // they are referenced only by the old "bracket" options + void setAddBracketsMode(bool state); + void setAddOneLineBracketsMode(bool state); + void setRemoveBracketsMode(bool state); + void setBreakClosingHeaderBracketsMode(bool state); + 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(); + BraceType getBraceType(); bool adjustChecksumIn(int adjustment); bool computeChecksumIn(const string& currentLine_); bool computeChecksumOut(const string& beautifiedLine); - bool addBracketsToStatement(); - bool removeBracketsFromStatement(); + bool addBracesToStatement(); + bool removeBracesFromStatement(); 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 isBraceType(BraceType a, BraceType b) const; bool isClassInitializer() const; bool isClosingHeader(const string* header) const; - bool isCurrentBracketBroken() const; + bool isCurrentBraceBroken() const; bool isDereferenceOrAddressOf() const; - bool isExecSQL(string& line, size_t index) const; + bool isExecSQL(const string& line, size_t index) const; bool isEmptyLine(const string& line) const; bool isExternC() const; bool isMultiStatementLine() const; bool isNextWordSharpNonParenHeader(int startChar) const; - bool isNonInStatementArrayBracket() const; + bool isNonInStatementArrayBrace() const; + bool isNumericVariable(string word) const; bool isOkToSplitFormattedLine(); bool isPointerOrReference() const; bool isPointerOrReferenceCentered() const; - bool isPointerOrReferenceVariable(string& word) const; + bool isPointerOrReferenceVariable(const string& word) const; + bool isPointerToPointer(const string& line, int currPos) const; bool isSharpStyleWithParen(const string* header) const; - bool isStructAccessModified(string& firstLine, size_t index) const; - bool isIndentablePreprocessorBlock(string& firstLine, size_t index); - bool isNDefPreprocStatement(string& nextLine_, string& preproc) const; + bool isStructAccessModified(const string& firstLine, size_t index) const; + bool isIndentablePreprocessorBlock(const string& firstLine, size_t index); + bool isNDefPreprocStatement(const string& nextLine_, const string& preproc) const; bool isUnaryOperator() const; - bool isUniformInitializerBracket() const; + bool isUniformInitializerBrace() const; bool isImmediatelyPostCast() const; bool isInExponent() const; bool isInSwitchStatement() const; - bool isNextCharOpeningBracket(int startChar) const; - bool isOkToBreakBlock(BracketType bracketType) const; + bool isNextCharOpeningBrace(int startChar) const; + bool isOkToBreakBlock(BraceType braceType) const; bool isOperatorPaddingDisabled() const; bool pointerSymbolFollows() const; int findObjCColonAlignment() const; int getCurrentLineCommentAdjustment(); int getNextLineCommentAdjustment(); int isOneLineBlockReached(const string& line, int startChar) const; void adjustComments(); void appendChar(char ch, bool canBreakLine); void appendCharInsideComments(); + void appendClosingHeader(); 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 deleteContainer(vector*& container); + void findReturnTypeSplitPoint(const string& firstLine); void formatArrayRunIn(); void formatRunIn(); - void formatArrayBrackets(BracketType bracketType, bool isOpeningArrayBracket); - void formatClosingBracket(BracketType bracketType); + void formatArrayBraces(BraceType braceType, bool isOpeningArrayBrace); + void formatClosingBrace(BraceType braceType); void formatCommentBody(); void formatCommentOpener(); void formatCommentCloser(); void formatLineCommentBody(); void formatLineCommentOpener(); - void formatOpeningBracket(BracketType bracketType); + void formatOpeningBrace(BraceType braceType); 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 initContainer(vector*& container, vector* value); void initNewLine(); void padObjCMethodColon(); void padObjCMethodPrefix(); void padObjCParamType(); void padObjCReturnType(); void padOperators(const string* newOperator); void padParens(); void processPreprocessor(); void resetEndOfStatement(); - void setAttachClosingBracketMode(bool state); + void setAttachClosingBraceMode(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; + size_t findNextChar(const 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; + string peekNextText(const string& firstLine, + bool endOnEmptyLine = false, + shared_ptr streamArg = nullptr) 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* preBraceHeaderStack; + vector* braceTypeStack; 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 runInIndentChars; int nextLineSpacePadNum; int objCColonAlign; - int preprocBracketTypeStackSize; + int preprocBraceTypeStackSize; int spacePadNum; int tabIncrementIn; int templateDepth; - int blockParenCount; + int squareBracketCount; size_t checksumIn; size_t checksumOut; - size_t currentLineFirstBracketNum; // first bracket location on currentLine + size_t currentLineFirstBraceNum; // first brace location on currentLine size_t formattedLineCommentNum; // comment location on formattedLine size_t leadingSpaces; size_t maxCodeLength; + size_t methodAttachCharNum; + size_t methodAttachLineNum; + size_t methodBreakCharNum; + size_t methodBreakLineNum; // 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; + BraceMode braceFormatMode; + BraceType previousBraceType; PointerAlign pointerAlignment; ReferenceAlign referenceAlignment; ObjCColonPad objCColonPadMode; LineEndFormat lineEnd; bool isVirgin; bool isInVirginLine; 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 shouldAttachClosingWhile; 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 foundTrailingReturnType; 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 isPreviousBraceBlockRelated; bool isInPotentialCalculation; bool isCharImmediatelyPostComment; bool isPreviousCharPostComment; bool isCharImmediatelyPostLineComment; bool isCharImmediatelyPostOpenBlock; bool isCharImmediatelyPostCloseBlock; bool isCharImmediatelyPostTemplate; bool isCharImmediatelyPostReturn; bool isCharImmediatelyPostThrow; bool isCharImmediatelyPostNewDelete; bool isCharImmediatelyPostOperator; bool isCharImmediatelyPostPointerOrReference; bool isInObjCMethodDefinition; bool isInObjCInterface; bool isInObjCReturnType; + bool isInObjCParam; bool isInObjCSelector; bool breakCurrentOneLineBlock; - bool shouldRemoveNextClosingBracket; - bool isInBracketRunIn; - bool currentLineBeginsWithBracket; - bool attachClosingBracketMode; + bool shouldRemoveNextClosingBrace; + bool isInBraceRunIn; + bool returnTypeChecked; + bool currentLineBeginsWithBrace; + bool attachClosingBraceMode; bool shouldBreakOneLineBlocks; bool shouldBreakOneLineHeaders; bool shouldBreakOneLineStatements; - bool shouldBreakClosingHeaderBrackets; + bool shouldBreakClosingHeaderBraces; bool shouldBreakElseIfs; bool shouldBreakLineAfterLogical; - bool shouldAddBrackets; - bool shouldAddOneLineBrackets; - bool shouldRemoveBrackets; + bool shouldAddBraces; + bool shouldAddOneLineBraces; + bool shouldRemoveBraces; bool shouldPadMethodColon; bool shouldPadMethodPrefix; bool shouldReparseCurrentChar; bool shouldUnPadMethodPrefix; bool shouldPadReturnType; bool shouldUnPadReturnType; bool shouldPadParamType; bool shouldUnPadParamType; bool shouldDeleteEmptyLines; - bool needHeaderOpeningBracket; + bool shouldBreakReturnType; + bool shouldBreakReturnTypeDecl; + bool shouldAttachReturnType; + bool shouldAttachReturnTypeDecl; + bool needHeaderOpeningBrace; 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 isImmediatelyPostNewDelete; bool isImmediatelyPostOperator; bool isImmediatelyPostTemplate; bool isImmediatelyPostPointerOrReference; bool shouldBreakBlocks; bool shouldBreakClosingHeaderBlocks; bool isPrependPostBlockEmptyLineRequested; bool isAppendPostBlockEmptyLineRequested; bool isIndentableProprocessor; bool isIndentableProprocessorBlock; bool prependEmptyLine; - bool appendOpeningBracket; + bool appendOpeningBrace; 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); - } + { 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; - } + { 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_); - } + { return ASBase::findHeader(currentLine, charNum, headers_); } // call ASBase::findOperator for the current character - const string* findOperator(const vector* headers_) - { - return ASBeautifier::findOperator(currentLine, charNum, headers_); - } + const string* findOperator(const vector* operators_) + { return ASBase::findOperator(currentLine, charNum, operators_); } }; // 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 +} // namespace astyle // end of astyle namespace -------------------------------------------------- #endif // closes ASTYLE_H diff --git a/plugins/astyle/astyle_formatter.cpp b/plugins/astyle/astyle_formatter.cpp index 0c473e97e6..2e04947fbf 100644 --- a/plugins/astyle/astyle_formatter.cpp +++ b/plugins/astyle/astyle_formatter.cpp @@ -1,524 +1,524 @@ /* This file is part of KDevelop * Copyright (C) 2008 Cédric Pasteur Copyright (C) 2001 Matthias Hölzer-Klüpfel This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "astyle_formatter.h" #include #include #include #include "astyle_stringiterator.h" #include "debug.h" using namespace KDevelop; AStyleFormatter::AStyleFormatter() : ASFormatter() { } QString AStyleFormatter::formatSource(const QString &text, const QString& leftContext, const QString& rightContext) { QString useText = leftContext + text + rightContext; AStyleStringIterator is(useText); QString output; QTextStream os(&output, QIODevice::WriteOnly); init(&is); while(hasMoreLines()) os << QString::fromUtf8(nextLine().c_str()) << endl; init(nullptr); return extractFormattedTextFromContext(output, text, leftContext, rightContext, m_options[QStringLiteral("FillCount")].toInt()); } void AStyleFormatter::setOption(const QString &key, const QVariant &value) { m_options[key] = value; } void AStyleFormatter::updateFormatter() { qCDebug(KDEV_ASTYLE) << "Updating option with: " << ISourceFormatter::optionMapToString(m_options) << endl; // fill int wsCount = m_options[QStringLiteral("FillCount")].toInt(); if(m_options[QStringLiteral("Fill")].toString() == QLatin1String("Tabs")) { ///TODO: rename FillForce somehow... bool force = m_options[QStringLiteral("FillForce")].toBool(); AStyleFormatter::setTabSpaceConversionMode(false); AStyleFormatter::setTabIndentation(wsCount, force ); m_indentString = QStringLiteral("\t"); } else { AStyleFormatter::setSpaceIndentation(wsCount); m_indentString.fill(QLatin1Char(' '), wsCount); AStyleFormatter::setTabSpaceConversionMode(m_options[QStringLiteral("FillForce")].toBool()); } AStyleFormatter::setEmptyLineFill(m_options[QStringLiteral("Fill_EmptyLines")].toBool()); // indent AStyleFormatter::setSwitchIndent(m_options[QStringLiteral("IndentSwitches")].toBool()); AStyleFormatter::setClassIndent(m_options[QStringLiteral("IndentClasses")].toBool()); AStyleFormatter::setCaseIndent(m_options[QStringLiteral("IndentCases")].toBool()); AStyleFormatter::setBracketIndent(m_options[QStringLiteral("IndentBrackets")].toBool()); AStyleFormatter::setNamespaceIndent(m_options[QStringLiteral("IndentNamespaces")].toBool()); AStyleFormatter::setLabelIndent(m_options[QStringLiteral("IndentLabels")].toBool()); AStyleFormatter::setBlockIndent(m_options[QStringLiteral("IndentBlocks")].toBool()); AStyleFormatter::setPreprocessorIndent(m_options[QStringLiteral("IndentPreprocessors")].toBool()); // continuation AStyleFormatter::setMaxInStatementIndentLength(m_options[QStringLiteral("MaxStatement")].toInt()); if(m_options[QStringLiteral("MinConditional")].toInt() != -1) AStyleFormatter::setMinConditionalIndentLength(m_options[QStringLiteral("MinConditional")].toInt()); // brackets QString s = m_options[QStringLiteral("Brackets")].toString(); if(s == QLatin1String("Break")) AStyleFormatter::setBracketFormatMode(astyle::BREAK_MODE); else if(s == QLatin1String("Attach")) AStyleFormatter::setBracketFormatMode(astyle::ATTACH_MODE); else if(s == QLatin1String("Linux")) AStyleFormatter::setBracketFormatMode(astyle::LINUX_MODE); else if(s == QLatin1String("Stroustrup")) // In astyle 2.06 BracketMode STROUSTRUP_MODE was removed and LINUX_MODE is the replacement AStyleFormatter::setBracketFormatMode(astyle::LINUX_MODE); else if(s == QLatin1String("Horstmann") || s == QLatin1String("RunInMode")) AStyleFormatter::setBracketFormatMode(astyle::RUN_IN_MODE); else AStyleFormatter::setBracketFormatMode(astyle::NONE_MODE); AStyleFormatter::setBreakClosingHeaderBracketsMode(m_options[QStringLiteral("BracketsCloseHeaders")].toBool()); // blocks AStyleFormatter::setBreakBlocksMode(m_options[QStringLiteral("BlockBreak")].toBool()); AStyleFormatter::setBreakClosingHeaderBlocksMode(m_options[QStringLiteral("BlockBreakAll")].toBool()); AStyleFormatter::setBreakElseIfsMode(m_options[QStringLiteral("BlockIfElse")].toBool()); // padding AStyleFormatter::setOperatorPaddingMode(m_options[QStringLiteral("PadOperators")].toBool()); AStyleFormatter::setParensInsidePaddingMode(m_options[QStringLiteral("PadParenthesesIn")].toBool()); AStyleFormatter::setParensOutsidePaddingMode(m_options[QStringLiteral("PadParenthesesOut")].toBool()); AStyleFormatter::setParensHeaderPaddingMode(m_options[QStringLiteral("PadParenthesesHeader")].toBool()); AStyleFormatter::setParensUnPaddingMode(m_options[QStringLiteral("PadParenthesesUn")].toBool()); // oneliner AStyleFormatter::setBreakOneLineBlocksMode(!m_options[QStringLiteral("KeepBlocks")].toBool()); AStyleFormatter::setBreakOneLineStatementsMode(!m_options[QStringLiteral("KeepStatements")].toBool()); // pointer s = m_options[QStringLiteral("PointerAlign")].toString(); if(s == QLatin1String("Name")) AStyleFormatter::setPointerAlignment(astyle::PTR_ALIGN_NAME); else if(s == QLatin1String("Middle")) AStyleFormatter::setPointerAlignment(astyle::PTR_ALIGN_MIDDLE); else if(s == QLatin1String("Type")) AStyleFormatter::setPointerAlignment(astyle::PTR_ALIGN_TYPE); else AStyleFormatter::setPointerAlignment(astyle::PTR_ALIGN_NONE); } void AStyleFormatter::resetStyle() { setSpaceIndentation(4); setBracketFormatMode(astyle::NONE_MODE); setBreakOneLineBlocksMode(true); setBreakOneLineStatementsMode(true); // blocks setBreakBlocksMode(false); setBreakClosingHeaderBlocksMode(false); setBreakElseIfsMode(false); setBreakClosingHeaderBracketsMode(false); //indent setTabIndentation(4, false); setEmptyLineFill(false); setMaxInStatementIndentLength(40); setMinConditionalIndentLength(-1); setSwitchIndent(true); setClassIndent(true); setCaseIndent(false); setBracketIndent(false); setNamespaceIndent(true); setLabelIndent(true); setBlockIndent(false); setPreprocessorIndent(false); //padding setOperatorPaddingMode(false); setParensInsidePaddingMode(true); setParensOutsidePaddingMode(true); setParensHeaderPaddingMode(true); setParensUnPaddingMode(true); } bool AStyleFormatter::predefinedStyle( const QString & style ) { if(style == QLatin1String("ANSI")) { resetStyle(); setBracketIndent(false); setSpaceIndentation(4); setBracketFormatMode(astyle::BREAK_MODE); setClassIndent(false); setSwitchIndent(false); setNamespaceIndent(false); return true; } else if(style == QLatin1String("K&R")) { resetStyle(); setBracketIndent(false); setSpaceIndentation(4); setBracketFormatMode(astyle::ATTACH_MODE); setClassIndent(false); setSwitchIndent(false); setNamespaceIndent(false); return true; } else if(style == QLatin1String("Linux")) { resetStyle(); setBracketIndent(false); setSpaceIndentation(8); setBracketFormatMode(astyle::LINUX_MODE); setClassIndent(false); setSwitchIndent(false); setNamespaceIndent(false); return true; } else if(style == QLatin1String("GNU")) { resetStyle(); setBlockIndent(true); setSpaceIndentation(2); setBracketFormatMode(astyle::BREAK_MODE); setClassIndent(false); setSwitchIndent(false); setNamespaceIndent(false); return true; } else if(style == QLatin1String("Java")) { resetStyle(); setJavaStyle(); setBracketIndent(false); setSpaceIndentation(4); setBracketFormatMode(astyle::ATTACH_MODE); setSwitchIndent(false); return true; } else if (style == QLatin1String("Stroustrup")) { resetStyle(); setBracketFormatMode(astyle::LINUX_MODE); setBlockIndent(false); setBracketIndent(false); setSpaceIndentation(5); setClassIndent(false); setSwitchIndent(false); setNamespaceIndent(false); return true; } else if (style == QLatin1String("Horstmann")) { resetStyle(); setBracketFormatMode(astyle::RUN_IN_MODE); setBlockIndent(false); setBracketIndent(false); setSwitchIndent(true); setSpaceIndentation(3); setClassIndent(false); setNamespaceIndent(false); return true; } else if (style == QLatin1String("Whitesmith")) { resetStyle(); setSpaceIndentation(4); setBracketFormatMode(astyle::BREAK_MODE); setBlockIndent(false); setBracketIndent(true); setClassIndent(true); setSwitchIndent(true); setNamespaceIndent(false); return true; } else if (style == QLatin1String("Banner")) { resetStyle(); setSpaceIndentation(4); setBracketFormatMode(astyle::ATTACH_MODE); setBlockIndent(false); setBracketIndent(true); setClassIndent(true); setSwitchIndent(true); setNamespaceIndent(false); return true; } else if (style == QLatin1String("1TBS")) { resetStyle(); setSpaceIndentation(4); setBracketFormatMode(astyle::LINUX_MODE); setBlockIndent(false); setBracketIndent(false); setAddBracketsMode(true); setClassIndent(false); setSwitchIndent(false); setNamespaceIndent(false); return true; } else if (style == QLatin1String("KDELibs")) { // https://community.kde.org/Policies/Kdelibs_Coding_Style resetStyle(); setSpaceIndentation(4); setBracketFormatMode(astyle::LINUX_MODE); setPointerAlignment(astyle::PTR_ALIGN_TYPE); setLabelIndent(true); setOperatorPaddingMode(true); setParensInsidePaddingMode(false); setParensOutsidePaddingMode(false); setParensHeaderPaddingMode(true); setParensUnPaddingMode(true); setBreakOneLineStatementsMode(false); setTabSpaceConversionMode(true); setPreprocessorIndent(true); setSwitchIndent(false); setClassIndent(false); setNamespaceIndent(false); return true; } else if (style == QLatin1String("Qt")) { // https://wiki.qt.io/Qt_Coding_Style resetStyle(); setPointerAlignment(astyle::PTR_ALIGN_NAME); setOperatorPaddingMode(true); setBracketFormatMode(astyle::LINUX_MODE); setSwitchIndent(false); setParensInsidePaddingMode(false); setParensOutsidePaddingMode(false); setParensHeaderPaddingMode(true); setParensUnPaddingMode(true); setSpaceIndentation(4); setClassIndent(false); setNamespaceIndent(false); return true; } return false; } QVariant AStyleFormatter::option(const QString &key) { if(!m_options.contains(key)) qCDebug(KDEV_ASTYLE) << "Missing option name " << key << endl; return m_options[key]; } QString AStyleFormatter::indentString() { return QString::fromUtf8(getIndentString().c_str()); } void AStyleFormatter::loadStyle(const QString &content) { m_options = ISourceFormatter::stringToOptionMap(content); updateFormatter(); } QString AStyleFormatter::saveStyle() { return ISourceFormatter::optionMapToString(m_options); } void AStyleFormatter::setTabIndentation(int length, bool forceTabs) { ASFormatter::setTabIndentation(length, forceTabs); m_options[QStringLiteral("Fill")] = QStringLiteral("Tabs"); m_options[QStringLiteral("FillForce")] = forceTabs; m_options[QStringLiteral("FillCount")] = length; } void AStyleFormatter::setSpaceIndentation(int length) { ASFormatter::setSpaceIndentation(length); m_options[QStringLiteral("Fill")] = QStringLiteral("Spaces"); m_options[QStringLiteral("FillCount")] = length; } void AStyleFormatter::setTabSpaceConversionMode(bool mode) { m_options[QStringLiteral("FillForce")] = mode; ASFormatter::setTabSpaceConversionMode(mode); } void AStyleFormatter::setFillEmptyLines(bool on) { m_options[QStringLiteral("FillEmptyLines")] = on; ASFormatter::setEmptyLineFill(on); } void AStyleFormatter::setBlockIndent(bool on) { m_options[QStringLiteral("IndentBlocks")] = on; ASFormatter::setBlockIndent(on); } void AStyleFormatter::setBracketIndent(bool on) { m_options[QStringLiteral("IndentBrackets")] = on; - ASFormatter::setBracketIndent(on); + ASFormatter::setBraceIndent(on); } void AStyleFormatter::setCaseIndent(bool on) { m_options[QStringLiteral("IndentCases")] = on; ASFormatter::setCaseIndent(on); } void AStyleFormatter::setClassIndent(bool on) { m_options[QStringLiteral("IndentClasses")] = on; ASFormatter::setClassIndent(on); } void AStyleFormatter::setLabelIndent(bool on) { m_options[QStringLiteral("IndentLabels")] = on; ASFormatter::setLabelIndent(on); } void AStyleFormatter::setNamespaceIndent(bool on) { m_options[QStringLiteral("IndentNamespaces")] = on; ASFormatter::setNamespaceIndent(on); } void AStyleFormatter::setPreprocessorIndent(bool on) { m_options[QStringLiteral("IndentPreprocessors")] = on; ASFormatter::setPreprocDefineIndent(on); } void AStyleFormatter::setSwitchIndent(bool on) { m_options[QStringLiteral("IndentSwitches")] = on; ASFormatter::setSwitchIndent(on); } void AStyleFormatter::setMaxInStatementIndentLength(int max) { m_options[QStringLiteral("MaxStatement")] = max; ASFormatter::setMaxInStatementIndentLength(max); } void AStyleFormatter::setMinConditionalIndentLength(int min) { m_options[QStringLiteral("MinConditional")] = min; ASFormatter::setMinConditionalIndentOption(min); ASFormatter::setMinConditionalIndentLength(); } -void AStyleFormatter::setBracketFormatMode(astyle::BracketMode mode) +void AStyleFormatter::setBracketFormatMode(astyle::BraceMode mode) { switch (mode) { case astyle::NONE_MODE: m_options[QStringLiteral("Brackets")] = QString(); break; case astyle::ATTACH_MODE: m_options[QStringLiteral("Brackets")] = QStringLiteral("Attach"); break; case astyle::BREAK_MODE: m_options[QStringLiteral("Brackets")] = QStringLiteral("Break"); break; case astyle::LINUX_MODE: m_options[QStringLiteral("Brackets")] = QStringLiteral("Linux"); break; case astyle::RUN_IN_MODE: m_options[QStringLiteral("Brackets")] = QStringLiteral("RunInMode"); break; } - ASFormatter::setBracketFormatMode(mode); + ASFormatter::setBraceFormatMode(mode); } void AStyleFormatter::setBreakClosingHeaderBracketsMode(bool state) { m_options[QStringLiteral("BracketsCloseHeaders")] = state; ASFormatter::setBreakClosingHeaderBracketsMode(state); } void AStyleFormatter::setBreakBlocksMode(bool state) { m_options[QStringLiteral("BlockBreak")] = state; ASFormatter::setBreakBlocksMode(state); } void AStyleFormatter::setBreakElseIfsMode(bool state) { m_options[QStringLiteral("BlockIfElse")] = state; ASFormatter::setBreakElseIfsMode(state); } void AStyleFormatter::setBreakClosingHeaderBlocksMode(bool state) { m_options[QStringLiteral("BlockBreakAll")] = state; ASFormatter::setBreakClosingHeaderBlocksMode(state); } void AStyleFormatter::setOperatorPaddingMode(bool mode) { m_options[QStringLiteral("PadOperators")] = mode; ASFormatter::setOperatorPaddingMode(mode); } void AStyleFormatter::setParensOutsidePaddingMode(bool mode) { m_options[QStringLiteral("PadParenthesesOut")] = mode; ASFormatter::setParensOutsidePaddingMode(mode); } void AStyleFormatter::setParensInsidePaddingMode(bool mode) { m_options[QStringLiteral("PadParenthesesIn")] = mode; ASFormatter::setParensInsidePaddingMode(mode); } void AStyleFormatter::setParensHeaderPaddingMode(bool mode) { m_options[QStringLiteral("PadParenthesesHeader")] = mode; ASFormatter::setParensHeaderPaddingMode(mode); } void AStyleFormatter::setParensUnPaddingMode(bool state) { m_options[QStringLiteral("PadParenthesesUn")] = state; ASFormatter::setParensUnPaddingMode(state); } void AStyleFormatter::setBreakOneLineBlocksMode(bool state) { m_options[QStringLiteral("KeepBlocks")] = !state; ASFormatter::setBreakOneLineBlocksMode(state); } void AStyleFormatter::setBreakOneLineStatementsMode(bool state) { m_options[QStringLiteral("KeepStatements")] = !state; ASFormatter::setBreakOneLineStatementsMode(state); } void AStyleFormatter::setPointerAlignment(astyle::PointerAlign alignment) { switch (alignment) { case astyle::PTR_ALIGN_NONE: m_options[QStringLiteral("PointerAlign")] = QStringLiteral("None"); break; case astyle::PTR_ALIGN_NAME: m_options[QStringLiteral("PointerAlign")] = QStringLiteral("Name"); break; case astyle::PTR_ALIGN_MIDDLE: m_options[QStringLiteral("PointerAlign")] = QStringLiteral("Middle"); break; case astyle::PTR_ALIGN_TYPE: m_options[QStringLiteral("PointerAlign")] = QStringLiteral("Type"); break; } ASFormatter::setPointerAlignment(alignment); } diff --git a/plugins/astyle/astyle_formatter.h b/plugins/astyle/astyle_formatter.h index c9603a9011..e125d3f85f 100644 --- a/plugins/astyle/astyle_formatter.h +++ b/plugins/astyle/astyle_formatter.h @@ -1,90 +1,90 @@ /* This file is part of KDevelop * Copyright (C) 2008 Cédric Pasteur Copyright (C) 2001 Matthias Hölzer-Klüpfel This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ASTYLEFORMATTER_H #define ASTYLEFORMATTER_H #include #include #include "astyle.h" class AStyleFormatter : public astyle::ASFormatter { public: /** Creates an empty AStyleFormatter with C style by default. */ AStyleFormatter(); QString formatSource(const QString& text, const QString& leftContext = QString(), const QString& rightContext = QString()); QVariant option(const QString &name); void setOption(const QString &key, const QVariant &value); QString indentString(); bool predefinedStyle(const QString &name); void loadStyle(const QString &content); QString saveStyle(); // indent void setTabIndentation(int length, bool forceTabs); void setSpaceIndentation(int length); void setTabSpaceConversionMode(bool mode); void setFillEmptyLines(bool on); void setBlockIndent(bool on); void setBracketIndent(bool on); void setCaseIndent(bool on); void setClassIndent(bool on); void setLabelIndent(bool on); void setNamespaceIndent(bool on); void setPreprocessorIndent(bool on); void setSwitchIndent(bool on); void setMaxInStatementIndentLength(int max); void setMinConditionalIndentLength(int min); //brackets - void setBracketFormatMode(astyle::BracketMode mode); + void setBracketFormatMode(astyle::BraceMode mode); void setBreakClosingHeaderBracketsMode(bool state); //blocks void setBreakBlocksMode(bool state); void setBreakElseIfsMode(bool state); void setBreakClosingHeaderBlocksMode(bool state); //padding void setOperatorPaddingMode(bool mode); void setParensOutsidePaddingMode(bool mode); void setParensInsidePaddingMode(bool mode); void setParensHeaderPaddingMode(bool mode); void setParensUnPaddingMode(bool state); //oneliners void setBreakOneLineBlocksMode(bool state); void setBreakOneLineStatementsMode(bool state); //pointer void setPointerAlignment(astyle::PointerAlign alignment); protected: void updateFormatter(); void resetStyle(); private: QString m_indentString; QVariantMap m_options; }; #endif // ASTYLEFORMATTER_H diff --git a/plugins/astyle/astyle_stringiterator.cpp b/plugins/astyle/astyle_stringiterator.cpp index 2884fcf5eb..27326cf7db 100644 --- a/plugins/astyle/astyle_stringiterator.cpp +++ b/plugins/astyle/astyle_stringiterator.cpp @@ -1,74 +1,80 @@ /* This file is part of KDevelop * Copyright (C) 2008 Cédric Pasteur Copyright (C) 2001 Matthias Hölzer-Klüpfel This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "astyle_stringiterator.h" #include AStyleStringIterator::AStyleStringIterator(const QString &text) : ASSourceIterator() , m_content(text) , m_is(&m_content, QIODevice::ReadOnly) , m_peekStart(-1) { } AStyleStringIterator::~AStyleStringIterator() { } astyle::streamoff AStyleStringIterator::tellg() { return m_is.pos(); } int AStyleStringIterator::getStreamLength() const { return m_content.size(); } bool AStyleStringIterator::hasMoreLines() const { return !m_is.atEnd(); } std::string AStyleStringIterator::nextLine(bool emptyLineWasDeleted) { Q_UNUSED(emptyLineWasDeleted) return m_is.readLine().toUtf8().data(); } std::string AStyleStringIterator::peekNextLine() { if (m_peekStart == -1) { m_peekStart = m_is.pos(); } return m_is.readLine().toUtf8().data(); } void AStyleStringIterator::peekReset() { if(m_peekStart != -1) m_is.seek(m_peekStart); m_peekStart = -1; // invalid } +astyle::streamoff AStyleStringIterator::getPeekStart() const +{ + return m_peekStart; +} + + diff --git a/plugins/astyle/astyle_stringiterator.h b/plugins/astyle/astyle_stringiterator.h index 4c52d9cf17..4424c0766e 100644 --- a/plugins/astyle/astyle_stringiterator.h +++ b/plugins/astyle/astyle_stringiterator.h @@ -1,51 +1,51 @@ /* This file is part of KDevelop * Copyright (C) 2008 Cédric Pasteur Copyright (C) 2001 Matthias Hölzer-Klüpfel This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ASTYLESTRINGITERATOR_H #define ASTYLESTRINGITERATOR_H #include #include #include "astyle.h" #include class AStyleStringIterator : public astyle::ASSourceIterator { public: explicit AStyleStringIterator(const QString &string); ~AStyleStringIterator() override; astyle::streamoff tellg() override; int getStreamLength() const override; bool hasMoreLines() const override; std::string nextLine(bool emptyLineWasDeleted = false) override; std::string peekNextLine() override; void peekReset() override; - + astyle::streamoff getPeekStart() const override; private: QString m_content; QTextStream m_is; qint64 m_peekStart; }; #endif // ASTYLESTRINGITERATOR_H diff --git a/plugins/astyle/kdevastyle.json b/plugins/astyle/kdevastyle.json index fe5a882287..1fbf83fff4 100644 --- a/plugins/astyle/kdevastyle.json +++ b/plugins/astyle/kdevastyle.json @@ -1,64 +1,64 @@ { "KPlugin": { "Authors": [ { "Name": "Cedric Pasteur, Matthias Hölzer-Klüpfel", "Name[x-test]": "xxCedric Pasteur, Matthias Hölzer-Klüpfelxx" } ], "Category": "Utilities", - "Description": "A plugin for formatting of sourcecode according to a specified set of rules", + "Description": "A plugin for formatting of sourcecode according to a specified set of rules.\nBased on the Artistic Style formatter v3.1 (https://sourceforge.net/projects/astyle)", "Description[ca@valencia]": "Un connector per a formatar el codi font d'acord a un conjunt especificat de regles", "Description[ca]": "Un connector per a formatar el codi font d'acord a un conjunt especificat de regles", "Description[de]": "Modul zum Formatieren von Quelltext nach bestimmten Vorschriften", "Description[es]": "Un complemento para formatear código fuente según el conjunto de reglas indicado", "Description[et]": "Plugin lähtekoodi vormindamiseks vastavalt konkreetsetele reeglitele.", "Description[fi]": "Liitännäinen lähdekoodin muotoilemiseen määritellyn sääntöjoukon mukaan", "Description[fr]": "Un module pour mettre en forme le code source d'après un ensemble de règles spécifié", "Description[gl]": "Complemento para formatar código fonte segundo un conxunto de regras indicado.", "Description[it]": "Un'estensione per la formattazione del codice sorgente secondo uno specifico insieme di regole", "Description[nl]": "Een plugin om broncode te formatteren volgens een speciale set regels", "Description[pl]": "Wtyczka do formatowania kodu źródłowego zgodnie z podanymi regułami", "Description[pt]": "Um 'plugin' para formatar código-fonte de acordo com um dado conjunto de regras", "Description[pt_BR]": "Um plugin para formatar código-fonte de acordo com um conjunto de regras", "Description[sk]": "Modul pre formátovanie zdrojového kódu podľa špecifických pravidiel", "Description[sl]": "Vstavek za oblikovanje izvorne kode po določenih pravilih", "Description[sv]": "Ett insticksprogram för formatering av källkod enligt en angiven uppsättning regler", "Description[tr]": "Belli kurallara göre kaynak kodları biçimlendirmeye yarayan bir eklenti", "Description[uk]": "Додаток для форматування коду у відповідності до вказаного набору правил", "Description[x-test]": "xxA plugin for formatting of sourcecode according to a specified set of rulesxx", "Description[zh_CN]": "一个根据指定规则设定格式化源代码的插件", "Icon": "text-field", "Id": "kdevastyle", "License": "LGPL", "Name": "AStyle Formatter Backend", "Name[ca@valencia]": "Dorsal del formatador AStyle", "Name[ca]": "Dorsal del formatador AStyle", "Name[de]": "AStyle-Formatierer", "Name[es]": "Motor de formateo AStyle", "Name[et]": "AStyle'i vormindamise taustaprogramm", "Name[fi]": "AStyle-muotoilijataustaohjelma", "Name[fr]": "Moteur de mise en forme AStyle", "Name[gl]": "Infraestrutura de formatación de AStyle", "Name[it]": "Backend formattatore AStyle", "Name[nl]": "Backend voor AStyle formatteerprogramma", "Name[pl]": "Silnik formatowania AStyle", "Name[pt]": "Infra-Estrutura de Formatação do AStyle", "Name[pt_BR]": "Formatador AStyle", "Name[sk]": "Backend formátovača AStyle", "Name[sl]": "Zaledje oblikovalnika AStyle", "Name[sv]": "Astyle-formateringsgränssnitt", "Name[tr]": "Astyle Biçimlendirici Arka Ucu", "Name[uk]": "Сервер форматування AStyle", "Name[x-test]": "xxAStyle Formatter Backendxx", "Name[zh_CN]": "AStyle 格式化器后端", "ServiceTypes": [ "KDevelop/Plugin" ] }, "X-KDevelop-Category": "Global", "X-KDevelop-Interfaces": [ "org.kdevelop.ISourceFormatter" ], "X-KDevelop-Mode": "NoGUI" }