"Fossies" - the Fresh Open Source Software Archive

Member "highlight-3.57-x64/src/core/astyle/ASResource.cpp" (12 May 2020, 27709 Bytes) of package /windows/www/highlight-3.57-x64.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // ASResource.cpp
    2 // Copyright (c) 2018 by Jim Pattee <jimp03@email.com>.
    3 // This code is licensed under the MIT License.
    4 // License.md describes the conditions under which this software may be distributed.
    5 
    6 //-----------------------------------------------------------------------------
    7 // headers
    8 //-----------------------------------------------------------------------------
    9 
   10 #include "astyle/astyle.h"
   11 #include <algorithm>
   12 
   13 //-----------------------------------------------------------------------------
   14 // astyle namespace
   15 //-----------------------------------------------------------------------------
   16 
   17 namespace astyle {
   18 //
   19 const string ASResource::_AS_EXCEPT = string("__except");
   20 const string ASResource::_AS_FINALLY = string("__finally");
   21 const string ASResource::_AS_TRY = string("__try");
   22 const string ASResource::AS_ADD = string("add");
   23 const string ASResource::AS_AUTO = string("auto");
   24 const string ASResource::AS_AUTORELEASEPOOL = string("autoreleasepool");
   25 const string ASResource::AS_CASE = string("case");
   26 const string ASResource::AS_CATCH = string("catch");
   27 const string ASResource::AS_CLASS = string("class");
   28 const string ASResource::AS_CONST = string("const");
   29 const string ASResource::AS_CONST_CAST = string("const_cast");
   30 const string ASResource::AS_DEFAULT = string("default");
   31 const string ASResource::AS_DELEGATE = string("delegate");
   32 const string ASResource::AS_DELETE = string("delete");
   33 const string ASResource::AS_DO = string("do");
   34 const string ASResource::AS_DYNAMIC_CAST = string("dynamic_cast");
   35 const string ASResource::AS_ELSE = string("else");
   36 const string ASResource::AS_END = string("end");
   37 const string ASResource::AS_ENUM = string("enum");
   38 const string ASResource::AS_EXTERN = string("extern");
   39 const string ASResource::AS_FINAL = string("final");
   40 const string ASResource::AS_FINALLY = string("finally");
   41 const string ASResource::AS_FIXED = string("fixed");
   42 const string ASResource::AS_FOR = string("for");
   43 const string ASResource::AS_FOREACH = string("foreach");
   44 const string ASResource::AS_FOREVER = string("forever");
   45 const string ASResource::AS_GET = string("get");
   46 const string ASResource::AS_IF = string("if");
   47 const string ASResource::AS_INTERFACE = string("interface");
   48 const string ASResource::AS_INTERRUPT = string("interrupt");
   49 const string ASResource::AS_LET = string("let");
   50 const string ASResource::AS_LOCK = string("lock");
   51 const string ASResource::AS_MODULE = string("module");  // CORBA IDL module definition
   52 const string ASResource::AS_NAMESPACE = string("namespace");
   53 const string ASResource::AS_NEW = string("new");
   54 const string ASResource::AS_NOEXCEPT = string("noexcept");
   55 const string ASResource::AS_NS_DURING = string("NS_DURING");
   56 const string ASResource::AS_NS_HANDLER = string("NS_HANDLER");
   57 const string ASResource::AS_OPERATOR = string("operator");
   58 const string ASResource::AS_OVERRIDE = string("override");
   59 const string ASResource::AS_PRIVATE = string("private");
   60 const string ASResource::AS_PROTECTED = string("protected");
   61 const string ASResource::AS_PUBLIC = string("public");
   62 const string ASResource::AS_QFOREACH = string("Q_FOREACH");
   63 const string ASResource::AS_QFOREVER = string("Q_FOREVER");
   64 const string ASResource::AS_REINTERPRET_CAST = string("reinterpret_cast");
   65 const string ASResource::AS_REMOVE = string("remove");
   66 const string ASResource::AS_SEALED = string("sealed");
   67 const string ASResource::AS_SELECTOR = string("selector");
   68 const string ASResource::AS_SET = string("set");
   69 const string ASResource::AS_STATIC = string("static");
   70 const string ASResource::AS_STATIC_CAST = string("static_cast");
   71 const string ASResource::AS_STRUCT = string("struct");
   72 const string ASResource::AS_SWITCH = string("switch");
   73 const string ASResource::AS_SYNCHRONIZED = string("synchronized");
   74 const string ASResource::AS_TEMPLATE = string("template");
   75 const string ASResource::AS_THROW = string("throw");
   76 const string ASResource::AS_THROWS = string("throws");
   77 const string ASResource::AS_TRY = string("try");
   78 const string ASResource::AS_UNCHECKED = string("unchecked");
   79 const string ASResource::AS_UNION = string("union");
   80 const string ASResource::AS_UNSAFE = string("unsafe");
   81 const string ASResource::AS_USING = string("using");
   82 const string ASResource::AS_VOLATILE = string("volatile");
   83 const string ASResource::AS_WHERE = string("where");
   84 const string ASResource::AS_WHILE = string("while");
   85 
   86 const string ASResource::AS_ASM = string("asm");
   87 const string ASResource::AS__ASM__ = string("__asm__");
   88 const string ASResource::AS_MS_ASM = string("_asm");
   89 const string ASResource::AS_MS__ASM = string("__asm");
   90 
   91 const string ASResource::AS_BAR_DEFINE = string("#define");
   92 const string ASResource::AS_BAR_INCLUDE = string("#include");
   93 const string ASResource::AS_BAR_IF = string("#if");
   94 const string ASResource::AS_BAR_EL = string("#el");
   95 const string ASResource::AS_BAR_ENDIF = string("#endif");
   96 
   97 const string ASResource::AS_OPEN_BRACE = string("{");
   98 const string ASResource::AS_CLOSE_BRACE = string("}");
   99 const string ASResource::AS_OPEN_LINE_COMMENT = string("//");
  100 const string ASResource::AS_OPEN_COMMENT = string("/*");
  101 const string ASResource::AS_CLOSE_COMMENT = string("*/");
  102 
  103 const string ASResource::AS_ASSIGN = string("=");
  104 const string ASResource::AS_PLUS_ASSIGN = string("+=");
  105 const string ASResource::AS_MINUS_ASSIGN = string("-=");
  106 const string ASResource::AS_MULT_ASSIGN = string("*=");
  107 const string ASResource::AS_DIV_ASSIGN = string("/=");
  108 const string ASResource::AS_MOD_ASSIGN = string("%=");
  109 const string ASResource::AS_OR_ASSIGN = string("|=");
  110 const string ASResource::AS_AND_ASSIGN = string("&=");
  111 const string ASResource::AS_XOR_ASSIGN = string("^=");
  112 const string ASResource::AS_GR_GR_ASSIGN = string(">>=");
  113 const string ASResource::AS_LS_LS_ASSIGN = string("<<=");
  114 const string ASResource::AS_GR_GR_GR_ASSIGN = string(">>>=");
  115 const string ASResource::AS_LS_LS_LS_ASSIGN = string("<<<=");
  116 const string ASResource::AS_GCC_MIN_ASSIGN = string("<?");
  117 const string ASResource::AS_GCC_MAX_ASSIGN = string(">?");
  118 
  119 const string ASResource::AS_RETURN = string("return");
  120 const string ASResource::AS_CIN = string("cin");
  121 const string ASResource::AS_COUT = string("cout");
  122 const string ASResource::AS_CERR = string("cerr");
  123 
  124 const string ASResource::AS_EQUAL = string("==");
  125 const string ASResource::AS_PLUS_PLUS = string("++");
  126 const string ASResource::AS_MINUS_MINUS = string("--");
  127 const string ASResource::AS_NOT_EQUAL = string("!=");
  128 const string ASResource::AS_GR_EQUAL = string(">=");
  129 const string ASResource::AS_GR_GR = string(">>");
  130 const string ASResource::AS_GR_GR_GR = string(">>>");
  131 const string ASResource::AS_LS_EQUAL = string("<=");
  132 const string ASResource::AS_LS_LS = string("<<");
  133 const string ASResource::AS_LS_LS_LS = string("<<<");
  134 const string ASResource::AS_QUESTION_QUESTION = string("??");
  135 const string ASResource::AS_LAMBDA = string("=>");            // C# lambda expression arrow
  136 const string ASResource::AS_ARROW = string("->");
  137 const string ASResource::AS_AND = string("&&");
  138 const string ASResource::AS_OR = string("||");
  139 const string ASResource::AS_SCOPE_RESOLUTION = string("::");
  140 
  141 const string ASResource::AS_PLUS = string("+");
  142 const string ASResource::AS_MINUS = string("-");
  143 const string ASResource::AS_MULT = string("*");
  144 const string ASResource::AS_DIV = string("/");
  145 const string ASResource::AS_MOD = string("%");
  146 const string ASResource::AS_GR = string(">");
  147 const string ASResource::AS_LS = string("<");
  148 const string ASResource::AS_NOT = string("!");
  149 const string ASResource::AS_BIT_OR = string("|");
  150 const string ASResource::AS_BIT_AND = string("&");
  151 const string ASResource::AS_BIT_NOT = string("~");
  152 const string ASResource::AS_BIT_XOR = string("^");
  153 const string ASResource::AS_QUESTION = string("?");
  154 const string ASResource::AS_COLON = string(":");
  155 const string ASResource::AS_COMMA = string(",");
  156 const string ASResource::AS_SEMICOLON = string(";");
  157 
  158 /**
  159  * Sort comparison function.
  160  * Compares the length of the value of pointers in the vectors.
  161  * The LONGEST strings will be first in the vector.
  162  *
  163  * @param a and b, the string pointers to be compared.
  164  */
  165 bool sortOnLength(const string* a, const string* b)
  166 {
  167     return (*a).length() > (*b).length();
  168 }
  169 
  170 /**
  171  * Sort comparison function.
  172  * Compares the value of pointers in the vectors.
  173  *
  174  * @param a and b, the string pointers to be compared.
  175  */
  176 bool sortOnName(const string* a, const string* b)
  177 {
  178     return *a < *b;
  179 }
  180 
  181 /**
  182  * Build the vector of assignment operators.
  183  * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp
  184  *
  185  * @param assignmentOperators   a reference to the vector to be built.
  186  */
  187 void ASResource::buildAssignmentOperators(vector<const string*>* assignmentOperators)
  188 {
  189     const size_t elements = 15;
  190     assignmentOperators->reserve(elements);
  191 
  192     assignmentOperators->emplace_back(&AS_ASSIGN);
  193     assignmentOperators->emplace_back(&AS_PLUS_ASSIGN);
  194     assignmentOperators->emplace_back(&AS_MINUS_ASSIGN);
  195     assignmentOperators->emplace_back(&AS_MULT_ASSIGN);
  196     assignmentOperators->emplace_back(&AS_DIV_ASSIGN);
  197     assignmentOperators->emplace_back(&AS_MOD_ASSIGN);
  198     assignmentOperators->emplace_back(&AS_OR_ASSIGN);
  199     assignmentOperators->emplace_back(&AS_AND_ASSIGN);
  200     assignmentOperators->emplace_back(&AS_XOR_ASSIGN);
  201 
  202     // Java
  203     assignmentOperators->emplace_back(&AS_GR_GR_GR_ASSIGN);
  204     assignmentOperators->emplace_back(&AS_GR_GR_ASSIGN);
  205     assignmentOperators->emplace_back(&AS_LS_LS_ASSIGN);
  206 
  207     // Unknown
  208     assignmentOperators->emplace_back(&AS_LS_LS_LS_ASSIGN);
  209 
  210     assert(assignmentOperators->size() < elements);
  211     sort(assignmentOperators->begin(), assignmentOperators->end(), sortOnLength);
  212 }
  213 
  214 /**
  215  * Build the vector of C++ cast operators.
  216  * Used by ONLY ASFormatter.cpp
  217  *
  218  * @param castOperators     a reference to the vector to be built.
  219  */
  220 void ASResource::buildCastOperators(vector<const string*>* castOperators)
  221 {
  222     const size_t elements = 5;
  223     castOperators->reserve(elements);
  224 
  225     castOperators->emplace_back(&AS_CONST_CAST);
  226     castOperators->emplace_back(&AS_DYNAMIC_CAST);
  227     castOperators->emplace_back(&AS_REINTERPRET_CAST);
  228     castOperators->emplace_back(&AS_STATIC_CAST);
  229 
  230     assert(castOperators->size() < elements);
  231     sort(castOperators->begin(), castOperators->end(), sortOnName);
  232 }
  233 
  234 /**
  235  * Build the vector of header words.
  236  * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp
  237  *
  238  * @param headers       a reference to the vector to be built.
  239  */
  240 void ASResource::buildHeaders(vector<const string*>* headers, int fileType, bool beautifier)
  241 {
  242     const size_t elements = 25;
  243     headers->reserve(elements);
  244 
  245     headers->emplace_back(&AS_IF);
  246     headers->emplace_back(&AS_ELSE);
  247     headers->emplace_back(&AS_FOR);
  248     headers->emplace_back(&AS_WHILE);
  249     headers->emplace_back(&AS_DO);
  250     headers->emplace_back(&AS_SWITCH);
  251     headers->emplace_back(&AS_CASE);
  252     headers->emplace_back(&AS_DEFAULT);
  253     headers->emplace_back(&AS_TRY);
  254     headers->emplace_back(&AS_CATCH);
  255     headers->emplace_back(&AS_QFOREACH);        // QT
  256     headers->emplace_back(&AS_QFOREVER);        // QT
  257     headers->emplace_back(&AS_FOREACH);     // QT & C#
  258     headers->emplace_back(&AS_FOREVER);     // Qt & Boost
  259 
  260     if (fileType == C_TYPE)
  261     {
  262         headers->emplace_back(&_AS_TRY);        // __try
  263         headers->emplace_back(&_AS_FINALLY);    // __finally
  264         headers->emplace_back(&_AS_EXCEPT); // __except
  265     }
  266     if (fileType == JAVA_TYPE)
  267     {
  268         headers->emplace_back(&AS_FINALLY);
  269         headers->emplace_back(&AS_SYNCHRONIZED);
  270     }
  271 
  272     if (fileType == SHARP_TYPE)
  273     {
  274         headers->emplace_back(&AS_FINALLY);
  275         headers->emplace_back(&AS_LOCK);
  276         headers->emplace_back(&AS_FIXED);
  277         headers->emplace_back(&AS_GET);
  278         headers->emplace_back(&AS_SET);
  279         headers->emplace_back(&AS_ADD);
  280         headers->emplace_back(&AS_REMOVE);
  281         headers->emplace_back(&AS_USING);
  282     }
  283 
  284     if (beautifier)
  285     {
  286         if (fileType == C_TYPE)
  287         {
  288             headers->emplace_back(&AS_TEMPLATE);
  289         }
  290 
  291         if (fileType == JAVA_TYPE)
  292         {
  293             headers->emplace_back(&AS_STATIC);         // for static constructor
  294         }
  295     }
  296 
  297     assert(headers->size() < elements);
  298     sort(headers->begin(), headers->end(), sortOnName);
  299 }
  300 
  301 /**
  302  * Build the vector of indentable headers.
  303  * Used by ONLY ASBeautifier.cpp
  304  *
  305  * @param indentableHeaders     a reference to the vector to be built.
  306  */
  307 void ASResource::buildIndentableHeaders(vector<const string*>* indentableHeaders)
  308 {
  309     indentableHeaders->emplace_back(&AS_RETURN);
  310 
  311 //  sort(indentableHeaders->begin(), indentableHeaders->end(), sortOnName);
  312 }
  313 
  314 /**
  315 * Build the vector of indentable macros pairs.
  316 * Initialized by ASFormatter, used by ONLY ASEnhancer.cpp
  317 *
  318 * @param indentableMacros       a reference to the vector to be built.
  319 */
  320 void ASResource::buildIndentableMacros(vector<const pair<const string, const string>* >* indentableMacros)
  321 {
  322     const size_t elements = 10;
  323     indentableMacros->reserve(elements);
  324 
  325     // the pairs must be retained in memory because of pair pointers
  326     using macro_pair = pair<const string, const string>;
  327     static const macro_pair macros[] =
  328     {
  329         // wxWidgets
  330         macro_pair("BEGIN_EVENT_TABLE",   "END_EVENT_TABLE"),
  331         macro_pair("wxBEGIN_EVENT_TABLE", "wxEND_EVENT_TABLE"),
  332         // MFC
  333         macro_pair("BEGIN_DISPATCH_MAP",  "END_DISPATCH_MAP"),
  334         macro_pair("BEGIN_EVENT_MAP",     "END_EVENT_MAP"),
  335         macro_pair("BEGIN_MESSAGE_MAP",   "END_MESSAGE_MAP"),
  336         macro_pair("BEGIN_PROPPAGEIDS",   "END_PROPPAGEIDS"),
  337     };
  338 
  339     size_t entries = sizeof(macros) / sizeof(macros[0]);
  340     for (size_t i = 0; i < entries; i++)
  341         indentableMacros->emplace_back(&macros[i]);
  342 
  343     assert(indentableMacros->size() < elements);
  344 }
  345 
  346 /**
  347  * Build the vector of non-assignment operators.
  348  * Used by ONLY ASBeautifier.cpp
  349  *
  350  * @param nonAssignmentOperators       a reference to the vector to be built.
  351  */
  352 void ASResource::buildNonAssignmentOperators(vector<const string*>* nonAssignmentOperators)
  353 {
  354     const size_t elements = 15;
  355     nonAssignmentOperators->reserve(elements);
  356 
  357     nonAssignmentOperators->emplace_back(&AS_EQUAL);
  358     nonAssignmentOperators->emplace_back(&AS_PLUS_PLUS);
  359     nonAssignmentOperators->emplace_back(&AS_MINUS_MINUS);
  360     nonAssignmentOperators->emplace_back(&AS_NOT_EQUAL);
  361     nonAssignmentOperators->emplace_back(&AS_GR_EQUAL);
  362     nonAssignmentOperators->emplace_back(&AS_GR_GR_GR);
  363     nonAssignmentOperators->emplace_back(&AS_GR_GR);
  364     nonAssignmentOperators->emplace_back(&AS_LS_EQUAL);
  365     nonAssignmentOperators->emplace_back(&AS_LS_LS_LS);
  366     nonAssignmentOperators->emplace_back(&AS_LS_LS);
  367     nonAssignmentOperators->emplace_back(&AS_ARROW);
  368     nonAssignmentOperators->emplace_back(&AS_AND);
  369     nonAssignmentOperators->emplace_back(&AS_OR);
  370     nonAssignmentOperators->emplace_back(&AS_LAMBDA);
  371 
  372     assert(nonAssignmentOperators->size() < elements);
  373     sort(nonAssignmentOperators->begin(), nonAssignmentOperators->end(), sortOnLength);
  374 }
  375 
  376 /**
  377  * Build the vector of header non-paren headers.
  378  * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp.
  379  * NOTE: Non-paren headers should also be included in the headers vector.
  380  *
  381  * @param nonParenHeaders       a reference to the vector to be built.
  382  */
  383 void ASResource::buildNonParenHeaders(vector<const string*>* nonParenHeaders, int fileType, bool beautifier)
  384 {
  385     const size_t elements = 20;
  386     nonParenHeaders->reserve(elements);
  387 
  388     nonParenHeaders->emplace_back(&AS_ELSE);
  389     nonParenHeaders->emplace_back(&AS_DO);
  390     nonParenHeaders->emplace_back(&AS_TRY);
  391     nonParenHeaders->emplace_back(&AS_CATCH);       // can be paren or non-paren
  392     nonParenHeaders->emplace_back(&AS_CASE);        // can be paren or non-paren
  393     nonParenHeaders->emplace_back(&AS_DEFAULT);
  394     nonParenHeaders->emplace_back(&AS_QFOREVER);    // QT
  395     nonParenHeaders->emplace_back(&AS_FOREVER); // Boost
  396 
  397     if (fileType == C_TYPE)
  398     {
  399         nonParenHeaders->emplace_back(&_AS_TRY);        // __try
  400         nonParenHeaders->emplace_back(&_AS_FINALLY);    // __finally
  401     }
  402     if (fileType == JAVA_TYPE)
  403     {
  404         nonParenHeaders->emplace_back(&AS_FINALLY);
  405     }
  406 
  407     if (fileType == SHARP_TYPE)
  408     {
  409         nonParenHeaders->emplace_back(&AS_FINALLY);
  410         nonParenHeaders->emplace_back(&AS_GET);
  411         nonParenHeaders->emplace_back(&AS_SET);
  412         nonParenHeaders->emplace_back(&AS_ADD);
  413         nonParenHeaders->emplace_back(&AS_REMOVE);
  414     }
  415 
  416     if (beautifier)
  417     {
  418         if (fileType == C_TYPE)
  419         {
  420             nonParenHeaders->emplace_back(&AS_TEMPLATE);
  421         }
  422         if (fileType == JAVA_TYPE)
  423         {
  424             nonParenHeaders->emplace_back(&AS_STATIC);
  425         }
  426     }
  427 
  428     assert(nonParenHeaders->size() < elements);
  429     sort(nonParenHeaders->begin(), nonParenHeaders->end(), sortOnName);
  430 }
  431 
  432 /**
  433  * Build the vector of operators.
  434  * Used by ONLY ASFormatter.cpp
  435  *
  436  * @param operators             a reference to the vector to be built.
  437  */
  438 void ASResource::buildOperators(vector<const string*>* operators, int fileType)
  439 {
  440     const size_t elements = 50;
  441     operators->reserve(elements);
  442 
  443     operators->emplace_back(&AS_PLUS_ASSIGN);
  444     operators->emplace_back(&AS_MINUS_ASSIGN);
  445     operators->emplace_back(&AS_MULT_ASSIGN);
  446     operators->emplace_back(&AS_DIV_ASSIGN);
  447     operators->emplace_back(&AS_MOD_ASSIGN);
  448     operators->emplace_back(&AS_OR_ASSIGN);
  449     operators->emplace_back(&AS_AND_ASSIGN);
  450     operators->emplace_back(&AS_XOR_ASSIGN);
  451     operators->emplace_back(&AS_EQUAL);
  452     operators->emplace_back(&AS_PLUS_PLUS);
  453     operators->emplace_back(&AS_MINUS_MINUS);
  454     operators->emplace_back(&AS_NOT_EQUAL);
  455     operators->emplace_back(&AS_GR_EQUAL);
  456     operators->emplace_back(&AS_GR_GR_GR_ASSIGN);
  457     operators->emplace_back(&AS_GR_GR_ASSIGN);
  458     operators->emplace_back(&AS_GR_GR_GR);
  459     operators->emplace_back(&AS_GR_GR);
  460     operators->emplace_back(&AS_LS_EQUAL);
  461     operators->emplace_back(&AS_LS_LS_LS_ASSIGN);
  462     operators->emplace_back(&AS_LS_LS_ASSIGN);
  463     operators->emplace_back(&AS_LS_LS_LS);
  464     operators->emplace_back(&AS_LS_LS);
  465     operators->emplace_back(&AS_QUESTION_QUESTION);
  466     operators->emplace_back(&AS_LAMBDA);
  467     operators->emplace_back(&AS_ARROW);
  468     operators->emplace_back(&AS_AND);
  469     operators->emplace_back(&AS_OR);
  470     operators->emplace_back(&AS_SCOPE_RESOLUTION);
  471     operators->emplace_back(&AS_PLUS);
  472     operators->emplace_back(&AS_MINUS);
  473     operators->emplace_back(&AS_MULT);
  474     operators->emplace_back(&AS_DIV);
  475     operators->emplace_back(&AS_MOD);
  476     operators->emplace_back(&AS_QUESTION);
  477     operators->emplace_back(&AS_COLON);
  478     operators->emplace_back(&AS_ASSIGN);
  479     operators->emplace_back(&AS_LS);
  480     operators->emplace_back(&AS_GR);
  481     operators->emplace_back(&AS_NOT);
  482     operators->emplace_back(&AS_BIT_OR);
  483     operators->emplace_back(&AS_BIT_AND);
  484     operators->emplace_back(&AS_BIT_NOT);
  485     operators->emplace_back(&AS_BIT_XOR);
  486     if (fileType == C_TYPE)
  487     {
  488         operators->emplace_back(&AS_GCC_MIN_ASSIGN);
  489         operators->emplace_back(&AS_GCC_MAX_ASSIGN);
  490     }
  491 
  492     assert(operators->size() < elements);
  493     sort(operators->begin(), operators->end(), sortOnLength);
  494 }
  495 
  496 /**
  497  * Build the vector of pre-block statements.
  498  * Used by ONLY ASBeautifier.cpp
  499  * NOTE: Cannot be both a header and a preBlockStatement.
  500  *
  501  * @param preBlockStatements        a reference to the vector to be built.
  502  */
  503 void ASResource::buildPreBlockStatements(vector<const string*>* preBlockStatements, int fileType)
  504 {
  505     const size_t elements = 10;
  506     preBlockStatements->reserve(elements);
  507 
  508     preBlockStatements->emplace_back(&AS_CLASS);
  509     if (fileType == C_TYPE)
  510     {
  511         preBlockStatements->emplace_back(&AS_STRUCT);
  512         preBlockStatements->emplace_back(&AS_UNION);
  513         preBlockStatements->emplace_back(&AS_NAMESPACE);
  514         preBlockStatements->emplace_back(&AS_MODULE);     // for CORBA IDL
  515         preBlockStatements->emplace_back(&AS_INTERFACE);  // for CORBA IDL
  516     }
  517     if (fileType == JAVA_TYPE)
  518     {
  519         preBlockStatements->emplace_back(&AS_INTERFACE);
  520         preBlockStatements->emplace_back(&AS_THROWS);
  521     }
  522     if (fileType == SHARP_TYPE)
  523     {
  524         preBlockStatements->emplace_back(&AS_INTERFACE);
  525         preBlockStatements->emplace_back(&AS_NAMESPACE);
  526         preBlockStatements->emplace_back(&AS_WHERE);
  527         preBlockStatements->emplace_back(&AS_STRUCT);
  528     }
  529 
  530     assert(preBlockStatements->size() < elements);
  531     sort(preBlockStatements->begin(), preBlockStatements->end(), sortOnName);
  532 }
  533 
  534 /**
  535  * Build the vector of pre-command headers.
  536  * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp.
  537  * NOTE: Cannot be both a header and a preCommandHeader.
  538  *
  539  * A preCommandHeader is in a function definition between
  540  * the closing paren and the opening brace.
  541  * e.g. in "void foo() const {}", "const" is a preCommandHeader.
  542  */
  543 void ASResource::buildPreCommandHeaders(vector<const string*>* preCommandHeaders, int fileType)
  544 {
  545     const size_t elements = 10;
  546     preCommandHeaders->reserve(elements);
  547 
  548     if (fileType == C_TYPE)
  549     {
  550         preCommandHeaders->emplace_back(&AS_CONST);
  551         preCommandHeaders->emplace_back(&AS_FINAL);
  552         preCommandHeaders->emplace_back(&AS_INTERRUPT);
  553         preCommandHeaders->emplace_back(&AS_NOEXCEPT);
  554         preCommandHeaders->emplace_back(&AS_OVERRIDE);
  555         preCommandHeaders->emplace_back(&AS_VOLATILE);
  556         preCommandHeaders->emplace_back(&AS_SEALED);            // Visual C only
  557         preCommandHeaders->emplace_back(&AS_AUTORELEASEPOOL);   // Obj-C only
  558     }
  559 
  560     if (fileType == JAVA_TYPE)
  561     {
  562         preCommandHeaders->emplace_back(&AS_THROWS);
  563     }
  564 
  565     if (fileType == SHARP_TYPE)
  566     {
  567         preCommandHeaders->emplace_back(&AS_WHERE);
  568     }
  569 
  570     assert(preCommandHeaders->size() < elements);
  571     sort(preCommandHeaders->begin(), preCommandHeaders->end(), sortOnName);
  572 }
  573 
  574 /**
  575  * Build the vector of pre-definition headers.
  576  * Used by ONLY ASFormatter.cpp
  577  * NOTE: Do NOT add 'enum' here. It is an array type brace.
  578  * NOTE: Do NOT add 'extern' here. Do not want an extra indent.
  579  *
  580  * @param preDefinitionHeaders      a reference to the vector to be built.
  581  */
  582 void ASResource::buildPreDefinitionHeaders(vector<const string*>* preDefinitionHeaders, int fileType)
  583 {
  584     const size_t elements = 10;
  585     preDefinitionHeaders->reserve(elements);
  586 
  587     preDefinitionHeaders->emplace_back(&AS_CLASS);
  588     if (fileType == C_TYPE)
  589     {
  590         preDefinitionHeaders->emplace_back(&AS_STRUCT);
  591         preDefinitionHeaders->emplace_back(&AS_UNION);
  592         preDefinitionHeaders->emplace_back(&AS_NAMESPACE);
  593         preDefinitionHeaders->emplace_back(&AS_MODULE);     // for CORBA IDL
  594         preDefinitionHeaders->emplace_back(&AS_INTERFACE);  // for CORBA IDL
  595     }
  596     if (fileType == JAVA_TYPE)
  597     {
  598         preDefinitionHeaders->emplace_back(&AS_INTERFACE);
  599     }
  600     if (fileType == SHARP_TYPE)
  601     {
  602         preDefinitionHeaders->emplace_back(&AS_STRUCT);
  603         preDefinitionHeaders->emplace_back(&AS_INTERFACE);
  604         preDefinitionHeaders->emplace_back(&AS_NAMESPACE);
  605     }
  606 
  607     assert(preDefinitionHeaders->size() < elements);
  608     sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName);
  609 }
  610 
  611 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  612  *                             ASBase Functions
  613  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  614 
  615 // check if a specific line position contains a header.
  616 const string* ASBase::findHeader(const string& line, int i,
  617                                  const vector<const string*>* possibleHeaders) const
  618 {
  619     assert(isCharPotentialHeader(line, i));
  620     // check the word
  621     size_t maxHeaders = possibleHeaders->size();
  622     for (size_t p = 0; p < maxHeaders; p++)
  623     {
  624         const string* header = (*possibleHeaders)[p];
  625         const size_t wordEnd = i + header->length();
  626         if (wordEnd > line.length())
  627             continue;
  628         int result = (line.compare(i, header->length(), *header));
  629         if (result > 0)
  630             continue;
  631         if (result < 0)
  632             break;
  633         // check that this is not part of a longer word
  634         if (wordEnd == line.length())
  635             return header;
  636         if (isLegalNameChar(line[wordEnd]))
  637             continue;
  638         const char peekChar = peekNextChar(line, wordEnd - 1);
  639         // is not a header if part of a definition
  640         if (peekChar == ',' || peekChar == ')')
  641             break;
  642         // the following accessor definitions are NOT headers
  643         // goto default; is NOT a header
  644         // default(int) keyword in C# is NOT a header
  645         if ((header == &AS_GET
  646                 || header == &AS_SET
  647                 || header == &AS_DEFAULT)
  648                 && (peekChar == ';' || peekChar == '(' || peekChar == '='))
  649             break;
  650         return header;
  651     }
  652     return nullptr;
  653 }
  654 
  655 // check if a specific line position contains a keyword.
  656 bool ASBase::findKeyword(const string& line, int i, const string& keyword) const
  657 {
  658     assert(isCharPotentialHeader(line, i));
  659     // check the word
  660     const size_t keywordLength = keyword.length();
  661     const size_t wordEnd = i + keywordLength;
  662     if (wordEnd > line.length())
  663         return false;
  664     if (line.compare(i, keywordLength, keyword) != 0)
  665         return false;
  666     // check that this is not part of a longer word
  667     if (wordEnd == line.length())
  668         return true;
  669     if (isLegalNameChar(line[wordEnd]))
  670         return false;
  671     // is not a keyword if part of a definition
  672     const char peekChar = peekNextChar(line, (int) wordEnd - 1);
  673     if (peekChar == ',' || peekChar == ')')
  674         return false;
  675     return true;
  676 }
  677 
  678 // check if a specific line position contains an operator.
  679 const string* ASBase::findOperator(const string& line, int i,
  680                                    const vector<const string*>* possibleOperators) const
  681 {
  682     assert(isCharPotentialOperator(line[i]));
  683     // find the operator in the vector
  684     // the vector contains the LONGEST operators first
  685     // must loop thru the entire vector
  686     size_t maxOperators = possibleOperators->size();
  687     for (size_t p = 0; p < maxOperators; p++)
  688     {
  689         const size_t wordEnd = i + (*(*possibleOperators)[p]).length();
  690         if (wordEnd > line.length())
  691             continue;
  692         if (line.compare(i, (*(*possibleOperators)[p]).length(), *(*possibleOperators)[p]) == 0)
  693             return (*possibleOperators)[p];
  694     }
  695     return nullptr;
  696 }
  697 
  698 // get the current word on a line
  699 // index must point to the beginning of the word
  700 string ASBase::getCurrentWord(const string& line, size_t index) const
  701 {
  702     assert(isCharPotentialHeader(line, index));
  703     size_t lineLength = line.length();
  704     size_t i;
  705     for (i = index; i < lineLength; i++)
  706     {
  707         if (!isLegalNameChar(line[i]))
  708             break;
  709     }
  710     return line.substr(index, i - index);
  711 }
  712 
  713 // check if a specific character can be used in a legal variable/method/class name
  714 bool ASBase::isLegalNameChar(char ch) const
  715 {
  716     if (isWhiteSpace(ch))
  717         return false;
  718     if ((unsigned char) ch > 127)
  719         return false;
  720     return (isalnum((unsigned char) ch)
  721             || ch == '.' || ch == '_'
  722             || (isJavaStyle() && ch == '$')
  723             || (isSharpStyle() && ch == '@'));  // may be used as a prefix
  724 }
  725 
  726 // check if a specific character can be part of a header
  727 bool ASBase::isCharPotentialHeader(const string& line, size_t i) const
  728 {
  729     assert(!isWhiteSpace(line[i]));
  730     char prevCh = ' ';
  731     if (i > 0)
  732         prevCh = line[i - 1];
  733     if (i > 1 && line[i - 2] == '\\')
  734         prevCh = ' ';
  735     if (!isLegalNameChar(prevCh) && isLegalNameChar(line[i]))
  736         return true;
  737     return false;
  738 }
  739 
  740 // check if a specific character can be part of an operator
  741 bool ASBase::isCharPotentialOperator(char ch) const
  742 {
  743     assert(!isWhiteSpace(ch));
  744     if ((unsigned) ch > 127)
  745         return false;
  746     return (ispunct((unsigned char) ch)
  747             && ch != '{' && ch != '}'
  748             && ch != '(' && ch != ')'
  749             && ch != '[' && ch != ']'
  750             && ch != ';' && ch != ','
  751             && ch != '#' && ch != '\\'
  752             && ch != '\'' && ch != '\"');
  753 }
  754 
  755 // check if a specific character is a digit
  756 // NOTE: Visual C isdigit() gives assert error if char > 256
  757 bool ASBase::isDigit(char ch) const
  758 {
  759     return (ch >= '0' && ch <= '9');
  760 }
  761 
  762 // check if a specific character is a digit separator
  763 bool ASBase::isDigitSeparator(const string& line, int i) const
  764 {
  765     assert(line[i] == '\'');
  766     // casting to (unsigned char) eliminates negative characters
  767     // will get a "Debug Assertion Failed" if not cast
  768     bool foundDigitSeparator = i > 0
  769                                && isxdigit((unsigned char) line[i - 1])
  770                                && i < (int) line.length() - 1
  771                                && isxdigit((unsigned char) line[i + 1]);
  772     return foundDigitSeparator;
  773 }
  774 
  775 // peek at the next unread character.
  776 char ASBase::peekNextChar(const string& line, int i) const
  777 {
  778     char ch = ' ';
  779     size_t peekNum = line.find_first_not_of(" \t", i + 1);
  780     if (peekNum == string::npos)
  781         return ch;
  782     ch = line[peekNum];
  783     return ch;
  784 }
  785 
  786 }   // end namespace astyle