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.

257 lines
8.8 KiB

/**
* @file parsing_frame.cpp
*
* Holds data needed for indenting and brace parsing
*
* @author Daniel Chumak
* @license GPL v2+
*/
#include "parsing_frame.h"
#include "chunk.h"
#include "options.h"
#include "uncrustify.h"
#include <stdexcept> // to get std::logic_error
using std::string;
using std::to_string;
using std::invalid_argument;
ParenStackEntry::ParenStackEntry()
{
m_openToken = CT_EOF;
m_openChunk = Chunk::NullChunkPtr;
m_openLevel = 0;
m_openLine = 0;
m_openCol = 0;
m_braceIndent = 0;
m_indent = 1;
m_indentTmp = 1;
m_indentTab = 1;
m_nsCount = 0;
m_indentContinue = false;
m_inPreproc = false;
m_nonVardef = false;
m_parent = CT_NONE;
m_stage = E_BraceStage::NONE;
m_indentationData = { Chunk::NullChunkPtr, 0 };
m_popChunk = Chunk::NullChunkPtr;
}
ParsingFrame::ParsingFrame()
{
//! amount of elements for which memory is going to be pre-initialized
static constexpr int CONTAINER_INIT_SIZE = 16;
m_parenStack = std::vector<ParenStackEntry>();
m_parenStack.reserve(CONTAINER_INIT_SIZE);
m_parenStack.push_back(ParenStackEntry());
m_lastPopped = ParenStackEntry();
m_refNumber = 0;
m_parenLevel = 0;
m_braceLevel = 0;
m_ppLevel = 0;
m_sParenCount = 0;
m_parenCount = 0;
m_ifdefType = E_Token::CT_NONE;
m_stmtCount = 0;
m_exprCount = 0;
}
ParenStackEntry &ParsingFrame::prev(size_t idx)
{
LOG_FUNC_ENTRY();
if (idx == 0)
{
throw invalid_argument(string(__FILE__) + ":" + to_string(__LINE__)
+ " idx can't be zero");
}
if (idx >= m_parenStack.size())
{
LOG_FMT(LINDPSE, "%s(%d): idx is %zu, size is %zu\n",
__func__, __LINE__, idx, m_parenStack.size());
throw invalid_argument(string(__FILE__) + ":" + to_string(__LINE__)
+ " idx can't be >= size()");
}
return(*std::prev(std::end(m_parenStack), idx + 1));
}
const ParenStackEntry &ParsingFrame::prev(size_t idx) const
{
LOG_FUNC_ENTRY();
// Reuse the code from non-const method
return((const_cast<ParsingFrame *>(this))->prev(idx));
}
ParenStackEntry &ParsingFrame::top()
{
// always at least one (dummy) element inside m_parenStack guaranteed
return(*std::prev(std::end(m_parenStack)));
}
const ParenStackEntry &ParsingFrame::top() const
{
// always at least one (dummy) element inside m_parenStack guaranteed
return(*std::prev(std::end(m_parenStack)));
}
void ParsingFrame::push(Chunk *pc, const char *func, int line, E_BraceStage stage)
{
LOG_FUNC_ENTRY();
ParenStackEntry new_entry;
if (pc->IsNotNullChunk())
{
new_entry.SetOpenToken(pc->GetType());
new_entry.SetOpenLevel(pc->GetLevel());
new_entry.SetOpenLine(pc->GetOrigLine());
new_entry.SetOpenCol(pc->GetOrigCol());
new_entry.SetOpenChunk(pc);
new_entry.SetIndentTab(top().GetIndentTab());
new_entry.SetIndentContinue(top().GetIndentContinue());
new_entry.SetStage(stage);
new_entry.SetInPreproc(pc->TestFlags(PCF_IN_PREPROC));
new_entry.SetNonVardef(false);
new_entry.IndentData() = top().GetIndentData();
new_entry.SetPopChunk(Chunk::NullChunkPtr);
}
m_parenStack.push_back(new_entry);
// uncomment the line below to get the address of the m_parenStack
// #define DEBUG_PUSH_POP
#ifdef DEBUG_PUSH_POP
LOG_FMT(LINDPSE, "ParsingFrame::push(%s:%d) Add is %4zu: orig line is %4zu, orig col is %4zu, type is %12s, "
"brace level is %2zu, level is %2zu, pse_tos: %2zu -> %2zu\n",
func, line, (size_t)this, pc->GetOrigLine(), pc->GetOrigCol(),
get_token_name(pc->GetType()), pc->GetBraceLevel(), pc->GetLevel(),
(m_parenStack.size() - 2), (m_parenStack.size() - 1));
#else /* DEBUG_PUSH_POP */
LOG_FMT(LINDPSE, "ParsingFrame::push(%s:%d): orig line is %4zu, orig col is %4zu, type is %12s, "
"brace level is %2zu, level is %2zu, pse_tos: %2zu -> %2zu\n",
func, line, pc->GetOrigLine(), pc->GetOrigCol(),
get_token_name(pc->GetType()), pc->GetBraceLevel(), pc->GetLevel(),
(m_parenStack.size() - 2), (m_parenStack.size() - 1));
#endif /* DEBUG_PUSH_POP */
}
void ParsingFrame::pop(const char *func, int line, Chunk *pc)
{
LOG_FUNC_ENTRY();
if ( pc->GetType() == CT_ACCESS
|| pc->GetType() == CT_ANGLE_CLOSE
|| pc->GetType() == CT_ANGLE_OPEN
|| pc->GetType() == CT_ARITH // Issue #3965
|| pc->GetType() == CT_ASSIGN
|| pc->GetType() == CT_ASSIGN_FUNC_PROTO // Issue #4026
|| pc->GetType() == CT_BRACE_CLOSE
|| pc->GetType() == CT_BRACE_OPEN
|| pc->GetType() == CT_BOOL
|| pc->GetType() == CT_CASE
|| pc->GetType() == CT_CLASS_COLON
|| pc->GetType() == CT_COMMA
|| pc->GetType() == CT_COMMENT
|| pc->GetType() == CT_COMMENT_CPP
|| pc->GetType() == CT_COMMENT_MULTI
|| pc->GetType() == CT_COMPARE // Issue #3915
|| pc->GetType() == CT_COND_COLON
|| pc->GetType() == CT_DC_MEMBER // Issue #4026
|| pc->GetType() == CT_FPAREN_CLOSE
|| pc->GetType() == CT_FPAREN_OPEN
|| pc->GetType() == CT_FUNC_CTOR_VAR // Issue #4026
|| pc->GetType() == CT_INCDEC_AFTER // Issue #4026
|| pc->GetType() == CT_LPAREN_CLOSE
|| pc->GetType() == CT_LPAREN_OPEN
|| pc->GetType() == CT_MACRO_CLOSE
|| pc->GetType() == CT_MACRO_FUNC_CALL // Issue #4026
|| pc->GetType() == CT_MACRO_OPEN
|| pc->GetType() == CT_MEMBER // Issue #3996
|| pc->GetType() == CT_NEWLINE
|| pc->GetType() == CT_NONE
|| pc->GetType() == CT_OC_END
|| pc->GetType() == CT_OC_MSG_NAME
|| pc->GetType() == CT_OC_PROPERTY
|| pc->GetType() == CT_OC_SCOPE
|| pc->GetType() == CT_OPERATOR // Issue #4026
|| pc->GetType() == CT_PARAMETER_PACK // Issue #4075
|| pc->GetType() == CT_PAREN_CLOSE
|| pc->GetType() == CT_PAREN_OPEN
|| pc->GetType() == CT_PREPROC
|| pc->GetType() == CT_QUESTION // Issue #4023
|| pc->GetType() == CT_RPAREN_CLOSE // Issue #3914
|| pc->GetType() == CT_RPAREN_OPEN
|| pc->GetType() == CT_SBOOL // Issue #3965
|| pc->GetType() == CT_SEMICOLON
|| pc->GetType() == CT_SHIFT // Issue #3983
|| pc->GetType() == CT_SPAREN_CLOSE
|| pc->GetType() == CT_SPAREN_OPEN
|| pc->GetType() == CT_SQL_END
|| pc->GetType() == CT_SQUARE_CLOSE
|| pc->GetType() == CT_SQUARE_OPEN
|| pc->GetType() == CT_TPAREN_CLOSE
|| pc->GetType() == CT_TPAREN_OPEN
|| pc->GetType() == CT_TYPEDEF
|| pc->GetType() == CT_VBRACE_CLOSE
|| pc->GetType() == CT_VBRACE_OPEN
|| pc->GetType() == CT_VSEMICOLON
|| pc->GetType() == CT_WORD)
{
LOG_FMT(LINDPSE, "ParsingFrame::pop (%s:%d): orig line is %4zu, orig col is %4zu, type is %12s\n",
func, line, pc->GetOrigLine(), pc->GetOrigCol(), get_token_name(pc->GetType()));
}
else
{
fprintf(stderr, "ParsingFrame::pop (%s:%d): orig line is %4zu, orig col is %4zu, type is %12s,\n",
func, line, pc->GetOrigLine(), pc->GetOrigCol(), get_token_name(pc->GetType()));
fprintf(stderr, "ParsingFrame::pop (%s:%d): the type is %s, is not coded. Please make a call.\n",
func, line, get_token_name(pc->GetType()));
log_flush(true);
if (uncrustify::options::debug_use_the_exit_function_pop()) // Issue #4075
{
exit(EX_SOFTWARE);
}
}
#ifdef DEBUG_PUSH_POP
LOG_FMT(LINDPSE, "ParsingFrame::pop (%s:%d) Add is %4zu: open_line is %4zu, clos_col is %4zu, type is %12s, "
"cpd.level is %2d, level is %2zu, pse_tos: %2zu -> %2zu\n",
func, line, (size_t)this, m_parenStack.back().open_line, m_parenStack.back().open_colu,
get_token_name(m_parenStack.back().type), cpd.pp_level, m_parenStack.back().level,
(m_parenStack.size() - 1), (m_parenStack.size() - 2));
#else /* DEBUG_PUSH_POP */
LOG_FMT(LINDPSE, "ParsingFrame::pop (%s:%d): open_line is %4zu, clos_col is %4zu, type is %12s, "
"cpd.level is %2d, level is %2zu, pse_tos: %2zu -> %2zu\n",
func, line, m_parenStack.back().GetOpenLine(), m_parenStack.back().GetOpenCol(),
get_token_name(m_parenStack.back().GetOpenToken()), cpd.pp_level, m_parenStack.back().GetOpenLevel(),
(m_parenStack.size() - 1), (m_parenStack.size() - 2));
#endif /* DEBUG_PUSH_POP */
m_lastPopped = *std::prev(std::end(m_parenStack));
if (m_parenStack.size() == 1)
{
*std::begin(m_parenStack) = ParenStackEntry();
}
else
{
m_parenStack.pop_back();
}
} // ParsingFrame::pop