void chunk_move_after(chunk_t *pc_in, chunk_t *ref) { g_cl.Pop(pc_in); g_cl.AddAfter(pc_in, ref); /* HACK: Adjust the original column */ pc_in->column = ref->column + space_col_align(ref, pc_in); pc_in->orig_col = pc_in->column; pc_in->orig_col_end = pc_in->orig_col + pc_in->len(); }
void chunk_move_after(chunk_t *pc_in, chunk_t *ref) { LOG_FUNC_ENTRY(); g_cl.Pop(pc_in); g_cl.AddAfter(pc_in, ref); // HACK: Adjust the original column pc_in->column = ref->column + space_col_align(ref, pc_in); pc_in->orig_col = static_cast<UINT32>(pc_in->column); pc_in->orig_col_end = pc_in->orig_col + pc_in->len(); }
/** * Adds an entry to the appropriate stack. * * @param pc The chunk * @param seqnum Optional seqnum (0=assign one) */ void AlignStack::Add(chunk_t *start, int seqnum) { /* Assign a seqnum if needed */ if (seqnum == 0) { seqnum = m_seqnum; } chunk_t *ali; chunk_t *ref; chunk_t *tmp; chunk_t *prev; chunk_t *next; int col_adj = 0; /* Amount the column is shifted for 'dangle' mode */ int tmp_col; int endcol; int gap; m_last_added = 0; /* Check threshold limits */ if ((m_max_col == 0) || (m_thresh == 0) || (((start->column + m_gap) <= (m_max_col + m_thresh)) && (((start->column + m_gap) >= (m_max_col - m_thresh)) || (start->column >= m_min_col)))) { /* we are adding it, so update the newline seqnum */ if (seqnum > m_nl_seqnum) { m_nl_seqnum = seqnum; } /** * SS_IGNORE: no special handling of '*' or '&', only 'foo' is aligned * void foo; // gap=5, 'foo' is aligned * char * foo; // gap=3, 'foo' is aligned * foomatic foo; // gap=1, 'foo' is aligned * The gap is the columns between 'foo' and the previous token. * [void - foo], ['*' - foo], etc * * SS_INCLUDE: - space between variable and '*' or '&' is eaten * void foo; // gap=5, 'foo' is aligned * char *foo; // gap=5, '*' is aligned * foomatic foo; // gap=1, 'foo' is aligned * The gap is the columns between the first '*' or '&' before foo * and the previous token. [void - foo], [char - '*'], etc * * SS_DANGLE: - space between variable and '*' or '&' is eaten * void foo; // gap=5 * char *bar; // gap=5, as the '*' doesn't count * foomatic foo; // gap=1 * The gap is the columns between 'foo' and the chunk before the first * '*' or '&'. [void - foo], [char - bar], etc * * If the gap < m_gap, then the column is bumped out by the difference. * So, if m_gap is 2, then the above would be: * SS_IGNORE: * void foo; // gap=6 * char * foo; // gap=4 * foomatic foo; // gap=2 * SS_INCLUDE: * void foo; // gap=6 * char *foo; // gap=6 * foomatic foo; // gap=2 * SS_DANGLE: * void foo; // gap=6 * char *bar; // gap=6, as the '*' doesn't count * foomatic foo; // gap=2 * Right aligned numbers: * #define A -1 * #define B 631 * #define C 3 * Left aligned numbers: * #define A -1 * #define B 631 * #define C 3 * * In the code below, pc is set to the item that is aligned. * In the above examples, that is 'foo', '*', '-', or 63. * * Ref is set to the last part of the type. * In the above examples, that is 'void', 'char', 'foomatic', 'A', or 'B'. * * The '*' and '&' can float between the two. * * If align_on_tabstop=true, then SS_DANGLE is changed to SS_INCLUDE. */ if (cpd.settings[UO_align_on_tabstop].b && (m_star_style == SS_DANGLE)) { m_star_style = SS_INCLUDE; } /* Find ref. Back up to the real item that is aligned. */ prev = start; while (((prev = chunk_get_prev(prev)) != NULL) && (chunk_is_star(prev) || chunk_is_addr(prev) || (prev->type == CT_TPAREN_OPEN))) { /* do nothing - we want prev when this exits */ } ref = prev; if (chunk_is_newline(ref)) { ref = chunk_get_next(ref); } /* Find the item that we are going to align. */ ali = start; if (m_star_style != SS_IGNORE) { /* back up to the first '*' preceding the token */ prev = chunk_get_prev(ali); while (chunk_is_star(prev)) { ali = prev; prev = chunk_get_prev(ali); } if (chunk_is_token(prev, CT_TPAREN_OPEN)) { ali = prev; prev = chunk_get_prev(ali); } } if (m_amp_style != SS_IGNORE) { /* back up to the first '&' preceding the token */ prev = chunk_get_prev(ali); while (chunk_is_addr(prev)) { ali = prev; prev = chunk_get_prev(ali); } } /* Tighten down the spacing between ref and start */ if (!cpd.settings[UO_align_keep_extra_space].b) { tmp_col = ref->column; tmp = ref; while (tmp != start) { next = chunk_get_next(tmp); tmp_col += space_col_align(tmp, next); if (next->column != tmp_col) { align_to_column(next, tmp_col); } tmp = next; } } /* Set the column adjust and gap */ col_adj = 0; gap = 0; if (ref != ali) { gap = ali->column - (ref->column + ref->len()); } tmp = ali; if (chunk_is_token(tmp, CT_TPAREN_OPEN)) { tmp = chunk_get_next(tmp); } if ((chunk_is_star(tmp) && (m_star_style == SS_DANGLE)) || (chunk_is_addr(tmp) && (m_amp_style == SS_DANGLE))) { col_adj = start->column - ali->column; gap = start->column - (ref->column + ref->len()); } /* See if this pushes out the max_col */ endcol = ali->column + col_adj; if (gap < m_gap) { endcol += m_gap - gap; } // LOG_FMT(LSYS, "[%p] line %d pc='%s' [%s] col:%d ali='%s' [%s] col:%d ref='%s' [%s] col:%d col_adj=%d endcol=%d, ss=%d as=%d, gap=%d\n", // this, // start->orig_line, // start->str.c_str(), get_token_name(start->type), start->column, // ali->str.c_str(), get_token_name(ali->type), ali->column, // ref->str.c_str(), get_token_name(ref->type), ref->column, // col_adj, endcol, m_star_style, m_amp_style, gap); ali->align.col_adj = col_adj; ali->align.ref = ref; ali->align.start = start; m_aligned.Push_Back(ali, seqnum); m_last_added = 1; LOG_FMT(LAS, "Add-[%s]: line %d, col %d, adj %d : ref=[%s] endcol=%d\n", ali->str.c_str(), ali->orig_line, ali->column, ali->align.col_adj, ref->str.c_str(), endcol); if (m_min_col > endcol) { m_min_col = endcol; } if (endcol > m_max_col) { LOG_FMT(LAS, "Add-aligned [%d/%d/%d]: line %d, col %d : max_col old %d, new %d - min_col %d\n", seqnum, m_nl_seqnum, m_seqnum, ali->orig_line, ali->column, m_max_col, endcol, m_min_col); m_max_col = endcol; /** * If there were any entries that were skipped, re-add them as they * may now be within the threshold */ if (!m_skipped.Empty()) { ReAddSkipped(); } } else { LOG_FMT(LAS, "Add-aligned [%d/%d/%d]: line %d, col %d : col %d <= %d - min_col %d\n", seqnum, m_nl_seqnum, m_seqnum, ali->orig_line, ali->column, endcol, m_max_col, m_min_col); } } else { /* The threshold check failed, so add it to the skipped list */ m_skipped.Push_Back(start, seqnum); m_last_added = 2; LOG_FMT(LAS, "Add-skipped [%d/%d/%d]: line %d, col %d <= %d + %d\n", seqnum, m_nl_seqnum, m_seqnum, start->orig_line, start->column, m_max_col, m_thresh); } }
/** * 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); }