You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
446 lines
10 KiB
446 lines
10 KiB
/**
|
|
* @file detect.cpp
|
|
* Scans the parsed file and tries to determine options.
|
|
*
|
|
* @author Ben Gardner
|
|
* @license GPL v2+
|
|
*/
|
|
|
|
#include "detect.h"
|
|
|
|
#include "prototypes.h"
|
|
|
|
|
|
using namespace uncrustify;
|
|
|
|
|
|
//! Detect spacing options
|
|
static void detect_space_options();
|
|
|
|
|
|
class sp_votes
|
|
{
|
|
protected:
|
|
size_t m_add = 0;
|
|
size_t m_remove = 0;
|
|
size_t m_force = 0;
|
|
Option<iarf_e> &m_option;
|
|
|
|
public:
|
|
sp_votes(Option<iarf_e> &opt)
|
|
: m_option(opt)
|
|
{}
|
|
|
|
//! Figure out the result of the vote and maybe update *m_av
|
|
~sp_votes();
|
|
|
|
void vote(Chunk *first, Chunk *second);
|
|
};
|
|
|
|
|
|
void sp_votes::vote(Chunk *first, Chunk *second)
|
|
{
|
|
if ( first->IsNullChunk()
|
|
|| first->IsNewline()
|
|
|| second->IsNullChunk()
|
|
|| second->IsNewline())
|
|
{
|
|
return;
|
|
}
|
|
int col_dif = second->GetColumn() - (first->GetColumn() + first->Len());
|
|
|
|
if (col_dif == 0)
|
|
{
|
|
m_remove++;
|
|
}
|
|
else if (col_dif == 1)
|
|
{
|
|
m_force++;
|
|
}
|
|
else
|
|
{
|
|
m_add++;
|
|
}
|
|
}
|
|
|
|
|
|
//! Figure out the result of the vote and maybe update *m_av
|
|
sp_votes::~sp_votes()
|
|
{
|
|
// no change if no items were added
|
|
if ( m_remove == 0
|
|
&& m_add == 0
|
|
&& m_force == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (m_remove == 0)
|
|
{
|
|
m_option = (m_force > m_add) ? IARF_FORCE : IARF_ADD;
|
|
}
|
|
else if ( m_force == 0
|
|
&& m_add == 0)
|
|
{
|
|
m_option = IARF_REMOVE;
|
|
}
|
|
else
|
|
{
|
|
// nothing conclusive. do not alter.
|
|
}
|
|
}
|
|
|
|
|
|
// generates "vote_sp_xxx" variable name from uncrustify option name "options::xxx()"
|
|
#define SP_VOTE_VAR(x) sp_votes vote_ ## x(options::x)
|
|
|
|
|
|
static void detect_space_options()
|
|
{
|
|
SP_VOTE_VAR(sp_arith);
|
|
SP_VOTE_VAR(sp_before_assign);
|
|
SP_VOTE_VAR(sp_after_assign);
|
|
SP_VOTE_VAR(sp_enum_before_assign);
|
|
SP_VOTE_VAR(sp_enum_after_assign);
|
|
SP_VOTE_VAR(sp_bool);
|
|
SP_VOTE_VAR(sp_compare);
|
|
SP_VOTE_VAR(sp_inside_paren);
|
|
SP_VOTE_VAR(sp_paren_paren);
|
|
SP_VOTE_VAR(sp_paren_brace);
|
|
SP_VOTE_VAR(sp_before_ptr_star);
|
|
SP_VOTE_VAR(sp_before_unnamed_ptr_star);
|
|
SP_VOTE_VAR(sp_between_ptr_star);
|
|
SP_VOTE_VAR(sp_between_ptr_ref);
|
|
SP_VOTE_VAR(sp_after_ptr_star);
|
|
SP_VOTE_VAR(sp_after_byref);
|
|
SP_VOTE_VAR(sp_before_byref);
|
|
SP_VOTE_VAR(sp_before_unnamed_byref);
|
|
SP_VOTE_VAR(sp_after_type);
|
|
SP_VOTE_VAR(sp_template_angle);
|
|
SP_VOTE_VAR(sp_before_angle);
|
|
SP_VOTE_VAR(sp_inside_angle);
|
|
SP_VOTE_VAR(sp_after_angle);
|
|
SP_VOTE_VAR(sp_angle_paren);
|
|
SP_VOTE_VAR(sp_angle_word);
|
|
SP_VOTE_VAR(sp_before_square);
|
|
SP_VOTE_VAR(sp_before_squares);
|
|
SP_VOTE_VAR(sp_inside_square);
|
|
SP_VOTE_VAR(sp_before_sparen);
|
|
SP_VOTE_VAR(sp_inside_sparen);
|
|
SP_VOTE_VAR(sp_after_sparen);
|
|
SP_VOTE_VAR(sp_sparen_brace);
|
|
SP_VOTE_VAR(sp_special_semi);
|
|
SP_VOTE_VAR(sp_before_semi);
|
|
SP_VOTE_VAR(sp_before_semi_for);
|
|
SP_VOTE_VAR(sp_before_semi_for_empty);
|
|
SP_VOTE_VAR(sp_after_semi_for_empty);
|
|
SP_VOTE_VAR(sp_after_comma);
|
|
SP_VOTE_VAR(sp_before_comma);
|
|
SP_VOTE_VAR(sp_after_class_colon);
|
|
SP_VOTE_VAR(sp_before_class_colon);
|
|
SP_VOTE_VAR(sp_inside_braces);
|
|
SP_VOTE_VAR(sp_inside_braces_empty);
|
|
SP_VOTE_VAR(sp_else_brace);
|
|
SP_VOTE_VAR(sp_brace_else);
|
|
SP_VOTE_VAR(sp_catch_brace);
|
|
SP_VOTE_VAR(sp_brace_catch);
|
|
SP_VOTE_VAR(sp_finally_brace);
|
|
SP_VOTE_VAR(sp_brace_finally);
|
|
SP_VOTE_VAR(sp_try_brace);
|
|
SP_VOTE_VAR(sp_getset_brace);
|
|
|
|
Chunk *prev = Chunk::GetHead();
|
|
Chunk *pc = prev->GetNext();
|
|
Chunk *next;
|
|
|
|
while (pc->IsNotNullChunk())
|
|
{
|
|
next = pc->GetNext();
|
|
|
|
if (next->IsNullChunk())
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ( pc->Is(CT_ARITH)
|
|
|| pc->Is(CT_SHIFT))
|
|
{
|
|
vote_sp_arith.vote(pc, next);
|
|
vote_sp_arith.vote(prev, pc);
|
|
}
|
|
|
|
if (pc->Is(CT_ASSIGN))
|
|
{
|
|
if (!pc->TestFlags(PCF_IN_ENUM))
|
|
{
|
|
vote_sp_before_assign.vote(prev, pc);
|
|
vote_sp_after_assign.vote(pc, next);
|
|
}
|
|
else
|
|
{
|
|
vote_sp_enum_before_assign.vote(prev, pc);
|
|
vote_sp_enum_after_assign.vote(pc, next);
|
|
}
|
|
}
|
|
|
|
if (pc->Is(CT_SQUARE_OPEN))
|
|
{
|
|
vote_sp_before_square.vote(prev, pc);
|
|
vote_sp_inside_square.vote(pc, next);
|
|
}
|
|
|
|
if (pc->Is(CT_SQUARE_CLOSE))
|
|
{
|
|
vote_sp_inside_square.vote(prev, pc);
|
|
}
|
|
|
|
if (pc->Is(CT_TSQUARE))
|
|
{
|
|
vote_sp_before_squares.vote(prev, pc);
|
|
}
|
|
|
|
if (pc->Is(CT_BOOL))
|
|
{
|
|
vote_sp_bool.vote(prev, pc);
|
|
vote_sp_bool.vote(pc, next);
|
|
}
|
|
|
|
if (pc->Is(CT_COMPARE))
|
|
{
|
|
vote_sp_compare.vote(prev, pc);
|
|
vote_sp_compare.vote(pc, next);
|
|
}
|
|
|
|
if (pc->Is(CT_PAREN_CLOSE))
|
|
{
|
|
vote_sp_inside_paren.vote(prev, pc);
|
|
}
|
|
|
|
if (pc->Is(CT_PAREN_OPEN))
|
|
{
|
|
vote_sp_inside_paren.vote(pc, next);
|
|
}
|
|
|
|
if ( ( pc->IsParenOpen()
|
|
&& next->IsParenOpen())
|
|
|| ( pc->IsParenClose()
|
|
&& next->IsParenClose()))
|
|
{
|
|
vote_sp_paren_paren.vote(pc, next);
|
|
}
|
|
|
|
if ( pc->IsParenClose()
|
|
&& next->Is(CT_BRACE_OPEN))
|
|
{
|
|
vote_sp_paren_brace.vote(pc, next);
|
|
}
|
|
|
|
if (pc->Is(CT_PTR_TYPE))
|
|
{
|
|
if (prev->Is(CT_PTR_TYPE))
|
|
{
|
|
vote_sp_between_ptr_star.vote(prev, pc);
|
|
}
|
|
else if (next->IsNot(CT_WORD))
|
|
{
|
|
vote_sp_before_unnamed_ptr_star.vote(prev, pc);
|
|
}
|
|
else
|
|
{
|
|
vote_sp_before_ptr_star.vote(prev, pc);
|
|
}
|
|
|
|
if (CharTable::IsKw1(next->GetStr()[0]))
|
|
{
|
|
vote_sp_after_ptr_star.vote(pc, next);
|
|
}
|
|
}
|
|
|
|
if (pc->Is(CT_BYREF))
|
|
{
|
|
if (next->IsNot(CT_WORD))
|
|
{
|
|
vote_sp_before_unnamed_byref.vote(prev, pc);
|
|
}
|
|
|
|
if (prev->Is(CT_PTR_TYPE))
|
|
{
|
|
vote_sp_between_ptr_ref.vote(prev, pc);
|
|
}
|
|
else
|
|
{
|
|
vote_sp_before_byref.vote(prev, pc);
|
|
}
|
|
vote_sp_after_byref.vote(pc, next);
|
|
}
|
|
|
|
if ( pc->IsNot(CT_PTR_TYPE)
|
|
&& ( prev->Is(CT_QUALIFIER)
|
|
|| prev->Is(CT_TYPE)))
|
|
{
|
|
vote_sp_after_type.vote(prev, pc);
|
|
}
|
|
|
|
if (pc->Is(CT_ANGLE_OPEN))
|
|
{
|
|
vote_sp_inside_angle.vote(pc, next);
|
|
|
|
if (prev->Is(CT_TEMPLATE))
|
|
{
|
|
vote_sp_template_angle.vote(prev, pc);
|
|
}
|
|
else
|
|
{
|
|
vote_sp_before_angle.vote(prev, pc);
|
|
}
|
|
}
|
|
|
|
if (pc->Is(CT_ANGLE_CLOSE))
|
|
{
|
|
vote_sp_inside_angle.vote(prev, pc);
|
|
|
|
if (next->IsParenOpen())
|
|
{
|
|
vote_sp_angle_paren.vote(prev, pc);
|
|
}
|
|
else if ( next->Is(CT_WORD)
|
|
|| CharTable::IsKw1(next->GetStr()[0]))
|
|
{
|
|
vote_sp_angle_word.vote(prev, pc);
|
|
}
|
|
else
|
|
{
|
|
vote_sp_after_angle.vote(pc, next);
|
|
}
|
|
}
|
|
|
|
if (pc->Is(CT_SPAREN_OPEN))
|
|
{
|
|
vote_sp_before_sparen.vote(prev, pc);
|
|
vote_sp_inside_sparen.vote(pc, next);
|
|
}
|
|
|
|
if (pc->Is(CT_SPAREN_CLOSE))
|
|
{
|
|
vote_sp_inside_sparen.vote(prev, pc);
|
|
|
|
if (next->Is(CT_BRACE_OPEN))
|
|
{
|
|
vote_sp_sparen_brace.vote(pc, next);
|
|
}
|
|
else
|
|
{
|
|
vote_sp_after_sparen.vote(pc, next);
|
|
}
|
|
}
|
|
|
|
if (pc->Is(CT_SEMICOLON))
|
|
{
|
|
if (pc->GetParentType() == CT_FOR)
|
|
{
|
|
if (prev->Is(CT_SPAREN_OPEN))
|
|
{
|
|
// empty, ie for (;;)
|
|
// ^ is prev
|
|
// ^ is pc
|
|
vote_sp_before_semi_for_empty.vote(prev, pc);
|
|
}
|
|
else if (next->Is(CT_SPAREN_CLOSE))
|
|
{
|
|
// empty, ie for (;;)
|
|
// ^ is pc
|
|
// ^ is next
|
|
vote_sp_after_semi_for_empty.vote(pc, next);
|
|
}
|
|
else if (prev->IsNot(CT_SEMICOLON))
|
|
{
|
|
// empty, ie for (; i < 8;)
|
|
// ^ is pc
|
|
// or
|
|
// ^ is prev
|
|
vote_sp_before_semi_for.vote(prev, pc);
|
|
}
|
|
}
|
|
else if (prev->Is(CT_VBRACE_OPEN))
|
|
{
|
|
vote_sp_special_semi.vote(prev->GetPrev(), pc);
|
|
}
|
|
else
|
|
{
|
|
vote_sp_before_semi.vote(prev, pc);
|
|
}
|
|
}
|
|
|
|
if (pc->Is(CT_COMMA))
|
|
{
|
|
vote_sp_before_comma.vote(prev, pc);
|
|
vote_sp_after_comma.vote(pc, next);
|
|
}
|
|
|
|
if (pc->Is(CT_CLASS_COLON))
|
|
{
|
|
vote_sp_before_class_colon.vote(prev, pc);
|
|
vote_sp_after_class_colon.vote(pc, next);
|
|
}
|
|
|
|
if (pc->Is(CT_BRACE_OPEN))
|
|
{
|
|
if (prev->Is(CT_ELSE))
|
|
{
|
|
vote_sp_else_brace.vote(prev, pc);
|
|
}
|
|
else if (prev->Is(CT_CATCH))
|
|
{
|
|
vote_sp_catch_brace.vote(prev, pc);
|
|
}
|
|
else if (prev->Is(CT_FINALLY))
|
|
{
|
|
vote_sp_catch_brace.vote(prev, pc);
|
|
}
|
|
else if (prev->Is(CT_TRY))
|
|
{
|
|
vote_sp_catch_brace.vote(prev, pc);
|
|
}
|
|
else if (prev->Is(CT_GETSET))
|
|
{
|
|
vote_sp_catch_brace.vote(prev, pc);
|
|
}
|
|
|
|
if (next->Is(CT_BRACE_CLOSE))
|
|
{
|
|
vote_sp_inside_braces_empty.vote(pc, next);
|
|
}
|
|
else
|
|
{
|
|
vote_sp_inside_braces.vote(pc, next);
|
|
}
|
|
}
|
|
|
|
if (pc->Is(CT_BRACE_CLOSE))
|
|
{
|
|
vote_sp_inside_braces.vote(prev, pc);
|
|
|
|
if (next->Is(CT_ELSE))
|
|
{
|
|
vote_sp_brace_else.vote(pc, next);
|
|
}
|
|
else if (next->Is(CT_CATCH))
|
|
{
|
|
vote_sp_brace_catch.vote(pc, next);
|
|
}
|
|
else if (next->Is(CT_FINALLY))
|
|
{
|
|
vote_sp_brace_finally.vote(pc, next);
|
|
}
|
|
}
|
|
prev = pc;
|
|
pc = next;
|
|
}
|
|
} // detect_space_options
|
|
|
|
|
|
void detect_options()
|
|
{
|
|
detect_space_options();
|
|
}
|