static size_t preproc_start(parse_frame_t *frm, chunk_t *pc) { LOG_FUNC_ENTRY(); chunk_t *next; size_t pp_level = cpd.pp_level; // Get the type of preprocessor and handle it next = chunk_get_next_ncnl(pc); if (next != nullptr) { cpd.in_preproc = next->type; // If we are in a define, push the frame stack. if (cpd.in_preproc == CT_PP_DEFINE) { pf_push(frm); // a preproc body starts a new, blank frame memset(frm, 0, sizeof(*frm)); frm->level = 1; frm->brace_level = 1; // TODO: not sure about the next 3 lines frm->pse_tos = 1; frm->pse[frm->pse_tos].type = CT_PP_DEFINE; frm->pse[frm->pse_tos].stage = brace_stage_e::NONE; } else { // Check for #if, #else, #endif, etc pp_level = pf_check(frm, pc); } } return(pp_level); }
/***************************************************************************** * Shared Open code *****************************************************************************/ static inline bool check_Property( demux_t *p_demux, const char **pp_psz, bool(*pf_check)(demux_t *, const char *) ) { while( *pp_psz ) { if( pf_check( p_demux, *pp_psz ) ) return true; pp_psz++; } return false; }
static int preproc_start(struct parse_frame *frm, chunk_t *pc) { LOG_FUNC_ENTRY(); chunk_t *next; int pp_level = cpd.pp_level; /* Get the type of preprocessor and handle it */ next = chunk_get_next_ncnl(pc); if (next != NULL) { cpd.in_preproc = next->type; /** * If we are in a define, push the frame stack. */ if (cpd.in_preproc == CT_PP_DEFINE) { pf_push(frm); /* a preproc body starts a new, blank frame */ memset(frm, 0, sizeof(*frm)); frm->level = 1; frm->brace_level = 1; /*TODO: not sure about the next 3 lines */ frm->pse_tos = 1; frm->pse[frm->pse_tos].type = CT_PP_DEFINE; frm->pse[frm->pse_tos].stage = BS_NONE; } else { /* Check for #if, #else, #endif, etc */ pp_level = pf_check(frm, pc); } } return(pp_level); }
/** * 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++; } }