Warning, file /kdevelop/kdevelop/plugins/astyle/3rdparty/libastyle/ASResource.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // ASResource.cpp
0002 // Copyright (c) 2018 by Jim Pattee <jimp03@email.com>.
0003 // This code is licensed under the MIT License.
0004 // License.md describes the conditions under which this software may be distributed.
0005 
0006 //-----------------------------------------------------------------------------
0007 // headers
0008 //-----------------------------------------------------------------------------
0009 
0010 #include "astyle.h"
0011 #include <algorithm>
0012 
0013 //-----------------------------------------------------------------------------
0014 // astyle namespace
0015 //-----------------------------------------------------------------------------
0016 
0017 namespace astyle {
0018 //
0019 const string ASResource::_AS_EXCEPT = string("__except");
0020 const string ASResource::_AS_FINALLY = string("__finally");
0021 const string ASResource::_AS_TRY = string("__try");
0022 const string ASResource::AS_ADD = string("add");
0023 const string ASResource::AS_AUTO = string("auto");
0024 const string ASResource::AS_AUTORELEASEPOOL = string("autoreleasepool");
0025 const string ASResource::AS_CASE = string("case");
0026 const string ASResource::AS_CATCH = string("catch");
0027 const string ASResource::AS_CLASS = string("class");
0028 const string ASResource::AS_CONST = string("const");
0029 const string ASResource::AS_CONST_CAST = string("const_cast");
0030 const string ASResource::AS_DEFAULT = string("default");
0031 const string ASResource::AS_DELEGATE = string("delegate");
0032 const string ASResource::AS_DELETE = string("delete");
0033 const string ASResource::AS_DO = string("do");
0034 const string ASResource::AS_DYNAMIC_CAST = string("dynamic_cast");
0035 const string ASResource::AS_ELSE = string("else");
0036 const string ASResource::AS_END = string("end");
0037 const string ASResource::AS_ENUM = string("enum");
0038 const string ASResource::AS_EXTERN = string("extern");
0039 const string ASResource::AS_FINAL = string("final");
0040 const string ASResource::AS_FINALLY = string("finally");
0041 const string ASResource::AS_FIXED = string("fixed");
0042 const string ASResource::AS_FOR = string("for");
0043 const string ASResource::AS_FOREACH = string("foreach");
0044 const string ASResource::AS_FOREVER = string("forever");
0045 const string ASResource::AS_GET = string("get");
0046 const string ASResource::AS_IF = string("if");
0047 const string ASResource::AS_INTERFACE = string("interface");
0048 const string ASResource::AS_INTERRUPT = string("interrupt");
0049 const string ASResource::AS_LET = string("let");
0050 const string ASResource::AS_LOCK = string("lock");
0051 const string ASResource::AS_MODULE = string("module");  // CORBA IDL module definition
0052 const string ASResource::AS_NAMESPACE = string("namespace");
0053 const string ASResource::AS_NEW = string("new");
0054 const string ASResource::AS_NOEXCEPT = string("noexcept");
0055 const string ASResource::AS_NS_DURING = string("NS_DURING");
0056 const string ASResource::AS_NS_HANDLER = string("NS_HANDLER");
0057 const string ASResource::AS_OPERATOR = string("operator");
0058 const string ASResource::AS_OVERRIDE = string("override");
0059 const string ASResource::AS_PRIVATE = string("private");
0060 const string ASResource::AS_PROTECTED = string("protected");
0061 const string ASResource::AS_PUBLIC = string("public");
0062 const string ASResource::AS_QFOREACH = string("Q_FOREACH");
0063 const string ASResource::AS_QFOREVER = string("Q_FOREVER");
0064 const string ASResource::AS_REINTERPRET_CAST = string("reinterpret_cast");
0065 const string ASResource::AS_REMOVE = string("remove");
0066 const string ASResource::AS_SEALED = string("sealed");
0067 const string ASResource::AS_SELECTOR = string("selector");
0068 const string ASResource::AS_SET = string("set");
0069 const string ASResource::AS_STATIC = string("static");
0070 const string ASResource::AS_STATIC_CAST = string("static_cast");
0071 const string ASResource::AS_STRUCT = string("struct");
0072 const string ASResource::AS_SWITCH = string("switch");
0073 const string ASResource::AS_SYNCHRONIZED = string("synchronized");
0074 const string ASResource::AS_TEMPLATE = string("template");
0075 const string ASResource::AS_THROW = string("throw");
0076 const string ASResource::AS_THROWS = string("throws");
0077 const string ASResource::AS_TRY = string("try");
0078 const string ASResource::AS_UNCHECKED = string("unchecked");
0079 const string ASResource::AS_UNION = string("union");
0080 const string ASResource::AS_UNSAFE = string("unsafe");
0081 const string ASResource::AS_USING = string("using");
0082 const string ASResource::AS_VOLATILE = string("volatile");
0083 const string ASResource::AS_WHERE = string("where");
0084 const string ASResource::AS_WHILE = string("while");
0085 
0086 const string ASResource::AS_ASM = string("asm");
0087 const string ASResource::AS__ASM__ = string("__asm__");
0088 const string ASResource::AS_MS_ASM = string("_asm");
0089 const string ASResource::AS_MS__ASM = string("__asm");
0090 
0091 const string ASResource::AS_BAR_DEFINE = string("#define");
0092 const string ASResource::AS_BAR_INCLUDE = string("#include");
0093 const string ASResource::AS_BAR_IF = string("#if");
0094 const string ASResource::AS_BAR_EL = string("#el");
0095 const string ASResource::AS_BAR_ENDIF = string("#endif");
0096 
0097 const string ASResource::AS_OPEN_BRACE = string("{");
0098 const string ASResource::AS_CLOSE_BRACE = string("}");
0099 const string ASResource::AS_OPEN_LINE_COMMENT = string("//");
0100 const string ASResource::AS_OPEN_COMMENT = string("/*");
0101 const string ASResource::AS_CLOSE_COMMENT = string("*/");
0102 
0103 const string ASResource::AS_ASSIGN = string("=");
0104 const string ASResource::AS_PLUS_ASSIGN = string("+=");
0105 const string ASResource::AS_MINUS_ASSIGN = string("-=");
0106 const string ASResource::AS_MULT_ASSIGN = string("*=");
0107 const string ASResource::AS_DIV_ASSIGN = string("/=");
0108 const string ASResource::AS_MOD_ASSIGN = string("%=");
0109 const string ASResource::AS_OR_ASSIGN = string("|=");
0110 const string ASResource::AS_AND_ASSIGN = string("&=");
0111 const string ASResource::AS_XOR_ASSIGN = string("^=");
0112 const string ASResource::AS_GR_GR_ASSIGN = string(">>=");
0113 const string ASResource::AS_LS_LS_ASSIGN = string("<<=");
0114 const string ASResource::AS_GR_GR_GR_ASSIGN = string(">>>=");
0115 const string ASResource::AS_LS_LS_LS_ASSIGN = string("<<<=");
0116 const string ASResource::AS_GCC_MIN_ASSIGN = string("<?");
0117 const string ASResource::AS_GCC_MAX_ASSIGN = string(">?");
0118 
0119 const string ASResource::AS_RETURN = string("return");
0120 const string ASResource::AS_CIN = string("cin");
0121 const string ASResource::AS_COUT = string("cout");
0122 const string ASResource::AS_CERR = string("cerr");
0123 
0124 const string ASResource::AS_EQUAL = string("==");
0125 const string ASResource::AS_PLUS_PLUS = string("++");
0126 const string ASResource::AS_MINUS_MINUS = string("--");
0127 const string ASResource::AS_NOT_EQUAL = string("!=");
0128 const string ASResource::AS_GR_EQUAL = string(">=");
0129 const string ASResource::AS_GR_GR = string(">>");
0130 const string ASResource::AS_GR_GR_GR = string(">>>");
0131 const string ASResource::AS_LS_EQUAL = string("<=");
0132 const string ASResource::AS_LS_LS = string("<<");
0133 const string ASResource::AS_LS_LS_LS = string("<<<");
0134 const string ASResource::AS_QUESTION_QUESTION = string("??");
0135 const string ASResource::AS_LAMBDA = string("=>");            // C# lambda expression arrow
0136 const string ASResource::AS_ARROW = string("->");
0137 const string ASResource::AS_AND = string("&&");
0138 const string ASResource::AS_OR = string("||");
0139 const string ASResource::AS_SCOPE_RESOLUTION = string("::");
0140 
0141 const string ASResource::AS_PLUS = string("+");
0142 const string ASResource::AS_MINUS = string("-");
0143 const string ASResource::AS_MULT = string("*");
0144 const string ASResource::AS_DIV = string("/");
0145 const string ASResource::AS_MOD = string("%");
0146 const string ASResource::AS_GR = string(">");
0147 const string ASResource::AS_LS = string("<");
0148 const string ASResource::AS_NOT = string("!");
0149 const string ASResource::AS_BIT_OR = string("|");
0150 const string ASResource::AS_BIT_AND = string("&");
0151 const string ASResource::AS_BIT_NOT = string("~");
0152 const string ASResource::AS_BIT_XOR = string("^");
0153 const string ASResource::AS_QUESTION = string("?");
0154 const string ASResource::AS_COLON = string(":");
0155 const string ASResource::AS_COMMA = string(",");
0156 const string ASResource::AS_SEMICOLON = string(";");
0157 
0158 /**
0159  * Sort comparison function.
0160  * Compares the length of the value of pointers in the vectors.
0161  * The LONGEST strings will be first in the vector.
0162  *
0163  * @param a and b, the string pointers to be compared.
0164  */
0165 bool sortOnLength(const string* a, const string* b)
0166 {
0167     return (*a).length() > (*b).length();
0168 }
0169 
0170 /**
0171  * Sort comparison function.
0172  * Compares the value of pointers in the vectors.
0173  *
0174  * @param a and b, the string pointers to be compared.
0175  */
0176 bool sortOnName(const string* a, const string* b)
0177 {
0178     return *a < *b;
0179 }
0180 
0181 /**
0182  * Build the vector of assignment operators.
0183  * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp
0184  *
0185  * @param assignmentOperators   a reference to the vector to be built.
0186  */
0187 void ASResource::buildAssignmentOperators(vector<const string*>* assignmentOperators)
0188 {
0189     const size_t elements = 15;
0190     static bool reserved = false;
0191     if (!reserved)
0192     {
0193         assignmentOperators->reserve(elements);
0194         reserved = true;
0195     }
0196 
0197     assignmentOperators->emplace_back(&AS_ASSIGN);
0198     assignmentOperators->emplace_back(&AS_PLUS_ASSIGN);
0199     assignmentOperators->emplace_back(&AS_MINUS_ASSIGN);
0200     assignmentOperators->emplace_back(&AS_MULT_ASSIGN);
0201     assignmentOperators->emplace_back(&AS_DIV_ASSIGN);
0202     assignmentOperators->emplace_back(&AS_MOD_ASSIGN);
0203     assignmentOperators->emplace_back(&AS_OR_ASSIGN);
0204     assignmentOperators->emplace_back(&AS_AND_ASSIGN);
0205     assignmentOperators->emplace_back(&AS_XOR_ASSIGN);
0206 
0207     // Java
0208     assignmentOperators->emplace_back(&AS_GR_GR_GR_ASSIGN);
0209     assignmentOperators->emplace_back(&AS_GR_GR_ASSIGN);
0210     assignmentOperators->emplace_back(&AS_LS_LS_ASSIGN);
0211 
0212     // Unknown
0213     assignmentOperators->emplace_back(&AS_LS_LS_LS_ASSIGN);
0214 
0215     assert(assignmentOperators->size() < elements);
0216     sort(assignmentOperators->begin(), assignmentOperators->end(), sortOnLength);
0217 }
0218 
0219 /**
0220  * Build the vector of C++ cast operators.
0221  * Used by ONLY ASFormatter.cpp
0222  *
0223  * @param castOperators     a reference to the vector to be built.
0224  */
0225 void ASResource::buildCastOperators(vector<const string*>* castOperators)
0226 {
0227     const size_t elements = 5;
0228     static bool reserved = false;
0229     if (!reserved)
0230     {
0231         castOperators->reserve(elements);
0232         reserved = true;
0233     }
0234 
0235     castOperators->emplace_back(&AS_CONST_CAST);
0236     castOperators->emplace_back(&AS_DYNAMIC_CAST);
0237     castOperators->emplace_back(&AS_REINTERPRET_CAST);
0238     castOperators->emplace_back(&AS_STATIC_CAST);
0239 
0240     assert(castOperators->size() < elements);
0241     sort(castOperators->begin(), castOperators->end(), sortOnName);
0242 }
0243 
0244 /**
0245  * Build the vector of header words.
0246  * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp
0247  *
0248  * @param headers       a reference to the vector to be built.
0249  */
0250 void ASResource::buildHeaders(vector<const string*>* headers, int fileType, bool beautifier)
0251 {
0252     const size_t elements = 25;
0253     static bool reserved = false;
0254     if (!reserved)
0255     {
0256         headers->reserve(elements);
0257         reserved = true;
0258     }
0259 
0260     headers->emplace_back(&AS_IF);
0261     headers->emplace_back(&AS_ELSE);
0262     headers->emplace_back(&AS_FOR);
0263     headers->emplace_back(&AS_WHILE);
0264     headers->emplace_back(&AS_DO);
0265     headers->emplace_back(&AS_SWITCH);
0266     headers->emplace_back(&AS_CASE);
0267     headers->emplace_back(&AS_DEFAULT);
0268     headers->emplace_back(&AS_TRY);
0269     headers->emplace_back(&AS_CATCH);
0270     headers->emplace_back(&AS_QFOREACH);        // QT
0271     headers->emplace_back(&AS_QFOREVER);        // QT
0272     headers->emplace_back(&AS_FOREACH);     // QT & C#
0273     headers->emplace_back(&AS_FOREVER);     // Qt & Boost
0274 
0275     if (fileType == C_TYPE)
0276     {
0277         headers->emplace_back(&_AS_TRY);        // __try
0278         headers->emplace_back(&_AS_FINALLY);    // __finally
0279         headers->emplace_back(&_AS_EXCEPT); // __except
0280     }
0281     if (fileType == JAVA_TYPE)
0282     {
0283         headers->emplace_back(&AS_FINALLY);
0284         headers->emplace_back(&AS_SYNCHRONIZED);
0285     }
0286 
0287     if (fileType == SHARP_TYPE)
0288     {
0289         headers->emplace_back(&AS_FINALLY);
0290         headers->emplace_back(&AS_LOCK);
0291         headers->emplace_back(&AS_FIXED);
0292         headers->emplace_back(&AS_GET);
0293         headers->emplace_back(&AS_SET);
0294         headers->emplace_back(&AS_ADD);
0295         headers->emplace_back(&AS_REMOVE);
0296         headers->emplace_back(&AS_USING);
0297     }
0298 
0299     if (beautifier)
0300     {
0301         if (fileType == C_TYPE)
0302         {
0303             headers->emplace_back(&AS_TEMPLATE);
0304         }
0305 
0306         if (fileType == JAVA_TYPE)
0307         {
0308             headers->emplace_back(&AS_STATIC);         // for static constructor
0309         }
0310     }
0311 
0312     assert(headers->size() < elements);
0313     sort(headers->begin(), headers->end(), sortOnName);
0314 }
0315 
0316 /**
0317  * Build the vector of indentable headers.
0318  * Used by ONLY ASBeautifier.cpp
0319  *
0320  * @param indentableHeaders     a reference to the vector to be built.
0321  */
0322 void ASResource::buildIndentableHeaders(vector<const string*>* indentableHeaders)
0323 {
0324     indentableHeaders->emplace_back(&AS_RETURN);
0325 
0326 //  sort(indentableHeaders->begin(), indentableHeaders->end(), sortOnName);
0327 }
0328 
0329 /**
0330 * Build the vector of indentable macros pairs.
0331 * Initialized by ASFormatter, used by ONLY ASEnhancer.cpp
0332 *
0333 * @param indentableMacros       a reference to the vector to be built.
0334 */
0335 void ASResource::buildIndentableMacros(vector<const pair<const string, const string>* >* indentableMacros)
0336 {
0337     const size_t elements = 10;
0338     static bool reserved = false;
0339     if (!reserved)
0340     {
0341         indentableMacros->reserve(elements);
0342         reserved = true;
0343     }
0344 
0345     // the pairs must be retained in memory because of pair pointers
0346     typedef pair<const string, const string> macro_pair;
0347     static const macro_pair macros[] =
0348     {
0349         // wxWidgets
0350         macro_pair("BEGIN_EVENT_TABLE",   "END_EVENT_TABLE"),
0351         macro_pair("wxBEGIN_EVENT_TABLE", "wxEND_EVENT_TABLE"),
0352         // MFC
0353         macro_pair("BEGIN_DISPATCH_MAP",  "END_DISPATCH_MAP"),
0354         macro_pair("BEGIN_EVENT_MAP",     "END_EVENT_MAP"),
0355         macro_pair("BEGIN_MESSAGE_MAP",   "END_MESSAGE_MAP"),
0356         macro_pair("BEGIN_PROPPAGEIDS",   "END_PROPPAGEIDS"),
0357     };
0358 
0359     size_t entries = sizeof(macros) / sizeof(macros[0]);
0360     for (size_t i = 0; i < entries; i++)
0361         indentableMacros->emplace_back(&macros[i]);
0362 
0363     assert(indentableMacros->size() < elements);
0364 }
0365 
0366 /**
0367  * Build the vector of non-assignment operators.
0368  * Used by ONLY ASBeautifier.cpp
0369  *
0370  * @param nonAssignmentOperators       a reference to the vector to be built.
0371  */
0372 void ASResource::buildNonAssignmentOperators(vector<const string*>* nonAssignmentOperators)
0373 {
0374     const size_t elements = 15;
0375     static bool reserved = false;
0376     if (!reserved)
0377     {
0378         nonAssignmentOperators->reserve(elements);
0379         reserved = true;
0380     }
0381 
0382     nonAssignmentOperators->emplace_back(&AS_EQUAL);
0383     nonAssignmentOperators->emplace_back(&AS_PLUS_PLUS);
0384     nonAssignmentOperators->emplace_back(&AS_MINUS_MINUS);
0385     nonAssignmentOperators->emplace_back(&AS_NOT_EQUAL);
0386     nonAssignmentOperators->emplace_back(&AS_GR_EQUAL);
0387     nonAssignmentOperators->emplace_back(&AS_GR_GR_GR);
0388     nonAssignmentOperators->emplace_back(&AS_GR_GR);
0389     nonAssignmentOperators->emplace_back(&AS_LS_EQUAL);
0390     nonAssignmentOperators->emplace_back(&AS_LS_LS_LS);
0391     nonAssignmentOperators->emplace_back(&AS_LS_LS);
0392     nonAssignmentOperators->emplace_back(&AS_ARROW);
0393     nonAssignmentOperators->emplace_back(&AS_AND);
0394     nonAssignmentOperators->emplace_back(&AS_OR);
0395     nonAssignmentOperators->emplace_back(&AS_LAMBDA);
0396 
0397     assert(nonAssignmentOperators->size() < elements);
0398     sort(nonAssignmentOperators->begin(), nonAssignmentOperators->end(), sortOnLength);
0399 }
0400 
0401 /**
0402  * Build the vector of header non-paren headers.
0403  * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp.
0404  * NOTE: Non-paren headers should also be included in the headers vector.
0405  *
0406  * @param nonParenHeaders       a reference to the vector to be built.
0407  */
0408 void ASResource::buildNonParenHeaders(vector<const string*>* nonParenHeaders, int fileType, bool beautifier)
0409 {
0410     const size_t elements = 20;
0411     static bool reserved = false;
0412     if (!reserved)
0413     {
0414         nonParenHeaders->reserve(elements);
0415         reserved = true;
0416     }
0417 
0418     nonParenHeaders->emplace_back(&AS_ELSE);
0419     nonParenHeaders->emplace_back(&AS_DO);
0420     nonParenHeaders->emplace_back(&AS_TRY);
0421     nonParenHeaders->emplace_back(&AS_CATCH);       // can be paren or non-paren
0422     nonParenHeaders->emplace_back(&AS_CASE);        // can be paren or non-paren
0423     nonParenHeaders->emplace_back(&AS_DEFAULT);
0424     nonParenHeaders->emplace_back(&AS_QFOREVER);    // QT
0425     nonParenHeaders->emplace_back(&AS_FOREVER); // Boost
0426 
0427     if (fileType == C_TYPE)
0428     {
0429         nonParenHeaders->emplace_back(&_AS_TRY);        // __try
0430         nonParenHeaders->emplace_back(&_AS_FINALLY);    // __finally
0431     }
0432     if (fileType == JAVA_TYPE)
0433     {
0434         nonParenHeaders->emplace_back(&AS_FINALLY);
0435     }
0436 
0437     if (fileType == SHARP_TYPE)
0438     {
0439         nonParenHeaders->emplace_back(&AS_FINALLY);
0440         nonParenHeaders->emplace_back(&AS_GET);
0441         nonParenHeaders->emplace_back(&AS_SET);
0442         nonParenHeaders->emplace_back(&AS_ADD);
0443         nonParenHeaders->emplace_back(&AS_REMOVE);
0444     }
0445 
0446     if (beautifier)
0447     {
0448         if (fileType == C_TYPE)
0449         {
0450             nonParenHeaders->emplace_back(&AS_TEMPLATE);
0451         }
0452         if (fileType == JAVA_TYPE)
0453         {
0454             nonParenHeaders->emplace_back(&AS_STATIC);
0455         }
0456     }
0457 
0458     assert(nonParenHeaders->size() < elements);
0459     sort(nonParenHeaders->begin(), nonParenHeaders->end(), sortOnName);
0460 }
0461 
0462 /**
0463  * Build the vector of operators.
0464  * Used by ONLY ASFormatter.cpp
0465  *
0466  * @param operators             a reference to the vector to be built.
0467  */
0468 void ASResource::buildOperators(vector<const string*>* operators, int fileType)
0469 {
0470     const size_t elements = 50;
0471     static bool reserved = false;
0472     if (!reserved)
0473     {
0474         operators->reserve(elements);
0475         reserved = true;
0476     }
0477 
0478 
0479     operators->emplace_back(&AS_PLUS_ASSIGN);
0480     operators->emplace_back(&AS_MINUS_ASSIGN);
0481     operators->emplace_back(&AS_MULT_ASSIGN);
0482     operators->emplace_back(&AS_DIV_ASSIGN);
0483     operators->emplace_back(&AS_MOD_ASSIGN);
0484     operators->emplace_back(&AS_OR_ASSIGN);
0485     operators->emplace_back(&AS_AND_ASSIGN);
0486     operators->emplace_back(&AS_XOR_ASSIGN);
0487     operators->emplace_back(&AS_EQUAL);
0488     operators->emplace_back(&AS_PLUS_PLUS);
0489     operators->emplace_back(&AS_MINUS_MINUS);
0490     operators->emplace_back(&AS_NOT_EQUAL);
0491     operators->emplace_back(&AS_GR_EQUAL);
0492     operators->emplace_back(&AS_GR_GR_GR_ASSIGN);
0493     operators->emplace_back(&AS_GR_GR_ASSIGN);
0494     operators->emplace_back(&AS_GR_GR_GR);
0495     operators->emplace_back(&AS_GR_GR);
0496     operators->emplace_back(&AS_LS_EQUAL);
0497     operators->emplace_back(&AS_LS_LS_LS_ASSIGN);
0498     operators->emplace_back(&AS_LS_LS_ASSIGN);
0499     operators->emplace_back(&AS_LS_LS_LS);
0500     operators->emplace_back(&AS_LS_LS);
0501     operators->emplace_back(&AS_QUESTION_QUESTION);
0502     operators->emplace_back(&AS_LAMBDA);
0503     operators->emplace_back(&AS_ARROW);
0504     operators->emplace_back(&AS_AND);
0505     operators->emplace_back(&AS_OR);
0506     operators->emplace_back(&AS_SCOPE_RESOLUTION);
0507     operators->emplace_back(&AS_PLUS);
0508     operators->emplace_back(&AS_MINUS);
0509     operators->emplace_back(&AS_MULT);
0510     operators->emplace_back(&AS_DIV);
0511     operators->emplace_back(&AS_MOD);
0512     operators->emplace_back(&AS_QUESTION);
0513     operators->emplace_back(&AS_COLON);
0514     operators->emplace_back(&AS_ASSIGN);
0515     operators->emplace_back(&AS_LS);
0516     operators->emplace_back(&AS_GR);
0517     operators->emplace_back(&AS_NOT);
0518     operators->emplace_back(&AS_BIT_OR);
0519     operators->emplace_back(&AS_BIT_AND);
0520     operators->emplace_back(&AS_BIT_NOT);
0521     operators->emplace_back(&AS_BIT_XOR);
0522     if (fileType == C_TYPE)
0523     {
0524         operators->emplace_back(&AS_GCC_MIN_ASSIGN);
0525         operators->emplace_back(&AS_GCC_MAX_ASSIGN);
0526     }
0527 
0528     assert(operators->size() < elements);
0529     sort(operators->begin(), operators->end(), sortOnLength);
0530 }
0531 
0532 /**
0533  * Build the vector of pre-block statements.
0534  * Used by ONLY ASBeautifier.cpp
0535  * NOTE: Cannot be both a header and a preBlockStatement.
0536  *
0537  * @param preBlockStatements        a reference to the vector to be built.
0538  */
0539 void ASResource::buildPreBlockStatements(vector<const string*>* preBlockStatements, int fileType)
0540 {
0541     const size_t elements = 10;
0542     static bool reserved = false;
0543     if (!reserved)
0544     {
0545         preBlockStatements->reserve(elements);
0546         reserved = true;
0547     }
0548 
0549     preBlockStatements->emplace_back(&AS_CLASS);
0550     if (fileType == C_TYPE)
0551     {
0552         preBlockStatements->emplace_back(&AS_STRUCT);
0553         preBlockStatements->emplace_back(&AS_UNION);
0554         preBlockStatements->emplace_back(&AS_NAMESPACE);
0555         preBlockStatements->emplace_back(&AS_MODULE);     // for CORBA IDL
0556         preBlockStatements->emplace_back(&AS_INTERFACE);  // for CORBA IDL
0557     }
0558     if (fileType == JAVA_TYPE)
0559     {
0560         preBlockStatements->emplace_back(&AS_INTERFACE);
0561         preBlockStatements->emplace_back(&AS_THROWS);
0562     }
0563     if (fileType == SHARP_TYPE)
0564     {
0565         preBlockStatements->emplace_back(&AS_INTERFACE);
0566         preBlockStatements->emplace_back(&AS_NAMESPACE);
0567         preBlockStatements->emplace_back(&AS_WHERE);
0568         preBlockStatements->emplace_back(&AS_STRUCT);
0569     }
0570 
0571     assert(preBlockStatements->size() < elements);
0572     sort(preBlockStatements->begin(), preBlockStatements->end(), sortOnName);
0573 }
0574 
0575 /**
0576  * Build the vector of pre-command headers.
0577  * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp.
0578  * NOTE: Cannot be both a header and a preCommandHeader.
0579  *
0580  * A preCommandHeader is in a function definition between
0581  * the closing paren and the opening brace.
0582  * e.g. in "void foo() const {}", "const" is a preCommandHeader.
0583  */
0584 void ASResource::buildPreCommandHeaders(vector<const string*>* preCommandHeaders, int fileType)
0585 {
0586     const size_t elements = 10;
0587     static bool reserved = false;
0588     if (!reserved)
0589     {
0590         preCommandHeaders->reserve(elements);
0591         reserved = true;
0592     }
0593 
0594     if (fileType == C_TYPE)
0595     {
0596         preCommandHeaders->emplace_back(&AS_CONST);
0597         preCommandHeaders->emplace_back(&AS_FINAL);
0598         preCommandHeaders->emplace_back(&AS_INTERRUPT);
0599         preCommandHeaders->emplace_back(&AS_NOEXCEPT);
0600         preCommandHeaders->emplace_back(&AS_OVERRIDE);
0601         preCommandHeaders->emplace_back(&AS_VOLATILE);
0602         preCommandHeaders->emplace_back(&AS_SEALED);            // Visual C only
0603         preCommandHeaders->emplace_back(&AS_AUTORELEASEPOOL);   // Obj-C only
0604     }
0605 
0606     if (fileType == JAVA_TYPE)
0607     {
0608         preCommandHeaders->emplace_back(&AS_THROWS);
0609     }
0610 
0611     if (fileType == SHARP_TYPE)
0612     {
0613         preCommandHeaders->emplace_back(&AS_WHERE);
0614     }
0615 
0616     assert(preCommandHeaders->size() < elements);
0617     sort(preCommandHeaders->begin(), preCommandHeaders->end(), sortOnName);
0618 }
0619 
0620 /**
0621  * Build the vector of pre-definition headers.
0622  * Used by ONLY ASFormatter.cpp
0623  * NOTE: Do NOT add 'enum' here. It is an array type brace.
0624  * NOTE: Do NOT add 'extern' here. Do not want an extra indent.
0625  *
0626  * @param preDefinitionHeaders      a reference to the vector to be built.
0627  */
0628 void ASResource::buildPreDefinitionHeaders(vector<const string*>* preDefinitionHeaders, int fileType)
0629 {
0630     const size_t elements = 10;
0631     static bool reserved = false;
0632     if (!reserved)
0633     {
0634         preDefinitionHeaders->reserve(elements);
0635         reserved = true;
0636     }
0637 
0638     preDefinitionHeaders->emplace_back(&AS_CLASS);
0639     if (fileType == C_TYPE)
0640     {
0641         preDefinitionHeaders->emplace_back(&AS_STRUCT);
0642         preDefinitionHeaders->emplace_back(&AS_UNION);
0643         preDefinitionHeaders->emplace_back(&AS_NAMESPACE);
0644         preDefinitionHeaders->emplace_back(&AS_MODULE);     // for CORBA IDL
0645         preDefinitionHeaders->emplace_back(&AS_INTERFACE);  // for CORBA IDL
0646     }
0647     if (fileType == JAVA_TYPE)
0648     {
0649         preDefinitionHeaders->emplace_back(&AS_INTERFACE);
0650     }
0651     if (fileType == SHARP_TYPE)
0652     {
0653         preDefinitionHeaders->emplace_back(&AS_STRUCT);
0654         preDefinitionHeaders->emplace_back(&AS_INTERFACE);
0655         preDefinitionHeaders->emplace_back(&AS_NAMESPACE);
0656     }
0657 
0658     assert(preDefinitionHeaders->size() < elements);
0659     sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName);
0660 }
0661 
0662 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
0663  *                             ASBase Functions
0664  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0665 
0666 // check if a specific line position contains a header.
0667 const string* ASBase::findHeader(const string& line, int i,
0668                                  const vector<const string*>* possibleHeaders) const
0669 {
0670     assert(isCharPotentialHeader(line, i));
0671     // check the word
0672     size_t maxHeaders = possibleHeaders->size();
0673     for (size_t p = 0; p < maxHeaders; p++)
0674     {
0675         const string* header = (*possibleHeaders)[p];
0676         const size_t wordEnd = i + header->length();
0677         if (wordEnd > line.length())
0678             continue;
0679         int result = (line.compare(i, header->length(), *header));
0680         if (result > 0)
0681             continue;
0682         if (result < 0)
0683             break;
0684         // check that this is not part of a longer word
0685         if (wordEnd == line.length())
0686             return header;
0687         if (isLegalNameChar(line[wordEnd]))
0688             continue;
0689         const char peekChar = peekNextChar(line, wordEnd - 1);
0690         // is not a header if part of a definition
0691         if (peekChar == ',' || peekChar == ')')
0692             break;
0693         // the following accessor definitions are NOT headers
0694         // goto default; is NOT a header
0695         // default(int) keyword in C# is NOT a header
0696         else if ((header == &AS_GET
0697                   || header == &AS_SET
0698                   || header == &AS_DEFAULT)
0699                  && (peekChar == ';' || peekChar == '(' || peekChar == '='))
0700             break;
0701         return header;
0702     }
0703     return nullptr;
0704 }
0705 
0706 // check if a specific line position contains a keyword.
0707 bool ASBase::findKeyword(const string& line, int i, const string& keyword) const
0708 {
0709     assert(isCharPotentialHeader(line, i));
0710     // check the word
0711     const size_t keywordLength = keyword.length();
0712     const size_t wordEnd = i + keywordLength;
0713     if (wordEnd > line.length())
0714         return false;
0715     if (line.compare(i, keywordLength, keyword) != 0)
0716         return false;
0717     // check that this is not part of a longer word
0718     if (wordEnd == line.length())
0719         return true;
0720     if (isLegalNameChar(line[wordEnd]))
0721         return false;
0722     // is not a keyword if part of a definition
0723     const char peekChar = peekNextChar(line, (int) wordEnd - 1);
0724     if (peekChar == ',' || peekChar == ')')
0725         return false;
0726     return true;
0727 }
0728 
0729 // check if a specific line position contains an operator.
0730 const string* ASBase::findOperator(const string& line, int i,
0731                                    const vector<const string*>* possibleOperators) const
0732 {
0733     assert(isCharPotentialOperator(line[i]));
0734     // find the operator in the vector
0735     // the vector contains the LONGEST operators first
0736     // must loop thru the entire vector
0737     size_t maxOperators = possibleOperators->size();
0738     for (size_t p = 0; p < maxOperators; p++)
0739     {
0740         const size_t wordEnd = i + (*(*possibleOperators)[p]).length();
0741         if (wordEnd > line.length())
0742             continue;
0743         if (line.compare(i, (*(*possibleOperators)[p]).length(), *(*possibleOperators)[p]) == 0)
0744             return (*possibleOperators)[p];
0745     }
0746     return nullptr;
0747 }
0748 
0749 // get the current word on a line
0750 // index must point to the beginning of the word
0751 string ASBase::getCurrentWord(const string& line, size_t index) const
0752 {
0753     assert(isCharPotentialHeader(line, index));
0754     size_t lineLength = line.length();
0755     size_t i;
0756     for (i = index; i < lineLength; i++)
0757     {
0758         if (!isLegalNameChar(line[i]))
0759             break;
0760     }
0761     return line.substr(index, i - index);
0762 }
0763 
0764 // check if a specific character can be used in a legal variable/method/class name
0765 bool ASBase::isLegalNameChar(char ch) const
0766 {
0767     if (isWhiteSpace(ch))
0768         return false;
0769     if ((unsigned char) ch > 127)
0770         return false;
0771     return (isalnum((unsigned char) ch)
0772             || ch == '.' || ch == '_'
0773             || (isJavaStyle() && ch == '$')
0774             || (isSharpStyle() && ch == '@'));  // may be used as a prefix
0775 }
0776 
0777 // check if a specific character can be part of a header
0778 bool ASBase::isCharPotentialHeader(const string& line, size_t i) const
0779 {
0780     assert(!isWhiteSpace(line[i]));
0781     char prevCh = ' ';
0782     if (i > 0)
0783         prevCh = line[i - 1];
0784     if (i > 1 && line[i - 2] == '\\')
0785         prevCh = ' ';
0786     if (!isLegalNameChar(prevCh) && isLegalNameChar(line[i]))
0787         return true;
0788     return false;
0789 }
0790 
0791 // check if a specific character can be part of an operator
0792 bool ASBase::isCharPotentialOperator(char ch) const
0793 {
0794     assert(!isWhiteSpace(ch));
0795     if ((unsigned) ch > 127)
0796         return false;
0797     return (ispunct((unsigned char) ch)
0798             && ch != '{' && ch != '}'
0799             && ch != '(' && ch != ')'
0800             && ch != '[' && ch != ']'
0801             && ch != ';' && ch != ','
0802             && ch != '#' && ch != '\\'
0803             && ch != '\'' && ch != '\"');
0804 }
0805 
0806 // check if a specific character is a digit
0807 // NOTE: Visual C isdigit() gives assert error if char > 256
0808 bool ASBase::isDigit(char ch) const
0809 {
0810     return (ch >= '0' && ch <= '9');
0811 }
0812 
0813 // check if a specific character is a digit separator
0814 bool ASBase::isDigitSeparator(const string& line, int i) const
0815 {
0816     assert(line[i] == '\'');
0817     // casting to (unsigned char) eliminates negative characters
0818     // will get a "Debug Assertion Failed" if not cast
0819     bool foundDigitSeparator = i > 0
0820                                && isxdigit((unsigned char) line[i - 1])
0821                                && i < (int) line.length() - 1
0822                                && isxdigit((unsigned char) line[i + 1]);
0823     return foundDigitSeparator;
0824 }
0825 
0826 // peek at the next unread character.
0827 char ASBase::peekNextChar(const string& line, int i) const
0828 {
0829     char ch = ' ';
0830     size_t peekNum = line.find_first_not_of(" \t", i + 1);
0831     if (peekNum == string::npos)
0832         return ch;
0833     ch = line[peekNum];
0834     return ch;
0835 }
0836 
0837 }   // end namespace astyle