void do_code_width(void) { LOG_FUNC_ENTRY(); LOG_FMT(LSPLIT, "%s(%d)\n", __func__, __LINE__); for (chunk_t *pc = chunk_get_head(); pc != nullptr; pc = chunk_get_next(pc)) { if ( !chunk_is_newline(pc) && !chunk_is_comment(pc) && pc->type != CT_SPACE && is_past_width(pc)) { if ( pc->type == CT_VBRACE_CLOSE // don't break if a vbrace close && chunk_is_last_on_line(*pc)) // is the last chunk on its line { continue; } bool split_OK = split_line(pc); if (split_OK) { LOG_FMT(LSPLIT, "%s(%d): on orig_line=%zu, orig_col=%zu, for %s\n", __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text()); } else { LOG_FMT(LSPLIT, "%s(%d): Bailed on orig_line=%zu, orig_col=%zu, for %s\n", __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text()); break; } } } }
static void add_file_header() { if (!chunk_is_comment(chunk_get_head())) { /*TODO: detect the typical #ifndef FOO / #define FOO sequence */ tokenize(cpd.file_hdr.data, chunk_get_head()); } }
/* * the value of after determines: * true: insert_vbrace_close_after(pc, frm) * false: insert_vbrace_open_before(pc, frm) */ static chunk_t *insert_vbrace(chunk_t *pc, bool after, struct parse_frame *frm) { LOG_FUNC_ENTRY(); chunk_t chunk; chunk_t *rv; chunk_t *ref; chunk.orig_line = pc->orig_line; chunk.parent_type = frm->pse[frm->pse_tos].type; chunk.level = frm->level; chunk.brace_level = frm->brace_level; chunk.flags = pc->flags & PCF_COPY_FLAGS; chunk.str = ""; if (after) { chunk.type = CT_VBRACE_CLOSE; rv = chunk_add_after(&chunk, pc); } else { ref = chunk_get_prev(pc); if ((ref->flags & PCF_IN_PREPROC) == 0) { chunk.flags &= ~PCF_IN_PREPROC; } while (chunk_is_newline(ref) || chunk_is_comment(ref)) { ref->level++; ref->brace_level++; ref = chunk_get_prev(ref); } /* Don't back into a preprocessor */ if (((pc->flags & PCF_IN_PREPROC) == 0) && (ref->flags & PCF_IN_PREPROC)) { if (ref->type == CT_PREPROC_BODY) { do { ref = chunk_get_prev(ref); } while ((ref != NULL) && (ref->flags & PCF_IN_PREPROC)); } else { ref = chunk_get_next(ref); } } chunk.orig_line = ref->orig_line; chunk.column = ref->column + ref->len() + 1; chunk.type = CT_VBRACE_OPEN; rv = chunk_add_after(&chunk, ref); } return(rv); } // insert_vbrace
/** * REVISIT: This needs to be re-checked, maybe cleaned up * * Indents comments in a (hopefully) smart manner. * * There are two type of comments that get indented: * - stand alone (ie, no tokens on the line before the comment) * - trailing comments (last token on the line apart from a linefeed) * + note that a stand-alone comment is a special case of a trailing * * The stand alone comments will get indented in one of three ways: * - column 1: * + There is an empty line before the comment AND the indent level is 0 * + The comment was originally in column 1 * * - Same column as trailing comment on previous line (ie, aligned) * + if originally within TBD (3) columns of the previous comment * * - syntax indent level * + doesn't fit in the previous categories * * Options modify this behavior: * - keep original column (don't move the comment, if possible) * - keep relative column (move out the same amount as first item on line) * - fix trailing comment in column TBD * * @param pc The comment, which is the first item on a line * @param col The column if this is to be put at indent level */ static void indent_comment(chunk_t *pc, int col) { chunk_t *nl; chunk_t *prev; LOG_FMT(LCMTIND, "%s: line %d, col %d, level %d: ", __func__, pc->orig_line, pc->orig_col, pc->level); /* force column 1 comment to column 1 if not changing them */ if ((pc->orig_col == 1) && !cpd.settings[UO_indent_col1_comment].b) { LOG_FMT(LCMTIND, "rule 1 - keep in col 1\n"); pc->column = 1; return; } nl = chunk_get_prev(pc); /* outside of any expression or statement? */ if (pc->level == 0) { if ((nl != NULL) && (nl->nl_count > 1)) { LOG_FMT(LCMTIND, "rule 2 - level 0, nl before\n"); pc->column = 1; return; } } prev = chunk_get_prev(nl); if (chunk_is_comment(prev) && (nl->nl_count == 1)) { int coldiff = prev->orig_col - pc->orig_col; if ((coldiff <= 3) && (coldiff >= -3)) { pc->column = prev->column; LOG_FMT(LCMTIND, "rule 3 - prev comment, coldiff = %d, now in %d\n", coldiff, pc->column); return; } } /* check if special single line comment rule applies */ if (cpd.settings[UO_indent_sing_line_comments].n > 0 && single_line_comment_indent_rule_applies(pc)) { pc->column = col + cpd.settings[UO_indent_sing_line_comments].n; LOG_FMT(LCMTIND, "rule 4 - single line comment indent, now in %d\n", pc->column); return; } LOG_FMT(LCMTIND, "rule 5 - fall-through, stay in %d\n", col); pc->column = col; }
static chunk_t *align_func_param(chunk_t *start) { AlignStack as; chunk_t *pc = start; as.Start(2, 0); 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; bool did_this_line = false; int comma_count = 0; int chunk_count = 0; while ((pc = chunk_get_next(pc)) != NULL) { chunk_count++; if (chunk_is_newline(pc)) { did_this_line = false; comma_count = 0; chunk_count = 0; } else if (pc->level <= start->level) { break; } else if (!did_this_line && (pc->flags & PCF_VAR_DEF)) { if (chunk_count > 1) { as.Add(pc); } did_this_line = true; } else if (comma_count > 0) { if (!chunk_is_comment(pc)) { comma_count = 2; break; } } else if (pc->type == CT_COMMA) { comma_count++; } } if (comma_count <= 1) { as.End(); } return(pc); }
/** * Gets the prev non-comment chunk */ chunk_t *chunk_get_prev_nc(chunk_t *cur, chunk_nav_t nav) { chunk_t *pc = cur; do { pc = chunk_get_prev(pc, nav); } while ((pc != NULL) && chunk_is_comment(pc)); return(pc); }
/** * Gets the next non-NEWLINE and non-comment chunk */ chunk_t *chunk_get_next_ncnl(chunk_t *cur, chunk_nav_t nav) { chunk_t *pc = cur; do { pc = chunk_get_next(pc, nav); } while ((pc != NULL) && (chunk_is_comment(pc) || chunk_is_newline(pc))); return(pc); }
/** * Gets the prev non-blank chunk */ chunk_t *chunk_get_prev_nblank(chunk_t *cur, chunk_nav_t nav) { chunk_t *pc = cur; do { pc = chunk_get_prev(pc, nav); } while ((pc != NULL) && (chunk_is_comment(pc) || chunk_is_newline(pc) || chunk_is_blank(pc))); return(pc); }
/** * Gets the prev non-NEWLINE and non-comment chunk, non-preprocessor chunk */ chunk_t *chunk_get_prev_ncnlnp(chunk_t *cur, chunk_nav_t nav) { chunk_t *pc = cur; if (chunk_is_preproc(cur)) { do { pc = chunk_get_prev(pc, nav); } while ((pc != NULL) && chunk_is_preproc(pc) && (chunk_is_comment(pc) || chunk_is_newline(pc))); } else { do { pc = chunk_get_prev(pc, nav); } while ((pc != NULL) && (chunk_is_comment(pc) || chunk_is_newline(pc) || chunk_is_preproc(pc))); } return(pc); }
/** * Step forward until a token goes beyond the limit and then call split_line() * to split the line at or before that point. */ void do_code_width(void) { chunk_t *pc; LOG_FMT(LSPLIT, "%s\n", __func__); for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc)) { if (!chunk_is_newline(pc) && !chunk_is_comment(pc) && (pc->type != CT_SPACE) && is_past_width(pc)) { split_line(pc); } } }
/** * Converts a single virtual brace into a brace */ static void convert_vbrace(chunk_t *vbr) { if (vbr == NULL) { return; } else if (vbr->type == CT_VBRACE_OPEN) { vbr->type = CT_BRACE_OPEN; vbr->len = 1; vbr->str = "{"; /* If the next chunk is a preprocessor, then move the open brace after the * preprocessor. */ chunk_t *tmp = chunk_get_next(vbr); if ((tmp != NULL) && (tmp->type == CT_PREPROC)) { tmp = chunk_get_next(vbr, CNAV_PREPROC); chunk_move_after(vbr, tmp); newline_add_after(vbr); } } else if (vbr->type == CT_VBRACE_CLOSE) { vbr->type = CT_BRACE_CLOSE; vbr->len = 1; vbr->str = "}"; /* If the next chunk is a comment, followed by a newline, then * move the brace after the newline and add another newline after * the close brace. */ chunk_t *tmp = chunk_get_next(vbr); if (chunk_is_comment(tmp)) { tmp = chunk_get_next(tmp); if (chunk_is_newline(tmp)) { chunk_move_after(vbr, tmp); newline_add_after(vbr); } } } }
/** * Changes the initial indent for a line to the given column * * @param pc The chunk at the start of the line * @param column The desired column */ void reindent_line(chunk_t *pc, int column) { int col_delta; int min_col; LOG_FMT(LINDLINE, "%s: %d] col %d on %.*s [%s] => %d\n", __func__, pc->orig_line, pc->column, pc->len, pc->str, get_token_name(pc->type), column); if (column == pc->column) return; col_delta = column - pc->column; pc->column = column; min_col = pc->column; do { min_col += pc->len; pc = chunk_get_next(pc); if (pc != NULL) { if (chunk_is_comment(pc)) { pc->column = pc->orig_col; if (pc->column < min_col) pc->column = min_col + 1; LOG_FMT(LINDLINE, "%s: set comment on line %d to col %d (orig %d)\n", __func__, pc->orig_line, pc->column, pc->orig_col); } else { pc->column += col_delta; if (pc->column < min_col) pc->column = min_col; } } } while ((pc != NULL) && (pc->nl_count == 0)); }
void pawn_add_virtual_semicolons(void) { LOG_FUNC_ENTRY(); chunk_t *prev; chunk_t *pc; /** Add Pawn virtual semicolons */ prev = NULL; if (cpd.lang_flags & LANG_PAWN) { pc = chunk_get_head(); while ((pc = chunk_get_next(pc)) != NULL) { if (!chunk_is_comment(pc) && !chunk_is_newline(pc) && (pc->type != CT_VBRACE_CLOSE) && (pc->type != CT_VBRACE_OPEN)) { prev = pc; } if ((prev == NULL) || ((pc->type != CT_NEWLINE) && (pc->type != CT_BRACE_CLOSE) && (pc->type != CT_VBRACE_CLOSE))) { continue; } /* we just hit a newline and we have a previous token */ if (((prev->flags & PCF_IN_PREPROC) == 0) && ((prev->flags & (PCF_IN_ENUM | PCF_IN_STRUCT)) == 0) && (prev->type != CT_VSEMICOLON) && (prev->type != CT_SEMICOLON) && !pawn_continued(prev, prev->brace_level)) { pawn_add_vsemi_after(prev); prev = NULL; } } } }
static void add_file_footer() { chunk_t *pc = chunk_get_tail(); /* Back up if the file ends with a newline */ if ((pc != NULL) && chunk_is_newline(pc)) { pc = chunk_get_prev(pc); } if ((pc != NULL) && (!chunk_is_comment(pc) || !chunk_is_newline(chunk_get_prev(pc)))) { pc = chunk_get_tail(); if (!chunk_is_newline(pc)) { LOG_FMT(LSYS, "Adding a newline at the end of the file\n"); newline_add_after(pc); } tokenize(cpd.file_ftr.data, NULL); } }
/** * Step forward until a token goes beyond the limit and then call split_line() * to split the line at or before that point. */ void do_code_width(void) { LOG_FUNC_ENTRY(); chunk_t *pc; LOG_FMT(LSPLIT, "%s\n", __func__); for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc)) { if (!chunk_is_newline(pc) && !chunk_is_comment(pc) && (pc->type != CT_SPACE) && is_past_width(pc)) { if (!split_line(pc)) { LOG_FMT(LSPLIT, "%s: Bailed on %lu:%lu %s\n", __func__, pc->orig_line, pc->orig_col, pc->text()); break; } } } }
static bool single_line_comment_indent_rule_applies(chunk_t *start) { chunk_t *pc = start; int nl_count = 0; if (!chunk_is_single_line_comment(pc)) return false; /* scan forward, if only single newlines and comments before next line of code, we want to apply */ while ((pc = chunk_get_next(pc)) != NULL) { if (chunk_is_newline(pc)) { if (nl_count > 0 || pc->nl_count > 1) return false; nl_count++; } else { nl_count = 0; if (!chunk_is_single_line_comment(pc)) { /* here we check for things to run into that we wouldn't want to indent the comment for */ /* for example, non-single line comment, closing brace */ if (chunk_is_comment(pc) || chunk_is_closing_brace(pc)) return false; return true; } } } return false; }