From 2672d55c0a0ee4d775e885cff2770e6057784c28 Mon Sep 17 00:00:00 2001 From: Thomas Jensen Date: Sat, 28 Oct 2023 21:16:44 +0200 Subject: [PATCH] Test and fix handling of line comment removal --- src/detect.c | 109 ++++++++++++-------- src/remove.c | 29 ++++-- test/186_remove_line_comments.txt | 28 +++++ test/187_remove_line_comments_killblank.txt | 21 ++++ 4 files changed, 135 insertions(+), 52 deletions(-) create mode 100644 test/186_remove_line_comments.txt create mode 100644 test/187_remove_line_comments_killblank.txt diff --git a/src/detect.c b/src/detect.c index 3d6e5bd7..df198a91 100644 --- a/src/detect.c +++ b/src/detect.c @@ -185,9 +185,16 @@ uint32_t *prepare_comp_shape( uint32_t *prepare_comp_input(size_t input_line_idx, int trim_left, comparison_t comp_type, size_t offset_right, size_t *out_indent, size_t *out_trailing) { + #ifdef DEBUG + fprintf(stderr, "prepare_comp_input(%d, %s, %s, %d, %p, %p)", (int) input_line_idx, + trim_left ? "true" : "false", comparison_name[comp_type], (int) offset_right, out_indent, out_trailing); + #endif if (input_line_idx >= input.num_lines) { bx_fprintf(stderr, "%s: prepare_comp_input(%d, %d, %s, %d): Index out of bounds\n", PROJECT, (int) input_line_idx, trim_left, comparison_name[comp_type], (int) offset_right); + #ifdef DEBUG + fprintf(stderr, " -> (null)\n"); + #endif return NULL; } bxstr_t *input_line = input.lines[input_line_idx].text; @@ -237,6 +244,11 @@ uint32_t *prepare_comp_input(size_t input_line_idx, int trim_left, comparison_t - input_line->first_char[input_line->num_chars_visible - input_line->trailing]; } } + #ifdef DEBUG + char *out_result = u32_strconv_to_output(result); + fprintf(stderr, " -> \"%s\"\n", out_result); + BFREE(out_result); + #endif return result; } @@ -305,6 +317,9 @@ static size_t find_east_corner(design_t *current_design, comparison_t comp_type, { size_t hits = 0; if (empty[BRIG] || (empty[BTOP] && corner == NE) || (empty[BBOT] && corner == SE)) { + #ifdef DEBUG + fprintf(stderr, "Checking %s corner produced %d hits.\n", shape_name[corner], (int) hits); + #endif return hits; } @@ -327,7 +342,7 @@ static size_t find_east_corner(design_t *current_design, comparison_t comp_type, } uint32_t *input_relevant = prepare_comp_input(a, 0, comp_type, length_relevant, NULL, NULL); - if (u32_strncmp(input_relevant, shape_relevant, length_relevant) == 0) { + if (input_relevant && (u32_strncmp(input_relevant, shape_relevant, length_relevant) == 0)) { ++hits; /* CHECK more hit points for longer matches, or simple boxes might match too easily */ } } @@ -355,7 +370,11 @@ static size_t find_horizontal_shape(design_t *current_design, comparison_t comp_ { size_t hits = 0; if (empty[BTOP] || empty[BBOT]) { - return 0; /* horizontal box part is empty */ + /* horizontal box part is empty */ + #ifdef DEBUG + fprintf(stderr, "Checking %-3s shape produced %d hits.\n", shape_name[hshape], (int) hits); + #endif + return hits; } for (size_t j = 0; j < current_design->shape[hshape].height; ++j) { @@ -398,7 +417,7 @@ static size_t find_horizontal_shape(design_t *current_design, comparison_t comp_ } #ifdef DEBUG - fprintf(stderr, "Checking %s shape produced %d hits.\n", shape_name[hshape], (int) hits); + fprintf(stderr, "Checking %-3s shape produced %d hits.\n", shape_name[hshape], (int) hits); #endif return hits; } @@ -419,36 +438,37 @@ static size_t find_vertical_west(design_t *current_design, comparison_t comp_typ size_t hits = 0; if (((empty[BTOP] ? 0 : current_design->shape[NW].height) + (empty[BBOT] ? 0 : current_design->shape[SW].height)) >= input.num_lines) { - return hits; + /* no hits */ } - if (isempty(current_design->shape + vshape)) { - return hits; + else if (isempty(current_design->shape + vshape)) { + /* no hits */ } + else { + for (size_t k = empty[BTOP] ? 0 : current_design->shape[NW].height; + k < input.num_lines - (empty[BBOT] ? 0 : current_design->shape[SW].height); ++k) + { + uint32_t *input_relevant = prepare_comp_input(k, 1, comp_type, 0, NULL, NULL); - for (size_t k = empty[BTOP] ? 0 : current_design->shape[NW].height; - k < input.num_lines - (empty[BBOT] ? 0 : current_design->shape[SW].height); ++k) - { - uint32_t *input_relevant = prepare_comp_input(k, 1, comp_type, 0, NULL, NULL); - - for (size_t j = 0; j < current_design->shape[vshape].height; ++j) { - bxstr_t *shape_line = current_design->shape[vshape].mbcs[j]; - if (bxs_is_blank(shape_line)) { - continue; - } + for (size_t j = 0; j < current_design->shape[vshape].height; ++j) { + bxstr_t *shape_line = current_design->shape[vshape].mbcs[j]; + if (bxs_is_blank(shape_line)) { + continue; + } - uint32_t *shape_relevant = prepare_comp_shape(current_design, vshape, j, comp_type, 1, 0); - size_t length_relevant = u32_strlen(shape_relevant); + uint32_t *shape_relevant = prepare_comp_shape(current_design, vshape, j, comp_type, 1, 0); + size_t length_relevant = u32_strlen(shape_relevant); - if (u32_strncmp(input_relevant, shape_relevant, length_relevant) == 0) { - ++hits; - break; + if (u32_strncmp(input_relevant, shape_relevant, length_relevant) == 0) { + ++hits; + break; + } + BFREE(shape_relevant); } - BFREE(shape_relevant); } } #ifdef DEBUG - fprintf(stderr, "Checking %s shape produced %d hits.\n", shape_name[vshape], (int) hits); + fprintf(stderr, "Checking %-3s shape produced %d hits.\n", shape_name[vshape], (int) hits); #endif return hits; } @@ -469,35 +489,36 @@ static size_t find_vertical_east(design_t *current_design, comparison_t comp_typ size_t hits = 0; if (((empty[BTOP] ? 0 : current_design->shape[NW].height) + (empty[BBOT] ? 0 : current_design->shape[SW].height)) >= input.num_lines) { - return hits; + /* no hits */ } - if (isempty(current_design->shape + vshape)) { - return hits; + else if (isempty(current_design->shape + vshape)) { + /* no hits */ } + else { + for (size_t j = 0; j < current_design->shape[vshape].height; ++j) { + bxstr_t *shape_line = current_design->shape[vshape].mbcs[j]; + if (bxs_is_blank(shape_line)) { + continue; + } - for (size_t j = 0; j < current_design->shape[vshape].height; ++j) { - bxstr_t *shape_line = current_design->shape[vshape].mbcs[j]; - if (bxs_is_blank(shape_line)) { - continue; - } - - uint32_t *shape_relevant = prepare_comp_shape(current_design, vshape, j, comp_type, 1, 1); - size_t length_relevant = u32_strlen(shape_relevant); + uint32_t *shape_relevant = prepare_comp_shape(current_design, vshape, j, comp_type, 1, 1); + size_t length_relevant = u32_strlen(shape_relevant); - for (size_t k = empty[BTOP] ? 0 : current_design->shape[NW].height; - k < input.num_lines - (empty[BBOT] ? 0 : current_design->shape[SW].height); ++k) - { - uint32_t *input_relevant = prepare_comp_input(k, 0, comp_type, length_relevant, NULL, NULL); - if (input_relevant != NULL && u32_strncmp(input_relevant, shape_relevant, length_relevant) == 0) { - ++hits; - break; + for (size_t k = empty[BTOP] ? 0 : current_design->shape[NW].height; + k < input.num_lines - (empty[BBOT] ? 0 : current_design->shape[SW].height); ++k) + { + uint32_t *input_relevant = prepare_comp_input(k, 0, comp_type, length_relevant, NULL, NULL); + if (input_relevant != NULL && u32_strncmp(input_relevant, shape_relevant, length_relevant) == 0) { + ++hits; + break; + } } + BFREE(shape_relevant); } - BFREE(shape_relevant); } #ifdef DEBUG - fprintf(stderr, "Checking %s shape produced %d hits.\n", shape_name[vshape], (int) hits); + fprintf(stderr, "Checking %-3s shape produced %d hits.\n", shape_name[vshape], (int) hits); #endif return hits; } @@ -568,7 +589,7 @@ design_t *autodetect_design() #ifdef DEBUG fprintf(stderr, "CONSIDERING DESIGN ---- \"%s\" ---------------\n", current_design->name); - fprintf(stderr, " comparison_type = '%s'\n", comparison_name[comp_type]); + fprintf(stderr, " comparison_type = %s\n", comparison_name[comp_type]); #endif long hits = match_design(current_design, comp_type); #ifdef DEBUG diff --git a/src/remove.c b/src/remove.c index 5e959c28..e08b5128 100644 --- a/src/remove.c +++ b/src/remove.c @@ -593,8 +593,10 @@ static size_t find_top_side(remove_ctx_t *ctx) input_line_idx++, shape_line_count++) { int matched = 0; - for (size_t shape_line_idx = input_line_idx - ctx->top_start_idx;; - shape_line_idx = (shape_line_idx + 1) % shapes[NE].height) + size_t shape_lines_tested = 0; + for (size_t shape_line_idx = (input_line_idx - ctx->top_start_idx) % shapes[NE].height; + shape_lines_tested < shapes[NE].height; + shape_line_idx = (shape_line_idx + 1) % shapes[NE].height, shape_lines_tested++) { if (match_horiz_line(ctx, BTOP, input_line_idx, shape_line_idx)) { matched = 1; @@ -613,15 +615,18 @@ static size_t find_top_side(remove_ctx_t *ctx) static size_t find_bottom_side(remove_ctx_t *ctx) { - size_t result = ctx->top_start_idx; + size_t result = ctx->bottom_end_idx; sentry_t *shapes = opt.design->shape; for (long input_line_idx = (long) ctx->bottom_end_idx - 1, shape_line_count = (long) shapes[SE].height - 1; input_line_idx >= 0 && shape_line_count >= 0; input_line_idx--, shape_line_count--) { int matched = 0; - for (size_t shape_line_idx = shapes[SE].height - (ctx->bottom_end_idx - input_line_idx);; - shape_line_idx = (shape_line_idx + 1) % shapes[SE].height) + size_t shape_lines_tested = 0; + for (long shape_line_idx = shapes[SE].height - (ctx->bottom_end_idx - input_line_idx); + shape_line_idx >= 0 && shape_lines_tested < shapes[SE].height; + shape_lines_tested++, + shape_line_idx = shape_line_idx == 0 ? (long) (shapes[SE].height - 1) : (long) (shape_line_idx - 1)) { if (match_horiz_line(ctx, BBOT, input_line_idx, shape_line_idx)) { matched = 1; @@ -1088,6 +1093,10 @@ int remove_box() else { ctx->top_end_idx = find_top_side(ctx); } + #ifdef DEBUG + fprintf(stderr, "ctx->top_start_idx = %d, ctx->top_end_idx = %d\n", (int) ctx->top_start_idx, + (int) ctx->top_end_idx); + #endif ctx->bottom_end_idx = find_last_line() + 1; if (ctx->empty_side[BBOT]) { @@ -1095,9 +1104,13 @@ int remove_box() } else { ctx->bottom_start_idx = find_bottom_side(ctx); - if (ctx->bottom_start_idx > ctx->top_end_idx) { - ctx->body_num_lines = ctx->bottom_start_idx - ctx->top_end_idx; - } + } + #ifdef DEBUG + fprintf(stderr, "ctx->bottom_start_idx = %d, ctx->bottom_end_idx = %d\n", (int) ctx->bottom_start_idx, + (int) ctx->bottom_end_idx); + #endif + if (ctx->bottom_start_idx > ctx->top_end_idx) { + ctx->body_num_lines = ctx->bottom_start_idx - ctx->top_end_idx; } if (ctx->body_num_lines > 0) { diff --git a/test/186_remove_line_comments.txt b/test/186_remove_line_comments.txt new file mode 100644 index 00000000..1a00ea0a --- /dev/null +++ b/test/186_remove_line_comments.txt @@ -0,0 +1,28 @@ +:DESC +Removes 'ada-cmt' line comments. Resulting three blank lines at top and bottom are not removed, because the default +for 'killblank' is false when top and bottom box sides are open, as is the case here. + +:ARGS +--design ada-cmt --remove +:INPUT +-- +-- +-- +-- foo +-- bar +-- boo +-- +-- +-- +:OUTPUT-FILTER +:EXPECTED + + + +foo +bar +boo + + + +:EOF diff --git a/test/187_remove_line_comments_killblank.txt b/test/187_remove_line_comments_killblank.txt new file mode 100644 index 00000000..41c86e18 --- /dev/null +++ b/test/187_remove_line_comments_killblank.txt @@ -0,0 +1,21 @@ +:DESC +Removes 'ada-cmt' line comments. Resulting three blank lines at top and bottom are removed ("killblank"). + +:ARGS +--design ada-cmt --remove --kill-blank +:INPUT +-- +-- +-- +-- foo +-- bar +-- boo +-- +-- +-- +:OUTPUT-FILTER +:EXPECTED +foo +bar +boo +:EOF