summaryrefslogtreecommitdiffstats
path: root/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/combine_tools.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/combine_tools.cpp')
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/combine_tools.cpp569
1 files changed, 569 insertions, 0 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/combine_tools.cpp b/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/combine_tools.cpp
new file mode 100644
index 00000000..53818133
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/src/combine_tools.cpp
@@ -0,0 +1,569 @@
+/**
+ * @file combine_tools.cpp
+ *
+ * @author Guy Maurel
+ * @license GPL v2+
+ * extract from combine.cpp
+ */
+
+#include "combine_tools.h"
+
+#include "unc_ctype.h"
+#include "uncrustify.h"
+
+
+bool can_be_full_param(Chunk *start, Chunk *end)
+{
+ LOG_FUNC_ENTRY();
+
+ LOG_FMT(LFPARAM, "%s(%d): start->Text() is '%s', type is %s\n",
+ __func__, __LINE__, start->Text(), get_token_name(start->GetType()));
+ LOG_FMT(LFPARAM, "%s(%d): end->Text() is '%s', type is %s\n",
+ __func__, __LINE__, end->Text(), get_token_name(end->GetType()));
+
+ int word_count = 0;
+ int type_count = 0;
+ Chunk *pc = Chunk::NullChunkPtr;
+ Chunk *first_word = Chunk::NullChunkPtr;
+ bool first_word_set = false;
+
+ for (pc = start;
+ pc->IsNotNullChunk() && pc != end;
+ pc = pc->GetNextNcNnl(E_Scope::PREPROC))
+ {
+ LOG_FMT(LFPARAM, "%s(%d): pc->Text() is '%s', type is %s\n",
+ __func__, __LINE__, pc->Text(), get_token_name(pc->GetType()));
+
+ if ( pc->Is(CT_QUALIFIER)
+ || pc->Is(CT_STRUCT)
+ || pc->Is(CT_ENUM)
+ || pc->Is(CT_UNION)
+ || pc->Is(CT_TYPENAME))
+ {
+ LOG_FMT(LFPARAM, "%s(%d): <== %s! (yes)\n",
+ __func__, __LINE__, get_token_name(pc->GetType()));
+ return(true);
+ }
+
+ if ( pc->Is(CT_WORD)
+ || pc->Is(CT_TYPE))
+ {
+ ++word_count;
+
+ if (!first_word_set)
+ {
+ first_word = pc;
+ first_word_set = true;
+ }
+
+ if (pc->Is(CT_TYPE))
+ {
+ ++type_count;
+ }
+ }
+ else if ( pc->Is(CT_MEMBER)
+ || pc->Is(CT_DC_MEMBER))
+ {
+ if (word_count > 0)
+ {
+ --word_count;
+ }
+ }
+ else if ( pc != start
+ && pc->IsPointerOperator())
+ {
+ // chunk is OK
+ }
+ else if (pc->Is(CT_ASSIGN))
+ {
+ // chunk is OK (default values)
+ break;
+ }
+ else if (pc->Is(CT_ANGLE_OPEN))
+ {
+ LOG_FMT(LFPARAM, "%s(%d): <== template\n",
+ __func__, __LINE__);
+
+ return(true);
+ }
+ else if (pc->Is(CT_ELLIPSIS))
+ {
+ LOG_FMT(LFPARAM, "%s(%d): <== ellipsis\n",
+ __func__, __LINE__);
+
+ return(true);
+ }
+ else if ( word_count == 0
+ && pc->Is(CT_PAREN_OPEN))
+ {
+ // Check for old-school func proto param '(type)'
+ Chunk *tmp1 = pc->GetClosingParen(E_Scope::PREPROC);
+
+ if (tmp1->IsNullChunk())
+ {
+ return(false);
+ }
+ Chunk *tmp2 = tmp1->GetNextNcNnl(E_Scope::PREPROC);
+
+ if (tmp2->IsNullChunk())
+ {
+ return(false);
+ }
+
+ if ( tmp2->Is(CT_COMMA)
+ || tmp2->IsParenClose())
+ {
+ do
+ {
+ pc = pc->GetNextNcNnl(E_Scope::PREPROC);
+
+ if (pc->IsNullChunk())
+ {
+ return(false);
+ }
+ LOG_FMT(LFPARAM, "%s(%d): pc->Text() is '%s', type is %s\n",
+ __func__, __LINE__, pc->Text(), get_token_name(pc->GetType()));
+ } while (pc != tmp1);
+
+ // reset some vars to allow [] after parens
+ word_count = 1;
+ type_count = 1;
+ }
+ else
+ {
+ LOG_FMT(LFPARAM, "%s(%d): <== '%s' not fcn type!\n",
+ __func__, __LINE__, get_token_name(pc->GetType()));
+ return(false);
+ }
+ }
+ else if ( ( word_count == 1
+ || (word_count == type_count))
+ && pc->Is(CT_PAREN_OPEN))
+ {
+ // Check for func proto param 'void (*name)' or 'void (*name)(params)' or 'void (^name)(params)'
+ // <name> can be optional
+ Chunk *tmp1 = pc->GetNextNcNnl(E_Scope::PREPROC);
+
+ if (tmp1->IsNullChunk())
+ {
+ return(false);
+ }
+ Chunk *tmp2 = tmp1->GetNextNcNnl(E_Scope::PREPROC);
+
+ if (tmp2->Is(CT_QUALIFIER))
+ {
+ // tmp2 is the "nullable" qualifier in this case:
+ // void (^nullable name)(params)
+ // skip the qualifier
+ tmp2 = tmp2->GetNextNcNnl(E_Scope::PREPROC);
+ }
+
+ if (tmp2->IsNullChunk())
+ {
+ return(false);
+ }
+ Chunk *tmp3 = (tmp2->IsString(")")) ? tmp2 : tmp2->GetNextNcNnl(E_Scope::PREPROC);
+
+ if (tmp3->IsNullChunk())
+ {
+ return(false);
+ }
+
+ if ( !tmp3->IsString(")")
+ || !( tmp1->IsString("*")
+ || tmp1->IsString("^")) // Issue #2656
+ || !( tmp2->GetType() == CT_WORD
+ || tmp2->IsString(")")))
+ {
+ LOG_FMT(LFPARAM, "%s(%d): <== '%s' not fcn type!\n",
+ __func__, __LINE__, get_token_name(pc->GetType()));
+ return(false);
+ }
+ LOG_FMT(LFPARAM, "%s(%d): <skip fcn type>\n",
+ __func__, __LINE__);
+
+ tmp1 = tmp3->GetNextNcNnl(E_Scope::PREPROC);
+
+ if (tmp1->IsNullChunk())
+ {
+ return(false);
+ }
+
+ if (tmp1->IsString("("))
+ {
+ tmp3 = tmp1->GetClosingParen(E_Scope::PREPROC);
+ }
+ pc = tmp3;
+ LOG_FMT(LFPARAM, "%s(%d): pc->Text() is '%s', type is %s\n",
+ __func__, __LINE__, pc->Text(), get_token_name(pc->GetType()));
+
+ // reset some vars to allow [] after parens
+ word_count = 1;
+ type_count = 1;
+ }
+ else if (pc->Is(CT_TSQUARE))
+ {
+ // ignore it
+ }
+ else if ( word_count == 1
+ && pc->Is(CT_SQUARE_OPEN))
+ {
+ // skip over any array stuff
+ pc = pc->GetClosingParen(E_Scope::PREPROC);
+ LOG_FMT(LFPARAM, "%s(%d): pc->Text() is '%s', type is %s\n",
+ __func__, __LINE__, pc->Text(), get_token_name(pc->GetType()));
+ }
+ else if ( word_count == 2
+ && pc->Is(CT_SQUARE_OPEN))
+ {
+ // Bug #671: is it such as: bool foo[FOO_MAX]
+ pc = pc->GetClosingParen(E_Scope::PREPROC);
+ LOG_FMT(LFPARAM, "%s(%d): pc->Text() is '%s', type is %s\n",
+ __func__, __LINE__, pc->Text(), get_token_name(pc->GetType()));
+ }
+ else if ( word_count == 1
+ && language_is_set(LANG_CPP)
+ && pc->IsString("&&"))
+ {
+ // ignore possible 'move' operator
+ }
+ else
+ {
+ LOG_FMT(LFPARAM, "%s(%d): <== type is %s, no way!, type count is %d, word count is %d\n",
+ __func__, __LINE__, get_token_name(pc->GetType()), type_count, word_count);
+ return(false);
+ }
+ LOG_FMT(LFPARAM, "%s(%d): pc->Text() is '%s', type is %s\n",
+ __func__, __LINE__, pc->Text(), get_token_name(pc->GetType()));
+ }
+
+ Chunk *last = pc->GetPrevNcNnlNi(); // Issue #2279
+
+ LOG_FMT(LFPARAM, "%s(%d): last->Text() is '%s', type is %s\n",
+ __func__, __LINE__, last->Text(), get_token_name(last->GetType()));
+
+ if (last->IsPointerOperator())
+ {
+ LOG_FMT(LFPARAM, "%s(%d): <== type is %s, sure!\n",
+ __func__, __LINE__, get_token_name(last->GetType()));
+ return(true);
+ }
+
+ if ( word_count < 2
+ && type_count < 1
+ && start->GetBraceLevel() > 0)
+ {
+ LOG_FMT(LFPARAM, "%s(%d): !MVP!\n",
+ __func__, __LINE__);
+ // Oh, joy, we are in Most Vexing Parse territory
+ Chunk *brace =
+ start->GetPrevType(CT_BRACE_OPEN, start->GetBraceLevel() - 1);
+
+ if (brace->IsNotNullChunk())
+ {
+ LOG_FMT(LFPARAM, "%s(%d): (matching %s brace at orig line %zu, orig col is %zu)",
+ __func__, __LINE__,
+ get_token_name(brace->GetParentType()), brace->GetOrigLine(), brace->GetOrigCol());
+ }
+
+ if ( brace->IsNotNullChunk()
+ && ( brace->GetParentType() == CT_CLASS
+ || brace->GetParentType() == CT_STRUCT))
+ {
+ // A Most Vexing Parse variable declaration cannot occur in the body
+ // of a struct/class, so we probably have a function prototype
+ LOG_FMT(LFPARAM, "%s(%d): <== type is %s, Likely!\n",
+ __func__, __LINE__, (pc->IsNullChunk() ? "null chunk" : get_token_name(pc->GetType())));
+ return(true);
+ }
+ }
+ LOG_FMT(LFPARAM, "%s(%d): pc->Text() is '%s', word_count is %d, type_count is %d\n",
+ __func__, __LINE__, pc->Text(), word_count, type_count);
+
+ if (first_word->IsNotNullChunk())
+ {
+ LOG_FMT(LFPARAM, "%s(%d): first_word->Text() is '%s'\n",
+ __func__, __LINE__, first_word->Text());
+ }
+ bool ret = ( word_count >= 2
+ || ( word_count == 1
+ && type_count == 1));
+
+ LOG_FMT(LFPARAM, "%s(%d): ret is %s\n",
+ __func__, __LINE__, ret ? "TRUE" : "FALSE");
+
+ LOG_FMT(LFPARAM, "%s(%d): pc->Text() is '%s', ",
+ __func__, __LINE__, pc->Text());
+ LOG_FMT(LFPARAM, "<== type is %s, ",
+ (pc->IsNullChunk() ? "null chunk" : get_token_name(pc->GetType())));
+
+ if (ret)
+ {
+ LOG_FMT(LFPARAM, "Yup!\n");
+ }
+ else
+ {
+ LOG_FMT(LFPARAM, "Unlikely!\n");
+ }
+ return(ret);
+} // can_be_full_param
+
+
+bool chunk_ends_type(Chunk *start)
+{
+ LOG_FUNC_ENTRY();
+
+ if (start->TestFlags(PCF_IN_FCN_CTOR))
+ {
+ return(false);
+ }
+ Chunk *pc = start;
+ bool ret = false;
+ size_t cnt = 0;
+ bool last_expr = false;
+ bool last_lval = false;
+
+ for ( ; pc->IsNotNullChunk(); pc = pc->GetPrevNcNnlNi()) // Issue #2279
+ {
+ LOG_FMT(LFTYPE, "%s(%d): type is %s, Text() '%s', orig line %zu, orig col %zu\n ",
+ __func__, __LINE__, get_token_name(pc->GetType()), pc->Text(),
+ pc->GetOrigLine(), pc->GetOrigCol());
+ log_pcf_flags(LFTYPE, pc->GetFlags());
+
+ if ( pc->Is(CT_WORD)
+ || pc->Is(CT_TYPE)
+ || pc->Is(CT_PTR_TYPE)
+ || pc->Is(CT_STAR)
+ || pc->Is(CT_STRUCT)
+ || pc->Is(CT_DC_MEMBER)
+ || pc->Is(CT_PP)
+ || pc->Is(CT_QUALIFIER)
+ || ( language_is_set(LANG_CPP | LANG_OC) // Issue #2727
+ && pc->GetParentType() == CT_TEMPLATE
+ && ( pc->Is(CT_ANGLE_OPEN)
+ || pc->Is(CT_ANGLE_CLOSE)))
+ || ( language_is_set(LANG_CS | LANG_VALA)
+ && (pc->Is(CT_MEMBER))))
+ {
+ cnt++;
+ last_expr = pc->TestFlags(PCF_EXPR_START)
+ && !pc->TestFlags(PCF_IN_FCN_CALL);
+ last_lval = pc->TestFlags(PCF_LVALUE);
+ continue;
+ }
+ /* If a comma is encountered within a template, it must be
+ * considered within the context of its immediate parent
+ * template (i.e. argument list nest level)
+ */
+
+ if ( ( pc->IsSemicolon()
+ && !pc->TestFlags(PCF_IN_FOR))
+ || pc->Is(CT_TYPEDEF)
+ || pc->Is(CT_BRACE_OPEN)
+ || pc->IsBraceClose()
+ || pc->Is(CT_FPAREN_CLOSE)
+ || pc->IsOCForinOpenParen()
+ || pc->Is(CT_MACRO)
+ || pc->Is(CT_PP_IF)
+ || pc->Is(CT_PP_ELSE)
+ || pc->Is(CT_PP_ENDIF)
+ || pc->GetParentType() == CT_PP_INCLUDE // Issue #3233
+ || ( ( pc->Is(CT_COMMA)
+ && !pc->TestFlags(PCF_IN_FCN_CALL)
+ && get_cpp_template_angle_nest_level(start) ==
+ get_cpp_template_angle_nest_level(pc))
+ && last_expr)
+ || ( pc->Is(CT_SPAREN_OPEN)
+ && last_lval))
+ {
+ ret = cnt > 0;
+ }
+ break;
+ }
+
+ if (pc->IsNullChunk())
+ {
+ // first token
+ ret = true;
+ }
+ LOG_FMT(LFTYPE, "%s(%d): first token verdict: %s\n",
+ __func__, __LINE__, ret ? "yes" : "no");
+
+ return(ret);
+} // chunk_ends_type
+
+
+bool chunkstack_match(ChunkStack &cs, Chunk *pc)
+{
+ for (size_t idx = 0; idx < cs.Len(); idx++)
+ {
+ Chunk *tmp = cs.GetChunk(idx);
+
+ if (pc->GetStr().equals(tmp->GetStr()))
+ {
+ return(true);
+ }
+ }
+
+ return(false);
+} // chunkstack_match
+
+
+void flag_series(Chunk *start, Chunk *end, PcfFlags set_flags, PcfFlags clr_flags, E_Scope nav)
+{
+ LOG_FUNC_ENTRY();
+
+ while ( start->IsNotNullChunk()
+ && start != end)
+ {
+ start->UpdateFlagBits(clr_flags, set_flags);
+ log_pcf_flags(LFTYPE, start->GetFlags());
+
+ start = start->GetNext(nav);
+
+ if (start->IsNullChunk())
+ {
+ return;
+ }
+ }
+
+ if (end->IsNotNullChunk())
+ {
+ end->UpdateFlagBits(clr_flags, set_flags);
+ log_pcf_flags(LFTYPE, end->GetFlags());
+ }
+} // flag_series
+
+
+size_t get_cpp_template_angle_nest_level(Chunk *pc)
+{
+ LOG_FUNC_ENTRY();
+ int nestLevel = 0;
+
+ while ( pc->IsNotNullChunk()
+ && pc->TestFlags(PCF_IN_TEMPLATE))
+ {
+ if ( pc->Is(CT_ANGLE_CLOSE)
+ && pc->GetParentType() == CT_TEMPLATE)
+ {
+ --nestLevel;
+ }
+ else if ( pc->Is(CT_ANGLE_OPEN)
+ && pc->GetParentType() == CT_TEMPLATE)
+ {
+ ++nestLevel;
+ }
+ pc = pc->GetPrevNcNnlNi();
+ }
+ return(nestLevel <= 0 ? 0 : size_t(nestLevel));
+}
+
+
+Chunk *get_d_template_types(ChunkStack &cs, Chunk *open_paren)
+{
+ LOG_FUNC_ENTRY();
+ Chunk *tmp = open_paren->GetNextNcNnl();
+ bool maybe_type = true;
+
+ while ( tmp->IsNullChunk()
+ && tmp->GetLevel() > open_paren->GetLevel())
+ {
+ if ( tmp->Is(CT_TYPE)
+ || tmp->Is(CT_WORD))
+ {
+ if (maybe_type)
+ {
+ make_type(tmp);
+ cs.Push_Back(tmp);
+ }
+ maybe_type = false;
+ }
+ else if (tmp->Is(CT_COMMA))
+ {
+ maybe_type = true;
+ }
+ tmp = tmp->GetNextNcNnl();
+ }
+ return(tmp);
+} // get_d_template_types
+
+
+bool go_on(Chunk *pc, Chunk *start)
+{
+ if ( pc->IsNullChunk()
+ || pc->GetLevel() != start->GetLevel())
+ {
+ return(false);
+ }
+
+ if (pc->TestFlags(PCF_IN_FOR))
+ {
+ return( (!pc->IsSemicolon())
+ && (!(pc->Is(CT_COLON))));
+ }
+ return(!pc->IsSemicolon());
+} // go_on
+
+
+bool is_ucase_str(const char *str, size_t len)
+{
+ while (len-- > 0)
+ {
+ if (unc_toupper(*str) != *str)
+ {
+ return(false);
+ }
+ str++;
+ }
+ return(true);
+} // is_ucase_str
+
+
+void make_type(Chunk *pc)
+{
+ LOG_FUNC_ENTRY();
+
+ if (pc->IsNotNullChunk())
+ {
+ if (pc->Is(CT_WORD))
+ {
+ pc->SetType(CT_TYPE);
+ }
+ else if ( ( pc->IsStar()
+ || pc->IsMsRef()
+ || pc->IsNullable())
+ && pc->GetPrev()->IsTypeDefinition()) // Issue # 2640
+ {
+ pc->SetType(CT_PTR_TYPE);
+ }
+ else if ( pc->IsAddress()
+ && pc->GetPrev()->IsNot(CT_SQUARE_OPEN)) // Issue # 2166
+ {
+ pc->SetType(CT_BYREF);
+ }
+ }
+} // make_type
+
+
+Chunk *set_paren_parent(Chunk *start, E_Token parent_type)
+{
+ LOG_FUNC_ENTRY();
+ Chunk *end;
+
+ end = start->GetClosingParen(E_Scope::PREPROC);
+
+ if (end->IsNotNullChunk())
+ {
+ LOG_FMT(LFLPAREN, "%s(%d): %zu:%zu '%s' and %zu:%zu '%s' type is %s, parent type is %s",
+ __func__, __LINE__, start->GetOrigLine(), start->GetOrigCol(), start->Text(),
+ end->GetOrigLine(), end->GetOrigCol(), end->Text(),
+ get_token_name(start->GetType()), get_token_name(parent_type));
+ log_func_stack_inline(LFLPAREN);
+ start->SetParentType(parent_type);
+ end->SetParentType(parent_type);
+ LOG_FMT(LFLPAREN, "%s(%d):\n", __func__, __LINE__);
+ return(end->GetNextNcNnl(E_Scope::PREPROC));
+ }
+ LOG_FMT(LFLPAREN, "%s(%d):\n", __func__, __LINE__);
+ return(Chunk::NullChunkPtr);
+} // set_paren_parent