📄 asbeautifier.cpp
字号:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* ASBeautifier.cpp
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU 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.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
#include "astyle.h"
#include <algorithm>
#include <iostream>
#define INIT_CONTAINER(container, value) {if ( (container) != NULL ) delete (container); (container) = (value); }
#define DELETE_CONTAINER(container) {if ( (container) != NULL ) delete (container); }
namespace astyle
{
vector<const string*> ASBeautifier::headers;
vector<const string*> ASBeautifier::nonParenHeaders;
vector<const string*> ASBeautifier::preBlockStatements;
vector<const string*> ASBeautifier::assignmentOperators;
vector<const string*> 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);
// cout << "beaut" << endl;
}
/**
* ASBeautifier's constructor
*/
ASBeautifier::ASBeautifier()
{
waitingBeautifierStack = NULL;
activeBeautifierStack = NULL;
waitingBeautifierStackLengthStack = NULL;
activeBeautifierStackLengthStack = NULL;
headerStack = NULL;
tempStacks = NULL;
blockParenDepthStack = NULL;
blockStatementStack = NULL;
parenStatementStack = NULL;
bracketBlockStateStack = NULL;
inStatementIndentStack = NULL;
inStatementIndentStackSizeStack = NULL;
parenIndentStack = NULL;
sourceIterator = NULL;
isMinimalConditinalIndentSet = false;
shouldForceTabIndentation = false;
setSpaceIndentation(4);
setMaxInStatementIndentLength(40);
setClassIndent(false);
setSwitchIndent(false);
setCaseIndent(false);
setBlockIndent(false);
setBracketIndent(false);
setNamespaceIndent(false);
setLabelIndent(false);
setEmptyLineFill(false);
fileType = C_TYPE;
setCStyle();
setPreprocessorIndent(false);
}
/**
* ASBeautifier's copy constructor
*/
ASBeautifier::ASBeautifier(const ASBeautifier &other)
{
waitingBeautifierStack = NULL;
activeBeautifierStack = NULL;
waitingBeautifierStackLengthStack = NULL;
activeBeautifierStackLengthStack = NULL;
headerStack = new vector<const string*>;
*headerStack = *other.headerStack;
tempStacks = new vector<vector<const string*>*>;
vector<vector<const string*>*>::iterator iter;
for (iter = other.tempStacks->begin();
iter != other.tempStacks->end();
++iter)
{
vector<const string*> *newVec = new vector<const string*>;
*newVec = **iter;
tempStacks->push_back(newVec);
}
blockParenDepthStack = new vector<int>;
*blockParenDepthStack = *other.blockParenDepthStack;
blockStatementStack = new vector<bool>;
*blockStatementStack = *other.blockStatementStack;
parenStatementStack = new vector<bool>;
*parenStatementStack = *other.parenStatementStack;
bracketBlockStateStack = new vector<bool>;
*bracketBlockStateStack = *other.bracketBlockStateStack;
inStatementIndentStack = new vector<int>;
*inStatementIndentStack = *other.inStatementIndentStack;
inStatementIndentStackSizeStack = new vector<int>;
*inStatementIndentStackSizeStack = *other.inStatementIndentStackSizeStack;
parenIndentStack = new vector<int>;
*parenIndentStack = *other.parenIndentStack;
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
inLineNumber = other.inLineNumber;
outLineNumber = other.outLineNumber;
lineCommentNoBeautify = other.lineCommentNoBeautify;
isNonInStatementArray = other.isNonInStatementArray;
// private variables
indentString = other.indentString;
currentHeader = other.currentHeader;
previousLastLineHeader = other.previousLastLineHeader;
immediatelyPreviousAssignmentOp = other.immediatelyPreviousAssignmentOp;
probationHeader = other.probationHeader;
isInQuote = other.isInQuote;
isInComment = other.isInComment;
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;
isInClassHeaderTab = other.isInClassHeaderTab;
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;
shouldForceTabIndentation = other.shouldForceTabIndentation;
emptyLineFill = other.emptyLineFill;
backslashEndsPrevLine = other.backslashEndsPrevLine;
blockCommentNoIndent = other.blockCommentNoIndent;
blockCommentNoBeautify = other.blockCommentNoBeautify;
previousLineProbationTab = other.previousLineProbationTab;
minConditionalIndent = other.minConditionalIndent;
parenDepth = other.parenDepth;
indentLength = other.indentLength;
blockTabCount = other.blockTabCount;
leadingWhiteSpaces = other.leadingWhiteSpaces;
maxInStatementIndent = other.maxInStatementIndent;
templateDepth = other.templateDepth;
prevFinalLineSpaceTabCount = other.prevFinalLineSpaceTabCount;
prevFinalLineTabCount = other.prevFinalLineTabCount;
defineTabCount = other.defineTabCount;
quoteChar = other.quoteChar;
prevNonSpaceCh = other.prevNonSpaceCh;
currentNonSpaceCh = other.currentNonSpaceCh;
currentNonLegalCh = other.currentNonLegalCh;
prevNonLegalCh = other.prevNonLegalCh;
}
/**
* ASBeautifier's destructor
*/
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);
}
/**
* initialize the ASBeautifier.
*
* init() should be called every time a ABeautifier object is to start
* beautifying a NEW source file.
* init() recieves 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.
*
* @param iter a pointer to the DYNAMICALLY CREATED ASSourceIterator object.
*/
void ASBeautifier::init(ASSourceIterator *iter)
{
sourceIterator = iter;
init();
}
/**
* initialize the ASBeautifier.
*/
void ASBeautifier::init()
{
initStatic();
INIT_CONTAINER(waitingBeautifierStack, new vector<ASBeautifier*>);
INIT_CONTAINER(activeBeautifierStack, new vector<ASBeautifier*>);
INIT_CONTAINER(waitingBeautifierStackLengthStack, new vector<int>);
INIT_CONTAINER(activeBeautifierStackLengthStack, new vector<int>);
INIT_CONTAINER(headerStack, new vector<const string*>);
INIT_CONTAINER(tempStacks, new vector<vector<const string*>*>);
tempStacks->push_back(new vector<const string*>);
INIT_CONTAINER(blockParenDepthStack, new vector<int>);
INIT_CONTAINER(blockStatementStack, new vector<bool>);
INIT_CONTAINER(parenStatementStack, new vector<bool>);
INIT_CONTAINER(bracketBlockStateStack, new vector<bool>);
bracketBlockStateStack->push_back(true);
INIT_CONTAINER(inStatementIndentStack, new vector<int>);
INIT_CONTAINER(inStatementIndentStackSizeStack, new vector<int>);
inStatementIndentStackSizeStack->push_back(0);
INIT_CONTAINER(parenIndentStack, new vector<int>);
immediatelyPreviousAssignmentOp = NULL;
previousLastLineHeader = NULL;
currentHeader = NULL;
isInQuote = false;
isInComment = false;
isInStatement = false;
isInCase = false;
isInQuestion = false;
isInClassHeader = false;
isInClassHeaderTab = false;
isInHeader = false;
isInOperator = false;
isInTemplate = false;
isInConditional = false;
templateDepth = 0;
parenDepth = 0;
blockTabCount = 0;
leadingWhiteSpaces = 0;
prevNonSpaceCh = '{';
currentNonSpaceCh = '{';
prevNonLegalCh = '{';
currentNonLegalCh = '{';
quoteChar = ' ';
prevFinalLineSpaceTabCount = 0;
prevFinalLineTabCount = 0;
probationHeader = NULL;
backslashEndsPrevLine = 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
}
/**
* 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;
}
/**
* indent using one tab per indentation
*/
void ASBeautifier::setTabIndentation(int length, bool forceTabs)
{
indentString = "\t";
indentLength = length;
shouldForceTabIndentation = forceTabs;
if (!isMinimalConditinalIndentSet)
minConditionalIndent = indentLength * 2;
}
/**
* indent using a number of spaces per indentation.
*
* @param length number of spaces per indent.
*/
void ASBeautifier::setSpaceIndentation(int length)
{
indentString = string(length, ' ');
indentLength = length;
if (!isMinimalConditinalIndentSet)
minConditionalIndent = indentLength * 2;
}
/**
* set the maximum indentation between two lines in a multi-line statement.
*
* @param max maximum indentation length.
*/
void ASBeautifier::setMaxInStatementIndentLength(int max)
{
maxInStatementIndent = max;
}
/**
* set the minimum indentation between two lines in a multi-line condition.
*
* @param min minimal indentation length.
*/
void ASBeautifier::setMinConditionalIndentLength(int min)
{
minConditionalIndent = min;
isMinimalConditinalIndentSet = true;
}
/**
* set the state of the bracket indentation option. If true, brackets will
* be indented one additional indent.
*
* @param state state of option.
*/
void ASBeautifier::setBracketIndent(bool state)
{
bracketIndent = state;
}
/**
* set the state of the block indentation option. If true, entire blocks
* will be indented one additional indent, similar to the GNU indent style.
*
* @param state state of option.
*/
void ASBeautifier::setBlockIndent(bool state)
{
if (state)
setBracketIndent(false); // so that we don't have both bracket and block indent
blockIndent = state;
}
/**
* set the state of the class indentation option. If true, C++ class
* definitions will be indented one additional indent.
*
* @param state state of option.
*/
void ASBeautifier::setClassIndent(bool state)
{
classIndent = state;
}
/**
* set the state of the switch indentation option. If true, blocks of 'switch'
* statements will be indented one additional indent.
*
* @param state state of option.
*/
void ASBeautifier::setSwitchIndent(bool state)
{
switchIndent = state;
}
/**
* set the state of the case indentation option. If true, lines of 'case'
* statements will be indented one additional indent.
*
* @param state state of option.
*/
void ASBeautifier::setCaseIndent(bool state)
{
caseIndent = state;
}
/**
* set the state of the namespace indentation option.
* If true, blocks of 'namespace' statements will be indented one
* additional indent. Otherwise, NO indentation will be added.
*
* @param state state of option.
*/
void ASBeautifier::setNamespaceIndent(bool state)
{
namespaceIndent = state;
}
/**
* set the state of the label indentation option.
* If true, labels will be indented one indent LESS than the
* current indentation level.
* If false, labels will be flushed to the left with NO
* indent at all.
*
* @param state state of option.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -