blob: 447d10f50172cc7a78bb97708b417a76bd7c550b [file] [log] [blame]
/**
* @file space.cpp
* Adds or removes inter-chunk spaces.
*
* @author Ben Gardner
* @license GPL v2+
*/
#include "uncrustify_types.h"
#include "chunk_list.h"
#include "prototypes.h"
#include "char_table.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <algorithm>
#include "unc_ctype.h"
static argval_t do_space(chunk_t *first, chunk_t *second, int& min_sp, bool complete);
struct no_space_table_s
{
c_token_t first;
c_token_t second;
};
/** this table lists out all combos where a space should NOT be present
* CT_UNKNOWN is a wildcard.
*
* TODO: some of these are no longer needed.
*/
struct no_space_table_s no_space_table[] =
{
{ CT_OC_AT, CT_UNKNOWN },
{ CT_INCDEC_BEFORE, CT_WORD },
{ CT_UNKNOWN, CT_INCDEC_AFTER },
{ CT_UNKNOWN, CT_LABEL_COLON },
{ CT_UNKNOWN, CT_PRIVATE_COLON },
{ CT_UNKNOWN, CT_SEMICOLON },
{ CT_UNKNOWN, CT_D_TEMPLATE },
{ CT_D_TEMPLATE, CT_UNKNOWN },
{ CT_MACRO_FUNC, CT_FPAREN_OPEN },
{ CT_PAREN_OPEN, CT_UNKNOWN },
{ CT_UNKNOWN, CT_PAREN_CLOSE },
{ CT_FPAREN_OPEN, CT_UNKNOWN },
{ CT_UNKNOWN, CT_SPAREN_CLOSE },
{ CT_SPAREN_OPEN, CT_UNKNOWN },
{ CT_UNKNOWN, CT_FPAREN_CLOSE },
{ CT_UNKNOWN, CT_COMMA },
{ CT_POS, CT_UNKNOWN },
{ CT_STAR, CT_UNKNOWN },
{ CT_VBRACE_CLOSE, CT_UNKNOWN },
{ CT_VBRACE_OPEN, CT_UNKNOWN },
{ CT_UNKNOWN, CT_VBRACE_CLOSE },
{ CT_UNKNOWN, CT_VBRACE_OPEN },
{ CT_PREPROC, CT_UNKNOWN },
{ CT_PREPROC_INDENT, CT_UNKNOWN },
{ CT_NEG, CT_UNKNOWN },
{ CT_UNKNOWN, CT_SQUARE_OPEN },
{ CT_UNKNOWN, CT_SQUARE_CLOSE },
{ CT_SQUARE_OPEN, CT_UNKNOWN },
{ CT_PAREN_CLOSE, CT_WORD },
{ CT_PAREN_CLOSE, CT_FUNC_DEF },
{ CT_PAREN_CLOSE, CT_FUNC_CALL },
{ CT_PAREN_CLOSE, CT_ADDR },
{ CT_PAREN_CLOSE, CT_FPAREN_OPEN },
{ CT_OC_SEL_NAME, CT_OC_SEL_NAME },
};
#define log_rule(rule) \
do { if (log_sev_on(LSPACE)) { \
log_rule2(__LINE__, (rule), first, second, complete); } \
} while (0)
static void log_rule2(int line, const char *rule, chunk_t *first, chunk_t *second, bool complete)
{
LOG_FUNC_ENTRY();
if (second->type != CT_NEWLINE)
{
LOG_FMT(LSPACE, "Spacing: line %d [%s/%s] '%s' <===> [%s/%s] '%s' : %s[%d]%s",
first->orig_line,
get_token_name(first->type), get_token_name(first->parent_type),
first->str.c_str(),
get_token_name(second->type), get_token_name(second->parent_type),
second->str.c_str(),
rule, line,
complete ? "\n" : "");
}
}
/**
* Decides how to change inter-chunk spacing.
* Note that the order of the if statements is VERY important.
*
* @param first The first chunk
* @param second The second chunk
* @return AV_IGNORE, AV_ADD, AV_REMOVE or AV_FORCE
*/
static argval_t do_space(chunk_t *first, chunk_t *second, int& min_sp, bool complete = true)
{
LOG_FUNC_ENTRY();
int idx;
argval_t arg;
chunk_t *next;
min_sp = 1;
if ((first->type == CT_IGNORED) || (second->type == CT_IGNORED))
{
log_rule("IGNORED");
return(AV_REMOVE);
}
if ((first->type == CT_PP) || (second->type == CT_PP))
{
log_rule("sp_pp_concat");
return(cpd.settings[UO_sp_pp_concat].a);
}
if (first->type == CT_POUND)
{
log_rule("sp_pp_stringify");
return(cpd.settings[UO_sp_pp_stringify].a);
}
if ((second->type == CT_POUND) && (second->flags & PCF_IN_PREPROC) &&
(first->parent_type != CT_MACRO_FUNC))
{
log_rule("sp_before_pp_stringify");
return(cpd.settings[UO_sp_before_pp_stringify].a);
}
if ((first->type == CT_SPACE) || (second->type == CT_SPACE))
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if ((second->type == CT_NEWLINE) ||
(second->type == CT_VBRACE_OPEN))
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if ((first->type == CT_VBRACE_OPEN) && (second->type != CT_NL_CONT))
{
log_rule("FORCE");
return(AV_FORCE);
}
if ((first->type == CT_VBRACE_CLOSE) && (second->type != CT_NL_CONT))
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if (second->type == CT_VSEMICOLON)
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if (first->type == CT_MACRO_FUNC)
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if (second->type == CT_NL_CONT)
{
log_rule("sp_before_nl_cont");
return(cpd.settings[UO_sp_before_nl_cont].a);
}
if ((first->type == CT_D_ARRAY_COLON) ||
(second->type == CT_D_ARRAY_COLON))
{
log_rule("sp_d_array_colon");
return(cpd.settings[UO_sp_d_array_colon].a);
}
if ((first->type == CT_CASE) && CharTable::IsKw1(second->str[0]))
{
log_rule("sp_case_label");
return(argval_t(cpd.settings[UO_sp_case_label].a | AV_ADD));
}
if (first->type == CT_FOR_COLON)
{
log_rule("sp_after_for_colon");
return cpd.settings[UO_sp_after_for_colon].a;
}
if (second->type == CT_FOR_COLON)
{
log_rule("sp_before_for_colon");
return cpd.settings[UO_sp_before_for_colon].a;
}
if ((first->type == CT_QUESTION) && (second->type == CT_COND_COLON))
{
if (cpd.settings[UO_sp_cond_ternary_short].a != AV_IGNORE)
{
return cpd.settings[UO_sp_cond_ternary_short].a;
}
}
if ((first->type == CT_QUESTION) || (second->type == CT_QUESTION))
{
if ((second->type == CT_QUESTION) &&
(cpd.settings[UO_sp_cond_question_before].a != AV_IGNORE))
{
log_rule("sp_cond_question_before");
return(cpd.settings[UO_sp_cond_question_before].a);
}
if ((first->type == CT_QUESTION) &&
(cpd.settings[UO_sp_cond_question_after].a != AV_IGNORE))
{
log_rule("sp_cond_question_after");
return(cpd.settings[UO_sp_cond_question_after].a);
}
if (cpd.settings[UO_sp_cond_question].a != AV_IGNORE)
{
log_rule("sp_cond_question");
return(cpd.settings[UO_sp_cond_question].a);
}
}
if ((first->type == CT_COND_COLON) || (second->type == CT_COND_COLON))
{
if ((second->type == CT_COND_COLON) &&
(cpd.settings[UO_sp_cond_colon_before].a != AV_IGNORE))
{
log_rule("sp_cond_colon_before");
return(cpd.settings[UO_sp_cond_colon_before].a);
}
if ((first->type == CT_COND_COLON) &&
(cpd.settings[UO_sp_cond_colon_after].a != AV_IGNORE))
{
log_rule("sp_cond_colon_after");
return(cpd.settings[UO_sp_cond_colon_after].a);
}
if (cpd.settings[UO_sp_cond_colon].a != AV_IGNORE)
{
log_rule("sp_cond_colon");
return(cpd.settings[UO_sp_cond_colon].a);
}
}
if ((first->type == CT_RANGE) || (second->type == CT_RANGE))
{
return(cpd.settings[UO_sp_range].a);
}
if ((first->type == CT_COLON) && (first->parent_type == CT_SQL_EXEC))
{
log_rule("REMOVE");
return(AV_REMOVE);
}
/* Macro stuff can only return IGNORE, ADD, or FORCE */
if (first->type == CT_MACRO)
{
log_rule("sp_macro");
arg = cpd.settings[UO_sp_macro].a;
return((argval_t)(arg | ((arg != AV_IGNORE) ? AV_ADD : AV_IGNORE)));
}
if ((first->type == CT_FPAREN_CLOSE) && (first->parent_type == CT_MACRO_FUNC))
{
log_rule("sp_macro_func");
arg = cpd.settings[UO_sp_macro_func].a;
return((argval_t)(arg | ((arg != AV_IGNORE) ? AV_ADD : AV_IGNORE)));
}
if (first->type == CT_PREPROC)
{
/* Remove spaces, unless we are ignoring. See indent_preproc() */
if (cpd.settings[UO_pp_space].a == AV_IGNORE)
{
log_rule("IGNORE");
return(AV_IGNORE);
}
log_rule("REMOVE");
return(AV_REMOVE);
}
if (second->type == CT_SEMICOLON)
{
if (second->parent_type == CT_FOR)
{
if ((cpd.settings[UO_sp_before_semi_for_empty].a != AV_IGNORE) &&
((first->type == CT_SPAREN_OPEN) || (first->type == CT_SEMICOLON)))
{
log_rule("sp_before_semi_for_empty");
return(cpd.settings[UO_sp_before_semi_for_empty].a);
}
if (cpd.settings[UO_sp_before_semi_for].a != AV_IGNORE)
{
log_rule("sp_before_semi_for");
return(cpd.settings[UO_sp_before_semi_for].a);
}
}
arg = cpd.settings[UO_sp_before_semi].a;
if ((first->type == CT_SPAREN_CLOSE) &&
(first->parent_type != CT_WHILE_OF_DO))
{
log_rule("sp_before_semi|sp_special_semi");
arg = (argval_t)(arg | cpd.settings[UO_sp_special_semi].a);
}
else
{
log_rule("sp_before_semi");
}
return(arg);
}
if ((second->type == CT_COMMENT) &&
((first->type == CT_PP_ELSE) || (first->type == CT_PP_ENDIF)))
{
if (cpd.settings[UO_sp_endif_cmt].a != AV_IGNORE)
{
set_chunk_type(second, CT_COMMENT_ENDIF);
log_rule("sp_endif_cmt");
return(cpd.settings[UO_sp_endif_cmt].a);
}
}
if ((cpd.settings[UO_sp_before_tr_emb_cmt].a != AV_IGNORE) &&
((second->parent_type == CT_COMMENT_END) ||
(second->parent_type == CT_COMMENT_EMBED)))
{
log_rule("sp_before_tr_emb_cmt");
min_sp = cpd.settings[UO_sp_num_before_tr_emb_cmt].n;
return(cpd.settings[UO_sp_before_tr_emb_cmt].a);
}
if (second->parent_type == CT_COMMENT_END)
{
switch (second->orig_prev_sp)
{
case 0:
log_rule("orig_prev_sp-REMOVE");
return AV_REMOVE;
case 1:
log_rule("orig_prev_sp-FORCE");
return AV_FORCE;
default:
log_rule("orig_prev_sp-ADD");
return AV_ADD;
}
}
/* "for (;;)" vs "for (;; )" and "for (a;b;c)" vs "for (a; b; c)" */
if (first->type == CT_SEMICOLON)
{
if (first->parent_type == CT_FOR)
{
if ((cpd.settings[UO_sp_after_semi_for_empty].a != AV_IGNORE) &&
(second->type == CT_SPAREN_CLOSE))
{
log_rule("sp_after_semi_for_empty");
return(cpd.settings[UO_sp_after_semi_for_empty].a);
}
if (cpd.settings[UO_sp_after_semi_for].a != AV_IGNORE)
{
log_rule("sp_after_semi_for");
return(cpd.settings[UO_sp_after_semi_for].a);
}
}
else if (!chunk_is_comment(second))
{
log_rule("sp_after_semi");
return(cpd.settings[UO_sp_after_semi].a);
}
/* Let the comment spacing rules handle this */
}
/* puts a space in the rare '+-' or '-+' */
if (((first->type == CT_NEG) || (first->type == CT_POS) || (first->type == CT_ARITH)) &&
((second->type == CT_NEG) || (second->type == CT_POS) || (second->type == CT_ARITH)))
{
log_rule("ADD");
return(AV_ADD);
}
/* "return(a);" vs "return (foo_t)a + 3;" vs "return a;" vs "return;" */
if (first->type == CT_RETURN)
{
if ((second->type == CT_PAREN_OPEN) &&
(second->parent_type == CT_RETURN))
{
log_rule("sp_return_paren");
return(cpd.settings[UO_sp_return_paren].a);
}
/* everything else requires a space */
log_rule("FORCE");
return(AV_FORCE);
}
/* "sizeof(foo_t)" vs "sizeof foo_t" */
if (first->type == CT_SIZEOF)
{
if (second->type == CT_PAREN_OPEN)
{
log_rule("sp_sizeof_paren");
return(cpd.settings[UO_sp_sizeof_paren].a);
}
log_rule("FORCE");
return(AV_FORCE);
}
/* handle '::' */
if (first->type == CT_DC_MEMBER)
{
log_rule("sp_after_dc");
return(cpd.settings[UO_sp_after_dc].a);
}
if ((second->type == CT_DC_MEMBER) &&
((first->type == CT_WORD) || (first->type == CT_TYPE) || (first->type == CT_PAREN_CLOSE) ||
CharTable::IsKw1(first->str[0])))
{
log_rule("sp_before_dc");
return(cpd.settings[UO_sp_before_dc].a);
}
/* "a,b" vs "a, b" */
if (first->type == CT_COMMA)
{
if (first->parent_type == CT_TYPE)
{
/* C# multidimensional array type: ',,' vs ', ,' or ',]' vs ', ]' */
if (second->type == CT_COMMA)
{
log_rule("sp_between_mdatype_commas");
return cpd.settings[UO_sp_between_mdatype_commas].a;
}
else
{
log_rule("sp_after_mdatype_commas");
return cpd.settings[UO_sp_after_mdatype_commas].a;
}
}
else
{
log_rule("sp_after_comma");
return(cpd.settings[UO_sp_after_comma].a);
}
}
if (second->type == CT_COMMA)
{
if ((first->type == CT_SQUARE_OPEN) &&
(first->parent_type == CT_TYPE))
{
log_rule("sp_before_mdatype_commas");
return cpd.settings[UO_sp_before_mdatype_commas].a;
}
if ((first->type == CT_PAREN_OPEN) &&
(cpd.settings[UO_sp_paren_comma].a != AV_IGNORE))
{
log_rule("sp_paren_comma");
return(cpd.settings[UO_sp_paren_comma].a);
}
log_rule("sp_before_comma");
return(cpd.settings[UO_sp_before_comma].a);
}
if (second->type == CT_ELLIPSIS)
{
/* non-punc followed by a ellipsis */
if (((first->flags & PCF_PUNCTUATOR) == 0) &&
(cpd.settings[UO_sp_before_ellipsis].a != AV_IGNORE))
{
log_rule("sp_before_ellipsis");
return(cpd.settings[UO_sp_before_ellipsis].a);
}
if (first->type == CT_TAG_COLON)
{
log_rule("FORCE");
return(AV_FORCE);
}
}
if ((first->type == CT_ELLIPSIS) && CharTable::IsKw1(second->str[0]))
{
log_rule("FORCE");
return(AV_FORCE);
}
if (first->type == CT_TAG_COLON)
{
log_rule("sp_after_tag");
return(cpd.settings[UO_sp_after_tag].a);
}
if (second->type == CT_TAG_COLON)
{
log_rule("REMOVE");
return(AV_REMOVE);
}
/* handle '~' */
if (first->type == CT_DESTRUCTOR)
{
log_rule("REMOVE");
return(AV_REMOVE);
}
/* "((" vs "( (" */
if ((chunk_is_str(first, "(", 1) && chunk_is_str(second, "(", 1)) ||
(chunk_is_str(first, ")", 1) && chunk_is_str(second, ")", 1)))
{
log_rule("sp_paren_paren");
return(cpd.settings[UO_sp_paren_paren].a);
}
if ((first->type == CT_CATCH) && (second->type == CT_SPAREN_OPEN) &&
(cpd.settings[UO_sp_catch_paren].a != AV_IGNORE))
{
log_rule("sp_catch_paren");
return(cpd.settings[UO_sp_catch_paren].a);
}
if ((first->type == CT_D_VERSION_IF) && (second->type == CT_SPAREN_OPEN) &&
(cpd.settings[UO_sp_version_paren].a != AV_IGNORE))
{
log_rule("sp_version_paren");
return(cpd.settings[UO_sp_version_paren].a);
}
if ((first->type == CT_D_SCOPE_IF) && (second->type == CT_SPAREN_OPEN) &&
(cpd.settings[UO_sp_scope_paren].a != AV_IGNORE))
{
log_rule("sp_scope_paren");
return(cpd.settings[UO_sp_scope_paren].a);
}
/* "if (" vs "if(" */
if (second->type == CT_SPAREN_OPEN)
{
log_rule("sp_before_sparen");
return(cpd.settings[UO_sp_before_sparen].a);
}
if ((first->type == CT_LAMBDA) ||
(second->type == CT_LAMBDA))
{
log_rule("sp_assign (lambda)");
return(cpd.settings[UO_sp_assign].a);
}
// Handle the special lambda case for C++11:
// [=](Something arg){.....}
if ((cpd.settings[UO_sp_cpp_lambda_assign].a != AV_IGNORE) &&
(((first->type == CT_SQUARE_OPEN) &&
(first->parent_type == CT_CPP_LAMBDA) &&
(second->type == CT_ASSIGN))
||
((first->type == CT_ASSIGN) &&
(second->type == CT_SQUARE_CLOSE) &&
(second->parent_type == CT_CPP_LAMBDA))))
{
log_rule("UO_sp_cpp_lambda_assign");
return(cpd.settings[UO_sp_cpp_lambda_assign].a);
}
// Handle the special lambda case for C++11:
// [](Something arg){.....}
if ((cpd.settings[UO_sp_cpp_lambda_paren].a != AV_IGNORE) &&
(first->type == CT_SQUARE_CLOSE) &&
(first->parent_type == CT_CPP_LAMBDA) &&
(second->type == CT_FPAREN_OPEN))
{
log_rule("UO_sp_cpp_lambda_paren");
return(cpd.settings[UO_sp_cpp_lambda_paren].a);
}
if ((first->type == CT_ENUM) && (second->type == CT_FPAREN_OPEN))
{
if (cpd.settings[UO_sp_enum_paren].a != AV_IGNORE)
{
log_rule("sp_enum_paren");
return(cpd.settings[UO_sp_enum_paren].a);
}
}
if (second->type == CT_ASSIGN)
{
if (second->flags & PCF_IN_ENUM)
{
if (cpd.settings[UO_sp_enum_before_assign].a != AV_IGNORE)
{
log_rule("sp_enum_before_assign");
return(cpd.settings[UO_sp_enum_before_assign].a);
}
log_rule("sp_enum_assign");
return(cpd.settings[UO_sp_enum_assign].a);
}
if ((cpd.settings[UO_sp_assign_default].a != AV_IGNORE) &&
(second->parent_type == CT_FUNC_PROTO))
{
log_rule("sp_assign_default");
return(cpd.settings[UO_sp_assign_default].a);
}
if (cpd.settings[UO_sp_before_assign].a != AV_IGNORE)
{
log_rule("sp_before_assign");
return(cpd.settings[UO_sp_before_assign].a);
}
log_rule("sp_assign");
return(cpd.settings[UO_sp_assign].a);
}
if (first->type == CT_ASSIGN)
{
if (first->flags & PCF_IN_ENUM)
{
if (cpd.settings[UO_sp_enum_after_assign].a != AV_IGNORE)
{
log_rule("sp_enum_after_assign");
return(cpd.settings[UO_sp_enum_after_assign].a);
}
log_rule("sp_enum_assign");
return(cpd.settings[UO_sp_enum_assign].a);
}
if ((cpd.settings[UO_sp_assign_default].a != AV_IGNORE) &&
(first->parent_type == CT_FUNC_PROTO))
{
log_rule("sp_assign_default");
return(cpd.settings[UO_sp_assign_default].a);
}
if (cpd.settings[UO_sp_after_assign].a != AV_IGNORE)
{
log_rule("sp_after_assign");
return(cpd.settings[UO_sp_after_assign].a);
}
log_rule("sp_assign");
return(cpd.settings[UO_sp_assign].a);
}
if (second->type == CT_OC_BLOCK_CARET)
{
log_rule("sp_before_oc_block_caret");
return(cpd.settings[UO_sp_before_oc_block_caret].a);
}
if (first->type == CT_OC_BLOCK_CARET)
{
log_rule("sp_after_oc_block_caret");
return(cpd.settings[UO_sp_after_oc_block_caret].a);
}
if (second->type == CT_OC_MSG_FUNC)
{
log_rule("sp_after_oc_msg_receiver");
return(cpd.settings[UO_sp_after_oc_msg_receiver].a);
}
/* "a [x]" vs "a[x]" */
if ((second->type == CT_SQUARE_OPEN) && (second->parent_type != CT_OC_MSG))
{
log_rule("sp_before_square");
return(cpd.settings[UO_sp_before_square].a);
}
/* "byte[]" vs "byte []" */
if (second->type == CT_TSQUARE)
{
log_rule("sp_before_squares");
return(cpd.settings[UO_sp_before_squares].a);
}
if ((cpd.settings[UO_sp_angle_shift].a != AV_IGNORE) &&
(first->type == CT_ANGLE_CLOSE) && (second->type == CT_ANGLE_CLOSE))
{
log_rule("sp_angle_shift");
return(cpd.settings[UO_sp_angle_shift].a);
}
/* spacing around template < > stuff */
if ((first->type == CT_ANGLE_OPEN) ||
(second->type == CT_ANGLE_CLOSE))
{
log_rule("sp_inside_angle");
return(cpd.settings[UO_sp_inside_angle].a);
}
if (second->type == CT_ANGLE_OPEN)
{
if ((first->type == CT_TEMPLATE) &&
(cpd.settings[UO_sp_template_angle].a != AV_IGNORE))
{
log_rule("sp_template_angle");
return(cpd.settings[UO_sp_template_angle].a);
}
log_rule("sp_before_angle");
return(cpd.settings[UO_sp_before_angle].a);
}
if (first->type == CT_ANGLE_CLOSE)
{
if ((second->type == CT_WORD) || CharTable::IsKw1(second->str[0]))
{
if (cpd.settings[UO_sp_angle_word].a != AV_IGNORE)
{
log_rule("sp_angle_word");
return(cpd.settings[UO_sp_angle_word].a);
}
}
if ((second->type == CT_FPAREN_OPEN) ||
(second->type == CT_PAREN_OPEN))
{
log_rule("sp_angle_paren");
return(cpd.settings[UO_sp_angle_paren].a);
}
if (second->type == CT_DC_MEMBER)
{
log_rule("sp_before_dc");
return(cpd.settings[UO_sp_before_dc].a);
}
if ((second->type != CT_BYREF) &&
(second->type != CT_PTR_TYPE))
{
log_rule("sp_after_angle");
return(cpd.settings[UO_sp_after_angle].a);
}
}
if ((first->type == CT_BYREF) &&
(cpd.settings[UO_sp_after_byref_func].a != AV_IGNORE) &&
((first->parent_type == CT_FUNC_DEF) ||
(first->parent_type == CT_FUNC_PROTO)))
{
log_rule("sp_after_byref_func");
return(cpd.settings[UO_sp_after_byref_func].a);
}
if ((first->type == CT_BYREF) && CharTable::IsKw1(second->str[0]))
{
log_rule("sp_after_byref");
return(cpd.settings[UO_sp_after_byref].a);
}
if (second->type == CT_BYREF)
{
if (cpd.settings[UO_sp_before_byref_func].a != AV_IGNORE)
{
next = chunk_get_next(second);
if ((next != NULL) &&
((next->type == CT_FUNC_DEF) ||
(next->type == CT_FUNC_PROTO)))
{
return(cpd.settings[UO_sp_before_byref_func].a);
}
}
if (cpd.settings[UO_sp_before_unnamed_byref].a != AV_IGNORE)
{
next = chunk_get_next_nc(second);
if ((next != NULL) && (next->type != CT_WORD))
{
log_rule("sp_before_unnamed_byref");
return(cpd.settings[UO_sp_before_unnamed_byref].a);
}
}
log_rule("sp_before_byref");
return(cpd.settings[UO_sp_before_byref].a);
}
if (first->type == CT_SPAREN_CLOSE)
{
if ((second->type == CT_BRACE_OPEN) &&
(cpd.settings[UO_sp_sparen_brace].a != AV_IGNORE))
{
log_rule("sp_sparen_brace");
return(cpd.settings[UO_sp_sparen_brace].a);
}
if (!chunk_is_comment(second) &&
(cpd.settings[UO_sp_after_sparen].a != AV_IGNORE))
{
log_rule("sp_after_sparen");
return(cpd.settings[UO_sp_after_sparen].a);
}
}
if ((second->type == CT_FPAREN_OPEN) &&
(first->parent_type == CT_OPERATOR) &&
(cpd.settings[UO_sp_after_operator_sym].a != AV_IGNORE))
{
log_rule("sp_after_operator_sym");
return(cpd.settings[UO_sp_after_operator_sym].a);
}
/* spaces between function and open paren */
if ((first->type == CT_FUNC_CALL) ||
(first->type == CT_FUNC_CTOR_VAR))
{
if ((cpd.settings[UO_sp_func_call_paren_empty].a != AV_IGNORE) &&
(second->type == CT_FPAREN_OPEN))
{
next = chunk_get_next_ncnl(second);
if (next && (next->type == CT_FPAREN_CLOSE))
{
log_rule("sp_func_call_paren_empty");
return(cpd.settings[UO_sp_func_call_paren_empty].a);
}
}
log_rule("sp_func_call_paren");
return(cpd.settings[UO_sp_func_call_paren].a);
}
if (first->type == CT_FUNC_CALL_USER)
{
log_rule("sp_func_call_user_paren");
return(cpd.settings[UO_sp_func_call_user_paren].a);
}
if (first->type == CT_ATTRIBUTE)
{
log_rule("sp_attribute_paren");
return(cpd.settings[UO_sp_attribute_paren].a);
}
if (first->type == CT_FUNC_DEF)
{
log_rule("sp_func_def_paren");
return(cpd.settings[UO_sp_func_def_paren].a);
}
if ((first->type == CT_CPP_CAST) || (first->type == CT_TYPE_WRAP))
{
log_rule("sp_cpp_cast_paren");
return(cpd.settings[UO_sp_cpp_cast_paren].a);
}
if ((first->type == CT_PAREN_CLOSE) &&
((second->type == CT_PAREN_OPEN) ||
(second->type == CT_FPAREN_OPEN)))
{
/* "(int)a" vs "(int) a" or "cast(int)a" vs "cast(int) a" */
if ((first->parent_type == CT_C_CAST) ||
(first->parent_type == CT_D_CAST))
{
log_rule("sp_after_cast");
return(cpd.settings[UO_sp_after_cast].a);
}
/* Must be an indirect/chained function call? */
log_rule("REMOVE");
return(AV_REMOVE); /* TODO: make this configurable? */
}
/* handle the space between parens in fcn type 'void (*f)(void)' */
if (first->type == CT_TPAREN_CLOSE)
{
log_rule("sp_after_tparen_close");
return(cpd.settings[UO_sp_after_tparen_close].a);
}
/* ")(" vs ") (" */
if ((chunk_is_str(first, ")", 1) && chunk_is_str(second, "(", 1)) ||
(chunk_is_paren_close(first) && chunk_is_paren_open(second)))
{
log_rule("sp_cparen_oparen");
return(cpd.settings[UO_sp_cparen_oparen].a);
}
if ((first->type == CT_FUNC_PROTO) ||
((second->type == CT_FPAREN_OPEN) &&
(second->parent_type == CT_FUNC_PROTO)))
{
log_rule("sp_func_proto_paren");
return(cpd.settings[UO_sp_func_proto_paren].a);
}
if ((first->type == CT_FUNC_CLASS_DEF) ||
(first->type == CT_FUNC_CLASS_PROTO))
{
log_rule("sp_func_class_paren");
return(cpd.settings[UO_sp_func_class_paren].a);
}
if ((first->type == CT_CLASS) && !(first->flags & PCF_IN_OC_MSG))
{
log_rule("FORCE");
return(AV_FORCE);
}
if ((first->type == CT_BRACE_OPEN) && (second->type == CT_BRACE_CLOSE))
{
log_rule("sp_inside_braces_empty");
return(cpd.settings[UO_sp_inside_braces_empty].a);
}
if (second->type == CT_BRACE_CLOSE)
{
if (second->parent_type == CT_ENUM)
{
log_rule("sp_inside_braces_enum");
return(cpd.settings[UO_sp_inside_braces_enum].a);
}
if ((second->parent_type == CT_STRUCT) ||
(second->parent_type == CT_UNION))
{
log_rule("sp_inside_braces_struct");
return(cpd.settings[UO_sp_inside_braces_struct].a);
}
log_rule("sp_inside_braces");
return(cpd.settings[UO_sp_inside_braces].a);
}
if (first->type == CT_D_CAST)
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if ((first->type == CT_PP_DEFINED) && (second->type == CT_PAREN_OPEN))
{
log_rule("sp_defined_paren");
return(cpd.settings[UO_sp_defined_paren].a);
}
if (first->type == CT_THROW)
{
if (second->type == CT_PAREN_OPEN)
{
log_rule("sp_throw_paren");
return(cpd.settings[UO_sp_throw_paren].a);
}
log_rule("sp_after_throw");
return(cpd.settings[UO_sp_after_throw].a);
}
if ((first->type == CT_THIS) && (second->type == CT_PAREN_OPEN))
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if ((first->type == CT_STATE) && (second->type == CT_PAREN_OPEN))
{
log_rule("ADD");
return(AV_ADD);
}
if ((first->type == CT_DELEGATE) && (second->type == CT_PAREN_OPEN))
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if ((first->type == CT_MEMBER) || (second->type == CT_MEMBER))
{
log_rule("sp_member");
return(cpd.settings[UO_sp_member].a);
}
if (first->type == CT_C99_MEMBER)
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if ((first->type == CT_SUPER) && (second->type == CT_PAREN_OPEN))
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if ((first->type == CT_FPAREN_CLOSE) && (second->type == CT_BRACE_OPEN))
{
if (second->parent_type == CT_DOUBLE_BRACE)
{
log_rule("sp_fparen_dbrace");
return(cpd.settings[UO_sp_fparen_dbrace].a);
}
log_rule("sp_fparen_brace");
return(cpd.settings[UO_sp_fparen_brace].a);
}
if ((first->type == CT_D_TEMPLATE) || (second->type == CT_D_TEMPLATE))
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if ((first->type == CT_ELSE) && (second->type == CT_BRACE_OPEN))
{
log_rule("sp_else_brace");
return(cpd.settings[UO_sp_else_brace].a);
}
if ((first->type == CT_ELSE) && (second->type == CT_ELSEIF))
{
log_rule("FORCE");
return(AV_FORCE);
}
if ((first->type == CT_CATCH) && (second->type == CT_BRACE_OPEN))
{
log_rule("sp_catch_brace");
return(cpd.settings[UO_sp_catch_brace].a);
}
if ((first->type == CT_FINALLY) && (second->type == CT_BRACE_OPEN))
{
log_rule("sp_finally_brace");
return(cpd.settings[UO_sp_finally_brace].a);
}
if ((first->type == CT_TRY) && (second->type == CT_BRACE_OPEN))
{
log_rule("sp_try_brace");
return(cpd.settings[UO_sp_try_brace].a);
}
if ((first->type == CT_GETSET) && (second->type == CT_BRACE_OPEN))
{
log_rule("sp_getset_brace");
return(cpd.settings[UO_sp_getset_brace].a);
}
if (((first->type == CT_WORD) || (first->type == CT_WORD)) &&
(second->type == CT_BRACE_OPEN))
{
if (first->parent_type == CT_NAMESPACE)
{
log_rule("sp_word_brace_ns");
return(cpd.settings[UO_sp_word_brace_ns].a);
}
if ((first->parent_type == CT_NONE) &&
(second->parent_type == CT_NONE))
{
log_rule("sp_word_brace");
return(cpd.settings[UO_sp_word_brace].a);
}
}
if ((second->type == CT_PAREN_OPEN) &&
(second->parent_type == CT_INVARIANT))
{
log_rule("sp_invariant_paren");
return(cpd.settings[UO_sp_invariant_paren].a);
}
if (first->type == CT_PAREN_CLOSE)
{
if (first->parent_type == CT_D_TEMPLATE)
{
log_rule("FORCE");
return(AV_FORCE);
}
if (first->parent_type == CT_INVARIANT)
{
log_rule("sp_after_invariant_paren");
return(cpd.settings[UO_sp_after_invariant_paren].a);
}
/* Arith after a cast comes first */
if ((second->type == CT_ARITH) || (second->type == CT_CARET))
{
log_rule("sp_arith");
return(cpd.settings[UO_sp_arith].a);
}
/* "(struct foo) {...}" vs "(struct foo){...}" */
if (second->type == CT_BRACE_OPEN)
{
log_rule("sp_paren_brace");
return(cpd.settings[UO_sp_paren_brace].a);
}
/* D-specific: "delegate(some thing) dg */
if (first->parent_type == CT_DELEGATE)
{
log_rule("ADD");
return(AV_ADD);
}
/* PAWN-specific: "state (condition) next" */
if (first->parent_type == CT_STATE)
{
log_rule("ADD");
return(AV_ADD);
}
}
/* "foo(...)" vs "foo( ... )" */
if ((first->type == CT_FPAREN_OPEN) || (second->type == CT_FPAREN_CLOSE))
{
if ((first->type == CT_FPAREN_OPEN) && (second->type == CT_FPAREN_CLOSE))
{
log_rule("sp_inside_fparens");
return(cpd.settings[UO_sp_inside_fparens].a);
}
log_rule("sp_inside_fparen");
return(cpd.settings[UO_sp_inside_fparen].a);
}
/* "foo(...)" vs "foo( ... )" */
if ((first->type == CT_TPAREN_OPEN) || (second->type == CT_TPAREN_CLOSE))
{
log_rule("sp_inside_tparen");
return(cpd.settings[UO_sp_inside_tparen].a);
}
if (first->type == CT_PAREN_CLOSE)
{
if (first->flags & PCF_OC_RTYPE) //== CT_OC_RTYPE)
{
log_rule("sp_after_oc_return_type");
return(cpd.settings[UO_sp_after_oc_return_type].a);
}
else if ((first->parent_type == CT_OC_MSG_SPEC) ||
(first->parent_type == CT_OC_MSG_DECL))
{
log_rule("sp_after_oc_type");
return(cpd.settings[UO_sp_after_oc_type].a);
}
else if ((first->parent_type == CT_OC_SEL) &&
(second->type != CT_SQUARE_CLOSE))
{
log_rule("sp_after_oc_at_sel_parens");
return(cpd.settings[UO_sp_after_oc_at_sel_parens].a);
}
}
if (cpd.settings[UO_sp_inside_oc_at_sel_parens].a != AV_IGNORE)
{
if (((first->type == CT_PAREN_OPEN) &&
((first->parent_type == CT_OC_SEL) ||
(first->parent_type == CT_OC_PROTOCOL)))
||
((second->type == CT_PAREN_CLOSE) &&
((second->parent_type == CT_OC_SEL) ||
(second->parent_type == CT_OC_PROTOCOL))))
{
log_rule("sp_inside_oc_at_sel_parens");
return(cpd.settings[UO_sp_inside_oc_at_sel_parens].a);
}
}
if ((second->type == CT_PAREN_OPEN) &&
((first->type == CT_OC_SEL) || (first->type == CT_OC_PROTOCOL)))
{
log_rule("sp_after_oc_at_sel");
return(cpd.settings[UO_sp_after_oc_at_sel].a);
}
/* C cast: "(int)" vs "( int )"
* D cast: "cast(int)" vs "cast( int )"
* CPP cast: "int(a + 3)" vs "int( a + 3 )"
*/
if (first->type == CT_PAREN_OPEN)
{
if ((first->parent_type == CT_C_CAST) ||
(first->parent_type == CT_CPP_CAST) ||
(first->parent_type == CT_D_CAST))
{
log_rule("sp_inside_paren_cast");
return(cpd.settings[UO_sp_inside_paren_cast].a);
}
log_rule("sp_inside_paren");
return(cpd.settings[UO_sp_inside_paren].a);
}
if (second->type == CT_PAREN_CLOSE)
{
if ((second->parent_type == CT_C_CAST) ||
(second->parent_type == CT_CPP_CAST) ||
(second->parent_type == CT_D_CAST))
{
log_rule("sp_inside_paren_cast");
return(cpd.settings[UO_sp_inside_paren_cast].a);
}
log_rule("sp_inside_paren");
return(cpd.settings[UO_sp_inside_paren].a);
}
/* "[3]" vs "[ 3 ]" */
if ((first->type == CT_SQUARE_OPEN) || (second->type == CT_SQUARE_CLOSE))
{
log_rule("sp_inside_square");
return(cpd.settings[UO_sp_inside_square].a);
}
if ((first->type == CT_SQUARE_CLOSE) && (second->type == CT_FPAREN_OPEN))
{
log_rule("sp_square_fparen");
return(cpd.settings[UO_sp_square_fparen].a);
}
/* "if(...)" vs "if( ... )" */
if ((second->type == CT_SPAREN_CLOSE) &&
(cpd.settings[UO_sp_inside_sparen_close].a != AV_IGNORE))
{
log_rule("sp_inside_sparen_close");
return(cpd.settings[UO_sp_inside_sparen_close].a);
}
if ((first->type == CT_SPAREN_OPEN) &&
(cpd.settings[UO_sp_inside_sparen_open].a != AV_IGNORE))
{
log_rule("sp_inside_sparen_open");
return(cpd.settings[UO_sp_inside_sparen_open].a);
}
if ((first->type == CT_SPAREN_OPEN) || (second->type == CT_SPAREN_CLOSE))
{
log_rule("sp_inside_sparen");
return(cpd.settings[UO_sp_inside_sparen].a);
}
if ((cpd.settings[UO_sp_after_class_colon].a != AV_IGNORE) &&
(first->type == CT_CLASS_COLON))
{
log_rule("sp_after_class_colon");
return(cpd.settings[UO_sp_after_class_colon].a);
}
if ((cpd.settings[UO_sp_before_class_colon].a != AV_IGNORE) &&
(second->type == CT_CLASS_COLON))
{
log_rule("sp_before_class_colon");
return(cpd.settings[UO_sp_before_class_colon].a);
}
if ((cpd.settings[UO_sp_after_constr_colon].a != AV_IGNORE) &&
(first->type == CT_CONSTR_COLON))
{
min_sp = cpd.settings[UO_indent_ctor_init_leading].n - 1; // default indent is 1 space
log_rule("sp_after_constr_colon");
return(cpd.settings[UO_sp_after_constr_colon].a);
}
if ((cpd.settings[UO_sp_before_constr_colon].a != AV_IGNORE) &&
(second->type == CT_CONSTR_COLON))
{
log_rule("sp_before_constr_colon");
return(cpd.settings[UO_sp_before_constr_colon].a);
}
if ((cpd.settings[UO_sp_before_case_colon].a != AV_IGNORE) &&
(second->type == CT_CASE_COLON))
{
log_rule("sp_before_case_colon");
return(cpd.settings[UO_sp_before_case_colon].a);
}
if (first->type == CT_DOT)
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if (second->type == CT_DOT)
{
log_rule("ADD");
return(AV_ADD);
}
if ((first->type == CT_ARITH) || (first->type == CT_CARET) ||
(second->type == CT_ARITH) || (second->type == CT_CARET))
{
log_rule("sp_arith");
return(cpd.settings[UO_sp_arith].a);
}
if ((first->type == CT_BOOL) || (second->type == CT_BOOL))
{
arg = cpd.settings[UO_sp_bool].a;
if ((cpd.settings[UO_pos_bool].tp != TP_IGNORE) &&
(first->orig_line != second->orig_line) &&
(arg != AV_REMOVE))
{
arg = (argval_t)(arg | AV_ADD);
}
log_rule("sp_bool");
return(arg);
}
if ((first->type == CT_COMPARE) || (second->type == CT_COMPARE))
{
log_rule("sp_compare");
return(cpd.settings[UO_sp_compare].a);
}
if ((first->type == CT_PAREN_OPEN) && (second->type == CT_PTR_TYPE))
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if ((first->type == CT_PTR_TYPE) &&
(cpd.settings[UO_sp_ptr_star_paren].a != AV_IGNORE) &&
((second->type == CT_FPAREN_OPEN) ||
(second->type == CT_TPAREN_OPEN)))
{
log_rule("sp_ptr_star_paren");
return cpd.settings[UO_sp_ptr_star_paren].a;
}
if ((first->type == CT_PTR_TYPE) &&
(second->type == CT_PTR_TYPE) &&
(cpd.settings[UO_sp_between_ptr_star].a != AV_IGNORE))
{
log_rule("sp_between_ptr_star");
return(cpd.settings[UO_sp_between_ptr_star].a);
}
if ((first->type == CT_PTR_TYPE) &&
(cpd.settings[UO_sp_after_ptr_star_func].a != AV_IGNORE) &&
((first->parent_type == CT_FUNC_DEF) ||
(first->parent_type == CT_FUNC_PROTO) ||
(first->parent_type == CT_FUNC_VAR)))
{
log_rule("sp_after_ptr_star_func");
return(cpd.settings[UO_sp_after_ptr_star_func].a);
}
if ((first->type == CT_PTR_TYPE) && CharTable::IsKw1(second->str[0]))
{
if ((second->type == CT_QUALIFIER) &&
(cpd.settings[UO_sp_after_ptr_star_qualifier].a != AV_IGNORE))
{
log_rule("sp_after_ptr_star_qualifier");
return(cpd.settings[UO_sp_after_ptr_star_qualifier].a);
}
else if (cpd.settings[UO_sp_after_ptr_star].a != AV_IGNORE)
{
log_rule("sp_after_ptr_star");
return(cpd.settings[UO_sp_after_ptr_star].a);
}
}
if (second->type == CT_PTR_TYPE)
{
if (cpd.settings[UO_sp_before_ptr_star_func].a != AV_IGNORE)
{
/* Find the next non-'*' chunk */
next = second;
do
{
next = chunk_get_next(next);
} while ((next != NULL) && (next->type == CT_PTR_TYPE));
if ((next != NULL) &&
((next->type == CT_FUNC_DEF) ||
(next->type == CT_FUNC_PROTO)))
{
return(cpd.settings[UO_sp_before_ptr_star_func].a);
}
}
if (cpd.settings[UO_sp_before_unnamed_ptr_star].a != AV_IGNORE)
{
next = chunk_get_next_nc(second);
while ((next != NULL) && (next->type == CT_PTR_TYPE))
{
next = chunk_get_next_nc(next);
}
if ((next != NULL) && (next->type != CT_WORD))
{
log_rule("sp_before_unnamed_ptr_star");
return(cpd.settings[UO_sp_before_unnamed_ptr_star].a);
}
}
if (cpd.settings[UO_sp_before_ptr_star].a != AV_IGNORE)
{
log_rule("sp_before_ptr_star");
return(cpd.settings[UO_sp_before_ptr_star].a);
}
}
if (first->type == CT_OPERATOR)
{
log_rule("sp_after_operator");
return(cpd.settings[UO_sp_after_operator].a);
}
if ((second->type == CT_FUNC_PROTO) || (second->type == CT_FUNC_DEF))
{
if (first->type != CT_PTR_TYPE)
{
log_rule("sp_type_func|ADD");
return((argval_t)(cpd.settings[UO_sp_type_func].a | AV_ADD));
}
log_rule("sp_type_func");
return(cpd.settings[UO_sp_type_func].a);
}
/* "(int)a" vs "(int) a" or "cast(int)a" vs "cast(int) a" */
if ((first->parent_type == CT_C_CAST) ||
(first->parent_type == CT_D_CAST))
{
log_rule("sp_after_cast");
return(cpd.settings[UO_sp_after_cast].a);
}
if (first->type == CT_BRACE_CLOSE)
{
if (second->type == CT_ELSE)
{
log_rule("sp_brace_else");
return(cpd.settings[UO_sp_brace_else].a);
}
else if (second->type == CT_CATCH)
{
log_rule("sp_brace_catch");
return(cpd.settings[UO_sp_brace_catch].a);
}
else if (second->type == CT_FINALLY)
{
log_rule("sp_brace_finally");
return(cpd.settings[UO_sp_brace_finally].a);
}
}
if (first->type == CT_BRACE_OPEN)
{
if (first->parent_type == CT_ENUM)
{
log_rule("sp_inside_braces_enum");
return(cpd.settings[UO_sp_inside_braces_enum].a);
}
else if ((first->parent_type == CT_UNION) ||
(first->parent_type == CT_STRUCT))
{
log_rule("sp_inside_braces_struct");
return(cpd.settings[UO_sp_inside_braces_struct].a);
}
else if (!chunk_is_comment(second))
{
log_rule("sp_inside_braces");
return(cpd.settings[UO_sp_inside_braces].a);
}
}
if (second->type == CT_BRACE_CLOSE)
{
if (second->parent_type == CT_ENUM)
{
log_rule("sp_inside_braces_enum");
return(cpd.settings[UO_sp_inside_braces_enum].a);
}
else if ((second->parent_type == CT_UNION) ||
(second->parent_type == CT_STRUCT))
{
log_rule("sp_inside_braces_struct");
return(cpd.settings[UO_sp_inside_braces_struct].a);
}
log_rule("sp_inside_braces");
return(cpd.settings[UO_sp_inside_braces].a);
}
if ((first->type == CT_BRACE_CLOSE) &&
(first->flags & PCF_IN_TYPEDEF) &&
((first->parent_type == CT_ENUM) ||
(first->parent_type == CT_STRUCT) ||
(first->parent_type == CT_UNION)))
{
log_rule("sp_brace_typedef");
return(cpd.settings[UO_sp_brace_typedef].a);
}
if (second->type == CT_SPAREN_OPEN)
{
log_rule("sp_before_sparen");
return(cpd.settings[UO_sp_before_sparen].a);
}
if ((second->type == CT_PAREN_OPEN) && (second->parent_type == CT_TEMPLATE))
{
log_rule("UO_sp_before_template_paren");
return(cpd.settings[UO_sp_before_template_paren].a);
}
if ((second->type != CT_PTR_TYPE) &&
((first->type == CT_QUALIFIER) || (first->type == CT_TYPE)))
{
arg = cpd.settings[UO_sp_after_type].a;
log_rule("sp_after_type");
return((arg != AV_REMOVE) ? arg : AV_FORCE);
}
if ((first->type == CT_MACRO_OPEN) ||
(first->type == CT_MACRO_CLOSE) ||
(first->type == CT_MACRO_ELSE))
{
if (second->type == CT_PAREN_OPEN)
{
log_rule("sp_func_call_paren");
return(cpd.settings[UO_sp_func_call_paren].a);
}
log_rule("IGNORE");
return(AV_IGNORE);
}
/* If nothing claimed the PTR_TYPE, then return ignore */
if ((first->type == CT_PTR_TYPE) || (second->type == CT_PTR_TYPE))
{
log_rule("IGNORE");
return(AV_IGNORE);
}
if (first->type == CT_NOT)
{
log_rule("sp_not");
return(cpd.settings[UO_sp_not].a);
}
if (first->type == CT_INV)
{
log_rule("sp_inv");
return(cpd.settings[UO_sp_inv].a);
}
if (first->type == CT_ADDR)
{
log_rule("sp_addr");
return(cpd.settings[UO_sp_addr].a);
}
if (first->type == CT_DEREF)
{
log_rule("sp_deref");
return(cpd.settings[UO_sp_deref].a);
}
if ((first->type == CT_POS) || (first->type == CT_NEG))
{
log_rule("sp_sign");
return(cpd.settings[UO_sp_sign].a);
}
if ((first->type == CT_INCDEC_BEFORE) || (second->type == CT_INCDEC_AFTER))
{
log_rule("sp_incdec");
return(cpd.settings[UO_sp_incdec].a);
}
if (second->type == CT_CS_SQ_COLON)
{
log_rule("REMOVE");
return(AV_REMOVE);
}
if (first->type == CT_CS_SQ_COLON)
{
log_rule("FORCE");
return(AV_FORCE);
}
if (first->type == CT_OC_SCOPE)
{
log_rule("sp_after_oc_scope");
return(cpd.settings[UO_sp_after_oc_scope].a);
}
if (first->type == CT_OC_DICT_COLON)
{
log_rule("sp_after_oc_dict_colon");
return(cpd.settings[UO_sp_after_oc_dict_colon].a);
}
if (second->type == CT_OC_DICT_COLON)
{
log_rule("sp_before_oc_dict_colon");
return(cpd.settings[UO_sp_before_oc_dict_colon].a);
}
if (first->type == CT_OC_COLON)
{
if (first->flags & PCF_IN_OC_MSG)
{
log_rule("sp_after_send_oc_colon");
return(cpd.settings[UO_sp_after_send_oc_colon].a);
}
else
{
log_rule("sp_after_oc_colon");
return(cpd.settings[UO_sp_after_oc_colon].a);
}
}
if (second->type == CT_OC_COLON)
{
if ((first->flags & PCF_IN_OC_MSG) &&
((first->type == CT_OC_MSG_FUNC) ||
(first->type == CT_OC_MSG_NAME)))
{
log_rule("sp_before_send_oc_colon");
return(cpd.settings[UO_sp_before_send_oc_colon].a);
}
else
{
log_rule("sp_before_oc_colon");
return(cpd.settings[UO_sp_before_oc_colon].a);
}
}
if ((second->type == CT_COMMENT) && (second->parent_type == CT_COMMENT_EMBED))
{
log_rule("FORCE");
return(AV_FORCE);
}
if (chunk_is_comment(second))
{
log_rule("IGNORE");
return(AV_IGNORE);
}
if (first->type == CT_COMMENT)
{
log_rule("FORCE");
return(AV_FORCE);
}
if ((first->type == CT_NEW) ||
(first->type == CT_DELETE) ||
((first->type == CT_TSQUARE) && (first->parent_type == CT_DELETE)))
{
log_rule("sp_after_new");
return(cpd.settings[UO_sp_after_new].a);
}
if ((first->type == CT_ANNOTATION) && chunk_is_paren_open(second))
{
log_rule("sp_annotation_paren");
return(cpd.settings[UO_sp_annotation_paren].a);
}
if (first->type == CT_OC_PROPERTY)
{
log_rule("sp_after_oc_property");
return(cpd.settings[UO_sp_after_oc_property].a);
}
if ((first->type == CT_EXTERN) && (second->type == CT_PAREN_OPEN))
{
log_rule("sp_extern_paren");
return cpd.settings[UO_sp_extern_paren].a;
}
for (idx = 0; idx < (int)ARRAY_SIZE(no_space_table); idx++)
{
if (((no_space_table[idx].first == CT_UNKNOWN) ||
(no_space_table[idx].first == first->type))
&&
((no_space_table[idx].second == CT_UNKNOWN) ||
(no_space_table[idx].second == second->type)))
{
log_rule("REMOVE");
return(AV_REMOVE);
}
}
log_rule("ADD");
return(AV_ADD);
}
/**
* Marches through the whole file and checks to see how many spaces should be
* between two chunks
*/
void space_text(void)
{
LOG_FUNC_ENTRY();
chunk_t *pc;
chunk_t *next;
chunk_t *tmp;
int column, prev_column;
int delta;
pc = chunk_get_head();
if (pc == NULL)
{
return;
}
column = pc->column;
while (pc != NULL)
{
next = chunk_get_next(pc);
while (chunk_is_blank(next) && !chunk_is_newline(next))
{
LOG_FMT(LSPACE, "%s: %d:%d Skip %s (%d+%d)\n", __func__,
next->orig_line, next->orig_col, get_token_name(next->type),
pc->column, pc->str.size());
next->column = pc->column + pc->str.size();
next = chunk_get_next(next);
}
if (!next)
{
break;
}
/* If the current chunk contains a newline, do not change the column
* of the next item */
if ((pc->type == CT_NEWLINE) ||
(pc->type == CT_NL_CONT) ||
(pc->type == CT_COMMENT_MULTI))
{
column = next->column;
}
else
{
/* Set to the minimum allowed column */
if (pc->nl_count == 0)
{
column += pc->len();
}
else
{
column = pc->orig_col_end;
}
prev_column = column;
/**
* Apply a general safety check
* If the two chunks combined will tokenize differently, then we
* must force a space.
* Two chunks -- "()" and "[]" will always tokenize differently.
* They are always safe to not have a space after them.
*/
pc->flags &= ~PCF_FORCE_SPACE;
if ((pc->len() > 0) &&
!chunk_is_str(pc, "[]", 2) &&
!chunk_is_str(pc, "{{", 2) &&
!chunk_is_str(pc, "}}", 2) &&
!chunk_is_str(pc, "()", 2) &&
!pc->str.startswith("@\""))
{
/* Find the next non-empty chunk on this line */
tmp = next;
while ((tmp != NULL) && (tmp->len() == 0) && !chunk_is_newline(tmp))
{
tmp = chunk_get_next(tmp);
}
if ((tmp != NULL) && (tmp->len() > 0))
{
bool kw1 = CharTable::IsKw2(pc->str[pc->len() - 1]);
bool kw2 = CharTable::IsKw1(next->str[0]);
if (kw1 && kw2)
{
/* back-to-back words need a space */
pc->flags |= PCF_FORCE_SPACE;
}
else if (!kw1 && !kw2 && (pc->len() < 4) && (next->len() < 4))
{
/* We aren't dealing with keywords. concat and try punctuators */
char buf[9];
memcpy(buf, pc->text(), pc->len());
memcpy(buf + pc->len(), next->text(), next->len());
buf[pc->len() + next->len()] = 0;
const chunk_tag_t *ct;
ct = find_punctuator(buf, cpd.lang_flags);
if ((ct != NULL) && ((int)strlen(ct->tag) != pc->len()))
{
/* punctuator parsed to a different size.. */
/* C++11 allows '>>' to mean '> >' in templates:
* some_func<vector<string>>();
*/
if ((((cpd.lang_flags & LANG_CPP) && cpd.settings[UO_sp_permit_cpp11_shift].b) ||
((cpd.lang_flags & LANG_JAVA) || (cpd.lang_flags & LANG_CS))) &&
(pc->type == CT_ANGLE_CLOSE) &&
(next->type == CT_ANGLE_CLOSE))
{
/* allow '>' and '>' to become '>>' */
}
else if (strcmp(ct->tag, "[]") == 0)
{
/* this is OK */
}
else
{
pc->flags |= PCF_FORCE_SPACE;
}
}
}
}
}
int min_sp;
int av = do_space(pc, next, min_sp, false);
if (pc->flags & PCF_FORCE_SPACE)
{
LOG_FMT(LSPACE, " <force between '%s' and '%s'>",
pc->str.c_str(), next->str.c_str());
av |= AV_ADD;
}
min_sp = max(1, min_sp);
switch (av)
{
case AV_FORCE:
/* add exactly the specified # of spaces */
column += min_sp;
break;
case AV_ADD:
delta = min_sp;
if ((next->orig_col >= pc->orig_col_end) && (pc->orig_col_end != 0))
{
/* Keep the same relative spacing, minimum 1 */
delta = next->orig_col - pc->orig_col_end;
if (delta < min_sp)
{
delta = min_sp;
}
}
column += delta;
break;
case AV_REMOVE:
/* the symbols will be back-to-back "a+3" */
break;
default:
/* Keep the same relative spacing, if possible */
if ((next->orig_col >= pc->orig_col_end) && (pc->orig_col_end != 0))
{
column += next->orig_col - pc->orig_col_end;
}
break;
}
if (chunk_is_comment(next) &&
chunk_is_newline(chunk_get_next(next)) &&
(column < (int)next->orig_col))
{
/* do some comment adjustments if sp_before_tr_emb_cmt and
* sp_endif_cmt did not apply.
*/
if (((cpd.settings[UO_sp_before_tr_emb_cmt].a == AV_IGNORE) ||
((next->parent_type != CT_COMMENT_END) &&
(next->parent_type != CT_COMMENT_EMBED)))
&&
((cpd.settings[UO_sp_endif_cmt].a == AV_IGNORE) ||
((pc->type != CT_PP_ELSE) && (pc->type != CT_PP_ENDIF))))
{
if (cpd.settings[UO_indent_relative_single_line_comments].b)
{
/* Try to keep relative spacing between tokens */
LOG_FMT(LSPACE, " <relative adj>");
column = pc->column + 1 + (next->orig_col - pc->orig_col_end);
}
else
{
/* If there was a space, we need to force one, otherwise
* try to keep the comment in the same column. */
int col_min = pc->column + pc->len() + ((next->orig_prev_sp > 0) ? 1 : 0);
column = next->orig_col;
if (column < col_min)
{
column = col_min;
}
LOG_FMT(LSPACE, " <relative set>");
}
}
}
next->column = column;
LOG_FMT(LSPACE, " = %s @ %d => %d\n",
(av == AV_IGNORE) ? "IGNORE" :
(av == AV_ADD) ? "ADD" :
(av == AV_REMOVE) ? "REMOVE" : "FORCE",
column - prev_column, next->column);
}
pc = next;
}
}
/**
* Marches through the whole file and adds spaces around nested parens
*/
void space_text_balance_nested_parens(void)
{
LOG_FUNC_ENTRY();
chunk_t *first;
chunk_t *next;
chunk_t *cur;
chunk_t *prev;
first = chunk_get_head();
while (first != NULL)
{
next = chunk_get_next(first);
if (next == NULL)
{
break;
}
if (chunk_is_str(first, "(", 1) && chunk_is_str(next, "(", 1))
{
/* insert a space between the two opening parens */
space_add_after(first, 1);
/* find the closing paren that matches the 'first' open paren and force
* a space before it */
cur = next;
prev = cur;
while ((cur = chunk_get_next(cur)) != NULL)
{
if (cur->level == first->level)
{
space_add_after(prev, 1);
break;
}
prev = cur;
}
}
else if (chunk_is_str(first, ")", 1) && chunk_is_str(next, ")", 1))
{
/* insert a space between the two closing parens */
space_add_after(first, 1);
/* find the opening paren that matches the 'next' close paren and force
* a space after it */
cur = first;
while ((cur = chunk_get_prev(cur)) != NULL)
{
if (cur->level == next->level)
{
space_add_after(cur, 1);
break;
}
}
}
first = next;
}
}
/**
* Determines if a space is required between two chunks
*/
int space_needed(chunk_t *first, chunk_t *second)
{
LOG_FUNC_ENTRY();
int min_sp;
LOG_FMT(LSPACE, "%s\n", __func__);
switch (do_space(first, second, min_sp))
{
case AV_ADD:
case AV_FORCE:
return(max(1, min_sp));
case AV_REMOVE:
return(0);
case AV_IGNORE:
default:
return(second->orig_col > (first->orig_col + first->len()));
}
}
/**
* Calculates the column difference between two chunks.
* The rules are bent a bit here, as AV_IGNORE and AV_ADD become AV_FORCE.
* So the column difference is either first->len or first->len + 1.
*
* @param first The first chunk
* @param second The second chunk
* @return the column difference between the two chunks
*/
int space_col_align(chunk_t *first, chunk_t *second)
{
LOG_FUNC_ENTRY();
int coldiff, min_sp;
argval_t av;
LOG_FMT(LSPACE, "%s: %d:%d [%s/%s] '%s' <==> %d:%d [%s/%s] '%s'", __func__,
first->orig_line, first->orig_col,
get_token_name(first->type), get_token_name(first->parent_type),
first->text(),
second->orig_line, second->orig_col,
get_token_name(second->type), get_token_name(second->parent_type),
second->text());
log_func_stack_inline(LSPACE);
av = do_space(first, second, min_sp);
LOG_FMT(LSPACE, "%s: av=%d, ", __func__, av);
if (first->nl_count)
{
LOG_FMT(LSPACE, "nl_count=%d, orig_col_end=%d", first->nl_count, first->orig_col_end);
coldiff = first->orig_col_end - 1;
}
else
{
LOG_FMT(LSPACE, "len=%d", first->len());
coldiff = first->len();
}
switch (av)
{
case AV_ADD:
case AV_FORCE:
coldiff++;
break;
case AV_REMOVE:
break;
case AV_IGNORE:
if (second->orig_col > (first->orig_col + first->len()))
{
coldiff++;
}
break;
}
LOG_FMT(LSPACE, " => %d\n", coldiff);
return(coldiff);
}
void space_add_after(chunk_t *pc, int count)
{
LOG_FUNC_ENTRY();
if (count <= 0)
{
return;
}
chunk_t *next = chunk_get_next(pc);
/* don't add at the end of the file or before a newline */
if ((next == NULL) || chunk_is_newline(next))
{
return;
}
/* Limit to 16 spaces */
if (count > 16)
{
count = 16;
}
/* Two CT_SPACE in a row -- use the max of the two */
if (next->type == CT_SPACE)
{
if (next->len() < count)
{
while (next->len() < count)
{
next->str.append(' ');
}
}
return;
}
chunk_t sp;
sp.flags = pc->flags & PCF_COPY_FLAGS;
sp.type = CT_SPACE;
sp.str = " "; // 16 spaces
sp.str.resize(count);
sp.level = pc->level;
sp.brace_level = pc->brace_level;
sp.pp_level = pc->pp_level;
sp.column = pc->column + pc->len();
sp.orig_line = pc->orig_line;
chunk_add_after(&sp, pc);
}