diff options
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.76.0/src/brace_cleanup.cpp')
-rw-r--r-- | debian/uncrustify-trinity/uncrustify-trinity-0.76.0/src/brace_cleanup.cpp | 1449 |
1 files changed, 0 insertions, 1449 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.76.0/src/brace_cleanup.cpp b/debian/uncrustify-trinity/uncrustify-trinity-0.76.0/src/brace_cleanup.cpp deleted file mode 100644 index 2cfe2ac2..00000000 --- a/debian/uncrustify-trinity/uncrustify-trinity-0.76.0/src/brace_cleanup.cpp +++ /dev/null @@ -1,1449 +0,0 @@ -/** - * @file brace_cleanup.cpp - * Determines the brace level and paren level. - * Inserts virtual braces as needed. - * Handles all that preprocessor stuff. - * - * @author Ben Gardner - * @license GPL v2+ - */ - -#include "brace_cleanup.h" - -#include "flag_parens.h" -#include "frame_list.h" -#include "keywords.h" -#include "lang_pawn.h" -#include "prototypes.h" - -#include <stdexcept> // to get std::invalid_argument - -constexpr static auto LCURRENT = LBC; - -using namespace uncrustify; - -using std::invalid_argument; -using std::string; -using std::to_string; -using std::stringstream; - - -/* - * abbreviations used: - * - sparen = tbd - * - PS = Parenthesis Stack - * - pse = Parenthesis Stack - */ - - -struct BraceState -{ - std::vector<ParseFrame> frames = {}; - E_Token in_preproc = CT_NONE; - int pp_level = 0; - bool consumed = false; -}; - -/** - * Called when a statement was just closed and the pse_tos was just - * decremented. - * - * - if the TOS is now VBRACE, insert a CT_VBRACE_CLOSE and recurse. - * - if the TOS is a complex statement, call handle_complex_close() - * - * @retval true done with this chunk - * @retval false keep processing - */ -static bool close_statement(ParseFrame &frm, Chunk *pc, const BraceState &braceState); - - -static size_t preproc_start(BraceState &braceState, ParseFrame &frm, Chunk *pc); - - -static void print_stack(log_sev_t logsev, const char *str, const ParseFrame &frm); - - -/** - * pc is a CT_WHILE. - * Scan backwards to see if we find a brace/vbrace with the parent set to CT_DO - */ -static bool maybe_while_of_do(Chunk *pc); - - -/** - * @param after determines: true - insert_vbrace_close_after(pc, frm) - * false - insert_vbrace_open_before(pc, frm) - */ -static Chunk *insert_vbrace(Chunk *pc, bool after, const ParseFrame &frm); - -#define insert_vbrace_close_after(pc, frm) insert_vbrace(pc, true, frm) -#define insert_vbrace_open_before(pc, frm) insert_vbrace(pc, false, frm) - -static void parse_cleanup(BraceState &braceState, ParseFrame &frm, Chunk *pc); - - -/** - * Checks the progression of complex statements. - * - checks for else after if - * - checks for if after else - * - checks for while after do - * - checks for open brace in BRACE2 and BRACE_DO stages, inserts open VBRACE - * - checks for open paren in PAREN1 and BRACE2 stages, complains - * - * @param frm The parse frame - * @param pc The current chunk - * - * @return true - done with this chunk, false - keep processing - */ -static bool check_complex_statements(ParseFrame &frm, Chunk *pc, const BraceState &braceState); - - -/** - * Handles a close paren or brace - just progress the stage, if the end - * of the statement is hit, call close_statement() - * - * @param frm The parse frame - * @param pc The current chunk - * - * @return true - done with this chunk, false - keep processing - */ -static bool handle_complex_close(ParseFrame &frm, Chunk *pc, const BraceState &braceState); - - -//! We're on a 'namespace' skip the word and then set the parent of the braces. -static void mark_namespace(Chunk *pns); - - -static size_t preproc_start(BraceState &braceState, ParseFrame &frm, Chunk *pc) -{ - LOG_FUNC_ENTRY(); - const size_t pp_level = braceState.pp_level; - - Chunk *next = pc->GetNextNcNnl(); - - if (next->IsNullChunk()) - { - return(pp_level); - } - // Get the type of preprocessor and handle it - braceState.in_preproc = next->GetType(); - - // If we are not in a define, check for #if, #else, #endif, etc - if (braceState.in_preproc != CT_PP_DEFINE) - { - int pp_indent = fl_check(braceState.frames, frm, braceState.pp_level, pc); - return(pp_indent); - } - // else push the frame stack - fl_push(braceState.frames, frm); - - // a preproc body starts a new, blank frame - frm = {}; - frm.level = 1; - frm.brace_level = 1; - - // TODO: not sure about the next 3 lines - frm.push(nullptr); - frm.top().type = CT_PP_DEFINE; - - return(pp_level); -} - - -static void print_stack(log_sev_t logsev, const char *str, - const ParseFrame &frm) -{ - LOG_FUNC_ENTRY(); - - if (!log_sev_on(logsev)) - { - return; - } - log_fmt(logsev, "%s(%d): str is '%s'", __func__, __LINE__, str); - - for (size_t idx = 1; idx < frm.size(); idx++) - { - if (frm.at(idx).stage != brace_stage_e::NONE) - { - LOG_FMT(logsev, " [%s - %u]", get_token_name(frm.at(idx).type), - (unsigned int)frm.at(idx).stage); - } - else - { - LOG_FMT(logsev, " [%s]", get_token_name(frm.at(idx).type)); - } - } - - log_fmt(logsev, "\n"); -} - - -//TODO: This can be cleaned up and simplified - we can look both forward and backward! -void brace_cleanup() -{ - LOG_FUNC_ENTRY(); - - BraceState braceState; - ParseFrame frm{}; - Chunk *pc = Chunk::GetHead(); - - while (pc->IsNotNullChunk()) - { - LOG_CHUNK(LTOK, pc); - - // Check for leaving a #define body - if ( braceState.in_preproc != CT_NONE - && !pc->TestFlags(PCF_IN_PREPROC)) - { - if (braceState.in_preproc == CT_PP_DEFINE) - { - // out of the #define body, restore the frame - size_t brace_level = frm.brace_level; - - if ( options::pp_warn_unbalanced_if() - && brace_level != 1) - { - LOG_FMT(LWARN, "%s(%d): orig line is %zu, unbalanced #define block braces, out-level is %zu\n", - __func__, __LINE__, pc->GetOrigLine(), brace_level); - } - fl_pop(braceState.frames, frm); - } - braceState.in_preproc = CT_NONE; - } - // Check for a preprocessor start - size_t pp_level; - - if (pc->Is(CT_PREPROC)) - { - pp_level = preproc_start(braceState, frm, pc); - } - else - { - pp_level = braceState.pp_level; - } - LOG_FMT(LTOK, "%s(%d): pp level is %zu\n", - __func__, __LINE__, pp_level); - - // Do before assigning stuff from the frame - if ( language_is_set(LANG_PAWN) - && frm.top().type == CT_VBRACE_OPEN - && pc->Is(CT_NEWLINE)) - { - pc = pawn_check_vsemicolon(pc); - - if (pc == nullptr) - { - return; - } - } - - // Issue #1813 - if (pc->Is(CT_NAMESPACE)) - { - mark_namespace(pc); - } - // Assume the level won't change - pc->SetLevel(frm.level); - pc->SetBraceLevel(frm.brace_level); - pc->SetPpLevel(pp_level); - - /* - * #define bodies get the full formatting treatment - * Also need to pass in the initial '#' to close out any virtual braces. - */ - if ( !pc->IsCommentOrNewline() - && !pc->Is(CT_ATTRIBUTE) - && !pc->Is(CT_IGNORED) // Issue #2279 - && ( braceState.in_preproc == CT_PP_DEFINE - || braceState.in_preproc == CT_NONE)) - { - braceState.consumed = false; - parse_cleanup(braceState, frm, pc); - print_stack(LBCSAFTER, (pc->Is(CT_VBRACE_CLOSE)) ? "Virt-}\n" : pc->GetStr().c_str(), frm); - } - pc = pc->GetNext(); - } -} // brace_cleanup - - -static bool maybe_while_of_do(Chunk *pc) -{ - LOG_FUNC_ENTRY(); - - Chunk *prev = pc->GetPrevNcNnl(); - - if ( prev->IsNullChunk() - || !prev->TestFlags(PCF_IN_PREPROC)) - { - return(false); - } - - // Find the chunk before the preprocessor - while ( prev->IsNullChunk() - && prev->TestFlags(PCF_IN_PREPROC)) - { - prev = prev->GetPrevNcNnl(); - } - - if ( ( prev->Is(CT_VBRACE_CLOSE) - || prev->Is(CT_BRACE_CLOSE)) - && prev->GetParentType() == CT_DO) - { - return(true); - } - return(false); -} - - -/** - * At the heart of this algorithm are two stacks. - * There is the Paren Stack (PS) and the Frame stack. - * - * The PS (pse in the code) keeps track of braces, parens, - * if/else/switch/do/while/etc items -- anything that is nestable. - * Complex statements go through stages. - * Take this simple if statement as an example: - * if ( x ) { x--; } - * - * The stack would change like so: 'token' stack afterwards - * 'if' [IF - 1] - * '(' [IF - 1] [PAREN OPEN] - * 'x' [IF - 1] [PAREN OPEN] - * ')' [IF - 2] <- note that the state was incremented - * '{' [IF - 2] [BRACE OPEN] - * 'x' [IF - 2] [BRACE OPEN] - * '--' [IF - 2] [BRACE OPEN] - * ';' [IF - 2] [BRACE OPEN] - * '}' [IF - 3] - * <- lack of else kills the IF, closes statement - * - * Virtual braces example: - * if ( x ) x--; else x++; - * - * 'if' [IF - 1] - * '(' [IF - 1] [PAREN OPEN] - * 'x' [IF - 1] [PAREN OPEN] - * ')' [IF - 2] - * 'x' [IF - 2] [VBRACE OPEN] <- VBrace open inserted before because '{' was not next - * '--' [IF - 2] [VBRACE OPEN] - * ';' [IF - 3] <- VBrace close inserted after semicolon - * 'else' [ELSE - 0] <- IF changed into ELSE - * 'x' [ELSE - 0] [VBRACE OPEN] <- lack of '{' -> VBrace - * '++' [ELSE - 0] [VBRACE OPEN] - * ';' [ELSE - 0] <- VBrace close inserted after semicolon - * <- ELSE removed after statement close - * - * The pse stack is kept on a frame stack. - * The frame stack is need for languages that support preprocessors (C, C++, C#) - * that can arbitrarily change code flow. It also isolates #define macros so - * that they are indented independently and do not affect the rest of the program. - * - * When an #if is hit, a copy of the current frame is push on the frame stack. - * When an #else/#elif is hit, a copy of the current stack is pushed under the - * #if frame and the original (pre-#if) frame is copied to the current frame. - * When #endif is hit, the top frame is popped. - * This has the following effects: - * - a simple #if / #endif does not affect program flow - * - #if / #else /#endif - continues from the #if clause - * - * When a #define is entered, the current frame is pushed and cleared. - * When a #define is exited, the frame is popped. - */ -static void parse_cleanup(BraceState &braceState, ParseFrame &frm, Chunk *pc) -{ - LOG_FUNC_ENTRY(); - - LOG_FMT(LTOK, "%s(%d): orig line is %zu, orig col is %zu, type is %s, tos is %zu, TOS.type is %s, TOS.stage is %s, ", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), get_token_name(pc->GetType()), - frm.size() - 1, get_token_name(frm.top().type), - get_brace_stage_name(frm.top().stage)); - log_pcf_flags(LTOK, pc->GetFlags()); - - // Mark statement starts - LOG_FMT(LTOK, "%s(%d): orig line is %zu, type is %s, Text() is '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), get_token_name(pc->GetType()), pc->Text()); - LOG_FMT(LTOK, "%s(%d): frm.stmt_count is %zu, frm.expr_count is %zu\n", - __func__, __LINE__, frm.stmt_count, frm.expr_count); - - if ( ( frm.stmt_count == 0 - || frm.expr_count == 0) - && !pc->IsSemicolon() - && pc->IsNot(CT_BRACE_CLOSE) - && pc->IsNot(CT_VBRACE_CLOSE) - && !pc->IsString(")") - && !pc->IsString("]")) - { - pc->SetFlagBits(PCF_EXPR_START | ((frm.stmt_count == 0) ? PCF_STMT_START : PCF_NONE)); - LOG_FMT(LSTMT, "%s(%d): orig line is %zu, 1.marked '%s' as %s, start stmt_count is %zu, expr_count is %zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->Text(), - pc->TestFlags(PCF_STMT_START) ? "stmt" : "expr", frm.stmt_count, - frm.expr_count); - } - frm.stmt_count++; - frm.expr_count++; - LOG_FMT(LTOK, "%s(%d): frm.stmt_count is %zu, frm.expr_count is %zu\n", - __func__, __LINE__, frm.stmt_count, frm.expr_count); - - if (frm.sparen_count > 0) - { - pc->SetFlagBits(PCF_IN_SPAREN); - - // Mark everything in the for statement - for (int tmp = static_cast<int>(frm.size()) - 2; tmp >= 0; tmp--) - { - if (frm.at(tmp).type == CT_FOR) - { - pc->SetFlagBits(PCF_IN_FOR); - break; - } - } - - // Mark the parent on semicolons in for() statements - if ( pc->Is(CT_SEMICOLON) - && frm.size() > 2 - && frm.prev().type == CT_FOR) - { - pc->SetParentType(CT_FOR); - } - } - - // Check the progression of complex statements - if ( frm.top().stage != brace_stage_e::NONE - && !pc->Is(CT_AUTORELEASEPOOL) - && check_complex_statements(frm, pc, braceState)) - { - return; - } - - /* - * Check for a virtual brace statement close due to a semicolon. - * The virtual brace will get handled the next time through. - * The semicolon isn't handled at all. - * TODO: may need to float VBRACE past comments until newline? - */ - if (frm.top().type == CT_VBRACE_OPEN) - { - if (pc->IsSemicolon()) - { - braceState.consumed = true; - close_statement(frm, pc, braceState); - } - else if ( language_is_set(LANG_PAWN) - && pc->Is(CT_BRACE_CLOSE)) - { - close_statement(frm, pc, braceState); - } - else if ( language_is_set(LANG_D) - && pc->Is(CT_BRACE_CLOSE)) - { - close_statement(frm, pc, braceState); - } - } - - // Handle close parenthesis, vbrace, brace, and square - if ( pc->Is(CT_PAREN_CLOSE) - || pc->Is(CT_BRACE_CLOSE) - || pc->Is(CT_VBRACE_CLOSE) - || pc->Is(CT_ANGLE_CLOSE) - || pc->Is(CT_MACRO_CLOSE) - || pc->Is(CT_SQUARE_CLOSE)) - { - // Change CT_PAREN_CLOSE into CT_SPAREN_CLOSE or CT_FPAREN_CLOSE - if ( pc->Is(CT_PAREN_CLOSE) - && ( (frm.top().type == CT_FPAREN_OPEN) - || (frm.top().type == CT_SPAREN_OPEN))) - { - // TODO: fix enum hack - pc->SetType(static_cast<E_Token>(frm.top().type + 1)); - - if (pc->Is(CT_SPAREN_CLOSE)) - { - frm.sparen_count--; - pc->ResetFlagBits(PCF_IN_SPAREN); - } - } - - // Make sure the open / close match - if (pc->IsNot((E_Token)(frm.top().type + 1))) - { - if (pc->TestFlags(PCF_IN_PREPROC)) // Issue #3113, #3283 - { - // do nothing - } - else - { - LOG_FMT(LWARN, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType())); - paren_stack_entry_t AA = frm.top(); // Issue #3055 - - if (AA.type != CT_EOF) - { - LOG_FMT(LWARN, "%s(%d): (frm.top().type + 1) is %s\n", - __func__, __LINE__, get_token_name((E_Token)(frm.top().type + 1))); - } - - if ( frm.top().type != CT_EOF - && frm.top().type != CT_PP_DEFINE) - { - LOG_FMT(LWARN, "%s(%d): File: %s, orig line is %zu, orig col is %zu, Error: Unexpected '%s' for '%s', which was on line %zu\n", - __func__, __LINE__, cpd.filename.c_str(), pc->GetOrigLine(), pc->GetOrigCol(), - pc->Text(), get_token_name(frm.top().pc->GetType()), - frm.top().pc->GetOrigLine()); - print_stack(LBCSPOP, "=Error ", frm); - exit(EXIT_FAILURE); - } - } - } - else - { - braceState.consumed = true; - - // Copy the parent, update the parenthesis/brace levels - pc->SetParentType(frm.top().parent); - frm.level--; - - if ( pc->Is(CT_BRACE_CLOSE) - || pc->Is(CT_VBRACE_CLOSE) - || pc->Is(CT_MACRO_CLOSE)) - { - frm.brace_level--; - LOG_FMT(LBCSPOP, "%s(%d): frm.brace_level decreased to %zu", - __func__, __LINE__, frm.brace_level); - log_pcf_flags(LBCSPOP, pc->GetFlags()); - } - pc->SetLevel(frm.level); - pc->SetBraceLevel(frm.brace_level); - - // Pop the entry - LOG_FMT(LBCSPOP, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType())); - frm.pop(__func__, __LINE__, pc); - print_stack(LBCSPOP, "-Close ", frm); - - if ( frm.top().stage == brace_stage_e::NONE - && ( pc->Is(CT_VBRACE_CLOSE) - || pc->Is(CT_BRACE_CLOSE) - || pc->Is(CT_SEMICOLON)) - && frm.top().pc->Is(CT_VBRACE_OPEN)) - { - // frames for functions are not created as they are for an if - // this here is a hackish solution to close a vbrace of a block that - // contains the function - frm.push(nullptr); // <- dummy frame for the function - frm.top().stage = brace_stage_e::BRACE2; - } - - // See if we are in a complex statement - if (frm.top().stage != brace_stage_e::NONE) - { - handle_complex_close(frm, pc, braceState); - } - } - } - - /* - * In this state, we expect a semicolon, but we'll also hit the closing - * sparen, so we need to check braceState.consumed to see if the close sparen - * was already handled. - */ - if (frm.top().stage == brace_stage_e::WOD_SEMI) - { - if (braceState.consumed) - { - /* - * If consumed, then we are on the close sparen. - * PAWN: Check the next chunk for a semicolon. If it isn't, then - * add a virtual semicolon, which will get handled on the next pass. - */ - if (language_is_set(LANG_PAWN)) - { - Chunk *tmp = pc->GetNextNcNnl(); - - if (!tmp->IsSemicolon()) - { - pawn_add_vsemi_after(pc); - } - } - } - else - { - // Complain if this ISN'T a semicolon, but close out WHILE_OF_DO anyway - if (pc->IsSemicolon()) - { - braceState.consumed = true; - pc->SetParentType(CT_WHILE_OF_DO); - } - else - { - LOG_FMT(LWARN, "%s: %s(%d): %zu: Error: Expected a semicolon for WHILE_OF_DO, but got '%s'\n", - cpd.filename.c_str(), __func__, __LINE__, pc->GetOrigLine(), - get_token_name(pc->GetType())); - exit(EX_SOFTWARE); - } - handle_complex_close(frm, pc, braceState); - } - } - // Get the parent type for brace and parenthesis open - E_Token parentType = pc->GetParentType(); - - if ( pc->Is(CT_PAREN_OPEN) - || pc->Is(CT_FPAREN_OPEN) - || pc->Is(CT_SPAREN_OPEN) - || pc->Is(CT_BRACE_OPEN)) - { - Chunk *prev = pc->GetPrevNcNnl(); - - if (prev->IsNotNullChunk()) - { - if ( pc->Is(CT_PAREN_OPEN) - || pc->Is(CT_FPAREN_OPEN) - || pc->Is(CT_SPAREN_OPEN)) - { - // Set the parent for parenthesis and change parenthesis type - if ( prev->Is(CT_IF) - || prev->Is(CT_CONSTEXPR) - || prev->Is(CT_ELSEIF) - || prev->Is(CT_WHILE) - || prev->Is(CT_WHILE_OF_DO) - || prev->Is(CT_DO) - || prev->Is(CT_FOR) - || prev->Is(CT_SWITCH) - || prev->Is(CT_CATCH) - || prev->Is(CT_SYNCHRONIZED) - || prev->Is(CT_D_VERSION) - || prev->Is(CT_D_VERSION_IF) - || prev->Is(CT_D_SCOPE) - || prev->Is(CT_D_SCOPE_IF)) - { - pc->SetType(CT_SPAREN_OPEN); - parentType = frm.top().type; - frm.sparen_count++; - } - else if (prev->Is(CT_FUNCTION)) - { - pc->SetType(CT_FPAREN_OPEN); - parentType = CT_FUNCTION; - } - // NS_ENUM and NS_OPTIONS are followed by a (type, name) pair - else if ( prev->Is(CT_ENUM) - && language_is_set(LANG_OC)) - { - // Treat both as CT_ENUM since the syntax is identical - pc->SetType(CT_FPAREN_OPEN); - parentType = CT_ENUM; - } - else if (prev->Is(CT_DECLSPEC)) // Issue 1289 - { - parentType = CT_DECLSPEC; - } - // else: no need to set parent - } - else // must be CT_BRACE_OPEN - { - // Set the parent for open braces - if (frm.top().stage != brace_stage_e::NONE) - { - parentType = frm.top().type; - } - else if ( prev->Is(CT_ASSIGN) - && (prev->GetStr()[0] == '=')) - { - parentType = CT_ASSIGN; - } - else if ( prev->Is(CT_RETURN) - && language_is_set(LANG_CPP)) - { - parentType = CT_RETURN; - } - // Carry through CT_ENUM parent in NS_ENUM (type, name) { - // only to help the vim command } - else if ( prev->Is(CT_FPAREN_CLOSE) - && language_is_set(LANG_OC) - && prev->GetParentType() == CT_ENUM) - { - parentType = CT_ENUM; - } - else if (prev->Is(CT_FPAREN_CLOSE)) - { - parentType = CT_FUNCTION; - } - // else: no need to set parent - } - } - } - - /* - * Adjust the level for opens & create a stack entry - * Note that CT_VBRACE_OPEN has already been handled. - */ - if ( pc->Is(CT_BRACE_OPEN) - || pc->Is(CT_PAREN_OPEN) - || pc->Is(CT_FPAREN_OPEN) - || pc->Is(CT_SPAREN_OPEN) - || pc->Is(CT_ANGLE_OPEN) - || pc->Is(CT_MACRO_OPEN) - || pc->Is(CT_SQUARE_OPEN)) - { - frm.level++; - - if ( pc->Is(CT_BRACE_OPEN) - || pc->Is(CT_MACRO_OPEN)) - { - // Issue #1813 - bool single = false; - - if (pc->GetParentType() == CT_NAMESPACE) - { - LOG_FMT(LBCSPOP, "%s(%d): parent type is NAMESPACE\n", - __func__, __LINE__); - Chunk *tmp = frm.top().pc; - - if ( tmp != nullptr - && tmp->GetParentType() == CT_NAMESPACE) - { - LOG_FMT(LBCSPOP, "%s(%d): tmp->GetParentType() is NAMESPACE\n", - __func__, __LINE__); - - log_rule_B("indent_namespace"); - log_rule_B("indent_namespace_single_indent"); - - if ( options::indent_namespace() - && options::indent_namespace_single_indent()) - { - LOG_FMT(LBCSPOP, "%s(%d): Options are SINGLE\n", - __func__, __LINE__); - single = true; - } - } - } - LOG_FMT(LBCSPOP, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s, parent type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType()), get_token_name(pc->GetParentType())); - - if (!single) - { - frm.brace_level++; - LOG_FMT(LBCSPOP, "%s(%d): frm.brace_level increased to %zu\n", - __func__, __LINE__, frm.brace_level); - } - } - frm.push(pc, __func__, __LINE__); - frm.top().parent = parentType; - pc->SetParentType(parentType); - } - // Issue #2281 - - if ( pc->Is(CT_BRACE_OPEN) - && pc->GetParentType() == CT_SWITCH) - { - size_t idx = frm.size(); - LOG_FMT(LBCSPOP, "%s(%d): idx is %zu\n", - __func__, __LINE__, idx); - Chunk *saved = frm.at(idx - 2).pc; - - if (saved != nullptr) - { - // set parent member - pc->SetParent(saved); - } - } - - if ( pc->Is(CT_CASE) - || pc->Is(CT_DEFAULT)) - { - Chunk *prev = pc->GetPrevNcNnl(); // Issue #3176 - - if ( pc->Is(CT_CASE) - || ( pc->Is(CT_DEFAULT) - && prev->IsNot(CT_ASSIGN))) - { - // it is a CT_DEFAULT from a switch - LOG_FMT(LBCSPOP, "%s(%d): pc orig line is %zu, orig col is %zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol()); - pc->SetParentType(CT_SWITCH); - size_t idx = frm.size(); - LOG_FMT(LBCSPOP, "%s(%d): idx is %zu\n", - __func__, __LINE__, idx); - Chunk *saved = frm.at(idx - 2).pc; - - if (saved != nullptr) - { - // set parent member - pc->SetParent(saved); - } - } - } - - if (pc->Is(CT_BREAK)) - { - LOG_FMT(LBCSPOP, "%s(%d): pc orig line is %zu, orig col is %zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol()); - size_t idx = frm.size(); - LOG_FMT(LBCSPOP, "%s(%d): idx is %zu\n", - __func__, __LINE__, idx); - Chunk *saved = frm.at(idx - 2).pc; - - if (saved != nullptr) - { - // set parent member - pc->SetParent(saved); - } - } - const pattern_class_e patcls = get_token_pattern_class(pc->GetType()); - - /* - * Create a stack entry for complex statements: - * if, elseif, switch, for, while, synchronized, using, lock, with, - * version, CT_D_SCOPE_IF - */ - if (patcls == pattern_class_e::BRACED) - { - frm.push(pc, __func__, __LINE__, (pc->Is(CT_DO) ? brace_stage_e::BRACE_DO - : brace_stage_e::BRACE2)); - // "+ComplexBraced" - } - else if (patcls == pattern_class_e::PBRACED) - { - brace_stage_e bs = brace_stage_e::PAREN1; - - if ( pc->Is(CT_WHILE) - && maybe_while_of_do(pc)) - { - pc->SetType(CT_WHILE_OF_DO); - bs = brace_stage_e::WOD_PAREN; - } - frm.push(pc, __func__, __LINE__, bs); - // "+ComplexParenBraced" - } - else if (patcls == pattern_class_e::OPBRACED) - { - frm.push(pc, __func__, __LINE__, brace_stage_e::OP_PAREN1); - // "+ComplexOpParenBraced"); - } - else if (patcls == pattern_class_e::ELSE) - { - frm.push(pc, __func__, __LINE__, brace_stage_e::ELSEIF); - // "+ComplexElse"); - } - - /* - * Mark simple statement/expression starts - * - after { or } - * - after ';', but not if the paren stack top is a paren - * - after '(' that has a parent type of CT_FOR - */ - if ( pc->Is(CT_SQUARE_OPEN) - || ( pc->Is(CT_BRACE_OPEN) - && pc->GetParentType() != CT_ASSIGN) - || pc->Is(CT_BRACE_CLOSE) - || pc->Is(CT_VBRACE_CLOSE) - || ( pc->Is(CT_SPAREN_OPEN) - && pc->GetParentType() == CT_FOR) - || pc->Is(CT_COLON) - || pc->Is(CT_OC_END) - || ( pc->IsSemicolon() - && frm.top().type != CT_PAREN_OPEN - && frm.top().type != CT_FPAREN_OPEN - && frm.top().type != CT_SPAREN_OPEN) - || pc->Is(CT_MACRO)) // Issue #2742 - { - LOG_FMT(LSTMT, "%s(%d): orig line is %zu, reset1 stmt on '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), pc->Text()); - frm.stmt_count = 0; - frm.expr_count = 0; - LOG_FMT(LTOK, "%s(%d): frm.stmt_count is %zu, frm.expr_count is %zu\n", - __func__, __LINE__, frm.stmt_count, frm.expr_count); - } - // Mark expression starts - LOG_FMT(LSTMT, "%s(%d): Mark expression starts: orig line is %zu, orig col is %zu, Text() is '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text()); - Chunk *tmp = pc->GetNextNcNnl(); - - if ( pc->Is(CT_ARITH) - || pc->Is(CT_SHIFT) - || pc->Is(CT_ASSIGN) - || pc->Is(CT_CASE) - || pc->Is(CT_COMPARE) - || ( pc->Is(CT_STAR) - && tmp->IsNot(CT_STAR)) - || pc->Is(CT_BOOL) - || pc->Is(CT_MINUS) - || pc->Is(CT_PLUS) - || pc->Is(CT_CARET) - || pc->Is(CT_ANGLE_OPEN) - || pc->Is(CT_ANGLE_CLOSE) - || pc->Is(CT_RETURN) - || pc->Is(CT_THROW) - || pc->Is(CT_GOTO) - || pc->Is(CT_CONTINUE) - || pc->Is(CT_PAREN_OPEN) - || pc->Is(CT_FPAREN_OPEN) - || pc->Is(CT_SPAREN_OPEN) - || pc->Is(CT_BRACE_OPEN) - || pc->IsSemicolon() - || pc->Is(CT_COMMA) - || pc->Is(CT_NOT) - || pc->Is(CT_INV) - || pc->Is(CT_COLON) - || pc->Is(CT_QUESTION)) - { - frm.expr_count = 0; - LOG_FMT(LSTMT, "%s(%d): orig line is %zu, orig col is %zu, reset expr on '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text()); - } -} // parse_cleanup - - -static bool check_complex_statements(ParseFrame &frm, Chunk *pc, const BraceState &braceState) -{ - LOG_FUNC_ENTRY(); - - brace_stage_e atest = frm.top().stage; - - LOG_FMT(LBCSPOP, "%s(%d): atest is %s\n", - __func__, __LINE__, get_brace_stage_name(atest)); - - // Turn an optional parenthesis into either a real parenthesis or a brace - if (frm.top().stage == brace_stage_e::OP_PAREN1) - { - frm.top().stage = (pc->IsNot(CT_PAREN_OPEN)) - ? brace_stage_e::BRACE2 - : brace_stage_e::PAREN1; - LOG_FMT(LBCSPOP, "%s(%d): frm.top().stage is now %s\n", - __func__, __LINE__, get_brace_stage_name(frm.top().stage)); - } - - // Check for CT_ELSE after CT_IF - while (frm.top().stage == brace_stage_e::ELSE) - { - if (pc->Is(CT_ELSE)) - { - // Replace CT_IF with CT_ELSE on the stack & we are done - frm.top().type = CT_ELSE; - frm.top().stage = brace_stage_e::ELSEIF; - print_stack(LBCSSWAP, "=Swap ", frm); - - return(true); - } - // Remove the CT_IF and close the statement - LOG_FMT(LBCSPOP, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType())); - frm.pop(__func__, __LINE__, pc); - print_stack(LBCSPOP, "-IF-CCS ", frm); - - if (close_statement(frm, pc, braceState)) - { - return(true); - } - } - - // Check for CT_IF after CT_ELSE - if (frm.top().stage == brace_stage_e::ELSEIF) - { - log_rule_B("indent_else_if"); - - if ( pc->Is(CT_IF) - && ( !options::indent_else_if() - || !pc->GetPrevNc()->IsNewline())) - { - // Replace CT_ELSE with CT_IF - pc->SetType(CT_ELSEIF); - frm.top().type = CT_ELSEIF; - frm.top().stage = brace_stage_e::PAREN1; - return(true); - } - // Jump to the 'expecting brace' stage - frm.top().stage = brace_stage_e::BRACE2; - } - - // Check for CT_CATCH or CT_FINALLY after CT_TRY or CT_CATCH - while (frm.top().stage == brace_stage_e::CATCH) - { - if ( pc->Is(CT_CATCH) - || pc->Is(CT_FINALLY)) - { - // Replace CT_TRY with CT_CATCH or CT_FINALLY on the stack & we are done - frm.top().type = pc->GetType(); - - if (language_is_set(LANG_CS)) - { - frm.top().stage = (pc->Is(CT_CATCH)) ? brace_stage_e::CATCH_WHEN : brace_stage_e::BRACE2; - } - else - { - // historically this used OP_PAREN1; however, to my knowledge the expression after a catch clause - // is only optional for C# which has been handled above; therefore, this should now always expect - // a parenthetical expression after the catch keyword and brace after the finally keyword - frm.top().stage = (pc->Is(CT_CATCH)) ? brace_stage_e::PAREN1 : brace_stage_e::BRACE2; - } - print_stack(LBCSSWAP, "=Swap ", frm); - - return(true); - } - // Remove the CT_TRY and close the statement - LOG_FMT(LBCSPOP, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType())); - frm.pop(__func__, __LINE__, pc); - print_stack(LBCSPOP, "-TRY-CCS ", frm); - - if (close_statement(frm, pc, braceState)) - { - return(true); - } - } - - // Check for optional parenthesis and optional CT_WHEN after CT_CATCH - if (frm.top().stage == brace_stage_e::CATCH_WHEN) - { - if (pc->Is(CT_PAREN_OPEN)) // this is for the paren after "catch" - { - // Replace CT_PAREN_OPEN with CT_SPAREN_OPEN - pc->SetType(CT_SPAREN_OPEN); - frm.top().type = pc->GetType(); - frm.top().stage = brace_stage_e::PAREN1; - - return(false); - } - - if (pc->Is(CT_WHEN)) - { - frm.top().type = pc->GetType(); - frm.top().stage = brace_stage_e::OP_PAREN1; - - return(true); - } - - if (pc->Is(CT_BRACE_OPEN)) - { - frm.top().stage = brace_stage_e::BRACE2; - - return(false); - } - } - - // Check for CT_WHILE after the CT_DO - if (frm.top().stage == brace_stage_e::WHILE) - { - if (pc->Is(CT_WHILE)) - { - pc->SetType(CT_WHILE_OF_DO); - frm.top().type = CT_WHILE_OF_DO; //CT_WHILE; - frm.top().stage = brace_stage_e::WOD_PAREN; - - return(true); - } - LOG_FMT(LWARN, "%s(%d): %s, orig line is %zu, Error: Expected 'while', got '%s'\n", - __func__, __LINE__, cpd.filename.c_str(), pc->GetOrigLine(), - pc->Text()); - LOG_FMT(LBCSPOP, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType())); - frm.pop(__func__, __LINE__, pc); - print_stack(LBCSPOP, "-Error ", frm); - exit(EX_SOFTWARE); - } - // Insert a CT_VBRACE_OPEN, if needed - // but not in a preprocessor - atest = frm.top().stage; - - if ( pc->IsNot(CT_BRACE_OPEN) - && !pc->TestFlags(PCF_IN_PREPROC) - && ( (frm.top().stage == brace_stage_e::BRACE2) - || (frm.top().stage == brace_stage_e::BRACE_DO))) - { - log_rule_B("indent_using_block"); - - if ( language_is_set(LANG_CS) - && pc->Is(CT_USING_STMT) - && (!options::indent_using_block())) - { - // don't indent the using block - } - else - { - const E_Token parentType = frm.top().type; - - Chunk *vbrace = insert_vbrace_open_before(pc, frm); - vbrace->SetParentType(parentType); - - frm.level++; - frm.brace_level++; - LOG_FMT(LBCSPOP, "%s(%d): frm.brace_level increased to %zu\n", - __func__, __LINE__, frm.brace_level); - log_pcf_flags(LBCSPOP, pc->GetFlags()); - - frm.push(vbrace, __func__, __LINE__, brace_stage_e::NONE); - // "+VBrace"); - - frm.top().parent = parentType; - - // update the level of pc - pc->SetLevel(frm.level); - pc->SetBraceLevel(frm.brace_level); - - // Mark as a start of a statement - frm.stmt_count = 0; - frm.expr_count = 0; - LOG_FMT(LTOK, "%s(%d): frm.stmt_count is %zu, frm.expr_count is %zu\n", - __func__, __LINE__, frm.stmt_count, frm.expr_count); - pc->SetFlagBits(PCF_STMT_START | PCF_EXPR_START); - frm.stmt_count = 1; - frm.expr_count = 1; - LOG_FMT(LSTMT, "%s(%d): orig line is %zu, 2.marked '%s' as stmt start\n", - __func__, __LINE__, pc->GetOrigLine(), pc->Text()); - } - } - - // Check for "constexpr" after CT_IF or CT_ELSEIF - if ( frm.top().stage == brace_stage_e::PAREN1 - && ( frm.top().type == CT_IF - || frm.top().type == CT_ELSEIF) - && pc->Is(CT_CONSTEXPR)) - { - return(false); - } - - // Verify open parenthesis in complex statement - if ( pc->IsNot(CT_PAREN_OPEN) - && ( (frm.top().stage == brace_stage_e::PAREN1) - || (frm.top().stage == brace_stage_e::WOD_PAREN))) - { - LOG_FMT(LWARN, "%s(%d): %s, orig line is %zu, Error: Expected '(', got '%s' for '%s'\n", - __func__, __LINE__, cpd.filename.c_str(), pc->GetOrigLine(), pc->Text(), - get_token_name(frm.top().type)); - - // Throw out the complex statement - LOG_FMT(LBCSPOP, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType())); - frm.pop(__func__, __LINE__, pc); - print_stack(LBCSPOP, "-Error ", frm); - exit(EX_SOFTWARE); - } - return(false); -} // check_complex_statements - - -static bool handle_complex_close(ParseFrame &frm, Chunk *pc, const BraceState &braceState) -{ - LOG_FUNC_ENTRY(); - - if (frm.top().stage == brace_stage_e::PAREN1) - { - if (pc->GetNext()->GetType() == CT_WHEN) - { - frm.top().type = pc->GetType(); - frm.top().stage = brace_stage_e::CATCH_WHEN; - - return(true); - } - // PAREN1 always => BRACE2 - frm.top().stage = brace_stage_e::BRACE2; - } - else if (frm.top().stage == brace_stage_e::BRACE2) - { - // BRACE2: IF => ELSE, anything else => close - if ( (frm.top().type == CT_IF) - || (frm.top().type == CT_ELSEIF)) - { - frm.top().stage = brace_stage_e::ELSE; - - // If the next chunk isn't CT_ELSE, close the statement - Chunk *next = pc->GetNextNcNnl(); - - if ( next->IsNullChunk() - || next->IsNot(CT_ELSE)) - { - LOG_FMT(LBCSPOP, "%s(%d): no CT_ELSE, pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType())); - frm.pop(__func__, __LINE__, pc); - print_stack(LBCSPOP, "-IF-HCS ", frm); - - return(close_statement(frm, pc, braceState)); - } - } - else if ( (frm.top().type == CT_TRY) - || (frm.top().type == CT_CATCH)) - { - frm.top().stage = brace_stage_e::CATCH; - - // If the next chunk isn't CT_CATCH or CT_FINALLY, close the statement - Chunk *next = pc->GetNextNcNnl(); - - if ( next->IsNot(CT_CATCH) - && next->IsNot(CT_FINALLY)) - { - LOG_FMT(LBCSPOP, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType())); - frm.pop(__func__, __LINE__, pc); - print_stack(LBCSPOP, "-TRY-HCS ", frm); - - return(close_statement(frm, pc, braceState)); - } - } - else - { - LOG_FMT(LNOTE, "%s(%d): close_statement on %s brace_stage_e::BRACE2\n", - __func__, __LINE__, get_token_name(frm.top().type)); - LOG_FMT(LBCSPOP, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType())); - frm.pop(__func__, __LINE__, pc); - print_stack(LBCSPOP, "-HCC B2 ", frm); - - return(close_statement(frm, pc, braceState)); - } - } - else if (frm.top().stage == brace_stage_e::BRACE_DO) - { - frm.top().stage = brace_stage_e::WHILE; - } - else if (frm.top().stage == brace_stage_e::WOD_PAREN) - { - LOG_FMT(LNOTE, "%s(%d): close_statement on %s brace_stage_e::WOD_PAREN\n", - __func__, __LINE__, get_token_name(frm.top().type)); - frm.top().stage = brace_stage_e::WOD_SEMI; - print_stack(LBCSPOP, "-HCC WoDP ", frm); - } - else if (frm.top().stage == brace_stage_e::WOD_SEMI) - { - LOG_FMT(LNOTE, "%s(%d): close_statement on %s brace_stage_e::WOD_SEMI\n", - __func__, __LINE__, get_token_name(frm.top().type)); - LOG_FMT(LBCSPOP, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType())); - frm.pop(__func__, __LINE__, pc); - print_stack(LBCSPOP, "-HCC WoDS ", frm); - - return(close_statement(frm, pc, braceState)); - } - else - { - // PROBLEM - LOG_FMT(LWARN, "%s(%d): %s:%zu Error: TOS.type='%s' TOS.stage=%u\n", - __func__, __LINE__, cpd.filename.c_str(), pc->GetOrigLine(), - get_token_name(frm.top().type), - (unsigned int)frm.top().stage); - exit(EX_SOFTWARE); - } - return(false); -} // handle_complex_close - - -static void mark_namespace(Chunk *pns) -{ - LOG_FUNC_ENTRY(); - // Issue #1813 - Chunk *br_close; - bool is_using = false; - - Chunk *pc = pns->GetPrevNcNnl(); - - if (pc->Is(CT_USING)) - { - is_using = true; - pns->SetParentType(CT_USING); - } - pc = pns->GetNextNcNnl(); - - while (pc->IsNotNullChunk()) - { - pc->SetParentType(CT_NAMESPACE); - - if (pc->IsNot(CT_BRACE_OPEN)) - { - if (pc->Is(CT_SEMICOLON)) - { - if (is_using) - { - pc->SetParentType(CT_USING); - } - return; - } - pc = pc->GetNextNcNnl(); - continue; - } - log_rule_B("indent_namespace_limit"); - - if ( (options::indent_namespace_limit() > 0) - && ((br_close = pc->GetClosingParen())->IsNotNullChunk())) - { - // br_close->GetOrigLine() is always >= pc->GetOrigLine(); - size_t numberOfLines = br_close->GetOrigLine() - pc->GetOrigLine() - 1; // Issue #2345 - LOG_FMT(LTOK, "%s(%d): br_close orig line is %zu, pc orig line is %zu\n", - __func__, __LINE__, br_close->GetOrigLine(), pc->GetOrigLine()); - LOG_FMT(LTOK, "%s(%d): numberOfLines is %zu, indent_namespace_limit() is %d\n", - __func__, __LINE__, numberOfLines, options::indent_namespace_limit()); - - log_rule_B("indent_namespace_limit"); - - if (numberOfLines > options::indent_namespace_limit()) - { - LOG_FMT(LTOK, "%s(%d): PCF_LONG_BLOCK is set\n", __func__, __LINE__); - pc->SetFlagBits(PCF_LONG_BLOCK); - br_close->SetFlagBits(PCF_LONG_BLOCK); - } - } - flag_parens(pc, PCF_IN_NAMESPACE, CT_NONE, CT_NAMESPACE, false); - return; - } -} // mark_namespace - - -static Chunk *insert_vbrace(Chunk *pc, bool after, const ParseFrame &frm) -{ - LOG_FUNC_ENTRY(); - - Chunk chunk; - - chunk.SetParentType(frm.top().type); - chunk.SetOrigLine(pc->GetOrigLine()); - chunk.SetLevel(frm.level); - chunk.SetPpLevel(frm.pp_level); - chunk.SetBraceLevel(frm.brace_level); - chunk.SetFlags(pc->GetFlags() & PCF_COPY_FLAGS); - chunk.Str() = ""; - - if (after) - { - chunk.SetOrigCol(pc->GetOrigCol()); - chunk.SetType(CT_VBRACE_CLOSE); - return(chunk.CopyAndAddAfter(pc)); - } - Chunk *ref = pc->GetPrev(); - - if (ref->IsNullChunk()) - { - return(nullptr); - } - - if (!ref->TestFlags(PCF_IN_PREPROC)) - { - chunk.ResetFlagBits(PCF_IN_PREPROC); - } - bool ref_is_comment = ref->IsComment(); // Issue #3351 - - while (ref->IsCommentOrNewline()) - { - ref->SetLevel(ref->GetLevel() + 1); - ref->SetBraceLevel(ref->GetBraceLevel() + 1); - ref = ref->GetPrev(); - } - - if (ref->IsNullChunk()) - { - return(nullptr); - } - - // Don't back into a preprocessor - if ( !pc->TestFlags(PCF_IN_PREPROC) - && ref->TestFlags(PCF_IN_PREPROC)) - { - if (ref->Is(CT_PREPROC_BODY)) - { - while ( ref->IsNotNullChunk() - && ref->TestFlags(PCF_IN_PREPROC)) - { - ref = ref->GetPrev(); - } - } - else - { - ref = ref->GetNext(); - - if (ref->Is(CT_COMMENT)) // Issue #3034 - { - ref = ref->GetNextNc(); - } - } - } - - if (ref_is_comment) // Issue #3351 - { - ref = ref->GetNext(); - } - - if (ref->IsNullChunk()) - { - return(nullptr); - } - chunk.SetOrigLine(ref->GetOrigLine()); - chunk.SetOrigCol(ref->GetOrigCol()); - chunk.SetColumn(ref->GetColumn() + ref->Len() + 1); - chunk.SetPpLevel(ref->GetPpLevel()); // Issue #3055 - chunk.SetType(CT_VBRACE_OPEN); - - return(chunk.CopyAndAddAfter(ref)); -} // insert_vbrace - - -bool close_statement(ParseFrame &frm, Chunk *pc, const BraceState &braceState) -{ - LOG_FUNC_ENTRY(); - - if ( pc == nullptr - || pc->IsNullChunk()) - { - throw invalid_argument(string(__func__) + ":" + to_string(__LINE__) - + "args cannot be nullptr"); - } - LOG_FMT(LTOK, "%s(%d): orig line is %zu, type is %s, '%s' type is %s, stage is %u\n", - __func__, __LINE__, pc->GetOrigLine(), - get_token_name(pc->GetType()), pc->Text(), - get_token_name(frm.top().type), - (unsigned int)frm.top().stage); - - if (braceState.consumed) - { - frm.stmt_count = 0; - frm.expr_count = 0; - LOG_FMT(LSTMT, "%s(%d): orig line is %zu> reset2 stmt on '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), pc->Text()); - } - /* - * Insert a CT_VBRACE_CLOSE, if needed: - * If we are in a virtual brace and we are not ON a CT_VBRACE_CLOSE add one - */ - Chunk *vbc = pc; - - if (frm.top().type == CT_VBRACE_OPEN) - { - // If the current token has already been consumed, then add after it - if (braceState.consumed) - { - insert_vbrace_close_after(pc, frm); - } - else - { - // otherwise, add before it and consume the vbrace - vbc = pc->GetPrevNcNnl(); - - frm.level--; - frm.brace_level--; - vbc = insert_vbrace_close_after(vbc, frm); - vbc->SetParentType(frm.top().parent); - - LOG_FMT(LBCSPOP, "%s(%d): frm.brace_level decreased to %zu\n", - __func__, __LINE__, frm.brace_level); - log_pcf_flags(LBCSPOP, pc->GetFlags()); - LOG_FMT(LBCSPOP, "%s(%d): pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), get_token_name(pc->GetType())); - frm.pop(__func__, __LINE__, pc); - - // Update the token level - pc->SetLevel(frm.level); - pc->SetBraceLevel(frm.brace_level); - - print_stack(LBCSPOP, "-CS VB ", frm); - - // And repeat the close - close_statement(frm, pc, braceState); - return(true); - } - } - - // See if we are done with a complex statement - if (frm.top().stage != brace_stage_e::NONE) - { - if (handle_complex_close(frm, vbc, braceState)) - { - return(true); - } - } - return(false); -} // close_statement |