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.
183 lines
4.3 KiB
183 lines
4.3 KiB
/**
|
|
* @file align_oc_msg_colons.cpp
|
|
*
|
|
* @author Guy Maurel
|
|
* @license GPL v2+
|
|
*/
|
|
|
|
#include "align_oc_msg_colons.h"
|
|
|
|
#include "align_stack.h"
|
|
#include "log_rules.h"
|
|
|
|
constexpr static auto LCURRENT = LOCMSG;
|
|
|
|
using namespace uncrustify;
|
|
|
|
|
|
void align_oc_msg_colon(Chunk *so)
|
|
{
|
|
LOG_FUNC_ENTRY();
|
|
|
|
AlignStack nas; // for the parameter tag
|
|
|
|
nas.Start(1);
|
|
nas.Reset();
|
|
log_rule_B("align_on_tabstop");
|
|
nas.m_right_align = !options::align_on_tabstop();
|
|
|
|
AlignStack cas; // for the colons
|
|
|
|
log_rule_B("align_oc_msg_colon_span");
|
|
size_t span = options::align_oc_msg_colon_span();
|
|
|
|
cas.Start(span);
|
|
|
|
size_t level = so->GetLevel();
|
|
Chunk *pc = so->GetNextNcNnl(E_Scope::PREPROC);
|
|
|
|
bool did_line = false;
|
|
bool has_colon = false;
|
|
size_t lcnt = 0; // line count with no colon for span
|
|
bool first_line = true;
|
|
|
|
while ( pc->IsNotNullChunk()
|
|
&& pc->GetLevel() > level)
|
|
{
|
|
if (pc->GetLevel() > (level + 1))
|
|
{
|
|
// do nothing
|
|
}
|
|
else if (pc->IsNewline())
|
|
{
|
|
if (!has_colon)
|
|
{
|
|
++lcnt;
|
|
}
|
|
did_line = false;
|
|
|
|
log_rule_B("align_oc_msg_colon_xcode_like");
|
|
|
|
if ( options::align_oc_msg_colon_xcode_like()
|
|
&& first_line
|
|
&& !has_colon)
|
|
{
|
|
span = 0;
|
|
}
|
|
has_colon = !has_colon;
|
|
first_line = false;
|
|
}
|
|
else if ( !did_line
|
|
&& (lcnt < span + 1)
|
|
&& pc->Is(CT_OC_COLON))
|
|
{
|
|
has_colon = true;
|
|
cas.Add(pc);
|
|
Chunk *tmp = pc->GetPrev();
|
|
|
|
if ( tmp->IsNotNullChunk()
|
|
&& ( tmp->Is(CT_OC_MSG_FUNC)
|
|
|| tmp->Is(CT_OC_MSG_NAME)))
|
|
{
|
|
nas.Add(tmp);
|
|
tmp->SetFlagBits(PCF_DONT_INDENT);
|
|
}
|
|
did_line = true;
|
|
}
|
|
pc = pc->GetNext(E_Scope::PREPROC);
|
|
}
|
|
log_rule_B("align_oc_msg_colon_first");
|
|
nas.m_skip_first = !options::align_oc_msg_colon_first();
|
|
cas.m_skip_first = !options::align_oc_msg_colon_first();
|
|
|
|
// find the longest args that isn't the first one
|
|
size_t first_len = 0;
|
|
size_t mlen = 0;
|
|
Chunk *longest = Chunk::NullChunkPtr;
|
|
|
|
size_t len = nas.m_aligned.Len();
|
|
|
|
for (size_t idx = 0; idx < len; idx++)
|
|
{
|
|
Chunk *tmp = nas.m_aligned.GetChunk(idx);
|
|
|
|
if (tmp->IsNotNullChunk())
|
|
{
|
|
size_t tlen = tmp->GetStr().size();
|
|
|
|
if (tlen > mlen)
|
|
{
|
|
mlen = tlen;
|
|
|
|
if (idx != 0)
|
|
{
|
|
longest = tmp;
|
|
}
|
|
}
|
|
|
|
if (idx == 0)
|
|
{
|
|
first_len = tlen + 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
// add spaces before the longest arg
|
|
log_rule_B("indent_oc_msg_colon");
|
|
len = options::indent_oc_msg_colon();
|
|
size_t len_diff = mlen - first_len;
|
|
|
|
log_rule_B("indent_columns");
|
|
size_t indent_size = options::indent_columns();
|
|
|
|
// Align with first colon if possible by removing spaces
|
|
log_rule_B("indent_oc_msg_prioritize_first_colon");
|
|
|
|
if ( longest->IsNotNullChunk()
|
|
&& options::indent_oc_msg_prioritize_first_colon()
|
|
&& len_diff > 0
|
|
&& ( (longest->GetColumn() >= len_diff)
|
|
&& (longest->GetColumn() - len_diff) > (longest->GetBraceLevel() * indent_size)))
|
|
{
|
|
longest->SetColumn(longest->GetColumn() - len_diff);
|
|
}
|
|
else if ( longest->IsNotNullChunk()
|
|
&& len > 0)
|
|
{
|
|
Chunk chunk;
|
|
|
|
chunk.SetType(CT_SPACE);
|
|
chunk.SetParentType(CT_NONE);
|
|
chunk.SetOrigLine(longest->GetOrigLine());
|
|
chunk.SetOrigCol(longest->GetOrigCol());
|
|
chunk.SetLevel(longest->GetLevel());
|
|
chunk.SetBraceLevel(longest->GetBraceLevel());
|
|
chunk.SetFlags(longest->GetFlags() & PCF_COPY_FLAGS);
|
|
|
|
// start at one since we already indent for the '['
|
|
for (size_t idx = 1; idx < len; idx++)
|
|
{
|
|
chunk.Str().append(' ');
|
|
}
|
|
|
|
chunk.CopyAndAddBefore(longest);
|
|
}
|
|
nas.End();
|
|
cas.End();
|
|
} // align_oc_msg_colon
|
|
|
|
|
|
void align_oc_msg_colons()
|
|
{
|
|
LOG_FUNC_ENTRY();
|
|
|
|
for (Chunk *pc = Chunk::GetHead(); pc->IsNotNullChunk(); pc = pc->GetNext())
|
|
{
|
|
if ( pc->Is(CT_SQUARE_OPEN)
|
|
&& pc->GetParentType() == CT_OC_MSG)
|
|
{
|
|
align_oc_msg_colon(pc);
|
|
}
|
|
}
|
|
} // align_oc_msg_colons
|