diff options
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/indent.cpp')
-rw-r--r-- | debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/indent.cpp | 4792 |
1 files changed, 0 insertions, 4792 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/indent.cpp b/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/indent.cpp deleted file mode 100644 index 364a899e..00000000 --- a/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/indent.cpp +++ /dev/null @@ -1,4792 +0,0 @@ -/** - * @file indent.cpp - * Does all the indenting stuff. - * - * @author Ben Gardner - * @author Guy Maurel October 2015- 2021 - * @license GPL v2+ - */ - -#include "indent.h" - -#include "align.h" -#include "options.h" -#include "options_for_QT.h" -#include "parsing_frame_stack.h" -#include "prototypes.h" -#include "quick_align_again.h" -#include "space.h" -#include <cstdint> - -#ifdef WIN32 -#include <algorithm> // to get max -#endif // ifdef WIN32 - -#ifdef IGNORE // WinBase.h -#undef IGNORE -#endif - - -constexpr static auto LCURRENT = LINDENT; - -using namespace std; -using namespace uncrustify; - - -/** - * General indenting approach: - * Indenting levels are put into a stack. - * - * The stack entries contain: - * - opening type - * - brace column - * - continuation column - * - * Items that start a new stack item: - * - preprocessor (new parse frame) - * - Brace Open (Virtual brace also) - * - Paren, Square, Angle open - * - Assignments - * - C++ '<<' operator (ie, cout << "blah") - * - case - * - class colon - * - return - * - types - * - any other continued statement - * - * Note that the column of items marked 'PCF_WAS_ALIGNED' is not changed. - * - * For an open brace: - * - indent increases by indent_columns - * - if part of if/else/do/while/switch/etc, an extra indent may be applied - * - if in a paren, then cont-col is set to column + 1, ie "({ some code })" - * - * Open paren/square/angle: - * cont-col is set to the column of the item after the open paren, unless - * followed by a newline, then it is set to (brace-col + indent_columns). - * Examples: - * a_really_long_function_name( - * param1, param2); - * a_really_long_function_name(param1, - * param2); - * - * Assignments: - * Assignments are continued aligned with the first item after the assignment, - * unless the assign is followed by a newline. - * Examples: - * some.variable = asdf + asdf + - * asdf; - * some.variable = - * asdf + asdf + asdf; - * - * C++ << operator: - * Handled the same as assignment. - * Examples: - * cout << "this is test number: " - * << test_number; - * - * case: - * Started with case or default. - * Terminated with close brace at level or another case or default. - * Special indenting according to various rules. - * - indent of case label - * - indent of case body - * - how to handle optional braces - * Examples: - * { - * case x: { - * a++; - * break; - * } - * case y: - * b--; - * break; - * default: - * c++; - * break; - * } - * - * Class colon: - * Indent continuation by indent_columns: - * class my_class : - * baseclass1, - * baseclass2 - * { - * - * Return: same as assignments - * If the return statement is not fully paren'd, then the indent continues at - * the column of the item after the return. If it is paren'd, then the paren - * rules apply. - * return somevalue + - * othervalue; - * - * Type: pretty much the same as assignments - * Examples: - * int foo, - * bar, - * baz; - * - * Any other continued item: - * There shouldn't be anything not covered by the above cases, but any other - * continued item is indented by indent_columns: - * Example: - * somereallycrazylongname.with[lotsoflongstuff]. - * thatreallyannoysme.whenIhavetomaintain[thecode] = 3; - */ - -/** - * REVISIT: This needs to be re-checked, maybe cleaned up - * - * Indents comments in a (hopefully) smart manner. - * - * There are two type of comments that get indented: - * - stand alone (ie, no tokens on the line before the comment) - * - trailing comments (last token on the line apart from a linefeed) - * + note that a stand-alone comment is a special case of a trailing - * - * The stand alone comments will get indented in one of three ways: - * - column 1: - * + There is an empty line before the comment AND the indent level is 0 - * + The comment was originally in column 1 - * - * - Same column as trailing comment on previous line (ie, aligned) - * + if originally within TBD (3) columns of the previous comment - * - * - syntax indent level - * + doesn't fit in the previous categories - * - * Options modify this behavior: - * - keep original column (don't move the comment, if possible) - * - keep relative column (move out the same amount as first item on line) - * - fix trailing comment in column TBD - * - * @param pc The comment, which is the first item on a line - * @param col The column if this is to be put at indent level - */ -static void indent_comment(Chunk *pc, size_t col); - - -static size_t token_indent(E_Token type); - - -static size_t calc_indent_continue(const ParsingFrame &frm, size_t pse_tos); - -/** - * Get candidate chunk first on line to which OC blocks can be indented against. - */ -static Chunk *candidate_chunk_first_on_line(Chunk *pc); - -/** - * We are on a '{' that has parent = OC_BLOCK_EXPR - * find the column of the param tag - */ -static Chunk *oc_msg_block_indent(Chunk *pc, bool from_brace, bool from_caret, bool from_colon, bool from_keyword); - - -/** - * returns true if forward or reverse scan reveals only single newlines or comments - * stops when hits code - * false if next thing hit is a closing brace, also if 2 newlines in a row - */ -static bool single_line_comment_indent_rule_applies(Chunk *start, bool forward); - -/** - * returns true if semicolon on the same level ends any assign operations - * false if next thing hit is not the end of an assign operation - */ -static bool is_end_of_assignment(Chunk *pc, const ParsingFrame &frm); - - -void indent_to_column(Chunk *pc, size_t column) -{ - LOG_FUNC_ENTRY(); - - if (column < pc->GetColumn()) - { - column = pc->GetColumn(); - } - reindent_line(pc, column); -} - - -enum class align_mode_e : unsigned int -{ - SHIFT, //! shift relative to the current column - KEEP_ABS, //! try to keep the original absolute column - KEEP_REL, //! try to keep the original gap -}; - - -enum class indent_mode_e : int -{ - INDENT = 0, //! indent by one level - ALIGN = 1, //! align under the open brace/parenthesis - IGNORE = -1, //! preserve original indentation -}; - - -void align_to_column(Chunk *pc, size_t column) -{ - LOG_FUNC_ENTRY(); - - if ( pc->IsNullChunk() - || column == pc->GetColumn()) - { - return; - } - LOG_FMT(LINDLINE, "%s(%d): orig line is %zu, orig col is %zu, Text() '%s', type is %s => column is %zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetColumn(), pc->Text(), - get_token_name(pc->GetType()), column); - - const int col_delta = column - pc->GetColumn(); - size_t min_col = column; - - pc->SetColumn(column); - - do - { - auto *next = pc->GetNext(); - - if (next->IsNullChunk()) - { - break; - } - const size_t min_delta = space_col_align(pc, next); - min_col += min_delta; - - const auto *prev = pc; - pc = next; - - auto almod = align_mode_e::SHIFT; - - if ( pc->IsComment() - && pc->GetParentType() != CT_COMMENT_EMBED) - { - log_rule_B("indent_relative_single_line_comments"); - almod = ( pc->IsSingleLineComment() - && options::indent_relative_single_line_comments()) - ? align_mode_e::KEEP_REL : align_mode_e::KEEP_ABS; - } - - if (almod == align_mode_e::KEEP_ABS) - { - // Keep same absolute column - pc->SetColumn(max(pc->GetOrigCol(), min_col)); - } - else if (almod == align_mode_e::KEEP_REL) - { - // Keep same relative column - size_t orig_delta = pc->GetOrigPrevSp() + prev->Len(); - orig_delta = max<size_t>(orig_delta, min_delta); // keeps orig_delta positive - - pc->SetColumn(prev->GetColumn() + orig_delta); - } - else // SHIFT - { - // Shift by the same amount, keep above negative values - pc->SetColumn(( col_delta >= 0 - || (size_t)(abs(col_delta)) < pc->GetColumn()) - ? pc->GetColumn() + col_delta : 0); - pc->SetColumn(max(pc->GetColumn(), min_col)); - } - LOG_FMT(LINDLINED, "%s(%d): %s set column of '%s', type is %s, orig line is %zu, to col %zu (orig col was %zu)\n", - __func__, __LINE__, - (almod == align_mode_e::KEEP_ABS) ? "abs" : - (almod == align_mode_e::KEEP_REL) ? "rel" : "sft", - pc->Text(), get_token_name(pc->GetType()), pc->GetOrigLine(), pc->GetColumn(), pc->GetOrigCol()); - } while ( pc->IsNotNullChunk() - && pc->GetNlCount() == 0); -} // align_to_column - - -void reindent_line(Chunk *pc, size_t column) -{ - LOG_FUNC_ENTRY(); - char copy[1000]; - - LOG_FMT(LINDLINE, "%s(%d): orig line is %zu, orig col is %zu, on '%s' [%s/%s] => %zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->ElidedText(copy), - get_token_name(pc->GetType()), get_token_name(pc->GetParentType()), - column); - log_func_stack_inline(LINDLINE); - - if (column == pc->GetColumn()) - { - return; - } - int col_delta = column - pc->GetColumn(); - size_t min_col = column; - - pc->SetColumn(column); - - do - { - if (QT_SIGNAL_SLOT_found) - { - // fix the bug #654 - // connect(&mapper, SIGNAL(mapped(QString &)), this, SLOT(onSomeEvent(QString &))); - // look for end of SIGNAL/SLOT block - if (!pc->TestFlags(PCF_IN_QT_MACRO)) - { - LOG_FMT(LINDLINE, "FLAGS is NOT set: PCF_IN_QT_MACRO\n"); - restore_options_for_QT(); - } - } - else - { - // look for begin of SIGNAL/SLOT block - if (pc->TestFlags(PCF_IN_QT_MACRO)) - { - LOG_FMT(LINDLINE, "FLAGS is set: PCF_IN_QT_MACRO\n"); - save_set_options_for_QT(pc->GetLevel()); - } - } - Chunk *next = pc->GetNext(); - - if (next->IsNullChunk()) - { - break; - } - - if (pc->GetNlCount()) - { - min_col = 0; - col_delta = 0; - } - min_col += space_col_align(pc, next); - pc = next; - - const bool is_comment = pc->IsComment(); - log_rule_B("indent_relative_single_line_comments"); - const bool keep = ( is_comment - && pc->IsSingleLineComment() - && options::indent_relative_single_line_comments()); - - if ( is_comment - && pc->GetParentType() != CT_COMMENT_EMBED - && !keep) - { - pc->SetColumn(max(pc->GetOrigCol(), min_col)); - LOG_FMT(LINDLINE, "%s(%d): set comment on line %zu to col %zu (orig %zu)\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetColumn(), pc->GetOrigCol()); - } - else - { - pc->SetColumn(max(pc->GetColumn() + col_delta, min_col)); - - LOG_FMT(LINDLINED, "%s(%d): set column of ", __func__, __LINE__); - - if (pc->Is(CT_NEWLINE)) - { - LOG_FMT(LINDLINED, "<Newline>"); - } - else - { - LOG_FMT(LINDLINED, "'%s'", pc->Text()); - } - LOG_FMT(LINDLINED, " to %zu (orig %zu/%zu)\n", pc->GetColumn(), pc->GetOrigLine(), pc->GetOrigCol()); - } - } while ( pc->IsNotNullChunk() - && pc->GetNlCount() == 0); -} // reindent_line - - -static size_t token_indent(E_Token type) -{ - switch (type) - { - case CT_IF: - case CT_DO: - return(3); - - case CT_FOR: - case CT_ELSE: // wacky, but that's what is wanted - return(4); - - case CT_WHILE: - case CT_USING_STMT: - return(6); - - case CT_SWITCH: - return(7); - - case CT_ELSEIF: - return(8); - - case CT_SYNCHRONIZED: - return(13); - - default: - return(0); - } -} - - -#define indent_column_set(X) \ - do { \ - LOG_FMT(LINDENT2, "%s(%d): orig line is %zu, indent_column changed from %zu to %zu\n", \ - __func__, __LINE__, pc->GetOrigLine(), indent_column, (size_t)X); \ - indent_column = (X); \ - } while (false) - - -static size_t get_indent_first_continue(Chunk *pc) -{ - log_rule_B("indent_ignore_first_continue"); - Chunk *continuation = pc->GetNextType(CT_NEWLINE, pc->GetLevel()); - - if (continuation->IsNotNullChunk()) - { - continuation = continuation->GetNext(); - - if (continuation->IsNotNullChunk()) - { - return(continuation->GetOrigCol()); - } - } - return(0); -} - - -static size_t calc_indent_continue(const ParsingFrame &frm, size_t pse_tos) -{ - log_rule_B("indent_continue"); - const int ic = options::indent_continue(); - - if ( ic < 0 - && frm.at(pse_tos).GetIndentContinue()) - { - return(frm.at(pse_tos).GetIndent()); - } - return(frm.at(pse_tos).GetIndent() + abs(ic)); -} - - -static size_t calc_indent_continue(const ParsingFrame &frm) -{ - return(calc_indent_continue(frm, frm.size() - 1)); -} - - -static Chunk *candidate_chunk_first_on_line(Chunk *pc) -{ - Chunk *first = pc->GetFirstChunkOnLine(); - - log_rule_B("indent_inside_ternary_operator"); - - if ( options::indent_inside_ternary_operator() - && ( first->Is(CT_QUESTION) - || first->Is(CT_COND_COLON))) - { - return(first->GetNextNcNnl()); - } - else - { - return(first); - } -} - - -static Chunk *oc_msg_block_indent(Chunk *pc, bool from_brace, - bool from_caret, bool from_colon, - bool from_keyword) -{ - LOG_FUNC_ENTRY(); - Chunk *tmp = pc->GetPrevNc(); - - if (from_brace) - { - return(pc); - } - - // Skip to open paren in ':^TYPE *(ARGS) {' - if (tmp->IsParenClose()) - { - tmp = tmp->GetOpeningParen()->GetPrevNc(); - } - - // // Check for star in ':^TYPE *(ARGS) {'. Issue 2477 - if (tmp->Is(CT_PTR_TYPE)) - { - tmp = tmp->GetPrevNc(); - } - - // Check for type in ':^TYPE *(ARGS) {'. Issue 2482 - if (tmp->Is(CT_TYPE)) - { - tmp = tmp->GetPrevNc(); - } - // Check for caret in ':^TYPE *(ARGS) {' - // Store the caret position - Chunk *caret_tmp = Chunk::NullChunkPtr; - - if ( tmp->IsNotNullChunk() - && tmp->GetType() == CT_OC_BLOCK_CARET) - { - caret_tmp = tmp; - } - else - { - caret_tmp = tmp->GetPrevType(CT_OC_BLOCK_CARET); - tmp = caret_tmp; - } - - // If we still cannot find caret then return first chunk on the line - if ( tmp->IsNullChunk() - || tmp->IsNot(CT_OC_BLOCK_CARET)) - { - return(candidate_chunk_first_on_line(pc)); - } - - if (from_caret) - { - return(tmp); - } - tmp = tmp->GetPrevNc(); - - // Check for colon in ':^TYPE *(ARGS) {' - if (from_colon) - { - if ( tmp->IsNullChunk() - || tmp->IsNot(CT_OC_COLON)) - { - return(candidate_chunk_first_on_line(pc)); - } - else - { - return(tmp); - } - } - tmp = tmp->GetPrevNc(); - - if (from_keyword) - { - if ( tmp->IsNullChunk() - || ( tmp->IsNot(CT_OC_MSG_NAME) - && tmp->IsNot(CT_OC_MSG_FUNC))) - { - return(candidate_chunk_first_on_line(pc)); - } - else - { - return(tmp); - } - } - // In almost all the cases, its better to return the first chunk on the line than not indenting at all. - tmp = candidate_chunk_first_on_line(pc); - return(tmp); -} // oc_msg_block_indent - - -#define log_indent() \ - do { _log_indent(__func__, __LINE__, frm); \ - } while (false) - - -static void _log_indent(const char *func, const uint32_t line, const ParsingFrame &frm) -{ - LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos is %zu, ...indent is %zu\n", - func, line, frm.size() - 1, frm.top().GetIndent()); -} - - -#define log_prev_indent() \ - do { _log_prev_indent(__func__, __LINE__, frm); \ - } while (false) - - -static void _log_prev_indent(const char *func, const uint32_t line, const ParsingFrame &frm) -{ - LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos is %zu, prev....indent is %zu\n", - func, line, frm.size() - 1, frm.prev().GetIndent()); -} - - -#define log_indent_tmp() \ - do { _log_indent_tmp(__func__, __LINE__, frm); \ - } while (false) - - -static void _log_indent_tmp(const char *func, const uint32_t line, const ParsingFrame &frm) -{ - LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos is %zu, ...indent_tmp is %zu\n", - func, line, frm.size() - 1, frm.top().GetIndentTmp()); -} - - -static void quick_indent_again() -{ - LOG_FUNC_ENTRY(); - - for (Chunk *pc = Chunk::GetHead(); pc->IsNotNullChunk(); pc = pc->GetNext()) - { - if (pc->GetIndentData().ref == nullptr) - { - continue; - } - Chunk *tmp = pc->GetPrev(); - - if (!tmp->IsNewline()) - { - continue; - } - const size_t col = pc->GetIndentData().ref->GetColumn() + pc->GetIndentData().delta; - indent_to_column(pc, col); - - LOG_FMT(LINDENTAG, "%s(%d): [%zu] indent [%s] to %zu based on [%s] @ %zu:%zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->Text(), col, - pc->GetIndentData().ref->Text(), pc->GetIndentData().ref->GetOrigLine(), - pc->GetIndentData().ref->GetColumn()); - } -} - - -void indent_text() -{ - LOG_FUNC_ENTRY(); - bool did_newline = true; - size_t vardefcol = 0; - - log_rule_B("indent_columns"); - const size_t indent_size = options::indent_columns(); - size_t indent_column = 0; - int xml_indent = 0; - size_t sql_col = 0; - size_t sql_orig_col = 0; - bool in_func_def = false; - - - ParsingFrameStack frames; - ParsingFrame frm; - - - Chunk *pc = Chunk::GetHead(); - bool classFound = false; // Issue #672 - - while (pc->IsNotNullChunk()) - { - LOG_CHUNK(LINDLINE, pc); - - // Mark continuation lines if absolute indentation is requested - if ( options::indent_continue() < 0 - && ( pc->Is(CT_PAREN_OPEN) - || pc->Is(CT_LPAREN_OPEN) - || pc->Is(CT_SPAREN_OPEN) - || pc->Is(CT_FPAREN_OPEN) - || pc->Is(CT_RPAREN_OPEN) - || pc->Is(CT_SQUARE_OPEN) - || pc->Is(CT_ANGLE_OPEN))) - { - Chunk *next = pc->GetNext(); - - if (next->IsNewline()) - { - while (next->IsNewline()) - { - next = next->GetNext(); - } - - if ( next->IsNotNullChunk() - && !next->IsPreproc()) - { - // Mark chunk as continuation line, so indentation can be - // correctly set over multiple passes - next->SetFlagBits(PCF_CONT_LINE); - - // Mark open and close parens as continuation line chunks. - // This will prevent an additional level and frame to be - // added to the current frame stack (issue 3105). - LOG_FMT(LSPLIT, "%s(%d): set PCF_LINE_CONT for pc text '%s', orig line is %zu, orig col is %zu\n", - __func__, __LINE__, pc->Text(), pc->GetOrigLine(), pc->GetOrigCol()); - - pc->SetFlagBits(PCF_CONT_LINE); - Chunk *closing_paren = pc->GetClosingParen(); - - if (closing_paren->IsNotNullChunk()) - { - closing_paren->SetFlagBits(PCF_CONT_LINE); - } - } - } - } - // forces string literal to column-1 [Fix for 1246] - log_rule_B("indent_col1_multi_string_literal"); - - if ( (pc->GetType() == CT_STRING_MULTI) - && !(cpd.lang_flags & LANG_OC) // Issue #1795 - && options::indent_col1_multi_string_literal()) - { - string str = pc->Text(); - - if ( (str[0] == '@') - && (pc->GetPrev()->GetType() == CT_NEWLINE)) - { - indent_column_set(1); - reindent_line(pc, indent_column); - pc = pc->GetNext(); - did_newline = false; - } - } - - if (pc->Is(CT_NEWLINE)) - { - LOG_FMT(LINDLINE, "%s(%d): orig line is %zu, <Newline>\n", - __func__, __LINE__, pc->GetOrigLine()); - } - else if (pc->Is(CT_NL_CONT)) - { - LOG_FMT(LINDLINE, "%s(%d): orig line is %zu, CT_NL_CONT\n", - __func__, __LINE__, pc->GetOrigLine()); - } - else - { - char copy[1000]; - LOG_FMT(LINDLINE, "%s(%d): orig line is %zu, orig col is %zu, column is %zu, for '%s'\n ", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->GetColumn(), pc->ElidedText(copy)); - log_pcf_flags(LINDLINE, pc->GetFlags()); - } - log_rule_B("use_options_overriding_for_qt_macros"); - - if ( options::use_options_overriding_for_qt_macros() - && ( strcmp(pc->Text(), "SIGNAL") == 0 - || strcmp(pc->Text(), "SLOT") == 0)) - { - LOG_FMT(LINDLINE, "%s(%d): orig line=%zu: type %s SIGNAL/SLOT found\n", - __func__, __LINE__, pc->GetOrigLine(), get_token_name(pc->GetType())); - } - // Handle preprocessor transitions - log_rule_B("indent_brace_parent"); - const size_t parent_token_indent = (options::indent_brace_parent()) - ? token_indent(pc->GetParentType()) : 0; - - // Handle "force indentation of function definition to start in column 1" - log_rule_B("indent_func_def_force_col1"); - - if (options::indent_func_def_force_col1()) - { - if (!in_func_def) - { - Chunk *next = pc->GetNextNcNnl(); - - if ( pc->GetParentType() == CT_FUNC_DEF - || ( pc->Is(CT_COMMENT) - && next->IsNotNullChunk() - && next->GetParentType() == CT_FUNC_DEF)) - { - in_func_def = true; - frm.push(pc, __func__, __LINE__); - frm.top().SetIndentTmp(1); - frm.top().SetIndent(1); - frm.top().SetIndentTab(1); - } - } - else - { - Chunk *prev = pc->GetPrev(); - - if ( prev->Is(CT_BRACE_CLOSE) - && prev->GetParentType() == CT_FUNC_DEF) - { - in_func_def = false; - LOG_FMT(LINDLINE, "%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); - } - } - } - // Clean up after a #define, etc - const bool in_preproc = pc->TestFlags(PCF_IN_PREPROC); - - if (!in_preproc) - { - while ( !frm.empty() - && frm.top().GetInPreproc()) - { - const E_Token type = frm.top().GetOpenToken(); - LOG_FMT(LINDLINE, "%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); - - /* - * If we just removed an #endregion, then check to see if a - * PP_REGION_INDENT entry is right below it - */ - if ( type == CT_PP_ENDREGION - && frm.top().GetOpenToken() == CT_PP_REGION_INDENT) - { - LOG_FMT(LINDLINE, "%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); - } - } - } - else if (pc->Is(CT_PREPROC)) // # - { - // Close out PP_IF_INDENT before playing with the parse frames - if ( frm.top().GetOpenToken() == CT_PP_IF_INDENT - && ( pc->GetParentType() == CT_PP_ENDIF - || pc->GetParentType() == CT_PP_ELSE)) - { - LOG_FMT(LINDLINE, "%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); - } - ParsingFrame frmbkup = frm; - frames.check(frm, cpd.pp_level, pc); - - // Indent the body of a #region here - log_rule_B("pp_region_indent_code"); - - if ( options::pp_region_indent_code() - && pc->GetParentType() == CT_PP_REGION) - { - Chunk *next = pc->GetNext(); - - if (next->IsNullChunk()) - { - break; - } - // Hack to get the logs to look right - next->SetType(CT_PP_REGION_INDENT); - frm.push(next, __func__, __LINE__); - next->SetType(CT_PP_REGION); - - // Indent one level - frm.top().SetIndent(frm.prev().GetIndent() + indent_size); - log_indent(); - - frm.top().SetIndentTab(frm.prev().GetIndentTab() + indent_size); - frm.top().SetIndentTmp(frm.top().GetIndent()); - frm.top().SetInPreproc(false); - log_indent_tmp(); - } - // If option set, remove indent inside switch statement - log_rule_B("indent_switch_pp"); - - if ( frm.top().GetOpenToken() == CT_CASE - && !options::indent_switch_pp()) - { - frm.push(pc, __func__, __LINE__); - LOG_FMT(LINDPC, "%s(%d): frm.top().indent is %zu, indent_size is %zu\n", - __func__, __LINE__, frm.top().GetIndent(), indent_size); - - if (frm.top().GetIndent() >= indent_size) - { - frm.prev().SetIndent(frm.top().GetIndent() - indent_size); - } - log_prev_indent(); - } - // Indent the body of a #if here - log_rule_B("pp_if_indent_code"); - - if ( options::pp_if_indent_code() - && ( pc->GetParentType() == CT_PP_IF - || pc->GetParentType() == CT_PP_ELSE)) - { - Chunk *next = pc->GetNext(); - - if (next->IsNullChunk()) - { - break; - } - int should_indent_preproc = true; - int should_ignore_preproc = false; - Chunk *preproc_next = pc->GetNextNl(); - preproc_next = preproc_next->GetNextNcNnlNet(); - - /* Look ahead at what's on the line after the #if */ - log_rule_B("pp_indent_brace"); - log_rule_B("pp_indent_func_def"); - log_rule_B("pp_indent_case"); - log_rule_B("pp_indent_extern"); - - while ( preproc_next->IsNotNullChunk() - && preproc_next->IsNot(CT_NEWLINE)) - { - if ( (preproc_next->Is(CT_BRACE_OPEN)) - || (preproc_next->Is(CT_BRACE_CLOSE))) - { - if (options::pp_indent_brace() == 0) - { - should_indent_preproc = false; - break; - } - else if (options::pp_indent_brace() == -1) - { - should_ignore_preproc = true; - break; - } - } - else if ( ( preproc_next->Is(CT_FUNC_DEF) - && !options::pp_indent_func_def()) - || ( preproc_next->Is(CT_CASE) - && !options::pp_indent_case()) - || ( preproc_next->Is(CT_EXTERN) - && !options::pp_indent_extern())) - { - should_indent_preproc = false; - break; - } - preproc_next = preproc_next->GetNext(); - } - - if (should_indent_preproc) - { - // Hack to get the logs to look right - - const E_Token memtype = next->GetType(); - next->SetType(CT_PP_IF_INDENT); - frm.push(next, __func__, __LINE__); - next->SetType(memtype); - - if (should_ignore_preproc) - { - // Preserve original indentation - frm.top().SetIndent(pc->GetNextNl()->GetNext()->GetOrigCol()); - log_indent(); - } - else - { - // Indent one level except if the #if is a #include guard - size_t extra = ( pc->GetPpLevel() == 0 - && ifdef_over_whole_file()) - ? 0 : indent_size; - - frm.top().SetIndent(frm.prev().GetIndent() + extra); - log_indent(); - - frm.top().SetIndentTab(frm.prev().GetIndentTab() + extra); - } - frm.top().SetIndentTmp(frm.top().GetIndent()); - frm.top().SetInPreproc(false); - log_indent_tmp(); - } - } - log_rule_B("indent_member_single"); - - if (options::indent_member_single()) - { - if (pc->GetParentType() == CT_PP_IF) - { - // do nothing - } - else if (pc->GetParentType() == CT_PP_ELSE) - { - if ( frm.top().GetOpenToken() == CT_MEMBER - && frm.top().GetPopChunk()->IsNotNullChunk() - && frm.top().GetOpenChunk() != frmbkup.top().GetOpenChunk()) - { - Chunk *tmp = pc->GetNextNcNnlNpp(); - - if (tmp->IsNotNullChunk()) - { - if ( tmp->Is(CT_WORD) - || tmp->Is(CT_TYPE)) - { - tmp = pc->GetNextNcNnlNpp(); - } - else if ( tmp->Is(CT_FUNC_CALL) - || tmp->Is(CT_FPAREN_OPEN)) - { - tmp = tmp->GetNextType(CT_FPAREN_CLOSE, tmp->GetLevel()); - - if (tmp->IsNotNullChunk()) - { - tmp = pc->GetNextNcNnlNpp(); - } - } - - if (tmp->IsNotNullChunk()) - { - frm.top().SetPopChunk(tmp); - } - } - } - } - else if (pc->GetParentType() == CT_PP_ENDIF) - { - if ( frmbkup.top().GetOpenToken() == CT_MEMBER - && frm.top().GetOpenToken() == CT_MEMBER) - { - frm.top().SetPopChunk(frmbkup.top().GetPopChunk()); - } - } - } - // Transition into a preproc by creating a dummy indent - Chunk *pp_next = pc->GetNext(); - - if (pp_next->IsNullChunk()) - { - return; - } - frm.push(pp_next, __func__, __LINE__); - - if ( pc->GetParentType() == CT_PP_DEFINE - || pc->GetParentType() == CT_PP_UNDEF) - { - log_rule_B("pp_define_at_level"); - frm.top().SetIndentTmp(options::pp_define_at_level() - ? frm.prev().GetIndentTmp() : 1); - - log_rule_B("pp_multiline_define_body_indent"); - - if (options::pp_multiline_define_body_indent() < 0) - { - frm.top().SetIndent(-options::pp_multiline_define_body_indent()); - } - else - { - frm.top().SetIndent(pc->GetColumn() + options::pp_multiline_define_body_indent()); - } - log_indent(); - - frm.top().SetIndentTab(frm.top().GetIndent()); - log_indent_tmp(); - } - else if ( ( pc->GetParentType() == CT_PP_PRAGMA - || pc->GetParentType() == CT_PP_OTHER) - && options::pp_define_at_level()) - { - log_rule_B("pp_define_at_level"); - frm.top().SetIndentTmp(frm.prev().GetIndentTmp()); - frm.top().SetIndent(frm.top().GetIndentTmp() + indent_size); - log_indent(); - - frm.top().SetIndentTab(frm.top().GetIndent()); - log_indent_tmp(); - } - else if ( pc->GetParentType() == CT_PP_INCLUDE - && options::pp_include_at_level()) - { - log_rule_B("pp_include_at_level"); - frm.top().SetIndentTmp(frm.prev().GetIndentTmp()); - frm.top().SetIndent(frm.top().GetIndentTmp() + indent_size); - log_indent(); - - frm.top().SetIndentTab(frm.top().GetIndent()); - log_indent_tmp(); - } - else - { - if ( (frm.prev().GetOpenToken() == CT_PP_REGION_INDENT) - || ( (frm.prev().GetOpenToken() == CT_PP_IF_INDENT) - && (frm.top().GetOpenToken() != CT_PP_ENDIF))) - { - frm.top().SetIndent(frm.prev(2).GetIndent()); - log_indent(); - } - else - { - frm.top().SetIndent(frm.prev().GetIndent()); - log_indent(); - } - log_indent(); - - - int val = 0; - - if ( pc->GetParentType() == CT_PP_REGION - || pc->GetParentType() == CT_PP_ENDREGION) - { - log_rule_B("pp_indent_region"); - val = options::pp_indent_region(); - log_indent(); - } - else if ( pc->GetParentType() == CT_PP_IF - || pc->GetParentType() == CT_PP_ELSE - || pc->GetParentType() == CT_PP_ENDIF) - { - log_rule_B("pp_indent_if"); - val = options::pp_indent_if(); - log_indent(); - } - - if (val != 0) - { - size_t indent = frm.top().GetIndent(); - indent = (val > 0) ? val // reassign if positive val, - : ((size_t)(abs(val)) < indent) // else if no underflow - ? (indent + val) : 0; // reduce, else 0 - frm.top().SetIndent(indent); - } - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - } - } - // Check for close XML tags "</..." - log_rule_B("indent_xml_string"); - - if (options::indent_xml_string() > 0) - { - if (pc->Is(CT_STRING)) - { - if ( pc->Len() > 4 - && xml_indent > 0 - && pc->GetStr()[1] == '<' - && pc->GetStr()[2] == '/') - { - log_rule_B("indent_xml_string"); - xml_indent -= options::indent_xml_string(); - } - } - else if (!pc->IsCommentOrNewline()) - { - xml_indent = 0; - } - } - // Handle non-brace closures - log_indent_tmp(); - - bool token_used = false; - size_t old_frm_size; - - do - { - old_frm_size = frm.size(); - - // End anything that drops a level - if ( !pc->IsCommentOrNewline() - && frm.top().GetOpenLevel() > pc->GetLevel()) - { - LOG_FMT(LINDLINE, "%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); - } - - if (frm.top().GetOpenLevel() >= pc->GetLevel()) - { - // process virtual braces closes (no text output) - if ( pc->Is(CT_VBRACE_CLOSE) - && frm.top().GetOpenToken() == CT_VBRACE_OPEN) - { - LOG_FMT(LINDLINE, "%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); - pc = pc->GetNext(); - LOG_FMT(LINDLINE, "%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())); - - if (pc->IsNullChunk()) - { - // need to break out of both the do and while loops - goto null_pc; - } - } - - if ( pc->Is(CT_BRACE_CLOSE) - && pc->GetParentType() == CT_ENUM) - { - Chunk *prev_ncnl = pc->GetPrevNcNnl(); - LOG_FMT(LINDLINE, "%s(%d): prev_ncnl is '%s', orig line is %zu, orig col is %zu\n", - __func__, __LINE__, prev_ncnl->Text(), prev_ncnl->GetOrigLine(), prev_ncnl->GetOrigCol()); - - if (prev_ncnl->Is(CT_COMMA)) - { - LOG_FMT(LINDLINE, "%s(%d): prev_ncnl is comma\n", __func__, __LINE__); - } - else - { - LOG_FMT(LINDLINE, "%s(%d): prev_ncnl is NOT comma\n", __func__, __LINE__); - } - } - - // End any assign operations with a semicolon on the same level - if (is_end_of_assignment(pc, frm)) - { - LOG_FMT(LINDLINE, "%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); - } - // Pop Colon from stack in ternary operator - // a - // ? b - // : e/*top*/;/*pc*/ - log_rule_B("indent_inside_ternary_operator"); - - if ( options::indent_inside_ternary_operator() - && (frm.top().GetOpenToken() == CT_COND_COLON) - && ( pc->IsSemicolon() - || pc->Is(CT_COMMA) - || pc->Is(CT_OC_MSG_NAME) - || pc->Is(CT_SPAREN_CLOSE))) // Issue #1130, #1715 - { - LOG_FMT(LINDLINE, "%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); - } - - // End any assign operations with a semicolon on the same level - if ( pc->IsSemicolon() - && ( (frm.top().GetOpenToken() == CT_IMPORT) - || (frm.top().GetOpenToken() == CT_USING))) - { - LOG_FMT(LINDLINE, "%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); - } - - // End any custom macro-based open/closes - if ( !token_used - && (frm.top().GetOpenToken() == CT_MACRO_OPEN) - && pc->Is(CT_MACRO_CLOSE)) - { - token_used = true; - LOG_FMT(LINDLINE, "%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); - } - - // End any CPP/ObjC class colon stuff - if ( ( (frm.top().GetOpenToken() == CT_CLASS_COLON) - || (frm.top().GetOpenToken() == CT_CONSTR_COLON)) - && ( pc->Is(CT_BRACE_OPEN) - || pc->Is(CT_OC_END) - || pc->Is(CT_OC_SCOPE) - || pc->Is(CT_OC_PROPERTY) - || pc->Is(CT_TYPEDEF) // Issue #2675 - || pc->Is(CT_MACRO_OPEN) - || pc->Is(CT_MACRO_CLOSE) - || ( language_is_set(LANG_OC) - && pc->IsComment() - && pc->GetParentType() == CT_COMMENT_WHOLE) // Issue #2675 - || pc->IsSemicolon())) - { - LOG_FMT(LINDLINE, "%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); - } - - // End ObjC class colon stuff inside of generic definition (like Test<T1: id<T3>>) - if ( (frm.top().GetOpenToken() == CT_CLASS_COLON) - && pc->Is(CT_ANGLE_CLOSE) - && pc->GetParentType() == CT_OC_GENERIC_SPEC) - { - LOG_FMT(LINDLINE, "%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); - } - - // End Objc nested message and boxed array - // TODO: ideally formatting would know which opens occurred on a line and group closes in the same manor - if ( language_is_set(LANG_OC) - && pc->Is(CT_SQUARE_CLOSE) - && pc->GetParentType() == CT_OC_AT - && frm.top().GetOpenLevel() >= pc->GetLevel()) - { - size_t count = 1; - Chunk *next = pc->GetNextNc(); - - while ( next->IsNotNullChunk() - && ( ( next->Is(CT_BRACE_CLOSE) - && next->GetParentType() == CT_OC_AT) - || ( next->Is(CT_SQUARE_CLOSE) - && next->GetParentType() == CT_OC_AT) - || ( next->Is(CT_SQUARE_CLOSE) - && next->GetParentType() == CT_OC_MSG))) - { - count++; - next = next->GetNextNc(); - } - count = std::min(count, frm.size()); - - if (count > 0) - { - while (count-- > 0) - { - if (frm.top().GetOpenToken() == CT_SQUARE_OPEN) - { - if (frm.GetParenCount() == 0) - { - fprintf(stderr, "%s(%d): frame parenthesis count is ZERO, cannot be decremented, at line %zu, column %zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol()); - log_flush(true); - exit(EX_SOFTWARE); - } - frm.SetParenCount(frm.GetParenCount() - 1); - } - LOG_FMT(LINDLINE, "%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); - } - - if (next->IsNotNullChunk()) - { - // End any assign operations with a semicolon on the same level - if (is_end_of_assignment(next, frm)) - { - LOG_FMT(LINDLINE, "%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); - } - } - // Indent the brace to match outer most brace/square - indent_column_set(frm.top().GetIndentTmp()); - continue; - } - } - - // a case is ended with another case or a close brace - if ( (frm.top().GetOpenToken() == CT_CASE) - && ( pc->Is(CT_BRACE_CLOSE) - || pc->Is(CT_CASE))) - { - LOG_FMT(LINDLINE, "%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); - } - - if (frm.top().GetPopChunk()->IsNotNullChunk()) - { - LOG_FMT(LINDLINE, "%s(%d): pop_pc orig line is %zu, orig col is %zu, Text() is '%s', type is %s\n", - __func__, __LINE__, frm.top().GetPopChunk()->GetOrigLine(), frm.top().GetPopChunk()->GetOrigCol(), - frm.top().GetPopChunk()->Text(), get_token_name(frm.top().GetPopChunk()->GetType())); - } - LOG_FMT(LINDLINE, "%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())); - - if ( (frm.top().GetOpenToken() == CT_MEMBER) - && frm.top().GetPopChunk() == pc) - { - LOG_FMT(LINDLINE, "%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); - } - - if ( (frm.top().GetOpenToken() == CT_LAMBDA) - && ( pc->Is(CT_SEMICOLON) - || pc->Is(CT_COMMA) - || pc->Is(CT_BRACE_OPEN))) - { - LOG_FMT(LINDLINE, "%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); - } - // a class scope is ended with another class scope or a close brace - log_rule_B("indent_access_spec_body"); - - if ( options::indent_access_spec_body() - && (frm.top().GetOpenToken() == CT_ACCESS) - && ( pc->Is(CT_BRACE_CLOSE) - || pc->Is(CT_ACCESS))) - { - LOG_FMT(LINDLINE, "%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); - } - - // return & throw are ended with a semicolon - if ( pc->IsSemicolon() - && ( (frm.top().GetOpenToken() == CT_RETURN) - || (frm.top().GetOpenToken() == CT_THROW))) - { - LOG_FMT(LINDLINE, "%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); - } - - // an OC SCOPE ('-' or '+') ends with a semicolon or brace open - if ( (frm.top().GetOpenToken() == CT_OC_SCOPE) - && ( pc->IsSemicolon() - || pc->Is(CT_BRACE_OPEN))) - { - LOG_FMT(LINDLINE, "%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); - } - - /* - * a typedef and an OC SCOPE ('-' or '+') ends with a semicolon or - * brace open - */ - if ( (frm.top().GetOpenToken() == CT_TYPEDEF) - && ( pc->IsSemicolon() - || pc->IsParenOpen() - || pc->Is(CT_BRACE_OPEN))) - { - LOG_FMT(LINDLINE, "%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); - } - - // an SQL EXEC is ended with a semicolon - if ( (frm.top().GetOpenToken() == CT_SQL_EXEC) - && pc->IsSemicolon()) - { - LOG_FMT(LINDLINE, "%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); - } - - // an CLASS is ended with a semicolon or brace open - if ( (frm.top().GetOpenToken() == CT_CLASS) - && ( pc->Is(CT_CLASS_COLON) - || pc->Is(CT_BRACE_OPEN) - || pc->IsSemicolon())) - { - LOG_FMT(LINDLINE, "%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); - } - log_rule_B("indent_oc_inside_msg_sel"); - - // Pop OC msg selector stack - if ( options::indent_oc_inside_msg_sel() - && (frm.top().GetOpenToken() != CT_SQUARE_OPEN) - && frm.top().GetOpenLevel() >= pc->GetLevel() - && ( pc->Is(CT_OC_MSG_FUNC) - || pc->Is(CT_OC_MSG_NAME))) // Issue #2658 - { - LOG_FMT(LINDLINE, "%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); - } - - // Close out parenthesis and squares - if ( (frm.top().GetOpenToken() == (pc->GetType() - 1)) - && ( pc->Is(CT_PAREN_CLOSE) - || pc->Is(CT_LPAREN_CLOSE) // Issue #3054 - || pc->Is(CT_SPAREN_CLOSE) - || pc->Is(CT_FPAREN_CLOSE) - || pc->Is(CT_RPAREN_CLOSE) // Issue #3914 - || pc->Is(CT_SQUARE_CLOSE) - || pc->Is(CT_ANGLE_CLOSE)) - && ( !pc->TestFlags(PCF_CONT_LINE) - || options::indent_continue() >= 0)) - { - LOG_FMT(LINDLINE, "%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); - - if (frm.GetParenCount() == 0) - { - fprintf(stderr, "%s(%d): frame parenthesis count is ZERO, cannot be decremented, at line %zu, column %zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol()); - log_flush(true); - exit(EX_SOFTWARE); - } - frm.SetParenCount(frm.GetParenCount() - 1); - } - } - } while (old_frm_size > frm.size()); - - // Grab a copy of the current indent - indent_column_set(frm.top().GetIndentTmp()); // Issue #3294 - log_indent_tmp(); - - log_rule_B("indent_single_newlines"); - - if ( pc->Is(CT_NEWLINE) - && options::indent_single_newlines()) - { - pc->SetNlColumn(indent_column); - } - - if ( !pc->IsCommentOrNewline() - && log_sev_on(LINDPC)) - { - LOG_FMT(LINDPC, "%s(%d):\n", __func__, __LINE__); - LOG_FMT(LINDPC, " -=[ pc orig line is %zu, orig col is %zu, Text() is '%s' ]=-, frm.size() is %zu\n", - pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), frm.size()); - - for (size_t ttidx = frm.size() - 1; ttidx > 0; ttidx--) - { - LOG_FMT(LINDPC, " [%zu %zu:%zu '%s' %s/%s tmp=%zu indent=%zu brace indent=%zu indent tab=%zu indent continue=%d level=%zu pc brace level=%zu]\n", - ttidx, - frm.at(ttidx).GetOpenChunk()->GetOrigLine(), - frm.at(ttidx).GetOpenChunk()->GetOrigCol(), - frm.at(ttidx).GetOpenChunk()->Text(), - get_token_name(frm.at(ttidx).GetOpenToken()), - get_token_name(frm.at(ttidx).GetOpenChunk()->GetParentType()), - frm.at(ttidx).GetIndentTmp(), - frm.at(ttidx).GetIndent(), - frm.at(ttidx).GetBraceIndent(), - frm.at(ttidx).GetIndentTab(), - frm.at(ttidx).GetIndentContinue(), - frm.at(ttidx).GetOpenLevel(), - frm.at(ttidx).GetOpenChunk()->GetBraceLevel()); - } - } - char copy[1000]; - LOG_FMT(LINDENT2, "%s(%d): orig line is %zu, orig col is %zu, column is %zu, Text() is '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->GetColumn(), pc->ElidedText(copy)); - - // Issue #672 - if ( pc->Is(CT_BRACE_OPEN) - && classFound) - { - LOG_FMT(LINDENT, "%s(%d): CT_BRACE_OPEN found, CLOSE IT\n", - __func__, __LINE__); - LOG_FMT(LINDLINE, "%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())); - classFound = false; - } - /* - * Handle stuff that can affect the current indent: - * - brace close - * - vbrace open - * - brace open - * - case (immediate) - * - labels (immediate) - * - class colons (immediate) - * - * And some stuff that can't - * - open paren - * - open square - * - assignment - * - return - */ - log_rule_B("indent_braces"); - log_rule_B("indent_braces_no_func"); - log_rule_B("indent_braces_no_class"); - log_rule_B("indent_braces_no_struct"); - const bool brace_indent = ( ( pc->Is(CT_BRACE_CLOSE) - || pc->Is(CT_BRACE_OPEN)) - && options::indent_braces() - && ( !options::indent_braces_no_func() - || pc->GetParentType() != CT_FUNC_DEF) - && ( !options::indent_braces_no_func() - || pc->GetParentType() != CT_FUNC_CLASS_DEF) - && ( !options::indent_braces_no_class() - || pc->GetParentType() != CT_CLASS) - && ( !options::indent_braces_no_struct() - || pc->GetParentType() != CT_STRUCT)); - LOG_FMT(LINDENT, "%s(%d): brace_indent is %s\n", - __func__, __LINE__, brace_indent ? "true" : "false"); - - if (pc->Is(CT_BRACE_CLOSE)) - { - if (language_is_set(LANG_OC)) - { - if ( frm.top().GetOpenToken() == CT_BRACE_OPEN - && frm.top().GetOpenLevel() >= pc->GetLevel()) - { - size_t count = 1; - Chunk *next = pc->GetNextNc(); - - while ( next->IsNotNullChunk() - && ( ( next->Is(CT_BRACE_CLOSE) - && next->GetParentType() == CT_OC_AT) - || ( next->Is(CT_SQUARE_CLOSE) - && next->GetParentType() == CT_OC_AT))) - { - count++; - next = next->GetNextNc(); - } - count = std::min(count, frm.size()); - - // End Objc nested boxed dictionary - // TODO: ideally formatting would know which opens occurred on a line and group closes in the same manor - if ( count > 0 - && pc->Is(CT_BRACE_CLOSE) - && pc->GetParentType() == CT_OC_AT) - { - if (frm.top().GetIndentData().ref) - { - pc->IndentData().ref = frm.top().GetIndentData().ref; - pc->IndentData().delta = 0; - } - - while (count-- > 0) - { - LOG_CHUNK(LINDLINE, pc); - frm.pop(__func__, __LINE__, pc); - } - - if (next->IsNotNullChunk()) - { - // End any assign operations with a semicolon on the same level - if (is_end_of_assignment(next, frm)) - { - LOG_CHUNK(LINDLINE, pc); - frm.pop(__func__, __LINE__, pc); - } - } - - // Indent the brace to match outer most brace/square - if (frm.top().GetIndentContinue()) - { - indent_column_set(frm.top().GetIndentTmp() - indent_size); - } - else - { - indent_column_set(frm.top().GetIndentTmp()); - } - } - else - { - // Indent the brace to match the open brace - indent_column_set(frm.top().GetBraceIndent()); - - if (frm.top().GetIndentData().ref) - { - pc->IndentData().ref = frm.top().GetIndentData().ref; - pc->IndentData().delta = 0; - } - LOG_FMT(LINDLINE, "%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); - } - } - } - else if (frm.top().GetBraceIndent()) // Issue #3421 - { - // Indent the brace to match the open brace - indent_column_set(frm.top().GetBraceIndent()); - - if (frm.top().GetIndentData().ref) - { - pc->IndentData().ref = frm.top().GetIndentData().ref; - pc->IndentData().delta = 0; - } - LOG_FMT(LINDLINE, "%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); - } - } - else if (pc->Is(CT_VBRACE_OPEN)) - { - frm.push(pc, __func__, __LINE__); - - log_rule_B("indent_min_vbrace_open"); - size_t iMinIndent = options::indent_min_vbrace_open(); - - if (indent_size > iMinIndent) - { - iMinIndent = indent_size; - } - size_t iNewIndent = frm.prev().GetIndent() + iMinIndent; - - log_rule_B("indent_vbrace_open_on_tabstop"); - - if (options::indent_vbrace_open_on_tabstop()) - { - iNewIndent = next_tab_column(iNewIndent); - } - frm.top().SetIndent(iNewIndent); - log_indent(); - frm.top().SetIndentTmp(frm.top().GetIndent()); - frm.top().SetIndentTab(frm.top().GetIndent()); - log_indent_tmp(); - - // Always indent on virtual braces - indent_column_set(frm.top().GetIndentTmp()); - } - else if ( pc->Is(CT_BRACE_OPEN) - && pc->GetNext()->IsNot(CT_NAMESPACE)) - { - LOG_FMT(LINDENT2, "%s(%d): orig line is %zu, orig col is %zu, Text() is '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text()); - frm.push(pc, __func__, __LINE__); - - log_rule_B("indent_macro_brace"); - - if ( !options::indent_macro_brace() - && frm.prev().GetOpenToken() == CT_PP_DEFINE - && frm.prev().GetOpenLine() == frm.top().GetOpenLine()) - { - LOG_FMT(LINDENT2, "%s(%d): indent_macro_brace\n", __func__, __LINE__); - } - else if ( options::indent_cpp_lambda_body() - && pc->GetParentType() == CT_CPP_LAMBDA) - { - log_rule_B("indent_cpp_lambda_body"); - frm.top().SetBraceIndent(frm.prev().GetIndent()); - - Chunk *head = frm.top().GetOpenChunk()->GetPrevNcNnlNpp(); - Chunk *tail = Chunk::NullChunkPtr; - Chunk *frm_prev = frm.prev().GetOpenChunk(); - bool enclosure = ( frm_prev->GetParentType() != CT_FUNC_DEF // Issue #3407 - && frm_prev != frm_prev->GetClosingParen()); - bool linematch = true; - - for (auto it = frm.rbegin(); it != frm.rend() && tail->IsNullChunk(); ++it) - { - if (it->GetOpenChunk() != frm.top().GetOpenChunk()) - { - linematch &= it->GetOpenChunk()->IsOnSameLine(head); - } - Chunk *match = it->GetOpenChunk()->GetClosingParen(); - - if (match->IsNullChunk()) - { - continue; - } - Chunk *target = match->GetNextNcNnlNpp(); - - while ( tail->IsNullChunk() - && target->IsNotNullChunk()) - { - if ( target->IsSemicolon() - && target->GetLevel() == match->GetLevel()) - { - tail = target; - } - else if (target->GetLevel() < match->GetLevel()) - { - break; - } - else - { - target = target->GetNextNcNnlNpp(); - } - } - } - - bool toplevel = true; - - for (auto it = frm.rbegin(); it != frm.rend() && tail->IsNotNullChunk(); ++it) - { - if (!it->GetOpenChunk()->Is(CT_FPAREN_OPEN)) - { - continue; - } - - if (it->GetOpenChunk()->GetLevel() < tail->GetLevel()) - { - toplevel = false; - break; - } - } - - // A few things to check: - // 1. The matching brace is on the same line as the ending semicolon - // 2a. If it's an assignment, check that both sides of the assignment operator are on the same line - // 2b. If it's inside some closure, check that all the frames are on the same line, - // and it is in the top level closure, and indent_continue is non-zero - bool sameLine = frm.top().GetOpenChunk()->GetClosingParen()->IsOnSameLine(tail); - - bool isAssignSameLine = - !enclosure - && options::align_assign_span() == 0 - && !options::indent_align_assign() - && frm.prev().GetOpenChunk()->GetPrevNcNnlNpp()->IsOnSameLine(frm.prev().GetOpenChunk()) - && frm.prev().GetOpenChunk()->IsOnSameLine(frm.prev().GetOpenChunk()->GetNextNcNnlNpp()); - - bool closureSameLineTopLevel = - (options::indent_continue() > 0) - && enclosure - && linematch - && toplevel - && frm.top().GetOpenChunk()->GetClosingParen()->IsOnSameLine(frm.top().GetOpenChunk()); - - if ( sameLine - && ( (isAssignSameLine) - || (closureSameLineTopLevel))) - { - if (indent_size > frm.top().GetBraceIndent()) // if options::indent_indent_columns() is too big - { - frm.top().SetBraceIndent(1); - } - else - { - frm.top().SetBraceIndent(frm.top().GetBraceIndent() - indent_size); - } - } - indent_column_set(frm.top().GetBraceIndent()); - frm.top().SetIndent(indent_column + indent_size); - log_indent(); - - frm.top().SetIndentTab(frm.top().GetIndent()); - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - - frm.prev().SetIndentTmp(frm.top().GetIndentTmp()); - log_indent_tmp(); - } - else if ( language_is_set(LANG_CPP) - && options::indent_cpp_lambda_only_once() - && (pc->GetParentType() == CT_CPP_LAMBDA)) - { - // test example cpp:30756 - log_rule_B("indent_cpp_lambda_only_once"); - - size_t namespace_indent_to_ignore = 0; // Issue #1813 - log_rule_B("indent_namespace"); - - if (!options::indent_namespace()) - { - for (auto i = frm.rbegin(); i != frm.rend(); ++i) - { - if (i->GetNsCount()) - { - namespace_indent_to_ignore = i->GetNsCount(); - break; - } - } - } - // Issue # 1296 - frm.top().SetBraceIndent(1 + (pc->GetBraceLevel() - namespace_indent_to_ignore) * indent_size); - indent_column_set(frm.top().GetBraceIndent()); - frm.top().SetIndent(indent_column + indent_size); - log_indent(); - frm.top().SetIndentTab(frm.top().GetIndent()); - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - - frm.prev().SetIndentTmp(frm.top().GetIndentTmp()); - log_indent_tmp(); - } - else if ( language_is_set(LANG_CS | LANG_JAVA) - && options::indent_cs_delegate_brace() - && ( pc->GetParentType() == CT_LAMBDA - || pc->GetParentType() == CT_DELEGATE)) - { - log_rule_B("indent_cs_delegate_brace"); - frm.top().SetBraceIndent(1 + (pc->GetBraceLevel() + 1) * indent_size); - indent_column_set(frm.top().GetBraceIndent()); - frm.top().SetIndent(indent_column + indent_size); - log_indent(); - frm.top().SetIndentTab(frm.top().GetIndent()); - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - - frm.prev().SetIndentTmp(frm.top().GetIndentTmp()); - log_indent_tmp(); - } - else if ( language_is_set(LANG_CS | LANG_JAVA) - && !options::indent_cs_delegate_brace() - && !options::indent_align_paren() - && ( pc->GetParentType() == CT_LAMBDA - || pc->GetParentType() == CT_DELEGATE)) - { - log_rule_B("indent_cs_delegate_brace"); - log_rule_B("indent_align_paren"); - frm.top().SetBraceIndent(frm.prev().GetIndent()); - - // Issue # 1620, UNI-24090.cs - if (frm.prev().GetOpenChunk()->IsOnSameLine(frm.top().GetOpenChunk()->GetPrevNcNnlNpp())) - { - frm.top().SetBraceIndent(frm.top().GetBraceIndent() - indent_size); - } - indent_column_set(frm.top().GetBraceIndent()); - frm.top().SetIndent(indent_column + indent_size); - log_indent(); - frm.top().SetIndentTab(frm.top().GetIndent()); - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - frm.prev().SetIndentTmp(frm.top().GetIndentTmp()); - log_indent_tmp(); - } - else if ( !options::indent_paren_open_brace() - && !language_is_set(LANG_CS) - && pc->GetParentType() == CT_CPP_LAMBDA - && ( pc->TestFlags(PCF_IN_FCN_DEF) - || pc->TestFlags(PCF_IN_FCN_CTOR)) // Issue #2152 - && pc->GetNextNc()->IsNewline()) - { - log_rule_B("indent_paren_open_brace"); - // Issue #1165 - LOG_FMT(LINDENT2, "%s(%d): orig line is %zu, brace level is %zu, for '%s', pc->GetLevel() is %zu, pc(-1)->GetLevel() is %zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetBraceLevel(), pc->Text(), pc->GetLevel(), frm.prev().GetOpenChunk()->GetLevel()); - frm.top().SetBraceIndent(1 + (pc->GetBraceLevel() + 1) * indent_size); - indent_column_set(frm.top().GetBraceIndent()); - frm.top().SetIndent(frm.prev().GetIndentTmp()); - log_indent(); - - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - } - // any '{' that is inside of a '(' overrides the '(' indent - // only to help the vim command } - else if ( !options::indent_paren_open_brace() - && frm.prev().GetOpenChunk()->IsParenOpen() - && pc->GetNextNc()->IsNewline()) - { - log_rule_B("indent_paren_open_brace"); - LOG_FMT(LINDENT2, "%s(%d): orig line is %zu, brace level is %zu, for '%s', pc->GetLevel() is %zu, pc(-1)->GetLevel() is %zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetBraceLevel(), pc->Text(), pc->GetLevel(), frm.prev().GetOpenChunk()->GetLevel()); - // FIXME: I don't know how much of this is necessary, but it seems to work - frm.top().SetBraceIndent(1 + pc->GetBraceLevel() * indent_size); - indent_column_set(frm.top().GetBraceIndent()); - frm.top().SetIndent(indent_column + indent_size); - log_indent(); - - if ( (pc->GetParentType() == CT_OC_BLOCK_EXPR) - && pc->TestFlags(PCF_IN_OC_MSG)) - { - frm.top().SetIndent(frm.prev().GetIndentTmp() + indent_size); - log_indent(); - frm.top().SetBraceIndent(frm.prev().GetIndentTmp()); - indent_column_set(frm.top().GetBraceIndent()); - } - frm.top().SetIndentTab(frm.top().GetIndent()); - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - - frm.prev().SetIndentTmp(frm.top().GetIndentTmp()); - } - else if ( frm.GetParenCount() != 0 - && !pc->TestFlags(PCF_IN_LAMBDA)) // Issue #3761 - { - if (frm.top().GetOpenChunk()->GetParentType() == CT_OC_BLOCK_EXPR) - { - log_rule_B("indent_oc_block_msg"); - - if ( pc->TestFlags(PCF_IN_OC_MSG) - && options::indent_oc_block_msg()) - { - frm.top().IndentData().ref = oc_msg_block_indent(pc, false, false, false, true); - log_rule_B("indent_oc_block_msg"); - frm.top().IndentData().delta = options::indent_oc_block_msg(); - } - log_rule_B("indent_oc_block"); - log_rule_B("indent_oc_block_msg_xcode_style"); - - if ( options::indent_oc_block() - || options::indent_oc_block_msg_xcode_style()) - { - bool in_oc_msg = pc->TestFlags(PCF_IN_OC_MSG); - log_rule_B("indent_oc_block_msg_from_keyword"); - bool indent_from_keyword = options::indent_oc_block_msg_from_keyword() - && in_oc_msg; - log_rule_B("indent_oc_block_msg_from_colon"); - bool indent_from_colon = options::indent_oc_block_msg_from_colon() - && in_oc_msg; - log_rule_B("indent_oc_block_msg_from_caret"); - bool indent_from_caret = options::indent_oc_block_msg_from_caret() - && in_oc_msg; - log_rule_B("indent_oc_block_msg_from_brace"); - bool indent_from_brace = options::indent_oc_block_msg_from_brace() - && in_oc_msg; - - /* - * In "Xcode indent mode", we want to indent: - * - if the colon is aligned (namely, if a newline has been - * added before it), indent_from_brace - * - otherwise, indent from previous block (the "else" statement here) - */ - log_rule_B("indent_oc_block_msg_xcode_style"); - - if (options::indent_oc_block_msg_xcode_style()) - { - Chunk *bbc = pc->GetClosingParen(); // block brace close '}' - Chunk *bbc_next_ncnl = bbc->GetNextNcNnl(); - - if ( bbc_next_ncnl->GetType() == CT_OC_MSG_NAME - || bbc_next_ncnl->GetType() == CT_OC_MSG_FUNC) - { - indent_from_brace = false; - indent_from_colon = false; - indent_from_caret = false; - indent_from_keyword = true; - } - else - { - indent_from_brace = false; - indent_from_colon = false; - indent_from_caret = false; - indent_from_keyword = false; - } - } - Chunk *ref = oc_msg_block_indent(pc, indent_from_brace, - indent_from_caret, - indent_from_colon, - indent_from_keyword); - - if (ref->IsNotNullChunk()) - { - frm.top().SetIndent(indent_size + ref->GetColumn()); - } - else - { - frm.top().SetIndent(1 + ((pc->GetBraceLevel() + 1) * indent_size)); - } - log_indent(); - indent_column_set(frm.top().GetIndent() - indent_size); - } - else - { - frm.top().SetIndent(frm.prev().GetIndentTmp() + indent_size); - log_indent(); - } - } - else if ( frm.top().GetOpenChunk()->GetType() == CT_BRACE_OPEN - && frm.top().GetOpenChunk()->GetParentType() == CT_OC_AT) - { - // We are inside @{ ... } -- indent one tab from the paren - if (frm.prev().GetIndentContinue()) - { - frm.top().SetIndent(frm.prev().GetIndentTmp()); - } - else - { - frm.top().SetIndent(frm.prev().GetIndentTmp() + indent_size); - } - log_indent(); - } - // Issue # 1620, UNI-24090.cs - else if ( frm.prev().GetOpenChunk()->IsOnSameLine(frm.top().GetOpenChunk()) - && !options::indent_align_paren() - && frm.prev().GetOpenChunk()->IsParenOpen() - && !pc->TestFlags(PCF_ONE_LINER)) - { - log_rule_B("indent_align_paren"); - // We are inside ({ ... }) -- where { and ( are on the same line, avoiding double indentations. - // only to help the vim command } - frm.top().SetBraceIndent(frm.prev().GetIndent() - indent_size); - indent_column_set(frm.top().GetBraceIndent()); - frm.top().SetIndent(frm.prev().GetIndentTmp()); - log_indent(); - } - else if ( frm.prev().GetOpenChunk()->IsOnSameLine(frm.top().GetOpenChunk()->GetPrevNcNnlNpp()) - && !options::indent_align_paren() - && frm.prev().GetOpenChunk()->IsParenOpen() - && !pc->TestFlags(PCF_ONE_LINER)) - { - log_rule_B("indent_align_paren"); - // We are inside ({ ... }) -- where { and ( are on adjacent lines, avoiding indentation of brace. - // only to help the vim command } - frm.top().SetBraceIndent(frm.prev().GetIndent() - indent_size); - indent_column_set(frm.top().GetBraceIndent()); - frm.top().SetIndent(frm.prev().GetIndentTmp()); - log_indent(); - } - else if ( options::indent_oc_inside_msg_sel() - && ( frm.prev().GetOpenToken() == CT_OC_MSG_FUNC - || frm.prev().GetOpenToken() == CT_OC_MSG_NAME)) // Issue #2658 - { - log_rule_B("indent_oc_inside_msg_sel"); - // [Class Message:{<here> - frm.top().SetIndent(frm.prev().GetOpenChunk()->GetColumn() + indent_size); - log_indent(); - indent_column_set(frm.prev().GetOpenChunk()->GetColumn()); - } - // Issue #3813 - else if (pc->TestFlags(PCF_OC_IN_BLOCK) && pc->GetParentType() == CT_SWITCH) - { - frm.top().SetIndent(frm.prev().GetIndentTmp()); - } - else - { - // We are inside ({ ... }) -- indent one tab from the paren - frm.top().SetIndent(frm.prev().GetIndentTmp() + indent_size); - - if (!frm.prev().GetOpenChunk()->IsParenOpen()) - { - frm.top().SetIndentTab(frm.top().GetIndent()); - } - log_indent(); - } - } - else if ( frm.top().GetOpenChunk()->GetType() == CT_BRACE_OPEN - && frm.top().GetOpenChunk()->GetParentType() == CT_OC_AT) - { - // We are inside @{ ... } -- indent one tab from the paren - if (frm.prev().GetIndentContinue()) - { - frm.top().SetIndent(frm.prev().GetIndentTmp()); - } - else - { - frm.top().SetIndent(frm.prev().GetIndentTmp() + indent_size); - frm.top().SetIndentTab(frm.top().GetIndent()); - } - log_indent(); - } - else if ( ( pc->GetParentType() == CT_BRACED_INIT_LIST - || ( !options::indent_compound_literal_return() - && pc->GetParentType() == CT_C_CAST)) - && frm.prev().GetOpenToken() == CT_RETURN) - { - log_rule_B("indent_compound_literal_return"); - - // we're returning either a c compound literal (CT_C_CAST) or a - // C++11 initialization list (CT_BRACED_INIT_LIST), use indent from the return. - if (frm.prev().GetIndentContinue()) - { - frm.top().SetIndent(frm.prev().GetIndentTmp()); - } - else - { - frm.top().SetIndent(frm.prev().GetIndentTmp() + indent_size); - } - log_indent(); - } - else - { - // Use the prev indent level + indent_size. - if (pc->GetParentType() == CT_SWITCH) - { - frm.top().SetIndent(frm.prev().GetIndent() + options::indent_switch_body()); - } - else - { - frm.top().SetIndent(frm.prev().GetIndent() + indent_size); - } - LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos is %zu, ... indent is %zu\n", - __func__, __LINE__, frm.size() - 1, frm.top().GetIndent()); - LOG_FMT(LINDLINE, "%s(%d): orig line is %zu, orig col is %zu, Text() is '%s', parent type is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text(), - get_token_name(pc->GetParentType())); - - // If this brace is part of a statement, bump it out by indent_brace - if ( pc->GetParentType() == CT_IF - || pc->GetParentType() == CT_ELSE - || pc->GetParentType() == CT_ELSEIF - || pc->GetParentType() == CT_TRY - || pc->GetParentType() == CT_CATCH - || pc->GetParentType() == CT_DO - || pc->GetParentType() == CT_WHILE - || pc->GetParentType() == CT_USING_STMT - || pc->GetParentType() == CT_SWITCH - || pc->GetParentType() == CT_SYNCHRONIZED - || pc->GetParentType() == CT_FOR) - { - if (parent_token_indent != 0) - { - frm.top().SetIndent(frm.top().GetIndent() + parent_token_indent - indent_size); - log_indent(); - } - else - { - log_rule_B("indent_brace"); - frm.top().SetIndent(frm.top().GetIndent() + options::indent_brace()); - log_indent(); - indent_column_set(indent_column + options::indent_brace()); - } - } - else if (pc->GetParentType() == CT_CASE) - { - if (options::indent_ignore_case_brace()) - { - log_rule_B("indent_ignore_case_brace"); - indent_column_set(pc->GetOrigCol()); - } - else - { - log_rule_B("indent_case_brace"); - const auto tmp_indent = static_cast<int>(frm.prev().GetIndent()) - - static_cast<int>(indent_size) - + options::indent_case_brace(); - /* - * An open brace with the parent of case does not indent by default - * options::indent_case_brace() can be used to indent the brace. - * So we need to take the CASE indent, subtract off the - * indent_size that was added above and then add indent_case_brace. - * may take negative value - */ - indent_column_set(max(tmp_indent, 0)); - } - // Stuff inside the brace still needs to be indented - frm.top().SetIndent(indent_column + indent_size); - log_indent(); - - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - } - else if ( pc->GetParentType() == CT_CLASS - && !options::indent_class()) - { - log_rule_B("indent_class"); - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, orig col is %zu, text is %s\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text()); - frm.top().SetIndent(frm.top().GetIndent() - indent_size); - log_indent(); - } - else if (pc->GetParentType() == CT_NAMESPACE) - { - frm.top().SetNsCount(frm.prev().GetNsCount() + 1); - - log_rule_B("indent_namespace"); - log_rule_B("indent_namespace_single_indent"); - - if ( options::indent_namespace() - && options::indent_namespace_single_indent()) - { - if (frm.top().GetNsCount() >= 2) - { - // undo indent on all except the first namespace - frm.top().SetIndent(frm.top().GetIndent() - indent_size); - log_indent(); - } - indent_column_set(frm.prev(frm.top().GetNsCount()).GetIndent()); - } - else if ( options::indent_namespace() - && options::indent_namespace_inner_only()) - { - if (frm.top().GetNsCount() == 1) - { - // undo indent on first namespace only - frm.top().SetIndent(frm.top().GetIndent() - indent_size); - log_indent(); - } - } - else if ( pc->TestFlags(PCF_LONG_BLOCK) - || !options::indent_namespace()) - { - log_rule_B("indent_namespace"); - // don't indent long blocks - frm.top().SetIndent(frm.top().GetIndent() - indent_size); - log_indent(); - } - else // indenting 'short' namespace - { - log_rule_B("indent_namespace_level"); - - if (options::indent_namespace_level() > 0) - { - frm.top().SetIndent(frm.top().GetIndent() - indent_size); - log_indent(); - frm.top().SetIndent(frm.top().GetIndent() + options::indent_namespace_level()); - log_indent(); - } - } - } - else if ( pc->GetParentType() == CT_EXTERN - && !options::indent_extern()) - { - log_rule_B("indent_extern"); - frm.top().SetIndent(frm.top().GetIndent() - indent_size); - log_indent(); - } - frm.top().SetIndentTab(frm.top().GetIndent()); - } - - if (pc->TestFlags(PCF_DONT_INDENT)) - { - frm.top().SetIndent(pc->GetColumn()); - log_indent(); - - indent_column_set(pc->GetColumn()); - } - else - { - /* - * If there isn't a newline between the open brace and the next - * item, just indent to wherever the next token is. - * This covers this sort of stuff: - * { a++; - * b--; }; - */ - Chunk *next = pc->GetNextNcNnl(); - - if (next->IsNullChunk()) - { - break; - } - Chunk *prev = pc->GetPrev(); - - if ( pc->GetParentType() == CT_BRACED_INIT_LIST - && prev->Is(CT_BRACE_OPEN) - && prev->GetParentType() == CT_BRACED_INIT_LIST) - { - indent_column = frm.prev().GetBraceIndent(); - frm.top().SetIndent(frm.prev().GetIndent()); - log_indent(); - } - else if ( !pc->IsNewlineBetween(next) - && next->GetParentType() != CT_BRACED_INIT_LIST - && options::indent_token_after_brace() - && !pc->TestFlags(PCF_ONE_LINER)) // Issue #1108 - { - log_rule_B("indent_token_after_brace"); - frm.top().SetIndent(next->GetColumn()); - log_indent(); - } - frm.top().SetIndentTmp(frm.top().GetIndent()); - frm.top().SetOpenLine(pc->GetOrigLine()); - log_indent_tmp(); - - log_rule_B("Update the indent_column"); - - // Update the indent_column if needed - if ( brace_indent - || parent_token_indent != 0) - { - indent_column_set(frm.top().GetIndentTmp()); - log_indent_tmp(); - } - } - // Save the brace indent - frm.top().SetBraceIndent(indent_column); - } - else if (pc->Is(CT_SQL_END)) - { - if (frm.top().GetOpenToken() == CT_SQL_BEGIN) - { - LOG_FMT(LINDLINE, "%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); - indent_column_set(frm.top().GetIndentTmp()); - log_indent_tmp(); - } - } - else if ( pc->Is(CT_SQL_BEGIN) - || pc->Is(CT_MACRO_OPEN) - || ( pc->Is(CT_CLASS) - && language_is_set(LANG_CS))) // Issue #3536 - { - frm.push(pc, __func__, __LINE__); - - frm.top().SetIndent(frm.prev().GetIndent() + indent_size); - log_indent(); - - frm.top().SetIndentTmp(frm.top().GetIndent()); - frm.top().SetIndentTab(frm.top().GetIndent()); - log_indent_tmp(); - } - else if (pc->Is(CT_SQL_EXEC)) - { - frm.push(pc, __func__, __LINE__); - - frm.top().SetIndent(frm.prev().GetIndent() + indent_size); - log_indent(); - - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - } - else if (pc->Is(CT_MACRO_ELSE)) - { - if (frm.top().GetOpenToken() == CT_MACRO_OPEN) - { - indent_column_set(frm.prev().GetIndent()); - } - } - else if (pc->Is(CT_CASE)) - { - // Start a case - indent options::indent_switch_case() from the switch level - log_rule_B("indent_switch_case"); - const size_t tmp = frm.top().GetIndent() + indent_size - - options::indent_switch_body() - + options::indent_switch_case(); - frm.push(pc, __func__, __LINE__); - - frm.top().SetIndent(tmp); - log_indent(); - - log_rule_B("indent_case_shift"); - frm.top().SetIndentTmp(tmp - indent_size + options::indent_case_shift()); - frm.top().SetIndentTab(tmp); - log_indent_tmp(); - - // Always set on case statements - indent_column_set(frm.top().GetIndentTmp()); - - if (options::indent_case_comment()) - { - // comments before 'case' need to be aligned with the 'case' - Chunk *pct = pc; - - while ( ((pct = pct->GetPrevNnl())->IsNotNullChunk()) - && pct->IsComment()) - { - Chunk *t2 = pct->GetPrev(); - - if (t2->IsNewline()) - { - pct->SetColumn(frm.top().GetIndentTmp()); - pct->SetColumnIndent(pct->GetColumn()); - } - } - } - } - else if (pc->Is(CT_BREAK)) - { - Chunk *prev = pc->GetPrevNcNnl(); - - if ( prev->Is(CT_BRACE_CLOSE) - && prev->GetParentType() == CT_CASE) - { - // issue #663 + issue #1366 - Chunk *prev_prev_newline = pc->GetPrevNl()->GetPrevNl(); - - if (prev_prev_newline->IsNotNullChunk()) - { - // This only affects the 'break', so no need for a stack entry - indent_column_set(prev_prev_newline->GetNext()->GetColumn()); - } - } - } - else if (pc->Is(CT_LABEL)) - { - if (options::indent_ignore_label()) - { - log_rule_B("indent_ignore_label"); - indent_column_set(pc->GetOrigCol()); - } - else - { - log_rule_B("indent_label"); - const int val = options::indent_label(); - size_t pse_indent = frm.top().GetIndent(); - - // Labels get sent to the left or backed up - if (val > 0) - { - indent_column_set(val); - - Chunk *next = pc->GetNext()->GetNext(); // colon + possible statement - - if ( next->IsNotNullChunk() - && !next->IsNewline() - // label (+ 2, because there is colon and space after it) must fit into indent - && (val + pc->Len() + 2 <= pse_indent)) - { - reindent_line(next, pse_indent); - } - } - else - { - bool no_underflow = (size_t)(abs(val)) < pse_indent; - indent_column_set((no_underflow ? (pse_indent + val) : 0)); - } - } - } - else if (pc->Is(CT_ACCESS)) - { - log_rule_B("indent_access_spec_body"); - - if (options::indent_access_spec_body()) - { - const size_t tmp = frm.top().GetIndent() + indent_size; - frm.push(pc, __func__, __LINE__); - - frm.top().SetIndent(tmp); - log_indent(); - - frm.top().SetIndentTmp(tmp - indent_size); - frm.top().SetIndentTab(tmp); - log_indent_tmp(); - - /* - * If we are indenting the body, then we must leave the access spec - * indented at brace level - */ - indent_column_set(frm.top().GetIndentTmp()); - // Issues 1161 + 2704 - // comments before 'access specifier' need to be aligned with the 'access specifier' - // unless it is a Doxygen comment - Chunk *pct = pc; - - while ( ((pct = pct->GetPrevNnl())->IsNotNullChunk()) - && pct->IsComment() - && !pct->IsDoxygenComment()) - { - Chunk *t2 = pct->GetPrev(); - - if (t2->IsNewline()) - { - pct->SetColumn(frm.top().GetIndentTmp()); - pct->SetColumnIndent(pct->GetColumn()); - } - } - } - else - { - // Access spec labels get sent to the left or backed up - log_rule_B("indent_access_spec"); - int val = options::indent_access_spec(); - - if (val > 0) - { - indent_column_set(val); - } - else - { - size_t pse_indent = frm.top().GetIndent(); - bool no_underflow = (size_t)(abs(val)) < pse_indent; - - indent_column_set(no_underflow ? (pse_indent + val) : 0); - } - } - } - else if ( pc->Is(CT_CLASS_COLON) - || pc->Is(CT_CONSTR_COLON)) - { - // just indent one level - frm.push(pc, __func__, __LINE__); - - frm.top().SetIndent(frm.prev().GetIndentTmp() + indent_size); - log_indent(); - - frm.top().SetIndentTmp(frm.top().GetIndent()); - frm.top().SetIndentTab(frm.top().GetIndent()); - log_indent_tmp(); - - if (pc->Is(CT_CLASS_COLON)) - { - if (options::indent_ignore_before_class_colon()) - { - log_rule_B("indent_ignore_before_class_colon"); - frm.top().SetIndentTmp(pc->GetOrigCol()); - log_indent_tmp(); - } - else if (options::indent_before_class_colon() != 0) - { - log_rule_B("indent_before_class_colon"); - frm.top().SetIndentTmp(std::max<ptrdiff_t>(frm.top().GetIndentTmp() + options::indent_before_class_colon(), 0)); - log_indent_tmp(); - } - } - indent_column_set(frm.top().GetIndentTmp()); - - log_rule_B("indent_class_colon"); - - if ( options::indent_class_colon() - && pc->Is(CT_CLASS_COLON)) - { - log_rule_B("indent_class_on_colon"); - - if (options::indent_class_on_colon()) - { - frm.top().SetIndent(pc->GetColumn()); - log_indent(); - } - else - { - Chunk *next = pc->GetNext(); - - if ( next->IsNotNullChunk() - && !next->IsNewline()) - { - frm.top().SetIndent(next->GetColumn()); - log_indent(); - } - } - } - else if (pc->Is(CT_CONSTR_COLON)) - { - if (options::indent_ignore_before_constr_colon()) - { - log_rule_B("indent_ignore_before_constr_colon"); - frm.top().SetIndentTmp(pc->GetOrigCol()); - indent_column_set(frm.top().GetIndentTmp()); - } - - if (options::indent_constr_colon()) - { - log_rule_B("indent_constr_colon"); - Chunk *prev = pc->GetPrev(); - - if (prev->IsNewline()) - { - log_rule_B("indent_ctor_init_following"); - frm.top().SetIndent(frm.top().GetIndent() + options::indent_ctor_init_following()); - log_indent(); - } - // TODO: Create a dedicated indent_constr_on_colon? - log_rule_B("indent_class_on_colon"); - - if (options::indent_ctor_init() != 0) - { - log_rule_B("indent_ctor_init"); - /* - * If the std::max() calls were specialized with size_t (the type of the underlying variable), - * they would never actually do their job, because size_t is unsigned and therefore even - * a "negative" result would be always greater than zero. - * Using ptrdiff_t (a standard signed type of the same size as size_t) in order to avoid that. - */ - frm.top().SetIndent(std::max<ptrdiff_t>(frm.top().GetIndent() + options::indent_ctor_init(), 0)); - log_indent(); - frm.top().SetIndentTmp(std::max<ptrdiff_t>(frm.top().GetIndentTmp() + options::indent_ctor_init(), 0)); - frm.top().SetIndentTab(std::max<ptrdiff_t>(frm.top().GetIndentTab() + options::indent_ctor_init(), 0)); - log_indent_tmp(); - indent_column_set(frm.top().GetIndentTmp()); - } - else if (options::indent_class_on_colon()) - { - frm.top().SetIndent(pc->GetColumn()); - log_indent(); - } - else - { - Chunk *next = pc->GetNext(); - - if ( next->IsNotNullChunk() - && !next->IsNewline()) - { - frm.top().SetIndent(next->GetColumn()); - log_indent(); - } - } - } - } - } - else if ( pc->Is(CT_PAREN_OPEN) - && ( pc->GetParentType() == CT_ASM - || ( pc->GetPrevNcNnl()->IsNotNullChunk() - && pc->GetPrevNcNnl()->GetType() == CT_ASM)) - && options::indent_ignore_asm_block()) - { - log_rule_B("indent_ignore_asm_block"); - Chunk *tmp = pc->GetClosingParen(); - - int move = 0; - - if ( pc->GetPrev()->IsNewline() - && pc->GetColumn() != indent_column) - { - move = indent_column - pc->GetColumn(); - } - else - { - move = pc->GetColumn() - pc->GetOrigCol(); - } - - do - { - if (!pc->TestFlags(PCF_IN_PREPROC)) - { - pc->SetColumn(pc->GetOrigCol() + move); - } - pc = pc->GetNext(); - } while (pc != tmp); - - reindent_line(pc, indent_column); - } - else if ( ( pc->Is(CT_PAREN_OPEN) - || pc->Is(CT_LPAREN_OPEN) // Issue #3054 - || pc->Is(CT_SPAREN_OPEN) - || pc->Is(CT_FPAREN_OPEN) - || pc->Is(CT_RPAREN_OPEN) // Issue #3914 - || pc->Is(CT_SQUARE_OPEN) - || pc->Is(CT_ANGLE_OPEN)) - && ( !pc->TestFlags(PCF_CONT_LINE) - || options::indent_continue() >= 0)) - { - /* - * Open parenthesis and squares - never update indent_column, - * unless right after a newline. - */ - frm.push(pc, __func__, __LINE__); - - if ( pc->GetPrev()->IsNewline() - && pc->GetColumn() != indent_column - && !pc->TestFlags(PCF_DONT_INDENT)) - { - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, indent => %zu, text is '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - frm.top().SetIndent(pc->GetColumn() + pc->Len()); - log_indent(); - - if ( pc->Is(CT_SQUARE_OPEN) - && language_is_set(LANG_D)) - { - frm.top().SetIndentTab(frm.top().GetIndent()); - } - bool skipped = false; - log_rule_B("indent_inside_ternary_operator"); - log_rule_B("indent_align_paren"); - - if ( options::indent_inside_ternary_operator() - && ( pc->Is(CT_FPAREN_OPEN) - || pc->Is(CT_PAREN_OPEN)) - && frm.size() > 2 - && ( frm.prev().GetOpenToken() == CT_QUESTION - || frm.prev().GetOpenToken() == CT_COND_COLON) - && !options::indent_align_paren()) - { - frm.top().SetIndent(frm.prev().GetIndentTmp() + indent_size); - log_indent(); - frm.top().SetIndentTab(frm.top().GetIndent()); - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - } - else if ( ( pc->Is(CT_FPAREN_OPEN) - || pc->Is(CT_ANGLE_OPEN)) - && ( ( options::indent_func_call_param() - && ( pc->GetParentType() == CT_FUNC_CALL - || pc->GetParentType() == CT_FUNC_CALL_USER)) - || ( options::indent_func_proto_param() - && pc->GetParentType() == CT_FUNC_PROTO) - || ( options::indent_func_class_param() - && ( pc->GetParentType() == CT_FUNC_CLASS_DEF - || pc->GetParentType() == CT_FUNC_CLASS_PROTO)) - || ( options::indent_template_param() - && pc->GetParentType() == CT_TEMPLATE) - || ( options::indent_func_ctor_var_param() - && pc->GetParentType() == CT_FUNC_CTOR_VAR) - || ( options::indent_func_def_param() - && pc->GetParentType() == CT_FUNC_DEF) - || ( !options::indent_func_def_param() // Issue #931 - && pc->GetParentType() == CT_FUNC_DEF - && options::indent_func_def_param_paren_pos_threshold() > 0 - && pc->GetOrigCol() > options::indent_func_def_param_paren_pos_threshold()))) - { - log_rule_B("indent_func_call_param"); - log_rule_B("indent_func_proto_param"); - log_rule_B("indent_func_class_param"); - log_rule_B("indent_template_param"); - log_rule_B("indent_func_ctor_var_param"); - log_rule_B("indent_func_def_param"); - log_rule_B("indent_func_def_param_paren_pos_threshold"); - // Skip any continuation indents - size_t idx = (!frm.empty()) ? frm.size() - 2 : 0; - - while ( ( ( idx > 0 - && frm.at(idx).GetOpenToken() != CT_BRACE_OPEN - && frm.at(idx).GetOpenToken() != CT_VBRACE_OPEN - && frm.at(idx).GetOpenToken() != CT_PAREN_OPEN - && frm.at(idx).GetOpenToken() != CT_FPAREN_OPEN - && frm.at(idx).GetOpenToken() != CT_RPAREN_OPEN // Issue #3914 - && frm.at(idx).GetOpenToken() != CT_SPAREN_OPEN - && frm.at(idx).GetOpenToken() != CT_SQUARE_OPEN - && frm.at(idx).GetOpenToken() != CT_ANGLE_OPEN - && frm.at(idx).GetOpenToken() != CT_CASE - && frm.at(idx).GetOpenToken() != CT_MEMBER - && frm.at(idx).GetOpenToken() != CT_QUESTION - && frm.at(idx).GetOpenToken() != CT_COND_COLON - && frm.at(idx).GetOpenToken() != CT_LAMBDA - && frm.at(idx).GetOpenToken() != CT_ASSIGN_NL) - || frm.at(idx).GetOpenChunk()->IsOnSameLine(frm.top().GetOpenChunk())) - && ( frm.at(idx).GetOpenToken() != CT_CLASS_COLON - && frm.at(idx).GetOpenToken() != CT_CONSTR_COLON - && !( frm.at(idx).GetOpenToken() == CT_LAMBDA - && frm.at(idx).GetOpenChunk()->GetPrevNc()->GetType() == CT_NEWLINE))) - { - if (idx == 0) - { - fprintf(stderr, "%s(%d): idx is ZERO, cannot be decremented, at line %zu, column %zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol()); - log_flush(true); - exit(EX_SOFTWARE); - } - idx--; - skipped = true; - } - // PR#381 - log_rule_B("indent_param"); - - if (options::indent_param() != 0) - { - frm.top().SetIndent(frm.at(idx).GetIndent() + options::indent_param()); - log_indent(); - } - else - { - frm.top().SetIndent(frm.at(idx).GetIndent() + indent_size); - log_indent(); - } - log_rule_B("indent_func_param_double"); - - if (options::indent_func_param_double()) - { - // double is: Use both values of the options indent_columns and indent_param - frm.top().SetIndent(frm.top().GetIndent() + indent_size); - log_indent(); - } - frm.top().SetIndentTab(frm.top().GetIndent()); - } - else if ( options::indent_oc_inside_msg_sel() - && pc->Is(CT_PAREN_OPEN) - && frm.size() > 2 - && ( frm.prev().GetOpenToken() == CT_OC_MSG_FUNC - || frm.prev().GetOpenToken() == CT_OC_MSG_NAME) - && !options::indent_align_paren()) // Issue #2658 - { - log_rule_B("indent_oc_inside_msg_sel"); - log_rule_B("indent_align_paren"); - // When parens are inside OC messages, push on the parse frame stack - // [Class Message:(<here> - frm.top().SetIndent(frm.prev().GetOpenChunk()->GetColumn() + indent_size); - log_indent(); - frm.top().SetIndentTab(frm.top().GetIndent()); - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - } - else if ( pc->Is(CT_PAREN_OPEN) - && !pc->GetNext()->IsNewline() - && !options::indent_align_paren() - && !pc->TestFlags(PCF_IN_SPAREN)) - { - log_rule_B("indent_align_paren"); - size_t idx = frm.size() - 2; - - while ( idx > 0 - && frm.at(idx).GetOpenChunk()->IsOnSameLine(frm.top().GetOpenChunk())) - { - idx--; - skipped = true; - } - frm.top().SetIndent(frm.at(idx).GetIndent() + indent_size); - log_indent(); - - frm.top().SetIndentTab(frm.top().GetIndent()); - skipped = true; - } - else if ( ( pc->IsString("(") - && !options::indent_paren_nl()) - || ( pc->IsString("<") - && !options::indent_paren_nl()) // TODO: add indent_angle_nl? - || ( pc->IsString("[") - && !options::indent_square_nl())) - { - log_rule_B("indent_paren_nl"); - log_rule_B("indent_square_nl"); - Chunk *next = pc->GetNextNc(); - - if (next->IsNullChunk()) - { - break; - } - log_rule_B("indent_paren_after_func_def"); - log_rule_B("indent_paren_after_func_decl"); - log_rule_B("indent_paren_after_func_call"); - - if ( next->IsNewline() - && !options::indent_paren_after_func_def() - && !options::indent_paren_after_func_decl() - && !options::indent_paren_after_func_call() - && ( !pc->TestFlags(PCF_CONT_LINE) - || options::indent_continue() >= 0)) - { - size_t sub = 2; - - if ( (frm.prev().GetOpenToken() == CT_ASSIGN) - || (frm.prev().GetOpenToken() == CT_RETURN)) - { - sub = 3; - } - sub = frm.size() - sub; - - log_rule_B("indent_align_paren"); - - if (!options::indent_align_paren()) - { - sub = frm.size() - 2; - - while ( sub > 0 - && frm.at(sub).GetOpenChunk()->IsOnSameLine(frm.top().GetOpenChunk())) - { - sub--; - skipped = true; - } - - if ( ( frm.at(sub + 1).GetOpenToken() == CT_CLASS_COLON - || frm.at(sub + 1).GetOpenToken() == CT_CONSTR_COLON) - && (frm.at(sub + 1).GetOpenChunk()->GetPrev()->Is(CT_NEWLINE))) - { - sub = sub + 1; - } - } - frm.top().SetIndent(frm.at(sub).GetIndent() + indent_size); - log_indent(); - - frm.top().SetIndentTab(frm.top().GetIndent()); - skipped = true; - } - else - { - if ( next->IsNotNullChunk() - && !next->IsComment()) - { - if (next->Is(CT_SPACE)) - { - next = next->GetNextNc(); - - if (next->IsNullChunk()) - { - break; - } - } - - if (next->GetPrev()->IsComment()) - { - // Issue #2099 - frm.top().SetIndent(next->GetPrev()->GetColumn()); - } - else - { - frm.top().SetIndent(next->GetColumn()); - } - log_indent(); - } - } - } - log_rule_B("use_indent_continue_only_once"); - log_rule_B("indent_paren_after_func_decl"); - log_rule_B("indent_paren_after_func_def"); - log_rule_B("indent_paren_after_func_call"); - - if ( ( ( !frm.top().GetIndentContinue() // Issue #3567 - && vardefcol == 0) - || ( !options::use_indent_continue_only_once() // Issue #1160 - && !options::indent_ignore_first_continue())) // Issue #3561 - && ( pc->Is(CT_FPAREN_OPEN) - && pc->GetPrev()->IsNewline()) - && ( ( ( pc->GetParentType() == CT_FUNC_PROTO - || pc->GetParentType() == CT_FUNC_CLASS_PROTO) - && options::indent_paren_after_func_decl()) - || ( ( pc->GetParentType() == CT_FUNC_DEF - || pc->GetParentType() == CT_FUNC_CLASS_DEF) - && options::indent_paren_after_func_def()) - || ( ( pc->GetParentType() == CT_FUNC_CALL - || pc->GetParentType() == CT_FUNC_CALL_USER) - && options::indent_paren_after_func_call()) - || !pc->GetNext()->IsNewline())) - { - frm.top().SetIndent(frm.prev().GetIndent() + indent_size); - log_indent(); - - indent_column_set(frm.top().GetIndent()); - } - log_rule_B("indent_continue"); - - if ( pc->GetParentType() != CT_OC_AT - && ( options::indent_ignore_first_continue() - || options::indent_continue() != 0) - && !skipped) - { - if (options::indent_ignore_first_continue()) - { - frm.top().SetIndent(get_indent_first_continue(pc->GetNext())); - } - else - { - frm.top().SetIndent(frm.prev().GetIndent()); - } - log_indent(); - - if ( pc->GetLevel() == pc->GetBraceLevel() - && !options::indent_ignore_first_continue() - && ( pc->Is(CT_FPAREN_OPEN) - || pc->Is(CT_RPAREN_OPEN) // Issue #1170 - || pc->Is(CT_SPAREN_OPEN) - || ( pc->Is(CT_SQUARE_OPEN) - && pc->GetParentType() != CT_OC_MSG) - || pc->Is(CT_ANGLE_OPEN))) // Issue #1170 - { - log_rule_B("use_indent_continue_only_once"); - - if ( (options::use_indent_continue_only_once()) - && (frm.top().GetIndentContinue()) - && vardefcol != 0) - { - /* - * The value of the indentation for a continuation line is calculate - * differently if the line is: - * a declaration :your case with QString fileName ... - * an assignment :your case with pSettings = new QSettings( ... - * At the second case the option value might be used twice: - * at the assignment - * at the function call (if present) - * If you want to prevent the double use of the option value - * you may use the new option : - * use_indent_continue_only_once - * with the value "true". - * use/don't use indent_continue once Guy 2016-05-16 - */ - - // if vardefcol isn't zero, use it - frm.top().SetIndent(vardefcol); - log_indent(); - } - else - { - frm.top().SetIndent(calc_indent_continue(frm)); - log_indent(); - frm.top().SetIndentContinue(true); - - log_rule_B("indent_sparen_extra"); - - if ( pc->Is(CT_SPAREN_OPEN) - && options::indent_sparen_extra() != 0) - { - frm.top().SetIndent(frm.top().GetIndent() + options::indent_sparen_extra()); - log_indent(); - } - } - } - } - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - - frm.SetParenCount(frm.GetParenCount() + 1); - } - else if ( options::indent_member_single() - && pc->Is(CT_MEMBER) - && (strcmp(pc->Text(), ".") == 0) - && language_is_set(LANG_CS | LANG_CPP)) - { - log_rule_B("indent_member_single"); - - if (frm.top().GetOpenToken() != CT_MEMBER) - { - frm.push(pc, __func__, __LINE__); - Chunk *tmp = frm.top().GetOpenChunk()->GetPrevNcNnlNpp(); - - if (frm.prev().GetOpenChunk()->IsOnSameLine(tmp)) - { - frm.top().SetIndent(frm.prev().GetIndent()); - } - else - { - frm.top().SetIndent(frm.prev().GetIndent() + indent_size); - } - log_indent(); - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - } - - if (pc->GetPrev()->IsNewline()) - { - if ( pc->Is(CT_MEMBER) // Issue #2890 - && language_is_set(LANG_CPP)) - { - // will be done at another place - // look at the comment: XXXXXXXXXXXXXXXXXXXXXXXXXX - } - else - { - indent_column_set(frm.top().GetIndent()); - reindent_line(pc, indent_column); - did_newline = false; - } - } - //check for the series of CT_member chunks else pop it. - Chunk *tmp = pc->GetNextNcNnlNpp(); - - if (tmp->IsNotNullChunk()) - { - if (tmp->Is(CT_FUNC_CALL)) - { - tmp = tmp->GetNextType(CT_FPAREN_CLOSE, tmp->GetLevel()); - tmp = tmp->GetNextNcNnlNpp(); - } - else if ( tmp->Is(CT_WORD) - || tmp->Is(CT_TYPE)) - { - tmp = tmp->GetNextNcNnlNpp(); - } - } - - if ( tmp->IsNotNullChunk() - && ( (strcmp(tmp->Text(), ".") != 0) - || tmp->IsNot(CT_MEMBER))) - { - if (tmp->IsParenClose()) - { - tmp = tmp->GetPrevNcNnlNpp(); - } - Chunk *local_prev = tmp->GetPrev(); // Issue #3294 - - if (local_prev->IsComment()) - { - tmp = tmp->GetPrev(); // Issue #3294 - } - - if ( tmp->IsNotNullChunk() - && tmp->GetPrev()->IsNewline()) - { - tmp = tmp->GetPrevNcNnlNpp()->GetNextNl(); - } - - if (tmp->IsNotNullChunk()) - { - frm.top().SetPopChunk(tmp); - } - } - } - else if ( pc->Is(CT_ASSIGN) - || pc->Is(CT_IMPORT) - || ( pc->Is(CT_USING) - && language_is_set(LANG_CS))) - { - /* - * if there is a newline after the '=' or the line starts with a '=', - * just indent one level, - * otherwise align on the '='. - */ - if ( pc->Is(CT_ASSIGN) - && pc->GetPrev()->IsNewline()) - { - if (frm.top().GetOpenToken() == CT_ASSIGN_NL) - { - frm.top().SetIndentTmp(frm.top().GetIndent()); - } - else - { - frm.top().SetIndentTmp(frm.top().GetIndent() + indent_size); - } - log_indent_tmp(); - - indent_column_set(frm.top().GetIndentTmp()); - LOG_FMT(LINDENT, "%s(%d): %zu] assign => %zu [%s]\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, frm.top().GetIndentTmp()); - } - Chunk *next = pc->GetNext(); - - if (next->IsNotNullChunk()) - { - /* - * fixes 1260 , 1268 , 1277 (Extra indentation after line with multiple assignments) - * For multiple consecutive assignments in single line , the indent of all these - * assignments should be same and one more than this line's indent. - * so popping the previous assign and pushing the new one - */ - if ( frm.top().GetOpenToken() == CT_ASSIGN - && pc->Is(CT_ASSIGN)) - { - LOG_FMT(LINDLINE, "%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); - } - frm.push(pc, __func__, __LINE__); - - if ( pc->Is(CT_ASSIGN) - && pc->GetPrev()->IsNewline()) - { - frm.top().SetOpenToken(CT_ASSIGN_NL); - } - log_rule_B("indent_continue"); - - if (options::indent_ignore_first_continue()) - { - frm.top().SetIndent(get_indent_first_continue(pc)); - log_indent(); - frm.top().SetIndentContinue(true); // Issue #3567 - } - else if (options::indent_continue() != 0) - { - frm.top().SetIndent(frm.prev().GetIndent()); - log_indent(); - - if ( pc->GetLevel() == pc->GetBraceLevel() - && ( pc->IsNot(CT_ASSIGN) - || ( pc->GetParentType() != CT_FUNC_PROTO - && pc->GetParentType() != CT_FUNC_DEF))) - { - log_rule_B("use_indent_continue_only_once"); - - if ( (options::use_indent_continue_only_once()) - && (frm.top().GetIndentContinue()) - && vardefcol != 0) - { - // if vardefcol isn't zero, use it - frm.top().SetIndent(vardefcol); - log_indent(); - } - else - { - frm.top().SetIndent(calc_indent_continue(frm)); - log_indent(); - - vardefcol = frm.top().GetIndent(); // use the same variable for the next line - frm.top().SetIndentContinue(true); - } - } - } - else if ( next->IsNewline() - || !options::indent_align_assign()) - { - log_rule_B("indent_align_assign"); - log_rule_B("indent_off_after_assign"); - - if (options::indent_off_after_assign()) // Issue #2591 - { - frm.top().SetIndent(frm.prev().GetIndentTmp()); - } - else - { - frm.top().SetIndent(frm.prev().GetIndentTmp() + indent_size); - } - log_indent(); - - if ( pc->Is(CT_ASSIGN) - && next->IsNewline()) - { - frm.top().SetOpenToken(CT_ASSIGN_NL); - frm.top().SetIndentTab(frm.top().GetIndent()); - } - } - else - { - frm.top().SetIndent(pc->GetColumn() + pc->Len() + 1); - log_indent(); - } - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - } - } - else if ( pc->Is(CT_RETURN) - || ( pc->Is(CT_THROW) - && pc->GetParentType() == CT_NONE)) - { - // don't count returns inside a () or [] - if ( pc->GetLevel() == pc->GetBraceLevel() - || pc->TestFlags(PCF_IN_LAMBDA)) - { - Chunk *next = pc->GetNext(); - - // Avoid indentation on return token set by the option. - log_rule_B("indent_off_after_return"); - - // Avoid indentation on return token if the next token is a new token - // to properly indent object initializers returned by functions. - log_rule_B("indent_off_after_return_new"); - bool indent_after_return = ( next->IsNotNullChunk() - && next->GetType() == CT_NEW) - ? !options::indent_off_after_return_new() - : !options::indent_off_after_return(); - - if ( indent_after_return - || next->IsNullChunk()) - { - frm.push(pc, __func__, __LINE__); - - log_rule_B("indent_single_after_return"); - - if ( next->IsNewline() - || ( pc->Is(CT_RETURN) - && options::indent_single_after_return())) - { - // apply normal single indentation - frm.top().SetIndent(frm.prev().GetIndent() + indent_size); - } - else - { - // indent after the return token - frm.top().SetIndent(frm.prev().GetIndent() + pc->Len() + 1); - } - log_indent(); - frm.top().SetIndentTmp(frm.prev().GetIndent()); - log_indent_tmp(); - } - log_indent(); - } - } - else if ( pc->Is(CT_OC_SCOPE) - || pc->Is(CT_TYPEDEF)) - { - frm.push(pc, __func__, __LINE__); - // Issue #405 - frm.top().SetIndent(frm.prev().GetIndent()); - log_indent(); - - frm.top().SetIndentTmp(frm.top().GetIndent()); - LOG_FMT(LINDLINE, "%s(%d): .indent is %zu, .indent_tmp is %zu\n", - __func__, __LINE__, frm.top().GetIndent(), frm.top().GetIndentTmp()); - - log_rule_B("indent_continue"); - - if (options::indent_ignore_first_continue()) - { - frm.top().SetIndent(get_indent_first_continue(pc)); - log_indent(); - } - else if (options::indent_continue() != 0) - { - frm.top().SetIndent(calc_indent_continue(frm, frm.size() - 2)); - log_indent(); - - frm.top().SetIndentContinue(true); - } - else - { - frm.top().SetIndent(frm.prev().GetIndent() + indent_size); - log_indent(); - } - } - else if (pc->Is(CT_C99_MEMBER)) - { - // nothing to do - } - else if (pc->Is(CT_WHERE_SPEC)) - { - /* class indentation is ok already, just need to adjust func */ - /* TODO: make this configurable, obviously.. */ - if ( pc->GetParentType() == CT_FUNC_DEF - || pc->GetParentType() == CT_FUNC_PROTO - || ( pc->GetParentType() == CT_STRUCT - && frm.top().GetOpenToken() != CT_CLASS_COLON)) - { - indent_column_set(frm.top().GetIndent() + 4); - } - } - else if ( options::indent_inside_ternary_operator() - && ( pc->Is(CT_QUESTION) - || pc->Is(CT_COND_COLON))) // Issue #1130, #1715 - { - log_rule_B("indent_inside_ternary_operator"); - - // Pop any colons before because they should already be processed - while ( pc->Is(CT_COND_COLON) - && frm.top().GetOpenToken() == CT_COND_COLON) - { - frm.pop(__func__, __LINE__, pc); - } - log_rule_B("indent_inside_ternary_operator"); - - // Pop Question from stack in ternary operator - if ( options::indent_inside_ternary_operator() - && pc->Is(CT_COND_COLON) - && frm.top().GetOpenToken() == CT_QUESTION) - { - LOG_FMT(LINDLINE, "%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); - indent_column_set(frm.top().GetIndentTmp()); - } - frm.push(pc, __func__, __LINE__); - - frm.top().SetIndent(frm.prev().GetIndent() + indent_size); - frm.top().SetIndentTab(frm.top().GetIndent()); - log_indent(); - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - } - else if ( pc->Is(CT_LAMBDA) - && (language_is_set(LANG_CS | LANG_JAVA)) - && pc->GetNextNcNnlNpp()->IsNot(CT_BRACE_OPEN) - && options::indent_cs_delegate_body()) - { - log_rule_B("indent_cs_delegate_body"); - frm.push(pc, __func__, __LINE__); - frm.top().SetIndent(frm.prev().GetIndent()); - log_indent(); - - if ( pc->GetPrevNc()->IsNewline() - && !frm.prev().GetOpenChunk()->IsOnSameLine(pc->GetPrevNcNnl())) - { - frm.top().SetIndent(frm.prev().GetIndent() + indent_size); - log_indent(); - reindent_line(pc, (frm.prev().GetIndent() + indent_size)); - did_newline = false; - } - else if ( pc->GetNextNc()->IsNewline() - && !frm.prev().GetOpenChunk()->IsOnSameLine(frm.top().GetOpenChunk())) - { - frm.top().SetIndent(frm.prev().GetIndent() + indent_size); - } - log_indent(); - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - } - else if ( options::indent_oc_inside_msg_sel() - && ( pc->Is(CT_OC_MSG_FUNC) - || pc->Is(CT_OC_MSG_NAME)) - && pc->GetNextNcNnl()->Is(CT_OC_COLON)) // Issue #2658 - { - log_rule_B("indent_oc_inside_msg_sel"); - // Pop the OC msg name that is on the top of the stack - // [Class Message:<here> - frm.push(pc, __func__, __LINE__); - - frm.top().SetIndent(frm.prev().GetIndent()); - frm.top().SetIndentTab(frm.prev().GetIndentTab()); - log_indent(); - frm.top().SetIndentTmp(frm.prev().GetIndentTmp()); - log_indent_tmp(); - } - else if (pc->IsComment()) - { - // Issue #3294 - Chunk *next = pc->GetNext(); - - if (next->Is(CT_COND_COLON)) - { - LOG_FMT(LINDLINE, "%s(%d): Comment and COND_COLON: 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); - } -// uncomment the line below to get debug info -// #define ANYTHING_ELSE -#ifdef ANYTHING_ELSE - else - { - // anything else? - // Issue #3294 - LOG_FMT(LINDLINE, "%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())); - LOG_FMT(LSPACE, "\n\n%s(%d): WARNING: unrecognize indent_text:\n", - __func__, __LINE__); - } -#endif /* ANYTHING_ELSE */ - } - else - { - // anything else? -#ifdef ANYTHING_ELSE - LOG_FMT(LINDLINE, "%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())); - LOG_FMT(LSPACE, "\n\n%s(%d): WARNING: unrecognize indent_text:\n", - __func__, __LINE__); -#endif /* ANYTHING_ELSE */ - } - // Handle shift expression continuation indenting - size_t shiftcontcol = 0; - - log_rule_B("indent_shift"); - - if ( options::indent_shift() == 1 - && !pc->TestFlags(PCF_IN_ENUM) - && pc->GetParentType() != CT_OPERATOR - && !pc->IsComment() - && pc->IsNot(CT_BRACE_OPEN) - && pc->GetLevel() > 0 - && !pc->IsEmptyText()) - { - bool in_shift = false; - bool is_operator = false; - - // Are we in such an expression? Go both forwards and backwards. - Chunk *tmp = pc; - - do - { - if (tmp->Is(CT_SHIFT)) - { - in_shift = true; - LOG_FMT(LINDENT2, "%s(%d): in_shift set to TRUE\n", - __func__, __LINE__); - - tmp = tmp->GetPrevNcNnl(); - - if (tmp->Is(CT_OPERATOR)) - { - is_operator = true; - } - break; - } - tmp = tmp->GetPrevNcNnl(); - } while ( !in_shift - && tmp->IsNotNullChunk() - && tmp->IsNot(CT_SEMICOLON) - && tmp->IsNot(CT_BRACE_OPEN) - && tmp->IsNot(CT_BRACE_CLOSE) - && tmp->IsNot(CT_COMMA) - && tmp->IsNot(CT_SPAREN_OPEN) - && tmp->IsNot(CT_SPAREN_CLOSE)); - - tmp = pc; - - do - { - tmp = tmp->GetNextNcNnl(); - - if ( tmp->IsNotNullChunk() - && tmp->Is(CT_SHIFT)) - { - in_shift = true; - LOG_FMT(LINDENT2, "%s(%d): in_shift set to TRUE\n", - __func__, __LINE__); - - tmp = tmp->GetPrevNcNnl(); - - if (tmp->Is(CT_OPERATOR)) - { - is_operator = true; - } - break; - } - } while ( !in_shift - && tmp->IsNotNullChunk() - && tmp->IsNot(CT_SEMICOLON) - && tmp->IsNot(CT_BRACE_OPEN) - && tmp->IsNot(CT_BRACE_CLOSE) - && tmp->IsNot(CT_COMMA) - && tmp->IsNot(CT_SPAREN_OPEN) - && tmp->IsNot(CT_SPAREN_CLOSE)); - - LOG_FMT(LINDENT2, "%s(%d): in_shift is %s\n", - __func__, __LINE__, in_shift ? "TRUE" : "FALSE"); - Chunk *prev_nonl = pc->GetPrevNcNnl(); - Chunk *prev2 = pc->GetPrevNc(); - - if (( prev_nonl->IsSemicolon() - || prev_nonl->IsBraceOpen() - || prev_nonl->IsBraceClose() - || prev_nonl->Is(CT_CASE_COLON) - || ( prev_nonl->IsNotNullChunk() - && prev_nonl->TestFlags(PCF_IN_PREPROC)) != pc->TestFlags(PCF_IN_PREPROC) - || prev_nonl->Is(CT_COMMA) - || is_operator)) - { - in_shift = false; - } - LOG_FMT(LINDENT2, "%s(%d): in_shift is %s\n", - __func__, __LINE__, in_shift ? "TRUE" : "FALSE"); - - if ( prev2->Is(CT_NEWLINE) - && in_shift) - { - shiftcontcol = calc_indent_continue(frm); - // Calling frm.top().SetIndentContinue(true) in the top context when the indent is not also set - // just leads to complications when succeeding statements try to indent based on being - // embedded in a continuation. In other words setting frm.top().SetIndentContinue(true) - // should only be set if frm.top().indent is also set. - - // Work around the doubly increased indent in RETURNs and assignments - bool need_workaround = false; - size_t sub = 0; - - for (int i = frm.size() - 1; i >= 0; i--) - { - if ( frm.at(i).GetOpenToken() == CT_RETURN - || frm.at(i).GetOpenToken() == CT_ASSIGN) - { - need_workaround = true; - sub = frm.size() - i; - break; - } - } - - if (need_workaround) - { - shiftcontcol = calc_indent_continue(frm, frm.size() - 1 - sub); - } - } - } - - // Handle variable definition continuation indenting - if ( vardefcol == 0 - && ( pc->Is(CT_WORD) - || pc->Is(CT_FUNC_CTOR_VAR)) - && !pc->TestFlags(PCF_IN_FCN_DEF) - && pc->TestFlags(PCF_VAR_1ST_DEF)) - { - log_rule_B("indent_continue"); - - if (options::indent_ignore_first_continue()) - { - vardefcol = get_indent_first_continue(pc); - } - else if (options::indent_continue() != 0) - { - vardefcol = calc_indent_continue(frm); - // Calling frm.top().SetIndentContinue(true) in the top context when the indent is not also set - // just leads to complications when succeeding statements try to indent based on being - // embedded in a continuation. In other words setting frm.top().SetIndentContinue(true) - // should only be set if frm.top().indent is also set. - } - else if ( options::indent_var_def_cont() - || pc->GetPrev()->IsNewline()) - { - log_rule_B("indent_var_def_cont"); - vardefcol = frm.top().GetIndent() + indent_size; - } - else - { - // Issue #3010 - vardefcol = pc->GetColumn(); - // BUT, we need to skip backward over any '*' - Chunk *tmp = pc->GetPrevNc(); - - while (tmp->Is(CT_PTR_TYPE)) - { - vardefcol = tmp->GetColumn(); - tmp = tmp->GetPrevNc(); - } - // BUT, we need to skip backward over any '::' or TYPE - //tmp = pc->GetPrevNc(); - - //if (tmp->Is(CT_DC_MEMBER)) - //{ - // // look for a type - // Chunk *tmp2 = tmp->GetPrevNc(); - // if (tmp2->Is(CT_TYPE)) - // { - // // we have something like "SomeLongNamespaceName::Foo()" - // vardefcol = tmp2->GetColumn(); - // LOG_FMT(LINDENT, "%s(%d): orig line is %zu, vardefcol is %zu\n", - // __func__, __LINE__, pc->GetOrigLine(), vardefcol); - // } - //} - } - } - - if ( pc->IsSemicolon() - || ( pc->Is(CT_BRACE_OPEN) - && ( pc->GetParentType() == CT_FUNCTION - || pc->GetParentType() == CT_CLASS))) //Issue #3576 - { - vardefcol = 0; - } - - // Indent the line if needed - if ( did_newline - && !pc->IsNewline() - && (pc->Len() != 0)) - { - if ( pc->TestFlags(PCF_CONT_LINE) - && options::indent_continue() < 0) - { - log_rule_B("indent_continue"); - indent_column = calc_indent_continue(frm); - log_indent(); - } - pc->SetColumnIndent(frm.top().GetIndentTab()); - - if (frm.top().GetIndentData().ref) - { - pc->IndentData().ref = frm.top().GetIndentData().ref; - pc->IndentData().delta = frm.top().GetIndentData().delta; - } - LOG_FMT(LINDENT2, "%s(%d): orig line is %zu, pc->GetColumn() indent is %zu, indent_column is %zu, for '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetColumnIndent(), indent_column, pc->ElidedText(copy)); - - /* - * Check for special continuations. - * Note that some of these could be done as a stack item like - * everything else - */ - - Chunk *prev = pc->GetPrevNcNnl(); - Chunk *prevv = prev->GetPrevNcNnl(); - Chunk *next = pc->GetNextNcNnl(); - - bool do_vardefcol = false; - - if ( vardefcol > 0 - && pc->GetLevel() == pc->GetBraceLevel() - && ( prev->Is(CT_COMMA) - || prev->Is(CT_TYPE) - || prev->Is(CT_PTR_TYPE) - || prev->Is(CT_WORD))) - { - Chunk *tmp = pc; - - while (tmp->Is(CT_PTR_TYPE)) - { - tmp = tmp->GetNextNcNnl(); - } - LOG_FMT(LINDENT2, "%s(%d): orig line is %zu, for '%s'", - __func__, __LINE__, tmp->GetOrigLine(), tmp->Text()); - LOG_FMT(LINDENT2, " tmp->GetFlags(): "); - log_pcf_flags(LINDENT2, tmp->GetFlags()); // Issue #2332 - - if ( tmp->TestFlags(PCF_VAR_DEF) - && ( tmp->Is(CT_WORD) - || tmp->Is(CT_FUNC_CTOR_VAR))) - { - do_vardefcol = true; - } - } - //LOG_FMT(LINDENT2, "%s(%d): GUY 2:\n", __func__, __LINE__); - - if (pc->TestFlags(PCF_DONT_INDENT)) - { - // no change - } - else if ( pc->GetParentType() == CT_SQL_EXEC - && options::indent_preserve_sql()) - { - log_rule_B("indent_preserve_sql"); - reindent_line(pc, sql_col + (pc->GetOrigCol() - sql_orig_col)); - LOG_FMT(LINDENT, "Indent SQL: [%s] to %zu (%zu/%zu)\n", - pc->Text(), pc->GetColumn(), sql_col, sql_orig_col); - } - else if ( !options::indent_member_single() - && !pc->TestFlags(PCF_STMT_START) - && ( pc->Is(CT_MEMBER) - || ( pc->Is(CT_DC_MEMBER) - && prev->Is(CT_TYPE)) - || ( prev->Is(CT_MEMBER) - || ( prev->Is(CT_DC_MEMBER) - && prevv->Is(CT_TYPE))))) - { - log_rule_B("indent_member_single"); - log_rule_B("indent_member"); - size_t tmp = options::indent_member() + indent_column; - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, member => %zu\n", - __func__, __LINE__, pc->GetOrigLine(), tmp); - reindent_line(pc, tmp); - } - else if (do_vardefcol) - { - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, vardefcol is %zu\n", - __func__, __LINE__, pc->GetOrigLine(), vardefcol); - reindent_line(pc, vardefcol); - } - else if (shiftcontcol > 0) - { - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, shiftcontcol is %zu\n", - __func__, __LINE__, pc->GetOrigLine(), shiftcontcol); - reindent_line(pc, shiftcontcol); - } - else if ( pc->Is(CT_NAMESPACE) - && options::indent_namespace() - && options::indent_namespace_single_indent() - && frm.top().GetNsCount()) - { - log_rule_B("indent_namespace"); - log_rule_B("indent_namespace_single_indent"); - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, Namespace => %zu\n", - __func__, __LINE__, pc->GetOrigLine(), frm.top().GetBraceIndent()); - reindent_line(pc, frm.top().GetBraceIndent()); - } - else if ( pc->Is(CT_STRING) - && prev->Is(CT_STRING) - && options::indent_align_string()) - { - log_rule_B("indent_align_string"); - const int tmp = (xml_indent != 0) ? xml_indent : prev->GetColumn(); - - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, String => %d\n", - __func__, __LINE__, pc->GetOrigLine(), tmp); - reindent_line(pc, tmp); - } - else if (pc->IsComment()) - { - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, comment => %zu\n", - __func__, __LINE__, pc->GetOrigLine(), frm.top().GetIndentTmp()); - indent_comment(pc, frm.top().GetIndentTmp()); - } - else if (pc->Is(CT_PREPROC)) - { - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, pp-indent => %zu [%s]\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - else if ( pc->IsParenClose() - || pc->Is(CT_ANGLE_CLOSE)) - { - /* - * This is a big hack. We assume that since we hit a paren close, - * that we just removed a paren open - */ - LOG_FMT(LINDLINE, "%s(%d): indent_column is %zu\n", - __func__, __LINE__, indent_column); - - if (frm.lastPopped().GetOpenToken() == E_Token(pc->GetType() - 1)) - { - // Issue # 405 - LOG_FMT(LINDLINE, "%s(%d): 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())); - Chunk *ck1 = frm.lastPopped().GetOpenChunk(); - LOG_FMT(LINDLINE, "%s(%d): ck1 orig line is %zu, orig col is %zu, Text() is '%s', GetType() is %s\n", - __func__, __LINE__, ck1->GetOrigLine(), ck1->GetOrigCol(), ck1->Text(), get_token_name(ck1->GetType())); - Chunk *ck2 = ck1->GetPrev(); - LOG_FMT(LINDLINE, "%s(%d): ck2 orig line is %zu, orig col is %zu, Text() is '%s', GetType() is %s\n", - __func__, __LINE__, ck2->GetOrigLine(), ck2->GetOrigCol(), ck2->Text(), get_token_name(ck2->GetType())); - - log_rule_B("indent_paren_close"); - - if (options::indent_paren_close() == -1) - { - LOG_FMT(LINDLINE, "%s(%d): [%zu:%zu] indent_paren_close is -1\n", - __func__, __LINE__, ck2->GetOrigLine(), ck2->GetOrigCol()); - indent_column_set(pc->GetOrigCol()); - LOG_FMT(LINDLINE, "%s(%d): [%zu:%zu] indent_column set to %zu\n", - __func__, __LINE__, ck2->GetOrigLine(), ck2->GetOrigCol(), indent_column); - } - else if ( ck2->IsNewline() - || (options::indent_paren_close() == 1)) - { - /* - * If the open parenthesis was the first thing on the line or we - * are doing mode 1, then put the close parenthesis in the same - * column - */ - LOG_FMT(LINDLINE, "%s(%d): [%zu:%zu] indent_paren_close is 1\n", - __func__, __LINE__, ck2->GetOrigLine(), ck2->GetOrigCol()); - indent_column_set(ck1->GetColumn()); - LOG_FMT(LINDLINE, "%s(%d): [%zu:%zu] indent_column set to %zu\n", - __func__, __LINE__, ck2->GetOrigLine(), ck2->GetOrigCol(), indent_column); - } - else - { - if (options::indent_paren_close() != 2) - { - // indent_paren_close is 0 or 1 - LOG_FMT(LINDLINE, "%s(%d): [%zu:%zu] indent_paren_close is 0 or 1\n", - __func__, __LINE__, ck2->GetOrigLine(), ck2->GetOrigCol()); - indent_column_set(frm.lastPopped().GetIndentTmp()); - LOG_FMT(LINDLINE, "%s(%d): [%zu:%zu] indent_column set to %zu\n", - __func__, __LINE__, ck2->GetOrigLine(), ck2->GetOrigCol(), indent_column); - pc->SetColumnIndent(frm.lastPopped().GetIndentTab()); - log_rule_B("indent_paren_close"); - - if (options::indent_paren_close() == 1) - { - LOG_FMT(LINDLINE, "%s(%d): [%zu:%zu] indent_paren_close is 1\n", - __func__, __LINE__, ck2->GetOrigLine(), ck2->GetOrigCol()); - - if (indent_column == 0) - { - fprintf(stderr, "%s(%d): indent_column is ZERO, cannot be decremented, at line %zu, column %zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol()); - log_flush(true); - exit(EX_SOFTWARE); - } - indent_column--; - LOG_FMT(LINDLINE, "%s(%d): [%zu:%zu] indent_column set to %zu\n", - __func__, __LINE__, ck2->GetOrigLine(), ck2->GetOrigCol(), indent_column); - } - } - else - { - // indent_paren_close is 2: Indent to the brace level - LOG_FMT(LINDLINE, "%s(%d): indent_paren_close is 2\n", - __func__, __LINE__); - LOG_FMT(LINDLINE, "%s(%d): ck2 orig line is %zu, orig col is %zu, ck2->Text() is '%s'\n", - __func__, __LINE__, ck2->GetOrigLine(), ck2->GetOrigCol(), ck2->Text()); - - if (pc->GetPrev()->GetType() == CT_NEWLINE) - { - LOG_FMT(LINDLINE, "%s(%d): 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())); - LOG_FMT(LINDLINE, "%s(%d): prev is <newline>\n", - __func__, __LINE__); - Chunk *search = pc; - - while (search->GetNext()->IsParenClose()) - { - search = search->GetNext(); - } - Chunk *searchNext = search->GetNext(); - - // Issue #3407 - Skip over a possible 'noexcept' keyword before going forward. - if (searchNext->GetType() == CT_NOEXCEPT) - { - searchNext = searchNext->GetNext(); - } - - if ( searchNext->GetType() == CT_SEMICOLON - || searchNext->GetType() == CT_MEMBER // Issue #2582 - || searchNext->GetType() == CT_NEWLINE) - { - LOG_FMT(LINDLINE, "%s(%d):\n", __func__, __LINE__); - search = search->GetOpeningParen(); - - if ( options::indent_oc_inside_msg_sel() - && search->GetPrevNcNnl()->Is(CT_OC_COLON) - && ( frm.top().GetOpenToken() == CT_OC_MSG_FUNC - || frm.top().GetOpenToken() == CT_OC_MSG_NAME)) // Issue #2658 - { - log_rule_B("indent_oc_inside_msg_sel"); - // [Class Message:(...)<here> - indent_column_set(frm.top().GetOpenChunk()->GetColumn()); - } - else if ( options::indent_inside_ternary_operator() - && ( frm.top().GetOpenToken() == CT_QUESTION - || frm.top().GetOpenToken() == CT_COND_COLON)) // Issue #1130, #1715 - { - log_rule_B("indent_inside_ternary_operator"); - indent_column_set(frm.top().GetIndent()); - } - else - { - search = search->GetPrevNl()->GetNext(); - - if (search->IsNullChunk()) - { - search = Chunk::GetHead(); - } - indent_column_set(search->GetColumn()); - } - } - } - } - } - } - size_t indent_value = 0; - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, closing parenthesis => %zu, text is '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - LOG_FMT(LINDENT, "%s(%d): [%s/%s]\n", - __func__, __LINE__, - get_token_name(pc->GetType()), get_token_name(pc->GetParentType())); - Chunk *prev2 = pc->GetPrev(); // Issue #2930 - LOG_FMT(LINDENT, "%s(%d): prev2 is orig line is %zu, text is '%s'\n", - __func__, __LINE__, prev2->GetOrigLine(), prev2->Text()); - Chunk *next2 = pc->GetNext(); - LOG_FMT(LINDENT, "%s(%d): next2 is orig line is %zu, text is '%s'\n", - __func__, __LINE__, next2->GetOrigLine(), next2->Text()); - - if ( pc->GetParentType() == CT_FUNC_DEF - && prev2->IsNewline() - && next2->IsNewline()) - { - if (options::donot_indent_func_def_close_paren()) - { - indent_value = 1; - } - else - { - reindent_line(pc, indent_column); - indent_value = indent_column; - } - } - else - { - indent_value = indent_column; - } - reindent_line(pc, indent_value); - } - else if (pc->Is(CT_COMMA)) - { - bool indent_align = false; - bool indent_ignore = false; - - if (frm.top().GetOpenChunk()->IsParenOpen()) - { - log_rule_B("indent_comma_paren"); - indent_align = options::indent_comma_paren() == (int)indent_mode_e::ALIGN; - indent_ignore = options::indent_comma_paren() == (int)indent_mode_e::IGNORE; - } - else if (frm.top().GetOpenChunk()->IsBraceOpen()) - { - log_rule_B("indent_comma_brace"); - indent_align = options::indent_comma_brace() == (int)indent_mode_e::ALIGN; - indent_ignore = options::indent_comma_brace() == (int)indent_mode_e::IGNORE; - } - - if (indent_ignore) - { - indent_column_set(pc->GetOrigCol()); - } - else if (indent_align) - { - indent_column_set(frm.top().GetOpenChunk()->GetColumn()); - } - LOG_FMT(LINDENT, "%s(%d): %zu] comma => %zu [%s]\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - else if ( options::indent_func_const() - && pc->Is(CT_QUALIFIER) - && strncasecmp(pc->Text(), "const", pc->Len()) == 0 - && ( next->Is(CT_BRACED) - || next->IsBraceOpen() - || next->Is(CT_NEWLINE) - || next->Is(CT_SEMICOLON) - || next->Is(CT_THROW))) - { - // indent const - void GetFoo(void)\n const\n { return (m_Foo); } - log_rule_B("indent_func_const"); - indent_column_set(frm.top().GetIndent() + options::indent_func_const()); - LOG_FMT(LINDENT, "%s(%d): %zu] const => %zu [%s]\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - else if ( options::indent_func_throw() - && pc->Is(CT_THROW) - && pc->GetParentType() != CT_NONE) - { - // indent throw - void GetFoo(void)\n throw()\n { return (m_Foo); } - log_rule_B("indent_func_throw"); - indent_column_set(options::indent_func_throw()); - LOG_FMT(LINDENT, "%s(%d): %zu] throw => %zu [%s]\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - else if (pc->Is(CT_SEMICOLON)) - { - if ( pc->TestFlags(PCF_IN_FOR) - && options::indent_semicolon_for_paren()) - { - log_rule_B("indent_semicolon_for_paren"); - indent_column_set(frm.top().GetOpenChunk()->GetColumn()); - - log_rule_B("indent_first_for_expr"); - - if (options::indent_first_for_expr()) - { - reindent_line(frm.top().GetOpenChunk()->GetNext(), - indent_column + pc->Len() + 1); - } - LOG_FMT(LINDENT, "%s(%d): %zu] SEMICOLON => %zu [%s]\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - else - { - log_rule_B("indent_ignore_semicolon"); - - if (options::indent_ignore_semicolon()) - { - indent_column_set(pc->GetOrigCol()); - } - LOG_FMT(LINDENT, "%s(%d): %zu] semicolon => %zu [%s]\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - } - else if (pc->Is(CT_BOOL)) - { - if (frm.top().GetOpenChunk()->IsParenOpen()) - { - log_rule_B("indent_bool_paren"); - - if (options::indent_bool_paren() == (int)indent_mode_e::IGNORE) - { - indent_column_set(pc->GetOrigCol()); - } - else if (options::indent_bool_paren() == (int)indent_mode_e::ALIGN) - { - indent_column_set(frm.top().GetOpenChunk()->GetColumn()); - - log_rule_B("indent_first_bool_expr"); - - if (options::indent_first_bool_expr()) - { - reindent_line(frm.top().GetOpenChunk()->GetNext(), - indent_column + pc->Len() + 1); - } - } - } - else - { - log_rule_B("indent_ignore_bool"); - - if (options::indent_ignore_bool()) - { - indent_column_set(pc->GetOrigCol()); - } - } - LOG_FMT(LINDENT, "%s(%d): %zu] bool => %zu [%s]\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - else if ( pc->Is(CT_ARITH) - || pc->Is(CT_CARET)) - { - log_rule_B("indent_ignore_arith"); - - if (options::indent_ignore_arith()) - { - indent_column_set(pc->GetOrigCol()); - } - LOG_FMT(LINDENT, "%s(%d): %zu] arith => %zu [%s]\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - else if (pc->Is(CT_SHIFT)) - { - log_rule_B("indent_shift"); - - if (options::indent_shift() == -1) - { - indent_column_set(pc->GetOrigCol()); - } - LOG_FMT(LINDENT, "%s(%d): %zu] shift => %zu [%s]\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - else if (pc->Is(CT_ASSIGN)) - { - log_rule_B("indent_ignore_assign"); - - if (options::indent_ignore_assign()) - { - indent_column_set(pc->GetOrigCol()); - } - LOG_FMT(LINDENT, "%s(%d): %zu] assign => %zu [%s]\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - else if ( options::indent_ternary_operator() == 1 - && prev->Is(CT_COND_COLON)) - { - log_rule_B("indent_ternary_operator"); - Chunk *tmp = prev->GetPrevType(CT_QUESTION); - - if (tmp->IsNotNullChunk()) - { - tmp = tmp->GetNextNcNnl(); - - if (tmp->IsNotNullChunk()) - { - LOG_FMT(LINDENT, "%s: %zu] ternarydefcol => %zu [%s]\n", - __func__, pc->GetOrigLine(), tmp->GetColumn(), pc->Text()); - reindent_line(pc, tmp->GetColumn()); - } - } - } - else if ( options::indent_ternary_operator() == 2 - && pc->Is(CT_COND_COLON)) - { - log_rule_B("indent_ternary_operator"); - // get the parent, the QUESTION - Chunk *question = pc->GetParent(); - - if (question->IsNotNullChunk()) - { - LOG_FMT(LINDENT, "%s: %zu] ternarydefcol => %zu [%s]\n", - __func__, pc->GetOrigLine(), question->GetColumn(), pc->Text()); - reindent_line(pc, question->GetColumn()); - } - } - else if ( options::indent_oc_inside_msg_sel() - && ( pc->Is(CT_OC_MSG_FUNC) - || pc->Is(CT_OC_MSG_NAME))) // Issue #2658 - { - log_rule_B("indent_oc_inside_msg_sel"); - reindent_line(pc, frm.top().GetIndent()); - } - else - { - bool use_indent = true; - const size_t ttidx = frm.size() - 1; - - if (ttidx > 0) - { - LOG_FMT(LINDPC, "%s(%d): (frm.at(ttidx).pc)->GetParentType() is %s\n", - __func__, __LINE__, get_token_name((frm.at(ttidx).GetOpenChunk())->GetParentType())); - - if ((frm.at(ttidx).GetOpenChunk())->GetParentType() == CT_FUNC_CALL) - { - LOG_FMT(LINDPC, "FUNC_CALL OK [%d]\n", __LINE__); - - log_rule_B("use_indent_func_call_param"); - - if (options::use_indent_func_call_param()) - { - LOG_FMT(LINDPC, "use is true [%d]\n", __LINE__); - } - else - { - LOG_FMT(LINDPC, "use is false [%d]\n", __LINE__); - use_indent = false; - } - } - } - LOG_FMT(LINDENT, "%s(%d): pc->line is %zu, pc->GetColumn() is %zu, pc->Text() is '%s, indent_column is %zu\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetColumn(), pc->Text(), indent_column); - - if ( use_indent - && pc->IsNot(CT_PP_IGNORE)) // Leave indentation alone for PP_IGNORE tokens - { - log_rule_B("pos_conditional"); - - if ( ( pc->Is(CT_QUESTION) // Issue #2101 - || pc->Is(CT_COND_COLON)) // Issue #2101 - && options::pos_conditional() == TP_IGNORE) - { - // do not indent this line - LOG_FMT(LINDENT, "%s(%d): %zu] don't indent this line\n", - __func__, __LINE__, pc->GetOrigLine()); - } - else if (pc->Is(CT_BREAK)) - { - // Issue #1692 - log_rule_B("indent_switch_break_with_case"); - - // Issue #2281 - if ( options::indent_switch_break_with_case() - && pc->GetTypeOfParent() == CT_SWITCH) - { - // look for a case before Issue #2735 - Chunk *whereIsCase = pc->GetPrevType(CT_CASE, pc->GetLevel()); - - if (whereIsCase->IsNotNullChunk()) - { - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, orig col is %zu, Text() is '%s'\n", - __func__, __LINE__, whereIsCase->GetOrigLine(), whereIsCase->GetOrigCol(), whereIsCase->Text()); - LOG_FMT(LINDENT, "%s(%d): column is %zu\n", - __func__, __LINE__, whereIsCase->GetColumn()); - reindent_line(pc, whereIsCase->GetColumn()); - } - } - else - { - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, indent_column set to %zu, for '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - } - else if ( pc->Is(CT_MEMBER) // Issue #2890 - && language_is_set(LANG_CPP)) - { - // comment name: XXXXXXXXXXXXXXXXXXXXXXXXXX - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, indent_column set to %zu, for '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - const size_t frm_size = frm.size(); - LOG_FMT(LINDPC, "%s(%d): frm_size is %zu\n", - __func__, __LINE__, frm_size); - // get pc - LOG_FMT(LINDPC, "%s(%d): Text() is '%s', (frm.at(frm_size - 1).pc)->GetType() is %s\n", - __func__, __LINE__, (frm.at(frm_size - 1).GetOpenChunk())->Text(), get_token_name((frm.at(frm_size - 1).GetOpenChunk())->GetType())); - // get the token before - const size_t temp_ttidx = frm_size - 2; - - if (temp_ttidx == 0) - { - indent_column = 1 + indent_size; - reindent_line(pc, indent_column); - } - else - { - Chunk *token_before = frm.at(temp_ttidx).GetOpenChunk(); - LOG_FMT(LINDPC, "%s(%d): Text() is '%s', token_before->GetType() is %s\n", - __func__, __LINE__, token_before->Text(), get_token_name(token_before->GetType())); - - size_t vor_col = 0; - - if (token_before->Is(CT_ASSIGN)) - { - Chunk *before_Assign = frm.at(temp_ttidx - 1).GetOpenChunk(); - - if (before_Assign->IsNullChunk()) - { - indent_column = 1 + indent_size; - } - else - { - vor_col = before_Assign->GetColumn(); - LOG_FMT(LINDPC, "%s(%d): Text() is '%s', before_Assign->GetType() is %s, column is %zu\n", - __func__, __LINE__, before_Assign->Text(), get_token_name(before_Assign->GetType()), vor_col); - indent_column = vor_col + 2 * indent_size; - } - } - else if (token_before->Is(CT_BRACE_OPEN)) - { - vor_col = token_before->GetColumn(); - LOG_FMT(LINDPC, "%s(%d): Text() is '%s', token_before->GetType() is %s, column is %zu\n", - __func__, __LINE__, token_before->Text(), get_token_name(token_before->GetType()), vor_col); - indent_column = vor_col + 2 * indent_size; - } - else if (token_before->Is(CT_RETURN)) - { - Chunk *before_Return = frm.at(temp_ttidx - 1).GetOpenChunk(); - vor_col = before_Return->GetColumn(); - LOG_FMT(LINDPC, "%s(%d): Text() is '%s', before_Return->GetType() is %s, column is %zu\n", - __func__, __LINE__, before_Return->Text(), get_token_name(before_Return->GetType()), vor_col); - indent_column = vor_col + 2 * indent_size; - } - else - { - // TO DO - } - reindent_line(pc, indent_column); - } - reindent_line(pc, indent_column); - } - else - { - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, indent_column set to %zu, for '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), indent_column, pc->Text()); - reindent_line(pc, indent_column); - } - } - else - { - // do not indent this line - LOG_FMT(LINDENT, "%s(%d): %zu] don't indent this line\n", - __func__, __LINE__, pc->GetOrigLine()); - } - } - did_newline = false; - - if ( pc->Is(CT_SQL_EXEC) - || pc->Is(CT_SQL_BEGIN) - || pc->Is(CT_SQL_END)) - { - sql_col = pc->GetColumn(); - sql_orig_col = pc->GetOrigCol(); - } - - // Handle indent for variable defs at the top of a block of code - if (pc->TestFlags(PCF_VAR_TYPE)) - { - if ( !frm.top().GetNonVardef() - && (frm.top().GetOpenToken() == CT_BRACE_OPEN)) - { - log_rule_B("indent_var_def_blk"); - int val = options::indent_var_def_blk(); - - if (val != 0) - { - size_t indent = indent_column; - indent = (val > 0) ? val // reassign if positive val, - : ((size_t)(abs(val)) < indent) // else if no underflow - ? (indent + val) : 0; // reduce, else 0 - - LOG_FMT(LINDENT, "%s(%d): %zu] var_type indent => %zu [%s]\n", - __func__, __LINE__, pc->GetOrigLine(), indent, pc->Text()); - reindent_line(pc, indent); - } - } - } - else if (pc != frm.top().GetOpenChunk()) - { - frm.top().SetNonVardef(true); - } - } - - // if we hit a newline, reset indent_tmp - if ( pc->IsNewline() - || pc->Is(CT_COMMENT_MULTI) - || pc->Is(CT_COMMENT_CPP)) - { - log_indent(); - frm.top().SetIndentTmp(frm.top().GetIndent()); - log_indent_tmp(); - - /* - * Handle the case of a multi-line #define w/o anything on the - * first line (indent_tmp will be 1 or 0) - */ - if ( pc->Is(CT_NL_CONT) - && frm.top().GetIndentTmp() <= indent_size - && frm.top().GetOpenToken() != CT_PP_DEFINE) - { - frm.top().SetIndentTmp(indent_size + 1); - log_indent_tmp(); - } - // Get ready to indent the next item - did_newline = true; - } - // Check for open XML tags "</..." - log_rule_B("indent_xml_string"); - - if ( options::indent_xml_string() > 0 - && pc->Is(CT_STRING) - && pc->Len() > 4 - && pc->GetStr()[1] == '<' - && pc->GetStr()[2] != '/' - && pc->GetStr()[pc->Len() - 3] != '/') - { - if (xml_indent <= 0) - { - xml_indent = pc->GetColumn(); - } - log_rule_B("indent_xml_string"); - xml_indent += options::indent_xml_string(); - } - // Issue #672 - log_rule_B("indent_continue_class_head"); - - if ( pc->Is(CT_CLASS) - && language_is_set(LANG_CPP | LANG_JAVA) - && ( options::indent_ignore_first_continue() - || options::indent_continue_class_head() != 0) - && !classFound) - { - LOG_FMT(LINDENT, "%s(%d): orig line is %zu, CT_CLASS found, OPEN IT\n", - __func__, __LINE__, pc->GetOrigLine()); - frm.push(pc, __func__, __LINE__); - - if (options::indent_ignore_first_continue()) - { - frm.top().SetIndent(get_indent_first_continue(pc)); - } - else - { - frm.top().SetIndent(frm.prev().GetIndent() + options::indent_continue_class_head()); - } - log_indent(); - - frm.top().SetIndentTmp(frm.top().GetIndent()); - frm.top().SetIndentTab(frm.top().GetIndent()); - log_indent_tmp(); - classFound = true; - } - pc = pc->GetNext(); - - if (pc->Is(CT_SPACE)) // Issue #3710 - { - pc = pc->GetNext(); - } - LOG_FMT(LINDLINE, "%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())); - } -null_pc: - - // Throw out any stuff inside a preprocessor - no need to warn - while ( !frm.empty() - && frm.top().GetInPreproc()) - { - frm.pop(__func__, __LINE__, pc); - } - - // Throw out any VBRACE_OPEN at the end - implied with the end of file - while ( !frm.empty() - && frm.top().GetOpenToken() == CT_VBRACE_OPEN) - { - frm.pop(__func__, __LINE__, pc); - } - - for (size_t idx_temp = 1; idx_temp < frm.size(); idx_temp++) - { - LOG_FMT(LWARN, "%s(%d): size is %zu\n", - __func__, __LINE__, frm.size()); - LOG_FMT(LWARN, "%s(%d): File: %s, open_line is %zu, parent is %s: Unmatched %s\n", - __func__, __LINE__, cpd.filename.c_str(), frm.at(idx_temp).GetOpenLine(), - get_token_name(frm.at(idx_temp).GetParent()), - get_token_name(frm.at(idx_temp).GetOpenToken())); - exit(EX_IOERR); - } - - LOG_FMT(LINDLINE, "%s(%d): before quick_align_again\n", __func__, __LINE__); - quick_align_again(); - quick_indent_again(); - LOG_FMT(LINDLINE, "%s(%d): after quick_align_again\n", __func__, __LINE__); -} // indent_text - - -static bool single_line_comment_indent_rule_applies(Chunk *start, bool forward) -{ - LOG_FUNC_ENTRY(); - - if (!start->IsSingleLineComment()) - { - return(false); - } - Chunk *pc = start; - size_t nl_count = 0; - - while ((pc = forward ? pc->GetNext() : pc->GetPrev())->IsNotNullChunk()) - { - if (pc->IsNewline()) - { - if ( nl_count > 0 - || pc->GetNlCount() > 1) - { - return(false); - } - nl_count++; - } - else if (pc->IsSingleLineComment()) - { - nl_count = 0; - } - else if ( pc->Is(CT_COMMENT_MULTI) - || (forward && pc->IsBraceClose()) - || (!forward && pc->IsBraceOpen())) - { - /* - * check for things we wouldn't want to indent the comment for - * example: non-single line comment, closing brace - */ - return(false); - } - else - { - return(true); - } - } - return(false); -} // single_line_comment_indent_rule_applies - - -static bool is_end_of_assignment(Chunk *pc, const ParsingFrame &frm) -{ - return( ( frm.top().GetOpenToken() == CT_ASSIGN_NL - || frm.top().GetOpenToken() == CT_MEMBER - || frm.top().GetOpenToken() == CT_ASSIGN) - && ( pc->IsSemicolon() - || pc->Is(CT_COMMA) - || pc->Is(CT_BRACE_OPEN) - || pc->Is(CT_SPAREN_CLOSE) - || ( pc->Is(CT_SQUARE_OPEN) - && pc->GetParentType() == CT_ASSIGN)) - && pc->GetParentType() != CT_CPP_LAMBDA); -} - - -static size_t calc_comment_next_col_diff(Chunk *pc) -{ - Chunk *next = pc; // assumes pc has a comment type - - LOG_FMT(LCMTIND, "%s(%d): next->Text() is '%s'\n", - __func__, __LINE__, next->Text()); - - // Note: every comment is squashed into a single token - // (including newline chars for multiline comments) and is followed by - // a newline token (unless there are no more tokens left) - do - { - Chunk *newline_token = next->GetNext(); - LOG_FMT(LCMTIND, "%s(%d): newline_token->Text() is '%s', orig line is %zu, orig col is %zu\n", - __func__, __LINE__, newline_token->Text(), newline_token->GetOrigLine(), newline_token->GetOrigCol()); - - if ( newline_token->IsNullChunk() - || newline_token->GetNlCount() > 1) - { - return(5000); // FIXME: Max thresh magic number 5000 - } - next = newline_token->GetNext(); - - if (next->IsNotNullChunk()) - { - LOG_FMT(LCMTIND, "%s(%d): next->Text() is '%s', orig line is %zu, orig col is %zu\n", - __func__, __LINE__, next->Text(), next->GetOrigLine(), next->GetOrigCol()); - } - } while (next->IsComment()); - - if (next->IsNullChunk()) - { - return(5000); // FIXME: Max thresh magic number 5000 - } - LOG_FMT(LCMTIND, "%s(%d): next->Text() is '%s'\n", - __func__, __LINE__, next->Text()); - // here next is the first non comment, non newline token - return(next->GetOrigCol() > pc->GetOrigCol() - ? next->GetOrigCol() - pc->GetOrigCol() - : pc->GetOrigCol() - next->GetOrigCol()); -} - - -static void indent_comment(Chunk *pc, size_t col) -{ - LOG_FUNC_ENTRY(); - char copy[1000]; - - LOG_FMT(LCMTIND, "%s(%d): pc->Text() is '%s', orig line %zu, orig col %zu, level %zu\n", - __func__, __LINE__, pc->ElidedText(copy), pc->GetOrigLine(), pc->GetOrigCol(), pc->GetLevel()); - - // force column 1 comment to column 1 if not changing them - log_rule_B("indent_col1_comment"); - - if ( pc->GetOrigCol() == 1 - && !options::indent_col1_comment() - && !pc->TestFlags(PCF_INSERTED)) - { - LOG_FMT(LCMTIND, "%s(%d): rule 1 - keep in col 1\n", __func__, __LINE__); - reindent_line(pc, 1); - return; - } - Chunk *nl = pc->GetPrev(); - - if (nl->IsNotNullChunk()) - { - LOG_FMT(LCMTIND, "%s(%d): nl->Text() is '%s', orig line %zu, orig col %zu, level %zu\n", - __func__, __LINE__, nl->Text(), nl->GetOrigLine(), nl->GetOrigCol(), nl->GetLevel()); - } - - if (pc->GetOrigCol() > 1) - { - Chunk *prev = nl->GetPrev(); - - if (prev->IsNotNullChunk()) - { - LOG_FMT(LCMTIND, "%s(%d): prev->Text() is '%s', orig line %zu, orig col %zu, level %zu\n", - __func__, __LINE__, prev->Text(), prev->GetOrigLine(), prev->GetOrigCol(), prev->GetLevel()); - log_pcf_flags(LCMTIND, prev->GetFlags()); - } - - if ( prev->IsComment() - && nl->GetNlCount() == 1) - { - const size_t prev_col_diff = (prev->GetOrigCol() > pc->GetOrigCol()) - ? prev->GetOrigCol() - pc->GetOrigCol() - : pc->GetOrigCol() - prev->GetOrigCol(); - LOG_FMT(LCMTIND, "%s(%d): prev_col_diff is %zu\n", - __func__, __LINE__, prev_col_diff); - - /* - * Here we want to align comments that are relatively close one to - * another but not when the comment is a Doxygen comment (Issue #1134) - */ - if (prev_col_diff <= options::indent_comment_align_thresh()) - { - LOG_FMT(LCMTIND, "%s(%d): prev->Text() is '%s', Doxygen_comment(prev) is %s\n", - __func__, __LINE__, prev->Text(), prev->IsDoxygenComment() ? "TRUE" : "FALSE"); - LOG_FMT(LCMTIND, "%s(%d): pc->Text() is '%s', Doxygen_comment(pc) is %s\n", - __func__, __LINE__, pc->Text(), pc->IsDoxygenComment() ? "TRUE" : "FALSE"); - - if (prev->IsDoxygenComment() == pc->IsDoxygenComment()) - { - const size_t next_col_diff = calc_comment_next_col_diff(pc); - LOG_FMT(LCMTIND, "%s(%d): next_col_diff is %zu\n", - __func__, __LINE__, next_col_diff); - - // Align to the previous comment or to the next token? - if ( prev_col_diff <= next_col_diff - || next_col_diff == 5000) // FIXME: Max thresh magic number 5000 - { - LOG_FMT(LCMTIND, "%s(%d): rule 3 - prev comment, coldiff = %zu, now in %zu\n", - __func__, __LINE__, prev_col_diff, pc->GetColumn()); - reindent_line(pc, prev->GetColumn()); - return; - } - } - } - } - } - // check if special single-line-comment-before-code rule applies - log_rule_B("indent_single_line_comments_before"); - - if ( (options::indent_single_line_comments_before() > 0) - && single_line_comment_indent_rule_applies(pc, true)) - { - LOG_FMT(LCMTIND, "%s(%d): rule 4 - indent single line comments before code, now in %zu\n", - __func__, __LINE__, pc->GetColumn()); - reindent_line(pc, col + options::indent_single_line_comments_before()); - return; - } - // check if special single-line-comment-after-code rule applies - log_rule_B("indent_single_line_comments_after"); - - if ( (options::indent_single_line_comments_after() > 0) - && single_line_comment_indent_rule_applies(pc, false)) - { - LOG_FMT(LCMTIND, "%s(%d): rule 4 - indent single line comments after code, now in %zu\n", - __func__, __LINE__, pc->GetColumn()); - reindent_line(pc, col + options::indent_single_line_comments_after()); - return; - } - log_rule_B("indent_comment"); - - if ( pc->GetOrigCol() > 1 - && !options::indent_comment()) - { - LOG_FMT(LCMTIND, "%s(%d): rule 5 - keep in orig col\n", __func__, __LINE__); - reindent_line(pc, pc->GetOrigCol()); - return; - } - LOG_FMT(LCMTIND, "%s(%d): rule 6 - fall-through, stay in %zu\n", - __func__, __LINE__, col); - reindent_line(pc, col); -} // indent_comment - - -bool ifdef_over_whole_file() -{ - LOG_FUNC_ENTRY(); - - // if requested, treat an #if that guards the entire file the same as any other #if - // if running as frag, assume #if is not a guard - if ( options::pp_indent_in_guard() - || cpd.frag) - { - return(false); - } - - // the results for this file are cached - if (cpd.ifdef_over_whole_file) - { - return(cpd.ifdef_over_whole_file > 0); - } - Chunk *start_pp = Chunk::NullChunkPtr; - Chunk *end_pp = Chunk::NullChunkPtr; - size_t IFstage = 0; - - for (Chunk *pc = Chunk::GetHead(); pc->IsNotNullChunk(); pc = pc->GetNext()) - { - LOG_FMT(LNOTE, "%s(%d): pc->pp level is %zu, pc orig line is %zu, orig col is %zu, pc->Text() is '%s'\n", - __func__, __LINE__, pc->GetPpLevel(), pc->GetOrigLine(), pc->GetOrigCol(), pc->Text()); - - if (pc->IsCommentOrNewline()) - { - continue; - } - - if (IFstage == 0) // 0 is BEGIN - { - // Check the first preprocessor, make sure it is an #if type - if (pc->IsNot(CT_PREPROC)) - { - break; - } - Chunk *next = pc->GetNext(); - - if ( next->IsNullChunk() - || next->IsNot(CT_PP_IF)) - { - break; - } - IFstage = 1; // 1 is CT_PP_IF found - start_pp = pc; - } - else if (IFstage == 1) // 1 is CT_PP_IF found - { - // Scan until a preprocessor at level 0 is found - the close to the #if - if (pc->Is(CT_PREPROC)) - { - if (pc->GetPpLevel() == 0) - { - IFstage = 2; - end_pp = pc; - } - } - continue; - } - else if (IFstage == 2) - { - // We should only see the rest of the preprocessor - if ( pc->Is(CT_PREPROC) - || !pc->TestFlags(PCF_IN_PREPROC)) - { - IFstage = 0; - break; - } - } - } - - cpd.ifdef_over_whole_file = (IFstage == 2) ? 1 : -1; - - if (cpd.ifdef_over_whole_file > 0) - { - start_pp->SetFlagBits(PCF_WF_IF); - end_pp->SetFlagBits(PCF_WF_ENDIF); - } - LOG_FMT(LNOTE, "The whole file is%s covered by a #IF\n", - (cpd.ifdef_over_whole_file > 0) ? "" : " NOT"); - return(cpd.ifdef_over_whole_file > 0); -} // ifdef_over_whole_file - - -void indent_preproc() -{ - LOG_FUNC_ENTRY(); - - // Scan to see if the whole file is covered by one #ifdef - const size_t pp_level_sub = ifdef_over_whole_file() ? 1 : 0; - - for (Chunk *pc = Chunk::GetHead(); pc->IsNotNullChunk(); pc = pc->GetNext()) - { - LOG_FMT(LPPIS, "%s(%d): orig line is %zu, orig col is %zu, pc->Text() is '%s'\n", - __func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->Text()); - - if (pc->IsNot(CT_PREPROC)) - { - continue; - } - Chunk *next = pc->GetNextNcNnl(); - - if (next->IsNullChunk()) - { - break; - } - const size_t pp_level = (pc->GetPpLevel() > pp_level_sub) - ? pc->GetPpLevel() - pp_level_sub : 0; - - // Adjust the indent of the '#' - if (options::pp_indent() & IARF_ADD) - { - log_rule_B("pp_indent ADD"); - reindent_line(pc, 1 + pp_level * options::pp_indent_count()); - } - else if (options::pp_indent() & IARF_REMOVE) - { - log_rule_B("pp_indent REMOVE"); - reindent_line(pc, 1); - } - // Add spacing by adjusting the length - log_rule_B("pp_space_after"); - - if ( (options::pp_space_after() != IARF_IGNORE) - && next->IsNotNullChunk()) - { - if (options::pp_space_after() & IARF_ADD) - { - log_rule_B("pp_space_after ADD"); - const size_t mult = options::pp_space_count(); - reindent_line(next, pc->GetColumn() + pc->Len() + (pp_level * mult)); - } - else if (options::pp_space_after() & IARF_REMOVE) - { - log_rule_B("pp_space_after REMOVE"); - reindent_line(next, pc->GetColumn() + pc->Len()); - } - } - // Mark as already handled if not region stuff or in column 1 - log_rule_B("pp_indent_at_level"); - - bool at_file_level = pc->GetBraceLevel() <= ((pc->GetParentType() == CT_PP_DEFINE) ? 1 : 0); - - if ( ( ( at_file_level - && !options::pp_indent_at_level0()) - || ( !at_file_level - && !options::pp_indent_at_level())) - && pc->GetParentType() != CT_PP_REGION - && pc->GetParentType() != CT_PP_ENDREGION) - { - log_rule_B("pp_define_at_level"); - - if ( !options::pp_define_at_level() - || pc->GetParentType() != CT_PP_DEFINE) - { - pc->SetFlagBits(PCF_DONT_INDENT); - } - } - LOG_FMT(LPPIS, "%s(%d): orig line %zu to %zu (len %zu, next->col %zu)\n", - __func__, __LINE__, pc->GetOrigLine(), 1 + pp_level, pc->Len(), - next ? next->GetColumn() : -1); - } -} // indent_preproc |