summaryrefslogtreecommitdiffstats
path: root/debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/indent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/indent.cpp')
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/indent.cpp4776
1 files changed, 0 insertions, 4776 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/indent.cpp b/debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/indent.cpp
deleted file mode 100644
index e23dc25c..00000000
--- a/debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/indent.cpp
+++ /dev/null
@@ -1,4776 +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 "frame_list.h"
-#include "options_for_QT.h"
-#include "prototypes.h"
-#include "quick_align_again.h"
-#include "space.h"
-
-#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_funcion_name(
- * param1, param2);
- * a_really_long_funcion_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 ParseFrame &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 ParseFrame &frm);
-
-
-void indent_to_column(Chunk *pc, size_t column)
-{
- LOG_FUNC_ENTRY();
-
- if (column < pc->column)
- {
- column = pc->column;
- }
- 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 == nullptr
- || column == pc->column)
- {
- 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->orig_line, pc->column, pc->Text(),
- get_token_name(pc->type), column);
-
- const auto col_delta = static_cast<int>(column) - static_cast<int>(pc->column);
- size_t min_col = column;
-
- pc->column = 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()
- && get_chunk_parent_type(pc) != CT_COMMENT_EMBED)
- {
- log_rule_B("indent_relative_single_line_comments");
- almod = ( chunk_is_single_line_comment(pc)
- && 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->column = max(pc->orig_col, min_col);
- }
- else if (almod == align_mode_e::KEEP_REL)
- {
- // Keep same relative column
- auto orig_delta = static_cast<int>(pc->orig_col) - static_cast<int>(prev->orig_col);
- orig_delta = max<int>(orig_delta, min_delta); // keeps orig_delta positive
-
- pc->column = prev->column + static_cast<size_t>(orig_delta);
- }
- else // SHIFT
- {
- // Shift by the same amount, keep above negative values
- pc->column = ( col_delta >= 0
- || cast_abs(pc->column, col_delta) < pc->column)
- ? pc->column + col_delta : 0;
- pc->column = max(pc->column, 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->type), pc->orig_line, pc->column, pc->orig_col);
- } while ( pc->IsNotNullChunk()
- && pc->nl_count == 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->orig_line, pc->orig_col, pc->ElidedText(copy),
- get_token_name(pc->type), get_token_name(get_chunk_parent_type(pc)),
- column);
- log_func_stack_inline(LINDLINE);
-
- if (column == pc->column)
- {
- return;
- }
- auto col_delta = static_cast<int>(column) - static_cast<int>(pc->column);
- auto min_col = column;
-
- pc->column = 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->flags.test(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->flags.test(PCF_IN_QT_MACRO))
- {
- LOG_FMT(LINDLINE, "FLAGS is set: PCF_IN_QT_MACRO\n");
- save_set_options_for_QT(pc->level);
- }
- }
- Chunk *next = pc->GetNext();
-
- if (next->IsNullChunk())
- {
- break;
- }
-
- if (pc->nl_count)
- {
- 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
- && chunk_is_single_line_comment(pc)
- && options::indent_relative_single_line_comments());
-
- if ( is_comment
- && get_chunk_parent_type(pc) != CT_COMMENT_EMBED
- && !keep)
- {
- pc->column = max(pc->orig_col, min_col);
- LOG_FMT(LINDLINE, "%s(%d): set comment on line %zu to col %zu (orig %zu)\n",
- __func__, __LINE__, pc->orig_line, pc->column, pc->orig_col);
- }
- else
- {
- const auto tmp_col = static_cast<int>(pc->column) + col_delta;
- pc->column = max(tmp_col, static_cast<int>(min_col));
-
- LOG_FMT(LINDLINED, "%s(%d): set column of ", __func__, __LINE__);
-
- if (chunk_is_token(pc, CT_NEWLINE))
- {
- LOG_FMT(LINDLINED, "<Newline>");
- }
- else
- {
- LOG_FMT(LINDLINED, "'%s'", pc->Text());
- }
- LOG_FMT(LINDLINED, " to %zu (orig %zu)\n", pc->column, pc->orig_col);
- }
- } while ( pc->IsNotNullChunk()
- && pc->nl_count == 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->orig_line, 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->level);
-
- if (continuation->IsNotNullChunk())
- {
- continuation = continuation->GetNext();
-
- if (continuation->IsNotNullChunk())
- {
- return(continuation->orig_col);
- }
- }
- return(0);
-}
-
-
-static size_t calc_indent_continue(const ParseFrame &frm, size_t pse_tos)
-{
- log_rule_B("indent_continue");
- const int ic = options::indent_continue();
-
- if ( ic < 0
- && frm.at(pse_tos).indent_cont)
- {
- return(frm.at(pse_tos).indent);
- }
- return(frm.at(pse_tos).indent + abs(ic));
-}
-
-
-static size_t calc_indent_continue(const ParseFrame &frm)
-{
- return(calc_indent_continue(frm, frm.size() - 1));
-}
-
-
-static Chunk *candidate_chunk_first_on_line(Chunk *pc)
-{
- Chunk *first = chunk_first_on_line(pc);
-
- log_rule_B("indent_inside_ternary_operator");
-
- if ( options::indent_inside_ternary_operator()
- && ( chunk_is_token(first, CT_QUESTION)
- || chunk_is_token(first, 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 = Chunk::NullChunkPtr;
-
- if (pc != nullptr)
- {
- tmp = pc->GetPrevNc();
- }
-
- if (from_brace)
- {
- return(pc);
- }
-
- // Skip to open paren in ':^TYPE *(ARGS) {'
- if (chunk_is_paren_close(tmp))
- {
- tmp = chunk_skip_to_match_rev(tmp)->GetPrevNc();
- }
-
- // // Check for star in ':^TYPE *(ARGS) {'. Issue 2477
- if (chunk_is_token(tmp, CT_PTR_TYPE))
- {
- tmp = tmp->GetPrevNc();
- }
-
- // Check for type in ':^TYPE *(ARGS) {'. Issue 2482
- if (chunk_is_token(tmp, CT_TYPE))
- {
- tmp = tmp->GetPrevNc();
- }
- // Check for caret in ':^TYPE *(ARGS) {'
- // Store the caret position
- Chunk *caret_tmp = Chunk::NullChunkPtr;
-
- if ( tmp->IsNotNullChunk()
- && tmp->type == CT_OC_BLOCK_CARET)
- {
- caret_tmp = tmp;
- }
- else
- {
- caret_tmp = tmp->GetPrevType(CT_OC_BLOCK_CARET, -1);
- tmp = caret_tmp;
- }
-
- // If we still cannot find caret then return first chunk on the line
- if ( tmp->IsNullChunk()
- || tmp->type != 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->type != CT_OC_COLON)
- {
- return(candidate_chunk_first_on_line(pc));
- }
- else
- {
- return(tmp);
- }
- }
- tmp = tmp->GetPrevNc();
-
- if (from_keyword)
- {
- if ( tmp->IsNullChunk()
- || ( tmp->type != CT_OC_MSG_NAME
- && tmp->type != 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 ParseFrame &frm)
-{
- LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos is %zu, ...indent is %zu\n",
- func, line, frm.size() - 1, frm.top().indent);
-}
-
-
-#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 ParseFrame &frm)
-{
- LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos is %zu, prev....indent is %zu\n",
- func, line, frm.size() - 1, frm.prev().indent);
-}
-
-
-#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 ParseFrame &frm)
-{
- LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos is %zu, ...indent_tmp is %zu\n",
- func, line, frm.size() - 1, frm.top().indent_tmp);
-}
-
-
-static void quick_indent_again(void)
-{
- LOG_FUNC_ENTRY();
-
- for (Chunk *pc = Chunk::GetHead(); pc->IsNotNullChunk(); pc = pc->GetNext())
- {
- if (pc->indent.ref == nullptr)
- {
- continue;
- }
- Chunk *tmp = pc->GetPrev();
-
- if (!chunk_is_newline(tmp))
- {
- continue;
- }
- const size_t col = pc->indent.ref->column + pc->indent.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->orig_line, pc->Text(), col,
- pc->indent.ref->Text(), pc->indent.ref->orig_line,
- pc->indent.ref->column);
- }
-}
-
-
-void indent_text(void)
-{
- 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;
-
-
- std::vector<ParseFrame> frames;
- ParseFrame frm{};
-
-
- Chunk *pc = Chunk::GetHead();
- bool classFound = false; // Issue #672
-
- while ( pc != nullptr
- && pc->IsNotNullChunk())
- {
- LOG_FMT(LINDLINE, "%s(%d): orig_line is %zu, orig_col is %zu, for '%s'\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->Text());
- // forces string literal to column-1 [Fix for 1246]
- log_rule_B("indent_col1_multi_string_literal");
-
- if ( (pc->type == 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()->type == CT_NEWLINE))
- {
- indent_column_set(1);
- reindent_line(pc, indent_column);
- pc = pc->GetNext();
- did_newline = false;
- }
- }
-
- if (chunk_is_token(pc, CT_NEWLINE))
- {
- LOG_FMT(LINDLINE, "%s(%d): orig_line is %zu, <Newline>\n",
- __func__, __LINE__, pc->orig_line);
- }
- else if (chunk_is_token(pc, CT_NL_CONT))
- {
- LOG_FMT(LINDLINE, "%s(%d): orig_line is %zu, CT_NL_CONT\n",
- __func__, __LINE__, pc->orig_line);
- }
- 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->orig_line, pc->orig_col, pc->column, pc->ElidedText(copy));
- log_pcf_flags(LINDLINE, pc->flags);
- }
- 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->orig_line, get_token_name(pc->type));
- }
- // Handle preprocessor transitions
- log_rule_B("indent_brace_parent");
- const size_t parent_token_indent = (options::indent_brace_parent())
- ? token_indent(get_chunk_parent_type(pc)) : 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 ( get_chunk_parent_type(pc) == CT_FUNC_DEF
- || ( chunk_is_token(pc, CT_COMMENT)
- && next->IsNotNullChunk()
- && get_chunk_parent_type(next) == CT_FUNC_DEF))
- {
- in_func_def = true;
- frm.push(pc, __func__, __LINE__);
- frm.top().indent_tmp = 1;
- frm.top().indent = 1;
- frm.top().indent_tab = 1;
- }
- }
- else
- {
- Chunk *prev = pc->GetPrev();
-
- if ( chunk_is_token(prev, CT_BRACE_CLOSE)
- && get_chunk_parent_type(prev) == 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
- }
- }
- // Clean up after a #define, etc
- const bool in_preproc = pc->flags.test(PCF_IN_PREPROC);
-
- if (!in_preproc)
- {
- while ( !frm.empty()
- && frm.top().in_preproc)
- {
- const E_Token type = frm.top().type;
- LOG_FMT(LINDLINE, "%s(%d): pc->orig_line is %zu, orig_col is %zu, Text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- 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().type == 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
- }
- }
- else if (chunk_is_token(pc, CT_PREPROC)) // #
- {
- // Close out PP_IF_INDENT before playing with the parse frames
- if ( frm.top().type == CT_PP_IF_INDENT
- && ( get_chunk_parent_type(pc) == CT_PP_ENDIF
- || get_chunk_parent_type(pc) == 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
- ParseFrame frmbkup = frm;
- fl_check(frames, 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()
- && get_chunk_parent_type(pc) == CT_PP_REGION)
- {
- Chunk *next = pc->GetNext();
-
- if (next->IsNullChunk())
- {
- break;
- }
- // Hack to get the logs to look right
- set_chunk_type(next, CT_PP_REGION_INDENT);
- frm.push(next, __func__, __LINE__);
- set_chunk_type(next, CT_PP_REGION);
-
- // Indent one level
- frm.top().indent = frm.prev().indent + indent_size;
- log_indent();
-
- frm.top().indent_tab = frm.prev().indent_tab + indent_size;
- frm.top().indent_tmp = frm.top().indent;
- frm.top().in_preproc = false;
- log_indent_tmp();
- }
- // If option set, remove indent inside switch statement
- log_rule_B("indent_switch_pp");
-
- if ( frm.top().type == 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().indent, indent_size);
-
- if (frm.top().indent >= indent_size)
- {
- frm.prev().indent = frm.top().indent - 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()
- && ( get_chunk_parent_type(pc) == CT_PP_IF
- || get_chunk_parent_type(pc) == 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->type != CT_NEWLINE)
- {
- if ( (chunk_is_token(preproc_next, CT_BRACE_OPEN))
- || (chunk_is_token(preproc_next, 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 ( ( chunk_is_token(preproc_next, CT_FUNC_DEF)
- && !options::pp_indent_func_def())
- || ( chunk_is_token(preproc_next, CT_CASE)
- && !options::pp_indent_case())
- || ( chunk_is_token(preproc_next, 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->type;
- set_chunk_type(next, CT_PP_IF_INDENT);
- frm.push(next, __func__, __LINE__);
- set_chunk_type(next, memtype);
-
- if (should_ignore_preproc)
- {
- // Preserve original indentation
- frm.top().indent = pc->GetNextNl()->GetNext()->orig_col;
- log_indent();
- }
- else
- {
- // Indent one level except if the #if is a #include guard
- size_t extra = ( pc->pp_level == 0
- && ifdef_over_whole_file())
- ? 0 : indent_size;
-
- frm.top().indent = frm.prev().indent + extra;
- log_indent();
-
- frm.top().indent_tab = frm.prev().indent_tab + extra;
- }
- frm.top().indent_tmp = frm.top().indent;
- frm.top().in_preproc = false;
- log_indent_tmp();
- }
- }
- log_rule_B("indent_member_single");
-
- if (options::indent_member_single())
- {
- if (get_chunk_parent_type(pc) == CT_PP_IF)
- {
- // do nothing
- }
- else if (get_chunk_parent_type(pc) == CT_PP_ELSE)
- {
- if ( frm.top().type == CT_MEMBER
- && frm.top().pop_pc != nullptr
- && frm.top().pc != frmbkup.top().pc)
- {
- Chunk *tmp = pc->GetNextNcNnlNpp();
-
- if (tmp->IsNotNullChunk())
- {
- if ( chunk_is_token(tmp, CT_WORD)
- || chunk_is_token(tmp, CT_TYPE))
- {
- tmp = pc->GetNextNcNnlNpp();
- }
- else if ( chunk_is_token(tmp, CT_FUNC_CALL)
- || chunk_is_token(tmp, CT_FPAREN_OPEN))
- {
- tmp = tmp->GetNextType(CT_FPAREN_CLOSE, tmp->level);
-
- if (tmp->IsNotNullChunk())
- {
- tmp = pc->GetNextNcNnlNpp();
- }
- }
-
- if (tmp->IsNotNullChunk())
- {
- frm.top().pop_pc = tmp;
- }
- }
- }
- }
- else if (get_chunk_parent_type(pc) == CT_PP_ENDIF)
- {
- if ( frmbkup.top().type == CT_MEMBER
- && frm.top().type == CT_MEMBER)
- {
- frm.top().pop_pc = frmbkup.top().pop_pc;
- }
- }
- }
- // 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 ( get_chunk_parent_type(pc) == CT_PP_DEFINE
- || get_chunk_parent_type(pc) == CT_PP_UNDEF)
- {
- log_rule_B("pp_define_at_level");
- frm.top().indent_tmp = options::pp_define_at_level()
- ? frm.prev().indent_tmp : 1;
- frm.top().indent = frm.top().indent_tmp + indent_size;
- log_indent();
-
- frm.top().indent_tab = frm.top().indent;
- log_indent_tmp();
- }
- else if ( ( get_chunk_parent_type(pc) == CT_PP_PRAGMA
- || get_chunk_parent_type(pc) == CT_PP_OTHER)
- && options::pp_define_at_level())
- {
- log_rule_B("pp_define_at_level");
- frm.top().indent_tmp = frm.prev().indent_tmp;
- frm.top().indent = frm.top().indent_tmp + indent_size;
- log_indent();
-
- frm.top().indent_tab = frm.top().indent;
- log_indent_tmp();
- }
- else if ( get_chunk_parent_type(pc) == CT_PP_INCLUDE
- && options::pp_include_at_level())
- {
- log_rule_B("pp_include_at_level");
- frm.top().indent_tmp = frm.prev().indent_tmp;
- frm.top().indent = frm.top().indent_tmp + indent_size;
- log_indent();
-
- frm.top().indent_tab = frm.top().indent;
- log_indent_tmp();
- }
- else
- {
- if ( (frm.prev().type == CT_PP_REGION_INDENT)
- || ( (frm.prev().type == CT_PP_IF_INDENT)
- && (frm.top().type != CT_PP_ENDIF)))
- {
- frm.top().indent = frm.prev(2).indent;
- log_indent();
- }
- else
- {
- frm.top().indent = frm.prev().indent;
- log_indent();
- }
- log_indent();
-
-
- auto val = 0;
-
- if ( get_chunk_parent_type(pc) == CT_PP_REGION
- || get_chunk_parent_type(pc) == CT_PP_ENDREGION)
- {
- log_rule_B("pp_indent_region");
- val = options::pp_indent_region();
- log_indent();
- }
- else if ( get_chunk_parent_type(pc) == CT_PP_IF
- || get_chunk_parent_type(pc) == CT_PP_ELSE
- || get_chunk_parent_type(pc) == CT_PP_ENDIF)
- {
- log_rule_B("pp_indent_if");
- val = options::pp_indent_if();
- log_indent();
- }
-
- if (val != 0)
- {
- auto &indent = frm.top().indent;
-
- indent = (val > 0) ? val // reassign if positive val,
- : (cast_abs(indent, val) < indent) // else if no underflow
- ? (indent + val) : 0; // reduce, else 0
- }
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
- }
- }
- // Check for close XML tags "</..."
- log_rule_B("indent_xml_string");
-
- if (options::indent_xml_string() > 0)
- {
- if (chunk_is_token(pc, CT_STRING))
- {
- if ( pc->Len() > 4
- && xml_indent > 0
- && pc->str[1] == '<'
- && pc->str[2] == '/')
- {
- log_rule_B("indent_xml_string");
- xml_indent -= options::indent_xml_string();
- }
- }
- else if ( !pc->IsComment()
- && !chunk_is_newline(pc))
- {
- 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 ( !chunk_is_newline(pc)
- && !pc->IsComment()
- && frm.top().level > pc->level)
- {
- LOG_FMT(LINDLINE, "%s(%d): pc->orig_line is %zu, orig_col is %zu, Text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- if (frm.top().level >= pc->level)
- {
- // process virtual braces closes (no text output)
- if ( chunk_is_token(pc, CT_VBRACE_CLOSE)
- && frm.top().type == 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
-
- if (pc->IsNullChunk())
- {
- // need to break out of both the do and while loops
- goto null_pc;
- }
- }
-
- if ( chunk_is_token(pc, CT_BRACE_CLOSE)
- && get_chunk_parent_type(pc) == CT_ENUM)
- {
- Chunk *prev_ncnl = pc->GetPrevNcNnl();
- LOG_FMT(LINDLINE, "%s(%d): prev_ncnl is '%s', prev_ncnl->orig_line is %zu, prev_ncnl->orig_col is %zu\n",
- __func__, __LINE__, prev_ncnl->Text(), prev_ncnl->orig_line, prev_ncnl->orig_col);
-
- if (chunk_is_token(prev_ncnl, 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- 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().type == CT_COND_COLON)
- && ( chunk_is_semicolon(pc)
- || chunk_is_token(pc, CT_COMMA)
- || chunk_is_token(pc, CT_OC_MSG_NAME)
- || chunk_is_token(pc, 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- // End any assign operations with a semicolon on the same level
- if ( chunk_is_semicolon(pc)
- && ( (frm.top().type == CT_IMPORT)
- || (frm.top().type == 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- // End any custom macro-based open/closes
- if ( !token_used
- && (frm.top().type == CT_MACRO_OPEN)
- && chunk_is_token(pc, 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- // End any CPP/ObjC class colon stuff
- if ( ( (frm.top().type == CT_CLASS_COLON)
- || (frm.top().type == CT_CONSTR_COLON))
- && ( chunk_is_token(pc, CT_BRACE_OPEN)
- || chunk_is_token(pc, CT_OC_END)
- || chunk_is_token(pc, CT_OC_SCOPE)
- || chunk_is_token(pc, CT_OC_PROPERTY)
- || chunk_is_token(pc, CT_TYPEDEF) // Issue #2675
- || chunk_is_token(pc, CT_MACRO_OPEN)
- || chunk_is_token(pc, CT_MACRO_CLOSE)
- || ( language_is_set(LANG_OC)
- && pc->IsComment()
- && get_chunk_parent_type(pc) == CT_COMMENT_WHOLE) // Issue #2675
- || chunk_is_semicolon(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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- // End ObjC class colon stuff inside of generic definition (like Test<T1: id<T3>>)
- if ( (frm.top().type == CT_CLASS_COLON)
- && chunk_is_token(pc, CT_ANGLE_CLOSE)
- && get_chunk_parent_type(pc) == 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- 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)
- && chunk_is_token(pc, CT_SQUARE_CLOSE)
- && get_chunk_parent_type(pc) == CT_OC_AT
- && frm.top().level >= pc->level)
- {
- size_t count = 1;
- Chunk *next = pc->GetNextNc();
-
- while ( next->IsNotNullChunk()
- && ( ( chunk_is_token(next, CT_BRACE_CLOSE)
- && get_chunk_parent_type(next) == CT_OC_AT)
- || ( chunk_is_token(next, CT_SQUARE_CLOSE)
- && get_chunk_parent_type(next) == CT_OC_AT)
- || ( chunk_is_token(next, CT_SQUARE_CLOSE)
- && get_chunk_parent_type(next) == CT_OC_MSG)))
- {
- count++;
- next = next->GetNextNc();
- }
- count = std::min(count, frm.size());
-
- if (count > 0)
- {
- while (count-- > 0)
- {
- if (frm.top().type == CT_SQUARE_OPEN)
- {
- if (frm.paren_count == 0)
- {
- fprintf(stderr, "%s(%d): frm.paren_count is ZERO, cannot be decremented, at line %zu, column %zu\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col);
- log_flush(true);
- exit(EX_SOFTWARE);
- }
- frm.paren_count--;
- }
- LOG_FMT(LINDLINE, "%s(%d): pc->orig_line is %zu, orig_col is %zu, Text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- if (next)
- {
- // 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
- }
- // Indent the brace to match outer most brace/square
- indent_column_set(frm.top().indent_tmp);
- continue;
- }
- }
-
- // a case is ended with another case or a close brace
- if ( (frm.top().type == CT_CASE)
- && ( chunk_is_token(pc, CT_BRACE_CLOSE)
- || chunk_is_token(pc, 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- if (frm.top().pop_pc != nullptr)
- {
- 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().pop_pc->orig_line, frm.top().pop_pc->orig_col,
- frm.top().pop_pc->Text(), get_token_name(frm.top().pop_pc->type));
- }
- LOG_FMT(LINDLINE, "%s(%d): pc->orig_line is %zu, orig_col is %zu, Text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
-
- if ( (frm.top().type == CT_MEMBER)
- && frm.top().pop_pc == 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- if ( (frm.top().type == CT_LAMBDA)
- && ( chunk_is_token(pc, CT_SEMICOLON)
- || chunk_is_token(pc, CT_COMMA)
- || chunk_is_token(pc, 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- 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().type == CT_ACCESS)
- && ( chunk_is_token(pc, CT_BRACE_CLOSE)
- || chunk_is_token(pc, 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- // return & throw are ended with a semicolon
- if ( chunk_is_semicolon(pc)
- && ( (frm.top().type == CT_RETURN)
- || (frm.top().type == 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- // an OC SCOPE ('-' or '+') ends with a semicolon or brace open
- if ( (frm.top().type == CT_OC_SCOPE)
- && ( chunk_is_semicolon(pc)
- || chunk_is_token(pc, 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- /*
- * a typedef and an OC SCOPE ('-' or '+') ends with a semicolon or
- * brace open
- */
- if ( (frm.top().type == CT_TYPEDEF)
- && ( chunk_is_semicolon(pc)
- || chunk_is_paren_open(pc)
- || chunk_is_token(pc, 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- // an SQL EXEC is ended with a semicolon
- if ( (frm.top().type == CT_SQL_EXEC)
- && chunk_is_semicolon(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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- // an CLASS is ended with a semicolon or brace open
- if ( (frm.top().type == CT_CLASS)
- && ( chunk_is_token(pc, CT_CLASS_COLON)
- || chunk_is_token(pc, CT_BRACE_OPEN)
- || chunk_is_semicolon(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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- 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().type != CT_SQUARE_OPEN)
- && frm.top().level >= pc->level
- && ( chunk_is_token(pc, CT_OC_MSG_FUNC)
- || chunk_is_token(pc, 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- // Close out parenthesis and squares
- if ( (frm.top().type == (pc->type - 1))
- && ( chunk_is_token(pc, CT_PAREN_CLOSE)
- || chunk_is_token(pc, CT_LPAREN_CLOSE) // Issue #3054
- || chunk_is_token(pc, CT_SPAREN_CLOSE)
- || chunk_is_token(pc, CT_FPAREN_CLOSE)
- || chunk_is_token(pc, CT_SQUARE_CLOSE)
- || chunk_is_token(pc, CT_ANGLE_CLOSE)))
- {
- LOG_FMT(LINDLINE, "%s(%d): pc->orig_line is %zu, orig_col is %zu, Text() is '%s', type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
-
- if (frm.paren_count == 0)
- {
- fprintf(stderr, "%s(%d): frm.paren_count is ZERO, cannot be decremented, at line %zu, column %zu\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col);
- log_flush(true);
- exit(EX_SOFTWARE);
- }
- frm.paren_count--;
- }
- }
- } while (old_frm_size > frm.size());
-
- // Grab a copy of the current indent
- indent_column_set(frm.top().indent_tmp); // Issue #3294
- log_indent_tmp();
-
- log_rule_B("indent_single_newlines");
-
- if ( chunk_is_token(pc, CT_NEWLINE)
- && options::indent_single_newlines())
- {
- pc->nl_column = indent_column;
- }
-
- if ( !chunk_is_newline(pc)
- && !pc->IsComment()
- && 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->orig_line, pc->orig_col, 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_cont=%d level=%zu pc->brace_level=%zu]\n",
- ttidx,
- frm.at(ttidx).pc->orig_line,
- frm.at(ttidx).pc->orig_col,
- frm.at(ttidx).pc->Text(),
- get_token_name(frm.at(ttidx).type),
- get_token_name(frm.at(ttidx).pc->parent_type),
- frm.at(ttidx).indent_tmp,
- frm.at(ttidx).indent,
- frm.at(ttidx).brace_indent,
- frm.at(ttidx).indent_tab,
- frm.at(ttidx).indent_cont,
- frm.at(ttidx).level,
- frm.at(ttidx).pc->brace_level);
- }
- }
- 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->orig_line, pc->orig_col, pc->column, pc->ElidedText(copy));
-
- // Issue #672
- if ( chunk_is_token(pc, 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- 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 = ( ( chunk_is_token(pc, CT_BRACE_CLOSE)
- || chunk_is_token(pc, CT_BRACE_OPEN))
- && options::indent_braces()
- && ( !options::indent_braces_no_func()
- || get_chunk_parent_type(pc) != CT_FUNC_DEF)
- && ( !options::indent_braces_no_func()
- || get_chunk_parent_type(pc) != CT_FUNC_CLASS_DEF)
- && ( !options::indent_braces_no_class()
- || get_chunk_parent_type(pc) != CT_CLASS)
- && ( !options::indent_braces_no_struct()
- || get_chunk_parent_type(pc) != CT_STRUCT));
- LOG_FMT(LINDENT, "%s(%d): brace_indent is %s\n",
- __func__, __LINE__, brace_indent ? "TRue" : "FAlse");
-
- if (chunk_is_token(pc, CT_BRACE_CLOSE))
- {
- if (language_is_set(LANG_OC))
- {
- if ( frm.top().type == CT_BRACE_OPEN
- && frm.top().level >= pc->level)
- {
- size_t count = 1;
- Chunk *next = pc->GetNextNc();
-
- while ( next->IsNotNullChunk()
- && ( ( chunk_is_token(next, CT_BRACE_CLOSE)
- && get_chunk_parent_type(next) == CT_OC_AT)
- || ( chunk_is_token(next, CT_SQUARE_CLOSE)
- && get_chunk_parent_type(next) == CT_OC_AT)
- || ( chunk_is_token(next, CT_SQUARE_CLOSE)
- && get_chunk_parent_type(next) == CT_OC_MSG)))
- {
- 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
- && chunk_is_token(pc, CT_BRACE_CLOSE)
- && get_chunk_parent_type(pc) == CT_OC_AT)
- {
- if (frm.top().ip.ref)
- {
- pc->indent.ref = frm.top().ip.ref;
- pc->indent.delta = 0;
- }
-
- while (count-- > 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
-
- if (next)
- {
- // 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
- }
-
- // Indent the brace to match outer most brace/square
- if (frm.top().indent_cont)
- {
- indent_column_set(frm.top().indent_tmp - indent_size);
- }
- else
- {
- indent_column_set(frm.top().indent_tmp);
- }
- }
- else
- {
- // Indent the brace to match the open brace
- indent_column_set(frm.top().brace_indent);
-
- if (frm.top().ip.ref)
- {
- pc->indent.ref = frm.top().ip.ref;
- pc->indent.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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
- }
- }
- else if (frm.top().brace_indent) // Issue #3421
- {
- // Indent the brace to match the open brace
- indent_column_set(frm.top().brace_indent);
-
- if (frm.top().ip.ref)
- {
- pc->indent.ref = frm.top().ip.ref;
- pc->indent.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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
- }
- else if (chunk_is_token(pc, 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().indent + iMinIndent;
-
- log_rule_B("indent_vbrace_open_on_tabstop");
-
- if (options::indent_vbrace_open_on_tabstop())
- {
- iNewIndent = next_tab_column(iNewIndent);
- }
- frm.top().indent = iNewIndent;
- log_indent();
- frm.top().indent_tmp = frm.top().indent;
- frm.top().indent_tab = frm.top().indent;
- log_indent_tmp();
-
- // Always indent on virtual braces
- indent_column_set(frm.top().indent_tmp);
- }
- else if ( chunk_is_token(pc, CT_BRACE_OPEN)
- && ( pc->next != nullptr
- && pc->next->type != CT_NAMESPACE))
- {
- LOG_FMT(LINDENT2, "%s(%d): orig_line is %zu, orig_col is %zu, Text() is '%s'\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->Text());
- frm.push(pc, __func__, __LINE__);
-
- log_rule_B("indent_macro_brace");
-
- if ( !options::indent_macro_brace()
- && frm.prev().type == CT_PP_DEFINE
- && frm.prev().open_line == frm.top().open_line)
- {
- LOG_FMT(LINDENT2, "%s(%d): indent_macro_brace\n", __func__, __LINE__);
- }
- else if ( options::indent_cpp_lambda_body()
- && get_chunk_parent_type(pc) == CT_CPP_LAMBDA)
- {
- log_rule_B("indent_cpp_lambda_body");
- frm.top().brace_indent = frm.prev().indent;
-
- Chunk *head = frm.top().pc->GetPrevNcNnlNpp();
- Chunk *tail = nullptr;
- Chunk *frm_prev = frm.prev().pc;
- bool enclosure = ( frm_prev->parent_type != CT_FUNC_DEF // Issue #3407
- && frm_prev != chunk_skip_to_match(frm_prev));
- bool linematch = true;
-
- for (auto it = frm.rbegin(); it != frm.rend() && tail == nullptr; ++it)
- {
- if (it->pc && it->pc != frm.top().pc)
- {
- linematch &= are_chunks_in_same_line(it->pc, head);
- }
- Chunk *match = chunk_skip_to_match(it->pc);
-
- if (match == nullptr)
- {
- continue;
- }
- Chunk *target = match->GetNextNcNnlNpp();
-
- while ( tail == nullptr
- && target->IsNotNullChunk())
- {
- if ( chunk_is_semicolon(target)
- && target->level == match->level)
- {
- tail = target;
- }
- else if (target->level < match->level)
- {
- break;
- }
- else
- {
- target = target->GetNextNcNnlNpp();
- }
- }
- }
-
- bool toplevel = true;
-
- for (auto it = frm.rbegin(); it != frm.rend() && tail != nullptr; ++it)
- {
- if (!chunk_is_token(it->pc, CT_FPAREN_OPEN))
- {
- continue;
- }
-
- if (it->pc->level < tail->level)
- {
- toplevel = false;
- break;
- }
- }
-
- // Issues: #1813, #3409, #3428
- // if enclosure is set, the namespace is already accounted for
- // so don't apply the correction twice.
- // And for some reason, it's also accounted for when
- // indent_namespace_single_indent is set
- if (!enclosure && !options::indent_namespace_single_indent())
- {
- size_t namespace_indent_to_ignore = 0;
- log_rule_B("indent_namespace");
-
- for (auto i = frm.rbegin(); i != frm.rend(); ++i)
- {
- if (i->ns_cnt)
- {
- const auto foo = i->ns_cnt;
- namespace_indent_to_ignore = indent_size * foo;
- break;
- }
- }
-
- if (namespace_indent_to_ignore && options::indent_namespace())
- {
- // I honestly don't know what's going on, so this is an
- // emperical fix. For some reason lambda's don't have
- // their indent calculated properly when indent_namespace
- // is true. But only if they are not in enclosures.
- namespace_indent_to_ignore = indent_size;
- }
-
- if (namespace_indent_to_ignore <= frm.top().brace_indent)
- {
- frm.top().brace_indent -= namespace_indent_to_ignore;
- }
- else
- {
- frm.top().brace_indent = 1;
- }
- }
-
- // 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
- if ( options::indent_continue() > 0
- && are_chunks_in_same_line(chunk_skip_to_match(frm.top().pc), tail)
- && ( ( !enclosure
- && options::align_assign_span() == 0
- && !options::indent_align_assign()
- && are_chunks_in_same_line(frm.prev().pc->GetPrevNcNnlNpp(), frm.prev().pc)
- && are_chunks_in_same_line(frm.prev().pc, frm.prev().pc->GetNextNcNnlNpp()))
- || ( enclosure
- && linematch
- && toplevel)))
- {
- if (indent_size > frm.top().brace_indent) // if options::indent_indent_columns() is too big
- {
- frm.top().brace_indent = 1;
- }
- else
- {
- frm.top().brace_indent -= indent_size;
- }
- }
- indent_column_set(frm.top().brace_indent);
- frm.top().indent = indent_column + indent_size;
- log_indent();
-
- frm.top().indent_tab = frm.top().indent;
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
-
- frm.prev().indent_tmp = frm.top().indent_tmp;
- log_indent_tmp();
- }
- else if ( language_is_set(LANG_CPP)
- && options::indent_cpp_lambda_only_once()
- && (get_chunk_parent_type(pc) == 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->ns_cnt)
- {
- namespace_indent_to_ignore = i->ns_cnt;
- break;
- }
- }
- }
- // Issue # 1296
- frm.top().brace_indent = 1 + ((pc->brace_level - namespace_indent_to_ignore) * indent_size);
- indent_column_set(frm.top().brace_indent);
- frm.top().indent = indent_column + indent_size;
- log_indent();
- frm.top().indent_tab = frm.top().indent;
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
-
- frm.prev().indent_tmp = frm.top().indent_tmp;
- log_indent_tmp();
- }
- else if ( language_is_set(LANG_CS | LANG_JAVA)
- && options::indent_cs_delegate_brace()
- && ( get_chunk_parent_type(pc) == CT_LAMBDA
- || get_chunk_parent_type(pc) == CT_DELEGATE))
- {
- log_rule_B("indent_cs_delegate_brace");
- frm.top().brace_indent = 1 + ((pc->brace_level + 1) * indent_size);
- indent_column_set(frm.top().brace_indent);
- frm.top().indent = indent_column + indent_size;
- log_indent();
- frm.top().indent_tab = frm.top().indent;
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
-
- frm.prev().indent_tmp = frm.top().indent_tmp;
- log_indent_tmp();
- }
- else if ( language_is_set(LANG_CS | LANG_JAVA)
- && !options::indent_cs_delegate_brace()
- && !options::indent_align_paren()
- && ( get_chunk_parent_type(pc) == CT_LAMBDA
- || get_chunk_parent_type(pc) == CT_DELEGATE))
- {
- log_rule_B("indent_cs_delegate_brace");
- log_rule_B("indent_align_paren");
- frm.top().brace_indent = frm.prev().indent;
-
- // Issue # 1620, UNI-24090.cs
- if (are_chunks_in_same_line(frm.prev().pc, frm.top().pc->GetPrevNcNnlNpp()))
- {
- frm.top().brace_indent -= indent_size;
- }
- indent_column_set(frm.top().brace_indent);
- frm.top().indent = indent_column + indent_size;
- log_indent();
- frm.top().indent_tab = frm.top().indent;
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
- frm.prev().indent_tmp = frm.top().indent_tmp;
- log_indent_tmp();
- }
- else if ( !options::indent_paren_open_brace()
- && !language_is_set(LANG_CS)
- && get_chunk_parent_type(pc) == CT_CPP_LAMBDA
- && ( pc->flags.test(PCF_IN_FCN_DEF)
- || pc->flags.test(PCF_IN_FCN_CTOR)) // Issue #2152
- && chunk_is_newline(pc->GetNextNc()))
- {
- log_rule_B("indent_paren_open_brace");
- // Issue #1165
- LOG_FMT(LINDENT2, "%s(%d): orig_line is %zu, pc->brace_level is %zu, for '%s', pc->level is %zu, pc(-1)->level is %zu\n",
- __func__, __LINE__, pc->orig_line, pc->brace_level, pc->Text(), pc->level, frm.prev().pc->level);
- frm.top().brace_indent = 1 + ((pc->brace_level + 1) * indent_size);
- indent_column_set(frm.top().brace_indent);
- frm.top().indent = frm.prev().indent_tmp;
- log_indent();
-
- frm.top().indent_tmp = frm.top().indent;
- 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()
- && chunk_is_paren_open(frm.prev().pc)
- && chunk_is_newline(pc->GetNextNc()))
- {
- log_rule_B("indent_paren_open_brace");
- LOG_FMT(LINDENT2, "%s(%d): orig_line is %zu, pc->brace_level is %zu, for '%s', pc->level is %zu, pc(-1)->level is %zu\n",
- __func__, __LINE__, pc->orig_line, pc->brace_level, pc->Text(), pc->level, frm.prev().pc->level);
- // FIXME: I don't know how much of this is necessary, but it seems to work
- frm.top().brace_indent = 1 + (pc->brace_level * indent_size);
- indent_column_set(frm.top().brace_indent);
- frm.top().indent = indent_column + indent_size;
- log_indent();
-
- if ( (get_chunk_parent_type(pc) == CT_OC_BLOCK_EXPR)
- && pc->flags.test(PCF_IN_OC_MSG))
- {
- frm.top().indent = frm.prev().indent_tmp + indent_size;
- log_indent();
- frm.top().brace_indent = frm.prev().indent_tmp;
- indent_column_set(frm.top().brace_indent);
- }
- frm.top().indent_tab = frm.top().indent;
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
-
- frm.prev().indent_tmp = frm.top().indent_tmp;
- }
- else if (frm.paren_count != 0)
- {
- if (frm.top().pc->parent_type == CT_OC_BLOCK_EXPR)
- {
- log_rule_B("indent_oc_block_msg");
-
- if ( pc->flags.test(PCF_IN_OC_MSG)
- && options::indent_oc_block_msg())
- {
- frm.top().ip.ref = oc_msg_block_indent(pc, false, false, false, true);
- log_rule_B("indent_oc_block_msg");
- frm.top().ip.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->flags.test(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 = chunk_skip_to_match(pc); // block brace close '}'
- Chunk *bbc_next_ncnl = bbc->GetNextNcNnl();
-
- if ( bbc_next_ncnl->type == CT_OC_MSG_NAME
- || bbc_next_ncnl->type == 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)
- {
- frm.top().indent = indent_size + ref->column;
- }
- else
- {
- frm.top().indent = 1 + ((pc->brace_level + 1) * indent_size);
- }
- log_indent();
- indent_column_set(frm.top().indent - indent_size);
- }
- else
- {
- frm.top().indent = frm.prev().indent_tmp + indent_size;
- log_indent();
- }
- }
- else if ( frm.top().pc->type == CT_BRACE_OPEN
- && frm.top().pc->parent_type == CT_OC_AT)
- {
- // We are inside @{ ... } -- indent one tab from the paren
- if (frm.prev().indent_cont)
- {
- frm.top().indent = frm.prev().indent_tmp;
- }
- else
- {
- frm.top().indent = frm.prev().indent_tmp + indent_size;
- }
- log_indent();
- }
- // Issue # 1620, UNI-24090.cs
- else if ( are_chunks_in_same_line(frm.prev().pc, frm.top().pc)
- && !options::indent_align_paren()
- && chunk_is_paren_open(frm.prev().pc)
- && !pc->flags.test(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().brace_indent = frm.prev().indent - indent_size;
- indent_column_set(frm.top().brace_indent);
- frm.top().indent = frm.prev().indent_tmp;
- log_indent();
- }
- else if ( are_chunks_in_same_line(frm.prev().pc, frm.top().pc->GetPrevNcNnlNpp())
- && !options::indent_align_paren()
- && chunk_is_paren_open(frm.prev().pc)
- && !pc->flags.test(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().brace_indent = frm.prev().indent - indent_size;
- indent_column_set(frm.top().brace_indent);
- frm.top().indent = frm.prev().indent_tmp;
- log_indent();
- }
- else if ( options::indent_oc_inside_msg_sel()
- && ( frm.prev().type == CT_OC_MSG_FUNC
- || frm.prev().type == CT_OC_MSG_NAME)) // Issue #2658
- {
- log_rule_B("indent_oc_inside_msg_sel");
- // [Class Message:{<here>
- frm.top().indent = frm.prev().pc->column + indent_size;
- log_indent();
- indent_column_set(frm.prev().pc->column);
- }
- else
- {
- // We are inside ({ ... }) -- indent one tab from the paren
- frm.top().indent = frm.prev().indent_tmp + indent_size;
-
- if (!chunk_is_paren_open(frm.prev().pc))
- {
- frm.top().indent_tab = frm.top().indent;
- }
- log_indent();
- }
- }
- else if ( frm.top().pc->type == CT_BRACE_OPEN
- && frm.top().pc->parent_type == CT_OC_AT)
- {
- // We are inside @{ ... } -- indent one tab from the paren
- if (frm.prev().indent_cont)
- {
- frm.top().indent = frm.prev().indent_tmp;
- }
- else
- {
- frm.top().indent = frm.prev().indent_tmp + indent_size;
- frm.top().indent_tab = frm.top().indent;
- }
- log_indent();
- }
- else if ( ( get_chunk_parent_type(pc) == CT_BRACED_INIT_LIST
- || ( !options::indent_compound_literal_return()
- && get_chunk_parent_type(pc) == CT_C_CAST))
- && frm.prev().type == 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().indent_cont)
- {
- frm.top().indent = frm.prev().indent_tmp;
- }
- else
- {
- frm.top().indent = frm.prev().indent_tmp + indent_size;
- }
- log_indent();
- }
- else
- {
- // Use the prev indent level + indent_size.
- if (get_chunk_parent_type(pc) == CT_SWITCH)
- {
- frm.top().indent = frm.prev().indent + options::indent_switch_body();
- }
- else
- {
- frm.top().indent = frm.prev().indent + indent_size;
- }
- LOG_FMT(LINDLINE, "%s(%d): frm.pse_tos is %zu, ... indent is %zu\n",
- __func__, __LINE__, frm.size() - 1, frm.top().indent);
- LOG_FMT(LINDLINE, "%s(%d): orig_line is %zu, orig_col is %zu, Text() is '%s', parent_type is %s\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col, pc->Text(),
- get_token_name(get_chunk_parent_type(pc)));
-
- // If this brace is part of a statement, bump it out by indent_brace
- if ( get_chunk_parent_type(pc) == CT_IF
- || get_chunk_parent_type(pc) == CT_ELSE
- || get_chunk_parent_type(pc) == CT_ELSEIF
- || get_chunk_parent_type(pc) == CT_TRY
- || get_chunk_parent_type(pc) == CT_CATCH
- || get_chunk_parent_type(pc) == CT_DO
- || get_chunk_parent_type(pc) == CT_WHILE
- || get_chunk_parent_type(pc) == CT_USING_STMT
- || get_chunk_parent_type(pc) == CT_SWITCH
- || get_chunk_parent_type(pc) == CT_SYNCHRONIZED
- || get_chunk_parent_type(pc) == CT_FOR)
- {
- if (parent_token_indent != 0)
- {
- frm.top().indent += parent_token_indent - indent_size;
- log_indent();
- }
- else
- {
- log_rule_B("indent_brace");
- frm.top().indent += options::indent_brace();
- log_indent();
- indent_column_set(indent_column + options::indent_brace());
- }
- }
- else if (get_chunk_parent_type(pc) == CT_CASE)
- {
- if (options::indent_ignore_case_brace())
- {
- log_rule_B("indent_ignore_case_brace");
- indent_column_set(pc->orig_col);
- }
- else
- {
- log_rule_B("indent_case_brace");
- const auto tmp_indent = static_cast<int>(frm.prev().indent)
- - static_cast<int>(indent_size)
- + options::indent_case_brace();
- /*
- * An open brace with the parent of case does not indent by default
- * UO_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().indent = indent_column + indent_size;
- log_indent();
-
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
- }
- else if ( get_chunk_parent_type(pc) == 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->orig_line, pc->orig_col, pc->Text());
- frm.top().indent -= indent_size;
- log_indent();
- }
- else if (get_chunk_parent_type(pc) == CT_NAMESPACE)
- {
- frm.top().ns_cnt = frm.prev().ns_cnt + 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().ns_cnt >= 2)
- {
- // undo indent on all except the first namespace
- frm.top().indent -= indent_size;
- log_indent();
- }
- indent_column_set(frm.prev(frm.top().ns_cnt).indent);
- }
- else if ( options::indent_namespace()
- && options::indent_namespace_inner_only())
- {
- if (frm.top().ns_cnt == 1)
- {
- // undo indent on first namespace only
- frm.top().indent -= indent_size;
- log_indent();
- }
- }
- else if ( pc->flags.test(PCF_LONG_BLOCK)
- || !options::indent_namespace())
- {
- log_rule_B("indent_namespace");
- // don't indent long blocks
- frm.top().indent -= indent_size;
- log_indent();
- }
- else // indenting 'short' namespace
- {
- log_rule_B("indent_namespace_level");
-
- if (options::indent_namespace_level() > 0)
- {
- frm.top().indent -= indent_size;
- log_indent();
-
- frm.top().indent +=
- options::indent_namespace_level();
- log_indent();
- }
- }
- }
- else if ( get_chunk_parent_type(pc) == CT_EXTERN
- && !options::indent_extern())
- {
- log_rule_B("indent_extern");
- frm.top().indent -= indent_size;
- log_indent();
- }
- frm.top().indent_tab = frm.top().indent;
- }
-
- if (pc->flags.test(PCF_DONT_INDENT))
- {
- frm.top().indent = pc->column;
- log_indent();
-
- indent_column_set(pc->column);
- }
- 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 ( get_chunk_parent_type(pc) == CT_BRACED_INIT_LIST
- && chunk_is_token(prev, CT_BRACE_OPEN)
- && get_chunk_parent_type(prev) == CT_BRACED_INIT_LIST)
- {
- indent_column = frm.prev().brace_indent;
- frm.top().indent = frm.prev().indent;
- log_indent();
- }
- else if ( !chunk_is_newline_between(pc, next)
- && get_chunk_parent_type(next) != CT_BRACED_INIT_LIST
- && options::indent_token_after_brace()
- && !pc->flags.test(PCF_ONE_LINER)) // Issue #1108
- {
- log_rule_B("indent_token_after_brace");
- frm.top().indent = next->column;
- log_indent();
- }
- frm.top().indent_tmp = frm.top().indent;
- frm.top().open_line = pc->orig_line;
- 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().indent_tmp);
- log_indent_tmp();
- }
- }
- // Save the brace indent
- frm.top().brace_indent = indent_column;
- }
- else if (chunk_is_token(pc, CT_SQL_END))
- {
- if (frm.top().type == 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- indent_column_set(frm.top().indent_tmp);
- log_indent_tmp();
- }
- }
- else if ( chunk_is_token(pc, CT_SQL_BEGIN)
- || chunk_is_token(pc, CT_MACRO_OPEN)
- || ( chunk_is_token(pc, CT_CLASS)
- && language_is_set(LANG_CS))) // Issue #3536
- {
- frm.push(pc, __func__, __LINE__);
-
- frm.top().indent = frm.prev().indent + indent_size;
- log_indent();
-
- frm.top().indent_tmp = frm.top().indent;
- frm.top().indent_tab = frm.top().indent;
- log_indent_tmp();
- }
- else if (chunk_is_token(pc, CT_SQL_EXEC))
- {
- frm.push(pc, __func__, __LINE__);
-
- frm.top().indent = frm.prev().indent + indent_size;
- log_indent();
-
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
- }
- else if (chunk_is_token(pc, CT_MACRO_ELSE))
- {
- if (frm.top().type == CT_MACRO_OPEN)
- {
- indent_column_set(frm.prev().indent);
- }
- }
- else if (chunk_is_token(pc, CT_CASE))
- {
- // Start a case - indent UO_indent_switch_case from the switch level
- log_rule_B("indent_switch_case");
- const size_t tmp = frm.top().indent + indent_size
- - options::indent_switch_body()
- + options::indent_switch_case();
- frm.push(pc, __func__, __LINE__);
-
- frm.top().indent = tmp;
- log_indent();
-
- log_rule_B("indent_case_shift");
- frm.top().indent_tmp = tmp - indent_size + options::indent_case_shift();
- frm.top().indent_tab = tmp;
- log_indent_tmp();
-
- // Always set on case statements
- indent_column_set(frm.top().indent_tmp);
-
- 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 (chunk_is_newline(t2))
- {
- pct->column = frm.top().indent_tmp;
- pct->column_indent = pct->column;
- }
- }
- }
- }
- else if (chunk_is_token(pc, CT_BREAK))
- {
- Chunk *prev = pc->GetPrevNcNnl();
-
- if ( chunk_is_token(prev, CT_BRACE_CLOSE)
- && get_chunk_parent_type(prev) == 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()->column);
- }
- }
- }
- else if (chunk_is_token(pc, CT_LABEL))
- {
- if (options::indent_ignore_label())
- {
- log_rule_B("indent_ignore_label");
- indent_column_set(pc->orig_col);
- }
- else
- {
- log_rule_B("indent_label");
- const auto val = options::indent_label();
- const auto pse_indent = frm.top().indent;
-
- // 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()
- && !chunk_is_newline(next)
- // label (+ 2, because there is colon and space after it) must fit into indent
- && (val + static_cast<int>(pc->Len()) + 2 <= static_cast<int>(pse_indent)))
- {
- reindent_line(next, pse_indent);
- }
- }
- else
- {
- const auto no_underflow = cast_abs(pse_indent, val) < pse_indent;
- indent_column_set(((no_underflow) ? (pse_indent + val) : 0));
- }
- }
- }
- else if (chunk_is_token(pc, CT_ACCESS))
- {
- log_rule_B("indent_access_spec_body");
-
- if (options::indent_access_spec_body())
- {
- const size_t tmp = frm.top().indent + indent_size;
- frm.push(pc, __func__, __LINE__);
-
- frm.top().indent = tmp;
- log_indent();
-
- frm.top().indent_tmp = tmp - indent_size;
- frm.top().indent_tab = 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().indent_tmp);
- // 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()
- && !chunk_is_Doxygen_comment(pct))
- {
- Chunk *t2 = pct->GetPrev();
-
- if (chunk_is_newline(t2))
- {
- pct->column = frm.top().indent_tmp;
- pct->column_indent = pct->column;
- }
- }
- }
- else
- {
- // Access spec labels get sent to the left or backed up
- log_rule_B("indent_access_spec");
- const auto val = options::indent_access_spec();
-
- if (val > 0)
- {
- indent_column_set(val);
- }
- else
- {
- const auto pse_indent = frm.top().indent;
- const auto no_underflow = cast_abs(pse_indent, val) < pse_indent;
-
- indent_column_set(no_underflow ? (pse_indent + val) : 0);
- }
- }
- }
- else if ( chunk_is_token(pc, CT_CLASS_COLON)
- || chunk_is_token(pc, CT_CONSTR_COLON))
- {
- // just indent one level
- frm.push(pc, __func__, __LINE__);
-
- frm.top().indent = frm.prev().indent_tmp + indent_size;
- log_indent();
-
- frm.top().indent_tmp = frm.top().indent;
- frm.top().indent_tab = frm.top().indent;
- log_indent_tmp();
-
- if (chunk_is_token(pc, CT_CLASS_COLON))
- {
- if (options::indent_ignore_before_class_colon())
- {
- log_rule_B("indent_ignore_before_class_colon");
- frm.top().indent_tmp = pc->orig_col;
- log_indent_tmp();
- }
- else if (options::indent_before_class_colon() != 0)
- {
- log_rule_B("indent_before_class_colon");
- frm.top().indent_tmp = std::max<ptrdiff_t>(frm.top().indent_tmp + options::indent_before_class_colon(), 0);
- log_indent_tmp();
- }
- }
- indent_column_set(frm.top().indent_tmp);
-
- log_rule_B("indent_class_colon");
-
- if ( options::indent_class_colon()
- && chunk_is_token(pc, CT_CLASS_COLON))
- {
- log_rule_B("indent_class_on_colon");
-
- if (options::indent_class_on_colon())
- {
- frm.top().indent = pc->column;
- log_indent();
- }
- else
- {
- Chunk *next = pc->GetNext();
-
- if ( next->IsNotNullChunk()
- && !chunk_is_newline(next))
- {
- frm.top().indent = next->column;
- log_indent();
- }
- }
- }
- else if (chunk_is_token(pc, CT_CONSTR_COLON))
- {
- if (options::indent_ignore_before_constr_colon())
- {
- log_rule_B("indent_ignore_before_constr_colon");
- frm.top().indent_tmp = pc->orig_col;
- indent_column_set(frm.top().indent_tmp);
- }
-
- if (options::indent_constr_colon())
- {
- log_rule_B("indent_constr_colon");
- Chunk *prev = pc->GetPrev();
-
- if (chunk_is_newline(prev))
- {
- log_rule_B("indent_ctor_init_following");
- frm.top().indent += 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().indent = std::max<ptrdiff_t>(frm.top().indent + options::indent_ctor_init(), 0);
- log_indent();
- frm.top().indent_tmp = std::max<ptrdiff_t>(frm.top().indent_tmp + options::indent_ctor_init(), 0);
- frm.top().indent_tab = std::max<ptrdiff_t>(frm.top().indent_tab + options::indent_ctor_init(), 0);
- log_indent_tmp();
- indent_column_set(frm.top().indent_tmp);
- }
- else if (options::indent_class_on_colon())
- {
- frm.top().indent = pc->column;
- log_indent();
- }
- else
- {
- Chunk *next = pc->GetNext();
-
- if ( next->IsNotNullChunk()
- && !chunk_is_newline(next))
- {
- frm.top().indent = next->column;
- log_indent();
- }
- }
- }
- }
- }
- else if ( chunk_is_token(pc, CT_PAREN_OPEN)
- && ( get_chunk_parent_type(pc) == CT_ASM
- || ( pc->GetPrevNcNnl()->IsNotNullChunk()
- && pc->GetPrevNcNnl()->type == CT_ASM))
- && options::indent_ignore_asm_block())
- {
- log_rule_B("indent_ignore_asm_block");
- Chunk *tmp = chunk_skip_to_match(pc);
-
- int move = 0;
-
- if ( chunk_is_newline(pc->GetPrev())
- && pc->column != indent_column)
- {
- move = indent_column - pc->column;
- }
- else
- {
- move = pc->column - pc->orig_col;
- }
-
- do
- {
- pc->column = pc->orig_col + move;
- pc = pc->GetNext();
- } while (pc != tmp);
-
- reindent_line(pc, indent_column);
- }
- else if ( chunk_is_token(pc, CT_PAREN_OPEN)
- || chunk_is_token(pc, CT_LPAREN_OPEN) // Issue #3054
- || chunk_is_token(pc, CT_SPAREN_OPEN)
- || chunk_is_token(pc, CT_FPAREN_OPEN)
- || chunk_is_token(pc, CT_SQUARE_OPEN)
- || chunk_is_token(pc, CT_ANGLE_OPEN))
- {
- /*
- * Open parenthesis and squares - never update indent_column,
- * unless right after a newline.
- */
- frm.push(pc, __func__, __LINE__);
-
- if ( chunk_is_newline(pc->GetPrev())
- && pc->column != indent_column
- && !pc->flags.test(PCF_DONT_INDENT))
- {
- LOG_FMT(LINDENT, "%s(%d): orig_line is %zu, indent => %zu, text is '%s'\n",
- __func__, __LINE__, pc->orig_line, indent_column, pc->Text());
- reindent_line(pc, indent_column);
- }
- frm.top().indent = pc->column + pc->Len();
- log_indent();
-
- if ( chunk_is_token(pc, CT_SQUARE_OPEN)
- && language_is_set(LANG_D))
- {
- frm.top().indent_tab = frm.top().indent;
- }
- bool skipped = false;
- log_rule_B("indent_inside_ternary_operator");
- log_rule_B("indent_align_paren");
-
- if ( options::indent_inside_ternary_operator()
- && ( chunk_is_token(pc, CT_FPAREN_OPEN)
- || chunk_is_token(pc, CT_PAREN_OPEN))
- && frm.size() > 2
- && ( frm.prev().type == CT_QUESTION
- || frm.prev().type == CT_COND_COLON)
- && !options::indent_align_paren())
- {
- frm.top().indent = frm.prev().indent_tmp + indent_size;
- log_indent();
- frm.top().indent_tab = frm.top().indent;
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
- }
- else if ( ( chunk_is_token(pc, CT_FPAREN_OPEN)
- || chunk_is_token(pc, CT_ANGLE_OPEN))
- && ( ( options::indent_func_call_param()
- && ( get_chunk_parent_type(pc) == CT_FUNC_CALL
- || get_chunk_parent_type(pc) == CT_FUNC_CALL_USER))
- || ( options::indent_func_proto_param()
- && get_chunk_parent_type(pc) == CT_FUNC_PROTO)
- || ( options::indent_func_class_param()
- && ( get_chunk_parent_type(pc) == CT_FUNC_CLASS_DEF
- || get_chunk_parent_type(pc) == CT_FUNC_CLASS_PROTO))
- || ( options::indent_template_param()
- && get_chunk_parent_type(pc) == CT_TEMPLATE)
- || ( options::indent_func_ctor_var_param()
- && get_chunk_parent_type(pc) == CT_FUNC_CTOR_VAR)
- || ( options::indent_func_def_param()
- && get_chunk_parent_type(pc) == CT_FUNC_DEF)
- || ( !options::indent_func_def_param() // Issue #931
- && get_chunk_parent_type(pc) == CT_FUNC_DEF
- && options::indent_func_def_param_paren_pos_threshold() > 0
- && pc->orig_col > 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).type != CT_BRACE_OPEN
- && frm.at(idx).type != CT_VBRACE_OPEN
- && frm.at(idx).type != CT_PAREN_OPEN
- && frm.at(idx).type != CT_FPAREN_OPEN
- && frm.at(idx).type != CT_SPAREN_OPEN
- && frm.at(idx).type != CT_SQUARE_OPEN
- && frm.at(idx).type != CT_ANGLE_OPEN
- && frm.at(idx).type != CT_CASE
- && frm.at(idx).type != CT_MEMBER
- && frm.at(idx).type != CT_QUESTION
- && frm.at(idx).type != CT_COND_COLON
- && frm.at(idx).type != CT_LAMBDA
- && frm.at(idx).type != CT_ASSIGN_NL)
- || are_chunks_in_same_line(frm.at(idx).pc, frm.top().pc))
- && ( frm.at(idx).type != CT_CLASS_COLON
- && frm.at(idx).type != CT_CONSTR_COLON
- && !( frm.at(idx).type == CT_LAMBDA
- && frm.at(idx).pc->GetPrevNc()->type == CT_NEWLINE)))
- {
- if (idx == 0)
- {
- fprintf(stderr, "%s(%d): idx is ZERO, cannot be decremented, at line %zu, column %zu\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col);
- log_flush(true);
- exit(EX_SOFTWARE);
- }
- idx--;
- skipped = true;
- }
- // PR#381
- log_rule_B("indent_param");
-
- if (options::indent_param() != 0)
- {
- frm.top().indent = frm.at(idx).indent + options::indent_param();
- log_indent();
- }
- else
- {
- frm.top().indent = frm.at(idx).indent + 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().indent += indent_size;
- log_indent();
- }
- frm.top().indent_tab = frm.top().indent;
- }
- else if ( options::indent_oc_inside_msg_sel()
- && chunk_is_token(pc, CT_PAREN_OPEN)
- && frm.size() > 2
- && ( frm.prev().type == CT_OC_MSG_FUNC
- || frm.prev().type == 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().indent = frm.prev().pc->column + indent_size;
- log_indent();
- frm.top().indent_tab = frm.top().indent;
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
- }
- else if ( chunk_is_token(pc, CT_PAREN_OPEN)
- && !chunk_is_newline(pc->GetNext())
- && !options::indent_align_paren()
- && !pc->flags.test(PCF_IN_SPAREN))
- {
- log_rule_B("indent_align_paren");
- int idx = static_cast<int>(frm.size()) - 2;
-
- while ( idx > 0
- && are_chunks_in_same_line(frm.at(idx).pc, frm.top().pc))
- {
- idx--;
- skipped = true;
- }
- frm.top().indent = frm.at(idx).indent + indent_size;
- log_indent();
-
- frm.top().indent_tab = frm.top().indent;
- skipped = true;
- }
- else if ( ( chunk_is_str(pc, "(")
- && !options::indent_paren_nl())
- || ( chunk_is_str(pc, "<")
- && !options::indent_paren_nl()) // TODO: add indent_angle_nl?
- || ( chunk_is_str(pc, "[")
- && !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 ( chunk_is_newline(next)
- && !options::indent_paren_after_func_def()
- && !options::indent_paren_after_func_decl()
- && !options::indent_paren_after_func_call())
- {
- size_t sub = 2;
-
- if ( (frm.prev().type == CT_ASSIGN)
- || (frm.prev().type == CT_RETURN))
- {
- sub = 3;
- }
- sub = static_cast<int>(frm.size()) - sub;
-
- log_rule_B("indent_align_paren");
-
- if (!options::indent_align_paren())
- {
- sub = static_cast<int>(frm.size()) - 2;
-
- while ( sub > 0
- && are_chunks_in_same_line(frm.at(sub).pc, frm.top().pc))
- {
- sub--;
- skipped = true;
- }
-
- if ( ( frm.at(sub + 1).type == CT_CLASS_COLON
- || frm.at(sub + 1).type == CT_CONSTR_COLON)
- && (chunk_is_token(frm.at(sub + 1).pc->prev, CT_NEWLINE)))
- {
- sub = sub + 1;
- }
- }
- frm.top().indent = frm.at(sub).indent + indent_size;
- log_indent();
-
- frm.top().indent_tab = frm.top().indent;
- skipped = true;
- }
- else
- {
- if ( next->IsNotNullChunk()
- && !next->IsComment())
- {
- if (chunk_is_token(next, CT_SPACE))
- {
- next = next->GetNextNc();
-
- if (next->IsNullChunk())
- {
- break;
- }
- }
-
- if (next->prev->IsComment())
- {
- // Issue #2099
- frm.top().indent = next->prev->column;
- }
- else
- {
- frm.top().indent = next->column;
- }
- 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().indent_cont // Issue #3567
- && vardefcol == 0)
- || ( !options::use_indent_continue_only_once() // Issue #1160
- && !options::indent_ignore_first_continue())) // Issue #3561
- && ( chunk_is_token(pc, CT_FPAREN_OPEN)
- && chunk_is_newline(pc->GetPrev()))
- && ( ( ( get_chunk_parent_type(pc) == CT_FUNC_PROTO
- || get_chunk_parent_type(pc) == CT_FUNC_CLASS_PROTO)
- && options::indent_paren_after_func_decl())
- || ( ( get_chunk_parent_type(pc) == CT_FUNC_DEF
- || get_chunk_parent_type(pc) == CT_FUNC_CLASS_DEF)
- && options::indent_paren_after_func_def())
- || ( ( get_chunk_parent_type(pc) == CT_FUNC_CALL
- || get_chunk_parent_type(pc) == CT_FUNC_CALL_USER)
- && options::indent_paren_after_func_call())
- || !chunk_is_newline(pc->GetNext())))
- {
- frm.top().indent = frm.prev().indent + indent_size;
- log_indent();
-
- indent_column_set(frm.top().indent);
- }
- log_rule_B("indent_continue");
-
- if ( get_chunk_parent_type(pc) != CT_OC_AT
- && ( options::indent_ignore_first_continue()
- || options::indent_continue() != 0)
- && !skipped)
- {
- if (options::indent_ignore_first_continue())
- {
- frm.top().indent = get_indent_first_continue(pc->GetNext());
- }
- else
- {
- frm.top().indent = frm.prev().indent;
- }
- log_indent();
-
- if ( pc->level == pc->brace_level
- && !options::indent_ignore_first_continue()
- && ( chunk_is_token(pc, CT_FPAREN_OPEN)
- || chunk_is_token(pc, CT_SPAREN_OPEN)
- || ( chunk_is_token(pc, CT_SQUARE_OPEN)
- && get_chunk_parent_type(pc) != CT_OC_MSG)
- || chunk_is_token(pc, CT_ANGLE_OPEN))) // Issue #1170
- {
- //log_rule_B("indent_continue");
- //frm.top().indent += abs(options::indent_continue());
- // frm.top().indent = calc_indent_continue(frm);
- // frm.top().indent_cont = true;
- log_rule_B("use_indent_continue_only_once");
-
- if ( (options::use_indent_continue_only_once())
- && (frm.top().indent_cont)
- && 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().indent = vardefcol;
- log_indent();
- }
- else
- {
- frm.top().indent = calc_indent_continue(frm);
- log_indent();
- frm.top().indent_cont = true;
-
- log_rule_B("indent_sparen_extra");
-
- if ( chunk_is_token(pc, CT_SPAREN_OPEN)
- && options::indent_sparen_extra() != 0)
- {
- frm.top().indent += options::indent_sparen_extra();
- log_indent();
- }
- }
- }
- }
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
-
- frm.paren_count++;
- }
- else if ( options::indent_member_single()
- && chunk_is_token(pc, CT_MEMBER)
- && (strcmp(pc->Text(), ".") == 0)
- && language_is_set(LANG_CS | LANG_CPP))
- {
- log_rule_B("indent_member_single");
-
- if (frm.top().type != CT_MEMBER)
- {
- frm.push(pc, __func__, __LINE__);
- Chunk *tmp = frm.top().pc->GetPrevNcNnlNpp();
-
- if (are_chunks_in_same_line(frm.prev().pc, tmp))
- {
- frm.top().indent = frm.prev().indent;
- }
- else
- {
- frm.top().indent = frm.prev().indent + indent_size;
- }
- log_indent();
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
- }
-
- if (chunk_is_newline(pc->GetPrev()))
- {
- if ( chunk_is_token(pc, 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().indent);
- 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 (chunk_is_token(tmp, CT_FUNC_CALL))
- {
- tmp = tmp->GetNextType(CT_FPAREN_CLOSE, tmp->level);
- tmp = tmp->GetNextNcNnlNpp();
- }
- else if ( chunk_is_token(tmp, CT_WORD)
- || chunk_is_token(tmp, CT_TYPE))
- {
- tmp = tmp->GetNextNcNnlNpp();
- }
- }
-
- if ( tmp->IsNotNullChunk()
- && ( (strcmp(tmp->Text(), ".") != 0)
- || tmp->type != CT_MEMBER))
- {
- if (chunk_is_paren_close(tmp))
- {
- tmp = tmp->GetPrevNcNnlNpp();
- }
- Chunk *local_prev = tmp->GetPrev(); // Issue #3294
-
- if (local_prev->IsComment())
- {
- tmp = tmp->GetPrev(); // Issue #3294
- }
-
- if ( tmp->IsNotNullChunk()
- && chunk_is_newline(tmp->GetPrev()))
- {
- tmp = tmp->GetPrevNcNnlNpp()->GetNextNl();
- }
-
- if (tmp->IsNotNullChunk())
- {
- frm.top().pop_pc = tmp;
- }
- }
- }
- else if ( chunk_is_token(pc, CT_ASSIGN)
- || chunk_is_token(pc, CT_IMPORT)
- || ( chunk_is_token(pc, 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 ( chunk_is_token(pc, CT_ASSIGN)
- && chunk_is_newline(pc->GetPrev()))
- {
- if (frm.top().type == CT_ASSIGN_NL)
- {
- frm.top().indent_tmp = frm.top().indent;
- }
- else
- {
- frm.top().indent_tmp = frm.top().indent + indent_size;
- }
- log_indent_tmp();
-
- indent_column_set(frm.top().indent_tmp);
- LOG_FMT(LINDENT, "%s(%d): %zu] assign => %zu [%s]\n",
- __func__, __LINE__, pc->orig_line, indent_column, pc->Text());
- reindent_line(pc, frm.top().indent_tmp);
- }
- 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 poping the previous assign and pushing the new one
- */
- if ( frm.top().type == CT_ASSIGN
- && chunk_is_token(pc, 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- }
- frm.push(pc, __func__, __LINE__);
-
- if ( chunk_is_token(pc, CT_ASSIGN)
- && chunk_is_newline(pc->GetPrev()))
- {
- frm.top().type = CT_ASSIGN_NL;
- }
- log_rule_B("indent_continue");
-
- if (options::indent_ignore_first_continue())
- {
- frm.top().indent = get_indent_first_continue(pc);
- log_indent();
- frm.top().indent_cont = true; // Issue #3567
- }
- else if (options::indent_continue() != 0)
- {
- frm.top().indent = frm.prev().indent;
- log_indent();
-
- if ( pc->level == pc->brace_level
- && ( pc->type != CT_ASSIGN
- || ( get_chunk_parent_type(pc) != CT_FUNC_PROTO
- && get_chunk_parent_type(pc) != CT_FUNC_DEF)))
- {
- log_rule_B("use_indent_continue_only_once");
-
- if ( (options::use_indent_continue_only_once())
- && (frm.top().indent_cont)
- && vardefcol != 0)
- {
- // if vardefcol isn't zero, use it
- frm.top().indent = vardefcol;
- log_indent();
- }
- else
- {
- frm.top().indent = calc_indent_continue(frm);
- log_indent();
-
- vardefcol = frm.top().indent; // use the same variable for the next line
- frm.top().indent_cont = true;
- }
- }
- }
- else if ( chunk_is_newline(next)
- || !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().indent = frm.prev().indent_tmp;
- }
- else
- {
- frm.top().indent = frm.prev().indent_tmp + indent_size;
- }
- log_indent();
-
- if ( chunk_is_token(pc, CT_ASSIGN)
- && chunk_is_newline(next))
- {
- frm.top().type = CT_ASSIGN_NL;
- frm.top().indent_tab = frm.top().indent;
- }
- }
- else
- {
- frm.top().indent = pc->column + pc->Len() + 1;
- log_indent();
- }
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
- }
- }
- else if ( chunk_is_token(pc, CT_RETURN)
- || ( chunk_is_token(pc, CT_THROW)
- && get_chunk_parent_type(pc) == CT_NONE))
- {
- // don't count returns inside a () or []
- if ( pc->level == pc->brace_level
- || pc->flags.test(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->type == 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 ( chunk_is_newline(next)
- || ( chunk_is_token(pc, CT_RETURN)
- && options::indent_single_after_return()))
- {
- // apply normal single indentation
- frm.top().indent = frm.prev().indent + indent_size;
- }
- else
- {
- // indent after the return token
- frm.top().indent = frm.prev().indent + pc->Len() + 1;
- }
- log_indent();
- frm.top().indent_tmp = frm.prev().indent;
- log_indent_tmp();
- }
- log_indent();
- }
- }
- else if ( chunk_is_token(pc, CT_OC_SCOPE)
- || chunk_is_token(pc, CT_TYPEDEF))
- {
- frm.push(pc, __func__, __LINE__);
- // Issue #405
- frm.top().indent = frm.prev().indent;
- log_indent();
-
- frm.top().indent_tmp = frm.top().indent;
- LOG_FMT(LINDLINE, "%s(%d): .indent is %zu, .indent_tmp is %zu\n",
- __func__, __LINE__, frm.top().indent, frm.top().indent_tmp);
-
- log_rule_B("indent_continue");
-
- if (options::indent_ignore_first_continue())
- {
- frm.top().indent = get_indent_first_continue(pc);
- log_indent();
- }
- else if (options::indent_continue() != 0)
- {
- frm.top().indent = calc_indent_continue(frm, frm.size() - 2);
- log_indent();
-
- frm.top().indent_cont = true;
- }
- else
- {
- frm.top().indent = frm.prev().indent + indent_size;
- log_indent();
- }
- }
- else if (chunk_is_token(pc, CT_C99_MEMBER))
- {
- // nothing to do
- }
- else if (chunk_is_token(pc, CT_WHERE_SPEC))
- {
- /* class indentation is ok already, just need to adjust func */
- /* TODO: make this configurable, obviously.. */
- if ( get_chunk_parent_type(pc) == CT_FUNC_DEF
- || get_chunk_parent_type(pc) == CT_FUNC_PROTO
- || ( get_chunk_parent_type(pc) == CT_STRUCT
- && frm.top().type != CT_CLASS_COLON))
- {
- indent_column_set(frm.top().indent + 4);
- }
- }
- else if ( options::indent_inside_ternary_operator()
- && ( chunk_is_token(pc, CT_QUESTION)
- || chunk_is_token(pc, CT_COND_COLON))) // Issue #1130, #1715
- {
- log_rule_B("indent_inside_ternary_operator");
-
- // Pop any colons before because they should already be processed
- while ( chunk_is_token(pc, CT_COND_COLON)
- && frm.top().type == 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()
- && chunk_is_token(pc, CT_COND_COLON)
- && frm.top().type == 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- frm.pop(__func__, __LINE__, pc);
- indent_column_set(frm.top().indent_tmp);
- }
- frm.push(pc, __func__, __LINE__);
-
- frm.top().indent = frm.prev().indent + indent_size;
- frm.top().indent_tab = frm.top().indent;
- log_indent();
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
- }
- else if ( chunk_is_token(pc, CT_LAMBDA)
- && (language_is_set(LANG_CS | LANG_JAVA))
- && pc->GetNextNcNnlNpp()->type != CT_BRACE_OPEN
- && options::indent_cs_delegate_body())
- {
- log_rule_B("indent_cs_delegate_body");
- frm.push(pc, __func__, __LINE__);
- frm.top().indent = frm.prev().indent;
- log_indent();
-
- if ( chunk_is_newline(pc->GetPrevNc())
- && !are_chunks_in_same_line(frm.prev().pc, pc->GetPrevNcNnl()))
- {
- frm.top().indent = frm.prev().indent + indent_size;
- log_indent();
- reindent_line(pc, (frm.prev().indent + indent_size));
- did_newline = false;
- }
- else if ( chunk_is_newline(pc->GetNextNc())
- && !are_chunks_in_same_line(frm.prev().pc, frm.top().pc))
- {
- frm.top().indent = frm.prev().indent + indent_size;
- }
- log_indent();
- frm.top().indent_tmp = frm.top().indent;
- log_indent_tmp();
- }
- else if ( options::indent_oc_inside_msg_sel()
- && ( chunk_is_token(pc, CT_OC_MSG_FUNC)
- || chunk_is_token(pc, CT_OC_MSG_NAME))
- && chunk_is_token(pc->GetNextNcNnl(), 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().indent = frm.prev().indent;
- frm.top().indent_tab = frm.prev().indent_tab;
- log_indent();
- frm.top().indent_tmp = frm.prev().indent_tmp;
- log_indent_tmp();
- }
- else if (pc->IsComment())
- {
- // Issue #3294
- Chunk *next = pc->GetNext();
-
- if (chunk_is_token(next, 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- 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->flags.test(PCF_IN_ENUM)
- && get_chunk_parent_type(pc) != CT_OPERATOR
- && pc->type != CT_COMMENT
- && pc->type != CT_COMMENT_CPP
- && pc->type != CT_COMMENT_MULTI
- && pc->type != CT_BRACE_OPEN
- && pc->level > 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 (chunk_is_token(tmp, CT_SHIFT))
- {
- in_shift = true;
- LOG_FMT(LINDENT2, "%s(%d): in_shift set to TRUE\n",
- __func__, __LINE__);
-
- tmp = tmp->GetPrevNcNnl();
-
- if (chunk_is_token(tmp, CT_OPERATOR))
- {
- is_operator = true;
- }
- break;
- }
- tmp = tmp->GetPrevNcNnl();
- } while ( !in_shift
- && tmp->IsNotNullChunk()
- && tmp->type != CT_SEMICOLON
- && tmp->type != CT_BRACE_OPEN
- && tmp->type != CT_BRACE_CLOSE
- && tmp->type != CT_COMMA
- && tmp->type != CT_SPAREN_OPEN
- && tmp->type != CT_SPAREN_CLOSE);
-
- tmp = pc;
-
- do
- {
- tmp = tmp->GetNextNcNnl();
-
- if ( tmp->IsNotNullChunk()
- && chunk_is_token(tmp, CT_SHIFT))
- {
- in_shift = true;
- LOG_FMT(LINDENT2, "%s(%d): in_shift set to TRUE\n",
- __func__, __LINE__);
-
- tmp = tmp->GetPrevNcNnl();
-
- if (chunk_is_token(tmp, CT_OPERATOR))
- {
- is_operator = true;
- }
- break;
- }
- } while ( !in_shift
- && tmp->IsNotNullChunk()
- && tmp->type != CT_SEMICOLON
- && tmp->type != CT_BRACE_OPEN
- && tmp->type != CT_BRACE_CLOSE
- && tmp->type != CT_COMMA
- && tmp->type != CT_SPAREN_OPEN
- && tmp->type != 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 (( chunk_is_semicolon(prev_nonl)
- || chunk_is_token(prev_nonl, CT_BRACE_OPEN)
- || chunk_is_token(prev_nonl, CT_BRACE_CLOSE)
- || chunk_is_token(prev_nonl, CT_VBRACE_CLOSE)
- || chunk_is_token(prev_nonl, CT_VBRACE_OPEN)
- || chunk_is_token(prev_nonl, CT_CASE_COLON)
- || ( prev_nonl->IsNotNullChunk()
- && prev_nonl->flags.test(PCF_IN_PREPROC)) != pc->flags.test(PCF_IN_PREPROC)
- || chunk_is_token(prev_nonl, CT_COMMA)
- || is_operator))
- {
- in_shift = false;
- }
- LOG_FMT(LINDENT2, "%s(%d): in_shift is %s\n",
- __func__, __LINE__, in_shift ? "TRUE" : "FALSE");
-
- if ( chunk_is_token(prev2, CT_NEWLINE)
- && in_shift)
- {
- shiftcontcol = calc_indent_continue(frm);
- // Setting frm.top().indent_cont = true in the top context when the indent is not also set
- // just leads to compications when succeeding statements try to indent based on being
- // embedded in a continuation. In other words setting frm.top().indent_cont = 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).type == CT_RETURN
- || frm.at(i).type == 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
- && ( chunk_is_token(pc, CT_WORD)
- || chunk_is_token(pc, CT_FUNC_CTOR_VAR))
- && !pc->flags.test(PCF_IN_FCN_DEF)
- && pc->flags.test(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);
- // Setting frm.top().indent_cont = true in the top context when the indent is not also set
- // just leads to compications when succeeding statements try to indent based on being
- // embedded in a continuation. In other words setting frm.top().indent_cont = true
- // should only be set if frm.top().indent is also set.
- }
- else if ( options::indent_var_def_cont()
- || chunk_is_newline(pc->GetPrev()))
- {
- log_rule_B("indent_var_def_cont");
- vardefcol = frm.top().indent + indent_size;
- }
- else
- {
- // Issue #3010
- vardefcol = pc->column;
- // BUT, we need to skip backward over any '*'
- Chunk *tmp = pc->GetPrevNc();
-
- while (chunk_is_token(tmp, CT_PTR_TYPE))
- {
- vardefcol = tmp->column;
- tmp = tmp->GetPrevNc();
- }
- // BUT, we need to skip backward over any '::' or TYPE
- //tmp = pc->GetPrevNc();
-
- //if (chunk_is_token(tmp, CT_DC_MEMBER))
- //{
- // // look for a type
- // Chunk *tmp2 = tmp->GetPrevNc();
- // if (chunk_is_token(tmp2, CT_TYPE))
- // {
- // // we have something like "SomeLongNamespaceName::Foo()"
- // vardefcol = tmp2->column;
- // LOG_FMT(LINDENT, "%s(%d): orig_line is %zu, vardefcol is %zu\n",
- // __func__, __LINE__, pc->orig_line, vardefcol);
- // }
- //}
- }
- }
-
- if ( chunk_is_semicolon(pc)
- || ( chunk_is_token(pc, CT_BRACE_OPEN)
- && ( get_chunk_parent_type(pc) == CT_FUNCTION
- || get_chunk_parent_type(pc) == CT_CLASS))) //Issue #3576
- {
- vardefcol = 0;
- }
-
- // Indent the line if needed
- if ( did_newline
- && !chunk_is_newline(pc)
- && (pc->Len() != 0))
- {
- pc->column_indent = frm.top().indent_tab;
-
- if (frm.top().ip.ref)
- {
- pc->indent.ref = frm.top().ip.ref;
- pc->indent.delta = frm.top().ip.delta;
- }
- LOG_FMT(LINDENT2, "%s(%d): orig_line is %zu, pc->column_indent is %zu, indent_column is %zu, for '%s'\n",
- __func__, __LINE__, pc->orig_line, pc->column_indent, indent_column, pc->ElidedText(copy));
-
- /*
- * Check for special continuations.
- * Note that some of these could be done as a stack item like
- * everything else
- */
-
- auto prev = pc->GetPrevNcNnl();
- auto prevv = prev->GetPrevNcNnl();
- auto next = pc->GetNextNcNnl();
-
- bool do_vardefcol = false;
-
- if ( vardefcol > 0
- && pc->level == pc->brace_level
- && ( chunk_is_token(prev, CT_COMMA)
- || chunk_is_token(prev, CT_TYPE)
- || chunk_is_token(prev, CT_PTR_TYPE)
- || chunk_is_token(prev, CT_WORD)))
- {
- Chunk *tmp = pc;
-
- while (chunk_is_token(tmp, CT_PTR_TYPE))
- {
- tmp = tmp->GetNextNcNnl();
- }
- LOG_FMT(LINDENT2, "%s(%d): orig_line is %zu, for '%s'",
- __func__, __LINE__, tmp->orig_line, tmp->Text());
- LOG_FMT(LINDENT2, " tmp->flags: ");
- log_pcf_flags(LINDENT2, tmp->flags); // Issue #2332
-
- if ( tmp->flags.test(PCF_VAR_DEF)
- && ( chunk_is_token(tmp, CT_WORD)
- || chunk_is_token(tmp, CT_FUNC_CTOR_VAR)))
- {
- do_vardefcol = true;
- }
- }
- //LOG_FMT(LINDENT2, "%s(%d): GUY 2:\n", __func__, __LINE__);
-
- if (pc->flags.test(PCF_DONT_INDENT))
- {
- // no change
- }
- else if ( get_chunk_parent_type(pc) == CT_SQL_EXEC
- && options::indent_preserve_sql())
- {
- log_rule_B("indent_preserve_sql");
- reindent_line(pc, sql_col + (pc->orig_col - sql_orig_col));
- LOG_FMT(LINDENT, "Indent SQL: [%s] to %zu (%zu/%zu)\n",
- pc->Text(), pc->column, sql_col, sql_orig_col);
- }
- else if ( !options::indent_member_single()
- && !pc->flags.test(PCF_STMT_START)
- && ( chunk_is_token(pc, CT_MEMBER)
- || ( chunk_is_token(pc, CT_DC_MEMBER)
- && chunk_is_token(prev, CT_TYPE))
- || ( chunk_is_token(prev, CT_MEMBER)
- || ( chunk_is_token(prev, CT_DC_MEMBER)
- && chunk_is_token(prevv, 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->orig_line, 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->orig_line, 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->orig_line, shiftcontcol);
- reindent_line(pc, shiftcontcol);
- }
- else if ( chunk_is_token(pc, CT_NAMESPACE)
- && options::indent_namespace()
- && options::indent_namespace_single_indent()
- && frm.top().ns_cnt)
- {
- 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->orig_line, frm.top().brace_indent);
- reindent_line(pc, frm.top().brace_indent);
- }
- else if ( chunk_is_token(pc, CT_STRING)
- && chunk_is_token(prev, CT_STRING)
- && options::indent_align_string())
- {
- log_rule_B("indent_align_string");
- const int tmp = (xml_indent != 0) ? xml_indent : prev->column;
-
- LOG_FMT(LINDENT, "%s(%d): orig_line is %zu, String => %d\n",
- __func__, __LINE__, pc->orig_line, tmp);
- reindent_line(pc, tmp);
- }
- else if (pc->IsComment())
- {
- LOG_FMT(LINDENT, "%s(%d): orig_line is %zu, comment => %zu\n",
- __func__, __LINE__, pc->orig_line, frm.top().indent_tmp);
- indent_comment(pc, frm.top().indent_tmp);
- }
- else if (chunk_is_token(pc, CT_PREPROC))
- {
- LOG_FMT(LINDENT, "%s(%d): orig_line is %zu, pp-indent => %zu [%s]\n",
- __func__, __LINE__, pc->orig_line, indent_column, pc->Text());
- reindent_line(pc, indent_column);
- }
- else if ( chunk_is_paren_close(pc)
- || chunk_is_token(pc, 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.poped().type == E_Token(pc->type - 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- Chunk *ck1 = frm.poped().pc;
- LOG_FMT(LINDLINE, "%s(%d): ck1->orig_line is %zu, ck1->orig_col is %zu, ck1->Text() is '%s', ck1->type is %s\n",
- __func__, __LINE__, ck1->orig_line, ck1->orig_col, ck1->Text(), get_token_name(ck1->type));
- Chunk *ck2 = ck1->GetPrev();
- LOG_FMT(LINDLINE, "%s(%d): ck2->orig_line is %zu, ck2->orig_col is %zu, ck2->Text() is '%s', ck2->type is %s\n",
- __func__, __LINE__, ck2->orig_line, ck2->orig_col, ck2->Text(), get_token_name(ck2->type));
-
- 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->orig_line, ck2->orig_col);
- indent_column_set(pc->orig_col);
- LOG_FMT(LINDLINE, "%s(%d): [%zu:%zu] indent_column set to %zu\n",
- __func__, __LINE__, ck2->orig_line, ck2->orig_col, indent_column);
- }
- else if ( chunk_is_newline(ck2)
- || (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->orig_line, ck2->orig_col);
- indent_column_set(ck1->column);
- LOG_FMT(LINDLINE, "%s(%d): [%zu:%zu] indent_column set to %zu\n",
- __func__, __LINE__, ck2->orig_line, ck2->orig_col, 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->orig_line, ck2->orig_col);
- indent_column_set(frm.poped().indent_tmp);
- LOG_FMT(LINDLINE, "%s(%d): [%zu:%zu] indent_column set to %zu\n",
- __func__, __LINE__, ck2->orig_line, ck2->orig_col, indent_column);
- pc->column_indent = frm.poped().indent_tab;
- 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->orig_line, ck2->orig_col);
-
- if (indent_column == 0)
- {
- fprintf(stderr, "%s(%d): indent_column is ZERO, cannot be decremented, at line %zu, column %zu\n",
- __func__, __LINE__, pc->orig_line, pc->orig_col);
- log_flush(true);
- exit(EX_SOFTWARE);
- }
- indent_column--;
- LOG_FMT(LINDLINE, "%s(%d): [%zu:%zu] indent_column set to %zu\n",
- __func__, __LINE__, ck2->orig_line, ck2->orig_col, 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, ck2->orig_col is %zu, ck2->Text() is '%s'\n",
- __func__, __LINE__, ck2->orig_line, ck2->orig_col, ck2->Text());
-
- if (pc->GetPrev()->type == 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- LOG_FMT(LINDLINE, "%s(%d): prev is <newline>\n",
- __func__, __LINE__);
- Chunk *search = pc;
-
- while (chunk_is_paren_close(search->GetNext()))
- {
- search = search->GetNext();
- }
- Chunk *searchNext = search->GetNext();
-
- // Issue #3407 - Skip over a possible 'noexcept' keyword before going forward.
- if (searchNext->type == CT_NOEXCEPT)
- {
- searchNext = searchNext->GetNext();
- }
-
- if ( searchNext->type == CT_SEMICOLON
- || searchNext->type == CT_MEMBER // Issue #2582
- || searchNext->type == CT_NEWLINE)
- {
- LOG_FMT(LINDLINE, "%s(%d):\n", __func__, __LINE__);
- search = chunk_skip_to_match_rev(search);
-
- if ( options::indent_oc_inside_msg_sel()
- && chunk_is_token(search->GetPrevNcNnl(), CT_OC_COLON)
- && ( frm.top().type == CT_OC_MSG_FUNC
- || frm.top().type == CT_OC_MSG_NAME)) // Issue #2658
- {
- log_rule_B("indent_oc_inside_msg_sel");
- // [Class Message:(...)<here>
- indent_column_set(frm.top().pc->column);
- }
- else if ( options::indent_inside_ternary_operator()
- && ( frm.top().type == CT_QUESTION
- || frm.top().type == CT_COND_COLON)) // Issue #1130, #1715
- {
- log_rule_B("indent_inside_ternary_operator");
- indent_column_set(frm.top().indent);
- }
- else
- {
- search = search->GetPrevNl()->GetNext();
-
- if (search->IsNullChunk())
- {
- search = Chunk::GetHead();
- }
- indent_column_set(search->column);
- }
- }
- }
- }
- }
- }
- size_t indent_value = 0;
- LOG_FMT(LINDENT, "%s(%d): orig_line is %zu, closing parenthesis => %zu, text is '%s'\n",
- __func__, __LINE__, pc->orig_line, indent_column, pc->Text());
- LOG_FMT(LINDENT, "%s(%d): [%s/%s]\n",
- __func__, __LINE__,
- get_token_name(pc->type), get_token_name(get_chunk_parent_type(pc)));
- Chunk *prev2 = pc->GetPrev(); // Issue #2930
- LOG_FMT(LINDENT, "%s(%d): prev2 is orig_line is %zu, text is '%s'\n",
- __func__, __LINE__, prev2->orig_line, prev2->Text());
- Chunk *next2 = pc->GetNext();
- LOG_FMT(LINDENT, "%s(%d): next2 is orig_line is %zu, text is '%s'\n",
- __func__, __LINE__, next2->orig_line, next2->Text());
-
- if ( get_chunk_parent_type(pc) == CT_FUNC_DEF
- && chunk_is_newline(prev2)
- && chunk_is_newline(next2))
- {
- 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 (chunk_is_token(pc, CT_COMMA))
- {
- bool align = false;
- bool ignore = false;
-
- if (chunk_is_paren_open(frm.top().pc))
- {
- log_rule_B("indent_comma_paren");
- align = options::indent_comma_paren() == (int)indent_mode_e::ALIGN;
- ignore = options::indent_comma_paren() == (int)indent_mode_e::IGNORE;
- }
- else if (chunk_is_opening_brace(frm.top().pc))
- {
- log_rule_B("indent_comma_brace");
- align = options::indent_comma_brace() == (int)indent_mode_e::ALIGN;
- ignore = options::indent_comma_brace() == (int)indent_mode_e::IGNORE;
- }
-
- if (ignore)
- {
- indent_column_set(pc->orig_col);
- }
- else if (align)
- {
- indent_column_set(frm.top().pc->column);
- }
- LOG_FMT(LINDENT, "%s(%d): %zu] comma => %zu [%s]\n",
- __func__, __LINE__, pc->orig_line, indent_column, pc->Text());
- reindent_line(pc, indent_column);
- }
- else if ( options::indent_func_const()
- && chunk_is_token(pc, CT_QUALIFIER)
- && strncasecmp(pc->Text(), "const", pc->Len()) == 0
- && ( next == nullptr
- || chunk_is_token(next, CT_BRACED)
- || chunk_is_token(next, CT_BRACE_OPEN)
- || chunk_is_token(next, CT_NEWLINE)
- || chunk_is_token(next, CT_SEMICOLON)
- || chunk_is_token(next, CT_THROW)
- || chunk_is_token(next, CT_VBRACE_OPEN)))
- {
- // indent const - void GetFoo(void)\n const\n { return (m_Foo); }
- log_rule_B("indent_func_const");
- indent_column_set(frm.top().indent + options::indent_func_const());
- LOG_FMT(LINDENT, "%s(%d): %zu] const => %zu [%s]\n",
- __func__, __LINE__, pc->orig_line, indent_column, pc->Text());
- reindent_line(pc, indent_column);
- }
- else if ( options::indent_func_throw()
- && chunk_is_token(pc, CT_THROW)
- && get_chunk_parent_type(pc) != 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->orig_line, indent_column, pc->Text());
- reindent_line(pc, indent_column);
- }
- else if (chunk_is_token(pc, CT_SEMICOLON))
- {
- if ( pc->flags.test(PCF_IN_FOR)
- && options::indent_semicolon_for_paren())
- {
- log_rule_B("indent_semicolon_for_paren");
- indent_column_set(frm.top().pc->column);
-
- log_rule_B("indent_first_for_expr");
-
- if (options::indent_first_for_expr())
- {
- reindent_line(frm.top().pc->GetNext(),
- indent_column + pc->Len() + 1);
- }
- LOG_FMT(LINDENT, "%s(%d): %zu] SEMICOLON => %zu [%s]\n",
- __func__, __LINE__, pc->orig_line, 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->orig_col);
- }
- LOG_FMT(LINDENT, "%s(%d): %zu] semicolon => %zu [%s]\n",
- __func__, __LINE__, pc->orig_line, indent_column, pc->Text());
- reindent_line(pc, indent_column);
- }
- }
- else if (chunk_is_token(pc, CT_BOOL))
- {
- if (chunk_is_paren_open(frm.top().pc))
- {
- log_rule_B("indent_bool_paren");
-
- if (options::indent_bool_paren() == (int)indent_mode_e::IGNORE)
- {
- indent_column_set(pc->orig_col);
- }
- else if (options::indent_bool_paren() == (int)indent_mode_e::ALIGN)
- {
- indent_column_set(frm.top().pc->column);
-
- log_rule_B("indent_first_bool_expr");
-
- if (options::indent_first_bool_expr())
- {
- reindent_line(frm.top().pc->GetNext(),
- indent_column + pc->Len() + 1);
- }
- }
- }
- else
- {
- log_rule_B("indent_ignore_bool");
-
- if (options::indent_ignore_bool())
- {
- indent_column_set(pc->orig_col);
- }
- }
- LOG_FMT(LINDENT, "%s(%d): %zu] bool => %zu [%s]\n",
- __func__, __LINE__, pc->orig_line, indent_column, pc->Text());
- reindent_line(pc, indent_column);
- }
- else if ( chunk_is_token(pc, CT_ARITH)
- || chunk_is_token(pc, CT_CARET))
- {
- log_rule_B("indent_ignore_arith");
-
- if (options::indent_ignore_arith())
- {
- indent_column_set(pc->orig_col);
- }
- LOG_FMT(LINDENT, "%s(%d): %zu] arith => %zu [%s]\n",
- __func__, __LINE__, pc->orig_line, indent_column, pc->Text());
- reindent_line(pc, indent_column);
- }
- else if (chunk_is_token(pc, CT_SHIFT))
- {
- log_rule_B("indent_shift");
-
- if (options::indent_shift() == -1)
- {
- indent_column_set(pc->orig_col);
- }
- LOG_FMT(LINDENT, "%s(%d): %zu] shift => %zu [%s]\n",
- __func__, __LINE__, pc->orig_line, indent_column, pc->Text());
- reindent_line(pc, indent_column);
- }
- else if (chunk_is_token(pc, CT_ASSIGN))
- {
- log_rule_B("indent_ignore_assign");
-
- if (options::indent_ignore_assign())
- {
- indent_column_set(pc->orig_col);
- }
- LOG_FMT(LINDENT, "%s(%d): %zu] assign => %zu [%s]\n",
- __func__, __LINE__, pc->orig_line, indent_column, pc->Text());
- reindent_line(pc, indent_column);
- }
- else if ( options::indent_ternary_operator() == 1
- && chunk_is_token(prev, CT_COND_COLON)
- && ( chunk_is_token(pc, CT_ADDR)
- || chunk_is_token(pc, CT_WORD)
- || chunk_is_token(pc, CT_DEREF)
- || chunk_is_token(pc, CT_NUMBER)
- || chunk_is_token(pc, CT_STRING)
- || chunk_is_token(pc, CT_PAREN_OPEN)))
- {
- log_rule_B("indent_ternary_operator");
- Chunk *tmp = prev->GetPrevType(CT_QUESTION, -1);
-
- if (tmp->IsNotNullChunk())
- {
- tmp = tmp->GetNextNcNnl();
-
- if (tmp->IsNotNullChunk())
- {
- LOG_FMT(LINDENT, "%s: %zu] ternarydefcol => %zu [%s]\n",
- __func__, pc->orig_line, tmp->column, pc->Text());
- reindent_line(pc, tmp->column);
- }
- }
- }
- else if ( options::indent_ternary_operator() == 2
- && chunk_is_token(pc, CT_COND_COLON))
- {
- log_rule_B("indent_ternary_operator");
- Chunk *tmp = pc->GetPrevType(CT_QUESTION, -1);
-
- if (tmp->IsNotNullChunk())
- {
- LOG_FMT(LINDENT, "%s: %zu] ternarydefcol => %zu [%s]\n",
- __func__, pc->orig_line, tmp->column, pc->Text());
- reindent_line(pc, tmp->column);
- }
- }
- else if ( options::indent_oc_inside_msg_sel()
- && ( chunk_is_token(pc, CT_OC_MSG_FUNC)
- || chunk_is_token(pc, CT_OC_MSG_NAME))) // Issue #2658
- {
- log_rule_B("indent_oc_inside_msg_sel");
- reindent_line(pc, frm.top().indent);
- }
- else
- {
- bool use_indent = true;
- const size_t ttidx = frm.size() - 1;
-
- if (ttidx > 0)
- {
- LOG_FMT(LINDPC, "%s(%d): (frm.at(ttidx).pc)->parent_type is %s\n",
- __func__, __LINE__, get_token_name((frm.at(ttidx).pc)->parent_type));
-
- if ((frm.at(ttidx).pc)->parent_type == 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->column is %zu, pc->Text() is '%s, indent_column is %zu\n",
- __func__, __LINE__, pc->orig_line, pc->column, pc->Text(), indent_column);
-
- if ( use_indent
- && pc->type != CT_PP_IGNORE) // Leave indentation alone for PP_IGNORE tokens
- {
- log_rule_B("pos_conditional");
-
- if ( ( chunk_is_token(pc, CT_QUESTION) // Issue #2101
- || chunk_is_token(pc, 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->orig_line);
- }
- else if (chunk_is_token(pc, CT_BREAK))
- {
- // Issue #1692
- log_rule_B("indent_switch_break_with_case");
-
- // Issue #2281
- if ( options::indent_switch_break_with_case()
- && get_type_of_the_parent(pc) == CT_SWITCH)
- {
- // look for a case before Issue #2735
- Chunk *whereIsCase = pc->GetPrevType(CT_CASE, pc->level);
-
- if (whereIsCase->IsNotNullChunk())
- {
- LOG_FMT(LINDENT, "%s(%d): orig_line is %zu, orig_col is %zu, Text() is '%s'\n",
- __func__, __LINE__, whereIsCase->orig_line, whereIsCase->orig_col, whereIsCase->Text());
- LOG_FMT(LINDENT, "%s(%d): column is %zu\n",
- __func__, __LINE__, whereIsCase->column);
- reindent_line(pc, whereIsCase->column);
- }
- }
- else
- {
- LOG_FMT(LINDENT, "%s(%d): orig_line is %zu, indent_column set to %zu, for '%s'\n",
- __func__, __LINE__, pc->orig_line, indent_column, pc->Text());
- reindent_line(pc, indent_column);
- }
- }
- else if ( chunk_is_token(pc, 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->orig_line, 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)->type is %s\n",
- __func__, __LINE__, (frm.at(frm_size - 1).pc)->Text(), get_token_name((frm.at(frm_size - 1).pc)->type));
- // 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).pc;
- LOG_FMT(LINDPC, "%s(%d): Text() is '%s', token_before->type is %s\n",
- __func__, __LINE__, token_before->Text(), get_token_name(token_before->type));
-
- size_t vor_col = 0;
-
- if (chunk_is_token(token_before, CT_ASSIGN))
- {
- Chunk *before_Assign = frm.at(temp_ttidx - 1).pc;
-
- if (before_Assign == nullptr)
- {
- indent_column = 1 + indent_size;
- }
- else
- {
- vor_col = before_Assign->column;
- LOG_FMT(LINDPC, "%s(%d): Text() is '%s', before_Assign->type is %s, column is %zu\n",
- __func__, __LINE__, before_Assign->Text(), get_token_name(before_Assign->type), vor_col);
- indent_column = vor_col + 2 * indent_size;
- }
- }
- else if (chunk_is_token(token_before, CT_BRACE_OPEN))
- {
- vor_col = token_before->column;
- LOG_FMT(LINDPC, "%s(%d): Text() is '%s', token_before->type is %s, column is %zu\n",
- __func__, __LINE__, token_before->Text(), get_token_name(token_before->type), vor_col);
- indent_column = vor_col + 2 * indent_size;
- }
- else if (chunk_is_token(token_before, CT_RETURN))
- {
- Chunk *before_Return = frm.at(temp_ttidx - 1).pc;
- vor_col = before_Return->column;
- LOG_FMT(LINDPC, "%s(%d): Text() is '%s', before_Return->type is %s, column is %zu\n",
- __func__, __LINE__, before_Return->Text(), get_token_name(before_Return->type), 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->orig_line, 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->orig_line);
- }
- }
- did_newline = false;
-
- if ( chunk_is_token(pc, CT_SQL_EXEC)
- || chunk_is_token(pc, CT_SQL_BEGIN)
- || chunk_is_token(pc, CT_SQL_END))
- {
- sql_col = pc->column;
- sql_orig_col = pc->orig_col;
- }
-
- // Handle indent for variable defs at the top of a block of code
- if (pc->flags.test(PCF_VAR_TYPE))
- {
- if ( !frm.top().non_vardef
- && (frm.top().type == CT_BRACE_OPEN))
- {
- log_rule_B("indent_var_def_blk");
- const auto val = options::indent_var_def_blk();
-
- if (val != 0)
- {
- auto indent = indent_column;
- indent = (val > 0) ? val // reassign if positive val,
- : (cast_abs(indent, 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->orig_line, indent, pc->Text());
- reindent_line(pc, indent);
- }
- }
- }
- else if (pc != frm.top().pc)
- {
- frm.top().non_vardef = true;
- }
- }
-
- // if we hit a newline, reset indent_tmp
- if ( chunk_is_newline(pc)
- || chunk_is_token(pc, CT_COMMENT_MULTI)
- || chunk_is_token(pc, CT_COMMENT_CPP))
- {
- log_indent();
- frm.top().indent_tmp = frm.top().indent;
- 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 ( chunk_is_token(pc, CT_NL_CONT)
- && (frm.top().indent_tmp <= indent_size))
- {
- frm.top().indent_tmp = 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
- && chunk_is_token(pc, CT_STRING)
- && pc->Len() > 4
- && pc->str[1] == '<'
- && pc->str[2] != '/'
- && pc->str[pc->Len() - 3] != '/')
- {
- if (xml_indent <= 0)
- {
- xml_indent = pc->column;
- }
- log_rule_B("indent_xml_string");
- xml_indent += options::indent_xml_string();
- }
- // Issue #672
- log_rule_B("indent_continue_class_head");
-
- if ( chunk_is_token(pc, 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->orig_line);
- frm.push(pc, __func__, __LINE__);
-
- if (options::indent_ignore_first_continue())
- {
- frm.top().indent = get_indent_first_continue(pc);
- }
- else
- {
- frm.top().indent = frm.prev().indent + options::indent_continue_class_head();
- }
- log_indent();
-
- frm.top().indent_tmp = frm.top().indent;
- frm.top().indent_tab = frm.top().indent;
- log_indent_tmp();
- classFound = true;
- }
- 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->orig_line, pc->orig_col, pc->Text(), get_token_name(pc->type));
- }
-null_pc:
-
- // Throw out any stuff inside a preprocessor - no need to warn
- while ( !frm.empty()
- && frm.top().in_preproc)
- {
- frm.pop(__func__, __LINE__, pc);
- }
-
- // Throw out any VBRACE_OPEN at the end - implied with the end of file
- while ( !frm.empty()
- && frm.top().type == 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).open_line,
- get_token_name(frm.at(idx_temp).parent),
- get_token_name(frm.at(idx_temp).type));
- cpd.error_count++;
- }
-
- 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 (!chunk_is_single_line_comment(start))
- {
- return(false);
- }
- Chunk *pc = start;
-
- if (pc == nullptr)
- {
- pc = Chunk::NullChunkPtr;
- }
- size_t nl_count = 0;
-
- while ((pc = forward ? pc->GetNext() : pc->GetPrev())->IsNotNullChunk())
- {
- if (chunk_is_newline(pc))
- {
- if ( nl_count > 0
- || pc->nl_count > 1)
- {
- return(false);
- }
- nl_count++;
- }
- else if (chunk_is_single_line_comment(pc))
- {
- nl_count = 0;
- }
- else if ( chunk_is_token(pc, CT_COMMENT_MULTI)
- || (forward && chunk_is_closing_brace(pc))
- || (!forward && chunk_is_opening_brace(pc)))
- {
- /*
- * 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 ParseFrame &frm)
-{
- return( ( frm.top().type == CT_ASSIGN_NL
- || frm.top().type == CT_MEMBER
- || frm.top().type == CT_ASSIGN)
- && ( chunk_is_semicolon(pc)
- || chunk_is_token(pc, CT_COMMA)
- || chunk_is_token(pc, CT_BRACE_OPEN)
- || chunk_is_token(pc, CT_SPAREN_CLOSE)
- || ( chunk_is_token(pc, CT_SQUARE_OPEN)
- && get_chunk_parent_type(pc) == CT_ASSIGN))
- && get_chunk_parent_type(pc) != 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->orig_line, newline_token->orig_col);
-
- if ( newline_token->IsNullChunk()
- || newline_token->nl_count > 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->orig_line, next->orig_col);
- }
- } 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->orig_col > pc->orig_col
- ? next->orig_col - pc->orig_col
- : pc->orig_col - next->orig_col);
-}
-
-
-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->orig_line, pc->orig_col, pc->level);
-
- // force column 1 comment to column 1 if not changing them
- log_rule_B("indent_col1_comment");
-
- if ( pc->orig_col == 1
- && !options::indent_col1_comment()
- && !pc->flags.test(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->orig_line, nl->orig_col, nl->level);
- }
-
- if (pc->orig_col > 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->orig_line, prev->orig_col, prev->level);
- log_pcf_flags(LCMTIND, prev->flags);
- }
-
- if ( prev->IsComment()
- && nl->nl_count == 1)
- {
- const size_t prev_col_diff = (prev->orig_col > pc->orig_col)
- ? prev->orig_col - pc->orig_col
- : pc->orig_col - prev->orig_col;
- 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(), chunk_is_Doxygen_comment(prev) ? "TRUE" : "FALSE");
- LOG_FMT(LCMTIND, "%s(%d): pc->Text() is '%s', Doxygen_comment(pc) is %s\n",
- __func__, __LINE__, pc->Text(), chunk_is_Doxygen_comment(pc) ? "TRUE" : "FALSE");
-
- if (chunk_is_Doxygen_comment(prev) == chunk_is_Doxygen_comment(pc))
- {
- 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->column);
- reindent_line(pc, prev->column);
- 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->column);
- 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->column);
- reindent_line(pc, col + options::indent_single_line_comments_after());
- return;
- }
- log_rule_B("indent_comment");
-
- if ( pc->orig_col > 1
- && !options::indent_comment())
- {
- LOG_FMT(LCMTIND, "%s(%d): rule 5 - keep in orig_col\n", __func__, __LINE__);
- reindent_line(pc, pc->orig_col);
- 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(void)
-{
- 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, pc->orig_col is %zu, pc->Text() is '%s'\n",
- __func__, __LINE__, pc->pp_level, pc->orig_line, pc->orig_col, pc->Text());
-
- if ( pc->IsComment()
- || chunk_is_newline(pc))
- {
- continue;
- }
-
- if (IFstage == 0) // 0 is BEGIN
- {
- // Check the first preprocessor, make sure it is an #if type
- if (pc->type != CT_PREPROC)
- {
- break;
- }
- Chunk *next = pc->GetNext();
-
- if ( next->IsNullChunk()
- || next->type != 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 (chunk_is_token(pc, CT_PREPROC))
- {
- if (pc->pp_level == 0)
- {
- IFstage = 2;
- end_pp = pc;
- }
- }
- continue;
- }
- else if (IFstage == 2)
- {
- // We should only see the rest of the preprocessor
- if ( chunk_is_token(pc, CT_PREPROC)
- || !pc->flags.test(PCF_IN_PREPROC))
- {
- IFstage = 0;
- break;
- }
- }
- }
-
- cpd.ifdef_over_whole_file = (IFstage == 2) ? 1 : -1;
-
- if (cpd.ifdef_over_whole_file > 0)
- {
- chunk_flags_set(start_pp, PCF_WF_IF);
- chunk_flags_set(end_pp, 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(void)
-{
- 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->orig_line, pc->orig_col, pc->Text());
-
- if (pc->type != CT_PREPROC)
- {
- continue;
- }
- Chunk *next = pc->GetNextNcNnl();
-
- if (next->IsNullChunk())
- {
- break;
- }
- const size_t pp_level = (pc->pp_level > pp_level_sub)
- ? pc->pp_level - pp_level_sub : 0;
-
- // Adjust the indent of the '#'
- log_rule_B("pp_indent");
-
- if (options::pp_indent() & IARF_ADD)
- {
- log_rule_B("pp_indent_count");
- reindent_line(pc, 1 + pp_level * options::pp_indent_count());
- }
- else if (options::pp_indent() & IARF_REMOVE)
- {
- log_rule_B("pp_indent");
- reindent_line(pc, 1);
- }
- // Add spacing by adjusting the length
- log_rule_B("pp_space");
-
- if ( (options::pp_space() != IARF_IGNORE)
- && next != nullptr)
- {
- if (options::pp_space() & IARF_ADD)
- {
- log_rule_B("pp_space_count");
- // Issue #3055
- const size_t mult = max<size_t>(options::pp_space_count(), 1);
- reindent_line(next, pc->column + pc->Len() + (pp_level * mult));
- }
- else if (options::pp_space() & IARF_REMOVE)
- {
- log_rule_B("pp_space");
- reindent_line(next, pc->column + 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->brace_level <= ((get_chunk_parent_type(pc) == CT_PP_DEFINE) ? 1 : 0);
-
- if ( ( ( at_file_level
- && !options::pp_indent_at_level0())
- || ( !at_file_level
- && !options::pp_indent_at_level()))
- && get_chunk_parent_type(pc) != CT_PP_REGION
- && get_chunk_parent_type(pc) != CT_PP_ENDREGION)
- {
- log_rule_B("pp_define_at_level");
-
- if ( !options::pp_define_at_level()
- || get_chunk_parent_type(pc) != CT_PP_DEFINE)
- {
- chunk_flags_set(pc, PCF_DONT_INDENT);
- }
- }
- LOG_FMT(LPPIS, "%s(%d): orig_line %zu to %zu (len %zu, next->col %zu)\n",
- __func__, __LINE__, pc->orig_line, 1 + pp_level, pc->Len(),
- next ? next->column : -1);
- }
-} // indent_preproc