/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 * reformatting tool for C, C++, C# and Java source files. * * * 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. * * 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 Artistic Style. If not, see . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "astyle.h" #include namespace astyle { const string ASResource::AS_IF = string("if"); const string ASResource::AS_ELSE = string("else"); const string ASResource::AS_FOR = string("for"); const string ASResource::AS_DO = string("do"); const string ASResource::AS_WHILE = string("while"); const string ASResource::AS_SWITCH = string("switch"); const string ASResource::AS_CASE = string("case"); const string ASResource::AS_DEFAULT = string("default"); const string ASResource::AS_CLASS = string("class"); const string ASResource::AS_STRUCT = string("struct"); const string ASResource::AS_UNION = string("union"); const string ASResource::AS_INTERFACE = string("interface"); const string ASResource::AS_NAMESPACE = string("namespace"); const string ASResource::AS_EXTERN = string("extern"); const string ASResource::AS_ENUM = string("enum"); const string ASResource::AS_PUBLIC = string("public"); const string ASResource::AS_PROTECTED = string("protected"); const string ASResource::AS_PRIVATE = string("private"); const string ASResource::AS_STATIC = string("static"); const string ASResource::AS_SYNCHRONIZED = string("synchronized"); const string ASResource::AS_OPERATOR = string("operator"); const string ASResource::AS_TEMPLATE = string("template"); const string ASResource::AS_TRY = string("try"); const string ASResource::AS_CATCH = string("catch"); const string ASResource::AS_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"); const string ASResource::AS_BAR_IF = string("#if"); const string ASResource::AS_BAR_EL = string("#el"); const string ASResource::AS_BAR_ENDIF = string("#endif"); const string ASResource::AS_OPEN_BRACKET = string("{"); const string ASResource::AS_CLOSE_BRACKET = string("}"); const string ASResource::AS_OPEN_LINE_COMMENT = string("//"); const string ASResource::AS_OPEN_COMMENT = string("/*"); const string ASResource::AS_CLOSE_COMMENT = string("*/"); const string ASResource::AS_ASSIGN = string("="); const string ASResource::AS_PLUS_ASSIGN = string("+="); const string ASResource::AS_MINUS_ASSIGN = string("-="); const string ASResource::AS_MULT_ASSIGN = string("*="); const string ASResource::AS_DIV_ASSIGN = string("/="); const string ASResource::AS_MOD_ASSIGN = string("%="); const string ASResource::AS_OR_ASSIGN = string("|="); const string ASResource::AS_AND_ASSIGN = string("&="); const string ASResource::AS_XOR_ASSIGN = string("^="); const string ASResource::AS_GR_GR_ASSIGN = string(">>="); const string ASResource::AS_LS_LS_ASSIGN = string("<<="); const string ASResource::AS_GR_GR_GR_ASSIGN = string(">>>="); const string ASResource::AS_LS_LS_LS_ASSIGN = string("<<<="); const string ASResource::AS_GCC_MIN_ASSIGN = string("?"); const string ASResource::AS_RETURN = string("return"); const string ASResource::AS_CIN = string("cin"); const string ASResource::AS_COUT = string("cout"); const string ASResource::AS_CERR = string("cerr"); const string ASResource::AS_EQUAL = string("=="); const string ASResource::AS_PLUS_PLUS = string("++"); const string ASResource::AS_MINUS_MINUS = string("--"); const string ASResource::AS_NOT_EQUAL = string("!="); const string ASResource::AS_GR_EQUAL = string(">="); const string ASResource::AS_GR_GR = string(">>"); const string ASResource::AS_GR_GR_GR = string(">>>"); const string ASResource::AS_LS_EQUAL = string("<="); const string ASResource::AS_LS_LS = string("<<"); const string ASResource::AS_LS_LS_LS = string("<<<"); const string ASResource::AS_QUESTION_QUESTION = string("??"); const string ASResource::AS_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("||"); const string ASResource::AS_COLON_COLON = string("::"); const string ASResource::AS_PAREN_PAREN = string("()"); const string ASResource::AS_BLPAREN_BLPAREN = string("[]"); const string ASResource::AS_PLUS = string("+"); const string ASResource::AS_MINUS = string("-"); const string ASResource::AS_MULT = string("*"); const string ASResource::AS_DIV = string("/"); const string ASResource::AS_MOD = string("%"); const string ASResource::AS_GR = string(">"); const string ASResource::AS_LS = string("<"); const string ASResource::AS_NOT = string("!"); const string ASResource::AS_BIT_OR = string("|"); const string ASResource::AS_BIT_AND = string("&"); const string ASResource::AS_BIT_NOT = string("~"); const string ASResource::AS_BIT_XOR = string("^"); const string ASResource::AS_QUESTION = string("?"); const string ASResource::AS_COLON = string(":"); const string ASResource::AS_COMMA = string(","); const string ASResource::AS_SEMICOLON = string(";"); const string ASResource::AS_FOREACH = string("foreach"); const string ASResource::AS_LOCK = string("lock"); const string ASResource::AS_UNSAFE = string("unsafe"); const string ASResource::AS_FIXED = string("fixed"); const string ASResource::AS_GET = string("get"); const string ASResource::AS_SET = string("set"); const string ASResource::AS_ADD = string("add"); const string ASResource::AS_REMOVE = string("remove"); const string ASResource::AS_DELEGATE = string("delegate"); const string ASResource::AS_UNCHECKED = string("unchecked"); const string ASResource::AS_CONST_CAST = string("const_cast"); const string ASResource::AS_DYNAMIC_CAST = string("dynamic_cast"); const string ASResource::AS_REINTERPRET_CAST = string("reinterpret_cast"); const string ASResource::AS_STATIC_CAST = string("static_cast"); /** * 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) { assignmentOperators->push_back(&AS_ASSIGN); assignmentOperators->push_back(&AS_PLUS_ASSIGN); assignmentOperators->push_back(&AS_MINUS_ASSIGN); assignmentOperators->push_back(&AS_MULT_ASSIGN); assignmentOperators->push_back(&AS_DIV_ASSIGN); assignmentOperators->push_back(&AS_MOD_ASSIGN); assignmentOperators->push_back(&AS_OR_ASSIGN); assignmentOperators->push_back(&AS_AND_ASSIGN); assignmentOperators->push_back(&AS_XOR_ASSIGN); // Java assignmentOperators->push_back(&AS_GR_GR_GR_ASSIGN); assignmentOperators->push_back(&AS_GR_GR_ASSIGN); assignmentOperators->push_back(&AS_LS_LS_ASSIGN); // Unknown assignmentOperators->push_back(&AS_LS_LS_LS_ASSIGN); sort(assignmentOperators->begin(), assignmentOperators->end(), sortOnLength); } /** * Build the vector of C++ cast operators. * Used by ONLY ASFormatter.cpp * * @param castOperators a reference to the vector to be built. */ void ASResource::buildCastOperators(vector* castOperators) { castOperators->push_back(&AS_CONST_CAST); castOperators->push_back(&AS_DYNAMIC_CAST); castOperators->push_back(&AS_REINTERPRET_CAST); castOperators->push_back(&AS_STATIC_CAST); } /** * Build the vector of header words. * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp * * @param headers a reference to the vector to be built. */ void ASResource::buildHeaders(vector* headers, int fileType, bool beautifier) { headers->push_back(&AS_IF); headers->push_back(&AS_ELSE); headers->push_back(&AS_FOR); headers->push_back(&AS_WHILE); headers->push_back(&AS_DO); headers->push_back(&AS_SWITCH); headers->push_back(&AS_TRY); headers->push_back(&AS_CATCH); if (fileType == JAVA_TYPE) { headers->push_back(&AS_FINALLY); headers->push_back(&AS_SYNCHRONIZED); } if (fileType == SHARP_TYPE) { headers->push_back(&AS_FINALLY); headers->push_back(&AS_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 (beautifier) { 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 nonAssignmentOperators a reference to the vector to be built. */ void ASResource::buildNonAssignmentOperators(vector* nonAssignmentOperators) { nonAssignmentOperators->push_back(&AS_EQUAL); nonAssignmentOperators->push_back(&AS_PLUS_PLUS); nonAssignmentOperators->push_back(&AS_MINUS_MINUS); nonAssignmentOperators->push_back(&AS_NOT_EQUAL); nonAssignmentOperators->push_back(&AS_GR_EQUAL); nonAssignmentOperators->push_back(&AS_GR_GR_GR); nonAssignmentOperators->push_back(&AS_GR_GR); nonAssignmentOperators->push_back(&AS_LS_EQUAL); nonAssignmentOperators->push_back(&AS_LS_LS_LS); nonAssignmentOperators->push_back(&AS_LS_LS); nonAssignmentOperators->push_back(&AS_ARROW); nonAssignmentOperators->push_back(&AS_AND); nonAssignmentOperators->push_back(&AS_OR); 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) { nonParenHeaders->push_back(&AS_ELSE); nonParenHeaders->push_back(&AS_DO); nonParenHeaders->push_back(&AS_TRY); if (fileType == JAVA_TYPE) { nonParenHeaders->push_back(&AS_FINALLY); } if (fileType == SHARP_TYPE) { 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 (beautifier) { 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) { 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, int fileType) { preBlockStatements->push_back(&AS_CLASS); if (fileType == C_TYPE) { preBlockStatements->push_back(&AS_STRUCT); preBlockStatements->push_back(&AS_UNION); preBlockStatements->push_back(&AS_NAMESPACE); } if (fileType == JAVA_TYPE) { preBlockStatements->push_back(&AS_INTERFACE); preBlockStatements->push_back(&AS_THROWS); } if (fileType == SHARP_TYPE) { preBlockStatements->push_back(&AS_INTERFACE); preBlockStatements->push_back(&AS_NAMESPACE); preBlockStatements->push_back(&AS_WHERE); preBlockStatements->push_back(&AS_STRUCT); } sort(preBlockStatements->begin(), preBlockStatements->end(), sortOnName); } /** * Build the vector of pre-command headers. * Used by ONLY ASFormatter.cpp * * @param preCommandHeaders a reference to the vector to be built. */ void ASResource::buildPreCommandHeaders(vector* preCommandHeaders, int fileType) { 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, int fileType) { preDefinitionHeaders->push_back(&AS_CLASS); if (fileType == C_TYPE) { preDefinitionHeaders->push_back(&AS_STRUCT); preDefinitionHeaders->push_back(&AS_UNION); preDefinitionHeaders->push_back(&AS_NAMESPACE); } if (fileType == JAVA_TYPE) { preDefinitionHeaders->push_back(&AS_INTERFACE); } if (fileType == SHARP_TYPE) { preDefinitionHeaders->push_back(&AS_STRUCT); preDefinitionHeaders->push_back(&AS_INTERFACE); preDefinitionHeaders->push_back(&AS_NAMESPACE); } sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ASBase 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