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.

231 lines
7.5 KiB

/**
* @file align_func_proto.cpp
*
* @author Guy Maurel
* split from align.cpp
* @author Ben Gardner
* @license GPL v2+
*/
#include "align_func_proto.h"
#include "align_stack.h"
#include "align_tools.h"
#include "log_rules.h"
#include <algorithm> // to get max
constexpr static auto LCURRENT = LALPROTO;
using namespace uncrustify;
void align_func_proto(size_t span)
{
LOG_FUNC_ENTRY();
size_t myspan = span;
size_t mythresh = 0;
log_rule_B("align_func_proto_gap");
size_t mygap = options::align_func_proto_gap();
log_rule_B("align_func_proto_thresh");
mythresh = options::align_func_proto_thresh();
// Issue #2771
// we align token-1 and token-2 if:
// token-1->GetLevel() == token-2->GetLevel()
// and
// token-1->GetBraceLevel() == token-2->GetBraceLevel()
// we don't check if token-1 and token-2 are in the same block
log_rule_B("align_func_proto_star_style");
size_t mystar_style = options::align_func_proto_star_style();
log_rule_B("align_func_proto_amp_style");
size_t myamp_style = options::align_func_proto_amp_style();
size_t num_of_column = 1;
size_t num_of_row = 1;
AlignStack *stack_init_value = nullptr;
// Issue #2984
vector<vector<AlignStack *> > many_as;
// Issue #2771
vector<vector<AlignStack *> > many_as_brace;
// init the vector ...
many_as.resize(num_of_column, vector<AlignStack *>(num_of_row, stack_init_value));
many_as_brace.resize(num_of_column, vector<AlignStack *>(num_of_row, stack_init_value));
log_rule_B("align_single_line_brace_gap");
size_t mybr_gap = options::align_single_line_brace_gap();
bool look_bro = false;
Chunk *toadd;
for (Chunk *pc = Chunk::GetHead(); pc->IsNotNullChunk(); pc = pc->GetNext())
{
char copy[1000];
LOG_FMT(LAS, "%s(%d): orig line %zu, orig col %zu, text '%s', type %s, level %zu, brace level %zu\n",
__func__, __LINE__, pc->GetOrigLine(), pc->GetOrigCol(), pc->ElidedText(copy),
get_token_name(pc->GetType()), pc->GetLevel(), pc->GetBraceLevel());
// make the vector larger if necessary
if ( pc->GetLevel() >= num_of_column // Issue #2960
|| pc->GetBraceLevel() >= num_of_row)
{
num_of_column = pc->GetLevel() + 1;
num_of_row = pc->GetBraceLevel() + 1;
many_as.resize(num_of_column);
many_as_brace.resize(num_of_column);
for (size_t i = 0; i < num_of_column; ++i)
{
many_as[i].resize(num_of_row);
many_as_brace[i].resize(num_of_row);
}
}
if ( pc->IsNewline()
&& ( !options::align_func_proto_span_ignore_cont_lines()
|| !pc->GetNextNnl()->TestFlags(PCF_CONT_LINE)) // Issue #4131
&& !pc->TestFlags(PCF_IN_FCN_CALL)) // Issue #2831
{
look_bro = false;
AlignStack *stack_at_l_bl = many_as.at(pc->GetLevel()).at(pc->GetBraceLevel());
if (stack_at_l_bl == nullptr)
{
// get a Stack
stack_at_l_bl = new AlignStack();
// start it
stack_at_l_bl->Start(myspan, mythresh);
stack_at_l_bl->m_gap = mygap;
stack_at_l_bl->m_star_style = static_cast<AlignStack::StarStyle>(mystar_style);
stack_at_l_bl->m_amp_style = static_cast<AlignStack::StarStyle>(myamp_style);
// store
many_as.at(pc->GetLevel()).at(pc->GetBraceLevel()) = stack_at_l_bl;
}
stack_at_l_bl->Debug();
for (size_t idx = 0; idx < num_of_column; idx++)
{
for (size_t idx_brace = 0; idx_brace < num_of_row; idx_brace++)
{
stack_at_l_bl = many_as.at(idx).at(idx_brace);
if (stack_at_l_bl != nullptr)
{
stack_at_l_bl->NewLines(pc->GetNlCount());
}
}
}
AlignStack *stack_at_l_bl_brace = many_as_brace.at(pc->GetLevel()).at(pc->GetBraceLevel());
if (stack_at_l_bl_brace == nullptr)
{
// get a Stack
stack_at_l_bl_brace = new AlignStack();
// start it
stack_at_l_bl_brace->Start(myspan, mythresh);
stack_at_l_bl_brace->m_gap = mybr_gap;
// store
many_as_brace.at(pc->GetLevel()).at(pc->GetBraceLevel()) = stack_at_l_bl_brace;
}
stack_at_l_bl_brace->Debug();
stack_at_l_bl_brace->NewLines(pc->GetNlCount());
}
else if ( pc->Is(CT_FUNC_PROTO)
|| ( pc->Is(CT_FUNC_DEF)
&& options::align_single_line_func()))
{
log_rule_B("align_single_line_func");
log_rule_B("align_on_operator");
if ( pc->GetParentType() == CT_OPERATOR
&& options::align_on_operator())
{
toadd = pc->GetPrevNcNnl();
}
else
{
toadd = pc;
}
Chunk *tmp = step_back_over_member(toadd);
LOG_FMT(LAS, "%s(%d): 'tmp' text is '%s', orig line is %zu, orig col is %zu, level is %zu, brace level is %zu\n",
__func__, __LINE__, tmp->Text(), tmp->GetOrigLine(), tmp->GetOrigCol(),
tmp->GetLevel(), tmp->GetBraceLevel());
// test the Stack
AlignStack *stack_at_l_bl = many_as.at(pc->GetLevel()).at(pc->GetBraceLevel());
if (stack_at_l_bl == nullptr)
{
// get a Stack
stack_at_l_bl = new AlignStack();
// start it
stack_at_l_bl->Start(myspan, mythresh);
stack_at_l_bl->m_gap = mygap;
stack_at_l_bl->m_star_style = static_cast<AlignStack::StarStyle>(mystar_style);
stack_at_l_bl->m_amp_style = static_cast<AlignStack::StarStyle>(myamp_style);
// store
many_as.at(pc->GetLevel()).at(pc->GetBraceLevel()) = stack_at_l_bl;
}
stack_at_l_bl->Add(tmp);
stack_at_l_bl->Debug();
log_rule_B("align_single_line_brace");
look_bro = (pc->Is(CT_FUNC_DEF))
&& options::align_single_line_brace();
}
else if ( look_bro
&& pc->Is(CT_BRACE_OPEN)
&& pc->TestFlags(PCF_ONE_LINER))
{
AlignStack *stack_at_l_bl_brace = many_as_brace.at(pc->GetLevel()).at(pc->GetBraceLevel());
if (stack_at_l_bl_brace == nullptr)
{
stack_at_l_bl_brace = new AlignStack();
stack_at_l_bl_brace->Start(myspan, mythresh);
stack_at_l_bl_brace->m_gap = mybr_gap;
many_as_brace.at(pc->GetLevel()).at(pc->GetBraceLevel()) = stack_at_l_bl_brace;
}
stack_at_l_bl_brace->Add(pc);
stack_at_l_bl_brace->Debug();
look_bro = false;
}
}
LOG_FMT(LAS, "%s(%d): as\n", __func__, __LINE__);
// purge
for (size_t idx = 0; idx < num_of_column; idx++)
{
for (size_t idx_brace = 0; idx_brace < num_of_row; idx_brace++)
{
AlignStack *stack_at_l_bl = many_as.at(idx).at(idx_brace);
if (stack_at_l_bl != nullptr)
{
stack_at_l_bl->End();
delete stack_at_l_bl;
stack_at_l_bl = nullptr;
}
AlignStack *stack_at_l_bl_brace = many_as_brace.at(idx).at(idx_brace);
if (stack_at_l_bl_brace != nullptr)
{
stack_at_l_bl_brace->End();
delete stack_at_l_bl_brace;
stack_at_l_bl_brace = nullptr;
}
}
}
} // align_func_proto