diff --git a/kdev-pg/ASBeautifier.cpp b/kdev-pg/ASBeautifier.cpp --- a/kdev-pg/ASBeautifier.cpp +++ b/kdev-pg/ASBeautifier.cpp @@ -1,27 +1,25 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * ASBeautifier.cpp + * Copyright (C) 2006-2010 by Jim Pattee + * Copyright (C) 1998-2002 by Tal Davidson + * * - * This file is a part of "Artistic Style" - an indentation and + * This file is a part of Artistic Style - an indentation and * reformatting tool for C, C++, C# and Java source files. - * http://astyle.sourceforge.net + * * - * The "Artistic Style" project, including all files needed to - * compile it, is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later - * version. + * Artistic Style is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * Artistic Style 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 Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public - * License along with this project; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with Artistic Style. If not, see . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -32,45 +30,17 @@ #include -#define INIT_CONTAINER(container, value) {if ( (container) != NULL ) delete (container); (container) = (value); } -#define DELETE_CONTAINER(container) {if ( (container) != NULL ) delete (container); } - - namespace astyle { -vector ASBeautifier::headers; -vector ASBeautifier::nonParenHeaders; -vector ASBeautifier::preBlockStatements; -vector ASBeautifier::assignmentOperators; -vector ASBeautifier::nonAssignmentOperators; - - -/* - * initialize the static vars - */ -void ASBeautifier::initStatic() -{ - static int beautifierFileType = 9; // initialized with an invalid type - - if (fileType == beautifierFileType) // don't build unless necessary - return; - - beautifierFileType = fileType; - - headers.clear(); - nonParenHeaders.clear(); - assignmentOperators.clear(); - nonAssignmentOperators.clear(); - preBlockStatements.clear(); - - ASResource::buildHeaders(headers, fileType, true); - ASResource::buildNonParenHeaders(nonParenHeaders, fileType, true); - ASResource::buildAssignmentOperators(assignmentOperators); - ASResource::buildNonAssignmentOperators(nonAssignmentOperators); - ASResource::buildPreBlockStatements(preBlockStatements); +// static member variables +int ASBeautifier::beautifierFileType = 9; // initialized with an invalid type +vector* ASBeautifier::headers = NULL; +vector* ASBeautifier::nonParenHeaders = NULL; +vector* ASBeautifier::preBlockStatements; +vector* ASBeautifier::assignmentOperators = NULL; +vector* ASBeautifier::nonAssignmentOperators; +vector* ASBeautifier::indentableHeaders; -// cout << "beaut" << endl; -} /** * ASBeautifier's constructor @@ -92,48 +62,63 @@ inStatementIndentStackSizeStack = NULL; parenIndentStack = NULL; sourceIterator = NULL; - - isMinimalConditinalIndentSet = false; + isIndentManuallySet = false; + isMinConditionalManuallySet = false; + isModeManuallySet = false; shouldForceTabIndentation = false; - - setSpaceIndentation(4); + setSpaceIndentation(4); // also sets minConditionalIndent setMaxInStatementIndentLength(40); + classInitializerTabs = 1; setClassIndent(false); setSwitchIndent(false); setCaseIndent(false); setBlockIndent(false); setBracketIndent(false); setNamespaceIndent(false); setLabelIndent(false); setEmptyLineFill(false); - fileType = C_TYPE; setCStyle(); setPreprocessorIndent(false); + + // initialize ASBeautifier static member vectors + beautifierFileType = 9; // reset to an invalid type + initVector(headers); + initVector(nonParenHeaders); + initVector(assignmentOperators); + initVector(nonAssignmentOperators); + initVector(preBlockStatements); + initVector(indentableHeaders); } /** * ASBeautifier's copy constructor + * must explicitly call the base class copy constructor */ -ASBeautifier::ASBeautifier(const ASBeautifier &other) +ASBeautifier::ASBeautifier(const ASBeautifier &other) : ASBase(other) { + // these don't need to copy the stack waitingBeautifierStack = NULL; activeBeautifierStack = NULL; waitingBeautifierStackLengthStack = NULL; activeBeautifierStackLengthStack = NULL; + // vector '=' operator performs a DEEP copy of all elements in the vector + headerStack = new vector; *headerStack = *other.headerStack; - tempStacks = new vector*>; - vector*>::iterator iter; - for (iter = other.tempStacks->begin(); - iter != other.tempStacks->end(); - ++iter) - { - vector *newVec = new vector; - *newVec = **iter; - tempStacks->push_back(newVec); - } + //tempStacks = new vector*>; + //vector*>::iterator iter; + //for (iter = other.tempStacks->begin(); + // iter != other.tempStacks->end(); + // ++iter) + //{ + // vector *newVec = new vector; + // *newVec = **iter; + // tempStacks->push_back(newVec); + //} + tempStacks = copyTempStacks(other); + blockParenDepthStack = new vector; *blockParenDepthStack = *other.blockParenDepthStack; @@ -158,58 +143,68 @@ sourceIterator = other.sourceIterator; // protected variables - fileType = other.fileType; - isCStyle = other.isCStyle; - isJavaStyle = other.isJavaStyle; - isSharpStyle = other.isSharpStyle; - // variables set by ASFormatter - // must also be updated in preprocessor + // must also be updated in activeBeautifierStack inLineNumber = other.inLineNumber; - outLineNumber = other.outLineNumber; + horstmannIndentInStatement = other.horstmannIndentInStatement; + nonInStatementBracket = other.nonInStatementBracket; lineCommentNoBeautify = other.lineCommentNoBeautify; isNonInStatementArray = other.isNonInStatementArray; + isSharpAccessor = other.isSharpAccessor; + isSharpDelegate = other.isSharpDelegate; + isInExtern = other.isInExtern; + isInBeautifySQL = other.isInBeautifySQL; + isInIndentableStruct = other.isInIndentableStruct; // private variables indentString = other.indentString; currentHeader = other.currentHeader; previousLastLineHeader = other.previousLastLineHeader; - immediatelyPreviousAssignmentOp = other.immediatelyPreviousAssignmentOp; probationHeader = other.probationHeader; isInQuote = other.isInQuote; + isInVerbatimQuote = other.isInVerbatimQuote; + haveLineContinuationChar = other.haveLineContinuationChar; + isInAsm = other.isInAsm; + isInAsmOneLine = other.isInAsmOneLine; + isInAsmBlock = other.isInAsmBlock; isInComment = other.isInComment; + isInHorstmannComment = other.isInHorstmannComment; isInCase = other.isInCase; isInQuestion = other.isInQuestion; isInStatement = other.isInStatement; isInHeader = other.isInHeader; - isInOperator = other.isInOperator; isInTemplate = other.isInTemplate; isInDefine = other.isInDefine; isInDefineDefinition = other.isInDefineDefinition; classIndent = other.classIndent; - isInClassHeader = other.isInClassHeader; + isInClassInitializer = other.isInClassInitializer; isInClassHeaderTab = other.isInClassHeaderTab; + isInEnum = other.isInEnum; switchIndent = other.switchIndent; caseIndent = other.caseIndent; namespaceIndent = other.namespaceIndent; bracketIndent = other.bracketIndent; blockIndent = other.blockIndent; labelIndent = other.labelIndent; preprocessorIndent = other.preprocessorIndent; isInConditional = other.isInConditional; - isMinimalConditinalIndentSet = other.isMinimalConditinalIndentSet; + isIndentManuallySet = other.isIndentManuallySet; + isMinConditionalManuallySet = other.isMinConditionalManuallySet; + isModeManuallySet = other.isModeManuallySet; shouldForceTabIndentation = other.shouldForceTabIndentation; emptyLineFill = other.emptyLineFill; + lineOpensComment = other.lineOpensComment; backslashEndsPrevLine = other.backslashEndsPrevLine; blockCommentNoIndent = other.blockCommentNoIndent; blockCommentNoBeautify = other.blockCommentNoBeautify; previousLineProbationTab = other.previousLineProbationTab; + fileType = other.fileType; minConditionalIndent = other.minConditionalIndent; parenDepth = other.parenDepth; indentLength = other.indentLength; blockTabCount = other.blockTabCount; - leadingWhiteSpaces = other.leadingWhiteSpaces; maxInStatementIndent = other.maxInStatementIndent; + classInitializerTabs = other.classInitializerTabs; templateDepth = other.templateDepth; prevFinalLineSpaceTabCount = other.prevFinalLineSpaceTabCount; prevFinalLineTabCount = other.prevFinalLineTabCount; @@ -226,28 +221,30 @@ */ ASBeautifier::~ASBeautifier() { - DELETE_CONTAINER(headerStack); - DELETE_CONTAINER(tempStacks); - DELETE_CONTAINER(blockParenDepthStack); - DELETE_CONTAINER(blockStatementStack); - DELETE_CONTAINER(parenStatementStack); - DELETE_CONTAINER(bracketBlockStateStack); - DELETE_CONTAINER(inStatementIndentStack); - DELETE_CONTAINER(inStatementIndentStackSizeStack); - DELETE_CONTAINER(parenIndentStack); + deleteContainer(waitingBeautifierStack); + deleteContainer(activeBeautifierStack); + deleteContainer(waitingBeautifierStackLengthStack); + deleteContainer(activeBeautifierStackLengthStack); + deleteContainer(headerStack); + deleteContainer(tempStacks); + deleteContainer(blockParenDepthStack); + deleteContainer(blockStatementStack); + deleteContainer(parenStatementStack); + deleteContainer(bracketBlockStateStack); + deleteContainer(inStatementIndentStack); + deleteContainer(inStatementIndentStackSizeStack); + deleteContainer(parenIndentStack); } /** * initialize the ASBeautifier. * * init() should be called every time a ABeautifier object is to start * beautifying a NEW source file. - * init() receives a pointer to a DYNAMICALLY CREATED ASSourceIterator object - * that will be used to iterate through the source code. This object will be - * deleted during the ASBeautifier's destruction, and thus should not be - * deleted elsewhere. + * init() recieves a pointer to a ASSourceIterator object that will be + * used to iterate through the source code. * - * @param iter a pointer to the DYNAMICALLY CREATED ASSourceIterator object. + * @param iter a pointer to the ASSourceIterator or ASStreamIterator object. */ void ASBeautifier::init(ASSourceIterator *iter) { @@ -261,48 +258,55 @@ void ASBeautifier::init() { initStatic(); + ASBase::init(getFileType()); - INIT_CONTAINER(waitingBeautifierStack, new vector); - INIT_CONTAINER(activeBeautifierStack, new vector); + initContainer(waitingBeautifierStack, new vector); + initContainer(activeBeautifierStack, new vector); - INIT_CONTAINER(waitingBeautifierStackLengthStack, new vector); - INIT_CONTAINER(activeBeautifierStackLengthStack, new vector); + initContainer(waitingBeautifierStackLengthStack, new vector); + initContainer(activeBeautifierStackLengthStack, new vector); - INIT_CONTAINER(headerStack, new vector); - INIT_CONTAINER(tempStacks, new vector*>); + initContainer(headerStack, new vector); + + initContainer(tempStacks, new vector*>); tempStacks->push_back(new vector); - INIT_CONTAINER(blockParenDepthStack, new vector); - INIT_CONTAINER(blockStatementStack, new vector); - INIT_CONTAINER(parenStatementStack, new vector); + initContainer(blockParenDepthStack, new vector); + initContainer(blockStatementStack, new vector); + initContainer(parenStatementStack, new vector); - INIT_CONTAINER(bracketBlockStateStack, new vector); + initContainer(bracketBlockStateStack, new vector); bracketBlockStateStack->push_back(true); - INIT_CONTAINER(inStatementIndentStack, new vector); - INIT_CONTAINER(inStatementIndentStackSizeStack, new vector); + initContainer(inStatementIndentStack, new vector); + initContainer(inStatementIndentStackSizeStack, new vector); inStatementIndentStackSizeStack->push_back(0); - INIT_CONTAINER(parenIndentStack, new vector); + initContainer(parenIndentStack, new vector); - immediatelyPreviousAssignmentOp = NULL; previousLastLineHeader = NULL; currentHeader = NULL; isInQuote = false; + isInVerbatimQuote = false; + haveLineContinuationChar = false; + isInAsm = false; + isInAsmOneLine = false; + isInAsmBlock = false; isInComment = false; + isInHorstmannComment = false; isInStatement = false; isInCase = false; isInQuestion = false; - isInClassHeader = false; + isInClassInitializer = false; isInClassHeaderTab = false; + isInEnum = false; isInHeader = false; - isInOperator = false; isInTemplate = false; isInConditional = false; + templateDepth = 0; parenDepth = 0; blockTabCount = 0; - leadingWhiteSpaces = 0; prevNonSpaceCh = '{'; currentNonSpaceCh = '{'; prevNonLegalCh = '{'; @@ -312,49 +316,80 @@ prevFinalLineTabCount = 0; probationHeader = NULL; backslashEndsPrevLine = false; + lineOpensComment = false; isInDefine = false; isInDefineDefinition = false; defineTabCount = 0; lineCommentNoBeautify = false; blockCommentNoIndent = false; blockCommentNoBeautify = false; previousLineProbationTab = false; isNonInStatementArray = false; - inLineNumber = -1; // for debugging - outLineNumber = 0; // for debugging + isSharpAccessor = false; + isSharpDelegate = false; + isInExtern = false; + isInBeautifySQL = false; + isInIndentableStruct = false; + inLineNumber = 0; + horstmannIndentInStatement = 0; + nonInStatementBracket = 0; +} + +/* + * initialize the static vars + */ +void ASBeautifier::initStatic() +{ + if (fileType == beautifierFileType) // don't build unless necessary + return; + + beautifierFileType = fileType; + + headers->clear(); + nonParenHeaders->clear(); + assignmentOperators->clear(); + nonAssignmentOperators->clear(); + preBlockStatements->clear(); + indentableHeaders->clear(); + + ASResource::buildHeaders(headers, fileType, true); + ASResource::buildNonParenHeaders(nonParenHeaders, fileType, true); + ASResource::buildAssignmentOperators(assignmentOperators); + ASResource::buildNonAssignmentOperators(nonAssignmentOperators); + ASResource::buildPreBlockStatements(preBlockStatements, fileType); + ASResource::buildIndentableHeaders(indentableHeaders); } /** * set indentation style to C/C++. */ void ASBeautifier::setCStyle() { fileType = C_TYPE; - isCStyle = true; - isJavaStyle = false; - isSharpStyle = false; } /** * set indentation style to Java. */ void ASBeautifier::setJavaStyle() { fileType = JAVA_TYPE; - isJavaStyle = true; - isCStyle = false; - isSharpStyle = false; } /** * set indentation style to C#. */ void ASBeautifier::setSharpStyle() { fileType = SHARP_TYPE; - isSharpStyle = true; - isCStyle = false; - isJavaStyle = false; +} + +/** + * set mode manually set flag + */ +void ASBeautifier::setModeManuallySet(bool state) +{ + isModeManuallySet = state; } /** @@ -366,7 +401,7 @@ indentLength = length; shouldForceTabIndentation = forceTabs; - if (!isMinimalConditinalIndentSet) + if (!isMinConditionalManuallySet) minConditionalIndent = indentLength * 2; } @@ -380,11 +415,19 @@ indentString = string(length, ' '); indentLength = length; - if (!isMinimalConditinalIndentSet) + if (!isMinConditionalManuallySet) minConditionalIndent = indentLength * 2; } /** + * set indent manually set flag + */ +void ASBeautifier::setIndentManuallySet(bool state) +{ + isIndentManuallySet = state; +} + +/** * set the maximum indentation between two lines in a multi-line statement. * * @param max maximum indentation length. @@ -402,7 +445,14 @@ void ASBeautifier::setMinConditionalIndentLength(int min) { minConditionalIndent = min; - isMinimalConditinalIndentSet = true; +} + +/** + * set min conditional manually set flag + */ +void ASBeautifier::setMinConditionalManuallySet(bool state) +{ + isMinConditionalManuallySet = state; } /** @@ -424,8 +474,6 @@ */ void ASBeautifier::setBlockIndent(bool state) { - if (state) - setBracketIndent(false); // so that we don't have both bracket and block indent blockIndent = state; } @@ -513,67 +561,120 @@ } /** + * get the file type. + */ +int ASBeautifier::getFileType() +{ + return fileType; +} + +/** * get the number of spaces per indent * * @return value of indentLength option. -*/ + */ int ASBeautifier::getIndentLength(void) { return indentLength; } /** * get the char used for indentation, space or tab - * + * * @return the char used for indentation. */ string ASBeautifier::getIndentString(void) { return indentString; } /** - * get the state of the case indentation option. If true, lines of 'case' - * statements will be indented one additional indent. + * get indent manually set flag + */ +bool ASBeautifier::getIndentManuallySet() +{ + return isIndentManuallySet; +} + +/** + * get the state of the isMinConditionalManuallySet flag * - * @return state of caseIndent option. + * @return the state of isMinConditionalManuallySet. */ -bool ASBeautifier::getCaseIndent(void) +bool ASBeautifier::getMinConditionalManuallySet() { - return caseIndent; + return isMinConditionalManuallySet; +} + +/** + * get mode manually set flag + */ +bool ASBeautifier::getModeManuallySet() +{ + return isModeManuallySet; +} + +/** + * get the state of the force tab indentation option. + * + * @return state of force tab indentation. + */ +bool ASBeautifier::getForceTabIndentation(void) +{ + return shouldForceTabIndentation; +} + +/** + * get the state of the block indentation option. + * + * @return state of blockIndent option. + */ +bool ASBeautifier::getBlockIndent(void) +{ + return blockIndent; +} + +/** + * get the state of the bracket indentation option. + * + * @return state of bracketIndent option. + */ +bool ASBeautifier::getBracketIndent(void) +{ + return bracketIndent; } /** - * get C style identifier. - * If true, a C source is being indented. + * get the state of the class indentation option. If true, blocks of + * the 'class' statement will be indented one additional indent. * - * @return state of isCStyle option. + * @return state of classIndent option. */ -bool ASBeautifier::getCStyle(void) +bool ASBeautifier::getClassIndent(void) { - return isCStyle; + return classIndent; } /** - * get Java style identifier. - * If true, a Java source is being indented. + * get the state of the switch indentation option. If true, blocks of + * the 'switch' statement will be indented one additional indent. * - * @return state of isJavaStyle option. + * @return state of switchIndent option. */ -bool ASBeautifier::getJavaStyle(void) +bool ASBeautifier::getSwitchIndent(void) { - return isJavaStyle; + return switchIndent; } /** - * get C# style identifier. - * If true, a C# source is being indented. + * get the state of the case indentation option. If true, lines of 'case' + * statements will be indented one additional indent. * - * @return state of isSharpStyle option. + * @return state of caseIndent option. */ -bool ASBeautifier::getSharpStyle(void) +bool ASBeautifier::getCaseIndent(void) { - return isSharpStyle; + return caseIndent; } /** @@ -624,100 +725,92 @@ bool lineStartsInComment = false; bool isInClass = false; bool isInSwitch = false; - bool isImmediatelyAfterConst = false; + bool isInOperator = false; bool isSpecialChar = false; + bool haveCaseIndent = false; + bool haveAssignmentThisLine = false; + bool lineBeginsWithBracket = false; + bool closingBracketReached = false; + bool shouldIndentBrackettedLine = true; + bool previousLineProbation = (probationHeader != NULL); + bool isInQuoteContinuation = isInVerbatimQuote | haveLineContinuationChar; char ch = ' '; char prevCh; - string outBuffer; // the newly idented line is bufferd here + char tempCh; int tabCount = 0; - const string *lastLineHeader = NULL; - bool closingBracketReached = false; int spaceTabCount = 0; - char tempCh; - size_t headerStackSize = headerStack->size(); - bool shouldIndentBrackettedLine = true; int lineOpeningBlocksNum = 0; int lineClosingBlocksNum = 0; - bool previousLineProbation = (probationHeader != NULL); + int tabIncrementIn = 0; int i; + int iPrelim; + string outBuffer; // the newly idented line is buffered here + const string *lastLineHeader = NULL; currentHeader = NULL; lineStartsInComment = isInComment; blockCommentNoBeautify = blockCommentNoIndent; + isInAsmOneLine = false; + lineOpensComment = false; previousLineProbationTab = false; - ++outLineNumber; + haveLineContinuationChar = false; // 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 (!isInComment) + if (isInQuoteContinuation) { - int strlen = originalLine.length(); - leadingWhiteSpaces = 0; - - for (int j = 0; j < strlen && isWhiteSpace(originalLine[j]); ++j) - { - if (originalLine[j] == '\t') - leadingWhiteSpaces += indentLength; - else - ++leadingWhiteSpaces; - } - line = trim(originalLine); + // 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); } else { - // convert leading tabs to spaces - string spaceTabs(indentLength, ' '); - string newLine = originalLine; - int strlen = newLine.length(); - - for (int j=0; j < leadingWhiteSpaces && j < strlen; ++j) - { - if (newLine[j] == '\t') - { - newLine.replace(j, 1, spaceTabs); - strlen = newLine.length(); - } - } - - // trim the comment leaving the new leading whitespace - int trimSize = 0; - strlen = newLine.length(); - - while (trimSize < strlen - && trimSize < leadingWhiteSpaces - && isWhiteSpace(newLine[trimSize])) - ++trimSize; - - - while (trimSize < strlen && isWhiteSpace(newLine[strlen-1])) - --strlen; + line = trim(originalLine); + if (line.length() > 0 && line[0] == '{') + lineBeginsWithBracket = true; - line = newLine.substr(trimSize, strlen); - size_t trimEnd = line.find_last_not_of(" \t"); - if (trimEnd != string::npos) + isInHorstmannComment = false; + size_t j = line.find_first_not_of(" \t{"); + if (j != string::npos && line.compare(j, 2, "/*") == 0) { - int spacesToDelete = line.length() - 1 - trimEnd; - if (spacesToDelete > 0) - line.erase(trimEnd + 1, spacesToDelete); + lineOpensComment = true; + size_t k = line.find_first_not_of(" \t"); + if (k != string::npos && line.compare(k, 1, "{") == 0) + isInHorstmannComment = true; } } - if (line.length() == 0) { - if (backslashEndsPrevLine) // must continue to clear variables + if (backslashEndsPrevLine) // must continue to clear variables line = ' '; - else if (emptyLineFill) + else if (emptyLineFill && !isInQuoteContinuation && headerStack->size() > 0) return preLineWS(prevFinalLineSpaceTabCount, prevFinalLineTabCount); else return line; } // handle preprocessor commands + // except C# region and endregion - if (isCStyle && !isInComment && (line[0] == '#' || backslashEndsPrevLine)) + if (!isInComment + && (line[0] == '#' || backslashEndsPrevLine) + && line.compare(0, 7, "#region") != 0 + && line.compare(0, 10, "#endregion") != 0) { if (line[0] == '#') { @@ -730,7 +823,7 @@ // 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 (preprocessorIndent && preproc.compare(0, 6, "define") == 0 && line[line.length() - 1] == '\\') + if (preprocessorIndent && preproc.compare(0, 6, "define") == 0 && line[line.length() - 1] == '\\') { if (!isInDefineDefinition) { @@ -839,31 +932,51 @@ if (!isInDefine && activeBeautifierStack != NULL && !activeBeautifierStack->empty()) { activeBeautifierStack->back()->inLineNumber = inLineNumber; - activeBeautifierStack->back()->outLineNumber = outLineNumber; + activeBeautifierStack->back()->horstmannIndentInStatement = horstmannIndentInStatement; + activeBeautifierStack->back()->nonInStatementBracket = nonInStatementBracket; activeBeautifierStack->back()->lineCommentNoBeautify = lineCommentNoBeautify; activeBeautifierStack->back()->isNonInStatementArray = isNonInStatementArray; - return activeBeautifierStack->back()->beautify(line); + activeBeautifierStack->back()->isSharpAccessor = isSharpAccessor; + activeBeautifierStack->back()->isSharpDelegate = isSharpDelegate; + activeBeautifierStack->back()->isInExtern = isInExtern; + activeBeautifierStack->back()->isInBeautifySQL = isInBeautifySQL; + activeBeautifierStack->back()->isInIndentableStruct = isInIndentableStruct; + // must return originalLine not the trimmed line + return activeBeautifierStack->back()->beautify(originalLine); } // calculate preliminary indentation based on data from past lines + if (!inStatementIndentStack->empty()) spaceTabCount = inStatementIndentStack->back(); - - for (i = 0; i < (int) headerStackSize; ++i) + for (i = 0; i < (int) headerStack->size(); i++) { isInClass = false; - if (blockIndent || (!(i > 0 && (*headerStack)[i-1] != &AS_OPEN_BRACKET - && (*headerStack)[i] == &AS_OPEN_BRACKET))) + if (blockIndent) + { + // do NOT indent opening block for these headers + if (!((*headerStack)[i] == &AS_NAMESPACE + || (*headerStack)[i] == &AS_CLASS + || (*headerStack)[i] == &AS_STRUCT + || (*headerStack)[i] == &AS_UNION + || (*headerStack)[i] == &AS_CONST + || (*headerStack)[i] == &AS_INTERFACE + || (*headerStack)[i] == &AS_THROWS + || (*headerStack)[i] == &AS_STATIC)) + ++tabCount; + } + else if (!(i > 0 && (*headerStack)[i-1] != &AS_OPEN_BRACKET + && (*headerStack)[i] == &AS_OPEN_BRACKET)) ++tabCount; - if (!isJavaStyle && !namespaceIndent && i >= 1 + if (!isJavaStyle() && !namespaceIndent && i >= 1 && (*headerStack)[i-1] == &AS_NAMESPACE && (*headerStack)[i] == &AS_OPEN_BRACKET) --tabCount; - if (isCStyle && i >= 1 + if (isCStyle() && i >= 1 && (*headerStack)[i-1] == &AS_CLASS && (*headerStack)[i] == &AS_OPEN_BRACKET) { @@ -873,41 +986,68 @@ } // 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 - ) + else if (switchIndent && i > 1 + && (*headerStack)[i-1] == &AS_SWITCH + && (*headerStack)[i] == &AS_OPEN_BRACKET) { ++tabCount; isInSwitch = true; } - } + } // end of for loop * end of for loop * end of for loop * end of for loop * end of for loop * + + iPrelim = i; if (!lineStartsInComment - && isCStyle + && isCStyle() && isInClass && classIndent - && headerStackSize >= 2 - && (*headerStack)[headerStackSize-2] == &AS_CLASS - && (*headerStack)[headerStackSize-1] == &AS_OPEN_BRACKET - && line[0] == '}') + && headerStack->size() >= 2 + && (*headerStack)[headerStack->size()-2] == &AS_CLASS + && (*headerStack)[headerStack->size()-1] == &AS_OPEN_BRACKET + && line[0] == '}' + && bracketBlockStateStack->back() == true) --tabCount; else if (!lineStartsInComment && isInSwitch && switchIndent - && headerStackSize >= 2 - && (*headerStack)[headerStackSize-2] == &AS_SWITCH - && (*headerStack)[headerStackSize-1] == &AS_OPEN_BRACKET + && headerStack->size() >= 2 + && (*headerStack)[headerStack->size()-2] == &AS_SWITCH + && (*headerStack)[headerStack->size()-1] == &AS_OPEN_BRACKET && line[0] == '}') --tabCount; - if (isInClassHeader) + if (isInClassInitializer) { - isInClassHeaderTab = true; - tabCount += 2; + if (lineStartsInComment || lineOpensComment) + { + if (!lineBeginsWithBracket) + tabCount--; + } + else if (isCStyle() && !isClassAccessModifier(line)) + { + isInClassHeaderTab = true; + tabCount += classInitializerTabs; + } + else if (blockIndent) + { + if (!lineBeginsWithBracket) + tabCount++; + } } + // handle special case of indented horstmann brackets + else if (lineStartsInComment && isInHorstmannComment && bracketIndent) + tabCount++; + + // handle special case of horstmann comment in an indented class statement + if (isInClass + && classIndent + && isInHorstmannComment + && !lineOpensComment + && headerStack->size() >= 2 + && (*headerStack)[headerStack->size()-2] == &AS_CLASS) + --tabCount; if (isInConditional) { @@ -917,56 +1057,81 @@ // parse characters in the current line. - for (i = 0; i < (int) line.length(); ++i) + for (i = 0; i < (int) line.length(); i++) { - tempCh = line[i]; + outBuffer.append(1, line[i]); + tempCh = line[i]; prevCh = ch; ch = tempCh; - outBuffer.append(1, ch); - - if (isWhiteSpace(ch)) - continue; - - // check for utf8 characters - // isalnum() will display an assert message in debug if not bypassed here - if (ch & 0x80) + if (isInBeautifySQL) continue; - // handle special characters (i.e. backslash+character such as \n, \t, ...) - if (isSpecialChar) + if (isWhiteSpace(ch)) { - isSpecialChar = false; + if (ch == '\t') + tabIncrementIn += convertTabToSpaces(i, tabIncrementIn); continue; } - if (!(isInComment || isInLineComment) && line.compare(i, 2, "\\\\") == 0) + + // handle special characters (i.e. backslash+character such as \n, \t, ...) + + if (isInQuote && !isInVerbatimQuote) { - outBuffer.append(1, '\\'); - ++i; - continue; + if (isSpecialChar) + { + isSpecialChar = false; + continue; + } + if (line.compare(i, 2, "\\\\") == 0) + { + outBuffer.append(1, '\\'); + i++; + continue; + } + if (ch == '\\') + { + if (peekNextChar(line, i) == ' ') // is this '\' at end of line + haveLineContinuationChar = true; + else + isSpecialChar = true; + continue; + } } - if (!(isInComment || isInLineComment) && ch == '\\') - { - isSpecialChar = true; + else if (isInDefine && ch == '\\') continue; - } // handle quotes (such as 'x' and "Hello Dolly") if (!(isInComment || isInLineComment) && (ch == '"' || ch == '\'')) - { + { if (!isInQuote) { quoteChar = ch; isInQuote = true; + if (isSharpStyle() && prevCh == '@') + isInVerbatimQuote = true; + } + else if (isInVerbatimQuote && ch == '"') + { + if (peekNextChar(line, i) == '"') // check consecutive quotes + { + outBuffer.append(1, '"'); + i++; + } + else + { + isInQuote = false; + isInVerbatimQuote = false; + } } else if (quoteChar == ch) { isInQuote = false; isInStatement = true; continue; } - } + } if (isInQuote) continue; @@ -976,33 +1141,48 @@ { isInLineComment = true; outBuffer.append(1, '/'); - ++i; + i++; continue; } else if (!(isInComment || isInLineComment) && line.compare(i, 2, "/*") == 0) { isInComment = true; outBuffer.append(1, '*'); - ++i; - size_t j = line.find_first_not_of(" \t"); - if (line.compare(j, 2, "/*") != 0) // does line start with comment? - blockCommentNoIndent = true; // if no, cannot indent continuation lines + i++; + if (!lineOpensComment) // does line start with comment? + blockCommentNoIndent = true; // if no, cannot indent continuation lines continue; } else if ((isInComment || isInLineComment) && line.compare(i, 2, "*/") == 0) { isInComment = false; outBuffer.append(1, '/'); - ++i; - blockCommentNoIndent = false; // ok to indent next comment + i++; + blockCommentNoIndent = false; // ok to indent next comment continue; } + // treat C# '#region' and '#endregion' statements as a line comment + else if (isSharpStyle() && + (line.compare(i, 7, "#region") == 0 || line.compare(i, 10, "#endregion") == 0)) + { + isInLineComment = true; + } if (isInComment || isInLineComment) + { + // append rest of the comment up to the comment end + while (i+1 < (int) line.length() + && line.compare(i+1, 2, "*/") != 0) + outBuffer.append(1, line[++i]); continue; + } // if we have reached this far then we are NOT in a comment or string of special character... + // SQL if formatted in ASEnhancer + if (isInBeautifySQL) + continue; + if (probationHeader != NULL) { if (((probationHeader == &AS_STATIC || probationHeader == &AS_CONST) && ch == '{') @@ -1014,14 +1194,15 @@ // handle the specific probation header isInConditional = (probationHeader == &AS_SYNCHRONIZED); - if (probationHeader == &AS_CONST) - isImmediatelyAfterConst = true; isInStatement = false; // if the probation comes from the previous line, then indent by 1 tab count. - if (previousLineProbation && ch == '{') + if (previousLineProbation + && ch == '{' + && !(blockIndent + && (probationHeader == &AS_CONST || probationHeader == &AS_STATIC))) { - ++tabCount; + tabCount++; previousLineProbationTab = true; } previousLineProbation = false; @@ -1047,9 +1228,9 @@ else currentHeader = NULL; - if (isCStyle && isInTemplate + if (isCStyle() && isInTemplate && (ch == '<' || ch == '>') - && findHeader(line, i, nonAssignmentOperators) == NULL) + && findOperator(line, i, nonAssignmentOperators) == NULL) { if (ch == '<') { @@ -1074,29 +1255,51 @@ { if (ch == '(' || ch == '[') { + isInOperator = false; + // if have a struct header, this is a declaration not a definition + if (ch == '(' + && (isInClassInitializer || isInClassHeaderTab) + && headerStack->size() > 0 + && headerStack->back() == &AS_STRUCT) + { + headerStack->pop_back(); + isInClassInitializer = false; + // -1 for isInClassInitializer, -2 for isInClassHeaderTab + if (isInClassHeaderTab) + { + tabCount -= (1 + classInitializerTabs); + isInClassHeaderTab = false; + } + if (tabCount < 0) + tabCount = 0; + } + if (parenDepth == 0) { parenStatementStack->push_back(isInStatement); isInStatement = true; } - ++parenDepth; + parenDepth++; inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size()); if (currentHeader != NULL) - registerInStatementIndent(line, i, spaceTabCount, minConditionalIndent/*indentLength*2*/, true); + registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, minConditionalIndent/*indentLength*2*/, true); else - registerInStatementIndent(line, i, spaceTabCount, 0, true); + registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, 0, true); } else if (ch == ')' || ch == ']') { - --parenDepth; + parenDepth--; if (parenDepth == 0) { - isInStatement = parenStatementStack->back(); - parenStatementStack->pop_back(); + if (!parenStatementStack->empty()) // in case of unmatched closing parens + { + isInStatement = parenStatementStack->back(); + parenStatementStack->pop_back(); + } ch = ' '; - + isInAsm = false; isInConditional = false; } @@ -1124,38 +1327,49 @@ if (ch == '{') { - bool isBlockOpener; // first, check if '{' is a block-opener or an static-array opener - isBlockOpener = ((prevNonSpaceCh == '{' && bracketBlockStateStack->back()) - || prevNonSpaceCh == '}' - || prevNonSpaceCh == ')' - || prevNonSpaceCh == ';' - || peekNextChar(line, i) == '{' - || isNonInStatementArray - || isInClassHeader -// || isBlockOpener - || isImmediatelyAfterConst - || (isInDefine && - (prevNonSpaceCh == '(' - || prevNonSpaceCh == '_' - || isalnum(prevNonSpaceCh)))); - - isInClassHeader = false; + bool isBlockOpener = ((prevNonSpaceCh == '{' && bracketBlockStateStack->back()) + || prevNonSpaceCh == '}' + || prevNonSpaceCh == ')' + || prevNonSpaceCh == ';' + || peekNextChar(line, i) == '{' + || isInClassInitializer + || isNonInStatementArray + || isSharpAccessor + || isSharpDelegate + || isInExtern + || (isInDefine && + (prevNonSpaceCh == '(' + || isLegalNameChar(prevNonSpaceCh)))); + + // remove inStatementIndent for C++ class initializer + if (isInClassInitializer) + { + if (inStatementIndentStack->size() > 0) + inStatementIndentStack->pop_back(); + isInStatement = false; + if (lineBeginsWithBracket) + spaceTabCount = 0; + isInClassInitializer = false; + } + if (!isBlockOpener && currentHeader != NULL) { - for (size_t n = 0; n < nonParenHeaders.size(); ++n) - if (currentHeader == nonParenHeaders[n]) + for (size_t n = 0; n < nonParenHeaders->size(); n++) + if (currentHeader == (*nonParenHeaders)[n]) { isBlockOpener = true; break; } } + bracketBlockStateStack->push_back(isBlockOpener); + if (!isBlockOpener) { inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size()); - registerInStatementIndent(line, i, spaceTabCount, 0, true); - ++parenDepth; + registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, 0, true); + parenDepth++; if (i == 0) shouldIndentBrackettedLine = false; @@ -1165,32 +1379,50 @@ // this bracket is a block opener... ++lineOpeningBlocksNum; -// if (isInClassHeader) -// isInClassHeader = false; if (isInClassHeaderTab) { isInClassHeaderTab = false; // decrease tab count if bracket is broken size_t firstChar = line.find_first_not_of(" \t"); - if (firstChar != string::npos) - if (line[firstChar] == '{' && (int) firstChar == i) - tabCount -= 2; + if (firstChar != string::npos + && line[firstChar] == '{' + && (int) firstChar == i) + { + tabCount -= classInitializerTabs; + // decrease one more if an empty class + if (headerStack->size() > 0 + && (*headerStack).back() == &AS_CLASS) + { + int nextChar = getNextProgramCharDistance(line, i); + if (line[nextChar] == '}') + tabCount--; + } + } } - // do not allow inStatementIndent - should occur for Java files only - if (inStatementIndentStack->size() > 0) + if (bracketIndent && !namespaceIndent && headerStack->size() > 0 + && (*headerStack).back() == &AS_NAMESPACE) { - spaceTabCount = 0; - inStatementIndentStack->back() = 0; + shouldIndentBrackettedLine = false; + tabCount--; } + // an indentable struct is treated like a class in the header stack + if (headerStack->size() > 0 + && (*headerStack).back() == &AS_STRUCT + && isInIndentableStruct) + (*headerStack).back() = &AS_CLASS; + blockParenDepthStack->push_back(parenDepth); blockStatementStack->push_back(isInStatement); inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size()); if (inStatementIndentStack->size() > 0) + { + spaceTabCount = 0; inStatementIndentStack->back() = 0; + } blockTabCount += isInStatement ? 1 : 0; parenDepth = 0; @@ -1204,13 +1436,34 @@ } //check if a header has been reached - if (isWhiteSpace(prevCh)) + bool isPotentialHeader = isCharPotentialHeader(line, i); + + if (isPotentialHeader) { - bool isIndentableHeader = true; const string *newHeader = findHeader(line, i, headers); + + if (newHeader != NULL) + { + char peekChar = peekNextChar(line, i + newHeader->length() - 1); + + // is not a header if part of a definition + if (peekChar == ',' || peekChar == ')') + newHeader = NULL; + // the following accessor definitions are NOT headers + // goto default; is NOT a header + // default(int) keyword in C# is NOT a header + else if ((newHeader == &AS_GET || newHeader == &AS_SET || newHeader == &AS_DEFAULT) + && (peekChar == ';' || peekChar == '(')) + { + newHeader = NULL; + } + } + if (newHeader != NULL) { // if we reached here, then this is a header... + bool isIndentableHeader = true; + isInHeader = true; vector *lastTempStack; @@ -1239,7 +1492,7 @@ // 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) + for (int r = 0; r < restackSize; r++) { headerStack->push_back(lastTempStack->back()); lastTempStack->pop_back(); @@ -1266,7 +1519,7 @@ // 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) + for (int r = 0; r < restackSize; r++) { headerStack->push_back(lastTempStack->back()); lastTempStack->pop_back(); @@ -1289,7 +1542,7 @@ // 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) + for (int r = 0; r < restackSize; r++) { headerStack->push_back(lastTempStack->back()); lastTempStack->pop_back(); @@ -1303,16 +1556,21 @@ else if (newHeader == &AS_CASE) { isInCase = true; - --tabCount; + if (!haveCaseIndent) + { + haveCaseIndent = true; + if (!lineBeginsWithBracket) + --tabCount; + } } else if (newHeader == &AS_DEFAULT) { isInCase = true; --tabCount; } else if (newHeader == &AS_STATIC || newHeader == &AS_SYNCHRONIZED - || (newHeader == &AS_CONST && isCStyle)) + || (newHeader == &AS_CONST && isCStyle())) { if (!headerStack->empty() && (headerStack->back() == &AS_STATIC @@ -1333,17 +1591,16 @@ } else if (newHeader == &AS_TEMPLATE) { - if (isCStyle) + if (isCStyle()) isInTemplate = true; isIndentableHeader = false; } - if (isIndentableHeader) { headerStack->push_back(newHeader); isInStatement = false; - if (indexOf(nonParenHeaders, newHeader) == -1) + if (indexOf(*nonParenHeaders, newHeader) == -1) { isInConditional = true; } @@ -1356,30 +1613,16 @@ i += newHeader->length() - 1; continue; - } - } + } // newHeader != NULL - if (isCStyle && !isalpha(prevCh) - && line.compare(i, 8, "operator") == 0 && !isalnum(line[i+8])) - { - isInOperator = true; - outBuffer.append(AS_OPERATOR.substr(1)); - i += 7; - continue; - } + if (isCStyle() && findKeyword(line, i, AS_ENUM)) + isInEnum = true; - // "new" operator is a pointer, not a calculation - if (!isalpha(prevCh) - && line.compare(i, 3, "new") == 0 && !isalnum(line[i+3])) - { - if (prevNonSpaceCh == '=' && isInStatement && !inStatementIndentStack->empty()) - inStatementIndentStack->back() = 0; - } + } // isPotentialHeader if (ch == '?') isInQuestion = true; - // special handling of 'case' statements if (ch == ':') { @@ -1396,62 +1639,109 @@ isInQuestion = false; } - else if (isCStyle && isInClass && prevNonSpaceCh != ')') + else if (isCStyle() && isInClassInitializer) { - --tabCount; - // found a 'private:' or 'public:' inside a class definition + // found a 'class A : public B' definition // so do nothing special } - else if (!isJavaStyle && isInClassHeader) + else if (isCStyle() + && (isInAsm || isInAsmOneLine || isInAsmBlock)) { - // found a 'class A : public B' definition - // so do nothing special + // do nothing special } - else if (isJavaStyle && lastLineHeader == &AS_FOR) + else if (isCStyle() && isdigit(peekNextChar(line, i))) { - // found a java for-each statement + // found a bit field // so do nothing special } - else if (isCStyle && prevNonSpaceCh == ')') + else if (isCStyle() && isInClass && prevNonSpaceCh != ')') + { + // found a 'private:' or 'public:' inside a class definition + --tabCount; + } + + else if (isCStyle() && prevNonSpaceCh == ')' && !isInCase) { - isInClassHeader = true; + isInClassInitializer = true; if (i == 0) - tabCount += 2; + tabCount += classInitializerTabs; } + + 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 if (isInCase) { isInCase = false; ch = ';'; // from here on, treat char as ';' } - - - else // is in a label (e.g. 'label1:') + else if (isCStyle() || (isSharpStyle() && peekNextChar(line, i) == ';')) // is in a label (e.g. 'label1:') { if (labelIndent) --tabCount; // unindent label by one indent - else + else if (!lineBeginsWithBracket) tabCount = 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(); + // handle commas + // previous "isInStatement" will be from an assignment operator + if (ch == ',' && parenDepth == 0 && !isInStatement && !isNonInStatementArray) + { + // is comma at end of line + size_t nextChar = line.find_first_not_of(" \t", i + 1); + if (nextChar != string::npos) + { + if (line.compare(nextChar, 2, "//") == 0 + || line.compare(nextChar, 2, "/*") == 0) + nextChar = string::npos; + } + // register indent + if (nextChar == string::npos) + { + // register indent at first word after the colon of a C++ class initializer + if (isInClassInitializer) + { + size_t firstChar = line.find_first_not_of(" \t"); + if (firstChar != string::npos && line[firstChar] == ':') + { + size_t firstWord = line.find_first_not_of(" \t", firstChar + 1); + if (firstChar != string::npos) + { + int inStatementIndent = firstWord + spaceTabCount + tabIncrementIn; + inStatementIndentStack->push_back(inStatementIndent); + isInStatement = true; + } + } + } + // register indent at previous word + else + { + int prevWord = getInStatementIndentComma(line, i); + int inStatementIndent = prevWord + spaceTabCount + tabIncrementIn; + inStatementIndentStack->push_back(inStatementIndent); + isInStatement = true; + } + } + } // handle ends of statements - if ((ch == ';' && parenDepth == 0) || ch == '}'/* || (ch == ',' && parenDepth == 0)*/) + if ((ch == ';' && parenDepth == 0) || ch == '}') { if (ch == '}') { @@ -1470,7 +1760,7 @@ inStatementIndentStackSizeStack->pop_back(); while (previousIndentStackSize < (int) inStatementIndentStack->size()) inStatementIndentStack->pop_back(); - --parenDepth; + parenDepth--; if (i == 0) shouldIndentBrackettedLine = false; @@ -1501,10 +1791,20 @@ blockStatementStack->pop_back(); if (isInStatement) - --blockTabCount; + blockTabCount--; } closingBracketReached = true; + isInAsmOneLine = false; + + // added for release 1.24 + // TODO: remove at the appropriate time + assert(isInAsm == false); + assert(isInAsmOneLine == false); + assert(isInQuote == false); + isInAsm = isInAsmOneLine = isInQuote = false; + // end remove + int headerPlace = indexOf(*headerStack, &AS_OPEN_BRACKET); if (headerPlace != -1) { @@ -1516,6 +1816,11 @@ } headerStack->pop_back(); + // do not indent namespace bracket unless namespaces are indented + if (!namespaceIndent && headerStack->size() > 0 + && (*headerStack).back() == &AS_NAMESPACE) + shouldIndentBrackettedLine = false; + if (!tempStacks->empty()) { vector *temp = tempStacks->back(); @@ -1531,7 +1836,7 @@ /* * 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. + * the begining 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, @@ -1550,76 +1855,173 @@ isInStatement = false; previousLastLineHeader = NULL; - isInClassHeader = false; + isInClassInitializer = false; + isInEnum = false; isInQuestion = false; continue; } - - // check for preBlockStatements ONLY if not within parenthesies - // (otherwise 'struct XXX' statements would be wrongly interpreted...) - if (isWhiteSpace(prevCh) && !isInTemplate && parenDepth == 0) + if (isPotentialHeader) { - const string *newHeader = findHeader(line, i, preBlockStatements); - if (newHeader != NULL) + // check for preBlockStatements in C/C++ ONLY if not within parenthesies + // (otherwise 'struct XXX' statements would be wrongly interpreted...) + if (!isInTemplate && !(isCStyle() && parenDepth > 0)) { - isInClassHeader = true; - outBuffer.append(newHeader->substr(1)); - i += newHeader->length() - 1; - headerStack->push_back(newHeader); + const string *newHeader = findHeader(line, i, preBlockStatements); + if (newHeader != NULL + && !(isCStyle() && newHeader == &AS_CLASS && isInEnum)) // is it 'enum class' + { + isInClassInitializer = true; + + if (!isSharpStyle()) + headerStack->push_back(newHeader); + // do not need 'where' in the headerStack + // do not need second 'class' statement in a row + else if (!(newHeader == &AS_WHERE + || (newHeader == &AS_CLASS + && headerStack->size() > 0 + && headerStack->back() == &AS_CLASS))) + headerStack->push_back(newHeader); + + outBuffer.append(newHeader->substr(1)); + i += newHeader->length() - 1; + continue; + } + } + const string *foundIndentableHeader = findHeader(line, i, indentableHeaders); + + if (foundIndentableHeader != NULL) + { + // must bypass the header before registering the in statement + outBuffer.append(foundIndentableHeader->substr(1)); + i += foundIndentableHeader->length() - 1; + if (!isInOperator && !isInTemplate && !isNonInStatementArray) + { + registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, 0, false); + isInStatement = true; + } + continue; + } + + if (isCStyle() && findKeyword(line, i, AS_OPERATOR)) + isInOperator = true; + + // "new" operator is a pointer, not a calculation + if (findKeyword(line, i, AS_NEW)) + { + if (prevNonSpaceCh == '=' && isInStatement && !inStatementIndentStack->empty()) + inStatementIndentStack->back() = 0; + } + + if (isCStyle()) + { + if (findKeyword(line, i, AS_ASM) + || findKeyword(line, i, AS__ASM__)) + { + isInAsm = true; + } + else if (findKeyword(line, i, AS_MS_ASM) // microsoft specific + || findKeyword(line, i, AS_MS__ASM)) + { + int index = 4; + if (peekNextChar(line, i) == '_') // check for __asm + index = 5; + + char peekedChar = ASBase::peekNextChar(line, i + index); + if (peekedChar == '{' || peekedChar == ' ') + isInAsmBlock = true; + else + isInAsmOneLine = true; + } } + + // append the entire name for all others + string name = getCurrentWord(line, i); + outBuffer.append(name.substr(1)); + i += name.length() - 1; + continue; } // Handle operators - immediatelyPreviousAssignmentOp = NULL; - - // Check if an operator has been reached. - const string *foundAssignmentOp = findHeader(line, i, assignmentOperators, false); - if (foundAssignmentOp == &AS_RETURN) - foundAssignmentOp = findHeader(line, i, assignmentOperators, true); - const string *foundNonAssignmentOp = findHeader(line, i, nonAssignmentOperators, false); - - // Since findHeader's boundary checking was not used above, it is possible - // that both an assignment op and a non-assignment op where found, - // e.g. '>>' and '>>='. If this is the case, treat the LONGER one as the - // found operator. - if (foundAssignmentOp != NULL && foundNonAssignmentOp != NULL) - { - if (foundAssignmentOp->length() < foundNonAssignmentOp->length()) - foundAssignmentOp = NULL; - else - foundNonAssignmentOp = NULL; - } - if (foundNonAssignmentOp != NULL) + bool isPotentialOperator = isCharPotentialOperator(ch); + + if (isPotentialOperator) { - if (foundNonAssignmentOp->length() > 1) + // Check if an operator has been reached. + const string *foundAssignmentOp = findOperator(line, i, assignmentOperators); + const string *foundNonAssignmentOp = findOperator(line, i, nonAssignmentOperators); + + // Since findHeader's boundry 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) { - outBuffer.append(foundNonAssignmentOp->substr(1)); - i += foundNonAssignmentOp->length() - 1; + if (foundAssignmentOp->length() < foundNonAssignmentOp->length()) + foundAssignmentOp = NULL; + else + foundNonAssignmentOp = NULL; } - } - else if (foundAssignmentOp != NULL) - { - if (foundAssignmentOp->length() > 1) + if (foundNonAssignmentOp != NULL) { - outBuffer.append(foundAssignmentOp->substr(1)); - i += foundAssignmentOp->length() - 1; + if (foundNonAssignmentOp->length() > 1) + { + outBuffer.append(foundNonAssignmentOp->substr(1)); + i += foundNonAssignmentOp->length() - 1; + } + + // For C++ input/output, operator<< and >> should be + // aligned, if we are not in a statement already and + // also not in the "operator<<(...)" header line + if (!isInOperator + && inStatementIndentStack->empty() + && isCStyle() + && (foundNonAssignmentOp == &AS_GR_GR || + foundNonAssignmentOp == &AS_LS_LS)) + { + // this will be true if the line begins with the operator + if (i < 2 && spaceTabCount == 0) + spaceTabCount += 2 * indentLength; + // align to the beginning column of the operator + registerInStatementIndent(line, i - foundNonAssignmentOp->length(), spaceTabCount, tabIncrementIn, 0, false); + } } - if (!isInOperator && !isInTemplate && !isNonInStatementArray) + else if (foundAssignmentOp != NULL) { - registerInStatementIndent(line, i, spaceTabCount, 0, false); - immediatelyPreviousAssignmentOp = foundAssignmentOp; - isInStatement = true; + if (foundAssignmentOp->length() > 1) + { + outBuffer.append(foundAssignmentOp->substr(1)); + i += foundAssignmentOp->length() - 1; + } + + if (!isInOperator && !isInTemplate && !isNonInStatementArray) + { + // 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 + spaceTabCount + tabIncrementIn; + inStatementIndentStack->push_back(inStatementIndent); + } + } + else + registerInStatementIndent(line, i, spaceTabCount, tabIncrementIn, 0, false); + + isInStatement = true; + } } } - - if (isInOperator) - isInOperator = false; - } + } // end of for loop * end of for loop * end of for loop * end of for loop * end of for loop * // handle special cases of unindentation: @@ -1638,6 +2040,18 @@ && shouldIndentBrackettedLine) --tabCount; + // must check one less in headerStack if more than one header on a line (allow-addins)... + else if (!lineStartsInComment + && (int) headerStack->size() > iPrelim + 1 + && !blockIndent + && outBuffer.length() > 0 + && outBuffer[0] == '{' + && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum == lineClosingBlocksNum) + && !(headerStack->size() > 2 && (*headerStack)[headerStack->size()-3] == &AS_OPEN_BRACKET) + && shouldIndentBrackettedLine) + --tabCount; + + // unindent a closing bracket... else if (!lineStartsInComment && outBuffer.length() > 0 && outBuffer[0] == '}' @@ -1652,14 +2066,27 @@ && previousLineProbationTab) --tabCount; //lineOpeningBlocksNum - (blockIndent ? 1 : 0); + // correctly indent class continuation lines... + else if (!lineStartsInComment + && !lineOpensComment + && isInClassHeaderTab + && !blockIndent + && outBuffer.length() > 0 + && lineOpeningBlocksNum == 0 + && lineOpeningBlocksNum == lineClosingBlocksNum + && (headerStack->size() > 0 && headerStack->back() == &AS_CLASS)) + --tabCount; + if (tabCount < 0) tabCount = 0; // take care of extra bracket indentatation option... - if (bracketIndent && outBuffer.length() > 0 && shouldIndentBrackettedLine) - if (outBuffer[0] == '{' || outBuffer[0] == '}') - ++tabCount; - + if (!lineStartsInComment + && bracketIndent + && shouldIndentBrackettedLine + && outBuffer.length() > 0 + && (outBuffer[0] == '{' || outBuffer[0] == '}')) + tabCount++; if (isInDefine) { @@ -1676,7 +2103,7 @@ else { defineTabCount = tabCount - 1; - --tabCount; + tabCount--; } } } @@ -1686,13 +2113,10 @@ if (tabCount < 0) tabCount = 0; - if (lineCommentNoBeautify || blockCommentNoBeautify) + if (lineCommentNoBeautify || blockCommentNoBeautify || isInQuoteContinuation) tabCount = spaceTabCount = 0; - // finally, insert indentations into beginning of line - - prevFinalLineSpaceTabCount = spaceTabCount; - prevFinalLineTabCount = tabCount; + // finally, insert indentations into begining of line if (shouldForceTabIndentation) { @@ -1702,6 +2126,9 @@ outBuffer = preLineWS(spaceTabCount, tabCount) + outBuffer; + prevFinalLineSpaceTabCount = spaceTabCount; + prevFinalLineTabCount = tabCount; + if (lastLineHeader != NULL) previousLastLineHeader = lastLineHeader; @@ -1713,79 +2140,121 @@ { string ws; - for (int i = 0; i < tabCount; ++i) + for (int i = 0; i < tabCount; i++) ws += indentString; - while ((--spaceTabCount) >= 0) + while ((spaceTabCount--) > 0) ws += string(" "); return ws; } +bool ASBeautifier::isClassAccessModifier(string& line) const +{ + size_t firstChar = line.find_first_not_of(" \t"); + if (firstChar == string::npos) + return false; + // bypass a colon + if (line[firstChar] == ':') + { + firstChar = line.find_first_not_of(" \t"); + if (firstChar == string::npos) + return false; + } + if (line.compare(firstChar, 7, "public ") == 0 + || line.compare(firstChar, 8, "private ") == 0 + || line.compare(firstChar, 10, "protected ") == 0) + return true; + return false; +} + /** * register an in-statement indent. */ void ASBeautifier::registerInStatementIndent(const string &line, int i, int spaceTabCount, - int minIndent, bool updateParenStack) + int tabIncrementIn, int minIndent, bool updateParenStack) { int inStatementIndent; int remainingCharNum = line.length() - i; int nextNonWSChar = getNextProgramCharDistance(line, i); - // if indent is around the last char in the line, indent instead 2 spaces from the previous indent + // if indent is around the last char in the line, indent instead one indent from the previous indent if (nextNonWSChar == remainingCharNum) { int previousIndent = spaceTabCount; if (!inStatementIndentStack->empty()) previousIndent = inStatementIndentStack->back(); - - inStatementIndentStack->push_back(/*2*/ indentLength + previousIndent); + int currIndent = /*2*/ indentLength + previousIndent; + if (currIndent > maxInStatementIndent + && line[i] != '{') + currIndent = indentLength * 2 + spaceTabCount; + inStatementIndentStack->push_back(currIndent); if (updateParenStack) parenIndentStack->push_back(previousIndent); return; } if (updateParenStack) - parenIndentStack->push_back(i + spaceTabCount); + parenIndentStack->push_back(i + spaceTabCount - horstmannIndentInStatement); + + int tabIncrement = tabIncrementIn; + + // check for following tabs + for (int j = i + 1; j < (i + nextNonWSChar); j++) + { + if (line[j] == '\t') + tabIncrement += convertTabToSpaces(j, tabIncrement); + } - inStatementIndent = i + nextNonWSChar + spaceTabCount; + inStatementIndent = i + nextNonWSChar + spaceTabCount + tabIncrement; - if (i + nextNonWSChar < minIndent) + // check for run-in statement + if (i > 0 && line[0] == '{') + inStatementIndent -= indentLength; + +// if (i + nextNonWSChar < minIndent) +// inStatementIndent = minIndent + spaceTabCount; + + if (inStatementIndent < minIndent) inStatementIndent = minIndent + spaceTabCount; - if (i + nextNonWSChar > maxInStatementIndent) - inStatementIndent = indentLength * 2 + spaceTabCount; +// if (i + nextNonWSChar > maxInStatementIndent) +// inStatementIndent = indentLength * 2 + spaceTabCount; + + if (inStatementIndent > maxInStatementIndent) + inStatementIndent = indentLength * 2 + spaceTabCount; if (!inStatementIndentStack->empty() && inStatementIndent < inStatementIndentStack->back()) inStatementIndent = inStatementIndentStack->back(); - if (isNonInStatementArray) + // the block opener is not indented for a NonInStatementArray + if (isNonInStatementArray && !bracketBlockStateStack->empty() && bracketBlockStateStack->back()) inStatementIndent = 0; inStatementIndentStack->push_back(inStatementIndent); } /** - * get distance to the next non-white sspace, non-comment character in the line. + * 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) +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) + for (charDistance = 1; charDistance < remainingCharNum; charDistance++) { ch = line[i + charDistance]; if (inComment) { if (line.compare(i + charDistance, 2, "*/") == 0) { - ++charDistance; + charDistance++; inComment = false; } continue; @@ -1798,7 +2267,7 @@ return remainingCharNum; else if (line.compare(i + charDistance, 2, "/*") == 0) { - ++charDistance; + charDistance++; inComment = true; } } @@ -1809,72 +2278,62 @@ return charDistance; } - -/** - * check if a specific line position contains a header, out of several possible headers. - * - * @return a pointer to the found header. if no header was found then return NULL. - */ -const string *ASBeautifier::findHeader(const string &line, int i, const vector &possibleHeaders, bool checkBoundary) +// check if a specific line position contains a header. +const string* ASBeautifier::findHeader(const string &line, int i, + const vector* possibleHeaders) const { - int maxHeaders = possibleHeaders.size(); - // const string *header = NULL; - int p; - - for (p = 0; p < maxHeaders; ++p) + 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]; - - if (line.compare(i, header->length(), header->c_str()) == 0) - { - // check that this is a header and not a part of a longer word - // (e.g. not at its beginning, not at its middle...) - - int lineLength = line.length(); - int headerEnd = i + header->length(); - char startCh = (*header)[0]; // first char of header - char endCh = 0; // char just after header - char prevCh = 0; // char just before header - - if (headerEnd < lineLength) - { - endCh = line[headerEnd]; - } - if (i > 0) - { - prevCh = line[i-1]; - } - - if (!checkBoundary) - { - return header; - } - else if (prevCh != 0 - && isLegalNameChar(startCh) - && isLegalNameChar(prevCh)) - { - return NULL; - } - else if (headerEnd >= lineLength - || !isLegalNameChar(startCh) - || !isLegalNameChar(endCh)) - { - return header; - } - else - { - return NULL; - } - } + 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; + // is not a header if part of a definition + const char peekChar = peekNextChar(line, wordEnd - 1); + if (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 ocntainer. -1 if element not found. + * @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 . */ @@ -1890,6 +2349,18 @@ } /** + * 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. @@ -1902,33 +2373,284 @@ int end = str.length() - 1; while (start < end && isWhiteSpace(str[start])) - ++start; + start++; while (start <= end && isWhiteSpace(str[end])) - --end; + end--; string returnStr(str, start, end + 1 - start); return returnStr; } /** -* peek at the next unread character. -* -* @return the next unread character. -* @param line the line to check. -* @param i the current char position on the line. -*/ -char ASBeautifier::peekNextChar(string &line, int i) + * Copy tempStacks for the copy constructor. + * The value of the vectors must also be copied. + */ +vector*>* ASBeautifier::copyTempStacks(const ASBeautifier &other) const { - char ch = ' '; - size_t peekNum = line.find_first_not_of(" \t", i + 1); + vector*> *tempStacksNew = new vector*>; + vector*>::iterator iter; + for (iter = other.tempStacks->begin(); + iter != other.tempStacks->end(); + ++iter) + { + vector *newVec = new vector; + *newVec = **iter; + tempStacksNew->push_back(newVec); + } + return tempStacksNew; +} + +/** + * delete a static member vector to eliminate memory leak reporting for the vector + */ +void ASBeautifier::deleteStaticVectors() +{ + beautifierFileType = 9; // reset to an invalid type + deleteVector(headers); + deleteVector(nonParenHeaders); + deleteVector(preBlockStatements); + deleteVector(assignmentOperators); + deleteVector(nonAssignmentOperators); + deleteVector(indentableHeaders); +} + +/** + * delete a vector object + * T is the type of vector + * used for all vectors except tempStacks + */ +template +void ASBeautifier::deleteContainer(T &container) +{ + if (container != NULL) + { + container->clear(); + delete (container); + container = NULL; + } +} + +/** + * Delete the 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::deleteContainer(vector*>* &container) +{ + if (container != NULL) + { + vector*>::iterator iter = container->begin(); + for (; iter != container->end(); iter++) + delete *iter; + container->clear(); + delete (container); + container = NULL; + } +} + +/** + * delete a vector* object + */ +void ASBeautifier::deleteVector(vector*& container) +{ + assert(container != NULL); + delete container; + container = NULL; +} + +/** + * initialize a vector object + * T is the type of vector + * used for all vectors + */ +template +void ASBeautifier::initContainer(T &container, T value) +{ + // since the ASFormatter object is never deleted, + // the existing vectors must be deleted before creating new ones + if (container != NULL ) + deleteContainer(container); + container = value; +} - if (peekNum == string::npos) - return ch; +/** + * initialize a vector* object + */ +void ASBeautifier::initVector(vector*& container) +{ + assert(container == NULL); + container = new vector; +} + +/** + * 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(string &line, int index) +{ + 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 == '\'') + { + 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(string& line, int startPos) const +{ + assert(line.compare(startPos, 2, "/*") == 0); + + // comment must be closed on this line with nothing after it + size_t endNum = line.find("*/", startPos + 2); + if (endNum != string::npos) + { + size_t nextChar = line.find_first_not_of(" \t", endNum + 2); + if (nextChar == string::npos) + return true; + } + return false; +} + +/** + * get the previous word index for an assignment operator + * + * @return is the index to the previous word (the in statement indent). + */ +int ASBeautifier::getInStatementIndentAssign(const string& line, size_t currPos) const +{ + assert(line[currPos] == '='); + + if (currPos == 0) + return 0; + + // get the last legal word (may be a number) + size_t end = line.find_last_not_of(" \t", currPos-1); + if (end == string::npos || !isLegalNameChar(line[end])) + return 0; + + int start; // start of the previous word + for (start = end; start > -1; start--) + { + if (!isLegalNameChar(line[start]) || line[start] == '.') + break; + } + start++; + + return start; +} + +/** + * get the instatement indent for a comma + * + * @return is the indent to the second word on the line (the in statement indent). + */ +int ASBeautifier::getInStatementIndentComma(const string& line, size_t currPos) const +{ + assert(line[currPos] == ','); + + if (currPos == 0) + return 0; + + // 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) + return 0; - ch = line[peekNum]; + // point to second word or assignment operator + indent = line.find_last_not_of(" \t", indent); + if (indent == string::npos || indent >= currPos) + return 0; - return ch; + return indent; } diff --git a/kdev-pg/ASEnhancer.cpp b/kdev-pg/ASEnhancer.cpp --- a/kdev-pg/ASEnhancer.cpp +++ b/kdev-pg/ASEnhancer.cpp @@ -1,60 +1,31 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * ASEnhancer.cpp + * Copyright (C) 2006-2010 by Jim Pattee + * Copyright (C) 1998-2002 by Tal Davidson + * * - * This file is a part of "Artistic Style" - an indentation and + * This file is a part of Artistic Style - an indentation and * reformatting tool for C, C++, C# and Java source files. - * http://astyle.sourceforge.net + * * - * The "Artistic Style" project, including all files needed to - * compile it, is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later - * version. + * Artistic Style is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * Artistic Style 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 Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public - * License along with this project; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with Artistic Style. If not, see . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -// can trace only if NDEBUG is not defined -#ifndef NDEBUG -// #define TRACEswitch -// #define TRACEcase -// #define TRACEmisc -#endif - #include "astyle.h" -#include -#include -#include - -#ifdef TRACEswitch -#define TRswitch(a,b) *traceOut << lineNumber << a << b << endl; -#else -#define TRswitch(a,b) ((void)0) -#endif // TRACEswitch -#ifdef TRACEcase -#define TRcase(a,b) *traceOut << lineNumber << a << b << endl; -#else -#define TRcase(a,b) ((void)0) -#endif // TRACEcase -#ifdef TRACEmisc -#define TRmisc(a) *traceOut << lineNumber << a << endl; -#else -#define TRmisc(a) ((void)0) -#endif // TRACEmisc - namespace astyle { @@ -66,64 +37,40 @@ */ ASEnhancer::ASEnhancer() { - // variables are initialized by init() - traceOut = new stringstream; + // the following prevents warning messages with cppcheck + // it will NOT compile if activated +// init(); } /** * Destructor of ASEnhancer - * Display the TRACE entries. */ ASEnhancer::~ASEnhancer() { -#if defined(TRACEswitch) || defined(TRACEcase) || defined(TRACEmisc) - string line; - string msg = "TRACE Entries\n\n"; - char countLine[50]; - int count = 0; - - while (getline(*traceOut, line)) - { - msg += line + '\n'; - count++; - } - sprintf(countLine, "\n%d Entries", count); - msg += countLine; - // write a text file to "My Documents" (Windows) - char filename [_MAX_PATH + _MAX_FNAME + _MAX_EXT + 1]; // full path and filename - strcpy(filename, qgetenv("USERPROFILE").data()); - strcat(filename, "\\My Documents\\tracee.txt"); - ofstream outfile(filename); - outfile << msg; - outfile.close(); -#endif - delete traceOut; } /** * initialize the ASEnhancer. * * init() is called each time an ASFormatter object is initialized. */ -void ASEnhancer::init(int _indentLength, +void ASEnhancer::init(int fileType, + int _indentLength, string _indentString, - bool _isCStyle, - bool _isJavaStyle, - bool _isSharpStyle, bool _caseIndent, bool _emptyLineFill) { // formatting variables from ASFormatter and ASBeautifier + ASBase::init(fileType); indentLength = _indentLength; - if (_indentString.compare(0, 1, "\t") == 0) + if (_indentString == "\t") useTabs = true; else useTabs = false; - isCStyle = _isCStyle; - isJavaStyle = _isJavaStyle; - isSharpStyle = _isSharpStyle; + caseIndent = _caseIndent; emptyLineFill = _emptyLineFill; + quoteChar = '\''; // unindent variables lineNumber = 0; @@ -134,9 +81,17 @@ lookingForCaseBracket = false; unindentNextLine = false; -#if defined(TRACEswitch) || defined(TRACEcase) || defined(TRACEmisc) - *traceOut << "New file -------------" << endl; -#endif + // switch struct and vector + sw.switchBracketCount = 0; + sw.unindentDepth = 0; + sw.unindentCase = false; + swVector.clear(); + + // other variables + nextLineIsEventIndent = false; + isInEventTable = false; + nextLineIsDeclareIndent = false; + isInDeclareSection = false; } /** @@ -148,29 +103,29 @@ * * @param line the original formatted line will be updated if necessary. */ -void ASEnhancer::enhance(string &line) +void ASEnhancer::enhance(string &line, bool isInSQL) { - static vector swVector; // stack vector of switch variables - static switchVariables sw; // switch variables struct - - static bool nextLineIsEventTable; // begin event table is reached - static bool isInEventTable; // need to indent an event table - - bool isSpecialChar = false; - size_t lineLength; // length of the line being parsed + bool isSpecialChar = false; // is a backslash escape character lineNumber++; - lineLength = line.length(); // check for beginning of event table - if (nextLineIsEventTable) + if (nextLineIsEventIndent) { isInEventTable = true; - nextLineIsEventTable = false; + nextLineIsEventIndent = false; } - if (lineLength == 0 + // check for beginning of SQL declare section + if (nextLineIsDeclareIndent) + { + isInDeclareSection = true; + nextLineIsDeclareIndent = false; + } + + if (line.length() == 0 && ! isInEventTable + && ! isInDeclareSection && ! emptyLineFill) return; @@ -180,17 +135,16 @@ sw.unindentDepth++; sw.unindentCase = true; unindentNextLine = false; - TRcase(" unindent case ", sw.unindentDepth); } // parse characters in the current line. - for (size_t i = 0; i < lineLength; i++) + for (size_t i = 0; i < line.length(); i++) { char ch = line[i]; // bypass whitespace - if (isWhiteSpaceX(ch)) + if (isWhiteSpace(ch)) continue; // handle special characters (i.e. backslash+character such as \n, \t, ...) @@ -211,8 +165,8 @@ } // handle quotes (such as 'x' and "Hello Dolly") - if (!(isInComment) && (ch == '"' || ch == '\'')) - { + if (!isInComment && (ch == '"' || ch == '\'')) + { if (!isInQuote) { quoteChar = ch; @@ -223,7 +177,8 @@ isInQuote = false; continue; } - } + } + if (isInQuote) continue; @@ -254,135 +209,151 @@ // if we have reached this far then we are NOT in a comment or string of special characters - if (line[i] == '{') // if open bracket + if (line[i] == '{') bracketCount++; - if (line[i] == '}') // if close bracket + if (line[i] == '}') bracketCount--; + bool isPotentialKeyword = isCharPotentialHeader(line, i); + // ---------------- process event tables -------------------------------------- - // check for event table begin - if (findKeyword(line, i, "BEGIN_EVENT_TABLE") - || findKeyword(line, i, "BEGIN_MESSAGE_MAP")) - nextLineIsEventTable = true; + if (isPotentialKeyword) + { + if (findKeyword(line, i, "BEGIN_EVENT_TABLE") + || findKeyword(line, i, "BEGIN_MESSAGE_MAP")) + { + nextLineIsEventIndent = true; + break; + } + + if (findKeyword(line, i, "END_EVENT_TABLE") + || findKeyword(line, i, "END_MESSAGE_MAP")) + { + isInEventTable = false; + break; + } + } + + // ---------------- process SQL ----------------------------------------------- - // check for event table end - if (findKeyword(line, i, "END_EVENT_TABLE") - || findKeyword(line, i, "END_MESSAGE_MAP")) - isInEventTable = false; + if (isInSQL) + { + if (isBeginDeclareSectionSQL(line, i)) + nextLineIsDeclareIndent = true; + if (isEndDeclareSectionSQL(line, i)) + isInDeclareSection = false; + break; + } // ---------------- process switch statements --------------------------------- - if (findKeyword(line, i, "switch")) // if switch statement + if (isPotentialKeyword && findKeyword(line, i, "switch")) { - switchDepth++; // bump switch depth - TRswitch(" switch ", switchDepth); + switchDepth++; swVector.push_back(sw); // save current variables sw.switchBracketCount = 0; sw.unindentCase = false; // don't clear case until end of switch i += 5; // bypass switch statement continue; } - // just want switch statements from this point - - if (caseIndent || switchDepth == 0) // from here just want switch statements - continue; // get next char + // just want unindented switch statements from this point - if (line[i] == '{') // if open bracket + if (caseIndent || switchDepth == 0) { - sw.switchBracketCount++; - if (lookingForCaseBracket) // if 1st after case statement + // bypass the entire word + if (isPotentialKeyword) { - sw.unindentCase = true; // unindenting this case - sw.unindentDepth++; // bump depth - lookingForCaseBracket = false; // not looking now - TRcase(" unindent case ", sw.unindentDepth); + string name = getCurrentWord(line, i); + i += name.length() - 1; } continue; } - lookingForCaseBracket = false; // no opening bracket, don't indent + i = processSwitchBlock(line, i); - if (line[i] == '}') // if close bracket - { - sw.switchBracketCount--; - if (sw.switchBracketCount == 0) // if end of switch statement - { - TRswitch(" endsw ", switchDepth); - switchDepth--; // one less switch - sw = swVector.back(); // restore sw struct - swVector.pop_back(); // remove last entry from stack - } - continue; - } + } // end of for loop * end of for loop * end of for loop * end of for loop - // look for case or default header + if (isInEventTable || isInDeclareSection) + { + if (line[0] != '#') + indentLine(line, 1); + } - if (findKeyword(line, i, "case") || findKeyword(line, i, "default")) + if (sw.unindentDepth > 0) + unindentLine(line, sw.unindentDepth); +} + +/** + * find the colon following a 'case' statement + * + * @param line a reference to the line. + * @param i the line index of the case statement. + * @return the line index of the colon. + */ +size_t ASEnhancer::findCaseColon(string &line, size_t caseIndex) const +{ + size_t i = caseIndex; + bool isInQuote = false; + char quoteChar = ' '; + for (; i < line.length(); i++) + { + if (isInQuote) { - if (sw.unindentCase) // if unindented last case - { - sw.unindentCase = false; // stop unindenting previous case - sw.unindentDepth--; // reduce depth - } - for (; i < lineLength; ++i) // bypass colon + if (line[i] == '\\') { - if (line[i] == ':') { - if ((i + 1 < lineLength) && (line[i + 1] == ':')) - ++i; // bypass scope resolution operator - else - break; - } + i++; + continue; } - ++i; - for (; i < lineLength; ++i) // bypass whitespace + else if (line[i] == quoteChar) // check ending quote { - if (!(isWhiteSpaceX(line[i]))) - break; + isInQuote = false; + quoteChar = ' '; + continue; } - if (i < lineLength) // check for bracket + else { - if (line[i] == '{') // if bracket found - { - sw.switchBracketCount++; - unindentNextLine = true; // start unindenting on next line - continue; - } + continue; // must close quote before continuing } - lookingForCaseBracket = true; // bracket must be on next line - --i; // need to check for comments + } + if (line[i] == '\'' || line[i] == '\"') // check opening quote + { + isInQuote = true; + quoteChar = line[i]; continue; } - } // end of for loop - - if (isInEventTable) // if need to indent - indentLine(line, 1); // do it - - if (sw.unindentDepth > 0) // if need to unindent - unindentLine(line, sw.unindentDepth); // do it + 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 pointer to the line to indent. + * @param line a reference to the line to indent. * @param unindent the number of tabsets to insert. * @return the number of characters inserted. */ -int ASEnhancer::indentLine(string &line, const int indent) const +int ASEnhancer::indentLine(string &line, int indent) const { if (line.length() == 0 && ! emptyLineFill) return 0; - size_t charsToInsert; // number of chars to insert + size_t charsToInsert; // number of chars to insert - if (useTabs) // if formatted with tabs + if (useTabs) // if formatted with tabs { - charsToInsert = indent; // tabs to insert + charsToInsert = indent; // tabs to insert line.insert((size_t) 0, charsToInsert, '\t'); // insert the tabs } else @@ -395,14 +366,187 @@ } /** + * check for SQL "BEGIN DECLARE SECTION". + * must compare case insensitive and allow any spacing between words. + * + * @param line a reference to the line to indent. + * @param index the current line index. + * @return true if a hit. + */ +bool ASEnhancer::isBeginDeclareSectionSQL(string &line, size_t index) const +{ + string word; + size_t hits = 0; + size_t i; + for (i = index; i < line.length(); i++) + { + i = line.find_first_not_of(" \t", i); + if (i == string::npos) + return false; + if (line[i] == ';') + break; + if (!isCharPotentialHeader(line, i)) + continue; + word = getCurrentWord(line, i); + for (size_t j = 0; j < word.length(); j++) + word[j] = (char) toupper(word[j]); + if (word == "EXEC" || word == "SQL") + { + i += word.length() - 1; + continue; + } + if (word == "DECLARE" || word == "SECTION") + { + hits++; + i += word.length() - 1; + continue; + } + if (word == "BEGIN") + { + hits++; + i += word.length() - 1; + continue; + } + return false; + } + if (hits == 3) + return true; + return false; +} + +/** + * check for SQL "END DECLARE SECTION". + * must compare case insensitive and allow any spacing between words. + * + * @param line a reference to the line to indent. + * @param index the current line index. + * @return true if a hit. + */ +bool ASEnhancer::isEndDeclareSectionSQL(string &line, size_t index) const +{ + string word; + size_t hits = 0; + size_t i; + for (i = index; i < line.length(); i++) + { + i = line.find_first_not_of(" \t", i); + if (i == string::npos) + return false; + if (line[i] == ';') + break; + if (!isCharPotentialHeader(line, i)) + continue; + word = getCurrentWord(line, i); + for (size_t j = 0; j < word.length(); j++) + word[j] = (char) toupper(word[j]); + if (word == "EXEC" || word == "SQL") + { + i += word.length() - 1; + continue; + } + if (word == "DECLARE" || word == "SECTION") + { + hits++; + i += word.length() - 1; + continue; + } + if (word == "END") + { + hits++; + i += word.length() - 1; + continue; + } + return false; + } + if (hits == 3) + return true; + return false; +} + +/** + * process the character at the current index in a switch block. + * + * @param line a reference to the line to indent. + * @param index the current line index. + * @return the new line index. + */ +size_t ASEnhancer::processSwitchBlock(string &line, size_t index) +{ + size_t i = index; + bool isPotentialKeyword = isCharPotentialHeader(line, i); + + if (line[i] == '{') + { + sw.switchBracketCount++; + if (lookingForCaseBracket) // if 1st after case statement + { + sw.unindentCase = true; // unindenting this case + sw.unindentDepth++; + lookingForCaseBracket = false; // not looking now + } + return i; + } + lookingForCaseBracket = false; // no opening bracket, don't indent + + if (line[i] == '}') // if close bracket + { + sw.switchBracketCount--; + if (sw.switchBracketCount == 0) // if end of switch statement + { + switchDepth--; // one less switch + sw = swVector.back(); // restore sw struct + swVector.pop_back(); // remove last entry from stack + } + return i; + } + + if (isPotentialKeyword + && (findKeyword(line, i, "case") || findKeyword(line, i, "default"))) + { + if (sw.unindentCase) // if unindented last case + { + sw.unindentCase = false; // stop unindenting previous case + sw.unindentDepth--; // reduce depth + } + + i = findCaseColon(line, i); + + i++; + for (; i < line.length(); i++) // bypass whitespace + { + if (!isWhiteSpace(line[i])) + break; + } + if (i < line.length()) + { + if (line[i] == '{') + { + sw.switchBracketCount++; + unindentNextLine = true; + return i; + } + } + lookingForCaseBracket = true; // bracket must be on next line + i--; // need to check for comments + 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 pointer to the line to unindent. + * @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, const int unindent) const +int ASEnhancer::unindentLine(string &line, int unindent) const { size_t whitespace = line.find_first_not_of(" \t"); @@ -414,7 +558,7 @@ size_t charsToErase; // number of chars to erase - if (useTabs) // if formatted with tabs + if (useTabs) // if formatted with tabs { charsToErase = unindent; // tabs to erase if (charsToErase <= whitespace) // if there is enough whitespace @@ -434,52 +578,5 @@ return charsToErase; } -/** - * check if a specific line position contains a keyword. - * - * @return true if the word was found. false if the word was not found. - */ -bool ASEnhancer::findKeyword(const string &line, int i, const char *keyword) const -{ - if (line.compare(i, strlen(keyword), keyword) == 0) - { - // check that this is a header and not a part of a longer word - // (e.g. not at its beginning, not at its middle...) - - int lineLength = line.length(); - int wordEnd = i + strlen(keyword); - char startCh = keyword[0]; // first char of header - char endCh = 0; // char just after header - char prevCh = 0; // char just before header - - if (wordEnd < lineLength) - { - endCh = line[wordEnd]; - } - if (i > 0) - { - prevCh = line[i-1]; - } - - if (prevCh != 0 - && isLegalNameCharX(startCh) - && isLegalNameCharX(prevCh)) - { - return false; - } - else if (wordEnd >= lineLength - || !isLegalNameCharX(startCh) - || !isLegalNameCharX(endCh)) - { - return true; - } - else - { - return false; - } - } - - return false; -} } // end namespace astyle diff --git a/kdev-pg/ASFormatter.cpp b/kdev-pg/ASFormatter.cpp --- a/kdev-pg/ASFormatter.cpp +++ b/kdev-pg/ASFormatter.cpp @@ -1,284 +1,389 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * ASFormatter.cpp + * Copyright (C) 2006-2010 by Jim Pattee + * Copyright (C) 1998-2002 by Tal Davidson + * * - * This file is a part of "Artistic Style" - an indentation and + * This file is a part of Artistic Style - an indentation and * reformatting tool for C, C++, C# and Java source files. - * http://astyle.sourceforge.net + * * - * The "Artistic Style" project, including all files needed to - * compile it, is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later - * version. + * Artistic Style is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * Artistic Style 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 Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public - * License along with this project; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with Artistic Style. If not, see . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "astyle.h" -#include - #include #include #include -#ifdef __VMS -#include -#else -#include -#include "kdev-pg.h" -#endif - -// can trace only if NDEBUG is not defined -#ifndef NDEBUG -// #define TRACEunpad -// #define TRACEcomment -// #define TRACEheader -// #define TRACEbracket -// #define TRACEarray -#if defined(TRACEunpad) || defined(TRACEcomment) || defined(TRACEheader) \ -|| defined(TRACEbracket) || defined(TRACEarray) -ofstream *traceOutF; -#define TRACEF -#endif -#endif - -#ifdef TRACEunpad -#define TRunpad(a,b,c) if(b > 0 || c > 0) *traceOutF << outLineNumber << " " << b << a << c << endl -#else -#define TRunpad(a,b,c) ((void)0) -#endif - -#ifdef TRACEcomment -#define TRcomment(a) *traceOutF << outLineNumber << " " << a << endl -#else -#define TRcomment(a) ((void)0) -#endif - -#ifdef TRACEheader -#define TRxtra(a) *traceOutF << outLineNumber << " " << a << endl -#else -#define TRxtra(a) ((void)0) -#endif - -#ifdef TRACEbracket -#define TRbracket(a) *traceOutF << outLineNumber << " " << a << endl -#else -#define TRbracket(a) ((void)0) -#endif - -#ifdef TRACEarray -#define TRarray(a) *traceOutF << outLineNumber << " " << a << endl -#else -#define TRarray(a) ((void)0) -#endif - -#define INIT_CONTAINER(container, value) {if ( (container) != NULL ) delete (container); (container) = (value); } -#define DELETE_CONTAINER(container) {if ( (container) != NULL ) delete (container); } -#define IS_A(a,b) ( ((a) & (b)) == (b)) - -using namespace std; + namespace astyle { -vector ASFormatter::headers; -vector ASFormatter::nonParenHeaders; -vector ASFormatter::preDefinitionHeaders; -vector ASFormatter::preCommandHeaders; -vector ASFormatter::operators; -vector ASFormatter::assignmentOperators; -vector ASFormatter::castOperators; +// static member variables +int ASFormatter::formatterFileType = 9; // initialized with an invalid type +vector* ASFormatter::headers = NULL; +vector* ASFormatter::nonParenHeaders = NULL; +vector* ASFormatter::preDefinitionHeaders = NULL; +vector* ASFormatter::preCommandHeaders = NULL; +vector* ASFormatter::operators = NULL; +vector* ASFormatter::assignmentOperators = NULL; +vector* ASFormatter::castOperators = NULL; /** * Constructor of ASFormatter */ ASFormatter::ASFormatter() { + sourceIterator = NULL; + enhancer = new ASEnhancer; preBracketHeaderStack = NULL; bracketTypeStack = NULL; parenStack = NULL; + structStack = NULL; lineCommentNoIndent = false; - sourceIterator = NULL; + formattingStyle = STYLE_NONE; bracketFormatMode = NONE_MODE; + pointerAlignment = ALIGN_NONE; + lineEnd = LINEEND_DEFAULT; shouldPadOperators = false; shouldPadParensOutside = false; shouldPadParensInside = false; + shouldPadHeader = false; shouldUnPadParens = false; shouldBreakOneLineBlocks = true; shouldBreakOneLineStatements = true; shouldConvertTabs = false; + shouldIndentCol1Comments = false; shouldBreakBlocks = false; shouldBreakClosingHeaderBlocks = false; shouldBreakClosingHeaderBrackets = false; + shouldDeleteEmptyLines = false; shouldBreakElseIfs = false; -#ifdef TRACEF - // create a trace text file - string filename = "/tracef.txt"; - string env = QDir::homePath().toStdString(); - if (!env.empty()) - filename = string(env) + filename; - else - { - env = qgetenv("USERPROFILE").data(); - if (!env.empty()) - filename = env + string("\\My Documents\\tracef.txt"); - else - { - cout << "\nCould not open tracef.txt\n" << endl; - exit(1); - } - } - traceOutF = new ofstream(filename.c_str()); -#endif + shouldAddBrackets = false; + shouldAddOneLineBrackets = false; + + // initialize ASFormatter static member vectors + formatterFileType = 9; // reset to an invalid type + initVector(headers); + initVector(nonParenHeaders); + initVector(preDefinitionHeaders); + initVector(preCommandHeaders); + initVector(operators); + initVector(assignmentOperators); + initVector(castOperators); + + // the following prevents warning messages with cppcheck + // it will NOT compile if activated +// init(); } /** * Destructor of ASFormatter */ ASFormatter::~ASFormatter() { - DELETE_CONTAINER(preBracketHeaderStack); -#ifdef TRACEF - delete traceOutF; -#endif -} - -/** - * initialization of static data of ASFormatter. - */ -void ASFormatter::staticInit() -{ - static int formatterFileType = 9; // initialized with an invalid type - - if (fileType == formatterFileType) // don't build unless necessary - return; - - formatterFileType = fileType; - - headers.clear(); - nonParenHeaders.clear(); - assignmentOperators.clear(); - operators.clear(); - preDefinitionHeaders.clear(); - preCommandHeaders.clear(); - castOperators.clear(); - - ASResource::buildHeaders(headers, fileType); - ASResource::buildNonParenHeaders(nonParenHeaders, fileType); - ASResource::buildAssignmentOperators(assignmentOperators); - ASResource::buildOperators(operators); - ASResource::buildPreDefinitionHeaders(preDefinitionHeaders); - ASResource::buildPreCommandHeaders(preCommandHeaders); - ASResource::buildCastOperators(castOperators); + // delete ASFormatter stack vectors + deleteContainer(preBracketHeaderStack); + deleteContainer(bracketTypeStack); + deleteContainer(parenStack); + deleteContainer(structStack); + + // delete static member vectors using swap to eliminate memory leak reporting + // delete ASFormatter static member vectors + formatterFileType = 9; // reset to an invalid type + deleteVector(headers); + deleteVector(nonParenHeaders); + deleteVector(preDefinitionHeaders); + deleteVector(preCommandHeaders); + deleteVector(operators); + deleteVector(assignmentOperators); + deleteVector(castOperators); + + // delete ASBeautifier static member vectors + // must be done when the ASFormatter object is deleted (not ASBeautifier) + ASBeautifier::deleteStaticVectors(); + + 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 DYNAMICALLY CREATED ASSourceIterator object - * that will be used to iterate through the source code. This object will be - * deleted during the ASFormatter's destruction, and thus should not be - * deleted elsewhere. + * init() recieves a pointer to a ASSourceIterator object that will be + * used to iterate through the source code. * - * @param iter a pointer to the DYNAMICALLY CREATED ASSourceIterator object. + * @param sourceIterator a pointer to the ASSourceIterator or ASStreamIterator object. */ void ASFormatter::init(ASSourceIterator *si) { - staticInit(); + buildLanguageVectors(); + fixOptionVariableConflicts(); ASBeautifier::init(si); - ASEnhancer::init(ASBeautifier::getIndentLength(), - ASBeautifier::getIndentString(), - ASBeautifier::getCStyle(), - ASBeautifier::getJavaStyle(), - ASBeautifier::getSharpStyle(), - ASBeautifier::getCaseIndent(), - ASBeautifier::getEmptyLineFill()); + enhancer->init(getFileType(), + getIndentLength(), + getIndentString(), + getCaseIndent(), + getEmptyLineFill()); sourceIterator = si; - INIT_CONTAINER(preBracketHeaderStack, new vector); - INIT_CONTAINER(bracketTypeStack, new vector); + initContainer(preBracketHeaderStack, new vector); + initContainer(parenStack, new vector); + initContainer(structStack, new vector); + parenStack->push_back(0); // parenStack must contain this default entry + initContainer(bracketTypeStack, new vector); bracketTypeStack->push_back(NULL_TYPE); - INIT_CONTAINER(parenStack, new vector); - parenStack->push_back(0); - ignoreStuff = false; currentHeader = NULL; - currentLine = string(""); - readyFormattedLine = string(""); + currentLine = ""; + readyFormattedLine = ""; formattedLine = ""; currentChar = ' '; previousChar = ' '; previousCommandChar = ' '; previousNonWSChar = ' '; quoteChar = '"'; charNum = 0; + leadingSpaces = 0; + formattedLineCommentNum = 0; + preprocBracketTypeStackSize = 0; spacePadNum = 0; + nextLineSpacePadNum = 0; + currentLineFirstBracketNum = string::npos; previousReadyFormattedLineLength = string::npos; templateDepth = 0; + traceLineNumber = 0; + horstmannIndentChars = 0; + tabIncrementIn = 0; previousBracketType = NULL_TYPE; previousOperator = NULL; isVirgin = true; isInLineComment = false; isInComment = false; + noTrimCommentContinuation = false; isInPreprocessor = false; doesLineStartComment = false; + lineEndsInCommentOnly = false; + lineIsLineCommentOnly = false; + lineIsEmpty = false; + isImmediatelyPostCommentOnly = false; + isImmediatelyPostEmptyLine = false; isInQuote = false; + isInVerbatimQuote = false; + haveLineContinuationChar = false; + isInQuoteContinuation = false; isSpecialChar = false; - isNonParenHeader = true; + isNonParenHeader = false; foundNamespaceHeader = false; foundClassHeader = false; + foundStructHeader = false; + foundInterfaceHeader = false; foundPreDefinitionHeader = false; foundPreCommandHeader = false; foundCastOperator = false; foundQuestionMark = false; isInLineBreak = false; endOfCodeReached = false; + isInExecSQL = false; + isInAsm = false; + isInAsmOneLine = false; + isInAsmBlock = false; isLineReady = false; - isPreviousBracketBlockRelated = true; + isPreviousBracketBlockRelated = false; isInPotentialCalculation = false; shouldReparseCurrentChar = false; + needHeaderOpeningBracket = false; + shouldBreakLineAtNextChar = false; passedSemicolon = false; passedColon = false; + clearNonInStatement = false; isInTemplate = false; isInBlParen = false; - shouldBreakLineAfterComments = false; isImmediatelyPostComment = false; isImmediatelyPostLineComment = false; isImmediatelyPostEmptyBlock = false; isImmediatelyPostPreprocessor = false; - + isImmediatelyPostReturn = false; + isImmediatelyPostOperator = false; + isCharImmediatelyPostReturn = false; + isCharImmediatelyPostOperator = false; + isCharImmediatelyPostComment = false; + isPreviousCharPostComment = false; + isCharImmediatelyPostLineComment = false; + isCharImmediatelyPostOpenBlock = false; + isCharImmediatelyPostCloseBlock = false; + isCharImmediatelyPostTemplate = false; + breakCurrentOneLineBlock = false; + isInHorstmannRunIn = false; + currentLineBeginsWithBracket = false; isPrependPostBlockEmptyLineRequested = false; isAppendPostBlockEmptyLineRequested = false; prependEmptyLine = false; appendOpeningBracket = false; - foundClosingHeader = false; - previousReadyFormattedLineLength = 0; - isImmediatelyPostHeader = false; isInHeader = false; -#ifdef TRACEF - // fileName will be empty if ASTYLE_LIB is defined - if (fileName.empty()) - *traceOutF << "new file" << endl; - else - *traceOutF << fileName << endl; -#endif + isInCase = 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(); + + ASResource::buildHeaders(headers, getFileType()); + ASResource::buildNonParenHeaders(nonParenHeaders, getFileType()); + ASResource::buildPreDefinitionHeaders(preDefinitionHeaders, getFileType()); + ASResource::buildPreCommandHeaders(preCommandHeaders, getFileType()); + if (operators->size() == 0) + ASResource::buildOperators(operators); + if (assignmentOperators->size() == 0) + ASResource::buildAssignmentOperators(assignmentOperators); + if (castOperators->size() == 0) + ASResource::buildCastOperators(castOperators); +} + +/** + * set the variables for each preefined style. + * this will override any previous settings. + */ +void ASFormatter::fixOptionVariableConflicts() +{ + if (formattingStyle == STYLE_ALLMAN) + { + setBracketFormatMode(BREAK_MODE); + setBlockIndent(false); + setBracketIndent(false); + } + else if (formattingStyle == STYLE_JAVA) + { + setBracketFormatMode(ATTACH_MODE); + setBlockIndent(false); + setBracketIndent(false); + } + else if (formattingStyle == STYLE_KandR) + { + setBracketFormatMode(LINUX_MODE); + setBlockIndent(false); + setBracketIndent(false); + } + else if (formattingStyle == STYLE_STROUSTRUP) + { + setBracketFormatMode(STROUSTRUP_MODE); + setBlockIndent(false); + setBracketIndent(false); + if (!getIndentManuallySet()) + { + if (getIndentString() == "\t") + setTabIndentation(5, getForceTabIndentation()); + else + setSpaceIndentation(5); + } + } + else if (formattingStyle == STYLE_WHITESMITH) + { + setBracketFormatMode(BREAK_MODE); + setBlockIndent(false); + setBracketIndent(true); + setClassIndent(true); + setSwitchIndent(true); + } + else if (formattingStyle == STYLE_BANNER) + { + setBracketFormatMode(ATTACH_MODE); + setBlockIndent(false); + setBracketIndent(true); + setClassIndent(true); + setSwitchIndent(true); + } + else if (formattingStyle == STYLE_GNU) + { + setBracketFormatMode(BREAK_MODE); + setBlockIndent(true); + setBracketIndent(false); + if (!getIndentManuallySet()) + { + if (getIndentString() == "\t") + setTabIndentation(2, getForceTabIndentation()); + else + setSpaceIndentation(2); + } + } + else if (formattingStyle == STYLE_LINUX) + { + setBracketFormatMode(LINUX_MODE); + setBlockIndent(false); + setBracketIndent(false); + if (!getIndentManuallySet()) + { + if (getIndentString() == "\t") + setTabIndentation(8, getForceTabIndentation()); + else + setSpaceIndentation(8); + } + if (!getMinConditionalManuallySet()) + setMinConditionalIndentLength(getIndentLength() / 2); + } + else if (formattingStyle == STYLE_HORSTMANN) + { + setBracketFormatMode(HORSTMANN_MODE); + setBlockIndent(false); + setBracketIndent(false); + setSwitchIndent(true); + if (!getIndentManuallySet()) + { + if (getIndentString() == "\t") + setTabIndentation(3, getForceTabIndentation()); + else + setSpaceIndentation(3); + } + } + else if (formattingStyle == STYLE_1TBS) + { + setBracketFormatMode(LINUX_MODE); + setBlockIndent(false); + setBracketIndent(false); + setAddBracketsMode(true); + } + + // add-one-line-brackets implies keep-one-line-blocks + if (shouldAddOneLineBrackets) + setBreakOneLineBlocksMode(false); + // cannot have both indent-blocks and indent-brackets, default to indent-blocks + if (getBlockIndent()) + setBracketIndent(false); } /** @@ -289,99 +394,15 @@ string ASFormatter::nextLine() { - #define next \ - if(sourceIterator->hasMoreLines()) \ - { \ - ++inLineNumber ; \ - currentLine = sourceIterator->nextLine(); \ - spacePadNum = 0; \ - charNum = 0; \ - if(currentLine.size() == 0) \ - currentLine = " "; \ - \ - isInLineBreak = true; \ - isVirgin = false; \ - \ - if (isInLineComment) \ - isImmediatelyPostLineComment = true; \ - isInLineComment = false; \ - \ - isImmediatelyPostPreprocessor = isInPreprocessor; \ - if (previousNonWSChar != '\\') \ - isInPreprocessor = false; \ - currentChar = currentLine[charNum]; \ - shouldReparseCurrentChar = true; \ - isLineReady = false; \ - readyFormattedLine = ""; \ - for(int i = ret.size() - 1; i >= 0; --i) \ - { \ - if(!isWhiteSpace(ret[i])) \ - { \ - previousNonWSChar = ret[i]; \ - if (!isInComment && !isInLineComment && !isInQuote \ - && !isImmediatelyPostComment \ - && !isImmediatelyPostLineComment) \ - previousCommandChar = previousNonWSChar; \ - break; \ - } \ - } \ - if(ret.size()) \ - previousChar = ret[ret.size()-1]; \ - } \ - else \ - endOfCodeReached = true; - - if(ignoreStuff) - { - if(currentLine.substr(0, 14) == "\01!AS/Ignore\"!!") - { - ignoreStuff = false; - string ret; - ret = "#"; - if(KDevPG::globalSystem.lineNumberPolicy == KDevPG::World::CompatibilityLineNumbers) - ret += "line"; - ret += " "; - ret += to_string(inLineNumber+2); - ret += " \"" + fileName + "\""; - if(KDevPG::globalSystem.lineNumberPolicy == KDevPG::World::FullLineNumbers) - ret += " 2"; - --inLineNumber; - next - if(hasMoreLines()) - nextLine(); // there is a mysterious line, I have to eat - return ret; - } - else - { - string ret = currentLine; - next - return ret; - } - } - else if(currentLine.substr(0, 13) == "\01!ASIgnore\"!!") - { - ignoreStuff = true; - string ret; - if(KDevPG::globalSystem.lineNumberPolicy == KDevPG::World::FullLineNumbers) - { - ret = "# "; - ret += to_string(inLineNumber+4); - ret += " \"" + fileName + "\""; - } - next - return ret; - } - #undef next - - // these are reset with each new line const string *newHeader; bool isInVirginLine = isVirgin; isCharImmediatelyPostComment = false; isPreviousCharPostComment = false; isCharImmediatelyPostLineComment = false; isCharImmediatelyPostOpenBlock = false; isCharImmediatelyPostCloseBlock = false; isCharImmediatelyPostTemplate = false; + traceLineNumber++; while (!isLineReady) { @@ -394,139 +415,129 @@ } else // stuff to do when reading a new character... { - // make sure that a virgin '{' at the beginning ofthe file will be treated as a block... - if (isInVirginLine && currentChar == '{') + // make sure that a virgin '{' at the begining of the file will be treated as a block... + if (isInVirginLine && currentChar == '{' + && currentLineBeginsWithBracket // lineBeginsWith('{') + && previousCommandChar == ' ') previousCommandChar = '{'; + if (clearNonInStatement) + { + isNonInStatementArray = false; + clearNonInStatement = false; + } + if (isInHorstmannRunIn) + isInLineBreak = false; + if (!isWhiteSpace(currentChar)) + isInHorstmannRunIn = false; isPreviousCharPostComment = isCharImmediatelyPostComment; isCharImmediatelyPostComment = false; isCharImmediatelyPostTemplate = false; + isCharImmediatelyPostReturn = false; + isCharImmediatelyPostOperator = false; + isCharImmediatelyPostOpenBlock = false; + isCharImmediatelyPostCloseBlock = false; } - //if (inLineNumber >= 185) - // int x = 1; +// if (inLineNumber >= 7) +// int x = 1; - if (isInLineComment) + if (shouldBreakLineAtNextChar && !isWhiteSpace(currentChar)) { + isInLineBreak = true; + shouldBreakLineAtNextChar = false; + } + + if (isInExecSQL && !passedSemicolon) + { + if (currentChar == ';') + passedSemicolon = true; appendCurrentChar(); + continue; + } - // 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. - } + if (isInLineComment) + { + formatLineCommentBody(); continue; } else if (isInComment) { - if (isSequenceReached("*/")) - { - isInComment = false; - isImmediatelyPostComment = true; - appendSequence(AS_CLOSE_COMMENT); - goForward(1); - } - else - appendCurrentChar(); - + formatCommentBody(); continue; } // not in line comment or comment else if (isInQuote) { - if (isSpecialChar) - { - isSpecialChar = false; - appendCurrentChar(); - } - else if (currentChar == '\\') - { - isSpecialChar = true; - appendCurrentChar(); - } - else if (quoteChar == currentChar) - { - isInQuote = false; - appendCurrentChar(); - } - else - { - appendCurrentChar(); - } - + formatQuoteBody(); continue; } - // handle white space - needed to simplify the rest. - if (isWhiteSpace(currentChar) || isInPreprocessor) + if (isSequenceReached("//")) { - appendCurrentChar(); + formatLineCommentOpener(); continue; } - - /* not in MIDDLE of quote or comment or white-space of any type ... */ - - if (isSequenceReached("//")) + else if (isSequenceReached("/*")) { - if (currentLine[charNum+2] == '\xf2') // check for windows line marker - isAppendPostBlockEmptyLineRequested = false; - isInLineComment = true; - // do not indent if in column 1 or 2 - if (lineCommentNoIndent == false) - { - if (charNum == 0) - lineCommentNoIndent = true; - else if (charNum == 1 && currentLine[0] == ' ') - lineCommentNoIndent = true; - } - // move comment if spaces were added or deleted - if (lineCommentNoIndent == false && spacePadNum != 0) - adjustComments(); - formattedLineCommentNum = formattedLine.length(); - appendSequence(AS_OPEN_LINE_COMMENT); - goForward(1); - // explicitly break a line when a line comment's end is found. - if (charNum + 1 == (int) currentLine.length()) + formatCommentOpener(); + continue; + } + else if (currentChar == '"' || currentChar == '\'') + { + formatQuoteOpener(); + continue; + } + // treat these preprocessor statements as a line comment + else if (currentChar =='#') + { + if (isSequenceReached("#region") + || isSequenceReached("#endregion") + || isSequenceReached("#error") + || isSequenceReached("#warning")) { - isInLineBreak = true; - isInLineComment = false; - isImmediatelyPostLineComment = true; - currentChar = 0; //make sure it is a neutral char. + // check for horstmann run-in + if (formattedLine[0] == '{') + { + isInLineBreak = true; + isInHorstmannRunIn = false; + } + isInLineComment = true; + appendCurrentChar(); + continue; } - continue; } - else if (isSequenceReached("/*")) + + if (isInPreprocessor) { - isInComment = true; - if (spacePadNum != 0) - adjustComments(); - formattedLineCommentNum = formattedLine.length(); - appendSequence(AS_OPEN_COMMENT); - goForward(1); + appendCurrentChar(); continue; } - else if (currentChar == '"' || currentChar == '\'') + + // handle white space - needed to simplify the rest. + if (isWhiteSpace(currentChar)) { - isInQuote = true; - quoteChar = currentChar; appendCurrentChar(); continue; } - /* not in quote or comment or white-space of any type ... */ + /* 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 + // ** isInPreprocessor will be automatically reset at the begining // of a new line in getnextChar() if (currentChar == '#') { isInPreprocessor = true; - appendCurrentChar(); - continue; + // check for horstmann run-in + if (formattedLine[0] == '{') + { + isInLineBreak = true; + isInHorstmannRunIn = false; + } + processPreprocessor(); + // need to fall thru here to reset the variables } /* not in preprocessor ... */ @@ -543,18 +554,33 @@ isCharImmediatelyPostLineComment = true; } - if (shouldBreakLineAfterComments) + if (isImmediatelyPostReturn) { - shouldBreakLineAfterComments = false; - shouldReparseCurrentChar = true; - breakLine(); - continue; + isImmediatelyPostReturn = false; + isCharImmediatelyPostReturn = true; + } + + if (isImmediatelyPostOperator) + { + isImmediatelyPostOperator = false; + isCharImmediatelyPostOperator = true; } // reset isImmediatelyPostHeader information if (isImmediatelyPostHeader) { - isImmediatelyPostHeader = false; + // should brackets be added + if (currentChar != '{' && shouldAddBrackets) + { + bool bracketsAdded = addBracketsToStatement(); + if (bracketsAdded && !shouldAddOneLineBrackets) + { + size_t firstText = currentLine.find_first_not_of(" \t"); + assert(firstText != string::npos); + if ((int) firstText == charNum) + breakCurrentOneLineBlock = true; + } + } // Make sure headers are broken from their succeeding blocks // (e.g. @@ -564,51 +590,56 @@ // DoBar; // ) // But treat else if() as a special case which should not be broken! - if (shouldBreakOneLineStatements) + if (shouldBreakOneLineStatements + && isOkToBreakBlock(bracketTypeStack->back())) { // if may break 'else if()'s, then simply break the line - if (shouldBreakElseIfs) isInLineBreak = true; } + + isImmediatelyPostHeader = false; } - if (passedSemicolon) // need to break the formattedLine + if (passedSemicolon) // need to break the formattedLine { passedSemicolon = false; if (parenStack->back() == 0 && currentChar != ';') // allow ;; { // does a one-line statement have ending comments? - if (IS_A(bracketTypeStack->back(), SINGLE_LINE_TYPE)) + if (isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)) { size_t blockEnd = currentLine.rfind(AS_CLOSE_BRACKET); assert(blockEnd != string::npos); // move ending comments to this formattedLine - if (isBeforeLineEndComment(blockEnd)) + if (isBeforeAnyLineEndComment(blockEnd)) { size_t commentStart = currentLine.find_first_not_of(" \t", blockEnd + 1); assert(commentStart != string::npos); assert((currentLine.compare(commentStart, 2, "//") == 0) || (currentLine.compare(commentStart, 2, "/*") == 0)); size_t commentLength = currentLine.length() - commentStart; - int tabCount = getIndentLength(); - appendSpacePad(); - for (int i=1; iback() == 0 && !isBeforeComment()) + if (parenStack->back() == 0 && !isBeforeAnyComment()) { shouldReparseCurrentChar = true; isInLineBreak = true; @@ -622,19 +653,18 @@ { int maxTemplateDepth = 0; templateDepth = 0; - const string *oper; for (size_t i = charNum; i < currentLine.length(); - i += (oper ? oper->length() : 1)) + i++) { - oper = ASBeautifier::findHeader(currentLine, i, operators); + char currentChar = currentLine[i]; - if (oper == &AS_LS) + if (currentChar == '<') { templateDepth++; maxTemplateDepth++; } - else if (oper == &AS_GR) + else if (currentChar == '>') { templateDepth--; if (templateDepth == 0) @@ -645,14 +675,25 @@ break; } } - else if (oper == &AS_COMMA // comma, e.g. A - || oper == &AS_BIT_AND // reference, e.g. A - || oper == &AS_MULT // pointer, e.g. A - || oper == &AS_COLON_COLON) // ::, e.g. std::string + else if (currentLine.compare(i, 2, "&&") == 0 + || currentLine.compare(i, 2, "||") == 0) + { + // this is not a template -> leave... + isInTemplate = false; + break; + } + else if (currentChar == ',' // comma, e.g. A + || currentChar == '&' // reference, e.g. A + || currentChar == '*' // pointer, e.g. A + || currentChar == ':' // ::, e.g. std::string + || currentChar == '[' // [] e.g. string[] + || currentChar == ']' // [] e.g. string[] + || currentChar == '(' // (...) e.g. function definition + || currentChar == ')') // (...) e.g. function definition { continue; } - else if (!isLegalNameChar(currentLine[i]) && !isWhiteSpace(currentLine[i])) + else if (!isLegalNameChar(currentChar) && !isWhiteSpace(currentChar)) { // this is not a template -> leave... isInTemplate = false; @@ -690,48 +731,75 @@ if (currentChar == ']') isInBlParen = false; if (currentChar == ')') + { foundCastOperator = false; + if (parenStack->back() == 0) + isInAsm = false; + } } // handle brackets if (currentChar == '{' || currentChar == '}') { - if (currentChar == '{') + // if appendOpeningBracket this was already done for the original bracket + if (currentChar == '{' && !appendOpeningBracket) { BracketType newBracketType = getBracketType(); foundNamespaceHeader = false; foundClassHeader = false; + foundStructHeader = false; + foundInterfaceHeader = false; foundPreDefinitionHeader = false; foundPreCommandHeader = false; isInPotentialCalculation = false; + isJavaStaticConstructor = false; + needHeaderOpeningBracket = false; + isPreviousBracketBlockRelated = !isBracketType(newBracketType, ARRAY_TYPE); bracketTypeStack->push_back(newBracketType); preBracketHeaderStack->push_back(currentHeader); currentHeader = NULL; - - isPreviousBracketBlockRelated = !IS_A(newBracketType, ARRAY_TYPE); + structStack->push_back(isInIndentableStruct); + if (isBracketType(newBracketType, STRUCT_TYPE) && isCStyle()) + isInIndentableStruct = isStructAccessModified(currentLine, charNum); + else + isInIndentableStruct = false; } // this must be done before the bracketTypeStack is popped BracketType bracketType = bracketTypeStack->back(); - bool isOpeningArrayBracket = (IS_A(bracketType, ARRAY_TYPE) + bool isOpeningArrayBracket = (isBracketType(bracketType, ARRAY_TYPE) && bracketTypeStack->size() >= 2 - && !IS_A((*bracketTypeStack)[bracketTypeStack->size()-2], ARRAY_TYPE) + && !isBracketType((*bracketTypeStack)[bracketTypeStack->size()-2], ARRAY_TYPE) ); if (currentChar == '}') { // if a request has been made to append a post block empty line, // but the block exists immediately before a closing bracket, - // then there is not need for the post block empty line. - // + // then there is no need for the post block empty line. isAppendPostBlockEmptyLineRequested = false; - - if (!bracketTypeStack->empty()) + breakCurrentOneLineBlock = false; + isInAsmBlock = false; + + // added for release 1.24 + // TODO: remove at the appropriate time + assert(isInAsm == false); + assert(isInAsmOneLine == false); + assert(isInQuote == false); + isInAsm = isInAsmOneLine = isInQuote = false; + // end remove + + if (bracketTypeStack->size() > 1) { previousBracketType = bracketTypeStack->back(); bracketTypeStack->pop_back(); - isPreviousBracketBlockRelated = !IS_A(bracketType, ARRAY_TYPE); + isPreviousBracketBlockRelated = !isBracketType(bracketType, ARRAY_TYPE); + } + else + { + previousBracketType = NULL_TYPE; + isPreviousBracketBlockRelated = false; } if (!preBracketHeaderStack->empty()) @@ -741,139 +809,193 @@ } else currentHeader = NULL; + + if (!structStack->empty()) + { + isInIndentableStruct = structStack->back(); + structStack->pop_back(); + } + else + isInIndentableStruct = false; + + if (isBracketType(bracketType, ARRAY_NIS_TYPE) && !isBracketType(bracketType, SINGLE_LINE_TYPE)) + clearNonInStatement = true; } // format brackets - if (IS_A(bracketType, ARRAY_TYPE)) + appendOpeningBracket = false; + if (isBracketType(bracketType, ARRAY_TYPE)) + { formatArrayBrackets(bracketType, isOpeningArrayBracket); + } else - formatBrackets(bracketType); + { + if (currentChar == '{') + formatOpeningBracket(bracketType); + else + formatClosingBracket(bracketType); + } continue; } - if (((previousCommandChar == '{' && isPreviousBracketBlockRelated) + if ((((previousCommandChar == '{' && isPreviousBracketBlockRelated) || ((previousCommandChar == '}' - && bracketFormatMode != NONE_MODE - && !isImmediatelyPostEmptyBlock - && isPreviousBracketBlockRelated - && !isPreviousCharPostComment // Fixes wrongly appended newlines after '}' immediately after comments - && peekNextChar() != ' ' - && !IS_A(previousBracketType, DEFINITION_TYPE) - && !(ASBeautifier::isJavaStyle && currentChar == ')')) - && !IS_A(bracketTypeStack->back(), DEFINITION_TYPE))) - && (shouldBreakOneLineBlocks - || !IS_A(bracketTypeStack->back(), SINGLE_LINE_TYPE))) + && !isImmediatelyPostEmptyBlock + && isPreviousBracketBlockRelated + && !isPreviousCharPostComment // Fixes wrongly appended newlines after '}' immediately after comments + && peekNextChar() != ' ' + && !isBracketType(previousBracketType, DEFINITION_TYPE)) + && !isBracketType(bracketTypeStack->back(), DEFINITION_TYPE))) + && isOkToBreakBlock(bracketTypeStack->back())) + // check for array + || (isBracketType(bracketTypeStack->back(), ARRAY_TYPE) + && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE) + && isNonInStatementArray)) { isCharImmediatelyPostOpenBlock = (previousCommandChar == '{'); isCharImmediatelyPostCloseBlock = (previousCommandChar == '}'); - //if (bracketFormatMode != NONE_MODE) - //{ - previousCommandChar = ' '; - isInLineBreak = true; - //} + if (isCharImmediatelyPostOpenBlock + && !isCharImmediatelyPostComment + && !isCharImmediatelyPostLineComment) + { + previousCommandChar = ' '; + + if (bracketFormatMode == NONE_MODE) + { + if (shouldBreakOneLineBlocks + && isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)) + isInLineBreak = true; + else if (currentLineBeginsWithBracket) + formatRunIn(); + else + breakLine(); + } + else if (bracketFormatMode == HORSTMANN_MODE + && currentChar != '#') + formatRunIn(); + else + isInLineBreak = true; + } + else if (isCharImmediatelyPostCloseBlock + && shouldBreakOneLineStatements + && (isLegalNameChar(currentChar) && currentChar != '.') + && !isCharImmediatelyPostComment) + { + previousCommandChar = ' '; + isInLineBreak = true; + } } // reset block handling flags isImmediatelyPostEmptyBlock = false; // look for headers - if (!isInTemplate) + bool isPotentialHeader = isCharPotentialHeader(currentLine, charNum); + + if (isPotentialHeader && !isInTemplate) { - if ((newHeader = findHeader(headers)) != NULL) + isNonParenHeader = false; + foundClosingHeader = false; + newHeader = findHeader(headers); + + if (newHeader != NULL) + { + char peekChar = ASBase::peekNextChar(currentLine, charNum + newHeader->length() - 1); + + // is not a header if part of a definition + if (peekChar == ',' || peekChar == ')') + newHeader = NULL; + // the following accessor definitions are NOT headers + // goto default; is NOT a header + else if ((newHeader == &AS_GET || newHeader == &AS_SET || newHeader == &AS_DEFAULT) + && peekChar == ';') + { + newHeader = NULL; + } + } + + if (newHeader != NULL) { - foundClosingHeader = false; const string *previousHeader; // recognize closing headers of do..while, if..else, try..catch..finally if ((newHeader == &AS_ELSE && currentHeader == &AS_IF) || (newHeader == &AS_WHILE && currentHeader == &AS_DO) || (newHeader == &AS_CATCH && currentHeader == &AS_TRY) || (newHeader == &AS_CATCH && currentHeader == &AS_CATCH) || (newHeader == &AS_FINALLY && currentHeader == &AS_TRY) - || (newHeader == &AS_FINALLY && currentHeader == &AS_CATCH)) + || (newHeader == &AS_FINALLY && currentHeader == &AS_CATCH) + || (newHeader == &AS_SET && currentHeader == &AS_GET) + || (newHeader == &AS_REMOVE && currentHeader == &AS_ADD)) foundClosingHeader = true; previousHeader = currentHeader; currentHeader = newHeader; + needHeaderOpeningBracket = true; - // If in ATTACH or LINUX bracket modes, attach closing headers (e.g. 'else', 'catch') - // to their preceding bracket, - // But do not perform the attachment if the shouldBreakClosingHeaderBrackets is set! - if (!shouldBreakClosingHeaderBrackets - && foundClosingHeader - && (bracketFormatMode == ATTACH_MODE || bracketFormatMode == BDAC_MODE) - && (shouldBreakOneLineBlocks || !IS_A(previousBracketType, SINGLE_LINE_TYPE)) - && previousNonWSChar == '}') + if (foundClosingHeader && previousNonWSChar == '}') { - spacePadNum = 0; // don't count as padding - - size_t firstChar = formattedLine.find_first_not_of(" \t"); - if (firstChar != string::npos) // if a blank line does not preceed this - { - isInLineBreak = false; - appendSpacePad(); - } - - if (shouldBreakBlocks) - isAppendPostBlockEmptyLineRequested = false; + if (isOkToBreakBlock(bracketTypeStack->back())) + isLineBreakBeforeClosingHeader(); + + // get the adjustment for a comment following the closing header + if (isInLineBreak) + nextLineSpacePadNum = getNextLineCommentAdjustment(); + else + spacePadNum = getCurrentLineCommentAdjustment(); } - // If NONE bracket mode, leave closing headers as they are (e.g. 'else', 'catch') - if (foundClosingHeader && bracketFormatMode == NONE_MODE && previousCommandChar == '}') + // check if the found header is non-paren header + isNonParenHeader = findHeader(nonParenHeaders) != NULL; + + // join 'else if' statements + if (currentHeader == &AS_IF && previousHeader == &AS_ELSE && isInLineBreak + && !shouldBreakElseIfs && !isCharImmediatelyPostLineComment) { - if (lineBeginsWith('}')) // is closing bracket broken? + // 'else' must be last thing on the line, but must not be #else + size_t start = formattedLine.length() >= 6 ? formattedLine.length()-6 : 0; + if (formattedLine.find("else", start) != string::npos + && formattedLine.find("#else", start) == string::npos) { - isInLineBreak = false; appendSpacePad(); + isInLineBreak = false; } - - if (shouldBreakBlocks) - isAppendPostBlockEmptyLineRequested = false; } - if (foundClosingHeader && bracketFormatMode == BREAK_MODE && previousCommandChar == '}') - breakLine(); - - //Check if a template definition as been reached, e.g. template - //if (newHeader == &AS_TEMPLATE) - //{ - // isInTemplate = true; - //} - - // check if the found header is non-paren header - isNonParenHeader = (find(nonParenHeaders.begin(), nonParenHeaders.end(), - newHeader) != nonParenHeaders.end()); - 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 - if (!isNonParenHeader && charNum < (int) currentLine.length() && !isWhiteSpace(currentLine[charNum+1])) + // in C# 'catch' can be either a paren or non-paren header + if (shouldPadHeader + && (!isNonParenHeader || (currentHeader == &AS_CATCH && peekNextChar() == '(')) + && charNum < (int) currentLine.length() && !isWhiteSpace(currentLine[charNum+1])) appendSpacePad(); // Signal that a header has been reached // *** But treat a closing while() (as in do...while) - // as if it where NOT a header since a closing while() + // as if it were NOT a header since a closing while() // should never have a block after it! if (!(foundClosingHeader && currentHeader == &AS_WHILE)) { isInHeader = true; - if (isNonParenHeader) + + // in C# 'catch' and 'delegate' can be a paren or non-paren header + if (isNonParenHeader && !isSharpStyleWithParen(currentHeader)) { isImmediatelyPostHeader = true; isInHeader = false; } } - if (currentHeader == &AS_IF && previousHeader == &AS_ELSE) - isInLineBreak = false; - - if (shouldBreakBlocks) + if (shouldBreakBlocks + && isOkToBreakBlock(bracketTypeStack->back())) { if (previousHeader == NULL && !foundClosingHeader - && !isCharImmediatelyPostOpenBlock) + && !isCharImmediatelyPostOpenBlock + && !isImmediatelyPostCommentOnly) { isPrependPostBlockEmptyLineRequested = true; } @@ -887,7 +1009,9 @@ } if (shouldBreakClosingHeaderBlocks - && isCharImmediatelyPostCloseBlock) + && isCharImmediatelyPostCloseBlock + && !isImmediatelyPostCommentOnly + && currentHeader != &AS_WHILE) // closing do-while block { isPrependPostBlockEmptyLineRequested = true; } @@ -903,20 +1027,19 @@ foundNamespaceHeader = true; if (newHeader == &AS_CLASS) foundClassHeader = true; + if (newHeader == &AS_STRUCT) + foundStructHeader = true; + if (newHeader == &AS_INTERFACE) + foundInterfaceHeader = true; foundPreDefinitionHeader = true; appendSequence(*newHeader); goForward(newHeader->length() - 1); - if (shouldBreakBlocks) - isPrependPostBlockEmptyLineRequested = true; - continue; } else if ((newHeader = findHeader(preCommandHeaders)) != NULL) { - if (ASBeautifier::isJavaStyle - || (*newHeader == AS_CONST && previousCommandChar == ')') // 'const' member functions is a command bracket - || *newHeader == AS_EXTERN) + if (!(*newHeader == AS_CONST && previousCommandChar != ')')) // 'const' member functions is a command bracket foundPreCommandHeader = true; appendSequence(*newHeader); goForward(newHeader->length() - 1); @@ -928,89 +1051,221 @@ 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 (previousNonWSChar == '}' || currentChar == ';') { - if (shouldBreakOneLineStatements && currentChar == ';' - && (shouldBreakOneLineBlocks || !IS_A(bracketTypeStack->back(), SINGLE_LINE_TYPE)) - //&& (! bracketFormatMode == NONE_MODE) - ) + if (currentChar == ';') { - passedSemicolon = true; - } + if ((shouldBreakOneLineStatements + || isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)) + && isOkToBreakBlock(bracketTypeStack->back())) + { + passedSemicolon = true; + } - if (shouldBreakBlocks && currentHeader != NULL && parenStack->back() == 0) - { - isAppendPostBlockEmptyLineRequested = true; + // append post block empty line for unbracketed header + if (shouldBreakBlocks && currentHeader != NULL && parenStack->back() == 0) + { + isAppendPostBlockEmptyLineRequested = true; + } } - if (currentChar != ';') + // end of block if a closing bracket was found + // or an opening bracket was not found (';' closes) + if (currentChar != ';' + || (needHeaderOpeningBracket && parenStack->back() == 0)) currentHeader = NULL; foundQuestionMark = false; foundNamespaceHeader = false; foundClassHeader = false; + foundStructHeader = false; + foundInterfaceHeader = false; foundPreDefinitionHeader = false; foundPreCommandHeader = false; foundCastOperator = false; isInPotentialCalculation = false; - isNonInStatementArray = false; + isSharpAccessor = false; + isSharpDelegate = false; + isInExtern = false; + nonInStatementBracket = 0; } - if (currentChar == ':' - && shouldBreakOneLineStatements - && !foundQuestionMark // not in a ... ? ... : ... sequence - && !foundPreDefinitionHeader // not in a definition block (e.g. class foo : public bar - && previousCommandChar != ')' // not immediately after closing paren of a method header, e.g. ASFormatter::ASFormatter(...) : ASBeautifier(...) - && previousChar != ':' // not part of '::' - && peekNextChar() != ':') // not part of '::' + if (currentChar == ':' && shouldBreakOneLineStatements) { - passedColon = true; - if (shouldBreakBlocks) - isPrependPostBlockEmptyLineRequested = true; + if (isInCase + && previousChar != ':' // not part of '::' + && peekNextChar() != ':') // not part of '::' + { + isInCase = false; + passedColon = true; + } + else if (isCStyle() // for C/C++ only + && !foundQuestionMark // not in a ... ? ... : ... sequence + && !foundPreDefinitionHeader // not in a definition block (e.g. class foo : public bar + && previousCommandChar != ')' // not immediately after closing paren of a method header, e.g. ASFormatter::ASFormatter(...) : ASBeautifier(...) + && previousChar != ':' // not part of '::' + && peekNextChar() != ':' // not part of '::' + && !isdigit(peekNextChar()) // not a bit field + && !isInAsm // not in extended assembler + && !isInAsmOneLine // not in extended assembler + && !isInAsmBlock) // not in extended assembler + { + passedColon = true; + } } if (currentChar == '?') foundQuestionMark = true; - // determine if this is a potential calculation - newHeader = findHeader(operators); - - if (newHeader != NULL) + if (isPotentialHeader && !isInTemplate) { - if (!isInPotentialCalculation) + if (findKeyword(currentLine, charNum, AS_CASE) + || findKeyword(currentLine, charNum, AS_DEFAULT)) + isInCase = true; + + if (findKeyword(currentLine, charNum, AS_NEW)) + isInPotentialCalculation = false; + + if (findKeyword(currentLine, charNum, AS_RETURN)) { - if (find(assignmentOperators.begin(), assignmentOperators.end(), newHeader) - != assignmentOperators.end()) - { - char peekedChar = peekNextChar(); - isInPotentialCalculation = (newHeader != &AS_RETURN - && !(newHeader == &AS_EQUAL && peekedChar == '*') - && !(newHeader == &AS_EQUAL && peekedChar == '&')); - } + isInPotentialCalculation = true; // return is the same as an = sign + isImmediatelyPostReturn = true; + } + + if (findKeyword(currentLine, charNum, AS_OPERATOR)) + isImmediatelyPostOperator = true; + + if (isCStyle() && findKeyword(currentLine, charNum, AS_EXTERN)) + isInExtern = true; + + if (isCStyle() && isExecSQL(currentLine, charNum)) + isInExecSQL = true; + + if (isCStyle()) + { + if (findKeyword(currentLine, charNum, AS_ASM) + || findKeyword(currentLine, charNum, AS__ASM__)) + { + isInAsm = true; + } + else if (findKeyword(currentLine, charNum, AS_MS_ASM) // microsoft specific + || findKeyword(currentLine, charNum, AS_MS__ASM)) + { + int index = 4; + if (peekNextChar() == '_') // check for __asm + index = 5; + + char peekedChar = ASBase::peekNextChar(currentLine, charNum + index); + if (peekedChar == '{' || peekedChar == ' ') + isInAsmBlock = true; + else + isInAsmOneLine = true; + } + } + + if (isJavaStyle() + && (findKeyword(currentLine, charNum, AS_STATIC) + && isNextCharOpeningBracket(charNum + 6))) + isJavaStaticConstructor = true; + + if (isSharpStyle() + && (findKeyword(currentLine, charNum, AS_DELEGATE) + || findKeyword(currentLine, charNum, AS_UNCHECKED))) + isSharpDelegate = true; + + // append the entire name + string name = getCurrentWord(currentLine, charNum); + appendSequence(name); + goForward(name.length() - 1); + + continue; + + } // (isPotentialHeader && !isInTemplate) + + // determine if this is a potential calculation + + bool isPotentialOperator = isCharPotentialOperator(currentChar); + newHeader = NULL; + + if (isPotentialOperator) + { + newHeader = findOperator(operators); + + if (newHeader != NULL) + { + // 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()) + { + char peekedChar = peekNextChar(); + isInPotentialCalculation = (!(newHeader == &AS_EQUAL && peekedChar == '*') + && !(newHeader == &AS_EQUAL && peekedChar == '&')); + } + } } } - else + + // process pointers and references + // check new header to elimnate things like '&&' sequence + if (isCStyle() + && (newHeader == &AS_MULT || newHeader == &AS_BIT_AND) + && isPointerOrReference() + && !isDereferenceOrAddressOf()) { - // the following are not calculations - if (currentLine.compare(charNum, 3, "new") == 0 && !isLegalNameChar(currentLine[charNum+3])) - isInPotentialCalculation = false; + formatPointerOrReference(); + continue; } if (shouldPadOperators && newHeader != NULL) { padOperators(newHeader); continue; } + // pad commas and semi-colons + if (currentChar == ';' + || (currentChar == ',' && shouldPadOperators)) + { + char nextChar = ' '; + if (charNum + 1 < (int) currentLine.length()) + nextChar = currentLine[charNum+1]; + if (!isWhiteSpace(nextChar) + && nextChar != '}' + && nextChar != ')' + && nextChar != ']' + && nextChar != '>' + && nextChar != ';' + && !isBeforeAnyComment() + /* && !(isBracketType(bracketTypeStack->back(), ARRAY_TYPE)) */ + ) + { + appendCurrentChar(); + appendSpaceAfter(); + continue; + } + } + if ((shouldPadParensOutside || shouldPadParensInside || shouldUnPadParens) && (currentChar == '(' || currentChar == ')')) { @@ -1030,48 +1285,89 @@ && readyFormattedLineLength > 0 && previousReadyFormattedLineLength > 0) { - isLineReady = true; // signal that a readyFormattedLine is still waiting + isLineReady = true; // signal a waiting readyFormattedLine beautifiedLine = beautify(""); previousReadyFormattedLineLength = 0; } - else // format the current formatted line + else // format the current formatted line { isLineReady = false; + horstmannIndentInStatement = horstmannIndentChars; beautifiedLine = beautify(readyFormattedLine); previousReadyFormattedLineLength = readyFormattedLineLength; + // the enhancer is not called for new empty lines + // or no-indent line comments + if (!lineCommentNoBeautify) + enhancer->enhance(beautifiedLine, isInBeautifySQL); + horstmannIndentChars = 0; lineCommentNoBeautify = lineCommentNoIndent; lineCommentNoIndent = false; - if (appendOpeningBracket) // insert bracket after this formatted line - { - appendOpeningBracket = false; - isLineReady = true; // signal that a readyFormattedLine is still waiting - readyFormattedLine = "{"; - isPrependPostBlockEmptyLineRequested = false; // next line should not be empty - } + isInBeautifySQL = isInExecSQL; } prependEmptyLine = false; - enhance(beautifiedLine); // call the enhancer function return beautifiedLine; } /** -* check if there are any indented lines ready to be read by nextLine() -* -* @return are there any indented lines ready? -*/ + * check if there are any indented lines ready to be read by nextLine() + * + * @return are there any indented lines ready? + */ bool ASFormatter::hasMoreLines() const { return !endOfCodeReached; } /** + * comparison function for BracketType enum + */ +bool ASFormatter::isBracketType(BracketType a, BracketType b) const +{ + return ((a & b) == b); +} + +/** + * set the formatting style. + * + * @param mode the formatting style. + */ +void ASFormatter::setFormattingStyle(FormatStyle style) +{ + formattingStyle = style; +} + +/** + * set the add brackets mode. + * options: + * true brackets added to headers for single line statements. + * false brackets NOT added to headers for single line statements. + * + * @param mode the bracket formatting mode. + */ +void ASFormatter::setAddBracketsMode(bool state) +{ + shouldAddBrackets = state; +} + +/** + * set the add one line brackets mode. + * options: + * true one line brackets added to headers for single line statements. + * false one line brackets NOT added to headers for single line statements. + * + * @param mode the bracket formatting mode. + */ +void ASFormatter::setAddOneLineBracketsMode(bool state) +{ + shouldAddBrackets = state; + shouldAddOneLineBrackets = state; +} + +/** * set the bracket formatting mode. * options: - * astyle::NONE_MODE no formatting of brackets. - * astyle::ATTACH_MODE Java, K&R style bracket placement. - * astyle::BREAK_MODE ANSI C/C++ style bracket placement. * * @param mode the bracket formatting mode. */ @@ -1121,39 +1417,52 @@ } /** -* set parenthesis outside padding mode. -* options: -* true statement parenthesiss will be padded with spaces around them. -* false statement parenthesiss will not be padded. -* -* @param state the padding mode. -*/ + * set parenthesis outside padding mode. + * options: + * true statement parenthesiss will be padded with spaces around them. + * false statement parenthesiss 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. -*/ + * 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 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. -*/ + * 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; @@ -1189,6 +1498,25 @@ 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. @@ -1211,6 +1539,27 @@ } /** + * set option to delete empty lines. + * + * @param state true = delete, false = don't delete. + */ +void ASFormatter::setDeleteEmptyLinesMode(bool state) +{ + shouldDeleteEmptyLines = state; +} + +/** + * set the pointer alignment. + * options: + * + * @param alignment the pointer alignment. + */ +void ASFormatter::setPointerAlignment(PointerAlign alignment) +{ + pointerAlignment = alignment; +} + +/** * jump over several characters. * * @param i the number of characters to jump over. @@ -1222,10 +1571,10 @@ } /** -* peek at the next unread character. -* -* @return the next unread character. -*/ + * peek at the next unread character. + * + * @return the next unread character. + */ char ASFormatter::peekNextChar() const { char ch = ' '; @@ -1236,38 +1585,53 @@ ch = currentLine[peekNum]; -// if (shouldConvertTabs && ch == '\t') -// ch = ' '; - return ch; } /** -* check if current placement is before a comment or line-comment -* -* @return is before a comment or line-comment. -*/ + * 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::isBeforeLineEndComment(int startPos) const + * 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); @@ -1281,20 +1645,51 @@ // comment must be closed on this line with nothing after it size_t endNum = currentLine.find("*/", peekNum + 2); if (endNum != string::npos) - if (currentLine.find_first_not_of(" \t", endNum + 2) == 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. -*/ + * get the next character, increasing the current placement in the process. + * the new character is inserted into the variable currentChar. + * + * @return whether succeded to recieve the new character. + */ bool ASFormatter::getNextChar() { isInLineBreak = false; @@ -1306,105 +1701,210 @@ if (!isInComment && !isInLineComment && !isInQuote && !isImmediatelyPostComment && !isImmediatelyPostLineComment + && !isInPreprocessor && !isSequenceReached("/*") && !isSequenceReached("//")) - previousCommandChar = previousNonWSChar; + previousCommandChar = currentChar; } - int currentLineLength = currentLine.length(); - - if (charNum + 1 < currentLineLength + if (charNum + 1 < (int) currentLine.length() && (!isWhiteSpace(peekNextChar()) || isInComment || isInLineComment)) { currentChar = currentLine[++charNum]; if (shouldConvertTabs && currentChar == '\t') - currentChar = ' '; + convertTabToSpaces(); return true; } - else // end of line has been reached - { - if (sourceIterator->hasMoreLines()) - { - currentLine = sourceIterator->nextLine(); - spacePadNum = 0; - - if (currentLine.length() == 0) - { - currentLine = string(" "); // a null is inserted if this is not done - } - - // unless reading in the first line of the file, - // break a new line. - if (!isVirgin) - isInLineBreak = true; - else - isVirgin = false; - - if (isInLineComment) - isImmediatelyPostLineComment = true; - isInLineComment = false; - - // check if is in preprocessor before line trimming - isImmediatelyPostPreprocessor = isInPreprocessor; - if (previousNonWSChar != '\\') - isInPreprocessor = false; - trimNewLine(); - currentChar = currentLine[charNum]; - - if (shouldConvertTabs && currentChar == '\t') - currentChar = ' '; + // end of line has been reached + return getNextLine(); +} - return true; +/** + * get the next line of input, increasing the current placement in the process. + * + * @param sequence the sequence to append. + * @return whether succeded in reading the next line. + */ +bool ASFormatter::getNextLine(bool emptyLineWasDeleted /*false*/) +{ + if (sourceIterator->hasMoreLines()) + { + if (appendOpeningBracket) + currentLine = "{"; // append bracket that was removed from the previous line + else + currentLine = sourceIterator->nextLine(emptyLineWasDeleted); + // reset variables for new line + inLineNumber++; + isInCase = false; + isInAsmOneLine = false; + isInQuoteContinuation = isInVerbatimQuote | haveLineContinuationChar; + haveLineContinuationChar= false; + isImmediatelyPostEmptyLine = lineIsEmpty; + previousChar = ' '; + + if (currentLine.length() == 0) + { + currentLine = string(" "); // a null is inserted if this is not done } + + // unless reading in the first line of the file, break a new line. + if (!isVirgin) + isInLineBreak = true; else + isVirgin = false; + + // check if is in preprocessor before line trimming + // a blank line after a \ will remove the flag + isImmediatelyPostPreprocessor = isInPreprocessor; + if (previousNonWSChar != '\\' + || isEmptyLine(currentLine)) + isInPreprocessor = false; + + if (passedSemicolon) + isInExecSQL = false; + initNewLine(); + currentChar = currentLine[charNum]; + if (isInHorstmannRunIn && previousNonWSChar == '{') + isInLineBreak = false; + isInHorstmannRunIn = false; + + if (shouldConvertTabs && currentChar == '\t') + convertTabToSpaces(); + + // check for an empty line inside a command bracket. + // if yes then read the next line (calls getNextLine recursively). + // must be after initNewLine. + if (shouldDeleteEmptyLines + && lineIsEmpty + && isBracketType((*bracketTypeStack)[bracketTypeStack->size()-1], COMMAND_TYPE)) { - endOfCodeReached = true; - return false; + // but do NOT delete an empty line between comments if blocks are being broken + if (!(shouldBreakBlocks || shouldBreakClosingHeaderBlocks) + || !isImmediatelyPostCommentOnly + || !commentAndHeaderFollows()) + { + isInPreprocessor = isImmediatelyPostPreprocessor; // restore + lineIsEmpty = false; + return getNextLine(true); + } } + + return true; + } + else + { + endOfCodeReached = true; + return false; } } /** -* jump over the leading white space in the current line, -* IF the line does not begin a comment or is in a preprocessor definition. -*/ -void ASFormatter::trimNewLine() + * 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() { - int len = currentLine.length(); + size_t len = currentLine.length(); + size_t indent = getIndentLength(); charNum = 0; - if (isInComment || isInPreprocessor) + if (isInPreprocessor || isInQuoteContinuation) + 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 = indent - ((tabCount + i) % indent); + currentLine.replace(i, 1, numSpaces, ' '); + tabCount++; + i += indent - 1; + } + } + // correct the format if EXEC SQL is not a hanging indent + if (i < leadingSpaces) + currentLine.insert((size_t)0, leadingSpaces - i, ' '); + trimContinuationLine(); return; + } - while (isWhiteSpace(currentLine[charNum]) && charNum + 1 < len) - ++charNum; + // 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; + lineIsLineCommentOnly = false; + lineEndsInCommentOnly = false; doesLineStartComment = false; + currentLineBeginsWithBracket = false; + lineIsEmpty = false; + currentLineFirstBracketNum = string::npos; + tabIncrementIn = 0; + + for (charNum = 0; isWhiteSpace(currentLine[charNum]) && charNum + 1 < (int) len; charNum++) + { + if (currentLine[charNum] == '\t') + tabIncrementIn += indent - 1 - ((tabIncrementIn + charNum) % indent); + } + leadingSpaces = charNum + tabIncrementIn; + if (isSequenceReached("/*")) { - charNum = 0; doesLineStartComment = true; } -} - -/** - * append a character to the current formatted line. - * Unless disabled (via canBreakLine == false), first check if a - * line-break has been registered, and if so break the - * formatted line, and only then append the character into - * the next formatted line. - * - * @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); + else if (isSequenceReached("//")) + { + lineIsLineCommentOnly = true; + } + else if (isSequenceReached("{")) + { + currentLineBeginsWithBracket = true; + currentLineFirstBracketNum = charNum; + size_t firstText = currentLine.find_first_not_of(" \t", charNum + 1); + if (firstText != string::npos) + { + if (currentLine.compare(firstText, 2, "//") == 0) + lineIsLineCommentOnly = true; + else if (currentLine.compare(firstText, 2, "/*") == 0 + || isExecSQL(currentLine, firstText)) + { + // get the extra adjustment + size_t j; + for (j = charNum + 1; isWhiteSpace(currentLine[j]) && j < firstText; j++) + { + if (currentLine[j] == '\t') + tabIncrementIn += indent - 1 - ((tabIncrementIn + j) % indent); + } + leadingSpaces = j + tabIncrementIn; + if (currentLine.compare(firstText, 2, "/*") == 0) + doesLineStartComment = true; + } + } + } + else if (isWhiteSpace(currentLine[charNum]) && !(charNum + 1 < (int) currentLine.length())) + { + lineIsEmpty = true; + } } /** @@ -1457,10 +1957,10 @@ */ void ASFormatter::breakLine() { - ++inLineNumber; isLineReady = true; isInLineBreak = false; - spacePadNum = 0; + spacePadNum = nextLineSpacePadNum; + nextLineSpacePadNum = 0; formattedLineCommentNum = string::npos; // queue an empty line prepend request if one exists @@ -1491,62 +1991,152 @@ * * @return the type of the opened block. */ -BracketType ASFormatter::getBracketType() const +BracketType ASFormatter::getBracketType() { + assert(currentChar == '{'); + BracketType returnVal; - if (foundPreDefinitionHeader) + if ((previousNonWSChar == '=' + || isBracketType(bracketTypeStack->back(), ARRAY_TYPE)) + && previousCommandChar != ')') + returnVal = ARRAY_TYPE; + else if (foundPreDefinitionHeader) { returnVal = DEFINITION_TYPE; if (foundNamespaceHeader) returnVal = (BracketType)(returnVal | NAMESPACE_TYPE); else if (foundClassHeader) returnVal = (BracketType)(returnVal | CLASS_TYPE); + else if (foundStructHeader) + returnVal = (BracketType)(returnVal | STRUCT_TYPE); + else if (foundInterfaceHeader) + returnVal = (BracketType)(returnVal | INTERFACE_TYPE); } else { - bool isCommandType = false; - - if (previousNonWSChar != '=') - isCommandType = (foundPreCommandHeader - || (currentHeader != NULL && isNonParenHeader) - || (previousCommandChar == ')') - || (previousCommandChar == ':' && !foundQuestionMark) - || (previousCommandChar == ';') - || ((previousCommandChar == '{' || previousCommandChar == '}') - && isPreviousBracketBlockRelated)); + bool isCommandType = (foundPreCommandHeader + || (currentHeader != NULL && isNonParenHeader) + || (previousCommandChar == ')') + || (previousCommandChar == ':' && !foundQuestionMark) + || (previousCommandChar == ';') + || ((previousCommandChar == '{' || previousCommandChar == '}') + && isPreviousBracketBlockRelated) + || 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; + } - returnVal = (isCommandType ? COMMAND_TYPE : ARRAY_TYPE); + if (!isCommandType && isInExtern) + returnVal = EXTERN_TYPE; + else + returnVal = (isCommandType ? COMMAND_TYPE : ARRAY_TYPE); } - if (isOneLineBlockReached()) + if (isOneLineBlockReached(currentLine, charNum)) returnVal = (BracketType)(returnVal | SINGLE_LINE_TYPE); - TRbracket(returnVal); + if (isBracketType(returnVal, ARRAY_TYPE) && isNonInStatementArrayBracket()) + { + returnVal = (BracketType)(returnVal | ARRAY_NIS_TYPE); + isNonInStatementArray = true; + nonInStatementBracket = formattedLine.length() - 1; + } + return returnVal; } /** - * check if the currently reached '*' or '&' character is - * a pointer-or-reference symbol, or another operator. - * this method takes for granted that the current character - * is either a '*' or '&'. + * 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 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 { - bool isPR; - isPR = (!isInPotentialCalculation - || IS_A(bracketTypeStack->back(), DEFINITION_TYPE) - || (!isLegalNameChar(previousNonWSChar) - && previousNonWSChar != ')' - && previousNonWSChar != ']') - ); + assert(currentChar == '*' || currentChar == '&'); + + if (!isCStyle()) + return false; + + if (currentChar == '&' && previousChar == '&') + return false; + + if (previousNonWSChar == '=' || isCharImmediatelyPostReturn) + return true; + + if (currentHeader == &AS_CATCH) + return true; + + // get the last legal word (may be a number) + string lastWord = getPreviousWord(currentLine, charNum); + if (lastWord.empty()) + lastWord[0] = ' '; + char nextChar = peekNextChar(); + + // check for preceding or following numeric values + if (isdigit(lastWord[0]) + || isdigit(nextChar)) + return false; + + // checks on other chars + if (isLegalNameChar(lastWord[0]) + && isLegalNameChar(nextChar) + && parenStack->back() > 0) + { + // if followed by an assignment it is a pointer or reference + size_t nextNum = currentLine.find_first_of("=;)", charNum + 1); + if (nextNum != string::npos && currentLine[nextNum] == '=') + return true; + + // if a function definition it is a pointer or reference + // otherwise it is an arithmetic operator + if (!isBracketType(bracketTypeStack->back(), COMMAND_TYPE)) + return true; + else + 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 + || isBracketType(bracketTypeStack->back(), DEFINITION_TYPE) + || (!isLegalNameChar(previousNonWSChar) + && !(previousNonWSChar == ')' && nextChar == '(') + && !(previousNonWSChar == ')' && currentChar == '*') + && previousNonWSChar != ']') + ); if (!isPR) { - char nextChar = peekNextChar(); isPR |= (!isWhiteSpace(nextChar) && nextChar != '-' && nextChar != '(' @@ -1557,34 +2147,136 @@ 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(isPointerOrReference()); + + if (previousNonWSChar == '=' + || previousNonWSChar == ',' + || previousNonWSChar == '.' + || previousNonWSChar == '>' + || previousNonWSChar == '<' + || isCharImmediatelyPostReturn) + return true; + + // check for ** + if (currentChar == '*' + && (int) currentLine.length() > charNum + && currentLine[charNum+1] == '*') + { + if (previousNonWSChar == '(') + 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")) + return true; + + size_t nextChar = currentLine.find_first_not_of(" \t", charNum+1); + if (nextChar != string::npos + && (currentLine[nextChar] == ')' + || currentLine[nextChar] == '>' + || currentLine[nextChar] == ',')) + return false; + + string lastWord = getPreviousWord(currentLine, charNum); + if (lastWord == "else" || lastWord == "delete") + return true; + + bool isDA = (!(isLegalNameChar(previousNonWSChar) || previousNonWSChar == '>') + || !isLegalNameChar(peekNextChar()) + || (ispunct(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 wil be deleted on the output. + * + * @return whether current character is centered. + */ +bool ASFormatter::isPointerOrReferenceCentered() const +{ + assert(currentLine[charNum] == '*' || currentLine[charNum] == '&'); + + int prNum = charNum; + int lineLength = (int) currentLine.length(); + // 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 ** + if (prNum + 1 < lineLength + && 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 the currently reached '-' character is - * a unary minus + * check if the currently reached '+' or '-' character is a unary operator * this method takes for granted that the current character - * is a '-'. + * is a '+' or '-'. * - * @return whether the current '-' is a unary minus. + * @return whether the current '+' or '-' is a unary operator. */ -bool ASFormatter::isUnaryMinus() const +bool ASFormatter::isUnaryOperator() const { - return ((previousOperator == &AS_RETURN || !isalnum(previousCommandChar)) + assert(currentChar == '+' || currentChar == '-'); + + return ((isCharImmediatelyPostReturn || !isLegalNameChar(previousCommandChar)) && previousCommandChar != '.' + && previousCommandChar != '\"' + && previousCommandChar != '\'' && previousCommandChar != ')' && previousCommandChar != ']'); } /** - * check if the currently reached '-' or '+' character is + * check if the currently reached '+' or '-' character is * part of an exponent, i.e. 0.2E-5. + * * this method takes for granted that the current character - * is a '-' or '+'. + * is a '+' or '-'. * - * @return whether the current '-' is in an exponent. + * @return whether the current '+' or '-' is in an exponent. */ bool ASFormatter::isInExponent() const { + assert(currentChar == '+' || currentChar == '-'); + int formattedLineLength = formattedLine.length(); if (formattedLineLength >= 2) { @@ -1599,27 +2291,62 @@ } /** + * check if an array bracket should NOT have an in-statement indent + * + * @return the array is non in-statement + */ +bool ASFormatter::isNonInStatementArrayBracket() const +{ + bool returnVal = false; + char nextChar = peekNextChar(); + // if this opening bracket begins the line there will be no inStatement indent + if (currentLineBeginsWithBracket + && charNum == (int) currentLineFirstBracketNum + && nextChar != '}') + returnVal = true; + // if an opening bracket ends the line there will be no inStatement indent + if (isWhiteSpace(nextChar) + || isBeforeAnyLineEndComment(charNum) + || nextChar == '{') + returnVal = true; + + // Java "new Type [] {...}" IS an inStatement indent + if (isJavaStyle() && previousNonWSChar == ']') + returnVal = false; + + // trace + //if (isNonInStatementArray) + // cout << traceLineNumber << " " << 'x' << endl; + //else + // cout << traceLineNumber << " " << ' ' << endl + + return returnVal; +} + +/** * check if a one-line bracket has been reached, * i.e. if the currently reached '{' character is closed * with a complimentry '}' elsewhere on the current line, *. * @return has a one-line bracket been reached? */ -bool ASFormatter::isOneLineBlockReached() const +bool ASFormatter::isOneLineBlockReached(string& line, int startChar) const { + assert(line[startChar] == '{'); + bool isInComment = false; bool isInQuote = false; int bracketCount = 1; - int currentLineLength = currentLine.length(); + int lineLength = line.length(); char quoteChar = ' '; - for (int i = charNum + 1; i < currentLineLength; ++i) + for (int i = startChar + 1; i < lineLength; ++i) { - char ch = currentLine[i]; + char ch = line[i]; if (isInComment) { - if (currentLine.compare(i, 2, "*/") == 0) + if (line.compare(i, 2, "*/") == 0) { isInComment = false; ++i; @@ -1647,10 +2374,10 @@ continue; } - if (currentLine.compare(i, 2, "//") == 0) + if (line.compare(i, 2, "//") == 0) break; - if (currentLine.compare(i, 2, "/*") == 0) + if (line.compare(i, 2, "/*") == 0) { isInComment = true; ++i; @@ -1670,34 +2397,107 @@ } /** - * check if one of a set of headers has been reached in the - * current position of the current line. + * 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 char position on currentLine to start the search + * @return true if the next word is get or set. + */ +bool ASFormatter::isNextWordSharpNonParenHeader(int startChar) const +{ + // look ahead to find the next non-comment text + string nextText = peekNextText(currentLine.substr(startChar)); + if (nextText.length() == 0) + return false; + if (nextText[0] == '[') + return true; + if (!isCharPotentialHeader(nextText, 0)) + return false; + if (findKeyword(nextText, 0, AS_GET) || findKeyword(nextText, 0, AS_SET) + || findKeyword(nextText, 0, AS_ADD) || findKeyword(nextText, 0, AS_REMOVE)) + return true; + return false; +} + +/** + * peek at the next char to determine if it is an opening bracket. + * will look ahead in the input file if necessary. + * this determines a java static constructor. * - * @return a pointer to the found header. Or a NULL if no header has been reached. - * @param headers a vector of headers. - * @param checkBoundry + * @param char position on currentLine to start the search + * @return true if the next word is an opening bracket. */ -const string *ASFormatter::findHeader(const vector &headers, bool checkBoundry) +bool ASFormatter::isNextCharOpeningBracket(int startChar) const { - return ASBeautifier::findHeader(currentLine, charNum, headers, checkBoundry); + bool retVal = false; + string nextText = peekNextText(currentLine.substr(startChar)); + if (nextText.compare(0, 1, "{") == 0) + retVal = true; + return retVal; } /** - * check if a line begins with the specified character - * i.e. if the current line begins with a open bracket. + * get the next non-whitespace substring on following lines, bypassing all comments. * - * @return true or false + * @param the first line to check + * @return the next non-whitespace substring. */ -bool ASFormatter::lineBeginsWith(char charToCheck) const +string ASFormatter::peekNextText(const string& firstLine, bool endOnEmptyLine /*false*/) const { - bool beginsWith = false; - size_t i = currentLine.find_first_not_of(" \t"); + bool isFirstLine = true; + bool needReset = false; + string nextLine = firstLine; + size_t firstChar= string::npos; + + // find the first non-blank text, bypassing all comments. + bool isInComment = false; + while (sourceIterator->hasMoreLines()) + { + if (isFirstLine) + isFirstLine = false; + else + { + nextLine = sourceIterator->peekNextLine(); + needReset = true; + } + + firstChar = nextLine.find_first_not_of(" \t"); + if (firstChar == string::npos) + { + if (endOnEmptyLine && !isInComment) + break; + continue; + } + + if (nextLine.compare(firstChar, 2, "/*") == 0) + 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; - if (i != string::npos) - if (currentLine[i] == charToCheck && (int) i == charNum) - beginsWith = true; + // found the next text + break; + } - return beginsWith; + if (needReset) + sourceIterator->peekReset(); + if (firstChar == string::npos) + nextLine = ""; + else + nextLine = nextLine.substr(firstChar); + return nextLine; } /** @@ -1723,62 +2523,69 @@ } 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 - if (formattedLine[len-1] != '\t') // don't adjust if a tab - formattedLine.append(adjust, ' '); -// else // comment out to avoid compiler warning -// adjust = 0; -// TRcomment(adjust); // trace macro + formattedLine.append(adjust, ' '); } - // if spaces were added, need to delete spaces before the comment, if possible + // 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; - if (formattedLine.find_last_not_of(' ') < len - adjust - 1 - && formattedLine[len-1] != '\t') // don't adjust a tab + size_t lastText = formattedLine.find_last_not_of(' '); + if (lastText != string::npos + && lastText < len - adjust - 1) formattedLine.resize(len - adjust); - // the following are commented out to avoid a Borland compiler warning - //else - // adjust = 0; - TRcomment(-adjust); // trace macro + else if (len > lastText + 2) + formattedLine.resize(lastText + 2); + else if (len < lastText + 2) + formattedLine.append(len - lastText, ' '); } } /** * append the current bracket inside the end of line comments * currentChar contains the bracket, it will be appended to formattedLine * formattedLineCommentNum is the comment location on formattedLine + * returns true f appended, false if not */ void ASFormatter::appendCharInsideComments(void) { - if (formattedLineCommentNum == string::npos // does the comment start on the previous line? - || isBeforeComment()) // does a comment follow on this line? + if (formattedLineCommentNum == string::npos) // does the comment start on the previous line? { - appendCurrentChar(true); // don't attach - return; + appendCurrentChar(); // don't attach + return; // false; } 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) // is the previous line comment only? + if (beg == string::npos) // is the previous line comment only? { - appendCurrentChar(true); // don't attach - return; + appendCurrentChar(); // don't attach + return; // false; } beg++; // insert the bracket - if (end - beg < 3) // is there room to insert? + 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 + if (formattedLine[beg] == '\t') // don't pad with a tab formattedLine.insert(beg, 1, ' '); formattedLine[beg+1] = currentChar; + + if (isBeforeComment()) + breakLine(); + else if (isCharImmediatelyPostLineComment) + shouldBreakLineAtNextChar = true; + return; // true; } /** @@ -1791,7 +2598,6 @@ */ void ASFormatter::padOperators(const string *newOperator) { - assert (shouldPadOperators); assert(newOperator != NULL); bool shouldPad = (newOperator != &AS_COLON_COLON @@ -1802,29 +2608,36 @@ && newOperator != &AS_NOT && newOperator != &AS_BIT_NOT && newOperator != &AS_ARROW - && newOperator != &AS_OPERATOR - && newOperator != &AS_RETURN && !(newOperator == &AS_MINUS && isInExponent()) - && !(newOperator == &AS_MINUS // check for negative number - && (previousNonWSChar == '(' - || previousNonWSChar == '=' - || previousNonWSChar == ',')) - && !(newOperator == &AS_PLUS && isInExponent()) - && previousOperator != &AS_OPERATOR - && !((newOperator == &AS_MULT || newOperator == &AS_BIT_AND) - && isPointerOrReference()) - && !(newOperator == &AS_MULT - && (previousNonWSChar == '.' - || previousNonWSChar == '>')) // check for -> - && !((isInTemplate || isCharImmediatelyPostTemplate) - && (newOperator == &AS_LS || newOperator == &AS_GR)) - ); + && !((newOperator == &AS_PLUS || newOperator == &AS_MINUS) // check for unary plus or minus + && (previousNonWSChar == '(' + || previousNonWSChar == '=' + || previousNonWSChar == ',')) + && !(newOperator == &AS_PLUS && isInExponent()) + && !isCharImmediatelyPostOperator + && !((newOperator == &AS_MULT || newOperator == &AS_BIT_AND) + && isPointerOrReference()) + && !(newOperator == &AS_MULT + && (previousNonWSChar == '.' + || previousNonWSChar == '>')) // check for -> + && !((isInTemplate || isCharImmediatelyPostTemplate) + && (newOperator == &AS_LS || newOperator == &AS_GR)) + && !(newOperator == &AS_GCC_MIN_ASSIGN + && ASBase::peekNextChar(currentLine, charNum+1) == '>') + && !(newOperator == &AS_GR && previousNonWSChar == '?') + && !isInCase + && !isInAsm + && !isInAsmOneLine + && !isInAsmBlock + ); + // pad before operator if (shouldPad && !isInBlParen && !(newOperator == &AS_COLON && !foundQuestionMark) - && newOperator != &AS_SEMICOLON - && newOperator != &AS_COMMA) + && !(newOperator == &AS_QUESTION && isSharpStyle() // check for C# nullable type (e.g. int?) + && currentLine.find(':', charNum+1) == string::npos) + ) appendSpacePad(); appendSequence(*newOperator); goForward(newOperator->length() - 1); @@ -1840,31 +2653,231 @@ // but do not pad after a '-' that is a unary-minus. if (shouldPad && !isInBlParen - && !isBeforeComment() - && !(newOperator == &AS_MINUS && isUnaryMinus()) + && !isBeforeAnyComment() + && !(newOperator == &AS_PLUS && isUnaryOperator()) + && !(newOperator == &AS_MINUS && isUnaryOperator()) && !(currentLine.compare(charNum + 1, 1, ";") == 0) - && !(currentLine.compare(charNum + 1, 2, "::") == 0)) + && !(currentLine.compare(charNum + 1, 2, "::") == 0) + && !(newOperator == &AS_QUESTION && isSharpStyle() // check for C# nullable type (e.g. int?) + && currentLine[charNum+1] == '[') + ) appendSpaceAfter(); previousOperator = newOperator; return; } /** + * format pointer or reference + * currentChar contains the pointer or reference + * the symbol and necessary padding will be appended to formattedLine + * the calling function should have a continue statement after calling this method + */ +void ASFormatter::formatPointerOrReference(void) +{ + assert(currentChar == '*' || currentChar == '&'); + assert(isCStyle()); + + // check for cast + char peekedChar = peekNextChar(); + if (currentChar == '*' + && (int) currentLine.length() > charNum + && currentLine[charNum+1] == '*') + { + size_t nextChar = currentLine.find_first_not_of(" \t", charNum+2); + if (nextChar == string::npos) + peekedChar = ' '; + else + peekedChar = currentLine[nextChar]; + } + if (peekedChar == ')' || peekedChar =='>' || peekedChar ==',') + { + formatPointerOrReferenceCast(); + return; + } + + // do this before bumping charNum + bool isOldPRCentered = isPointerOrReferenceCentered(); + + if (pointerAlignment == ALIGN_TYPE) + { + size_t prevCh = formattedLine.find_last_not_of(" \t"); + if (prevCh == string::npos) + prevCh = 0; + if (formattedLine.length() == 0 || prevCh == formattedLine.length() - 1) + appendCurrentChar(); + else + { + // exchange * or & with character following the type + // this may not work every time with a tab character + string charSave = formattedLine.substr(prevCh+1, 1); + formattedLine[prevCh+1] = currentChar; + formattedLine.append(charSave); + } + if (isSequenceReached("**")) + { + formattedLine.insert(prevCh+2, "*"); + goForward(1); + } + // if no space after * then add one + if (charNum < (int) currentLine.length() - 1 + && !isWhiteSpace(currentLine[charNum+1]) + && currentLine[charNum+1] != ')') + appendSpacePad(); + // if old pointer or reference is centered, remove a space + if (isOldPRCentered + && isWhiteSpace(formattedLine[formattedLine.length()-1])) + { + formattedLine.erase(formattedLine.length()-1, 1); + spacePadNum--; + } + } + else if (pointerAlignment == ALIGN_MIDDLE) + { + // 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; + // adjust for ** + string sequenceToInsert = currentChar == '*' ? "*" : "&"; + if (isSequenceReached("**")) + { + sequenceToInsert = "**"; + goForward(1); + } + size_t charNumSave = 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++) + { + goForward(1); + formattedLine.append(1, currentLine[i]); + } + // whitespace should be at least 2 chars + size_t wsAfter = currentLine.find_first_not_of(" \t", charNumSave + 1); + if (wsAfter == string::npos) + wsAfter = 0; + else + wsAfter = wsAfter - charNumSave - 1; + 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; + formattedLine.insert(formattedLine.length() - padAfter, sequenceToInsert); + } + else if (pointerAlignment == ALIGN_NAME) + { + size_t startNum = formattedLine.find_last_not_of(" \t"); + string sequenceToInsert = currentChar == '*' ? "*" : "&"; + if (isSequenceReached("**")) + { + sequenceToInsert = "**"; + goForward(1); + } + // 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); + formattedLine.append(1, currentLine[i]); + } + appendSequence(sequenceToInsert, false); + // if no space before * then add one + if (startNum != string::npos + && !isWhiteSpace(formattedLine[startNum+1])) + { + formattedLine.insert(startNum+1 , 1, ' '); + spacePadNum++; + } + // if old pointer or reference is centered, remove a space + if (isOldPRCentered + && formattedLine.length() > startNum+1 + && isWhiteSpace(formattedLine[startNum+1])) + { + formattedLine.erase(startNum+1, 1); + spacePadNum--; + } + } + else // pointerAlignment == ALIGN_NONE + { + appendCurrentChar(); + } + return; +} + +/** + * format pointer or reference cast + * currentChar contains the pointer or reference + * NOTE: the pointers and references in function definitions + * are processed as a cast (e.g. void foo(void*, void*)) + * is processed here. + */ +void ASFormatter::formatPointerOrReferenceCast(void) +{ + assert(currentChar == '*' || currentChar == '&'); + assert(isCStyle()); + + string sequenceToInsert = currentChar == '*' ? "*" : "&"; + if (isSequenceReached("**")) + { + sequenceToInsert = "**"; + goForward(1); + } + if (pointerAlignment == ALIGN_NONE) + { + appendSequence(sequenceToInsert, false); + return; + } + // remove trailing whitespace + size_t prevCh = formattedLine.find_last_not_of(" \t"); + if (prevCh == string::npos) + prevCh = 0; + if (formattedLine.length() > 0 && isWhiteSpace(formattedLine[prevCh+1])) + { + spacePadNum -= (formattedLine.length() - 1 - prevCh); + formattedLine.erase(prevCh+1); + } + if (pointerAlignment == ALIGN_TYPE) + { + appendSequence(sequenceToInsert, false); + } + else if (pointerAlignment == ALIGN_MIDDLE + || pointerAlignment == ALIGN_NAME) + { + appendSpacePad(); + appendSequence(sequenceToInsert, false); + } + else + appendSequence(sequenceToInsert, false); +} + +/** * add or remove space padding to parens * currentChar contains the paren * the parens and necessary padding will be appended to formattedLine * the calling function should have a continue statement after calling this method */ void ASFormatter::padParens(void) { - assert(shouldPadParensOutside || shouldPadParensInside || shouldUnPadParens); - assert (currentChar == '(' || currentChar == ')'); + assert(currentChar == '(' || currentChar == ')'); + + int spacesOutsideToDelete = 0; + int spacesInsideToDelete = 0; if (currentChar == '(') { - int spacesOutsideToDelete = formattedLine.length() - 1; - int spacesInsideToDelete = 0; + spacesOutsideToDelete = formattedLine.length() - 1; + spacesInsideToDelete = 0; // compute spaces outside the opening paren to delete if (shouldUnPadParens) @@ -1874,50 +2887,53 @@ size_t i = formattedLine.find_last_not_of(" \t"); if (i != string::npos) { - size_t end = i; - spacesOutsideToDelete -= i; - lastChar = formattedLine[i]; - // was last word a paren header? - int start; // start of the previous word - for (start = i; start > 0; start--) - { - if (isLegalNameChar(formattedLine[start]) || formattedLine[start] == '*') - continue; - start++; - break; - } - string prevWord = formattedLine.substr(start, end-start+1); - // if previous word is a header, it will be a paren header - const string *prevWordH = ASBeautifier::findHeader(formattedLine, start, headers); - if (prevWordH != NULL) - { - prevIsParenHeader = true; - TRxtra(*prevWordH); // trace macro - } - else if (prevWord == "return" // don't unpad return statements - || prevWord == "*") // don't unpad multiply or pointer - { - prevIsParenHeader = true; - TRxtra(prevWord); // trace macro - } - // don't unpad variables - else if (prevWord == "bool" - || prevWord == "int" - || prevWord == "void" - || prevWord == "void*" - || (prevWord.length() >= 6 // check end of word for _t - && prevWord.compare(prevWord.length()-2, 2, "_t") == 0) - || prevWord == "BOOL" - || prevWord == "DWORD" - || prevWord == "HWND" - || prevWord == "INT" - || prevWord == "LPSTR" - || prevWord == "VOID" - || prevWord == "LPVOID" - ) + // if last char is a bracket the previous whitespace is an indent + if (formattedLine[i] == '{') + spacesOutsideToDelete = 0; + else { - prevIsParenHeader = true; - TRxtra(prevWord); // trace macro + spacesOutsideToDelete -= i; + lastChar = formattedLine[i]; + // if previous word is a header, it will be a paren header + string prevWord = getPreviousWord(formattedLine, formattedLine.length()); + const string* prevWordH = NULL; + if (shouldPadHeader + && prevWord.length() > 0 + && isCharPotentialHeader(prevWord, 0)) + prevWordH = ASBeautifier::findHeader(prevWord, 0, headers); + if (prevWordH != NULL) + { + prevIsParenHeader = true; + // trace + //cout << traceLineNumber << " " << *prevWordH << endl; + } + else if (prevWord == "return" // don't unpad return statements + || prevWord == "*") // don't unpad multiply or pointer + { + prevIsParenHeader = true; + // trace + //cout << traceLineNumber << " " << prevWord << endl; + } + // don't unpad variables + else if (prevWord == "bool" + || prevWord == "int" + || prevWord == "void" + || prevWord == "void*" + || (prevWord.length() >= 6 // check end of word for _t + && prevWord.compare(prevWord.length()-2, 2, "_t") == 0) + || prevWord == "BOOL" + || prevWord == "DWORD" + || prevWord == "HWND" + || prevWord == "INT" + || prevWord == "LPSTR" + || prevWord == "VOID" + || prevWord == "LPVOID" + ) + { + prevIsParenHeader = true; + // trace + //cout << traceLineNumber << " " << prevWord << endl; + } } } // do not unpad operators, but leave them if already padded @@ -1967,20 +2983,27 @@ currentLine.erase(charNum + 1, spacesInsideToDelete); spacePadNum -= spacesInsideToDelete; } + // convert tab to space if requested + if (shouldConvertTabs + && (int)currentLine.length() > charNum + && currentLine[charNum+1] == '\t') + currentLine[charNum+1] = ' '; + } // pad open paren inside char peekedCharInside = peekNextChar(); if (shouldPadParensInside) if (!(currentChar == '(' && peekedCharInside == ')')) appendSpaceAfter(); - - TRunpad('(', spacesOutsideToDelete, spacesInsideToDelete); // trace macro + // trace + //if(spacesOutsideToDelete > 0 || spacesInsideToDelete > 0) + // cout << traceLineNumber << " " << spacesOutsideToDelete << '(' << spacesInsideToDelete << endl; } else if (currentChar == ')' /*|| currentChar == ']'*/) { - int spacesOutsideToDelete = 0; - int spacesInsideToDelete = formattedLine.length(); + spacesOutsideToDelete = 0; + spacesInsideToDelete = formattedLine.length(); // unpad close paren inside if (shouldUnPadParens) @@ -2014,7 +3037,6 @@ spacesOutsideToDelete = j - charNum - 1; if (shouldPadParensOutside) spacesOutsideToDelete--; -// spacesOutsideToDelete--; // always leave 1 space if (spacesOutsideToDelete > 0) { @@ -2030,166 +3052,174 @@ && peekedCharOutside != ',' && peekedCharOutside != '.' && peekedCharOutside != '-') // check for -> -// && !(currentChar == ']' && peekedCharOutside == '[')) appendSpaceAfter(); - TRunpad(')', spacesInsideToDelete, 0 /*spacesOutsideToDelete*/); // trace macro + // trace + //if(spacesInsideToDelete > 0) + // cout << traceLineNumber << " " << spacesInsideToDelete << ')' << 0 << endl; } return; } /** - * format brackets as attached or broken + * format opening bracket as attached or broken * currentChar contains the bracket * the brackets will be appended to the current formattedLine or a new formattedLine as necessary * the calling function should have a continue statement after calling this method * * @param bracketType the type of bracket to be formatted. */ -void ASFormatter::formatBrackets(BracketType bracketType) +void ASFormatter::formatOpeningBracket(BracketType bracketType) { - assert(!IS_A(bracketType, ARRAY_TYPE)); - assert (currentChar == '{' || currentChar == '}'); + assert(!isBracketType(bracketType, ARRAY_TYPE)); + assert(currentChar == '{'); - if (currentChar == '{') - { - parenStack->push_back(0); - } - else if (currentChar == '}') + parenStack->push_back(0); + + bool breakBracket = isCurrentBracketBroken(); + + if (breakBracket) { - if (!parenStack->empty()) + if (isBeforeAnyComment() && isOkToBreakBlock(bracketType)) { - parenStack->pop_back(); + // if comment is at line end leave the comment on this line + if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBracket) // lineBeginsWith('{') + { + currentChar = ' '; // remove bracket from current line + currentLine[charNum] = currentChar; + appendOpeningBracket = true; // append bracket to following line + } + // else put comment after the bracket + else if (!isBeforeMultipleLineEndComments(charNum)) + breakLine(); } - } + else if (!isBracketType(bracketType, SINGLE_LINE_TYPE)) + breakLine(); + else if (shouldBreakOneLineBlocks && peekNextChar() != '}') + breakLine(); + else if (!isInLineBreak) + appendSpacePad(); - if (currentChar == '{') + appendCurrentChar(); + + // should a following comment break from the bracket? + // must break the line AFTER the bracket + if (isBeforeComment() + && formattedLine[0] == '{' + && isOkToBreakBlock(bracketType) + && (bracketFormatMode == BREAK_MODE + || bracketFormatMode == LINUX_MODE + || bracketFormatMode == STROUSTRUP_MODE)) + { + shouldBreakLineAtNextChar = true; + } + + } + else // attach bracket { - bool bdacBreak = false; - // should a Linux bracket be broken? - if (bracketFormatMode == BDAC_MODE) + // are there comments before the bracket? + if (isCharImmediatelyPostComment || isCharImmediatelyPostLineComment) { - // always break a class - if (IS_A((*bracketTypeStack)[bracketTypeStack->size()-1], CLASS_TYPE)) - bdacBreak = true; - // break a namespace and the first bracket if a function - else if (bracketTypeStack->size() <= 2) - { - if (IS_A((*bracketTypeStack)[bracketTypeStack->size()-1], NAMESPACE_TYPE) - || IS_A((*bracketTypeStack)[bracketTypeStack->size()-1], COMMAND_TYPE)) - bdacBreak = true; - } - // break the first bracket after a namespace if a function - else if (IS_A((*bracketTypeStack)[bracketTypeStack->size()-2], NAMESPACE_TYPE)) + if (isOkToBreakBlock(bracketType) + && !(isCharImmediatelyPostComment && isCharImmediatelyPostLineComment) // don't attach if two comments on the line + && peekNextChar() != '}' // don't attach { } + && previousCommandChar != '{' // don't attach { { + && previousCommandChar != '}' // don't attach } { + && previousCommandChar != ';') // don't attach ; { { - if (IS_A((*bracketTypeStack)[bracketTypeStack->size()-1], COMMAND_TYPE)) - bdacBreak = true; + appendCharInsideComments(); } - // if not C style then break the first bracket after a class if a function - else if (!ASBeautifier::isCStyle) + else { - if (IS_A((*bracketTypeStack)[bracketTypeStack->size()-2], CLASS_TYPE) - && IS_A((*bracketTypeStack)[bracketTypeStack->size()-1], COMMAND_TYPE)) - bdacBreak = true; + appendCurrentChar(); // don't attach } } - if (bracketFormatMode == ATTACH_MODE - || (bracketFormatMode == BDAC_MODE && !bdacBreak)) + else if (previousCommandChar == '{' + || previousCommandChar == '}' + || previousCommandChar == ';') // '}' , ';' chars added for proper handling of '{' immediately after a '}' or ';' { - // are there comments before the bracket? - if (isCharImmediatelyPostComment || isCharImmediatelyPostLineComment) - { - if ((shouldBreakOneLineBlocks || !IS_A(bracketType, SINGLE_LINE_TYPE)) - && peekNextChar() != '}') - appendCharInsideComments(); - else - appendCurrentChar(true); // don't attach - } - else if (previousCommandChar == '{' - || previousCommandChar == '}' - || previousCommandChar == ';') // '}' , ';' chars added for proper handling of '{' immediately after a '}' or ';' - { - appendCurrentChar(true); // don't attach - } - else + appendCurrentChar(); // don't attach + } + else + { + // if a blank line preceeds this don't attach + if (isEmptyLine(formattedLine)) + appendCurrentChar(); // don't attach + else if (isOkToBreakBlock(bracketType) + && !(isImmediatelyPostPreprocessor + && currentLineBeginsWithBracket)) // lineBeginsWith('{') { - size_t firstChar = formattedLine.find_first_not_of(" \t"); - if (firstChar == string::npos) // if a blank line preceeds this - appendCurrentChar(true); // don't attach - else if (shouldBreakOneLineBlocks - || !IS_A(bracketType, SINGLE_LINE_TYPE) - || peekNextChar() == '}') + if (peekNextChar() != '}') { appendSpacePad(); - appendCurrentChar(false); // OK to attach + appendCurrentChar(false); // OK to attach + // should a following comment attach with the bracket? + // insert spaces to reposition the comment + if (isBeforeComment() + && !isBeforeMultipleLineEndComments(charNum) + && (!isBeforeAnyLineEndComment(charNum) || currentLineBeginsWithBracket)) // lineBeginsWith('{') + { + breakLine(); + currentLine.insert(charNum+1, charNum+1, ' '); + } } else - appendCurrentChar(true); // don't attach - } - } - else if (bracketFormatMode == BREAK_MODE - || (bracketFormatMode == BDAC_MODE && bdacBreak)) - { - if (isBeforeComment()) - { - // do not break unless comment is at line end - if (isBeforeLineEndComment(charNum)) { - currentChar = ' '; // remove bracket from current line - appendOpeningBracket = true; // append bracket to following line + appendSpacePad(); + appendCurrentChar(); } } - else if (!IS_A(bracketType, SINGLE_LINE_TYPE)) - breakLine(); - else if (shouldBreakOneLineBlocks && peekNextChar() != '}') - breakLine(); - - appendCurrentChar(); - } - else if (bracketFormatMode == NONE_MODE) - { - if (lineBeginsWith('{')) // is opening bracket broken? - appendCurrentChar(true); else - appendCurrentChar(false); + { + if (!isInLineBreak) + appendSpacePad(); + appendCurrentChar(); // don't attach + } } } - else if (currentChar == '}') - { - // mark state of immediately after empty block - // this state will be used for locating brackets that appear immedately AFTER an empty block (e.g. '{} \n}'). - if (previousCommandChar == '{') - isImmediatelyPostEmptyBlock = true; +} - if ((!(previousCommandChar == '{' && isPreviousBracketBlockRelated)) // this '{' does not close an empty block - && (shouldBreakOneLineBlocks || !IS_A(bracketType, SINGLE_LINE_TYPE)) // astyle is allowed to break on line blocks - && (!(bracketFormatMode == NONE_MODE && IS_A(bracketType, SINGLE_LINE_TYPE))) - && !isImmediatelyPostEmptyBlock) // this '}' does not immediately follow an empty block - { - breakLine(); - appendCurrentChar(); - } - else - { - if (!isCharImmediatelyPostComment - && bracketFormatMode != NONE_MODE - && !isImmediatelyPostEmptyBlock) - isInLineBreak = false; +/** + * format closing bracket + * currentChar contains the bracket + * the calling function should have a continue statement after calling this method + * + * @param bracketType the type of bracket to be formatted. + */ +void ASFormatter::formatClosingBracket(BracketType bracketType) +{ + assert(!isBracketType(bracketType, ARRAY_TYPE)); + assert(currentChar == '}'); - appendCurrentChar(); + // parenStack must contain one entry + if (parenStack->size() > 1) + parenStack->pop_back(); - //if (!bracketFormatMode == NONE_MODE) - // if ((shouldBreakOneLineBlocks || !IS_A(bracketType, SINGLE_LINE_TYPE)) - // && !(currentChar == '}' && peekNextChar() == ';')) // fixes }; placed on separate lines - // shouldBreakLineAfterComments = true; - } + // mark state of immediately after empty block + // this state will be used for locating brackets that appear immedately AFTER an empty block (e.g. '{} \n}'). + if (previousCommandChar == '{') + isImmediatelyPostEmptyBlock = true; - if (shouldBreakBlocks) - { - isAppendPostBlockEmptyLineRequested = true; - } + if ((!(previousCommandChar == '{' && isPreviousBracketBlockRelated)) // this '{' does not close an empty block + && isOkToBreakBlock(bracketType) // astyle is allowed to break on line blocks + && !isImmediatelyPostEmptyBlock) // this '}' does not immediately follow an empty block + { + breakLine(); + appendCurrentChar(); + } + else + { + appendCurrentChar(); + } + + // if a declaration follows a definition, space pad + if (isLegalNameChar(peekNextChar())) + appendSpaceAfter(); + + if (shouldBreakBlocks && currentHeader != NULL && parenStack->back() == 0) + { + isAppendPostBlockEmptyLineRequested = true; } - return; } /** @@ -2204,82 +3234,1287 @@ */ void ASFormatter::formatArrayBrackets(BracketType bracketType, bool isOpeningArrayBracket) { - assert(IS_A(bracketType, ARRAY_TYPE)); - assert (currentChar == '{' || currentChar == '}'); + assert(isBracketType(bracketType, ARRAY_TYPE)); + assert(currentChar == '{' || currentChar == '}'); if (currentChar == '{') { // is this the first opening bracket in the array? if (isOpeningArrayBracket) { - if (bracketFormatMode == ATTACH_MODE || bracketFormatMode == BDAC_MODE) + if (bracketFormatMode == ATTACH_MODE + || bracketFormatMode == LINUX_MODE + || bracketFormatMode == STROUSTRUP_MODE) { // don't attach to a preprocessor directive - if (isImmediatelyPostPreprocessor) - appendCurrentChar(true); // don't attach - // are there comments before the bracket? - else if (isCharImmediatelyPostComment || isCharImmediatelyPostLineComment) + if (isImmediatelyPostPreprocessor && currentLineBeginsWithBracket) // lineBeginsWith('{') + { + isInLineBreak = true; + appendCurrentChar(); // don't attach + } + else if (isCharImmediatelyPostComment) + { + // TODO: attach bracket to line-end comment + appendCurrentChar(); // don't attach + } + else if (isCharImmediatelyPostLineComment) { appendCharInsideComments(); } else { - // if bracket is broken or not an assignment - if (lineBeginsWith('{') || previousNonWSChar != '=') - appendSpacePad(); - appendCurrentChar(false); // OK to attach + // if a blank line preceeds this don't attach + if (isEmptyLine(formattedLine)) + appendCurrentChar(); // don't attach + else + { + // if bracket is broken or not an assignment + if (currentLineBeginsWithBracket // lineBeginsWith('{') + && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)) + { + appendSpacePad(); + appendCurrentChar(false); // OK to attach + + if (currentLineBeginsWithBracket + && (int)currentLineFirstBracketNum == charNum) + shouldBreakLineAtNextChar = true; + } + else + { + appendSpacePad(); + appendCurrentChar(); + } + } } } else if (bracketFormatMode == BREAK_MODE) { if (isWhiteSpace(peekNextChar())) breakLine(); - else if (isBeforeComment()) + else if (isBeforeAnyComment()) + { + // do not break unless comment is at line end + if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBracket) + { + currentChar = ' '; // remove bracket from current line + appendOpeningBracket = true; // append bracket to following line + } + } + if (!isInLineBreak) + appendSpacePad(); + appendCurrentChar(); + + if (currentLineBeginsWithBracket + && (int)currentLineFirstBracketNum == charNum + && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)) + shouldBreakLineAtNextChar = true; + } + else if (bracketFormatMode == HORSTMANN_MODE) + { + if (isWhiteSpace(peekNextChar())) + breakLine(); + else if (isBeforeAnyComment()) { // do not break unless comment is at line end - if (isBeforeLineEndComment(charNum)) + if (isBeforeAnyLineEndComment(charNum) && !currentLineBeginsWithBracket) // lineBeginsWith('{') { - currentChar = ' '; // remove bracket from current line - appendOpeningBracket = true; // append bracket to following line + currentChar = ' '; // remove bracket from current line + appendOpeningBracket = true; // append bracket to following line } } + if (!isInLineBreak) + appendSpacePad(); appendCurrentChar(); } else if (bracketFormatMode == NONE_MODE) { - if (lineBeginsWith('{')) // is opening bracket broken? - appendCurrentChar(); + if (currentLineBeginsWithBracket) // lineBeginsWith('{') + { + appendCurrentChar(); // don't attach + } else - appendCurrentChar(false); + { + appendSpacePad(); + appendCurrentChar(false); // OK to attach + } } } - else - appendCurrentChar(); // not the first opening bracket - don't change - - // if an opening bracket ends the line there will be no inStatement indent - char nextChar = peekNextChar(); - if (isWhiteSpace(nextChar) - || isBeforeLineEndComment(charNum) - || nextChar == '{') - isNonInStatementArray = true; - if (isNonInStatementArray) - TRarray('x'); - else - TRarray(' '); + else // not the first opening bracket + { + if (bracketFormatMode == HORSTMANN_MODE) + { + if (previousNonWSChar == '{' + && bracketTypeStack->size() > 2 + && !isBracketType((*bracketTypeStack)[bracketTypeStack->size()-2], SINGLE_LINE_TYPE)) + formatArrayRunIn(); + } + else if (!isInLineBreak + && !isWhiteSpace(peekNextChar()) + && previousNonWSChar == '{' + && bracketTypeStack->size() > 2 + && !isBracketType((*bracketTypeStack)[bracketTypeStack->size()-2], SINGLE_LINE_TYPE)) + formatArrayRunIn(); + appendCurrentChar(); + } } else if (currentChar == '}') { // does this close the first opening bracket in the array? - if (isOpeningArrayBracket && !IS_A(bracketType, SINGLE_LINE_TYPE) ) + if (!isBracketType(bracketType, SINGLE_LINE_TYPE) ) + breakLine(); + appendCurrentChar(); + + // if a declaration follows an enum definition, space pad + char peekedChar = peekNextChar(); + if (isLegalNameChar(peekedChar) + || peekedChar == '[') + appendSpaceAfter(); + } +} + +/** + * determine if a run-in can be attached. + * if it can insert the indents in formattedLine and reset the current line break. + */ +void ASFormatter::formatRunIn() +{ + assert(bracketFormatMode == HORSTMANN_MODE || bracketFormatMode == NONE_MODE); + + // keep one line blocks returns true without indenting the run-in + if (!isOkToBreakBlock(bracketTypeStack->back())) + return; // true; + + size_t lastText = formattedLine.find_last_not_of(" \t"); + if (lastText == string::npos || formattedLine[lastText] != '{') + return; // false; + + // make sure the bracket is broken + if (formattedLine.find_first_not_of(" \t{") != string::npos) + return; // false; + + if (isBracketType(bracketTypeStack->back(), NAMESPACE_TYPE)) + return; // false; + + bool extraIndent = false; + isInLineBreak = true; + + // cannot attach a class modifier without indent-classes + if (isCStyle() + && isCharPotentialHeader(currentLine, charNum) + && (isBracketType(bracketTypeStack->back(), CLASS_TYPE) + || (isBracketType(bracketTypeStack->back(), STRUCT_TYPE) + && isInIndentableStruct))) + { + if (findKeyword(currentLine, charNum, AS_PUBLIC) + || findKeyword(currentLine, charNum, AS_PRIVATE) + || findKeyword(currentLine, charNum, AS_PROTECTED)) + { + if (!getClassIndent()) + return; // false; + } + else if (getClassIndent()) + extraIndent = true; + } + + // cannot attach a 'case' statement without indent-switches + if (!getSwitchIndent() + && isCharPotentialHeader(currentLine, charNum) + && (findKeyword(currentLine, charNum, AS_CASE) + || findKeyword(currentLine, charNum, AS_DEFAULT))) + return; // false; + + // extra indent for switch statements + if (getSwitchIndent() + && !preBracketHeaderStack->empty() + && preBracketHeaderStack->back() == &AS_SWITCH + && ((isLegalNameChar(currentChar) + && !findKeyword(currentLine, charNum, AS_CASE)) + || isSequenceReached("//") + || isSequenceReached("/*"))) + 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 (getIndentString() == "\t") + { + appendChar('\t', false); + horstmannIndentChars = 2; // one for { and one for tab + if (extraIndent) + { + appendChar('\t', false); + horstmannIndentChars++; + } + } + else + { + int indent = getIndentLength(); + formattedLine.append(indent-1, ' '); + horstmannIndentChars = indent; + if (extraIndent) + { + formattedLine.append(indent, ' '); + horstmannIndentChars += indent; + } + } + isInHorstmannRunIn = true; +} + +/** + * remove whitepace and add indentation for an array run-in. + */ +void ASFormatter::formatArrayRunIn() +{ + assert(isBracketType(bracketTypeStack->back(), ARRAY_TYPE)); + + // make sure the bracket is broken + if (formattedLine.find_first_not_of(" \t{") != string::npos) + return; + + size_t lastText = formattedLine.find_last_not_of(" \t"); + if (lastText == string::npos || formattedLine[lastText] != '{') + return; + + // check for extra whitespace + if (formattedLine.length() > lastText+1 + && formattedLine.find_first_not_of(" \t", lastText+1) == string::npos) + formattedLine.erase(lastText+1); + + if (getIndentString() == "\t") + { + appendChar('\t', false); + horstmannIndentChars = 2; // one for { and one for tab + } + else + { + int indent = getIndentLength(); + formattedLine.append(indent-1, ' '); + horstmannIndentChars = indent; + } + isInHorstmannRunIn = true; + isInLineBreak = false; +} + +/** + * delete a bracketTypeStack vector object + * BracketTypeStack did not work with the DeleteContainer template + */ +void ASFormatter::deleteContainer(vector* &container) +{ + if (container != NULL) + { + container->clear(); + delete (container); + container = NULL; + } +} + +/** + * delete a vector object + * T is the type of vector + * used for all vectors except bracketTypeStack + */ +template +void ASFormatter::deleteContainer(T &container) +{ + if (container != NULL) + { + container->clear(); + delete (container); + container = NULL; + } +} + +/** + * initialize a BracketType vector object + * BracketType did not work with the DeleteContainer template + */ +void ASFormatter::initContainer(vector* &container, vector* value) +{ + if (container != NULL) + deleteContainer(container); + container = value; +} + +/** + * initialize a vector object + * T is the type of vector + * used for all vectors except bracketTypeStack + */ +template +void ASFormatter::initContainer(T &container, T value) +{ + // since the ASFormatter object is never deleted, + // the existing vectors must be deleted before creating new ones + if (container != NULL) + deleteContainer(container); + container = value; +} + +/** + * convert a tab to spaces. + * charNum points to the current character to convert to spaces. + * tabIncrementIn is the increment that must be added for tab indent characters + * to get the correct column for the current tab. + * replaces the tab in currentLine with the required number of spaces. + * replaces the value of currentChar. + */ +void ASFormatter::convertTabToSpaces() +{ + assert(currentLine[charNum] == '\t'); + + // do NOT replace if in quotes + if (isInQuote || isInQuoteContinuation) + return; + + size_t indent = getIndentLength(); + size_t numSpaces = indent - ((tabIncrementIn + charNum) % indent); + currentLine.replace(charNum, 1, numSpaces, ' '); + currentChar = currentLine[charNum]; +} + +/** +* is it ok to break this block? +*/ +bool ASFormatter::isOkToBreakBlock(BracketType bracketType) const +{ + // Actually, there should not be an ARRAY_TYPE bracket here. + // But this will avoid breaking a one line block when there is. + // Otherwise they will be formatted differently on consecutive runs. + if (isBracketType(bracketType, ARRAY_TYPE) + && isBracketType(bracketType, SINGLE_LINE_TYPE)) + return false; + if (!isBracketType(bracketType, SINGLE_LINE_TYPE) + || shouldBreakOneLineBlocks + || breakCurrentOneLineBlock) + return true; + return false; +} + +/** +* check if a sharp header is a paren or nonparen header +*/ +bool ASFormatter::isSharpStyleWithParen(const string* header) const +{ + if (isSharpStyle() && peekNextChar() == '(' + && (header == &AS_CATCH + || header == &AS_DELEGATE)) + return true; + return false; +} + +/** + * check for a following header when a comment is reached. + * if a header follows, the comments are kept as part of the header block. + * firstLine must contain the start of the comment. + */ +void ASFormatter::checkForFollowingHeader(const string& firstLine) +{ + // look ahead to find the next non-comment text + string nextText = peekNextText(firstLine, true); + if (nextText.length() == 0 || !isCharPotentialHeader(nextText, 0)) + return; + + const string* newHeader = ASBeautifier::findHeader(nextText, 0, headers); + + if (newHeader == NULL) + return; + + // may need to break if a header follows + bool isClosingHeader = (newHeader == &AS_ELSE + || newHeader == &AS_CATCH + || newHeader == &AS_FINALLY); + + // if a closing header, reset break unless break is requested + if (isClosingHeader) + { + if (!shouldBreakClosingHeaderBlocks) + isPrependPostBlockEmptyLineRequested = false; + } + // if an opening header, break before the comment + else + { + isPrependPostBlockEmptyLineRequested = true; + } +} + +/** + * process preprocessor statements. + * charNum should be the index of the preprocessor directive. + * + * delete bracketTypeStack entries added by #if if a #else is found. + * prevents double entries in the bracketTypeStack. + */ +void ASFormatter::processPreprocessor() +{ + assert(currentChar == '#'); + + const int preproc = charNum + 1; + + if (currentLine.compare(preproc, 2, "if") == 0) + { + preprocBracketTypeStackSize = bracketTypeStack->size(); + } + else if (currentLine.compare(preproc, 4, "else") == 0) + { + // delete stack entries added in #if + // should be replaced by #else + if (preprocBracketTypeStackSize > 0) + { + int addedPreproc = bracketTypeStack->size() - preprocBracketTypeStackSize; + for (int i=0; i < addedPreproc; i++) + bracketTypeStack->pop_back(); + } + } +} + +/** + * determine if the next line starts a comment + * and a header follows the comment or comments + */ +bool ASFormatter::commentAndHeaderFollows() const +{ + // is the next line a comment + string nextLine = sourceIterator->peekNextLine(); + size_t firstChar = nextLine.find_first_not_of(" \t"); + if (firstChar == string::npos + || !(nextLine.compare(firstChar, 2, "//") == 0 + || nextLine.compare(firstChar, 2, "/*") == 0)) + { + sourceIterator->peekReset(); + return false; + } + + // if next line is a comment, find the next non-comment text + string nextText = peekNextText(nextLine, true); + if (nextText.length() == 0 || !isCharPotentialHeader(nextText, 0)) + return false; + + const string* newHeader = ASBeautifier::findHeader(nextText, 0, headers); + + if (newHeader == NULL) + return false; + + bool isClosingHeader = (newHeader == &AS_ELSE + || newHeader == &AS_CATCH + || newHeader == &AS_FINALLY); + + if (isClosingHeader && !shouldBreakClosingHeaderBlocks) + return false; + + return true; +} + +/** + * determine if a bracket should be attached or broken + * uses brackets in the bracketTypeStack + * the last bracket in the bracketTypeStack is the one being formatted + * returns true if the bracket should be broken + */ +bool ASFormatter::isCurrentBracketBroken() const +{ + assert(bracketTypeStack->size() > 0); + + bool breakBracket = false; + size_t bracketTypeStackEnd = bracketTypeStack->size()-1; + + if (isBracketType((*bracketTypeStack)[bracketTypeStackEnd], EXTERN_TYPE)) + { + if (currentLineBeginsWithBracket + || bracketFormatMode == HORSTMANN_MODE) + breakBracket = true; + } + else if (bracketFormatMode == NONE_MODE) + { + if (currentLineBeginsWithBracket + && (int)currentLineFirstBracketNum == charNum) // lineBeginsWith('{') + breakBracket = true; + } + else if (bracketFormatMode == BREAK_MODE || bracketFormatMode == HORSTMANN_MODE) + { + breakBracket = true; + } + else if (bracketFormatMode == LINUX_MODE || bracketFormatMode == STROUSTRUP_MODE) + { + // break a class if Linux + if (isBracketType((*bracketTypeStack)[bracketTypeStackEnd], CLASS_TYPE)) + { + if (bracketFormatMode == LINUX_MODE) + breakBracket = true; + } + // break a namespace or interface if Linux + else if (isBracketType((*bracketTypeStack)[bracketTypeStackEnd], NAMESPACE_TYPE) + || isBracketType((*bracketTypeStack)[bracketTypeStackEnd], INTERFACE_TYPE)) { + if (bracketFormatMode == LINUX_MODE) + breakBracket = true; + } + // break the first bracket if a function + else if (bracketTypeStackEnd == 1 + && isBracketType((*bracketTypeStack)[bracketTypeStackEnd], COMMAND_TYPE)) + { + breakBracket = true; + } + else if (bracketTypeStackEnd > 1) + { + // break the first bracket after a namespace or extern if a function + if (isBracketType((*bracketTypeStack)[bracketTypeStackEnd-1], NAMESPACE_TYPE) + || isBracketType((*bracketTypeStack)[bracketTypeStackEnd-1], EXTERN_TYPE)) + { + if (isBracketType((*bracketTypeStack)[bracketTypeStackEnd], COMMAND_TYPE)) + breakBracket = true; + } + // if not C style then break the first bracket after a class if a function + else if (!isCStyle()) + { + if ((isBracketType((*bracketTypeStack)[bracketTypeStackEnd-1], CLASS_TYPE) + || isBracketType((*bracketTypeStack)[bracketTypeStackEnd-1], ARRAY_TYPE) + || isBracketType((*bracketTypeStack)[bracketTypeStackEnd-1], STRUCT_TYPE)) + && isBracketType((*bracketTypeStack)[bracketTypeStackEnd], COMMAND_TYPE)) + breakBracket = true; + } + } + } + return breakBracket; +} + +/** + * format comment body + * the calling function should have a continue statement after calling this method + */ +void ASFormatter::formatCommentBody() +{ + assert(isInComment); + + if (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) + && isOkToBreakBlock(bracketTypeStack->back())) breakLine(); + } + else + { + appendCurrentChar(); + // append the comment up to the next tab or comment end + // tabs must be checked for convert-tabs before appending + while (charNum + 1 < (int) currentLine.length() + && currentLine[charNum+1] != '\t' + && currentLine.compare(charNum+1, 2, "*/") != 0) + { + currentChar = currentLine[++charNum]; appendCurrentChar(); } + } +} + +/** + * 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 = true; + isImmediatelyPostLineComment = false; + + if (spacePadNum != 0) + adjustComments(); + formattedLineCommentNum = formattedLine.length(); + + // must be done BEFORE appendSequence + if (previousCommandChar == '{' + && !isImmediatelyPostComment + && !isImmediatelyPostLineComment) + { + if (bracketFormatMode == NONE_MODE) + { + // should a run-in statement be attached? + if (currentLineBeginsWithBracket) + formatRunIn(); + } + else if (bracketFormatMode == ATTACH_MODE) + { + // if the bracket was not attached? + if (formattedLine[0] == '{' + && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE)) + isInLineBreak = true; + } + else if (bracketFormatMode == HORSTMANN_MODE) + { + // should a run-in statement be attached? + if (formattedLine[0] == '{') + formatRunIn(); + } + } + else if (!doesLineStartComment) + noTrimCommentContinuation = true; + + // appendSequence will write the previous line + appendSequence(AS_OPEN_COMMENT); + goForward(1); + + // must be done AFTER appendSequence + if (shouldBreakBlocks) + { + // break before the comment if a header follows the comment + // for speed, do not check if previous line is empty, + // if previous line is a line comment or if previous line is '{' + if (doesLineStartComment + && !isImmediatelyPostEmptyLine + && !isImmediatelyPostComment + && !isImmediatelyPostLineComment + && previousCommandChar != '{') + { + checkForFollowingHeader(currentLine.substr(charNum-1)); + } + } + + if (previousCommandChar == '}') + currentHeader = NULL; +} + +/** + * format a line comment body + * the calling function should have a continue statement after calling this method + */ +void ASFormatter::formatLineCommentBody() +{ + assert(isInLineComment); + + appendCurrentChar(); + // append the comment up to the next tab + // tabs must be checked for convert-tabs before appending + while (charNum + 1 < (int) currentLine.length() + && currentLine[charNum+1] != '\t') + { + currentChar = currentLine[++charNum]; + appendCurrentChar(); + } + + // explicitely 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 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 (currentLine[charNum+2] == '\xf2') // check for windows line marker + isAppendPostBlockEmptyLineRequested = false; + + isInLineComment = true; + isCharImmediatelyPostComment = false; + + // do not indent if in column 1 or 2 + if (!shouldIndentCol1Comments && !lineCommentNoIndent) + { + if (charNum == 0) + lineCommentNoIndent = true; + else if (charNum == 1 && currentLine[0] == ' ') + lineCommentNoIndent = true; + } + // move comment if spaces were added or deleted + if (lineCommentNoIndent == false && spacePadNum != 0) + adjustComments(); + formattedLineCommentNum = formattedLine.length(); + + // must be done BEFORE appendSequence + // check for run-in statement + if (previousCommandChar == '{' + && !isImmediatelyPostComment + && !isImmediatelyPostLineComment) + { + if (bracketFormatMode == NONE_MODE) + { + if (currentLineBeginsWithBracket) + formatRunIn(); + } + else if (bracketFormatMode == HORSTMANN_MODE) + { + if (!lineCommentNoIndent) + formatRunIn(); + else + isInLineBreak = true; + } + else if (bracketFormatMode == BREAK_MODE) + { + if (formattedLine[0] == '{') + isInLineBreak = true; + } else + { + if (currentLineBeginsWithBracket) + isInLineBreak = true; + } + } + + // appendSequence will write the previous line + appendSequence(AS_OPEN_LINE_COMMENT); + goForward(1); + + if (formattedLine.compare(0, 2, "//") == 0) + lineIsLineCommentOnly = true; + + // must be done AFTER appendSequence + if (shouldBreakBlocks) + { + // break before the comment if a header follows the line comment + // for speed, do not check if previous line is empty, + // if previous line is a comment or if previous line is '{' + if (lineIsLineCommentOnly + && previousCommandChar != '{' + && !isImmediatelyPostEmptyLine + && !isImmediatelyPostComment + && !isImmediatelyPostLineComment) + { + checkForFollowingHeader(currentLine.substr(charNum-1)); + } + } + + if (previousCommandChar == '}') + currentHeader = NULL; + + // if tabbed input don't convert the immediately following tabs to spaces + if (getIndentString() == "\t" && lineCommentNoIndent) + { + while (charNum + 1 < (int) currentLine.length() + && currentLine[charNum+1] == '\t') + { + currentChar = currentLine[++charNum]; appendCurrentChar(); + } + } + + // explicitely 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 (peekNextChar() == '"') // check consecutive quotes + { + appendSequence("\"\""); + goForward(1); + return; + } + else + { + isInQuote = false; + isInVerbatimQuote = false; + } + } + else if (quoteChar == currentChar) + { + isInQuote = false; + } + + appendCurrentChar(); + + // append the text to the ending quoteChar or an escape sequence + // tabs in quotes are NOT changed by convert-tabs + if (isInQuote && currentChar != '\\') + { + while (charNum + 1 < (int) currentLine.length() + && currentLine[charNum+1] != quoteChar + && currentLine[charNum+1] != '\\') + { + currentChar = currentLine[++charNum]; + appendCurrentChar(); + } + } +} + +/** + * format a quote opener + * the quote opener will be appended to the current formattedLine or a new formattedLine as necessary + * the calling function should have a continue statement after calling this method + */ +void ASFormatter::formatQuoteOpener() +{ + assert(currentChar == '"' || currentChar == '\''); + + isInQuote = true; + quoteChar = currentChar; + if (isSharpStyle() && previousChar == '@') + isInVerbatimQuote = true; + + // a quote following a bracket is an array + if (previousCommandChar == '{' + && !isImmediatelyPostComment + && !isImmediatelyPostLineComment + && isNonInStatementArray + && !isBracketType(bracketTypeStack->back(), SINGLE_LINE_TYPE) + && !isWhiteSpace(peekNextChar())) + { + if (bracketFormatMode == NONE_MODE) + { + if (currentLineBeginsWithBracket) + formatRunIn(); + } + else if (bracketFormatMode == HORSTMANN_MODE) + { + if (!lineCommentNoIndent) + formatRunIn(); + else + isInLineBreak = true; + } + else if (bracketFormatMode == BREAK_MODE) + { + if (formattedLine[0] == '{') + isInLineBreak = true; + } + else + { + if (currentLineBeginsWithBracket) + isInLineBreak = true; + } + } + previousCommandChar = ' '; + appendCurrentChar(); +} + +/** + * get the next line comment adjustment that results from breaking a closing bracket. + * the bracket must be on the same line as the closing header. + * i.e "} else" changed to "} \n else". + */ +int ASFormatter::getNextLineCommentAdjustment() +{ + assert(foundClosingHeader && previousNonWSChar == '}'); + if (charNum < 1) + return 0; + size_t lastBracket = currentLine.rfind('}', charNum - 1); + if (lastBracket != string::npos) + return (lastBracket - charNum); // return a negative number + return 0; +} + +LineEndFormat ASFormatter::getLineEndFormat() const +{ + return lineEnd; +} + +/** + * get the current line comment adjustment that results from attaching + * a closing header to a closing bracket. + * the bracket must be on the line previous to the closing header. + * the adjustment is 2 chars, one for the bracket and one for the space. + * i.e "} \n else" changed to "} else". + */ +int ASFormatter::getCurrentLineCommentAdjustment() +{ + assert(foundClosingHeader && previousNonWSChar == '}'); + if (charNum < 1) + return 2; + size_t lastBracket = currentLine.rfind('}', charNum - 1); + if (lastBracket == string::npos) + return 2; + return 0; +} + +/** + * get the previous word + * the argument 'end' must point to the search start. + * + * @return is the previous word. + */ +string ASFormatter::getPreviousWord(const string& line, int currPos) const +{ + // get the last legal word (may be a number) + if (currPos == 0) + return string(); + + size_t end = line.find_last_not_of(" \t", currPos-1); + if (end == string::npos || !isLegalNameChar(line[end])) + return string(); + + int start; // start of the previous word + for (start = end; start > -1; start--) + { + if (!isLegalNameChar(line[start]) || line[start] == '.') + break; + } + start++; + + return (line.substr(start, end-start+1)); +} + +/** + * check if a line break is needed when a closing bracket + * is followed by a closing header. + * the break depends on the bracketFormatMode and other factors. + */ +void ASFormatter::isLineBreakBeforeClosingHeader() +{ + assert(foundClosingHeader && previousNonWSChar == '}'); + if (bracketFormatMode == BREAK_MODE || bracketFormatMode == HORSTMANN_MODE) + { + isInLineBreak = true; + } + else if (bracketFormatMode == NONE_MODE) + { + if (shouldBreakClosingHeaderBrackets + || getBracketIndent() || getBlockIndent()) + { + isInLineBreak = true; + } + else + { + appendSpacePad(); + // is closing bracket broken? + size_t i = currentLine.find_first_not_of(" \t"); + if (i != string::npos && currentLine[i] == '}') + isInLineBreak = false; + + if (shouldBreakBlocks) + isAppendPostBlockEmptyLineRequested = false; + } + } + // bracketFormatMode == ATTACH_MODE, LINUX_MODE, STROUSTRUP_MODE + else + { + if (shouldBreakClosingHeaderBrackets + || getBracketIndent() || getBlockIndent()) + { + isInLineBreak = true; + } + else + { + // if a blank line does not preceed this + // or last line is not a one line block, attach header + bool previousLineIsEmpty = isEmptyLine(formattedLine); + bool previousLineIsOneLineBlock = false; + size_t firstBracket = findNextChar(formattedLine, '{'); + if (firstBracket != string::npos) + previousLineIsOneLineBlock = isOneLineBlockReached(formattedLine, firstBracket); + if (!previousLineIsEmpty + && !previousLineIsOneLineBlock) + { + isInLineBreak = false; + appendSpacePad(); + spacePadNum = 0; // don't count as comment padding + } + + if (shouldBreakBlocks) + isAppendPostBlockEmptyLineRequested = false; + } } } +/** + * Add brackets to a single line statement following a header. + * Brackets are not added if the proper conditions are not met. + * Brackets are added to the currentLine. + */ +bool ASFormatter::addBracketsToStatement() +{ + assert(isImmediatelyPostHeader); + + if (currentHeader != &AS_IF + && currentHeader != &AS_ELSE + && currentHeader != &AS_FOR + && currentHeader != &AS_WHILE + && currentHeader != &AS_DO + && currentHeader != &AS_FOREACH) + return false; + + // do not add if a header follows (i.e. else if) + if (isCharPotentialHeader(currentLine, charNum)) + if (findHeader(headers) != NULL) + return false; + + // find the next semi-colon + size_t nextSemiColon = findNextChar(currentLine, ';', charNum+1); + if (nextSemiColon == string::npos) + return false; + + // add closing bracket before changing the line length + if (nextSemiColon == currentLine.length() - 1) + currentLine.append(" }"); + else + currentLine.insert(nextSemiColon + 1, " }"); + // add opening bracket + currentLine.insert(charNum, "{ "); + currentChar = '{'; + // remove extra spaces + if (!shouldAddOneLineBrackets) + { + size_t lastText = formattedLine.find_last_not_of(" \t"); + if ((formattedLine.length() - 1) - lastText > 1) + formattedLine.erase(lastText + 1); + } + return true; +} + +/** + * 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 char to find. + * @return the position on the line or string::npos if not found. + */ +size_t ASFormatter::findNextChar(string& line, char searchChar, int searchStart /*0*/) +{ + // 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 (line[i] == '\'' || line[i] == '\"') + { + char quote = line[i]; + while (i < line.length()) + { + size_t endQuote = line.find(quote, i+1); + if (endQuote == string::npos) + return string::npos; + i = endQuote; + if (line[endQuote-1] != '\\') // check for '\"' + break; + if (line[endQuote-2] == '\\') // check for '\\' + break; + } + } + + if (line[i] == searchChar) + break; + + // for now don't process C# 'delegate' brackets + // do this last in case the search char is a '{' + if (line[i] == '{') + return string::npos; + } + if (i >= line.length()) // didn't find searchChar + return string::npos; + + return i; +} + +/** + * Look ahead in the file to see if a struct has access modifiers. + * + * @param line a reference to the line to indent. + * @param index the current line index. + * @return true if the struct has access modifiers. + */ +bool ASFormatter::isStructAccessModified(string &firstLine, size_t index) const +{ + assert(firstLine[index] == '{'); + assert(isCStyle()); + + bool isFirstLine = true; + bool needReset = false; + size_t bracketCount = 1; + string nextLine = firstLine.substr(index + 1); + + // find the first non-blank text, bypassing all comments. + bool isInComment = false; + while (sourceIterator->hasMoreLines()) + { + if (isFirstLine) + isFirstLine = false; + else + { + nextLine = sourceIterator->peekNextLine(); + needReset = true; + } + // parse the line + for (size_t i = 0; i < nextLine.length(); i++) + { + if (isWhiteSpace(nextLine[i])) + continue; + if (nextLine.compare(i, 2, "/*") == 0) + isInComment = true; + if (isInComment) + { + i = nextLine.find("*/", i); + if (i == string::npos) + { + i = nextLine.length(); + continue; + } + i++; + isInComment = false; + continue; + } + if (nextLine.compare(i, 2, "//") == 0) + { + i = nextLine.length(); + continue; + } + // handle brackets + if (nextLine[i] == '{') + bracketCount++; + if (nextLine[i] == '}') + bracketCount--; + if (bracketCount == 0) + { + if (needReset) + sourceIterator->peekReset(); + return false; + } + // check for access modifiers + if (isCharPotentialHeader(nextLine, i)) + { + if (findKeyword(nextLine, i, AS_PUBLIC) + || findKeyword(nextLine, i, AS_PRIVATE) + || findKeyword(nextLine, i, AS_PROTECTED)) + { + if (needReset) + sourceIterator->peekReset(); + return true; + } + string name = getCurrentWord(nextLine, i); + i += name.length() - 1; + } + } // end of for loop + } // end of while loop + + if (needReset) + sourceIterator->peekReset(); + return false; +} + +/** + * Check to see if this is an EXEC SQL statement. + * + * @param line a reference to the line to indent. + * @param index the current line index. + * @return true if the statement is EXEC SQL. + */ +bool ASFormatter::isExecSQL(string &line, size_t index) const +{ + if (line[index] != 'e' && line[index] != 'E') // quick check to reject most + return false; + string word; + if (isCharPotentialHeader(line, index)) + word = getCurrentWord(line, index); + for (size_t i = 0; i < word.length(); i++) + word[i] = (char) toupper(word[i]); + if (word != "EXEC") + return false; + size_t index2 = index + word.length(); + index2 = line.find_first_not_of(" \t", index2); + if (index2 == string::npos) + return false; + word.erase(); + if (isCharPotentialHeader(line, index2)) + word = getCurrentWord(line, index2); + for (size_t i = 0; i < word.length(); i++) + word[i] = (char) toupper(word[i]); + if (word != "SQL") + return false; + return true; +} + +/** + * The continuation lines must be adjusted so the leading spaces + * is equivalent to the text on the opening line. + * + * Updates currentLine and charNum. + */ +void ASFormatter::trimContinuationLine() +{ + size_t len = currentLine.length(); + size_t indent = getIndentLength(); + 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 + { + i = 0; + continuationIncrementIn = tabIncrementIn; + break; + } + if (currentLine[i] == '\t') + continuationIncrementIn += indent - 1 - ((continuationIncrementIn + i) % indent); + } + + 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 (i >= len) + charNum = 0; + } + return; +} + } // end namespace astyle diff --git a/kdev-pg/ASLocalizer.h b/kdev-pg/ASLocalizer.h new file mode 100644 --- /dev/null +++ b/kdev-pg/ASLocalizer.h @@ -0,0 +1,159 @@ +// ASLocalizer.h +// Copyright (c) 2016 by Jim Pattee . +// This code is licensed under the MIT License. +// License.txt describes the conditions under which this software may be distributed. + + +#ifndef ASLOCALIZER_H +#define ASLOCALIZER_H + +#include +#include + +namespace astyle { + +using namespace std; + +#ifndef ASTYLE_LIB + +//----------------------------------------------------------------------------- +// ASLocalizer class for console build. +// This class encapsulates all language-dependent settings and is a +// generalization of the C locale concept. +//----------------------------------------------------------------------------- +class Translation; + +class ASLocalizer +{ +public: // functions + ASLocalizer(); + virtual ~ASLocalizer(); + string getLanguageID() const; + const Translation* getTranslationClass() const; +#ifdef _WIN32 + void setLanguageFromLCID(size_t lcid); +#endif + void setLanguageFromName(const char* langID); + const char* settext(const char* textIn) const; + +private: // functions + void setTranslationClass(); + +private: // variables + Translation* m_translation; // pointer to a polymorphic Translation class + string m_langID; // language identifier from the locale + string m_subLangID; // sub language identifier, if needed + string m_localeName; // name of the current locale (Linux only) + size_t m_lcid; // LCID of the user locale (Windows only) +}; + +//---------------------------------------------------------------------------- +// Translation base class. +//---------------------------------------------------------------------------- + +class Translation +// This base class is inherited by the language translation classes. +// Polymorphism is used to call the correct language translator. +// This class contains the translation vector and settext translation method. +// The language vector is built by the language sub classes. +// NOTE: This class must have virtual methods for typeid() to work. +// typeid() is used by AStyleTestI18n_Localizer.cpp. +{ +public: + Translation() {} + virtual ~Translation() {} + string convertToMultiByte(const wstring& wideStr) const; + size_t getTranslationVectorSize() const; + bool getWideTranslation(const string& stringIn, wstring& wideOut) const; + string& translate(const string& stringIn) const; + +protected: + void addPair(const string& english, const wstring& translated); + // variables + vector > m_translation; // translation vector + +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/kdev-pg/ASLocalizer.cpp b/kdev-pg/ASLocalizer.cpp new file mode 100644 --- /dev/null +++ b/kdev-pg/ASLocalizer.cpp @@ -0,0 +1,1098 @@ +// ASLocalizer.cpp +// Copyright (c) 2016 by Jim Pattee . +// This code is licensed under the MIT License. +// License.txt 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; + + // Not all compilers support the C++ function locale::global(locale("")); + char* localeName = setlocale(LC_ALL, ""); + if (localeName == NULL) // use the english (ascii) defaults + { + fprintf(stderr, "\n%s\n\n", "Cannot set native locale, reverting to English"); + setTranslationClass(); + return; + } + // set the class variables +#ifdef _WIN32 + size_t lcid = GetUserDefaultLCID(); + setLanguageFromLCID(lcid); +#else + setLanguageFromName(localeName); +#endif +} + +ASLocalizer::~ASLocalizer() +// Delete dynamically allocated memory. +{ + delete m_translation; +} + +#ifdef _WIN32 + +struct WinLangCode +{ + size_t winLang; + char canonicalLang[3]; +}; + +static WinLangCode wlc[] = +// primary language identifier http://msdn.microsoft.com/en-us/library/aa912554.aspx +// sublanguage identifier http://msdn.microsoft.com/en-us/library/aa913256.aspx +// language ID http://msdn.microsoft.com/en-us/library/ee797784%28v=cs.20%29.aspx +{ + { LANG_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 + +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) + { + delete m_translation; + m_translation = NULL; + } + 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); +} + +string Translation::convertToMultiByte(const wstring& wideStr) const +// Convert wchar_t to a multibyte string using the currently assigned locale. +// Return an empty string if an error occurs. +{ + static bool msgDisplayed = false; + // get length of the output excluding the NULL and validate the parameters + size_t mbLen = wcstombs(NULL, wideStr.c_str(), 0); + if (mbLen == string::npos) + { + if (!msgDisplayed) + { + fprintf(stderr, "\n%s\n\n", "Cannot convert to multi-byte string, reverting to English"); + msgDisplayed = true; + } + return ""; + } + // convert the characters + char* mbStr = new (nothrow) char[mbLen + 1]; + if (mbStr == NULL) + { + if (!msgDisplayed) + { + fprintf(stderr, "\n%s\n\n", "Bad memory alloc for multi-byte string, reverting to English"); + msgDisplayed = true; + } + return ""; + } + wcstombs(mbStr, wideStr.c_str(), mbLen + 1); + // return the string + string mbTranslation = mbStr; + delete[] mbStr; + return mbTranslation; +} + +size_t Translation::getTranslationVectorSize() const +// Return the translation vector size. Used for testing. +{ + return m_translation.size(); +} + +bool Translation::getWideTranslation(const string& stringIn, wstring& wideOut) const +// Get the wide translation string. Used for testing. +{ + for (size_t i = 0; i < m_translation.size(); i++) + { + if (m_translation[i].first == stringIn) + { + wideOut = m_translation[i].second; + return true; + } + } + // not found + wideOut = L""; + return false; +} + +string& Translation::translate(const string& stringIn) const +// Translate a string. +// Return a 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("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 command line options:", L"Невалидни опции за командния ред:"); + addPair("For help on options type 'astyle -h'", L"За помощ относно възможностите тип 'astyle -h'"); + addPair("Cannot open options file", L"Не може да се отвори файл опции"); + addPair("Cannot open directory", L"Не може да се отвори директория"); + addPair("Cannot open HTML file %s\n", L"Не може да се отвори HTML файл %s\n"); + addPair("Command execute failure", L"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 е прекратено"); +} + +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("Exclude %s\n", L"排除 %s\n"); + addPair("Exclude (unmatched) %s\n", L"排除(无匹配项) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s 格式化 %s 未改变 "); + addPair(" seconds ", L" 秒 "); + addPair("%d min %d sec ", L"%d 分 %d 秒 "); + addPair("%s lines\n", L"%s 行\n"); + addPair("Using default options file %s\n", L"使用默认配置文件 %s\n"); + addPair("Opening HTML documentation %s\n", L"打开HTML文档 %s\n"); + addPair("Invalid option file options:", L"无效的配置文件选项:"); + addPair("Invalid command line options:", L"无效的命令行选项:"); + addPair("For help on options type 'astyle -h'", L"输入 'astyle -h' 以获得有关命令行的帮助"); + addPair("Cannot open options file", L"无法打开配置文件"); + addPair("Cannot open directory", L"无法打开目录"); + addPair("Cannot open HTML file %s\n", L"无法打开HTML文件 %s\n"); + addPair("Command execute failure", L"执行命令失败"); + addPair("Command is not installed", L"未安装命令"); + addPair("Missing filename in %s\n", L"在%s缺少文件名\n"); + addPair("Recursive option with no wildcard", L"递归选项没有通配符"); + addPair("Did you intend quote the filename", L"你打算引用文件名"); + addPair("No file to process %s\n", L"没有文件可处理 %s\n"); + addPair("Did you intend to use --recursive", L"你打算使用 --recursive"); + addPair("Cannot process UTF-32 encoding", L"不能处理UTF-32编码"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style 已经终止运行"); +} + +ChineseTraditional::ChineseTraditional() // 中文(繁體) +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"格式化 %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"未改變 %s\n"); // should align with formatted + addPair("Directory %s\n", L"目錄 %s\n"); + addPair("Exclude %s\n", L"排除 %s\n"); + addPair("Exclude (unmatched) %s\n", L"排除(無匹配項) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s 格式化 %s 未改變 "); + addPair(" seconds ", L" 秒 "); + addPair("%d min %d sec ", L"%d 分 %d 秒 "); + addPair("%s lines\n", L"%s 行\n"); + addPair("Using default options file %s\n", L"使用默認配置文件 %s\n"); + addPair("Opening HTML documentation %s\n", L"打開HTML文檔 %s\n"); + addPair("Invalid option file options:", L"無效的配置文件選項:"); + addPair("Invalid command line options:", L"無效的命令行選項:"); + addPair("For help on options type 'astyle -h'", L"輸入'astyle -h'以獲得有關命令行的幫助:"); + addPair("Cannot open options file", L"無法打開配置文件"); + addPair("Cannot open directory", L"無法打開目錄"); + addPair("Cannot open HTML file %s\n", L"無法打開HTML文件 %s\n"); + addPair("Command execute failure", L"執行命令失敗"); + addPair("Command is not installed", L"未安裝命令"); + addPair("Missing filename in %s\n", L"在%s缺少文件名\n"); + addPair("Recursive option with no wildcard", L"遞歸選項沒有通配符"); + addPair("Did you intend quote the filename", L"你打算引用文件名"); + addPair("No file to process %s\n", L"沒有文件可處理 %s\n"); + addPair("Did you intend to use --recursive", L"你打算使用 --recursive"); + addPair("Cannot process UTF-32 encoding", L"不能處理UTF-32編碼"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style 已經終止運行"); +} + +Dutch::Dutch() // Nederlandse +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Geformatteerd %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Onveranderd %s\n"); // should align with formatted + addPair("Directory %s\n", L"Directory %s\n"); + addPair("Exclude %s\n", L"Uitsluiten %s\n"); + addPair("Exclude (unmatched) %s\n", L"Uitgesloten (ongeëvenaarde) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s geformatteerd %s onveranderd "); + addPair(" seconds ", L" seconden "); + addPair("%d min %d sec ", L"%d min %d sec "); + addPair("%s lines\n", L"%s lijnen\n"); + addPair("Using default options file %s\n", L"Met behulp van standaard opties bestand %s\n"); + addPair("Opening HTML documentation %s\n", L"Het openen van HTML-documentatie %s\n"); + addPair("Invalid option file options:", L"Ongeldige optie file opties:"); + addPair("Invalid command line options:", L"Ongeldige command line opties:"); + addPair("For help on options type 'astyle -h'", L"Voor hulp bij 'astyle-h' opties het type"); + addPair("Cannot open options file", L"Kan niet worden geopend options bestand"); + addPair("Cannot open directory", L"Kan niet open directory"); + addPair("Cannot open HTML file %s\n", L"Kan HTML-bestand niet openen %s\n"); + addPair("Command execute failure", L"Voeren commando falen"); + addPair("Command is not installed", L"Command is niet geïnstalleerd"); + addPair("Missing filename in %s\n", L"Ontbrekende bestandsnaam in %s\n"); + addPair("Recursive option with no wildcard", L"Recursieve optie met geen wildcard"); + addPair("Did you intend quote the filename", L"Heeft u van plan citaat van de bestandsnaam"); + addPair("No file to process %s\n", L"Geen bestand te verwerken %s\n"); + addPair("Did you intend to use --recursive", L"Hebt u van plan bent te gebruiken --recursive"); + addPair("Cannot process UTF-32 encoding", L"Kan niet verwerken UTF-32 codering"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style heeft beëindigd"); +} + +English::English() +// this class is NOT translated +{} + +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("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 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 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"); +} + +Finnish::Finnish() // Suomeksi +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Muotoiltu %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Ennallaan %s\n"); // should align with formatted + addPair("Directory %s\n", L"Directory %s\n"); + addPair("Exclude %s\n", L"Sulkea %s\n"); + addPair("Exclude (unmatched) %s\n", L"Sulkea (verraton) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s muotoiltu %s ennallaan "); + addPair(" seconds ", L" sekuntia "); + addPair("%d min %d sec ", L"%d min %d sek "); + addPair("%s lines\n", L"%s linjat\n"); + addPair("Using default options file %s\n", L"Käyttämällä oletusasetuksia tiedosto %s\n"); + addPair("Opening HTML documentation %s\n", L"Avaaminen HTML asiakirjat %s\n"); + addPair("Invalid option file options:", L"Virheellinen vaihtoehto tiedosto vaihtoehtoja:"); + addPair("Invalid command line options:", L"Virheellinen komentorivin:"); + addPair("For help on options type 'astyle -h'", L"Apua vaihtoehdoista tyyppi 'astyle -h'"); + addPair("Cannot open options file", L"Ei voi avata vaihtoehtoja tiedostoa"); + addPair("Cannot open directory", L"Ei Open Directory"); + addPair("Cannot open HTML file %s\n", L"Ei voi avata HTML-tiedoston %s\n"); + addPair("Command execute failure", L"Suorita komento vika"); + addPair("Command is not installed", L"Komento ei ole asennettu"); + addPair("Missing filename in %s\n", L"Puuttuvat tiedostonimi %s\n"); + addPair("Recursive option with no wildcard", L"Rekursiivinen vaihtoehto ilman wildcard"); + addPair("Did you intend quote the filename", L"Oletko aio lainata tiedostonimi"); + addPair("No file to process %s\n", L"Ei tiedostoa käsitellä %s\n"); + addPair("Did you intend to use --recursive", L"Oliko aiot käyttää --recursive"); + addPair("Cannot process UTF-32 encoding", L"Ei voi käsitellä UTF-32 koodausta"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style on päättynyt"); +} + +French::French() // Française +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Formaté %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Inchangée %s\n"); // should align with formatted + addPair("Directory %s\n", L"Répertoire %s\n"); + addPair("Exclude %s\n", L"Exclure %s\n"); + addPair("Exclude (unmatched) %s\n", L"Exclure (non appariés) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s formaté %s inchangée "); + addPair(" seconds ", L" seconde "); + addPair("%d min %d sec ", L"%d min %d sec "); + addPair("%s lines\n", L"%s lignes\n"); + addPair("Using default options file %s\n", L"Options par défaut utilisation du fichier %s\n"); + addPair("Opening HTML documentation %s\n", L"Ouverture documentation HTML %s\n"); + addPair("Invalid option file options:", L"Options Blancs option du fichier:"); + addPair("Invalid command line options:", L"Blancs options ligne de commande:"); + addPair("For help on options type 'astyle -h'", L"Pour de l'aide sur les options tapez 'astyle -h'"); + addPair("Cannot open options file", L"Impossible d'ouvrir le fichier d'options"); + addPair("Cannot open directory", L"Impossible d'ouvrir le répertoire"); + addPair("Cannot open HTML file %s\n", L"Impossible d'ouvrir le fichier HTML %s\n"); + addPair("Command execute failure", L"Exécuter échec de la commande"); + addPair("Command is not installed", L"Commande n'est pas installé"); + addPair("Missing filename in %s\n", L"Nom de fichier manquant dans %s\n"); + addPair("Recursive option with no wildcard", L"Option récursive sans joker"); + addPair("Did you intend quote the filename", L"Avez-vous l'intention de citer le nom de fichier"); + addPair("No file to process %s\n", L"Aucun fichier à traiter %s\n"); + addPair("Did you intend to use --recursive", L"Avez-vous l'intention d'utiliser --recursive"); + addPair("Cannot process UTF-32 encoding", L"Impossible de traiter codage UTF-32"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style a mis fin"); +} + +German::German() // Deutsch +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Formatiert %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Unverändert %s\n"); // should align with formatted + addPair("Directory %s\n", L"Verzeichnis %s\n"); + addPair("Exclude %s\n", L"Ausschließen %s\n"); + addPair("Exclude (unmatched) %s\n", L"Ausschließen (unerreichte) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s formatiert %s unverändert "); + addPair(" seconds ", L" sekunden "); + addPair("%d min %d sec ", L"%d min %d sek "); + addPair("%s lines\n", L"%s linien\n"); + addPair("Using default options file %s\n", L"Mit Standard-Optionen Dat %s\n"); + addPair("Opening HTML documentation %s\n", L"Öffnen HTML-Dokumentation %s\n"); + addPair("Invalid option file options:", L"Ungültige Option Datei-Optionen:"); + addPair("Invalid command line options:", L"Ungültige Kommandozeilen-Optionen:"); + addPair("For help on options type 'astyle -h'", L"Für Hilfe zu den Optionen geben Sie 'astyle -h'"); + addPair("Cannot open options file", L"Kann nicht geöffnet werden Optionsdatei"); + addPair("Cannot open directory", L"Kann nicht geöffnet werden Verzeichnis"); + addPair("Cannot open HTML file %s\n", L"Kann nicht öffnen HTML-Datei %s\n"); + addPair("Command execute failure", L"Execute Befehl Scheitern"); + addPair("Command is not installed", L"Befehl ist nicht installiert"); + addPair("Missing filename in %s\n", L"Missing in %s Dateiname\n"); + addPair("Recursive option with no wildcard", L"Rekursive Option ohne Wildcard"); + addPair("Did you intend quote the filename", L"Haben Sie die Absicht Inhalte der Dateiname"); + addPair("No file to process %s\n", L"Keine Datei zu verarbeiten %s\n"); + addPair("Did you intend to use --recursive", L"Haben Sie verwenden möchten --recursive"); + addPair("Cannot process UTF-32 encoding", L"Nicht verarbeiten kann UTF-32 Codierung"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style ist beendet"); +} + +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("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 command line options:", L"Μη έγκυρη επιλογές γραμμής εντολών:"); + addPair("For help on options type 'astyle -h'", L"Για βοήθεια σχετικά με το είδος επιλογές 'astyle -h'"); + addPair("Cannot open options file", L"Δεν μπορείτε να ανοίξετε το αρχείο επιλογών"); + addPair("Cannot open directory", L"Δεν μπορείτε να ανοίξετε τον κατάλογο"); + addPair("Cannot open HTML file %s\n", L"Δεν μπορείτε να ανοίξετε το αρχείο HTML %s\n"); + addPair("Command execute failure", L"Εντολή να εκτελέσει την αποτυχία"); + addPair("Command is not installed", L"Η εντολή δεν έχει εγκατασταθεί"); + addPair("Missing filename in %s\n", L"Λείπει το όνομα αρχείου σε %s\n"); + addPair("Recursive option with no wildcard", L"Αναδρομικές επιλογή χωρίς μπαλαντέρ"); + addPair("Did you intend quote the filename", L"Μήπως σκοπεύετε να αναφέρετε το όνομα του αρχείου"); + addPair("No file to process %s\n", L"Δεν υπάρχει αρχείο για την επεξεργασία %s\n"); + addPair("Did you intend to use --recursive", L"Μήπως σκοπεύετε να χρησιμοποιήσετε --recursive"); + addPair("Cannot process UTF-32 encoding", L"δεν μπορεί να επεξεργαστεί UTF-32 κωδικοποίηση"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style έχει λήξει"); +} + +Hindi::Hindi() // हिन्दी +// build the translation vector in the Translation base class +{ + // NOTE: Scintilla based editors (CodeBlocks) cannot always edit Hindi. + // Use Visual Studio instead. + addPair("Formatted %s\n", L"स्वरूपित किया %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"अपरिवर्तित %s\n"); // should align with formatted + addPair("Directory %s\n", L"निर्देशिका %s\n"); + addPair("Exclude %s\n", L"निकालना %s\n"); + addPair("Exclude (unmatched) %s\n", L"अपवर्जित (बेजोड़) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s स्वरूपित किया %s अपरिवर्तित "); + addPair(" seconds ", L" सेकंड "); + addPair("%d min %d sec ", L"%d मिनट %d सेकंड "); + addPair("%s lines\n", L"%s लाइनों\n"); + addPair("Using default options file %s\n", L"डिफ़ॉल्ट विकल्प का उपयोग कर फ़ाइल %s\n"); + addPair("Opening HTML documentation %s\n", L"एचटीएमएल प्रलेखन खोलना %s\n"); + addPair("Invalid option file options:", L"अवैध विकल्प फ़ाइल विकल्प हैं:"); + addPair("Invalid command line options:", L"कमांड लाइन विकल्प अवैध:"); + addPair("For help on options type 'astyle -h'", L"विकल्पों पर मदद के लिए प्रकार 'astyle -h'"); + addPair("Cannot open options file", L"विकल्प फ़ाइल नहीं खोल सकता है"); + addPair("Cannot open directory", L"निर्देशिका नहीं खोल सकता"); + addPair("Cannot open HTML file %s\n", L"HTML फ़ाइल नहीं खोल सकता %s\n"); + addPair("Command execute failure", L"आदेश विफलता निष्पादित"); + addPair("Command is not installed", L"कमान स्थापित नहीं है"); + addPair("Missing filename in %s\n", L"लापता में फ़ाइलनाम %s\n"); + addPair("Recursive option with no wildcard", L"कोई वाइल्डकार्ड साथ पुनरावर्ती विकल्प"); + addPair("Did you intend quote the filename", L"क्या आप बोली फ़ाइलनाम का इरादा"); + addPair("No file to process %s\n", L"कोई फ़ाइल %s प्रक्रिया के लिए\n"); + addPair("Did you intend to use --recursive", L"क्या आप उपयोग करना चाहते हैं --recursive"); + addPair("Cannot process UTF-32 encoding", L"UTF-32 कूटबन्धन प्रक्रिया नहीं कर सकते"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style समाप्त किया है"); +} + +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("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 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 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"); +} + +Italian::Italian() // Italiano +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Formattata %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Immutato %s\n"); // should align with formatted + addPair("Directory %s\n", L"Elenco %s\n"); + addPair("Exclude %s\n", L"Escludere %s\n"); + addPair("Exclude (unmatched) %s\n", L"Escludere (senza pari) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s ormattata %s immutato "); + addPair(" seconds ", L" secondo "); + addPair("%d min %d sec ", L"%d min %d seg "); + addPair("%s lines\n", L"%s linee\n"); + addPair("Using default options file %s\n", L"Utilizzando file delle opzioni di default %s\n"); + addPair("Opening HTML documentation %s\n", L"Apertura di documenti HTML %s\n"); + addPair("Invalid option file options:", L"Opzione non valida file delle opzioni:"); + addPair("Invalid command line options:", L"Opzioni della riga di comando non valido:"); + addPair("For help on options type 'astyle -h'", L"Per informazioni sulle opzioni di tipo 'astyle-h'"); + addPair("Cannot open options file", L"Impossibile aprire il file opzioni"); + addPair("Cannot open directory", L"Impossibile aprire la directory"); + addPair("Cannot open HTML file %s\n", L"Impossibile aprire il file HTML %s\n"); + addPair("Command execute failure", L"Esegui fallimento comando"); + addPair("Command is not installed", L"Il comando non è installato"); + addPair("Missing filename in %s\n", L"Nome del file mancante in %s\n"); + addPair("Recursive option with no wildcard", L"Opzione ricorsiva senza jolly"); + addPair("Did you intend quote the filename", L"Avete intenzione citare il nome del file"); + addPair("No file to process %s\n", L"Nessun file al processo %s\n"); + addPair("Did you intend to use --recursive", L"Hai intenzione di utilizzare --recursive"); + addPair("Cannot process UTF-32 encoding", L"Non è possibile processo di codifica UTF-32"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style ha terminato"); +} + +Japanese::Japanese() // 日本語 +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"フォーマット済みの %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"変わりません %s\n"); // should align with formatted + addPair("Directory %s\n", L"ディレクトリ %s\n"); + addPair("Exclude %s\n", L"除外する %s\n"); + addPair("Exclude (unmatched) %s\n", L"除外する(一致しません) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s フフォーマット済みの %s 変わりません "); + addPair(" seconds ", L" 秒 "); + addPair("%d min %d sec ", L"%d 分 %d 秒 "); + addPair("%s lines\n", L"%s ライン\n"); + addPair("Using default options file %s\n", L"デフォルトのオプションファイルを使用して、 %s\n"); + addPair("Opening HTML documentation %s\n", L"オープニングHTMLドキュメント %s\n"); + addPair("Invalid option file options:", L"無効なオプションファイルのオプション:"); + addPair("Invalid command line options:", L"無効なコマンドラインオプション:"); + addPair("For help on options type 'astyle -h'", L"コオプションの種類のヘルプについて'astyle- h'を入力してください"); + addPair("Cannot open options file", L"オプションファイルを開くことができません"); + addPair("Cannot open directory", L"ディレクトリを開くことができません。"); + addPair("Cannot open HTML file %s\n", L"HTMLファイルを開くことができません %s\n"); + addPair("Command execute failure", L"コマンドが失敗を実行します"); + addPair("Command is not installed", L"コマンドがインストールされていません"); + addPair("Missing filename in %s\n", L"%s で、ファイル名がありません\n"); + addPair("Recursive option with no wildcard", L"無ワイルドカードを使用して再帰的なオプション"); + addPair("Did you intend quote the filename", L"あなたはファイル名を引用するつもりでした"); + addPair("No file to process %s\n", L"いいえファイルは処理しないように %s\n"); + addPair("Did you intend to use --recursive", L"あなたは--recursive使用するつもりでした"); + addPair("Cannot process UTF-32 encoding", L"UTF - 32エンコーディングを処理できません"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style 終了しました"); +} + +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("Exclude %s\n", L"제외됨 %s\n"); + addPair("Exclude (unmatched) %s\n", L"제외 (NO 일치) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s 수정됨 %s 변경없음 "); + addPair(" seconds ", L" 초 "); + addPair("%d min %d sec ", L"%d 분 %d 초 "); + addPair("%s lines\n", L"%s 라인\n"); + addPair("Using default options file %s\n", L"기본 구성 파일을 사용 %s\n"); + addPair("Opening HTML documentation %s\n", L"HTML 문서를 열기 %s\n"); + addPair("Invalid option file options:", L"잘못된 구성 파일 옵션 :"); + addPair("Invalid command line options:", L"잘못된 명령줄 옵션 :"); + addPair("For help on options type 'astyle -h'", L"도움말을 보려면 옵션 유형 'astyle - H'를 사용합니다"); + addPair("Cannot open options file", L"구성 파일을 열 수 없습니다"); + addPair("Cannot open directory", L"디렉토리를 열지 못했습니다"); + addPair("Cannot open HTML file %s\n", L"HTML 파일을 열 수 없습니다 %s\n"); + addPair("Command execute failure", L"명령 실패를 실행"); + addPair("Command is not installed", L"명령이 설치되어 있지 않습니다"); + addPair("Missing filename in %s\n", L"%s 에서 누락된 파일 이름\n"); + addPair("Recursive option with no wildcard", L"와일드 카드없이 재귀 옵션"); + addPair("Did you intend quote the filename", L"당신은 파일 이름을 인용하고자하나요"); + addPair("No file to process %s\n", L"처리할 파일이 없습니다 %s\n"); + addPair("Did you intend to use --recursive", L"--recursive 를 사용하고자 하십니까"); + addPair("Cannot process UTF-32 encoding", L"UTF-32 인코딩을 처리할 수 없습니다"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style를 종료합니다"); +} + +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("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 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 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"); +} + +Polish::Polish() // Polski +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Sformatowany %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Niezmienione %s\n"); // should align with formatted + addPair("Directory %s\n", L"Katalog %s\n"); + addPair("Exclude %s\n", L"Wykluczać %s\n"); + addPair("Exclude (unmatched) %s\n", L"Wyklucz (niezrównany) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s sformatowany %s niezmienione "); + addPair(" seconds ", L" sekund "); + addPair("%d min %d sec ", L"%d min %d sek "); + addPair("%s lines\n", L"%s linii\n"); + addPair("Using default options file %s\n", L"Korzystanie z domyślnej opcji %s plik\n"); + addPair("Opening HTML documentation %s\n", L"Otwarcie dokumentacji HTML %s\n"); + addPair("Invalid option file options:", L"Nieprawidłowy opcji pliku opcji:"); + addPair("Invalid command line options:", L"Nieprawidłowe opcje wiersza polecenia:"); + addPair("For help on options type 'astyle -h'", L"Aby uzyskać pomoc od rodzaju opcji 'astyle -h'"); + addPair("Cannot open options file", L"Nie można otworzyć pliku opcji"); + addPair("Cannot open directory", L"Nie można otworzyć katalogu"); + addPair("Cannot open HTML file %s\n", L"Nie można otworzyć pliku HTML %s\n"); + addPair("Command execute failure", L"Wykonaj polecenia niepowodzenia"); + addPair("Command is not installed", L"Polecenie nie jest zainstalowany"); + addPair("Missing filename in %s\n", L"Brakuje pliku w %s\n"); + addPair("Recursive option with no wildcard", L"Rekurencyjne opcja bez symboli"); + addPair("Did you intend quote the filename", L"Czy zamierza Pan podać nazwę pliku"); + addPair("No file to process %s\n", L"Brak pliku do procesu %s\n"); + addPair("Did you intend to use --recursive", L"Czy masz zamiar używać --recursive"); + addPair("Cannot process UTF-32 encoding", L"Nie można procesu kodowania UTF-32"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style został zakończony"); +} + +Portuguese::Portuguese() // Português +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Formatado %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Inalterado %s\n"); // should align with formatted + addPair("Directory %s\n", L"Diretório %s\n"); + addPair("Exclude %s\n", L"Excluir %s\n"); + addPair("Exclude (unmatched) %s\n", L"Excluir (incomparável) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s formatado %s inalterado "); + addPair(" seconds ", L" segundo "); + addPair("%d min %d sec ", L"%d min %d seg "); + addPair("%s lines\n", L"%s linhas\n"); + addPair("Using default options file %s\n", L"Usando o arquivo de opções padrão %s\n"); + addPair("Opening HTML documentation %s\n", L"Abrindo a documentação HTML %s\n"); + addPair("Invalid option file options:", L"Opções de arquivo inválido opção:"); + addPair("Invalid command line options:", L"Opções de linha de comando inválida:"); + addPair("For help on options type 'astyle -h'", L"Para obter ajuda sobre as opções de tipo 'astyle -h'"); + addPair("Cannot open options file", L"Não é possível abrir arquivo de opções"); + addPair("Cannot open directory", L"Não é possível abrir diretório"); + addPair("Cannot open HTML file %s\n", L"Não é possível abrir arquivo HTML %s\n"); + addPair("Command execute failure", L"Executar falha de comando"); + addPair("Command is not installed", L"Comando não está instalado"); + addPair("Missing filename in %s\n", L"Filename faltando em %s\n"); + addPair("Recursive option with no wildcard", L"Opção recursiva sem curinga"); + addPair("Did you intend quote the filename", L"Será que você pretende citar o nome do arquivo"); + addPair("No file to process %s\n", L"Nenhum arquivo para processar %s\n"); + addPair("Did you intend to use --recursive", L"Será que você pretende usar --recursive"); + addPair("Cannot process UTF-32 encoding", L"Não pode processar a codificação UTF-32"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style terminou"); +} + +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("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 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 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"); +} + +Russian::Russian() // русский +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Форматированный %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"без изменений %s\n"); // should align with formatted + addPair("Directory %s\n", L"каталог %s\n"); + addPair("Exclude %s\n", L"исключать %s\n"); + addPair("Exclude (unmatched) %s\n", L"Исключить (непревзойденный) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s Форматированный %s без изменений "); + addPair(" seconds ", L" секунды "); + addPair("%d min %d sec ", L"%d мин %d сек "); + addPair("%s lines\n", L"%s линий\n"); + addPair("Using default options file %s\n", L"Использование опции по умолчанию файл %s\n"); + addPair("Opening HTML documentation %s\n", L"Открытие HTML документации %s\n"); + addPair("Invalid option file options:", L"Недопустимый файл опций опцию:"); + addPair("Invalid command line options:", L"Недопустимые параметры командной строки:"); + addPair("For help on options type 'astyle -h'", L"Для получения справки по 'astyle -h' опций типа"); + addPair("Cannot open options file", L"Не удается открыть файл параметров"); + addPair("Cannot open directory", L"Не могу открыть каталог"); + addPair("Cannot open HTML file %s\n", L"Не удается открыть файл HTML %s\n"); + addPair("Command execute failure", L"Выполнить команду недостаточности"); + addPair("Command is not installed", L"Не установлен Команда"); + addPair("Missing filename in %s\n", L"Отсутствует имя файла в %s\n"); + addPair("Recursive option with no wildcard", L"Рекурсивный вариант без каких-либо шаблона"); + addPair("Did you intend quote the filename", L"Вы намерены цитатой файла"); + addPair("No file to process %s\n", L"Нет файлов для обработки %s\n"); + addPair("Did you intend to use --recursive", L"Неужели вы собираетесь использовать --recursive"); + addPair("Cannot process UTF-32 encoding", L"Не удается обработать UTF-32 кодировке"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style прекратил"); +} + +Spanish::Spanish() // Español +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Formato %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Inalterado %s\n"); // should align with formatted + addPair("Directory %s\n", L"Directorio %s\n"); + addPair("Exclude %s\n", L"Excluir %s\n"); + addPair("Exclude (unmatched) %s\n", L"Excluir (incomparable) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s formato %s inalterado "); + addPair(" seconds ", L" segundo "); + addPair("%d min %d sec ", L"%d min %d seg "); + addPair("%s lines\n", L"%s líneas\n"); + addPair("Using default options file %s\n", L"Uso de las opciones por defecto del archivo %s\n"); + addPair("Opening HTML documentation %s\n", L"Apertura de documentación HTML %s\n"); + addPair("Invalid option file options:", L"Opción no válida opciones de archivo:"); + addPair("Invalid command line options:", L"No válido opciones de línea de comando:"); + addPair("For help on options type 'astyle -h'", L"Para obtener ayuda sobre las opciones tipo 'astyle -h'"); + addPair("Cannot open options file", L"No se puede abrir el archivo de opciones"); + addPair("Cannot open directory", L"No se puede abrir el directorio"); + addPair("Cannot open HTML file %s\n", L"No se puede abrir el archivo HTML %s\n"); + addPair("Command execute failure", L"Ejecutar el fracaso de comandos"); + addPair("Command is not installed", L"El comando no está instalado"); + addPair("Missing filename in %s\n", L"Falta nombre del archivo en %s\n"); + addPair("Recursive option with no wildcard", L"Recursiva opción sin comodín"); + addPair("Did you intend quote the filename", L"Se tiene la intención de citar el nombre de archivo"); + addPair("No file to process %s\n", L"No existe el fichero a procesar %s\n"); + addPair("Did you intend to use --recursive", L"Se va a utilizar --recursive"); + addPair("Cannot process UTF-32 encoding", L"No se puede procesar la codificación UTF-32"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style ha terminado"); +} + +Swedish::Swedish() // Svenska +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"Formaterade %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"Oförändrade %s\n"); // should align with formatted + addPair("Directory %s\n", L"Katalog %s\n"); + addPair("Exclude %s\n", L"Uteslut %s\n"); + addPair("Exclude (unmatched) %s\n", L"Uteslut (oöverträffad) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s formaterade %s oförändrade "); + addPair(" seconds ", L" sekunder "); + addPair("%d min %d sec ", L"%d min %d sek "); + addPair("%s lines\n", L"%s linjer\n"); + addPair("Using default options file %s\n", L"Använda standardalternativ fil %s\n"); + addPair("Opening HTML documentation %s\n", L"Öppna HTML-dokumentation %s\n"); + addPair("Invalid option file options:", L"Ogiltigt alternativ fil alternativ:"); + addPair("Invalid command line options:", L"Ogiltig kommandoraden alternativ:"); + addPair("For help on options type 'astyle -h'", L"För hjälp om alternativ typ 'astyle -h'"); + addPair("Cannot open options file", L"Kan inte öppna inställningsfilen"); + addPair("Cannot open directory", L"Kan inte öppna katalog"); + addPair("Cannot open HTML file %s\n", L"Kan inte öppna HTML-filen %s\n"); + addPair("Command execute failure", L"Utför kommando misslyckande"); + addPair("Command is not installed", L"Kommandot är inte installerat"); + addPair("Missing filename in %s\n", L"Saknade filnamn i %s\n"); + addPair("Recursive option with no wildcard", L"Rekursiva alternativ utan jokertecken"); + addPair("Did you intend quote the filename", L"Visste du tänker citera filnamnet"); + addPair("No file to process %s\n", L"Ingen fil att bearbeta %s\n"); + addPair("Did you intend to use --recursive", L"Har du för avsikt att använda --recursive"); + addPair("Cannot process UTF-32 encoding", L"Kan inte hantera UTF-32 kodning"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style har upphört"); +} + +Ukrainian::Ukrainian() // Український +// build the translation vector in the Translation base class +{ + addPair("Formatted %s\n", L"форматований %s\n"); // should align with unchanged + addPair("Unchanged %s\n", L"без змін %s\n"); // should align with formatted + addPair("Directory %s\n", L"Каталог %s\n"); + addPair("Exclude %s\n", L"Виключити %s\n"); + addPair("Exclude (unmatched) %s\n", L"Виключити (неперевершений) %s\n"); + addPair(" %s formatted %s unchanged ", L" %s відформатований %s без змін "); + addPair(" seconds ", L" секунди "); + addPair("%d min %d sec ", L"%d хви %d cek "); + addPair("%s lines\n", L"%s ліній\n"); + addPair("Using default options file %s\n", L"Використання файлів опцій за замовчуванням %s\n"); + addPair("Opening HTML documentation %s\n", L"Відкриття HTML документації %s\n"); + addPair("Invalid option file options:", L"Неприпустимий файл опцій опцію:"); + addPair("Invalid command line options:", L"Неприпустима параметри командного рядка:"); + addPair("For help on options type 'astyle -h'", L"Для отримання довідки по 'astyle -h' опцій типу"); + addPair("Cannot open options file", L"Не вдається відкрити файл параметрів"); + addPair("Cannot open directory", L"Не можу відкрити каталог"); + addPair("Cannot open HTML file %s\n", L"Не вдається відкрити файл HTML %s\n"); + addPair("Command execute failure", L"Виконати команду недостатності"); + addPair("Command is not installed", L"Не встановлений Команда"); + addPair("Missing filename in %s\n", L"Відсутня назва файлу в %s\n"); + addPair("Recursive option with no wildcard", L"Рекурсивний варіант без будь-яких шаблону"); + addPair("Did you intend quote the filename", L"Ви маєте намір цитатою файлу"); + addPair("No file to process %s\n", L"Немає файлів для обробки %s\n"); + addPair("Did you intend to use --recursive", L"Невже ви збираєтеся використовувати --recursive"); + addPair("Cannot process UTF-32 encoding", L"Не вдається обробити UTF-32 кодуванні"); + addPair("\nArtistic Style has terminated", L"\nArtistic Style припинив"); +} + + +#endif // ASTYLE_LIB + +} // end of namespace astyle + diff --git a/kdev-pg/ASResource.cpp b/kdev-pg/ASResource.cpp --- a/kdev-pg/ASResource.cpp +++ b/kdev-pg/ASResource.cpp @@ -1,32 +1,31 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * ASResource.cpp + * Copyright (C) 2006-2010 by Jim Pattee + * Copyright (C) 1998-2002 by Tal Davidson + * * - * This file is a part of "Artistic Style" - an indentation and + * This file is a part of Artistic Style - an indentation and * reformatting tool for C, C++, C# and Java source files. - * http://astyle.sourceforge.net + * * - * The "Artistic Style" project, including all files needed to - * compile it, is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later - * version. + * Artistic Style is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * Artistic Style 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 Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public - * License along with this project; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with Artistic Style. If not, see . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "astyle.h" +#include namespace astyle @@ -45,6 +44,7 @@ const string ASResource::AS_INTERFACE = string("interface"); const string ASResource::AS_NAMESPACE = string("namespace"); const string ASResource::AS_EXTERN = string("extern"); +const string ASResource::AS_ENUM = string("enum"); const string ASResource::AS_PUBLIC = string("public"); const string ASResource::AS_PROTECTED = string("protected"); const string ASResource::AS_PRIVATE = string("private"); @@ -57,8 +57,13 @@ const string ASResource::AS_FINALLY = string("finally"); const string ASResource::AS_THROWS = string("throws"); const string ASResource::AS_CONST = string("const"); +const string ASResource::AS_WHERE = string("where"); +const string ASResource::AS_NEW = string("new"); const string ASResource::AS_ASM = string("asm"); +const string ASResource::AS__ASM__ = string("__asm__"); +const string ASResource::AS_MS_ASM = string("_asm"); +const string ASResource::AS_MS__ASM = string("__asm"); const string ASResource::AS_BAR_DEFINE = string("#define"); const string ASResource::AS_BAR_INCLUDE = string("#include"); @@ -85,7 +90,13 @@ 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("++"); @@ -97,6 +108,8 @@ 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_EQUAL_GR = string("=>"); // C# lambda expression arrow const string ASResource::AS_ARROW = string("->"); const string ASResource::AS_AND = string("&&"); const string ASResource::AS_OR = string("||"); @@ -129,261 +142,406 @@ 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"); /** + * Sort comparison function. + * Compares the length of the value of pointers in the vectors. + * The LONGEST strings will be first in the vector. + * + * @params 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. + * + * @params 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) +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); + assignmentOperators->push_back(&AS_ASSIGN); + assignmentOperators->push_back(&AS_PLUS_ASSIGN); + assignmentOperators->push_back(&AS_MINUS_ASSIGN); + assignmentOperators->push_back(&AS_MULT_ASSIGN); + assignmentOperators->push_back(&AS_DIV_ASSIGN); + assignmentOperators->push_back(&AS_MOD_ASSIGN); + assignmentOperators->push_back(&AS_OR_ASSIGN); + assignmentOperators->push_back(&AS_AND_ASSIGN); + assignmentOperators->push_back(&AS_XOR_ASSIGN); // Java - assignmentOperators.push_back(&AS_GR_GR_GR_ASSIGN); - assignmentOperators.push_back(&AS_GR_GR_ASSIGN); - assignmentOperators.push_back(&AS_LS_LS_ASSIGN); + assignmentOperators->push_back(&AS_GR_GR_GR_ASSIGN); + assignmentOperators->push_back(&AS_GR_GR_ASSIGN); + assignmentOperators->push_back(&AS_LS_LS_ASSIGN); // Unknown - assignmentOperators.push_back(&AS_LS_LS_LS_ASSIGN); + assignmentOperators->push_back(&AS_LS_LS_LS_ASSIGN); - assignmentOperators.push_back(&AS_RETURN); + 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) +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); + castOperators->push_back(&AS_CONST_CAST); + castOperators->push_back(&AS_DYNAMIC_CAST); + castOperators->push_back(&AS_REINTERPRET_CAST); + castOperators->push_back(&AS_STATIC_CAST); } /** * Build the vector of header words. * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp * * @param headers a reference to the vector to be built. */ -void ASResource::buildHeaders(vector &headers, int fileType, bool beautifier) +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_TRY); - headers.push_back(&AS_CATCH); + 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_TRY); + headers->push_back(&AS_CATCH); - if (beautifier) + if (fileType == JAVA_TYPE) { - headers.push_back(&AS_CASE); - headers.push_back(&AS_DEFAULT); - headers.push_back(&AS_CONST); - headers.push_back(&AS_STATIC); - headers.push_back(&AS_EXTERN); - headers.push_back(&AS_TEMPLATE); + headers->push_back(&AS_FINALLY); + headers->push_back(&AS_SYNCHRONIZED); } - if (fileType == JAVA_TYPE) + if (fileType == SHARP_TYPE) { - headers.push_back(&AS_FINALLY); - headers.push_back(&AS_SYNCHRONIZED); + headers->push_back(&AS_FINALLY); + headers->push_back(&AS_FOREACH); + headers->push_back(&AS_LOCK); +// headers->push_back(&AS_UNSAFE); + 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); } - if (fileType == SHARP_TYPE) + if (beautifier) { - headers.push_back(&AS_FINALLY); - headers.push_back(&AS_FOREACH); - headers.push_back(&AS_LOCK); - headers.push_back(&AS_UNSAFE); - 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_CASE); + headers->push_back(&AS_DEFAULT); + + if (fileType == C_TYPE) + { + headers->push_back(&AS_CONST); + headers->push_back(&AS_TEMPLATE); + } + + if (fileType == JAVA_TYPE) + { + headers->push_back(&AS_STATIC); // for static constructor + } } + sort(headers->begin(), headers->end(), sortOnName); +} + +/** + * Build the vector of indentable headers. + * Used by ONLY ASBeautifier.cpp + * + * @param indentableHeaders a reference to the vector to be built. + */ +void ASResource::buildIndentableHeaders(vector* indentableHeaders) +{ + indentableHeaders->push_back(&AS_RETURN); +// indentableHeaders->push_back(&AS_COUT); +// indentableHeaders->push_back(&AS_CERR); +// indentableHeaders->push_back(&AS_CIN); + + sort(indentableHeaders->begin(), indentableHeaders->end(), sortOnName); } /** * Build the vector of non-assignment operators. * Used by ONLY ASBeautifier.cpp * - * @param nonParenHeaders a reference to the vector to be built. + * @param nonAssignmentOperators a reference to the vector to be built. */ -void ASResource::buildNonAssignmentOperators(vector &nonAssignmentOperators) +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_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); + + sort(nonAssignmentOperators->begin(), nonAssignmentOperators->end(), sortOnLength); } /** * Build the vector of header non-paren headers. * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp * * @param nonParenHeaders a reference to the vector to be built. */ -void ASResource::buildNonParenHeaders(vector &nonParenHeaders, int fileType, bool beautifier) +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_ELSE); + nonParenHeaders->push_back(&AS_DO); + nonParenHeaders->push_back(&AS_TRY); - if (beautifier) + if (fileType == JAVA_TYPE) { - nonParenHeaders.push_back(&AS_CASE); - nonParenHeaders.push_back(&AS_DEFAULT); - nonParenHeaders.push_back(&AS_CONST); - nonParenHeaders.push_back(&AS_STATIC); - nonParenHeaders.push_back(&AS_EXTERN); - nonParenHeaders.push_back(&AS_TEMPLATE); + nonParenHeaders->push_back(&AS_FINALLY); } - if (fileType == JAVA_TYPE) + if (fileType == SHARP_TYPE) { - nonParenHeaders.push_back(&AS_FINALLY); + nonParenHeaders->push_back(&AS_CATCH); // can be a paren or non-paren header + nonParenHeaders->push_back(&AS_FINALLY); +// nonParenHeaders->push_back(&AS_UNSAFE); + nonParenHeaders->push_back(&AS_GET); + nonParenHeaders->push_back(&AS_SET); + nonParenHeaders->push_back(&AS_ADD); + nonParenHeaders->push_back(&AS_REMOVE); } - if (fileType == SHARP_TYPE) + if (beautifier) { - nonParenHeaders.push_back(&AS_FINALLY); - nonParenHeaders.push_back(&AS_UNSAFE); - nonParenHeaders.push_back(&AS_GET); - nonParenHeaders.push_back(&AS_SET); - nonParenHeaders.push_back(&AS_ADD); - nonParenHeaders.push_back(&AS_REMOVE); + nonParenHeaders->push_back(&AS_CASE); + nonParenHeaders->push_back(&AS_DEFAULT); + if (fileType == C_TYPE) + { + nonParenHeaders->push_back(&AS_CONST); + nonParenHeaders->push_back(&AS_TEMPLATE); + } + if (fileType == JAVA_TYPE) + { + nonParenHeaders->push_back(&AS_STATIC); + } } + sort(nonParenHeaders->begin(), nonParenHeaders->end(), sortOnName); } /** * Build the vector of operators. * Used by ONLY ASFormatter.cpp * * @param operators a reference to the vector to be built. */ -void ASResource::buildOperators(vector &operators) +void ASResource::buildOperators(vector* operators) { - 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_ARROW); - operators.push_back(&AS_AND); - operators.push_back(&AS_OR); - operators.push_back(&AS_COLON_COLON); - 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); - operators.push_back(&AS_OPERATOR); - operators.push_back(&AS_COMMA); - operators.push_back(&AS_RETURN); + 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_EQUAL_GR); + operators->push_back(&AS_GCC_MIN_ASSIGN); + operators->push_back(&AS_GCC_MAX_ASSIGN); + operators->push_back(&AS_ARROW); + operators->push_back(&AS_AND); + operators->push_back(&AS_OR); + operators->push_back(&AS_COLON_COLON); + 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); + + 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) +void ASResource::buildPreBlockStatements(vector* preBlockStatements, int fileType) { - preBlockStatements.push_back(&AS_CLASS); - preBlockStatements.push_back(&AS_STRUCT); - preBlockStatements.push_back(&AS_UNION); - preBlockStatements.push_back(&AS_INTERFACE); - preBlockStatements.push_back(&AS_NAMESPACE); - preBlockStatements.push_back(&AS_THROWS); - preBlockStatements.push_back(&AS_EXTERN); + preBlockStatements->push_back(&AS_CLASS); + if (fileType == C_TYPE) + { + preBlockStatements->push_back(&AS_STRUCT); + preBlockStatements->push_back(&AS_UNION); + preBlockStatements->push_back(&AS_NAMESPACE); + } + if (fileType == JAVA_TYPE) + { + preBlockStatements->push_back(&AS_INTERFACE); + preBlockStatements->push_back(&AS_THROWS); + } + if (fileType == SHARP_TYPE) + { + preBlockStatements->push_back(&AS_INTERFACE); + preBlockStatements->push_back(&AS_NAMESPACE); + preBlockStatements->push_back(&AS_WHERE); + preBlockStatements->push_back(&AS_STRUCT); + } + sort(preBlockStatements->begin(), preBlockStatements->end(), sortOnName); } /** * Build the vector of pre-command headers. * Used by ONLY ASFormatter.cpp * * @param preCommandHeaders a reference to the vector to be built. */ -void ASResource::buildPreCommandHeaders(vector &preCommandHeaders) +void ASResource::buildPreCommandHeaders(vector* preCommandHeaders, int fileType) { - preCommandHeaders.push_back(&AS_EXTERN); - preCommandHeaders.push_back(&AS_THROWS); - preCommandHeaders.push_back(&AS_CONST); + if (fileType == C_TYPE) + { + preCommandHeaders->push_back(&AS_CONST); + } + + if (fileType == JAVA_TYPE) + { + preCommandHeaders->push_back(&AS_THROWS); + } + + if (fileType == SHARP_TYPE) + { + preCommandHeaders->push_back(&AS_WHERE); + } + + sort(preCommandHeaders->begin(), preCommandHeaders->end(), sortOnName); } /** * Build the vector of pre-definition headers. * Used by ONLY ASFormatter.cpp + * NOTE: Do NOT add 'enum' here. It is an array type bracket. + * NOTE: Do NOT add 'extern' here. Do not want an extra indent. * * @param preDefinitionHeaders a reference to the vector to be built. */ -void ASResource::buildPreDefinitionHeaders(vector &preDefinitionHeaders) +void ASResource::buildPreDefinitionHeaders(vector* preDefinitionHeaders, int fileType) { - preDefinitionHeaders.push_back(&AS_CLASS); - preDefinitionHeaders.push_back(&AS_INTERFACE); - preDefinitionHeaders.push_back(&AS_NAMESPACE); - preDefinitionHeaders.push_back(&AS_STRUCT); + preDefinitionHeaders->push_back(&AS_CLASS); + if (fileType == C_TYPE) + { + preDefinitionHeaders->push_back(&AS_STRUCT); + preDefinitionHeaders->push_back(&AS_UNION); + preDefinitionHeaders->push_back(&AS_NAMESPACE); + } + if (fileType == JAVA_TYPE) + { + preDefinitionHeaders->push_back(&AS_INTERFACE); + } + if (fileType == SHARP_TYPE) + { + preDefinitionHeaders->push_back(&AS_STRUCT); + preDefinitionHeaders->push_back(&AS_INTERFACE); + preDefinitionHeaders->push_back(&AS_NAMESPACE); + } + sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName); } +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * ASBase Funtions + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// check if a specific line position contains a keyword. +bool ASBase::findKeyword(const string &line, int i, const string &keyword) const +{ + assert(isCharPotentialHeader(line, i)); + // check the word + const size_t keywordLength = keyword.length(); + const size_t wordEnd = i + keywordLength; + if (wordEnd > line.length()) + return false; + if (line.compare(i, keywordLength, keyword) != 0) + return false; + // check that this is not part of a longer word + if (wordEnd == line.length()) + return true; + if (isLegalNameChar(line[wordEnd])) + return false; + // is not a keyword if part of a definition + const char peekChar = peekNextChar(line, wordEnd - 1); + if (peekChar == ',' || peekChar == ')') + return false; + return true; +} + +// get the current word on a line +// index must point to the beginning of the word +string ASBase::getCurrentWord(const string& line, size_t index) const +{ + assert(isCharPotentialHeader(line, index)); + size_t lineLength = line.length(); + size_t i; + for (i = index; i < lineLength; i++) + { + if (!isLegalNameChar(line[i])) + break; + } + return line.substr(index, i - index); +} } // end namespace astyle diff --git a/kdev-pg/astyle.h b/kdev-pg/astyle.h --- a/kdev-pg/astyle.h +++ b/kdev-pg/astyle.h @@ -1,27 +1,25 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * astyle.h + * Copyright (C) 2006-2010 by Jim Pattee + * Copyright (C) 1998-2002 by Tal Davidson + * * - * This file is a part of "Artistic Style" - an indentation and + * This file is a part of Artistic Style - an indentation and * reformatting tool for C, C++, C# and Java source files. - * http://astyle.sourceforge.net + * * - * The "Artistic Style" project, including all files needed to - * compile it, is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later - * version. + * Artistic Style is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * Artistic Style 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 Lesser General Public License for more details. * - * You should have received a copy of the GNU Lesser General Public - * License along with this project; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with Artistic Style. If not, see . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -31,114 +29,275 @@ #ifdef __VMS #define __USE_STD_IOSTREAM 1 -#include +#include +#else +#include #endif +#include // need both string and string.h for GCC #include #include #include -#include - -using namespace std; +#ifdef _WIN32 +#define STDCALL __stdcall +#define EXPORT __declspec(dllexport) +#else +#define STDCALL +#define EXPORT +#endif -// 4996 - secure version deprecation warnings for .NET 2005 -// 4267 - 64 bit signed/unsigned loss of data #ifdef _MSC_VER -#pragma warning(disable: 4996) -#pragma warning(disable: 4267) +#pragma warning(disable: 4996) // secure version deprecation warnings +#pragma warning(disable: 4267) // 64 bit signed/unsigned loss of data +#endif + +#ifdef __BORLANDC__ +#pragma warn -aus // variable is assigned a value that is never used in function. +#endif + +#ifdef __INTEL_COMPILER +#pragma warning(disable: 383) // value copied to temporary, reference to temporary used +#pragma warning(disable: 444) // destructor for base class is not virtual +#pragma warning(disable: 981) // operands are evaluated in unspecified order #endif +using namespace std; + namespace astyle { 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 BracketMode { NONE_MODE, ATTACH_MODE, BREAK_MODE, BDAC_MODE }; +enum FormatStyle { STYLE_NONE, + STYLE_ALLMAN, + STYLE_JAVA, + STYLE_KandR, + STYLE_STROUSTRUP, + STYLE_WHITESMITH, + STYLE_BANNER, + STYLE_GNU, + STYLE_LINUX, + STYLE_HORSTMANN, + STYLE_1TBS + }; + +enum BracketMode { NONE_MODE, + ATTACH_MODE, + BREAK_MODE, + LINUX_MODE, + STROUSTRUP_MODE, + HORSTMANN_MODE, + BDAC_MODE = LINUX_MODE + }; enum BracketType { NULL_TYPE = 0, - NAMESPACE_TYPE = 1, // also a DEFINITION_TYPE - CLASS_TYPE = 2, // also a DEFINITION_TYPE - DEFINITION_TYPE = 4, - COMMAND_TYPE = 8, - ARRAY_TYPE = 16, // arrays and enums - SINGLE_LINE_TYPE = 32 + 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 + ARRAY_TYPE = 128, // arrays and enums + EXTERN_TYPE = 256, // extern "C". not a command type extern + SINGLE_LINE_TYPE = 512 }; +enum PointerAlign { ALIGN_NONE, + ALIGN_TYPE, + ALIGN_MIDDLE, + ALIGN_NAME + }; + +enum FileEncoding { ENCODING_OK, + UTF_16BE, + UTF_16LE, + 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 plugin to define +// their own ASStreamIterator. The ASStreamIterator class must inherit +// this class. +//---------------------------------------------------------------------------- + class ASSourceIterator { public: - int eolWindows; - int eolLinux; - int eolMacOld; - char outputEOL[4]; // output end of line char - ASSourceIterator() { eolWindows = eolLinux = eolMacOld = 0; } + ASSourceIterator() {} virtual ~ASSourceIterator() {} virtual bool hasMoreLines() const = 0; - virtual string nextLine() = 0; + virtual string nextLine(bool emptyLineWasDeleted = false) = 0; + virtual string peekNextLine() = 0; + virtual void peekReset() = 0; }; +//---------------------------------------------------------------------------- +// Class ASResource +//---------------------------------------------------------------------------- + class ASResource { public: - void buildAssignmentOperators(vector &assignmentOperators); - void buildCastOperators(vector &castOperators); - void buildHeaders(vector &headers, int fileType, bool beautifier=false); - void buildNonAssignmentOperators(vector &nonAssignmentOperators); - void buildNonParenHeaders(vector &nonParenHeaders, int fileType, bool beautifier=false); - void buildOperators(vector &operators); - void buildPreBlockStatements(vector &preBlockStatements); - void buildPreCommandHeaders(vector &preCommandHeaders); - void buildPreDefinitionHeaders(vector &preDefinitionHeaders); + void buildAssignmentOperators(vector* assignmentOperators); + void buildCastOperators(vector* castOperators); + void buildHeaders(vector* headers, int fileType, bool beautifier=false); + void buildIndentableHeaders(vector* indentableHeaders); + void buildNonAssignmentOperators(vector* nonAssignmentOperators); + void buildNonParenHeaders(vector* nonParenHeaders, int fileType, bool beautifier=false); + void buildOperators(vector* operators); + 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_THROWS, AS_FINALLY; static const string AS_PUBLIC, AS_PROTECTED, AS_PRIVATE; - static const string AS_CLASS, AS_STRUCT, AS_UNION, AS_INTERFACE, AS_NAMESPACE, AS_EXTERN; - static const string AS_STATIC; - static const string AS_CONST; + static const string AS_CLASS, AS_STRUCT, AS_UNION, AS_INTERFACE, AS_NAMESPACE; + static const string AS_EXTERN, AS_ENUM; + static const string AS_STATIC, AS_CONST, AS_WHERE, AS_NEW; static const string AS_SYNCHRONIZED; static const string AS_OPERATOR, AS_TEMPLATE; static const string AS_OPEN_BRACKET, AS_CLOSE_BRACKET; static const string AS_OPEN_LINE_COMMENT, AS_OPEN_COMMENT, AS_CLOSE_COMMENT; static const string AS_BAR_DEFINE, AS_BAR_INCLUDE, AS_BAR_IF, AS_BAR_EL, AS_BAR_ENDIF; static const string AS_RETURN; + static const string AS_CIN, AS_COUT, AS_CERR; static const string AS_ASSIGN, AS_PLUS_ASSIGN, AS_MINUS_ASSIGN, AS_MULT_ASSIGN; static const string AS_DIV_ASSIGN, AS_MOD_ASSIGN, AS_XOR_ASSIGN, AS_OR_ASSIGN, AS_AND_ASSIGN; static const string AS_GR_GR_ASSIGN, AS_LS_LS_ASSIGN, AS_GR_GR_GR_ASSIGN, AS_LS_LS_LS_ASSIGN; + static const string AS_GCC_MIN_ASSIGN, AS_GCC_MAX_ASSIGN; static const string AS_EQUAL, AS_PLUS_PLUS, AS_MINUS_MINUS, AS_NOT_EQUAL, AS_GR_EQUAL, AS_GR_GR_GR, AS_GR_GR; - static const string AS_LS_EQUAL, AS_LS_LS_LS, AS_LS_LS, AS_ARROW, AS_AND, AS_OR; + static const string AS_LS_EQUAL, AS_LS_LS_LS, AS_LS_LS; + static const string AS_QUESTION_QUESTION, AS_EQUAL_GR; + static const string AS_ARROW, AS_AND, AS_OR; static const string AS_COLON_COLON, AS_PAREN_PAREN, AS_BLPAREN_BLPAREN; 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; + static const string AS_ASM, AS__ASM__, AS_MS_ASM, AS_MS__ASM; 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; -}; +}; // Class ASResource + +//---------------------------------------------------------------------------- +// Class ASBase +//---------------------------------------------------------------------------- + +class ASBase +{ + private: + // all variables should be set by the "init" function + int baseFileType; // a value from enum FileType + + protected: + ASBase() { baseFileType = C_TYPE; } + ~ASBase() {} + + // functions definitions are at the end of ASResource.cpp + bool findKeyword(const string &line, int i, const string &keyword) const; + string getCurrentWord(const string& line, size_t index) const; -class ASBeautifier : protected ASResource + protected: + + 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); } + + // check if a specific character can be used in a legal variable/method/class name + bool isLegalNameChar(char ch) const { + if (isWhiteSpace(ch)) return false; + if ((unsigned) ch > 127) return false; + return (isalnum(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 isCharPotentialHeader(const string &line, size_t i) const { + assert(!isWhiteSpace(line[i])); + char prevCh = ' '; + if (i > 0) prevCh = line[i-1]; + if (!isLegalNameChar(prevCh) && isLegalNameChar(line[i])) + return true; + return false; + } + + // check if a specific character can be part of an operator + bool isCharPotentialOperator(char ch) const { + assert(!isWhiteSpace(ch)); + if ((unsigned) ch > 127) return false; + return (ispunct(ch) + && ch != '{' && ch != '}' + && ch != '(' && ch != ')' + && ch != '[' && ch != ']' + && ch != ';' && ch != ',' + && ch != '#' && ch != '\\' + && ch != '\'' && ch != '\"'); + } + + // check if a specific character is a whitespace character + bool isWhiteSpace(char ch) const { return (ch == ' ' || ch == '\t'); } + + // peek at the next unread character. + char 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; + } +}; // Class ASBase + +//---------------------------------------------------------------------------- +// Class ASBeautifier +//---------------------------------------------------------------------------- + +class ASBeautifier : protected ASResource, protected ASBase { public: ASBeautifier(); virtual ~ASBeautifier(); - virtual void init(ASSourceIterator* iter); // pointer to dynamically created iterator. + virtual void init(ASSourceIterator* iter); void init(); virtual bool hasMoreLines() const; virtual string nextLine(); virtual string beautify(const string &line); + void deleteVector(vector*& container); + void initVector(vector*& container); void setTabIndentation(int length = 4, bool forceTabs = false); void setSpaceIndentation(int length = 4); void setMaxInStatementIndentLength(int max); void setMinConditionalIndentLength(int min); + void setIndentManuallySet(bool state); + void setMinConditionalManuallySet(bool state); + void setModeManuallySet(bool state); void setClassIndent(bool state); void setSwitchIndent(bool state); void setCaseIndent(bool state); @@ -151,47 +310,58 @@ void setSharpStyle(); void setEmptyLineFill(bool state); void setPreprocessorIndent(bool state); + int getFileType(); int getIndentLength(void); string getIndentString(void); + bool getBracketIndent(void); + bool getBlockIndent(void); bool getCaseIndent(void); - bool getCStyle(void); - bool getJavaStyle(void); - bool getSharpStyle(void); + bool getClassIndent(void); bool getEmptyLineFill(void); + bool getForceTabIndentation(void); + bool getIndentManuallySet(void); + bool getMinConditionalManuallySet(void); + bool getModeManuallySet(void); + bool getSwitchIndent(void); protected: - int getNextProgramCharDistance(const string &line, int i); -// bool isLegalNameChar(char ch) const; - const string *findHeader(const string &line, int i, - const vector &possibleHeaders, - bool checkBoundary = true); - string trim(const string &str); + void deleteStaticVectors(); + 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); - int fileType; - bool isCStyle; - bool isJavaStyle; - bool isSharpStyle; + string trim(const string &str); - // variables set by ASFormatter - must be updated in preprocessor - int inLineNumber; // for debugging - int outLineNumber; // for debugging + // variables set by ASFormatter - must be updated in activeBeautifierStack + int inLineNumber; + int horstmannIndentInStatement; + int nonInStatementBracket; bool lineCommentNoBeautify; bool isNonInStatementArray; + bool isSharpAccessor; + bool isSharpDelegate; + bool isInExtern; + bool isInBeautifySQL; + bool isInIndentableStruct; private: ASBeautifier(const ASBeautifier ©); - void operator=(ASBeautifier&); // not to be implemented + ASBeautifier& operator=(ASBeautifier&); // not to be implemented void initStatic(); void registerInStatementIndent(const string &line, int i, int spaceTabCount, - int minIndent, bool updateParenStack); + int tabIncrementIn, int minIndent, bool updateParenStack); string preLineWS(int spaceTabCount, int tabCount); - static vector headers; - static vector nonParenHeaders; - static vector preBlockStatements; - static vector assignmentOperators; - static vector nonAssignmentOperators; + static int beautifierFileType; + static vector* headers; + static vector* nonParenHeaders; + static vector* preBlockStatements; + static vector* assignmentOperators; + static vector* nonAssignmentOperators; + static vector* indentableHeaders; ASSourceIterator *sourceIterator; vector *waitingBeautifierStack; @@ -203,49 +373,70 @@ vector *blockParenDepthStack; vector *blockStatementStack; vector *parenStatementStack; + vector *bracketBlockStateStack; vector *inStatementIndentStack; vector *inStatementIndentStackSizeStack; vector *parenIndentStack; - vector *bracketBlockStateStack; + int convertTabToSpaces(int i, int tabIncrementIn) const; + int getInStatementIndentAssign(const string& line, size_t currPos) const; + int getInStatementIndentComma(const string& line, size_t currPos) const; + bool isClassAccessModifier(string& line) const; + bool isLineEndComment(string& line, int startPos) const; + bool statementEndsWithComma(string &line, int index); + vector*>* copyTempStacks(const ASBeautifier &other) const; + template void deleteContainer(T &container); + void deleteContainer(vector*>* &container); + template void initContainer(T &container, T value); + + private: // variables string indentString; const string *currentHeader; const string *previousLastLineHeader; - const string *immediatelyPreviousAssignmentOp; const string *probationHeader; bool isInQuote; + bool isInVerbatimQuote; + bool haveLineContinuationChar; + bool isInAsm; + bool isInAsmOneLine; + bool isInAsmBlock; bool isInComment; + bool isInHorstmannComment; bool isInCase; bool isInQuestion; bool isInStatement; bool isInHeader; - bool isInOperator; bool isInTemplate; bool isInDefine; bool isInDefineDefinition; bool classIndent; - bool isInClassHeader; + bool isInClassInitializer; bool isInClassHeaderTab; + bool isInEnum; bool switchIndent; bool caseIndent; bool namespaceIndent; bool bracketIndent; bool blockIndent; bool labelIndent; bool preprocessorIndent; bool isInConditional; - bool isMinimalConditinalIndentSet; + bool isIndentManuallySet; + bool isMinConditionalManuallySet; + bool isModeManuallySet; bool shouldForceTabIndentation; bool emptyLineFill; bool backslashEndsPrevLine; + bool lineOpensComment; bool blockCommentNoIndent; bool blockCommentNoBeautify; bool previousLineProbationTab; + int fileType; int minConditionalIndent; int parenDepth; int indentLength; int blockTabCount; - int leadingWhiteSpaces; int maxInStatementIndent; + int classInitializerTabs; int templateDepth; int prevFinalLineSpaceTabCount; int prevFinalLineTabCount; @@ -255,39 +446,26 @@ char currentNonSpaceCh; char currentNonLegalCh; char prevNonLegalCh; - char peekNextChar(string &line, int i); +}; // Class ASBeautifier - protected: // inline functions - // check if a specific character can be used in a legal variable/method/class name - inline bool isLegalNameChar(char ch) const { - return (isalnum(ch) || ch == '.' || ch == '_' || (isJavaStyle && ch == '$') || (isCStyle && ch == '~')); - } +//---------------------------------------------------------------------------- +// Class ASEnhancer +//---------------------------------------------------------------------------- - // check if a specific character is a whitespace character - inline bool isWhiteSpace(char ch) const { - return (ch == ' ' || ch == '\t'); - } -}; - - -class ASEnhancer +class ASEnhancer : protected ASBase { - public: - // functions + public: // functions ASEnhancer(); ~ASEnhancer(); - void init(int, string, bool, bool, bool, bool, bool); - void enhance(string &line); + void init(int, int, string, bool, bool); + void enhance(string &line, bool isInSQL); private: - // set by init function - int indentLength; - bool useTabs; - bool isCStyle; - bool isJavaStyle; - bool isSharpStyle; - bool caseIndent; - bool emptyLineFill; + // options from command line or options file + int indentLength; + bool useTabs; + bool caseIndent; + bool emptyLineFill; // parsing variables int lineNumber; @@ -301,150 +479,224 @@ bool lookingForCaseBracket; bool unindentNextLine; - // stringstream for trace - stringstream *traceOut; - - private: // private functions - bool findKeyword(const string &line, int i, const char *header) const; - int indentLine(string &line, const int indent) const; - int unindentLine(string &line, const int unindent) const; - - private: // struct used by ParseFormattedLine function // contains variables used to unindent the case blocks struct switchVariables { int switchBracketCount; int unindentDepth; bool unindentCase; - - switchVariables() { // constructor - switchBracketCount = 0; - unindentDepth = 0; - unindentCase = false; - } }; - private: // inline functions - // check if a specific character can be used in a legal variable/method/class name - inline bool isLegalNameCharX(char ch) const { - return (isalnum(ch) || ch == '.' || ch == '_' || (isJavaStyle && ch == '$') || (isCStyle && ch == '~')); - } + switchVariables sw; // switch variables struct + vector swVector; // stack vector of switch variables - // check if a specific character is a whitespace character - inline bool isWhiteSpaceX(char ch) const { - return (ch == ' ' || ch == '\t'); - } -}; + // event table variables + bool nextLineIsEventIndent; // begin event table indent is reached + bool isInEventTable; // need to indent an event table + + // SQL variables + bool nextLineIsDeclareIndent; // begin declare section indent is reached + bool isInDeclareSection; // need to indent a declare section + + + private: // functions + 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; + size_t processSwitchBlock(string &line, size_t index); + int unindentLine(string &line, int unindent) const; +}; // Class ASEnhancer +//---------------------------------------------------------------------------- +// Class ASFormatter +//---------------------------------------------------------------------------- -class ASFormatter : public ASBeautifier, private ASEnhancer +class ASFormatter : public ASBeautifier { - public: + public: // functions ASFormatter(); virtual ~ASFormatter(); virtual void init(ASSourceIterator* iter); virtual bool hasMoreLines() const; virtual string nextLine(); + LineEndFormat getLineEndFormat() const; + void setFormattingStyle(FormatStyle style); + void setAddBracketsMode(bool state); + void setAddOneLineBracketsMode(bool state); void setBracketFormatMode(BracketMode mode); void setBreakClosingHeaderBracketsMode(bool state); + void setBreakBlocksMode(bool state); + void setBreakClosingHeaderBlocksMode(bool state); + void setBreakElseIfsMode(bool state); + void setBreakOneLineBlocksMode(bool state); + void setDeleteEmptyLinesMode(bool state); + void setIndentCol1CommentsMode(bool state); + void setLineEndFormat(LineEndFormat fmt); void setOperatorPaddingMode(bool mode); void setParensOutsidePaddingMode(bool mode); void setParensInsidePaddingMode(bool mode); + void setParensHeaderPaddingMode(bool mode); void setParensUnPaddingMode(bool state); - void setBreakOneLineBlocksMode(bool state); + void setPointerAlignment(PointerAlign alignment); void setSingleStatementsMode(bool state); void setTabSpaceConversionMode(bool state); - void setBreakBlocksMode(bool state); - void setBreakClosingHeaderBlocksMode(bool state); - void setBreakElseIfsMode(bool state); - string fileName; - private: - void ASformatter(ASFormatter ©); // not to be imlpemented - void operator=(ASFormatter&); // not to be implemented - void staticInit(); - void goForward(int i); - void trimNewLine(); + private: // functions + void ASformatter(ASFormatter ©); // not to be imlpemented + ASFormatter& operator=(ASFormatter&); // not to be implemented + template void deleteContainer(T &container); + template void initContainer(T &container, T value); char peekNextChar() const; - BracketType getBracketType() const; + BracketType getBracketType(); + bool addBracketsToStatement(); + bool commentAndHeaderFollows() const; bool getNextChar(); + bool getNextLine(bool emptyLineWasDeleted = false); bool isBeforeComment() const; - bool isBeforeLineEndComment(int startPos) const; + bool isBeforeAnyComment() const; + bool isBeforeAnyLineEndComment(int startPos) const; + bool isBeforeMultipleLineEndComments(int startPos) const; + bool isBracketType(BracketType a, BracketType b) const; + bool isCurrentBracketBroken() const; + bool isDereferenceOrAddressOf() const; + bool isExecSQL(string &line, size_t index) const; + bool isEmptyLine(const string &line) const; + bool isNextWordSharpNonParenHeader(int startChar) const; + bool isNonInStatementArrayBracket() const; bool isPointerOrReference() const; - bool isUnaryMinus() const; + bool isPointerOrReferenceCentered() const; + bool isSharpStyleWithParen(const string* header) const; + bool isStructAccessModified(string &firstLine, size_t index) const; + bool isUnaryOperator() const; bool isInExponent() const; - bool isOneLineBlockReached() const; -// bool isNextCharWhiteSpace() const; - bool lineBeginsWith(char charToCheck) const; - void appendChar(char ch, bool canBreakLine = true); + bool isOneLineBlockReached(string& line, int startChar) const; + bool isNextCharOpeningBracket(int startChar) const; + bool isOkToBreakBlock(BracketType bracketType) const; + int getCurrentLineCommentAdjustment(); + int getNextLineCommentAdjustment(); void appendCharInsideComments(); void appendSequence(const string &sequence, bool canBreakLine = true); void appendSpacePad(); void appendSpaceAfter(); void breakLine(); + void buildLanguageVectors(); + void checkForFollowingHeader(const string& firstLine); + void convertTabToSpaces(); + void deleteContainer(vector* &container); + void formatArrayRunIn(); + void formatRunIn(); + void goForward(int i); + void initContainer(vector* &container, vector* value); + void initNewLine(); void padOperators(const string *newOperator); void padParens(); - void formatBrackets(BracketType bracketType); void formatArrayBrackets(BracketType bracketType, bool isOpeningArrayBracket); + void formatClosingBracket(BracketType bracketType); + void formatCommentBody(); + void formatCommentOpener(); + void formatLineCommentBody(); + void formatLineCommentOpener(); + void formatOpeningBracket(BracketType bracketType); + void formatQuoteBody(); + void formatQuoteOpener(); + void formatPointerOrReference(); + void formatPointerOrReferenceCast(); void adjustComments(); - const string *findHeader(const vector &headers, bool checkBoundary = true); - - static vector headers; - static vector nonParenHeaders; - static vector preDefinitionHeaders; - static vector preCommandHeaders; - static vector operators; - static vector assignmentOperators; - static vector castOperators; + void isLineBreakBeforeClosingHeader(); + void setBreakBlocksVariables(); + void fixOptionVariableConflicts(); + void processPreprocessor(); + void trimContinuationLine(); + size_t findNextChar(string& line, char searchChar, int searchStart = 0); + string getPreviousWord(const string& line, int currPos) const; + string peekNextText(const string& firstLine, bool endOnEmptyLine=false) const; + + private: // variables + static int formatterFileType; + static vector* headers; + static vector* nonParenHeaders; + static vector* preDefinitionHeaders; + static vector* preCommandHeaders; + static vector* operators; + static vector* assignmentOperators; + static vector* castOperators; ASSourceIterator *sourceIterator; + ASEnhancer *enhancer; + vector *preBracketHeaderStack; vector *bracketTypeStack; vector *parenStack; + vector *structStack; string readyFormattedLine; string currentLine; string formattedLine; const string *currentHeader; - const string *previousOperator; // used ONLY by pad=oper + const string *previousOperator; // used ONLY by pad-oper char currentChar; char previousChar; char previousNonWSChar; char previousCommandChar; char quoteChar; int charNum; + int preprocBracketTypeStackSize; + int tabIncrementIn; int spacePadNum; + int nextLineSpacePadNum; int templateDepth; - int traceFileNumber; - size_t formattedLineCommentNum; // comment location on formattedLine + int traceLineNumber; + int horstmannIndentChars; + size_t leadingSpaces; + size_t formattedLineCommentNum; // comment location on formattedLine + size_t currentLineFirstBracketNum; // first bracket location on currentLine size_t previousReadyFormattedLineLength; + FormatStyle formattingStyle; BracketMode bracketFormatMode; BracketType previousBracketType; - bool ignoreStuff; - bool isVirgin; + PointerAlign pointerAlignment; + LineEndFormat lineEnd; + bool isVirgin; bool shouldPadOperators; bool shouldPadParensOutside; bool shouldPadParensInside; + bool shouldPadHeader; bool shouldUnPadParens; bool shouldConvertTabs; + bool shouldIndentCol1Comments; bool isInLineComment; bool isInComment; + bool noTrimCommentContinuation; bool isInPreprocessor; - bool isInTemplate; // true both in template definitions (e.g. template) and template usage (e.g. F). + bool isInTemplate; bool doesLineStartComment; + bool lineEndsInCommentOnly; + bool lineIsLineCommentOnly; + bool lineIsEmpty; + bool isImmediatelyPostCommentOnly; + bool isImmediatelyPostEmptyLine; bool isInQuote; + bool isInVerbatimQuote; + bool haveLineContinuationChar; + bool isInQuoteContinuation; bool isInBlParen; bool isSpecialChar; bool isNonParenHeader; bool foundQuestionMark; bool foundPreDefinitionHeader; bool foundNamespaceHeader; bool foundClassHeader; + bool foundStructHeader; + bool foundInterfaceHeader; bool foundPreCommandHeader; bool foundCastOperator; bool isInLineBreak; -// bool isInClosingBracketLineBreak; bool endOfCodeReached; bool lineCommentNoIndent; + bool isInExecSQL; + bool isInAsm; + bool isInAsmOneLine; + bool isInAsmBlock; bool isLineReady; bool isPreviousBracketBlockRelated; bool isInPotentialCalculation; @@ -454,18 +706,30 @@ bool isCharImmediatelyPostOpenBlock; bool isCharImmediatelyPostCloseBlock; bool isCharImmediatelyPostTemplate; + bool isCharImmediatelyPostReturn; + bool isCharImmediatelyPostOperator; + bool breakCurrentOneLineBlock; + bool isInHorstmannRunIn; + bool currentLineBeginsWithBracket; bool shouldBreakOneLineBlocks; bool shouldReparseCurrentChar; bool shouldBreakOneLineStatements; - bool shouldBreakLineAfterComments; bool shouldBreakClosingHeaderBrackets; bool shouldBreakElseIfs; + bool shouldAddBrackets; + bool shouldAddOneLineBrackets; + bool shouldDeleteEmptyLines; + bool needHeaderOpeningBracket; + bool shouldBreakLineAtNextChar; bool passedSemicolon; bool passedColon; + bool clearNonInStatement; bool isImmediatelyPostComment; bool isImmediatelyPostLineComment; bool isImmediatelyPostEmptyBlock; bool isImmediatelyPostPreprocessor; + bool isImmediatelyPostReturn; + bool isImmediatelyPostOperator; bool shouldBreakBlocks; bool shouldBreakClosingHeaderBlocks; @@ -478,20 +742,61 @@ bool isInHeader; bool isImmediatelyPostHeader; + bool isInCase; + bool isJavaStaticConstructor; + + private: // inline functions + // append a character to the current formatted line. + void appendChar(char ch, bool canBreakLine) { + if (canBreakLine && isInLineBreak) + breakLine(); + formattedLine.append(1, ch); + isImmediatelyPostCommentOnly = false; + } - private: // inline functions - // append the CURRENT character (curentChar)to the current formatted line. - inline void appendCurrentChar(bool canBreakLine = true) { + // append the CURRENT character (curentChar) to the current formatted line. + void appendCurrentChar(bool canBreakLine = true) { appendChar(currentChar, canBreakLine); } // check if a specific sequence exists in the current placement of the current line - inline bool isSequenceReached(const char *sequence) const { + bool isSequenceReached(const char *sequence) const { return currentLine.compare(charNum, strlen(sequence), sequence) == 0; } -}; -} // end of namespace astyle + // call ASBase::findHeader for the current character + const string *findHeader(const vector* headers) { + return ASBeautifier::findHeader(currentLine, charNum, headers); + } -#endif // closes ASTYLE_H + // call ASBase::findOperator for the current character + const string *findOperator(const vector* headers) { + return ASBeautifier::findOperator(currentLine, charNum, headers); + } +}; // Class ASFormatter + + +//---------------------------------------------------------------------------- +// astyle namespace global declarations +//---------------------------------------------------------------------------- +// sort comparison functions for ASResource +bool sortOnLength(const string *a, const string *b); +bool sortOnName(const string *a, const string *b); + +} // end of astyle namespace +// end of astyle namespace -------------------------------------------------- + + +//---------------------------------------------------------------------------- +// declarations for library build +// global because they are called externally and are NOT part of the namespace +//---------------------------------------------------------------------------- + +typedef void (STDCALL *fpError)(int, char*); // pointer to callback error handler +typedef char* (STDCALL *fpAlloc)(unsigned long); // pointer to callback memory allocation +extern "C" EXPORT char* STDCALL AStyleMain(const char*, const char*, fpError, fpAlloc); +extern "C" EXPORT const char* STDCALL AStyleGetVersion (void); + + +#endif // closes ASTYLE_H diff --git a/kdev-pg/kdev-pg-beautifier.h b/kdev-pg/kdev-pg-beautifier.h --- a/kdev-pg/kdev-pg-beautifier.h +++ b/kdev-pg/kdev-pg-beautifier.h @@ -32,11 +32,16 @@ class IteratorQTextStream : public astyle::ASSourceIterator { public: - IteratorQTextStream( QTextStream& stream ); + IteratorQTextStream(QTextStream& stream); + bool hasMoreLines() const override; - std::string nextLine() override; + std::string nextLine(bool emptyLineWasDeleted = false) override; + std::string peekNextLine() override; + void peekReset() override; + private: - QTextStream& strm; + QTextStream& m_stream; + qint64 m_peekStart; }; void format(QTextStream &in, const QString& oname); diff --git a/kdev-pg/kdev-pg-beautifier.cpp b/kdev-pg/kdev-pg-beautifier.cpp --- a/kdev-pg/kdev-pg-beautifier.cpp +++ b/kdev-pg/kdev-pg-beautifier.cpp @@ -26,17 +26,35 @@ { IteratorQTextStream::IteratorQTextStream( QTextStream& stream ) - : strm(stream) + : m_stream(stream) + , m_peekStart(-1) { - strcpy(outputEOL, "\n"); } + bool IteratorQTextStream::hasMoreLines() const { - return !strm.atEnd(); + return !m_stream.atEnd(); +} + +std::string IteratorQTextStream::nextLine(bool emptyLineWasDeleted) +{ + Q_UNUSED(emptyLineWasDeleted) + return m_stream.readLine().toStdString(); } -std::string IteratorQTextStream::nextLine() + +string IteratorQTextStream::peekNextLine() +{ + if (m_peekStart == -1) { + m_peekStart = m_stream.pos(); + } + return m_stream.readLine().toUtf8().data(); +} + +void IteratorQTextStream::peekReset() { - return strm.readLine().toStdString(); + if(m_peekStart != -1) + m_stream.seek(m_peekStart); + m_peekStart = -1; // invalid } void format(QTextStream& in, const QString& oname) @@ -63,7 +81,6 @@ f.setBreakElseIfsMode(false); f.setParensUnPaddingMode(false); f.setEmptyLineFill(false); - f.fileName = QFileInfo(ofile).absoluteFilePath().toStdString(); IteratorQTextStream strm(in); f.init(&strm); diff --git a/kdev-pg/kdev-pg-lexer.cc b/kdev-pg/kdev-pg-lexer.cc --- a/kdev-pg/kdev-pg-lexer.cc +++ b/kdev-pg/kdev-pg-lexer.cc @@ -1,15 +1,15 @@ -#line 2 "/home/jonathan/gitKDE/kdevelop-pg-qt/build/kdev-pg/kdev-pg-lexer.cc" +#line 2 "kdev-pg-lexer.cc" -#line 4 "/home/jonathan/gitKDE/kdevelop-pg-qt/build/kdev-pg/kdev-pg-lexer.cc" +#line 4 "kdev-pg-lexer.cc" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 1 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -54,7 +54,6 @@ typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -85,27 +84,17 @@ #define UINT32_MAX (4294967295U) #endif -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST +#endif /* ! C99 */ -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ +#endif /* ! FLEXINT_H */ -#ifdef YY_USE_CONST +/* TODO: this is always defined, so inline it */ #define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) #else -#define yyconst +#define yynoreturn #endif /* Returned upon end-of-file. */ @@ -141,7 +130,15 @@ /* Size of default input buffer. */ #ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else #define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. @@ -153,6 +150,11 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + extern int yyleng; extern FILE *yyin, *yyout; @@ -162,6 +164,7 @@ #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) + #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ @@ -179,11 +182,6 @@ #define unput(c) yyunput( c, (yytext_ptr) ) -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state @@ -196,7 +194,7 @@ /* Size of input buffer in bytes, not including room for EOB * characters. */ - yy_size_t yy_buf_size; + int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. @@ -224,7 +222,7 @@ int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ - + /* Whether to try to fill the input buffer when we reach the * end of it. */ @@ -252,7 +250,7 @@ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general @@ -275,7 +273,7 @@ int yyleng; /* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; +static char *yy_c_buf_p = NULL; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ @@ -334,29 +332,32 @@ typedef unsigned char YY_CHAR; -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +FILE *yyin = NULL, *yyout = NULL; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); -static void yy_fatal_error (yyconst char msg[] ); +static void yynoreturn yy_fatal_error (yyconst char* msg ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ (yytext_ptr) -= (yy_more_len); \ - yyleng = (size_t) (yy_cp - (yytext_ptr)); \ + yyleng = (int) (yy_cp - (yytext_ptr)); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; @@ -508,7 +509,7 @@ 513, 513, 514, 515, 516, 516, 517, 518, 518 } ; -static yyconst flex_int32_t yy_ec[256] = +static yyconst YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, 4, 1, 1, 1, 1, 1, 1, 1, @@ -540,7 +541,7 @@ 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[71] = +static yyconst YY_CHAR yy_meta[71] = { 0, 1, 2, 3, 3, 4, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 8, 8, @@ -551,7 +552,7 @@ 12, 12, 12, 12, 12, 12, 5, 5, 14, 5 } ; -static yyconst flex_int16_t yy_base[704] = +static yyconst flex_uint16_t yy_base[704] = { 0, 0, 0, 68, 70, 73, 77, 92, 98, 138, 0, 83, 100, 208, 0, 1820, 1821, 92, 1821, 1816, 76, @@ -715,7 +716,7 @@ 668, 668, 668 } ; -static yyconst flex_int16_t yy_nxt[1892] = +static yyconst flex_uint16_t yy_nxt[1892] = { 0, 16, 17, 18, 19, 17, 16, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 16, 31, 32, @@ -1169,8 +1170,8 @@ #define YY_MORE_ADJ (yy_more_len) #define YY_RESTORE_YY_MORE_OFFSET char *yytext; -#line 1 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" -#line 2 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 1 "kdev-pg-lexer.ll" +#line 2 "kdev-pg-lexer.ll" /* This file is part of kdev-pg-qt Copyright (C) 2006 Jakob Petsovits @@ -1236,7 +1237,7 @@ } \ else \ { \ - QByteArray tmp("\n\01!ASIgnore\"!!\n#"); \ + QByteArray tmp("\n#"); \ if(KDevPG::globalSystem.lineNumberPolicy == KDevPG::World::CompatibilityLineNumbers) \ tmp += "line"; \ tmp += " " + QString::number(firstCodeLine).toLocal8Bit(); \ @@ -1249,7 +1250,6 @@ strncpy(yylval.str, tmp.data(), tmp.size()); \ memset(yylval.str + tmp.size(), ' ', firstCodeColumn); \ strncpy(yylval.str + tmp.size() + firstCodeColumn, string, len); \ - strncpy(yylval.str + memlen - 17, "\n\01!AS/Ignore\"!!\n", 16); \ yylval.str[memlen-1] = '\0'; \ } @@ -1280,7 +1280,7 @@ -#line 1284 "/home/jonathan/gitKDE/kdevelop-pg-qt/build/kdev-pg/kdev-pg-lexer.cc" +#line 1284 "kdev-pg-lexer.cc" #define INITIAL 0 #define CODE 1 @@ -1311,19 +1311,19 @@ FILE *yyget_in (void ); -void yyset_in (FILE * in_str ); +void yyset_in (FILE * _in_str ); FILE *yyget_out (void ); -void yyset_out (FILE * out_str ); +void yyset_out (FILE * _out_str ); -int yyget_leng (void ); + int yyget_leng (void ); char *yyget_text (void ); int yyget_lineno (void ); -void yyset_lineno (int line_number ); +void yyset_lineno (int _line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. @@ -1337,8 +1337,12 @@ #endif #endif +#ifndef YY_NO_UNPUT + static void yyunput (int c,char *buf_ptr ); +#endif + #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif @@ -1359,15 +1363,20 @@ /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else #define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -1378,7 +1387,7 @@ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - int n; \ + size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -1391,7 +1400,7 @@ else \ { \ errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ @@ -1446,7 +1455,7 @@ /* Code executed at the end of each rule. */ #ifndef YY_BREAK -#define YY_BREAK break; +#define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ @@ -1456,16 +1465,10 @@ */ YY_DECL { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; -#line 119 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" - - - -#line 1468 "/home/jonathan/gitKDE/kdevelop-pg-qt/build/kdev-pg/kdev-pg-lexer.cc" - if ( !(yy_init) ) { (yy_init) = 1; @@ -1498,7 +1501,14 @@ yy_load_buffer_state( ); } - while ( 1 ) /* loops until end-of-file is reached */ + { +#line 118 "kdev-pg-lexer.ll" + + + +#line 1510 "kdev-pg-lexer.cc" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { (yy_more_len) = 0; if ( (yy_more_flag) ) @@ -1524,14 +1534,14 @@ yy_match: do { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 669 ) yy_c = yy_meta[(unsigned int) yy_c]; } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; *(yy_state_ptr)++ = yy_current_state; ++yy_cp; } @@ -1587,361 +1597,361 @@ { /* beginning of action switch */ case 1: YY_RULE_SETUP -#line 122 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 121 "kdev-pg-lexer.ll" /* skip */ ; YY_BREAK case 2: /* rule 2 can match eol */ YY_RULE_SETUP -#line 123 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 122 "kdev-pg-lexer.ll" newline(); YY_BREAK case 3: YY_RULE_SETUP -#line 124 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 123 "kdev-pg-lexer.ll" /* line comments, skip */ ; YY_BREAK case 4: YY_RULE_SETUP -#line 126 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 125 "kdev-pg-lexer.ll" rulePosition = RuleBody; return ';'; YY_BREAK case 5: YY_RULE_SETUP -#line 127 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 126 "kdev-pg-lexer.ll" if(rulePosition == RuleLexer) BEGIN(RULE_LEXER); else rulePosition = RuleFooter; return T_ARROW; YY_BREAK case 6: YY_RULE_SETUP -#line 128 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 127 "kdev-pg-lexer.ll" return T_INLINE; YY_BREAK case 7: YY_RULE_SETUP -#line 130 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 129 "kdev-pg-lexer.ll" return '('; YY_BREAK case 8: YY_RULE_SETUP -#line 131 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 130 "kdev-pg-lexer.ll" return ')'; YY_BREAK case 9: YY_RULE_SETUP -#line 132 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 131 "kdev-pg-lexer.ll" return '{'; YY_BREAK case 10: YY_RULE_SETUP -#line 133 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 132 "kdev-pg-lexer.ll" return '}'; YY_BREAK case 11: YY_RULE_SETUP -#line 134 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 133 "kdev-pg-lexer.ll" return ','; YY_BREAK case 12: YY_RULE_SETUP -#line 135 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 134 "kdev-pg-lexer.ll" return '0'; YY_BREAK case 13: YY_RULE_SETUP -#line 136 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 135 "kdev-pg-lexer.ll" return '#'; YY_BREAK case 14: YY_RULE_SETUP -#line 137 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 136 "kdev-pg-lexer.ll" return '.'; YY_BREAK case 15: YY_RULE_SETUP -#line 138 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 137 "kdev-pg-lexer.ll" return ':'; YY_BREAK case 16: YY_RULE_SETUP -#line 139 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 138 "kdev-pg-lexer.ll" return '='; YY_BREAK case 17: YY_RULE_SETUP -#line 140 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 139 "kdev-pg-lexer.ll" return '+'; YY_BREAK case 18: YY_RULE_SETUP -#line 141 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 140 "kdev-pg-lexer.ll" return '*'; YY_BREAK case 19: YY_RULE_SETUP -#line 142 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 141 "kdev-pg-lexer.ll" return '?'; YY_BREAK case 20: YY_RULE_SETUP -#line 143 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 142 "kdev-pg-lexer.ll" return '@'; YY_BREAK case 21: YY_RULE_SETUP -#line 144 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 143 "kdev-pg-lexer.ll" return '|'; YY_BREAK case 22: YY_RULE_SETUP -#line 145 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 144 "kdev-pg-lexer.ll" return '&'; YY_BREAK case 23: YY_RULE_SETUP -#line 147 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 146 "kdev-pg-lexer.ll" return T_TRY_RECOVER; YY_BREAK case 24: YY_RULE_SETUP -#line 148 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 147 "kdev-pg-lexer.ll" return T_TRY_ROLLBACK; YY_BREAK case 25: YY_RULE_SETUP -#line 149 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 148 "kdev-pg-lexer.ll" return T_CATCH; YY_BREAK case 26: YY_RULE_SETUP -#line 151 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 150 "kdev-pg-lexer.ll" return T_EXPORT_MACRO; YY_BREAK case 27: YY_RULE_SETUP -#line 152 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 151 "kdev-pg-lexer.ll" return T_EXPORT_MACRO_HEADER; YY_BREAK case 28: YY_RULE_SETUP -#line 153 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 152 "kdev-pg-lexer.ll" return T_TOKEN_DECLARATION; YY_BREAK case 29: YY_RULE_SETUP -#line 154 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 153 "kdev-pg-lexer.ll" return T_TOKEN_STREAM_DECLARATION; YY_BREAK case 30: YY_RULE_SETUP -#line 155 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 154 "kdev-pg-lexer.ll" return T_NAMESPACE_DECLARATION; YY_BREAK case 31: YY_RULE_SETUP -#line 156 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 155 "kdev-pg-lexer.ll" BEGIN(PARSERCLASS); return T_PARSERCLASS_DECLARATION; YY_BREAK case 32: YY_RULE_SETUP -#line 157 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 156 "kdev-pg-lexer.ll" BEGIN(PARSERCLASS); return T_LEXERCLASS_DECLARATION; YY_BREAK case 33: YY_RULE_SETUP -#line 158 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 157 "kdev-pg-lexer.ll" return T_INPUT_STREAM; YY_BREAK case 34: YY_RULE_SETUP -#line 159 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 158 "kdev-pg-lexer.ll" return T_AST_DECLARATION; YY_BREAK case 35: YY_RULE_SETUP -#line 160 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 159 "kdev-pg-lexer.ll" return T_PARSER_DECLARATION_HEADER; YY_BREAK case 36: YY_RULE_SETUP -#line 161 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 160 "kdev-pg-lexer.ll" return T_PARSER_BITS_HEADER; YY_BREAK case 37: YY_RULE_SETUP -#line 162 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 161 "kdev-pg-lexer.ll" return T_AST_HEADER; YY_BREAK case 38: YY_RULE_SETUP -#line 163 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 162 "kdev-pg-lexer.ll" return T_LEXER_DECLARATION_HEADER; YY_BREAK case 39: YY_RULE_SETUP -#line 164 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 163 "kdev-pg-lexer.ll" return T_LEXER_BITS_HEADER; YY_BREAK case 40: YY_RULE_SETUP -#line 165 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 164 "kdev-pg-lexer.ll" return T_INPUT_ENCODING; YY_BREAK case 41: YY_RULE_SETUP -#line 166 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 165 "kdev-pg-lexer.ll" return T_TABLE_LEXER; YY_BREAK case 42: YY_RULE_SETUP -#line 167 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 166 "kdev-pg-lexer.ll" return T_SEQUENCE_LEXER; YY_BREAK case 43: YY_RULE_SETUP -#line 168 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 167 "kdev-pg-lexer.ll" return T_AST_BASE; YY_BREAK case 44: YY_RULE_SETUP -#line 169 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 168 "kdev-pg-lexer.ll" return T_PARSER_BASE; YY_BREAK case 45: YY_RULE_SETUP -#line 170 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 169 "kdev-pg-lexer.ll" return T_LEXER_BASE; YY_BREAK case 46: YY_RULE_SETUP -#line 171 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 170 "kdev-pg-lexer.ll" return T_BIN; YY_BREAK case 47: YY_RULE_SETUP -#line 172 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 171 "kdev-pg-lexer.ll" return T_PRE; YY_BREAK case 48: YY_RULE_SETUP -#line 173 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 172 "kdev-pg-lexer.ll" return T_POST; YY_BREAK case 49: YY_RULE_SETUP -#line 174 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 173 "kdev-pg-lexer.ll" return T_TERN; YY_BREAK case 50: YY_RULE_SETUP -#line 175 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 174 "kdev-pg-lexer.ll" return T_PAREN; YY_BREAK case 51: YY_RULE_SETUP -#line 176 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 175 "kdev-pg-lexer.ll" return T_PRIORITY; YY_BREAK case 52: YY_RULE_SETUP -#line 177 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 176 "kdev-pg-lexer.ll" rulePosition = RuleBody; return T_LOPR; YY_BREAK case 53: YY_RULE_SETUP -#line 178 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 177 "kdev-pg-lexer.ll" rulePosition = RuleFooter; return T_ROPR; YY_BREAK case 54: YY_RULE_SETUP -#line 179 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 178 "kdev-pg-lexer.ll" return T_LEFT_ASSOC; YY_BREAK case 55: YY_RULE_SETUP -#line 180 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 179 "kdev-pg-lexer.ll" return T_RIGHT_ASSOC; YY_BREAK case 56: YY_RULE_SETUP -#line 181 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 180 "kdev-pg-lexer.ll" return T_IS_LEFT_ASSOC; YY_BREAK case 57: YY_RULE_SETUP -#line 182 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 181 "kdev-pg-lexer.ll" return T_IS_RIGHT_ASSOC; YY_BREAK case 58: YY_RULE_SETUP -#line 183 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 182 "kdev-pg-lexer.ll" rulePosition = RuleLexer; return T_LEXER; YY_BREAK case 59: YY_RULE_SETUP -#line 186 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 185 "kdev-pg-lexer.ll" /* skip */ ; YY_BREAK case 60: /* rule 60 can match eol */ YY_RULE_SETUP -#line 187 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 186 "kdev-pg-lexer.ll" newline(); YY_BREAK case 61: YY_RULE_SETUP -#line 188 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 187 "kdev-pg-lexer.ll" return '('; YY_BREAK case 62: YY_RULE_SETUP -#line 189 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 188 "kdev-pg-lexer.ll" return T_PUBLIC; YY_BREAK case 63: YY_RULE_SETUP -#line 190 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 189 "kdev-pg-lexer.ll" return T_PRIVATE; YY_BREAK case 64: YY_RULE_SETUP -#line 191 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 190 "kdev-pg-lexer.ll" return T_PROTECTED; YY_BREAK case 65: YY_RULE_SETUP -#line 192 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 191 "kdev-pg-lexer.ll" return T_DECLARATION; YY_BREAK case 66: YY_RULE_SETUP -#line 193 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 192 "kdev-pg-lexer.ll" return T_CONSTRUCTOR; YY_BREAK case 67: YY_RULE_SETUP -#line 194 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 193 "kdev-pg-lexer.ll" return T_DESTRUCTOR; YY_BREAK case 68: YY_RULE_SETUP -#line 195 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 194 "kdev-pg-lexer.ll" return T_BITS; YY_BREAK case 69: YY_RULE_SETUP -#line 196 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 195 "kdev-pg-lexer.ll" BEGIN(INITIAL); return ')'; YY_BREAK case 70: YY_RULE_SETUP -#line 197 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 196 "kdev-pg-lexer.ll" BEGIN(INITIAL); REJECT; /* everything else */ YY_BREAK case 71: YY_RULE_SETUP -#line 201 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 200 "kdev-pg-lexer.ll" { if (rulePosition == RuleBody) { /* use the arguments in a rule call */ firstCodeLine = yyLine; @@ -1956,170 +1966,170 @@ case 72: YY_RULE_SETUP -#line 213 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 212 "kdev-pg-lexer.ll" /* line comments, skip */ ; YY_BREAK case 73: /* rule 73 can match eol */ YY_RULE_SETUP -#line 214 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 213 "kdev-pg-lexer.ll" newline(); YY_BREAK case 74: YY_RULE_SETUP -#line 215 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 214 "kdev-pg-lexer.ll" ++yytext; COPY_TO_YYLVAL(yytext,yyleng-2); return T_NAMED_REGEXP; YY_BREAK case 75: /* rule 75 can match eol */ YY_RULE_SETUP -#line 216 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 215 "kdev-pg-lexer.ll" countNewlines(yytext, yyleng); rulePosition = RuleBody; BEGIN(INITIAL); return ';'; YY_BREAK case 76: YY_RULE_SETUP -#line 217 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 216 "kdev-pg-lexer.ll" return ';'; YY_BREAK case 77: YY_RULE_SETUP -#line 218 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 217 "kdev-pg-lexer.ll" ++openBrackets; return '['; YY_BREAK case 78: YY_RULE_SETUP -#line 219 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 218 "kdev-pg-lexer.ll" --openBrackets; return ']'; YY_BREAK case 79: YY_RULE_SETUP -#line 220 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 219 "kdev-pg-lexer.ll" ++openBrackets; return '('; YY_BREAK case 80: YY_RULE_SETUP -#line 221 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 220 "kdev-pg-lexer.ll" --openBrackets; return ')'; YY_BREAK case 81: YY_RULE_SETUP -#line 222 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 221 "kdev-pg-lexer.ll" return '?'; YY_BREAK case 82: YY_RULE_SETUP -#line 223 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 222 "kdev-pg-lexer.ll" return '|'; YY_BREAK case 83: YY_RULE_SETUP -#line 224 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 223 "kdev-pg-lexer.ll" return '^'; YY_BREAK case 84: YY_RULE_SETUP -#line 225 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 224 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_RANGE; YY_BREAK case 85: YY_RULE_SETUP -#line 226 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 225 "kdev-pg-lexer.ll" return '&'; YY_BREAK case 86: YY_RULE_SETUP -#line 227 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 226 "kdev-pg-lexer.ll" return '~'; YY_BREAK case 87: YY_RULE_SETUP -#line 228 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 227 "kdev-pg-lexer.ll" return '*'; YY_BREAK case 88: YY_RULE_SETUP -#line 229 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 228 "kdev-pg-lexer.ll" return '+'; YY_BREAK case 89: YY_RULE_SETUP -#line 230 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 229 "kdev-pg-lexer.ll" return '@'; YY_BREAK case 90: YY_RULE_SETUP -#line 231 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 230 "kdev-pg-lexer.ll" return '.'; YY_BREAK case 91: YY_RULE_SETUP -#line 232 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 231 "kdev-pg-lexer.ll" return T_ARROW; YY_BREAK case 92: YY_RULE_SETUP -#line 233 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 232 "kdev-pg-lexer.ll" return T_CONTINUE; YY_BREAK case 93: YY_RULE_SETUP -#line 234 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 233 "kdev-pg-lexer.ll" return T_FAIL; YY_BREAK case 94: YY_RULE_SETUP -#line 235 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 234 "kdev-pg-lexer.ll" return T_ENTER_RULE_SET; YY_BREAK case 95: YY_RULE_SETUP -#line 236 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 235 "kdev-pg-lexer.ll" return T_LEAVE_RULE_SET; YY_BREAK case 96: YY_RULE_SETUP -#line 237 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 236 "kdev-pg-lexer.ll" return T_LOOKAHEAD; YY_BREAK case 97: YY_RULE_SETUP -#line 238 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 237 "kdev-pg-lexer.ll" return T_BARRIER; YY_BREAK case 98: YY_RULE_SETUP -#line 239 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 238 "kdev-pg-lexer.ll" firstCodeLine = yyLine; firstCodeColumn = currentOffset + 2; BEGIN(CODE); YY_BREAK case 99: /* rule 99 can match eol */ YY_RULE_SETUP -#line 240 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 239 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_TERMINAL; YY_BREAK case 100: /* rule 100 can match eol */ YY_RULE_SETUP -#line 241 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 240 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_IDENTIFIER; YY_BREAK case 101: YY_RULE_SETUP -#line 242 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 241 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_UNQUOTED_STRING; YY_BREAK case 102: YY_RULE_SETUP -#line 243 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 242 "kdev-pg-lexer.ll" /* skip */ YY_BREAK case 103: YY_RULE_SETUP -#line 244 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 243 "kdev-pg-lexer.ll" yytext++; COPY_TO_YYLVAL(yytext,yyleng-2); return T_STRING; YY_BREAK case YY_STATE_EOF(RULE_LEXER): -#line 246 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 245 "kdev-pg-lexer.ll" { BEGIN(INITIAL); // is not set automatically by yyrestart() KDevPG::checkOut << "** ERROR Encountered end of file in an unclosed rule lexer definition..." << endl; @@ -2132,32 +2142,32 @@ case 104: /* rule 104 can match eol */ YY_RULE_SETUP -#line 255 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 254 "kdev-pg-lexer.ll" newline(); YYMORE; YY_BREAK case 105: YY_RULE_SETUP -#line 256 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 255 "kdev-pg-lexer.ll" YYMORE; /* this and... */ YY_BREAK case 106: YY_RULE_SETUP -#line 257 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 256 "kdev-pg-lexer.ll" YYMORE; /* ...this prevent brackets inside strings to be counted */ YY_BREAK case 107: YY_RULE_SETUP -#line 258 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 257 "kdev-pg-lexer.ll" YYMORE; /* gather everything that's not a bracket, and append what comes next */ YY_BREAK case 108: YY_RULE_SETUP -#line 259 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 258 "kdev-pg-lexer.ll" openBrackets++; YYMORE; YY_BREAK case 109: YY_RULE_SETUP -#line 260 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 259 "kdev-pg-lexer.ll" { openBrackets--; if (openBrackets < 0) { @@ -2168,7 +2178,7 @@ } YY_BREAK case YY_STATE_EOF(RULE_ARGUMENTS): -#line 268 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 267 "kdev-pg-lexer.ll" { BEGIN(INITIAL); // is not set automatically by yyrestart() KDevPG::checkOut << "** ERROR Encountered end of file in an unclosed rule argument specification..." << endl; @@ -2180,96 +2190,96 @@ case 110: YY_RULE_SETUP -#line 277 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 276 "kdev-pg-lexer.ll" /* skip */ ; YY_BREAK case 111: /* rule 111 can match eol */ YY_RULE_SETUP -#line 278 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 277 "kdev-pg-lexer.ll" newline(); YY_BREAK case 112: YY_RULE_SETUP -#line 279 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 278 "kdev-pg-lexer.ll" /* line comments, skip */ ; YY_BREAK case 113: YY_RULE_SETUP -#line 280 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 279 "kdev-pg-lexer.ll" BEGIN(RULE_PARAMETERS_VARNAME); return ':'; YY_BREAK case 114: YY_RULE_SETUP -#line 281 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 280 "kdev-pg-lexer.ll" return '#'; YY_BREAK case 115: YY_RULE_SETUP -#line 282 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 281 "kdev-pg-lexer.ll" return T_MEMBER; YY_BREAK case 116: YY_RULE_SETUP -#line 283 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 282 "kdev-pg-lexer.ll" return T_TEMPORARY; YY_BREAK case 117: YY_RULE_SETUP -#line 284 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 283 "kdev-pg-lexer.ll" return T_ARGUMENT; YY_BREAK case 118: YY_RULE_SETUP -#line 285 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 284 "kdev-pg-lexer.ll" return T_NODE; YY_BREAK case 119: YY_RULE_SETUP -#line 286 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 285 "kdev-pg-lexer.ll" return T_TOKEN; YY_BREAK case 120: YY_RULE_SETUP -#line 287 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 286 "kdev-pg-lexer.ll" return T_VARIABLE; YY_BREAK case 121: YY_RULE_SETUP -#line 288 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 287 "kdev-pg-lexer.ll" return ';'; /* only used for "token" types */ YY_BREAK case 122: YY_RULE_SETUP -#line 289 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 288 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_IDENTIFIER; YY_BREAK case 123: YY_RULE_SETUP -#line 290 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 289 "kdev-pg-lexer.ll" BEGIN(INITIAL); return ']'; YY_BREAK case 124: YY_RULE_SETUP -#line 291 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 290 "kdev-pg-lexer.ll" BEGIN(INITIAL); REJECT; /* everything else */ YY_BREAK case 125: /* rule 125 can match eol */ YY_RULE_SETUP -#line 295 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 294 "kdev-pg-lexer.ll" newline(); YYMORE; YY_BREAK case 126: YY_RULE_SETUP -#line 296 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 295 "kdev-pg-lexer.ll" YYMORE; /* gather everything that's not a semicolon, and append what comes next */ YY_BREAK case 127: YY_RULE_SETUP -#line 297 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 296 "kdev-pg-lexer.ll" { // strip trailing whitespace int length = yyleng-1; // and first, the trailing semicolon @@ -2292,35 +2302,35 @@ YY_BREAK case 128: YY_RULE_SETUP -#line 316 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 315 "kdev-pg-lexer.ll" BEGIN(INITIAL); REJECT; /* everything else */ YY_BREAK case 129: YY_RULE_SETUP -#line 320 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 319 "kdev-pg-lexer.ll" firstCodeLine = yyLine; firstCodeColumn = currentOffset + 2; BEGIN(CODE); YY_BREAK case 130: /* rule 130 can match eol */ YY_RULE_SETUP -#line 322 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 321 "kdev-pg-lexer.ll" newline(); YYMORE; YY_BREAK case 131: YY_RULE_SETUP -#line 323 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 322 "kdev-pg-lexer.ll" YYMORE; /* gather everything that's not a colon, and append what comes next */ YY_BREAK case 132: YY_RULE_SETUP -#line 324 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 323 "kdev-pg-lexer.ll" YYMORE; /* also gather colons that are not followed by colons or newlines */ YY_BREAK case 133: YY_RULE_SETUP -#line 325 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 324 "kdev-pg-lexer.ll" { COPY_CODE_TO_YYLVAL(yytext, (yyleng-2)); /* cut off the trailing stuff */ if(rulePosition == RuleLexer) @@ -2331,7 +2341,7 @@ } YY_BREAK case YY_STATE_EOF(CODE): -#line 333 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 332 "kdev-pg-lexer.ll" { BEGIN(INITIAL); // is not set automatically by yyrestart() KDevPG::checkOut << "** ERROR Encountered end of file in an unclosed code segment..." << endl; @@ -2342,42 +2352,42 @@ case 134: YY_RULE_SETUP -#line 342 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 341 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_TERMINAL; YY_BREAK case 135: YY_RULE_SETUP -#line 343 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 342 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_IDENTIFIER; YY_BREAK case 136: YY_RULE_SETUP -#line 344 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 343 "kdev-pg-lexer.ll" COPY_TO_YYLVAL(yytext,yyleng); return T_NUMBER; YY_BREAK case 137: YY_RULE_SETUP -#line 347 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 346 "kdev-pg-lexer.ll" { yytext++; /* start inside the quotes */ COPY_TO_YYLVAL(yytext,yyleng-2); /* cut off the trailing quote */ return T_STRING; } YY_BREAK case 138: YY_RULE_SETUP -#line 353 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 352 "kdev-pg-lexer.ll" { KDevPG::checkOut << "Unexpected character: ``" << yytext[0] << "''" << endl; yyerror(""); } YY_BREAK case 139: YY_RULE_SETUP -#line 359 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 358 "kdev-pg-lexer.ll" ECHO; YY_BREAK -#line 2381 "/home/jonathan/gitKDE/kdevelop-pg-qt/build/kdev-pg/kdev-pg-lexer.cc" +#line 2391 "kdev-pg-lexer.cc" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(PARSERCLASS): case YY_STATE_EOF(RULE_PARAMETERS_HEADER): @@ -2511,6 +2521,7 @@ "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ + } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer @@ -2522,9 +2533,9 @@ */ static int yy_get_next_buffer (void) { - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = (yytext_ptr); - register int number_to_move, i; + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) @@ -2553,7 +2564,7 @@ /* Try to read more data. */ /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); @@ -2582,7 +2593,7 @@ /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), (size_t) num_to_read ); + (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } @@ -2606,9 +2617,9 @@ else ret_val = EOB_ACT_CONTINUE_SCAN; - if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); @@ -2627,24 +2638,24 @@ static yy_state_type yy_get_previous_state (void) { - register yy_state_type yy_current_state; - register char *yy_cp; + yy_state_type yy_current_state; + char *yy_cp; yy_current_state = (yy_start); (yy_state_ptr) = (yy_state_buf); *(yy_state_ptr)++ = yy_current_state; for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 669 ) yy_c = yy_meta[(unsigned int) yy_c]; } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; *(yy_state_ptr)++ = yy_current_state; } @@ -2658,26 +2669,28 @@ */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { - register int yy_is_jam; + int yy_is_jam; - register YY_CHAR yy_c = 1; + YY_CHAR yy_c = 1; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 669 ) yy_c = yy_meta[(unsigned int) yy_c]; } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; yy_is_jam = (yy_current_state == 668); if ( ! yy_is_jam ) *(yy_state_ptr)++ = yy_current_state; - return yy_is_jam ? 0 : yy_current_state; + return yy_is_jam ? 0 : yy_current_state; } - static void yyunput (int c, register char * yy_bp ) +#ifndef YY_NO_UNPUT + + static void yyunput (int c, char * yy_bp ) { - register char *yy_cp; + char *yy_cp; yy_cp = (yy_c_buf_p); @@ -2687,19 +2700,19 @@ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ - register int number_to_move = (yy_n_chars) + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + int number_to_move = (yy_n_chars) + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = + char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); @@ -2712,6 +2725,8 @@ (yy_c_buf_p) = yy_cp; } +#endif + #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) @@ -2760,7 +2775,7 @@ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) - return EOF; + return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; @@ -2861,7 +2876,7 @@ if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - b->yy_buf_size = size; + b->yy_buf_size = (yy_size_t)size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. @@ -2896,10 +2911,6 @@ yyfree((void *) b ); } -#ifndef __cplusplus -extern int isatty (int ); -#endif /* __cplusplus */ - /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. @@ -3020,24 +3031,24 @@ * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ - num_to_alloc = 1; + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - + (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; + yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc @@ -3057,7 +3068,7 @@ * @param base the character buffer * @param size the size in bytes of the character buffer * - * @return the newly allocated buffer state object. + * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { @@ -3067,16 +3078,16 @@ base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ - return 0; + return NULL; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; - b->yy_input_file = 0; + b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; @@ -3099,13 +3110,13 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { - return yy_scan_bytes(yystr,strlen(yystr) ); + return yy_scan_bytes(yystr,(int) strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ @@ -3117,7 +3128,7 @@ int i; /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; + n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); @@ -3143,9 +3154,9 @@ #define YY_EXIT_FAILURE 2 #endif -static void yy_fatal_error (yyconst char* msg ) +static void yynoreturn yy_fatal_error (yyconst char* msg ) { - (void) fprintf( stderr, "%s\n", msg ); + (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } @@ -3173,7 +3184,7 @@ */ int yyget_lineno (void) { - + return yylineno; } @@ -3211,51 +3222,51 @@ } /** Set the current line number. - * @param line_number + * @param _line_number line number * */ -void yyset_lineno (int line_number ) +void yyset_lineno (int _line_number ) { - yylineno = line_number; + yylineno = _line_number; } /** Set the input stream. This does not discard the current * input buffer. - * @param in_str A readable stream. + * @param _in_str A readable stream. * * @see yy_switch_to_buffer */ -void yyset_in (FILE * in_str ) +void yyset_in (FILE * _in_str ) { - yyin = in_str ; + yyin = _in_str ; } -void yyset_out (FILE * out_str ) +void yyset_out (FILE * _out_str ) { - yyout = out_str ; + yyout = _out_str ; } int yyget_debug (void) { return yy_flex_debug; } -void yyset_debug (int bdebug ) +void yyset_debug (int _bdebug ) { - yy_flex_debug = bdebug ; + yy_flex_debug = _bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ - (yy_buffer_stack) = 0; + (yy_buffer_stack) = NULL; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; - (yy_c_buf_p) = (char *) 0; + (yy_c_buf_p) = NULL; (yy_init) = 0; (yy_start) = 0; @@ -3269,8 +3280,8 @@ yyin = stdin; yyout = stdout; #else - yyin = (FILE *) 0; - yyout = (FILE *) 0; + yyin = NULL; + yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by @@ -3311,16 +3322,17 @@ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { - register int i; + + int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { - register int n; + int n; for ( n = 0; s[n]; ++n ) ; @@ -3330,29 +3342,30 @@ void *yyalloc (yy_size_t size ) { - return (void *) malloc( size ); + return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size ) { + /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ - return (void *) realloc( (char *) ptr, size ); + return realloc(ptr, size); } void yyfree (void * ptr ) { - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" -#line 359 "/home/jonathan/gitKDE/kdevelop-pg-qt/kdev-pg/kdev-pg-lexer.ll" +#line 358 "kdev-pg-lexer.ll" diff --git a/kdev-pg/kdev-pg-lexer.ll b/kdev-pg/kdev-pg-lexer.ll --- a/kdev-pg/kdev-pg-lexer.ll +++ b/kdev-pg/kdev-pg-lexer.ll @@ -64,7 +64,7 @@ } \ else \ { \ - QByteArray tmp("\n\01!ASIgnore\"!!\n#"); \ + QByteArray tmp("\n#"); \ if(KDevPG::globalSystem.lineNumberPolicy == KDevPG::World::CompatibilityLineNumbers) \ tmp += "line"; \ tmp += " " + QString::number(firstCodeLine).toLocal8Bit(); \ @@ -77,7 +77,6 @@ strncpy(yylval.str, tmp.data(), tmp.size()); \ memset(yylval.str + tmp.size(), ' ', firstCodeColumn); \ strncpy(yylval.str + tmp.size() + firstCodeColumn, string, len); \ - strncpy(yylval.str + memlen - 17, "\n\01!AS/Ignore\"!!\n", 16); \ yylval.str[memlen-1] = '\0'; \ }