diff options
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/cpp/output.cpp')
-rw-r--r-- | debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/cpp/output.cpp | 657 |
1 files changed, 657 insertions, 0 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/cpp/output.cpp b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/cpp/output.cpp new file mode 100644 index 00000000..4563c43b --- /dev/null +++ b/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/tests/input/cpp/output.cpp @@ -0,0 +1,657 @@ +/** + * @file output.cpp + * Does all the output & comment formatting. + * + * $Id: output.cpp 510 2006-09-20 01:14:56Z bengardner $ + */ + +#include "uncrustify_types.h" +#include "prototypes.h" +#include "chunk_list.h" +#include <cstring> +#include <cstdlib> + + + +void add_char(char ch) +{ + /* convert a newline into the LF/CRLF/CR sequence */ + if (ch == '\n') + { + fputs(cpd.newline, cpd.fout); + cpd.column = 1; + cpd.did_newline = 1; + } + else + { + fputc(ch, cpd.fout); + if (ch == '\t') + { + cpd.column = next_tab_column(cpd.column); + } + else + { + cpd.column++; + } + } +} + +void add_text(const char *text) +{ + char ch; + + while ((ch = *text) != 0) + { + text++; + add_char(ch); + } +} + +void add_text_len(const char *text, int len) +{ + while (len-- > 0) + { + add_char(*text); + text++; + } +} + + +/** + * Advance to a specific column + * cpd.column is the current column + * + * @param column The column to advance to + */ +void output_to_column(int column, bool allow_tabs) +{ + int nc; + + cpd.did_newline = 0; + if (allow_tabs) + { + /* tab out as far as possible and then use spaces */ + while ((nc = next_tab_column(cpd.column)) <= column) + { + add_text("\t"); + } + } + /* space out the final bit */ + while (cpd.column < column) + { + add_text(" "); + } +} + +void output_indent(int column, int brace_col) +{ + if ((cpd.column == 1) && (cpd.settings[UO_indent_with_tabs].n != 0)) + { + if (cpd.settings[UO_indent_with_tabs].n == 2) + { + brace_col = column; + } + + /* tab out as far as possible and then use spaces */ + int nc; + while ((nc = next_tab_column(cpd.column)) <= brace_col) + { + add_text("\t"); + } + } + + /* space out the rest */ + while (cpd.column < column) + { + add_text(" "); + } +} + + + +void output_parsed(FILE *pfile) +{ + chunk_t *pc; + int cnt; + + output_options(pfile); + output_defines(pfile); + output_types(pfile); + + fprintf(pfile, "-=====-\n"); + fprintf(pfile, "Line Tag Parent Columns Br/Lvl/pp Flg Nl Text"); + for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc)) + { + fprintf(pfile, "\n%3d> %13.13s[%13.13s][%2d/%2d/%2d][%d/%d/%d][%6x][%d-%d]", + pc->orig_line, get_token_name(pc->type), + get_token_name(pc->parent_type), + pc->column, pc->orig_col, pc->orig_col_end, + pc->brace_level, pc->level, pc->pp_level, + pc->flags, pc->nl_count, pc->after_tab); + + if ((pc->type != CT_NEWLINE) && (pc->len != 0)) + { + for (cnt = 0; cnt < pc->column; cnt++) + { + fprintf(pfile, " "); + } + fprintf(pfile, "%.*s", pc->len, pc->str); + } + } + fprintf(pfile, "\n-=====-\n"); + fflush(pfile); +} + +void output_options(FILE *pfile) +{ + int idx; + const option_map_value *ptr; + + fprintf(pfile, "-== Options ==-\n"); + for (idx = 0; idx < UO_option_count; idx++) + { + ptr = get_option_name(idx); + if (ptr != NULL) + { + if (ptr->type == AT_BOOL) + { + fprintf(pfile, "%3d) %32s = %s\n", + ptr->id, ptr->name, + cpd.settings[ptr->id].b ? "True" : "False"); + } + else if (ptr->type == AT_IARF) + { + fprintf(pfile, "%3d) %32s = %s\n", + ptr->id, ptr->name, + (cpd.settings[ptr->id].a == AV_ADD) ? "Add" : + (cpd.settings[ptr->id].a == AV_REMOVE) ? "Remove" : + (cpd.settings[ptr->id].a == AV_FORCE) ? "Force" : "Ignore"); + } + else if (ptr->type == AT_LINE) + { + fprintf(pfile, "%3d) %32s = %s\n", + ptr->id, ptr->name, + (cpd.settings[ptr->id].le == LE_AUTO) ? "Auto" : + (cpd.settings[ptr->id].le == LE_LF) ? "LF" : + (cpd.settings[ptr->id].le == LE_CRLF) ? "CRLF" : + (cpd.settings[ptr->id].le == LE_CR) ? "CR" : "???"); + } + else /* AT_NUM */ + { + fprintf(pfile, "%3d) %32s = %d\n", + ptr->id, ptr->name, cpd.settings[ptr->id].n); + } + } + } +} + +/** + * This renders the chunk list to a file. + */ +void output_text(FILE *pfile) +{ + chunk_t *pc; + chunk_t *prev; + int cnt; + int lvlcol; + bool allow_tabs; + + cpd.fout = pfile; + + for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc)) + { + if (pc->type == CT_NEWLINE) + { + for (cnt = 0; cnt < pc->nl_count; cnt++) + { + add_char('\n'); + } + cpd.did_newline = 1; + cpd.column = 1; + LOG_FMT(LOUTIND, " xx\n"); + } + else if (pc->type == CT_COMMENT_MULTI) + { + output_comment_multi(pc); + } + else if (pc->type == CT_COMMENT_CPP) + { + pc = output_comment_cpp(pc); + } + else if (pc->len == 0) + { + /* don't do anything for non-visible stuff */ + LOG_FMT(LOUTIND, " <%d> -", pc->column); + } + else + { + /* indent to the 'level' first */ + if (cpd.did_newline) + { + if (cpd.settings[UO_indent_with_tabs].n == 1) + { + lvlcol = 1 + (pc->brace_level * cpd.settings[UO_indent_columns].n); + if ((pc->column >= lvlcol) && (lvlcol > 1)) + { + output_to_column(lvlcol, true); + } + } + allow_tabs = (cpd.settings[UO_indent_with_tabs].n == 2) || + (chunk_is_comment(pc) && + (cpd.settings[UO_indent_with_tabs].n != 0)); + + LOG_FMT(LOUTIND, " %d> col %d/%d - ", pc->orig_line, pc->column, cpd.column); + } + else + { + /* not the first item on a line */ + if (cpd.settings[UO_align_keep_tabs].b) + { + allow_tabs = pc->after_tab; + } + else + { + prev = chunk_get_prev(pc); + allow_tabs = (cpd.settings[UO_align_with_tabs].b && + ((pc->flags & PCF_WAS_ALIGNED) != 0) && + (((pc->column - 1) % cpd.settings[UO_output_tab_size].n) == 0) && + ((prev->column + prev->len + 1) != pc->column)); + } + LOG_FMT(LOUTIND, " %d -", pc->column); + } + + output_to_column(pc->column, allow_tabs); + add_text_len(pc->str, pc->len); + cpd.did_newline = chunk_is_newline(pc); + } + } +} + + +/** + * Given a multi-line comemnt block that starts in column X, figure out how + * much subsequent lines should be indented. + * + * The answer is either 0 or 1. + * + * The decision is based on: + * - the first line length + * - the second line leader length + * - the last line length + * + * If the first and last line are the same length and don't contain any alnum + * chars and (the first line len > 2 or the second leader is the same as the + * first line length), then the indent is 0. + * + * If the leader on the second line is 1 wide or missing, then the indent is 1. + * + * Otherwise, the indent is 0. + * + * @param str The comment string + * @param len Length of the comment + * @param start_col Starting column + * @return 0 or 1 + */ +static int calculate_comment_body_indent(const char *str, int len, int start_col) +{ + int idx = 0; + int first_len = 0; + int last_len = 0; + int width = 0; + + /* find the last line length */ + for (idx = len - 1; idx > 0; idx--) + { + if ((str[idx] == '\n') || (str[idx] == '\r')) + { + idx++; + while ((idx < len) && ((str[idx] == ' ') || (str[idx] == '\t'))) + { + idx++; + } + last_len = len - idx; + break; + } + } + + /* find the first line length */ + for (idx = 0; idx < len; idx++) + { + if ((str[idx] == '\n') || (str[idx] == '\r')) + { + first_len = idx; + while ((str[first_len - 1] == ' ') || (str[first_len - 1] == '\t')) + { + first_len--; + } + + /* handle DOS endings */ + if ((str[idx] == '\r') && (str[idx + 1] == '\n')) + { + idx++; + } + idx++; + break; + } + } + + /* Scan the second line */ + width = 0; + for ( /* nada */; idx < len; idx++) + { + if ((str[idx] == ' ') || (str[idx] == '\t')) + { + if (width > 0) + { + break; + } + continue; + } + if ((str[idx] == '\n') || (str[idx] == '\r')) + { + /* Done with second line */ + break; + } + + /* Count the leading chars */ + if ((str[idx] == '*') || + (str[idx] == '|') || + (str[idx] == '\\') || + (str[idx] == '#') || + (str[idx] == '+')) + { + width++; + } + else + { + break; + } + } + + //LOG_FMT(LSYS, "%s: first=%d last=%d width=%d\n", __func__, first_len, last_len, width); + + /*TODO: make the first_len minimum (4) configurable? */ + if ((first_len == last_len) && ((first_len > 4) || first_len == width)) + { + return(0); + } + + return((width == 2) ? 0 : 1); +} + +/** + * Outputs the CPP comment at pc. + * CPP comment combining is done here + * + * @return the last chunk output'd + */ +chunk_t *output_comment_cpp(chunk_t *first) +{ + int col = first->column; + int col_br = 1 + (first->brace_level * cpd.settings[UO_indent_columns].n); + + /* Make sure we have at least one space past the last token */ + if (first->parent_type == CT_COMMENT_END) + { + chunk_t *prev = chunk_get_prev(first); + if (prev != NULL) + { + int col_min = prev->column + prev->len + 1; + if (col < col_min) + { + col = col_min; + } + } + } + + /* Bump out to the column */ + output_indent(col, col_br); + + if (!cpd.settings[UO_cmt_cpp_to_c].b) + { + add_text_len(first->str, first->len); + return(first); + } + + /* If we are grouping, see if there is something to group */ + bool combined = false; + if (cpd.settings[UO_cmt_cpp_group].b) + { + /* next is a newline by definition */ + chunk_t *next = chunk_get_next(first); + if ((next != NULL) && (next->nl_count == 1)) + { + next = chunk_get_next(next); + + /** + * Only combine the next comment if they are both at indent level or + * the second one is NOT at indent or less + * + * A trailing comment cannot be combined with a comment at indent + * level or less + */ + if ((next != NULL) && + (next->type == CT_COMMENT_CPP) && + (((next->column == 1) && (first->column == 1)) || + ((next->column == col_br) && (first->column == col_br)) || + ((next->column > col_br) && (first->parent_type == CT_COMMENT_END)))) + { + combined = true; + } + } + } + + if (!combined) + { + /* nothing to group: just output a single line */ + add_text_len("/*", 2); + if ((first->str[2] != ' ') && (first->str[2] != '\t')) + { + add_char(' '); + } + add_text_len(&first->str[2], first->len - 2); + add_text_len(" */", 3); + return(first); + } + + chunk_t *pc = first; + chunk_t *last = first; + + /* Output the first line */ + add_text_len("/*", 2); + if (combined && cpd.settings[UO_cmt_cpp_nl_start].b) + { + /* I suppose someone more clever could do this without a goto or + * repeating too much code... + */ + goto cpp_newline; + } + goto cpp_addline; + + /* Output combined lines */ + while ((pc = chunk_get_next(pc)) != NULL) + { + if ((pc->type == CT_NEWLINE) && (pc->nl_count == 1)) + { + continue; + } + if (pc->type != CT_COMMENT_CPP) + { + break; + } + if (((pc->column == 1) && (first->column == 1)) || + ((pc->column == col_br) && (first->column == col_br)) || + ((pc->column > col_br) && (first->parent_type == CT_COMMENT_END))) + { + last = pc; +cpp_newline: + add_char('\n'); + output_indent(col, col_br); + add_char(' '); + add_char(cpd.settings[UO_cmt_star_cont].b ? '*' : ' '); +cpp_addline: + if ((pc->str[2] != ' ') && (pc->str[2] != '\t')) + { + add_char(' '); + } + add_text_len(&pc->str[2], pc->len - 2); + } + } + + if (cpd.settings[UO_cmt_cpp_nl_end].b) + { + add_char('\n'); + output_indent(col, col_br); + } + add_text_len(" */", 3); + return(last); +} + +void output_comment_multi(chunk_t *pc) +{ + int cmt_col = pc->column; + const char *cmt_str; + int remaining; + char ch; + chunk_t *prev; + char line[1024]; + int line_len; + int line_count = 0; + int ccol; + int col_diff = 0; + int xtra = 1; + + prev = chunk_get_prev(pc); + if ((prev != NULL) && (prev->type != CT_NEWLINE)) + { + cmt_col = pc->orig_col; + } + else + { + col_diff = pc->orig_col - pc->column; + } + + // fprintf(stderr, "Indenting1 line %d to col %d (orig=%d) col_diff=%d\n", + // pc->orig_line, cmt_col, pc->orig_col, col_diff); + + xtra = calculate_comment_body_indent(pc->str, pc->len, pc->column); + + ccol = 1; + remaining = pc->len; + cmt_str = pc->str; + line_len = 0; + while (remaining > 0) + { + ch = *cmt_str; + cmt_str++; + remaining--; + + /* handle the CRLF and CR endings. convert both to LF */ + if (ch == '\r') + { + ch = '\n'; + if (*cmt_str == '\n') + { + cmt_str++; + remaining--; + } + } + + /* Find the start column */ + if (line_len == 0) + { + if (ch == ' ') + { + ccol++; + continue; + } + else if (ch == '\t') + { + ccol = calc_next_tab_column(ccol, cpd.settings[UO_input_tab_size].n); + continue; + } + else + { + //fprintf(stderr, "%d] Text starts in col %d\n", line_count, ccol); + } + } + + line[line_len++] = ch; + + /* If we just hit an end of line OR we just hit end-of-comment... */ + if ((ch == '\n') || (remaining == 0)) + { + line_count++; + + /* strip trailing tabs and spaces before the newline */ + if (ch == '\n') + { + line_len--; + while ((line_len > 0) && + ((line[line_len - 1] == ' ') || + (line[line_len - 1] == '\t'))) + { + line_len--; + } + line[line_len++] = ch; + } + line[line_len] = 0; + + if (line_count == 1) + { + /* this is the first line - add unchanged */ + + /*TODO: need to support indent_with_tabs mode 1 */ + output_to_column(cmt_col, cpd.settings[UO_indent_with_tabs].b); + add_text_len(line, line_len); + } + else + { + /* This is not the first line, so we need to indent to the + * correct column. + */ + ccol -= col_diff; + if (ccol < cmt_col) + { + ccol = cmt_col; + } + + if (line[0] == '\n') + { + /* Emtpy line - just a '\n' */ + if (cpd.settings[UO_cmt_star_cont].b) + { + output_to_column(cmt_col, cpd.settings[UO_indent_with_tabs].b); + add_text((xtra == 1) ? " *" : "*"); + } + add_char('\n'); + } + else + { + /* If this doesn't start with a '*' or '|' */ + if ((line[0] != '*') && (line[0] != '|') && (line[0] != '#') && + (line[0] != '\\') && (line[0] != '+')) + { + output_to_column(cmt_col, cpd.settings[UO_indent_with_tabs].b); + if (cpd.settings[UO_cmt_star_cont].b) + { + add_text((xtra == 1) ? " * " : "* "); + } + else + { + add_text(" "); + } + output_to_column(ccol, cpd.settings[UO_indent_with_tabs].b); + } + else + { + output_to_column(cmt_col + xtra, cpd.settings[UO_indent_with_tabs].b); + } + add_text_len(line, line_len); + } + } + line_len = 0; + ccol = 1; + } + } +} |