/** * Calculates the column difference between two chunks. * The rules are bent a bit here, as AV_IGNORE and AV_ADD become AV_FORCE. * So the column difference is either first->len or first->len + 1. * * @param first The first chunk * @param second The second chunk * @return the column difference between the two chunks */ int space_col_align(chunk_t *first, chunk_t *second) { int coldiff; argval_t av; av = do_space(first, second); coldiff = first->len; switch (av) { case AV_ADD: case AV_FORCE: coldiff++; break; case AV_REMOVE: break; case AV_IGNORE: if (second->orig_col > (first->orig_col + first->len)) { coldiff++; } break; } return(coldiff); }
static void handle_block(char *s,int size) { expr *cnt,*fill=0; cnt = parse_expr_tmplab(&s); s = skip(s); if (*s == ',') { s = skip(s+1); fill = parse_expr_tmplab(&s); } do_space(size,cnt,fill); eol(s); }
/** * Determines if a space is required between two chunks */ bool space_needed(chunk_t *first, chunk_t *second) { switch (do_space(first, second)) { case AV_ADD: case AV_FORCE: return(true); case AV_REMOVE: return(false); case AV_IGNORE: default: return(second->orig_col > (first->orig_col + first->len)); } }
/** * Determines if a space is required between two chunks */ int space_needed(chunk_t *first, chunk_t *second) { int min_sp; switch (do_space(first, second, min_sp)) { case AV_ADD: case AV_FORCE: return(max(1, min_sp)); case AV_REMOVE: return(0); case AV_IGNORE: default: return(second->orig_col > (first->orig_col + first->len())); } }
/** * Marches through the whole file and checks to see how many spaces should be * between two chunks */ void space_text(void) { chunk_t *pc; chunk_t *next; chunk_t *tmp; int column, prev_column; int delta; pc = chunk_get_head(); if (pc == NULL) { return; } column = pc->column; while (pc != NULL) { next = chunk_get_next(pc); if (next == NULL) { break; } /* If the current chunk contains a newline, do not change the column * of the next item */ if ((pc->type == CT_NEWLINE) || (pc->type == CT_NL_CONT) || (pc->type == CT_COMMENT_MULTI)) { column = next->column; } else { /* Set to the minimum allowed column */ if (pc->nl_count == 0) { column += pc->len; } else { column = pc->orig_col_end; } prev_column = column; /** * Apply a general safety check * If the two chunks combined will tokenize differently, then we * must force a space. * Two chunks -- "()" and "[]" will always tokenize differently. * They are always safe to not have a space after them. */ pc->flags &= ~PCF_FORCE_SPACE; if ((pc->len > 0) && !chunk_is_str(pc, "[]", 2) && !chunk_is_str(pc, "()", 2)) { /* Find the next non-empty chunk on this line */ tmp = next; while ((tmp != NULL) && (tmp->len == 0) && !chunk_is_newline(tmp)) { tmp = chunk_get_next(tmp); } if ((tmp != NULL) && (tmp->len > 0)) { bool kw1 = CharTable::IsKw2(pc->str[pc->len - 1]); bool kw2 = CharTable::IsKw1(next->str[0]); if (kw1 && kw2) { /* back-to-back words need a space */ pc->flags |= PCF_FORCE_SPACE; } else if (!kw1 && !kw2 && (pc->len < 4) && (next->len < 4)) { /* We aren't dealing with keywords. concat and try punctuators */ char buf[9]; memcpy(buf, pc->str, pc->len); memcpy(buf + pc->len, next->str, next->len); buf[pc->len + next->len] = 0; const chunk_tag_t *ct; ct = find_punctuator(buf, cpd.lang_flags); if ((ct != NULL) && ((int)strlen(ct->tag) != pc->len)) { /* punctuator parsed to a different size.. */ pc->flags |= PCF_FORCE_SPACE; } } } } int av = do_space(pc, next, false); if (pc->flags & PCF_FORCE_SPACE) { av |= AV_ADD; } switch (av) { case AV_FORCE: /* add exactly one space */ column++; break; case AV_ADD: delta = 1; if ((next->orig_col >= pc->orig_col_end) && (pc->orig_col_end != 0)) { /* Keep the same relative spacing, minimum 1 */ delta = next->orig_col - pc->orig_col_end; if (delta < 1) { delta = 1; } } column += delta; break; case AV_REMOVE: /* the symbols will be back-to-back "a+3" */ break; default: /* Keep the same relative spacing, if possible */ if ((next->orig_col >= pc->orig_col_end) && (pc->orig_col_end != 0)) { column += next->orig_col - pc->orig_col_end; } break; } if (chunk_is_comment(next) && chunk_is_newline(chunk_get_next(next)) && (column < (int)next->orig_col)) { if ((cpd.settings[UO_sp_endif_cmt].a == AV_IGNORE) || ((pc->type != CT_PP_ELSE) && (pc->type != CT_PP_ENDIF))) { if (cpd.settings[UO_indent_relative_single_line_comments].b) { column = pc->column + (next->orig_col - pc->orig_col_end); } else { column = next->orig_col; } } } next->column = column; LOG_FMT(LSPACE, " = %s @ %d\n", (av == AV_IGNORE) ? "IGNORE" : (av == AV_ADD) ? "ADD" : (av == AV_ADD) ? "REMOVE" : "FORCE", column - prev_column); } pc = next; } }
static void handle_space(char *s,int size) { do_space(size,parse_expr_tmplab(&s),0); eol(s); }
int yylex() { for (;;) { int tk = get_token(1); switch(tk) { case UNDEF: do_undef(); break; case SDEFINE: do_definition(1); break; case DEFINE: do_definition(0); break; case TDEFINE: if (!nroff) do_definition(0); else ignore_definition(); break; case NDEFINE: if (nroff) do_definition(0); else ignore_definition(); break; case GSIZE: do_gsize(); break; case GFONT: do_gfont(); break; case GRFONT: do_grfont(); break; case GBFONT: do_gbfont(); break; case SPACE: do_space(); break; case INCLUDE: do_include(); break; case IFDEF: do_ifdef(); break; case DELIM: do_delim(); break; case CHARTYPE: do_chartype(); break; case SET: do_set(); break; case QUOTED_TEXT: case TEXT: token_buffer += '\0'; yylval.str = strsave(token_buffer.contents()); // fall through default: return tk; } } }
/** * Marches through the whole file and checks to see how many spaces should be * between two chunks */ void space_text(void) { chunk_t *pc; chunk_t *next; chunk_t *tmp; int column, prev_column; int delta; pc = chunk_get_head(); if (pc == NULL) { return; } column = pc->column; while (pc != NULL) { next = chunk_get_next(pc); if (next == NULL) { break; } /* If the current chunk contains a newline, do not change the column * of the next item */ if ((pc->type == CT_NEWLINE) || (pc->type == CT_NL_CONT) || (pc->type == CT_COMMENT_MULTI)) { column = next->column; } else { /* Set to the minimum allowed column */ if (pc->nl_count == 0) { column += pc->len(); } else { column = pc->orig_col_end; } prev_column = column; /** * Apply a general safety check * If the two chunks combined will tokenize differently, then we * must force a space. * Two chunks -- "()" and "[]" will always tokenize differently. * They are always safe to not have a space after them. */ pc->flags &= ~PCF_FORCE_SPACE; if ((pc->len() > 0) && !chunk_is_str(pc, "[]", 2) && !chunk_is_str(pc, "()", 2)) { /* Find the next non-empty chunk on this line */ tmp = next; while ((tmp != NULL) && (tmp->len() == 0) && !chunk_is_newline(tmp)) { tmp = chunk_get_next(tmp); } if ((tmp != NULL) && (tmp->len() > 0)) { bool kw1 = CharTable::IsKw2(pc->str[pc->len() - 1]); bool kw2 = CharTable::IsKw1(next->str[0]); if (kw1 && kw2) { /* back-to-back words need a space */ pc->flags |= PCF_FORCE_SPACE; } else if (!kw1 && !kw2 && (pc->len() < 4) && (next->len() < 4)) { /* We aren't dealing with keywords. concat and try punctuators */ char buf[9]; memcpy(buf, pc->text(), pc->len()); memcpy(buf + pc->len(), next->text(), next->len()); buf[pc->len() + next->len()] = 0; const chunk_tag_t *ct; ct = find_punctuator(buf, cpd.lang_flags); if ((ct != NULL) && ((int)strlen(ct->tag) != pc->len())) { /* punctuator parsed to a different size.. */ /* C++11 allows '>>' to mean '> >' in templates: * some_func<vector<string>>(); */ if ((cpd.lang_flags & LANG_CPP) && cpd.settings[UO_sp_permit_cpp11_shift].b && (pc->type == CT_ANGLE_CLOSE) && (next->type == CT_ANGLE_CLOSE)) { /* allow '>' and '>' to become '>>' */ } else if (strcmp(ct->tag, "[]") == 0) { /* this is OK */ } else { pc->flags |= PCF_FORCE_SPACE; } } } } } int min_sp; int av = do_space(pc, next, min_sp, false); if (pc->flags & PCF_FORCE_SPACE) { LOG_FMT(LSPACE, " <force between '%s' and '%s'>", pc->str.c_str(), next->str.c_str()); av |= AV_ADD; } min_sp = max(1, min_sp); switch (av) { case AV_FORCE: /* add exactly the specified # of spaces */ column += min_sp; break; case AV_ADD: delta = min_sp; if ((next->orig_col >= pc->orig_col_end) && (pc->orig_col_end != 0)) { /* Keep the same relative spacing, minimum 1 */ delta = next->orig_col - pc->orig_col_end; if (delta < min_sp) { delta = min_sp; } } column += delta; break; case AV_REMOVE: /* the symbols will be back-to-back "a+3" */ break; default: /* Keep the same relative spacing, if possible */ if ((next->orig_col >= pc->orig_col_end) && (pc->orig_col_end != 0)) { column += next->orig_col - pc->orig_col_end; } break; } if (chunk_is_comment(next) && chunk_is_newline(chunk_get_next(next)) && (column < (int)next->orig_col)) { if (((cpd.settings[UO_sp_before_tr_emb_cmt].a == AV_IGNORE) || ((next->parent_type != CT_COMMENT_END) && (next->parent_type != CT_COMMENT_EMBED))) && ((cpd.settings[UO_sp_endif_cmt].a == AV_IGNORE) || ((pc->type != CT_PP_ELSE) && (pc->type != CT_PP_ENDIF)))) { if (cpd.settings[UO_indent_relative_single_line_comments].b) { LOG_FMT(LSPACE, " <relative adj>"); column = pc->column + (next->orig_col - pc->orig_col_end); } else { LOG_FMT(LSPACE, " <relative set>"); column = next->orig_col; } } } next->column = column; LOG_FMT(LSPACE, " = %s @ %d\n", (av == AV_IGNORE) ? "IGNORE" : (av == AV_ADD) ? "ADD" : (av == AV_REMOVE) ? "REMOVE" : "FORCE", column - prev_column); } pc = next; } }