static bool should_add_braces(chunk_t *vbopen) { LOG_FUNC_ENTRY(); size_t nl_max = cpd.settings[UO_mod_full_brace_nl].u; if (nl_max == 0) { return(false); } LOG_FMT(LBRDEL, "%s: start on %zu : ", __func__, vbopen->orig_line); chunk_t *pc; size_t nl_count = 0; for (pc = chunk_get_next_nc(vbopen, CNAV_PREPROC); (pc != NULL) && (pc->level > vbopen->level); pc = chunk_get_next_nc(pc, CNAV_PREPROC)) { if (chunk_is_newline(pc)) { nl_count += pc->nl_count; } } if ((pc != NULL) && (nl_count > nl_max) && (vbopen->pp_level == pc->pp_level)) { LOG_FMT(LBRDEL, " exceeded %zu newlines\n", nl_max); return(true); } return(false); }
/** * We are on a level 0 function proto of def */ static chunk_t *pawn_mark_function0(chunk_t *start, chunk_t *fcn) { chunk_t *last; /* handle prototypes */ if (start == fcn) { last = chunk_get_next_type(fcn, CT_PAREN_CLOSE, fcn->level); last = chunk_get_next(last); if ((last != NULL) && (last->type == CT_SEMICOLON)) { LOG_FMT(LPFUNC, "%s: %d] '%s' proto due to semicolon\n", __func__, fcn->orig_line, fcn->str.c_str()); fcn->type = CT_FUNC_PROTO; return(last); } } else { if ((start->type == CT_FORWARD) || (start->type == CT_NATIVE)) { LOG_FMT(LPFUNC, "%s: %d] '%s' [%s] proto due to %s\n", __func__, fcn->orig_line, fcn->str.c_str(), get_token_name(fcn->type), get_token_name(start->type)); fcn->type = CT_FUNC_PROTO; return(chunk_get_next_nc(fcn)); } } /* Not a prototype, so it must be a function def */ return(pawn_process_func_def(fcn)); }
chunk_t *pawn_add_vsemi_after(chunk_t *pc) { if ((pc->type == CT_VSEMICOLON) || (pc->type == CT_SEMICOLON)) { return(pc); } chunk_t *next = chunk_get_next_nc(pc); if ((next != NULL) && ((next->type == CT_VSEMICOLON) || (next->type == CT_SEMICOLON))) { return(pc); } chunk_t chunk; chunk = *pc; chunk.type = CT_VSEMICOLON; chunk.str = cpd.settings[UO_mod_pawn_semicolon].b ? ";" : ""; chunk.column += pc->len(); chunk.parent_type = CT_NONE; LOG_FMT(LPVSEMI, "%s: Added VSEMI on line %d, prev='%s' [%s]\n", __func__, pc->orig_line, pc->str.c_str(), get_token_name(pc->type)); return(chunk_add_after(&chunk, pc)); }
/** * Does a scan of level 0 BEFORE stuff in combine.cpp is called. * At this point, VSemis have been added only in VBraces. * Otherwise, all level info is correct, except for unbraced functions. * * We are looking for unbraced functions. */ void pawn_prescan(void) { /* Start at the beginning and step through the entire file, and clean up * any questionable stuff */ chunk_t *pc; bool did_nl = true; pc = chunk_get_head(); while (pc != NULL) { if (did_nl && (pc->type != CT_PREPROC) && !chunk_is_newline(pc) && (pc->level == 0)) { /* pc now points to the start of a line */ pc = pawn_process_line(pc); } /* note that continued lines are ignored */ if (pc != NULL) { did_nl = (pc->type == CT_NEWLINE); } pc = chunk_get_next_nc(pc); } }
/** * Functions prototypes and definitions can only appear in level 0. * * Function prototypes start with "native", "forward", or are just a function * with a trailing semicolon instead of a open brace (or something else) * * somefunc(params) <-- def * stock somefunc(params) <-- def * somefunc(params); <-- proto * forward somefunc(params) <-- proto * native somefunc[rect](params) <-- proto * * Functions start with 'stock', 'static', 'public', or '@' (on level 0) * * Variable definitions start with 'stock', 'static', 'new', or 'public'. */ static chunk_t *pawn_process_line(chunk_t *start) { LOG_FUNC_ENTRY(); chunk_t *pc; chunk_t *fcn = NULL; //LOG_FMT(LSYS, "%s: %d - %s\n", __func__, // start->orig_line, start->text()); if ((start->type == CT_NEW) || chunk_is_str(start, "const", 5)) { return(pawn_process_variable(start)); } /* if a open paren is found before an assign, then this is a function */ if (start->type == CT_WORD) { fcn = start; } pc = start; while (((pc = chunk_get_next_nc(pc)) != NULL) && !chunk_is_str(pc, "(", 1) && (pc->type != CT_ASSIGN) && (pc->type != CT_NEWLINE)) { if ((pc->level == 0) && ((pc->type == CT_FUNCTION) || (pc->type == CT_WORD) || (pc->type == CT_OPERATOR_VAL))) { fcn = pc; } } if (pc != NULL) { if (pc->type == CT_ASSIGN) { return(pawn_process_variable(pc)); } } if (fcn != NULL) { //LOG_FMT(LSYS, "FUNCTION: %s\n", fcn->text()); return(pawn_mark_function0(start, fcn)); } if (start->type == CT_ENUM) { pc = chunk_get_next_type(start, CT_BRACE_CLOSE, start->level); return(pc); } //LOG_FMT(LSYS, "%s: Don't understand line %d, starting with '%s' [%s]\n", // __func__, start->orig_line, start->text(), get_token_name(start->type)); return(start); } // pawn_process_line
/** * follows a variable definition at level 0 until the end. * Adds a semicolon at the end, if needed. */ static chunk_t *pawn_process_variable(chunk_t *start) { chunk_t *prev = NULL; chunk_t *pc = start; while ((pc = chunk_get_next_nc(pc)) != NULL) { if ((pc->type == CT_NEWLINE) && !pawn_continued(prev, start->level)) { if ((prev->type != CT_VSEMICOLON) && (prev->type != CT_SEMICOLON)) { pawn_add_vsemi_after(prev); } break; } prev = pc; } return(pc); }
/** * 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 */ argval_t do_space(chunk_t *first, chunk_t *second, bool complete = true) { int idx; argval_t arg; chunk_t *next; 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 ((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("ADD"); return(AV_ADD); } 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_QUESTION) || (second->type == CT_QUESTION)) { if (cpd.settings[UO_sp_cond_question].a != AV_IGNORE) { return(cpd.settings[UO_sp_cond_question].a); } } if ((first->type == CT_COND_COLON) || (second->type == CT_COND_COLON)) { if (cpd.settings[UO_sp_cond_colon].a != AV_IGNORE) { 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; log_rule("sp_before_semi"); if ((first->type == CT_SPAREN_CLOSE) && (first->parent_type != CT_WHILE_OF_DO)) { log_rule("sp_special_semi"); arg = (argval_t)(arg | cpd.settings[UO_sp_special_semi].a); } return(arg); } /* "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 */ } 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))) { log_rule("sp_before_dc"); return(cpd.settings[UO_sp_before_dc].a); } /* "a,b" vs "a, b" */ if (first->type == CT_COMMA) { log_rule("sp_after_comma"); return(cpd.settings[UO_sp_after_comma].a); } if (second->type == CT_COMMA) { 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 (" 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); } 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_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_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_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); } /* "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); } /* 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)) { 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) { 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? */ } 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) { log_rule("sp_func_class_paren"); return(cpd.settings[UO_sp_func_class_paren].a); } if ((first->type == CT_CLASS) && (first->parent_type != CT_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) && (second->type == CT_PAREN_OPEN)) { log_rule("sp_throw_paren"); return(cpd.settings[UO_sp_throw_paren].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)) { 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 ((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) { log_rule("sp_arith"); return(cpd.settings[UO_sp_arith].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); } /* "(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); } if (first->type == CT_PAREN_CLOSE) { if (first->parent_type == 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); } } if ((first->type == CT_OC_SEL) && (second->type == CT_PAREN_OPEN)) { 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) || (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_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) || (second->type == CT_ARITH)) { 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) && (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))) { log_rule("sp_after_ptr_star_func"); return(cpd.settings[UO_sp_after_ptr_star_func].a); } if ((first->type == CT_PTR_TYPE) && (cpd.settings[UO_sp_after_ptr_star].a != AV_IGNORE) && CharTable::IsKw1(second->str[0])) { 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); } 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_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_COLON) { if (first->parent_type == CT_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->parent_type == CT_OC_MSG) { 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 ((second->type == CT_COMMENT) && ((first->type == CT_PP_ELSE) || (first->type == CT_PP_ENDIF))) { if (cpd.settings[UO_sp_endif_cmt].a != AV_IGNORE) { second->type = CT_COMMENT_ENDIF; log_rule("sp_endif_cmt"); return(cpd.settings[UO_sp_endif_cmt].a); } } if (chunk_is_comment(second)) { log_rule("IGNORE"); return(AV_IGNORE); } if (first->type == CT_COMMENT) { log_rule("FORCE"); return(AV_FORCE); } 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); }
/** * Change the top-level indentation only by changing the column member in * the chunk structures. * The level indicator must already be set. */ void indent_text(void) { chunk_t *pc; chunk_t *next; chunk_t *prev = NULL; bool did_newline = true; int idx; int vardefcol = 0; int indent_size = cpd.settings[UO_indent_columns].n; int tmp; struct parse_frame frm; bool in_preproc = false, was_preproc = false; int indent_column; int cout_col = 0; // for aligning << stuff int cout_level = 0; // for aligning << stuff int parent_token_indent = 0; memset(&frm, 0, sizeof(frm)); /* dummy top-level entry */ frm.pse[0].indent = 1; frm.pse[0].indent_tmp = 1; frm.pse[0].type = CT_EOF; pc = chunk_get_head(); while (pc != NULL) { /* Handle proprocessor transitions */ was_preproc = in_preproc; in_preproc = (pc->flags & PCF_IN_PREPROC) != 0; if (cpd.settings[UO_indent_brace_parent].b) parent_token_indent = token_indent(pc->parent_type); /* Clean up after a #define */ if (!in_preproc) while ((frm.pse_tos > 0) && frm.pse[frm.pse_tos].in_preproc) indent_pse_pop(frm, pc); else { pf_check(&frm, pc); if (!was_preproc) { /* Transition into a preproc by creating a dummy indent */ frm.level++; indent_pse_push(frm, pc); frm.pse[frm.pse_tos].indent = 1 + indent_size; frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent; } } if ((cout_col > 0) && (chunk_is_semicolon(pc) || (pc->level < cout_level))) { cout_col = 0; cout_level = 0; } /** * Handle non-brace closures */ int old_pse_tos; do { old_pse_tos = frm.pse_tos; /* End anything that drops a level * REVISIT: not sure about the preproc check */ if (!chunk_is_newline(pc) && !chunk_is_comment(pc) && ((pc->flags & PCF_IN_PREPROC) == 0) && (frm.pse[frm.pse_tos].level > pc->level)) indent_pse_pop(frm, pc); if (frm.pse[frm.pse_tos].level == pc->level) { /* process virtual braces closes (no text output) */ if ((pc->type == CT_VBRACE_CLOSE) && (frm.pse[frm.pse_tos].type == CT_VBRACE_OPEN)) { indent_pse_pop(frm, pc); frm.level--; pc = chunk_get_next(pc); } /* End any assign operations with a semicolon on the same level */ if ((frm.pse[frm.pse_tos].type == CT_ASSIGN) && (chunk_is_semicolon(pc) || (pc->type == CT_COMMA) || (pc->type == CT_BRACE_OPEN))) indent_pse_pop(frm, pc); /* End any CPP class colon crap */ if ((frm.pse[frm.pse_tos].type == CT_CLASS_COLON) && ((pc->type == CT_BRACE_OPEN) || chunk_is_semicolon(pc))) indent_pse_pop(frm, pc); /* a case is ended with another case or a close brace */ if ((frm.pse[frm.pse_tos].type == CT_CASE) && ((pc->type == CT_BRACE_CLOSE) || (pc->type == CT_CASE))) indent_pse_pop(frm, pc); /* a return is ended with a semicolon */ if ((frm.pse[frm.pse_tos].type == CT_RETURN) && chunk_is_semicolon(pc)) indent_pse_pop(frm, pc); /* Close out parens and squares */ if ((frm.pse[frm.pse_tos].type == (pc->type - 1)) && ((pc->type == CT_PAREN_CLOSE) || (pc->type == CT_SPAREN_CLOSE) || (pc->type == CT_FPAREN_CLOSE) || (pc->type == CT_SQUARE_CLOSE) || (pc->type == CT_ANGLE_CLOSE))) { indent_pse_pop(frm, pc); frm.paren_count--; } } } while (old_pse_tos > frm.pse_tos); /* Grab a copy of the current indent */ indent_column = frm.pse[frm.pse_tos].indent_tmp; if (!chunk_is_newline(pc) && !chunk_is_comment(pc)) { LOG_FMT(LINDPC, " -=[ %.*s ]=- top=%d %s %d/%d\n", pc->len, pc->str, frm.pse_tos, get_token_name(frm.pse[frm.pse_tos].type), frm.pse[frm.pse_tos].indent_tmp, frm.pse[frm.pse_tos].indent); } /** * Handle stuff that can affect the current indent: * - brace close * - vbrace open * - brace open * - case (immediate) * - labels (immediate) * - class colons (immediate) * * And some stuff that can't * - open paren * - open square * - assignment * - return */ if (pc->type == CT_BRACE_CLOSE) { if (frm.pse[frm.pse_tos].type == CT_BRACE_OPEN) { indent_pse_pop(frm, pc); frm.level--; /* Update the indent_column if needed */ if (!cpd.settings[UO_indent_braces].b && (parent_token_indent == 0)) indent_column = frm.pse[frm.pse_tos].indent_tmp; if ((pc->parent_type == CT_IF) || (pc->parent_type == CT_ELSE) || (pc->parent_type == CT_ELSEIF) || (pc->parent_type == CT_DO) || (pc->parent_type == CT_WHILE) || (pc->parent_type == CT_SWITCH) || (pc->parent_type == CT_FOR)) indent_column += cpd.settings[UO_indent_brace].n; } } else if (pc->type == CT_VBRACE_OPEN) { frm.level++; indent_pse_push(frm, pc); frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size; frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent; /* Always indent on virtual braces */ indent_column = frm.pse[frm.pse_tos].indent_tmp; } else if (pc->type == CT_BRACE_OPEN) { frm.level++; indent_pse_push(frm, pc); if (frm.paren_count != 0) /* We are inside ({ ... }) -- indent one tab from the paren */ frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size; else { /* Use the prev indent level + indent_size. */ frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size; /* If this brace is part of a statement, bump it out by indent_brace */ if ((pc->parent_type == CT_IF) || (pc->parent_type == CT_ELSE) || (pc->parent_type == CT_ELSEIF) || (pc->parent_type == CT_DO) || (pc->parent_type == CT_WHILE) || (pc->parent_type == CT_SWITCH) || (pc->parent_type == CT_FOR)) { if (parent_token_indent != 0) frm.pse[frm.pse_tos].indent += parent_token_indent - indent_size; else { frm.pse[frm.pse_tos].indent += cpd.settings[UO_indent_brace].n; indent_column += cpd.settings[UO_indent_brace].n; } } else if (pc->parent_type == CT_CASE) { /* The indent_case_brace setting affects the parent CT_CASE */ frm.pse[frm.pse_tos].indent_tmp += cpd.settings[UO_indent_case_brace].n; frm.pse[frm.pse_tos].indent += cpd.settings[UO_indent_case_brace].n; } else if ((pc->parent_type == CT_CLASS) && !cpd.settings[UO_indent_class].b) frm.pse[frm.pse_tos].indent -= indent_size; else if ((pc->parent_type == CT_NAMESPACE) && !cpd.settings[UO_indent_namespace].b) frm.pse[frm.pse_tos].indent -= indent_size; } if ((pc->flags & PCF_DONT_INDENT) != 0) { frm.pse[frm.pse_tos].indent = pc->column; indent_column = pc->column; } else { /** * If there isn't a newline between the open brace and the next * item, just indent to wherever the next token is. * This covers this sort of stuff: * { a++; * b--; }; */ next = chunk_get_next_ncnl(pc); if (!chunk_is_newline_between(pc, next)) frm.pse[frm.pse_tos].indent = next->column; frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent; frm.pse[frm.pse_tos].open_line = pc->orig_line; /* Update the indent_column if needed */ if (cpd.settings[UO_indent_braces].n || (parent_token_indent != 0)) indent_column = frm.pse[frm.pse_tos].indent_tmp; } } else if (pc->type == CT_CASE) { /* Start a case - indent UO_indent_switch_case from the switch level */ tmp = frm.pse[frm.pse_tos].indent + cpd.settings[UO_indent_switch_case].n; indent_pse_push(frm, pc); frm.pse[frm.pse_tos].indent = tmp; frm.pse[frm.pse_tos].indent_tmp = tmp - indent_size; /* Always set on case statements */ indent_column = frm.pse[frm.pse_tos].indent_tmp; } else if (pc->type == CT_LABEL) { /* Labels get sent to the left or backed up */ if (cpd.settings[UO_indent_label].n > 0) indent_column = cpd.settings[UO_indent_label].n; else indent_column = frm.pse[frm.pse_tos].indent + cpd.settings[UO_indent_label].n; } else if (pc->type == CT_CLASS_COLON) { /* just indent one level */ indent_pse_push(frm, pc); frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size; frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent; indent_column = frm.pse[frm.pse_tos].indent_tmp; if (cpd.settings[UO_indent_class_colon].b) { prev = chunk_get_prev(pc); if (chunk_is_newline(prev)) frm.pse[frm.pse_tos].indent += 2; /* don't change indent of current line */ } } else if ((pc->type == CT_PAREN_OPEN) || (pc->type == CT_SPAREN_OPEN) || (pc->type == CT_FPAREN_OPEN) || (pc->type == CT_SQUARE_OPEN) || (pc->type == CT_ANGLE_OPEN)) { /* Open parens and squares - never update indent_column */ indent_pse_push(frm, pc); frm.pse[frm.pse_tos].indent = pc->column + pc->len; if (cpd.settings[UO_indent_func_call_param].b && (pc->type == CT_FPAREN_OPEN) && (pc->parent_type == CT_FUNC_CALL)) frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size; if ((chunk_is_str(pc, "(", 1) && !cpd.settings[UO_indent_paren_nl].b) || (chunk_is_str(pc, "[", 1) && !cpd.settings[UO_indent_square_nl].b)) { next = chunk_get_next_nc(pc); if (chunk_is_newline(next)) { int sub = 1; if (frm.pse[frm.pse_tos - 1].type == CT_ASSIGN) sub = 2; frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - sub].indent + indent_size; } } frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent; frm.paren_count++; } else if (pc->type == CT_ASSIGN) { /** * if there is a newline after the '=', just indent one level, * otherwise align on the '='. * Never update indent_column. */ next = chunk_get_next(pc); if (next != NULL) { indent_pse_push(frm, pc); if (chunk_is_newline(next)) frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size; else frm.pse[frm.pse_tos].indent = pc->column + pc->len + 1; frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent; } } else if (pc->type == CT_RETURN) { /* don't count returns inside a () or [] */ if (pc->level == pc->brace_level) { indent_pse_push(frm, pc); frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + pc->len + 1; frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos - 1].indent; } } else if (chunk_is_str(pc, "<<", 2)) { if (cout_col == 0) { cout_col = pc->column; cout_level = pc->level; } } else { /* anything else? */ } /** * Indent the line if needed */ if (did_newline && !chunk_is_newline(pc) && (pc->len != 0)) { /** * Check for special continuations. * Note that some of these could be done as a stack item like * everything else */ prev = chunk_get_prev_ncnl(pc); if ((pc->type == CT_MEMBER) || (pc->type == CT_DC_MEMBER) || ((prev != NULL) && ((prev->type == CT_MEMBER) || (prev->type == CT_DC_MEMBER)))) { tmp = cpd.settings[UO_indent_member].n + indent_column; LOG_FMT(LINDENT, "%s: %d] member => %d\n", __func__, pc->orig_line, tmp); reindent_line(pc, tmp); } else if (chunk_is_str(pc, "<<", 2) && (cout_col > 0)) { LOG_FMT(LINDENT, "%s: %d] cout_col => %d\n", __func__, pc->orig_line, cout_col); reindent_line(pc, cout_col); } else if ((vardefcol > 0) && (pc->type == CT_WORD) && ((pc->flags & PCF_VAR_DEF) != 0) && (prev != NULL) && (prev->type == CT_COMMA)) { LOG_FMT(LINDENT, "%s: %d] Vardefcol => %d\n", __func__, pc->orig_line, vardefcol); reindent_line(pc, vardefcol); } else if ((pc->type == CT_STRING) && (prev->type == CT_STRING) && cpd.settings[UO_indent_align_string].b) { LOG_FMT(LINDENT, "%s: %d] String => %d\n", __func__, pc->orig_line, prev->column); reindent_line(pc, prev->column); } else if (chunk_is_comment(pc)) { LOG_FMT(LINDENT, "%s: %d] comment => %d\n", __func__, pc->orig_line, frm.pse[frm.pse_tos].indent_tmp); indent_comment(pc, frm.pse[frm.pse_tos].indent_tmp); } else if (pc->type == CT_PREPROC) { /* Preprocs are always in column 1. See indent_preproc() */ if (pc->column != 1) reindent_line(pc, 1); } else { if (pc->column != indent_column) { LOG_FMT(LINDENT, "%s: %d] indent => %d [%.*s]\n", __func__, pc->orig_line, indent_column, pc->len, pc->str); reindent_line(pc, indent_column); } } did_newline = false; } /** * Handle variable definition continuation indenting */ if ((pc->type == CT_WORD) && ((pc->flags & PCF_IN_FCN_DEF) == 0) && ((pc->flags & PCF_VAR_1ST_DEF) == PCF_VAR_1ST_DEF)) vardefcol = pc->column; if (chunk_is_semicolon(pc) || ((pc->type == CT_BRACE_OPEN) && (pc->parent_type == CT_FUNCTION))) vardefcol = 0; /* if we hit a newline, reset indent_tmp */ if (chunk_is_newline(pc) || (pc->type == CT_COMMENT_MULTI) || (pc->type == CT_COMMENT_CPP)) { frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent; /** * Handle the case of a multi-line #define w/o anything on the * first line (indent_tmp will be 1 or 0) */ if ((pc->type == CT_NL_CONT) && (frm.pse[frm.pse_tos].indent_tmp <= indent_size)) frm.pse[frm.pse_tos].indent_tmp = indent_size + 1; /* Get ready to indent the next item */ did_newline = true; } if (!chunk_is_comment(pc) && !chunk_is_newline(pc)) prev = pc; pc = chunk_get_next(pc); } /* Throw out any stuff inside a preprocessor - no need to warn */ while ((frm.pse_tos > 0) && frm.pse[frm.pse_tos].in_preproc) indent_pse_pop(frm, pc); for (idx = 1; idx <= frm.pse_tos; idx++) { LOG_FMT(LWARN, "%s:%d Unmatched %s\n", cpd.filename, frm.pse[idx].open_line, get_token_name(frm.pse[idx].type)); cpd.error_count++; } }
static void examine_brace(chunk_t *bopen) { LOG_FUNC_ENTRY(); chunk_t *next; chunk_t *prev = NULL; size_t semi_count = 0; size_t level = bopen->level + 1; bool hit_semi = false; bool was_fcn = false; size_t nl_max = cpd.settings[UO_mod_full_brace_nl].u; size_t nl_count = 0; size_t if_count = 0; int br_count = 0; LOG_FMT(LBRDEL, "%s: start on %zu : ", __func__, bopen->orig_line); chunk_t *pc = chunk_get_next_nc(bopen); while ((pc != NULL) && (pc->level >= level)) { if (pc->flags & PCF_IN_PREPROC) { LOG_FMT(LBRDEL, " PREPROC\n"); return; } if (chunk_is_newline(pc)) { nl_count += pc->nl_count; if ((nl_max > 0) && (nl_count > nl_max)) { LOG_FMT(LBRDEL, " exceeded %zu newlines\n", nl_max); return; } } else { if (pc->type == CT_BRACE_OPEN) { br_count++; } else if (pc->type == CT_BRACE_CLOSE) { br_count--; if (br_count == 0) { next = chunk_get_next_ncnl(pc, CNAV_PREPROC); if ((next == NULL) || (next->type != CT_BRACE_CLOSE)) { LOG_FMT(LBRDEL, " junk after close brace\n"); return; } } } else if ((pc->type == CT_IF) || (pc->type == CT_ELSEIF)) { if (br_count == 0) { if_count++; } } if (pc->level == level) { if ((semi_count > 0) && hit_semi) { /* should have bailed due to close brace level drop */ LOG_FMT(LBRDEL, " no close brace\n"); return; } LOG_FMT(LBRDEL, " [%s %zu-%zu]", pc->text(), pc->orig_line, semi_count); if (pc->type == CT_ELSE) { LOG_FMT(LBRDEL, " bailed on %s on line %zu\n", pc->text(), pc->orig_line); return; } was_fcn = (prev != NULL) && (prev->type == CT_FPAREN_CLOSE); if (chunk_is_semicolon(pc) || (pc->type == CT_IF) || (pc->type == CT_ELSEIF) || (pc->type == CT_FOR) || (pc->type == CT_DO) || (pc->type == CT_WHILE) || (pc->type == CT_SWITCH) || (pc->type == CT_USING_STMT) || ((pc->type == CT_BRACE_OPEN) && was_fcn)) { hit_semi |= chunk_is_semicolon(pc); if (++semi_count > 1) { LOG_FMT(LBRDEL, " bailed on %zu because of %s on line %zu\n", bopen->orig_line, pc->text(), pc->orig_line); return; } } } } prev = pc; pc = chunk_get_next_nc(pc); } if (pc == NULL) { LOG_FMT(LBRDEL, " NULL\n"); return; } LOG_FMT(LBRDEL, " - end on '%s' on line %zu. if_count=%zu semi_count=%zu\n", get_token_name(pc->type), pc->orig_line, if_count, semi_count); if (pc->type == CT_BRACE_CLOSE) { next = chunk_get_next_ncnl(pc); while ((next != NULL) && (next->type == CT_VBRACE_CLOSE)) { next = chunk_get_next_ncnl(next); } LOG_FMT(LBRDEL, " next is '%s'\n", get_token_name(next->type)); if ((if_count > 0) && ((next->type == CT_ELSE) || (next->type == CT_ELSEIF))) { LOG_FMT(LBRDEL, " bailed on because 'else' is next and %zu ifs\n", if_count); return; } if (semi_count > 0) { if (bopen->parent_type == CT_ELSE) { next = chunk_get_next_ncnl(bopen); if (next->type == CT_IF) { prev = chunk_get_prev_ncnl(bopen); LOG_FMT(LBRDEL, " else-if removing braces on line %zu and %zu\n", bopen->orig_line, pc->orig_line); chunk_del(bopen); chunk_del(pc); newline_del_between(prev, next); if (cpd.settings[UO_nl_else_if].a & AV_ADD) { newline_add_between(prev, next); } return; } } /* we have a pair of braces with only 1 statement inside */ convert_brace(bopen); convert_brace(pc); LOG_FMT(LBRDEL, " removing braces on line %zu and %zu\n", bopen->orig_line, pc->orig_line); } else { LOG_FMT(LBRDEL, " empty statement\n"); } } else { LOG_FMT(LBRDEL, " not a close brace? - '%s'\n", pc->text()); } } // examine_brace
static bool can_remove_braces(chunk_t *bopen) { LOG_FUNC_ENTRY(); chunk_t *prev = NULL; size_t semi_count = 0; size_t level = bopen->level + 1; bool hit_semi = false; bool was_fcn = false; size_t nl_max = cpd.settings[UO_mod_full_brace_nl].u; size_t nl_count = 0; size_t if_count = 0; int br_count = 0; /* Cannot remove braces inside a preprocessor */ if (bopen->flags & PCF_IN_PREPROC) { return(false); } chunk_t *pc = chunk_get_next_ncnl(bopen, CNAV_PREPROC); if ((pc != NULL) && (pc->type == CT_BRACE_CLOSE)) { /* Can't remove empty statement */ return(false); } LOG_FMT(LBRDEL, "%s: start on %zu : ", __func__, bopen->orig_line); pc = chunk_get_next_nc(bopen, CNAV_ALL); while ((pc != NULL) && (pc->level >= level)) { if (pc->flags & PCF_IN_PREPROC) { /* Cannot remove braces that contain a preprocessor */ return(false); } if (chunk_is_newline(pc)) { nl_count += pc->nl_count; if ((nl_max > 0) && (nl_count > nl_max)) { LOG_FMT(LBRDEL, " exceeded %zu newlines\n", nl_max); return(false); } } else { if (pc->type == CT_BRACE_OPEN) { br_count++; } else if (pc->type == CT_BRACE_CLOSE) { br_count--; } else if ((pc->type == CT_IF) || (pc->type == CT_ELSEIF)) { if (br_count == 0) { if_count++; } } if (pc->level == level) { if ((semi_count > 0) && hit_semi) { /* should have bailed due to close brace level drop */ LOG_FMT(LBRDEL, " no close brace\n"); return(false); } LOG_FMT(LBRDEL, " [%s %zu-%zu]", pc->text(), pc->orig_line, semi_count); if (pc->type == CT_ELSE) { LOG_FMT(LBRDEL, " bailed on %s on line %zu\n", pc->text(), pc->orig_line); return(false); } was_fcn = (prev != NULL) && (prev->type == CT_FPAREN_CLOSE); if (chunk_is_semicolon(pc) || (pc->type == CT_IF) || (pc->type == CT_ELSEIF) || (pc->type == CT_FOR) || (pc->type == CT_DO) || (pc->type == CT_WHILE) || (pc->type == CT_USING_STMT) || ((pc->type == CT_BRACE_OPEN) && was_fcn)) { hit_semi |= chunk_is_semicolon(pc); if (++semi_count > 1) { LOG_FMT(LBRDEL, " bailed on %zu because of %s on line %zu\n", bopen->orig_line, pc->text(), pc->orig_line); return(false); } } } } prev = pc; pc = chunk_get_next_nc(pc); } if (pc == NULL) { LOG_FMT(LBRDEL, " NULL\n"); return(false); } if ((pc->type == CT_BRACE_CLOSE) && (pc->parent_type == CT_IF)) { chunk_t *next = chunk_get_next_ncnl(pc, CNAV_PREPROC); prev = chunk_get_prev_ncnl(pc, CNAV_PREPROC); if ((next != NULL) && (next->type == CT_ELSE) && ((prev->type == CT_BRACE_CLOSE) || (prev->type == CT_VBRACE_CLOSE)) && (prev->parent_type == CT_IF)) { LOG_FMT(LBRDEL, " - bailed on '%s'[%s] on line %zu due to 'if' and 'else' sequence\n", get_token_name(pc->type), get_token_name(pc->parent_type), pc->orig_line); return(false); } } LOG_FMT(LBRDEL, " - end on '%s' on line %zu. if_count=%zu semi_count=%zu\n", get_token_name(pc->type), pc->orig_line, if_count, semi_count); return((pc->type == CT_BRACE_CLOSE) && (pc->pp_level == bopen->pp_level)); } // can_remove_braces
void do_braces(void) { LOG_FUNC_ENTRY(); if (cpd.settings[UO_mod_full_brace_if_chain].b || cpd.settings[UO_mod_full_brace_if_chain_only].b) { mod_full_brace_if_chain(); } if ((cpd.settings[UO_mod_full_brace_if].a | cpd.settings[UO_mod_full_brace_do].a | cpd.settings[UO_mod_full_brace_for].a | cpd.settings[UO_mod_full_brace_using].a | cpd.settings[UO_mod_full_brace_while].a) & AV_REMOVE) { examine_braces(); } /* convert vbraces if needed */ if ((cpd.settings[UO_mod_full_brace_if].a | cpd.settings[UO_mod_full_brace_do].a | cpd.settings[UO_mod_full_brace_for].a | cpd.settings[UO_mod_full_brace_function].a | cpd.settings[UO_mod_full_brace_using].a | cpd.settings[UO_mod_full_brace_while].a) & AV_ADD) { convert_vbrace_to_brace(); } /* Mark one-liners */ chunk_t *pc = chunk_get_head(); while ((pc = chunk_get_next_ncnl(pc)) != NULL) { if ((pc->type != CT_BRACE_OPEN) && (pc->type != CT_VBRACE_OPEN)) { continue; } chunk_t *br_open = pc; c_token_t brc_type = c_token_t(pc->type + 1); /* Detect empty bodies */ chunk_t *tmp = chunk_get_next_ncnl(pc); if ((tmp != NULL) && (tmp->type == brc_type)) { chunk_flags_set(br_open, PCF_EMPTY_BODY); chunk_flags_set(tmp, PCF_EMPTY_BODY); } /* Scan for the brace close or a newline */ tmp = br_open; while ((tmp = chunk_get_next_nc(tmp)) != NULL) { if (chunk_is_newline(tmp)) { break; } if ((tmp->type == brc_type) && (br_open->level == tmp->level)) { flag_series(br_open, tmp, PCF_ONE_LINER); break; } } } if (cpd.settings[UO_mod_case_brace].a != AV_IGNORE) { mod_case_brace(); } if (cpd.settings[UO_mod_move_case_break].b) { move_case_break(); } } // do_braces
/** * Scan everything at the current level until the close brace and find the * variable def align column. Also aligns bit-colons, but that assumes that * bit-types are the same! But that should always be the case... */ static chunk_t *align_var_def_brace(chunk_t *start, int span, int *p_nl_count) { chunk_t *pc; chunk_t *next; chunk_t *prev; UINT64 align_mask = PCF_IN_FCN_DEF | PCF_VAR_1ST; int myspan = span; int mythresh = 0; int mygap = 0; AlignStack as; /* var/proto/def */ AlignStack as_bc; /* bit-colon */ AlignStack as_at; /* attribute */ AlignStack as_br; /* one-liner brace open */ bool fp_active = cpd.settings[UO_align_mix_var_proto].b; bool fp_look_bro = false; if (start == NULL) { return(NULL); } /* Override the span, if this is a struct/union */ if ((start->parent_type == CT_STRUCT) || (start->parent_type == CT_UNION)) { myspan = cpd.settings[UO_align_var_struct_span].n; mythresh = cpd.settings[UO_align_var_struct_thresh].n; mygap = cpd.settings[UO_align_var_struct_gap].n; } else { mythresh = cpd.settings[UO_align_var_def_thresh].n; mygap = cpd.settings[UO_align_var_def_gap].n; } /* can't be any variable definitions in a "= {" block */ prev = chunk_get_prev_ncnl(start); if ((prev != NULL) && (prev->type == CT_ASSIGN)) { LOG_FMT(LAVDB, "%s: start=%.*s [%s] on line %d (abort due to assign)\n", __func__, start->len, start->str, get_token_name(start->type), start->orig_line); pc = chunk_get_next_type(start, CT_BRACE_CLOSE, start->level); return(chunk_get_next_ncnl(pc)); } LOG_FMT(LAVDB, "%s: start=%.*s [%s] on line %d\n", __func__, start->len, start->str, get_token_name(start->type), start->orig_line); if (!cpd.settings[UO_align_var_def_inline].b) { align_mask |= PCF_VAR_INLINE; } /* Set up the var/proto/def aligner */ as.Start(myspan, mythresh); as.m_gap = mygap; as.m_star_style = (AlignStack::StarStyle)cpd.settings[UO_align_var_def_star_style].n; as.m_amp_style = (AlignStack::StarStyle)cpd.settings[UO_align_var_def_amp_style].n; /* Set up the bit colon aligner */ as_bc.Start(myspan, 0); as_bc.m_gap = cpd.settings[UO_align_var_def_colon_gap].n; as_at.Start(myspan, 0); /* Set up the brace open aligner */ as_br.Start(myspan, mythresh); as_br.m_gap = cpd.settings[UO_align_single_line_brace_gap].n; bool did_this_line = false; pc = chunk_get_next(start); while ((pc != NULL) && ((pc->level >= start->level) || (pc->level == 0))) { if (chunk_is_comment(pc)) { if (pc->nl_count > 0) { as.NewLines(pc->nl_count); as_bc.NewLines(pc->nl_count); as_at.NewLines(pc->nl_count); as_br.NewLines(pc->nl_count); } pc = chunk_get_next(pc); continue; } if (fp_active) { if ((pc->type == CT_FUNC_PROTO) || ((pc->type == CT_FUNC_DEF) && cpd.settings[UO_align_single_line_func].b)) { LOG_FMT(LAVDB, " add=[%.*s] line=%d col=%d level=%d\n", pc->len, pc->str, pc->orig_line, pc->orig_col, pc->level); as.Add(pc); fp_look_bro = (pc->type == CT_FUNC_DEF) && cpd.settings[UO_align_single_line_brace].b; } else if (fp_look_bro && (pc->type == CT_BRACE_OPEN) && (pc->flags & PCF_ONE_LINER)) { as_br.Add(pc); fp_look_bro = false; } } /* process nested braces */ if (pc->type == CT_BRACE_OPEN) { int sub_nl_count = 0; pc = align_var_def_brace(pc, span, &sub_nl_count); if (sub_nl_count > 0) { fp_look_bro = false; did_this_line = false; as.NewLines(sub_nl_count); as_bc.NewLines(sub_nl_count); as_at.NewLines(sub_nl_count); as_br.NewLines(sub_nl_count); if (p_nl_count != NULL) { *p_nl_count += sub_nl_count; } } continue; } /* Done with this brace set? */ if (pc->type == CT_BRACE_CLOSE) { pc = chunk_get_next(pc); break; } if (chunk_is_newline(pc)) { fp_look_bro = false; did_this_line = false; as.NewLines(pc->nl_count); as_bc.NewLines(pc->nl_count); as_at.NewLines(pc->nl_count); as_br.NewLines(pc->nl_count); if (p_nl_count != NULL) { *p_nl_count += pc->nl_count; } } /* don't align stuff inside parens/squares/angles */ if (pc->level > pc->brace_level) { pc = chunk_get_next(pc); continue; } /* If this is a variable def, update the max_col */ if ((pc->type != CT_FUNC_CLASS) && ((pc->flags & align_mask) == PCF_VAR_1ST) && ((pc->level == (start->level + 1)) || (pc->level == 0))) { if (!did_this_line) { LOG_FMT(LAVDB, " add=[%.*s] line=%d col=%d level=%d\n", pc->len, pc->str, pc->orig_line, pc->orig_col, pc->level); as.Add(pc); if (cpd.settings[UO_align_var_def_colon].b) { next = chunk_get_next_nc(pc); if (next->type == CT_BIT_COLON) { as_bc.Add(next); } } if (cpd.settings[UO_align_var_def_attribute].b) { next = pc; while ((next = chunk_get_next_nc(next)) != NULL) { if (next->type == CT_ATTRIBUTE) { as_at.Add(next); break; } if ((next->type == CT_SEMICOLON) || chunk_is_newline(next)) { break; } } } } did_this_line = true; } else if (pc->type == CT_BIT_COLON) { if (!did_this_line) { as_bc.Add(pc); did_this_line = true; } } pc = chunk_get_next(pc); } as.End(); as_bc.End(); as_at.End(); as_br.End(); return(pc); }
/** * Scans the whole file for #defines. Aligns all within X lines of each other */ void align_preprocessor(void) { chunk_t *pc; AlignStack as; // value macros AlignStack asf; // function macros AlignStack *cur_as = &as; as.Start(cpd.settings[UO_align_pp_define_span].n); as.m_gap = cpd.settings[UO_align_pp_define_gap].n; asf.Start(cpd.settings[UO_align_pp_define_span].n); asf.m_gap = cpd.settings[UO_align_pp_define_gap].n; pc = chunk_get_head(); while (pc != NULL) { /* Note: not counting back-slash newline combos */ if (pc->type == CT_NEWLINE) { as.NewLines(pc->nl_count); asf.NewLines(pc->nl_count); } /* If we aren't on a 'define', then skip to the next non-comment */ if (pc->type != CT_PP_DEFINE) { pc = chunk_get_next_nc(pc); continue; } /* step past the 'define' */ pc = chunk_get_next_nc(pc); if (pc == NULL) { break; } LOG_FMT(LALPP, "%s: define (%.*s) on line %d col %d\n", __func__, pc->len, pc->str, pc->orig_line, pc->orig_col); cur_as = &as; if (pc->type == CT_MACRO_FUNC) { cur_as = &asf; /* Skip to the close paren */ pc = chunk_get_next_nc(pc); // point to open ( pc = chunk_get_next_type(pc, CT_FPAREN_CLOSE, pc->level); LOG_FMT(LALPP, "%s: jumped to (%.*s) on line %d col %d\n", __func__, pc->len, pc->str, pc->orig_line, pc->orig_col); } /* step to the value past the close paren or the macro name */ pc = chunk_get_next(pc); if (pc == NULL) { break; } /* don't align anything if the first line ends with a newline before * a value is given */ if (!chunk_is_newline(pc)) { LOG_FMT(LALPP, "%s: align on '%.*s', line %d col %d\n", __func__, pc->len, pc->str, pc->orig_line, pc->orig_col); cur_as->Add(pc); } } as.End(); asf.End(); }
/** * Scans a line for stuff to align on. * * We trigger on BRACE_OPEN, FPAREN_OPEN, ASSIGN, and COMMA. * We want to align the NEXT item. */ static chunk_t *scan_ib_line(chunk_t *start, bool first_pass) { chunk_t *pc; chunk_t *next; chunk_t *prev_match = NULL; int token_width; int idx = 0; bool last_was_comment = false; /* Skip past C99 "[xx] =" stuff */ if (start->type == CT_SQUARE_OPEN) { start->parent_type = CT_TSQUARE; start = chunk_get_next_type(start, CT_ASSIGN, start->level); start = chunk_get_next_ncnl(start); cpd.al_c99_array = true; } pc = start; if (pc != NULL) { LOG_FMT(LSIB, "%s: start=%s col %d/%d line %d\n", __func__, get_token_name(pc->type), pc->column, pc->orig_col, pc->orig_line); } while ((pc != NULL) && !chunk_is_newline(pc) && (pc->level >= start->level)) { //LOG_FMT(LSIB, "%s: '%.*s' col %d/%d line %d\n", __func__, // pc->len, pc->str, pc->column, pc->orig_col, pc->orig_line); next = chunk_get_next(pc); if ((next == NULL) || chunk_is_comment(next)) { /* do nothing */ } else if ((pc->type == CT_ASSIGN) || (pc->type == CT_BRACE_OPEN) || (pc->type == CT_BRACE_CLOSE) || (pc->type == CT_COMMA)) { token_width = space_col_align(pc, next); /*TODO: need to handle missing structure defs? ie NULL vs { ... } ?? */ /* Is this a new entry? */ if (idx >= cpd.al_cnt) { LOG_FMT(LSIB, " - New [%d] %.2d/%d - %10.10s\n", idx, pc->column, token_width, get_token_name(pc->type)); cpd.al[cpd.al_cnt].type = pc->type; cpd.al[cpd.al_cnt].col = pc->column; cpd.al[cpd.al_cnt].len = token_width; cpd.al_cnt++; idx++; last_was_comment = false; } else { /* expect to match stuff */ if (cpd.al[idx].type == pc->type) { LOG_FMT(LSIB, " - Match [%d] %.2d/%d - %10.10s", idx, pc->column, token_width, get_token_name(pc->type)); /* Shift out based on column */ if (prev_match == NULL) { if (pc->column > cpd.al[idx].col) { LOG_FMT(LSIB, " [ pc->col(%d) > col(%d) ] ", pc->column, cpd.al[idx].col); ib_shift_out(idx, pc->column - cpd.al[idx].col); cpd.al[idx].col = pc->column; } } else if (idx > 0) { int min_col_diff = pc->column - prev_match->column; int cur_col_diff = cpd.al[idx].col - cpd.al[idx - 1].col; if (cur_col_diff < min_col_diff) { LOG_FMT(LSIB, " [ min_col_diff(%d) > cur_col_diff(%d) ] ", min_col_diff, cur_col_diff); ib_shift_out(idx, min_col_diff - cur_col_diff); } } LOG_FMT(LSIB, " - now col %d, len %d\n", cpd.al[idx].col, cpd.al[idx].len); idx++; } } prev_match = pc; } last_was_comment = chunk_is_comment(pc); pc = chunk_get_next_nc(pc); } //if (last_was_comment && (cpd.al[cpd.al_cnt - 1].type == CT_COMMA)) //{ // cpd.al_cnt--; //} return(pc); }
/** * Checks to see if the braces can be removed. * - less than a certain length * - doesn't mess up if/else stuff */ static bool can_remove_braces(chunk_t *bopen) { chunk_t *pc; chunk_t *prev = NULL; int semi_count = 0; int level = bopen->level + 1; bool hit_semi = false; bool was_fcn = false; int nl_max = cpd.settings[UO_mod_full_brace_nl].n; int nl_count = 0; int if_count = 0; int br_count = 0; /* Cannot remove braces inside a preprocessor */ if (bopen->flags & PCF_IN_PREPROC) { return(false); } pc = chunk_get_next_ncnl(bopen, CNAV_PREPROC); if ((pc != NULL) && (pc->type == CT_BRACE_CLOSE)) { /* Can't remove empty statement */ return(false); } LOG_FMT(LBRDEL, "%s: start on %d : ", __func__, bopen->orig_line); pc = chunk_get_next_nc(bopen, CNAV_PREPROC); while ((pc != NULL) && (pc->level >= level)) { if (chunk_is_newline(pc)) { nl_count += pc->nl_count; if ((nl_max > 0) && (nl_count > nl_max)) { LOG_FMT(LBRDEL, " exceeded %d newlines\n", nl_max); return(false); } } else { if (pc->type == CT_BRACE_OPEN) { br_count++; } else if (pc->type == CT_BRACE_CLOSE) { br_count--; } else if ((pc->type == CT_IF) || (pc->type == CT_ELSEIF)) { if (br_count == 0) { if_count++; } } if (pc->level == level) { if ((semi_count > 0) && hit_semi) { /* should have bailed due to close brace level drop */ LOG_FMT(LBRDEL, " no close brace\n"); return(false); } LOG_FMT(LBRDEL, " [%.*s %d-%d]", pc->len, pc->str, pc->orig_line, semi_count); if (pc->type == CT_ELSE) { LOG_FMT(LBRDEL, " bailed on %.*s on line %d\n", pc->len, pc->str, pc->orig_line); return(false); } was_fcn = (prev != NULL) && (prev->type == CT_FPAREN_CLOSE); if (chunk_is_semicolon(pc) || (pc->type == CT_IF) || (pc->type == CT_ELSEIF) || (pc->type == CT_FOR) || (pc->type == CT_DO) || (pc->type == CT_WHILE) || ((pc->type == CT_BRACE_OPEN) && was_fcn)) { hit_semi |= chunk_is_semicolon(pc); if (++semi_count > 1) { LOG_FMT(LBRDEL, " bailed on %d because of %.*s on line %d\n", bopen->orig_line, pc->len, pc->str, pc->orig_line); return(false); } } } } prev = pc; pc = chunk_get_next_nc(pc, CNAV_PREPROC); } if (pc == NULL) { LOG_FMT(LBRDEL, " NULL\n"); return(false); } LOG_FMT(LBRDEL, " - end on '%s' on line %d. if_count=%d semi_count=%d\n", get_token_name(pc->type), pc->orig_line, if_count, semi_count); return((pc->type == CT_BRACE_CLOSE) && (pc->pp_level == bopen->pp_level)); }