mirror of
https://github.com/ascii-boxes/boxes.git
synced 2025-01-07 14:39:24 +01:00
Extract match_outer_shape() function in 'remove' module
This commit is contained in:
parent
c4982a15df
commit
cde5ecc26a
141
src/remove.c
141
src/remove.c
@ -94,14 +94,11 @@ typedef struct _remove_ctx_t {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct _shape_line_ctx_t {
|
typedef struct _shape_line_ctx_t {
|
||||||
/** flag indicating whether the shape is empty */
|
/** flag indicating whether the (entire!) shape is empty */
|
||||||
int empty;
|
int empty;
|
||||||
|
|
||||||
/** one line of a shape, possibly trimmed, with invisible characters filtered according to the comparison type */
|
/** one line of a shape, with invisible characters filtered according to the comparison type */
|
||||||
uint32_t *text;
|
bxstr_t *text;
|
||||||
|
|
||||||
/** the length of `text` in characters */
|
|
||||||
size_t length;
|
|
||||||
|
|
||||||
/** flag indicating whether the shape to which this line belongs is elastic */
|
/** flag indicating whether the shape to which this line belongs is elastic */
|
||||||
int elastic;
|
int elastic;
|
||||||
@ -170,13 +167,13 @@ static int hmm(shape_line_ctx_t *shapes_relevant, uint32_t *cur_pos, size_t shap
|
|||||||
else if (shapes_relevant[shape_idx].empty) {
|
else if (shapes_relevant[shape_idx].empty) {
|
||||||
result = hmm(shapes_relevant, cur_pos, shape_idx + 1, end_pos);
|
result = hmm(shapes_relevant, cur_pos, shape_idx + 1, end_pos);
|
||||||
}
|
}
|
||||||
else if (u32_strncmp(cur_pos, shapes_relevant[shape_idx].text, shapes_relevant[shape_idx].length) == 0) {
|
else if (u32_strncmp(cur_pos, shapes_relevant[shape_idx].text->memory, shapes_relevant[shape_idx].text->num_chars) == 0) {
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
if (shapes_relevant[shape_idx].elastic) {
|
if (shapes_relevant[shape_idx].elastic) {
|
||||||
rc = hmm(shapes_relevant, cur_pos + shapes_relevant[shape_idx].length, shape_idx, end_pos);
|
rc = hmm(shapes_relevant, cur_pos + shapes_relevant[shape_idx].text->num_chars, shape_idx, end_pos);
|
||||||
}
|
}
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
result = hmm(shapes_relevant, cur_pos + shapes_relevant[shape_idx].length, shape_idx + 1, end_pos);
|
result = hmm(shapes_relevant, cur_pos + shapes_relevant[shape_idx].text->num_chars, shape_idx + 1, end_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,10 +193,11 @@ static shape_line_ctx_t *prepare_comp_shapes_horiz(int hside, comparison_t comp_
|
|||||||
for (size_t i = 0; i < SHAPES_PER_SIDE; i++) {
|
for (size_t i = 0; i < SHAPES_PER_SIDE; i++) {
|
||||||
shapes_relevant[i].empty = isempty(opt.design->shape + side_shapes[i]);
|
shapes_relevant[i].empty = isempty(opt.design->shape + side_shapes[i]);
|
||||||
if (!shapes_relevant[i].empty) {
|
if (!shapes_relevant[i].empty) {
|
||||||
shapes_relevant[i].text = prepare_comp_shape(opt.design, side_shapes[i], shape_line_idx, comp_type, 0,
|
uint32_t *s = prepare_comp_shape(opt.design, side_shapes[i], shape_line_idx, comp_type, 0,
|
||||||
i == SHAPES_PER_SIDE - 1);
|
i == SHAPES_PER_SIDE - 1);
|
||||||
shapes_relevant[i].length = u32_strlen(shapes_relevant[i].text);
|
shapes_relevant[i].text = bxs_from_unicode(s);
|
||||||
shapes_relevant[i].elastic = opt.design->shape[side_shapes[i]].elastic;
|
shapes_relevant[i].elastic = opt.design->shape[side_shapes[i]].elastic;
|
||||||
|
BFREE(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,6 +205,73 @@ static shape_line_ctx_t *prepare_comp_shapes_horiz(int hside, comparison_t comp_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static match_result_t *new_match_result(uint32_t *p, size_t p_idx, size_t len, int shiftable)
|
||||||
|
{
|
||||||
|
match_result_t *result = (match_result_t *) calloc(1, sizeof(match_result_t));
|
||||||
|
result->p = p;
|
||||||
|
result->p_idx = p_idx;
|
||||||
|
result->len = len;
|
||||||
|
result->shiftable = shiftable;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Match a `shape_line` at the beginning (`vside` == `BLEF`) or the end (`vside` == `BRIG`) of an `input_line`.
|
||||||
|
* Both `input_line` and `shape_line` may contain invisible characters, who are then matched, too, just like any other
|
||||||
|
* characters.
|
||||||
|
* @param vside BLEF or BRIG
|
||||||
|
* @param input_line the input line to examine. We expect that it was NOT trimmed.
|
||||||
|
* @param shape_line the shape line to match, also NOT trimmed
|
||||||
|
* @return pointer to the match result (in existing memory of `input_line->memory`), or `NULL` if no match
|
||||||
|
*/
|
||||||
|
match_result_t *match_outer_shape(int vside, bxstr_t *input_line, bxstr_t *shape_line)
|
||||||
|
{
|
||||||
|
if (input_line == NULL || shape_line == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vside == BLEF) {
|
||||||
|
if (bxs_is_blank(shape_line)) {
|
||||||
|
return new_match_result(input_line->memory, 0, 0, 1);
|
||||||
|
}
|
||||||
|
for (uint32_t *s = shape_line->memory; s == shape_line->memory || is_blank(*s); s++) {
|
||||||
|
uint32_t *p = u32_strstr(input_line->memory, s);
|
||||||
|
size_t p_idx = p != NULL ? p - input_line->memory : 0;
|
||||||
|
if (p == NULL || p_idx > input_line->first_char[input_line->indent]) {
|
||||||
|
continue; /* not found or found too far in */
|
||||||
|
}
|
||||||
|
return new_match_result(p, p_idx, shape_line->num_chars - (s - shape_line->memory), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (bxs_is_blank(shape_line)) {
|
||||||
|
uint32_t *p = bxs_last_char_ptr(input_line);
|
||||||
|
size_t p_idx = p - input_line->memory;
|
||||||
|
return new_match_result(p, p_idx, 0, 1);
|
||||||
|
}
|
||||||
|
int slen = shape_line->num_chars;
|
||||||
|
uint32_t *s = u32_strdup(shape_line->memory);
|
||||||
|
for (; slen == (int) shape_line->num_chars || is_blank(s[slen]); slen--) {
|
||||||
|
s[slen] = char_nul;
|
||||||
|
uint32_t *p = u32_strnrstr(input_line->memory, s, slen, 0);
|
||||||
|
size_t p_idx = p != NULL ? p - input_line->memory : 0;
|
||||||
|
if (p == NULL || p_idx + slen
|
||||||
|
< input_line->first_char[input_line->num_chars_visible - input_line->trailing]) {
|
||||||
|
continue; /* not found or found too far in */
|
||||||
|
}
|
||||||
|
BFREE(s);
|
||||||
|
return new_match_result(p, p_idx, (size_t) slen, 0);
|
||||||
|
}
|
||||||
|
BFREE(s);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO gdb --args out/boxes -n UTF-8 -d diamonds -ac -m test/117_unicode_ansi_mending.input.tmp
|
// TODO gdb --args out/boxes -n UTF-8 -d diamonds -ac -m test/117_unicode_ansi_mending.input.tmp
|
||||||
static int match_horiz_line(remove_ctx_t *ctx, int hside, size_t input_line_idx, size_t shape_line_idx)
|
static int match_horiz_line(remove_ctx_t *ctx, int hside, size_t input_line_idx, size_t shape_line_idx)
|
||||||
{
|
{
|
||||||
@ -229,8 +294,8 @@ static int match_horiz_line(remove_ctx_t *ctx, int hside, size_t input_line_idx,
|
|||||||
fprintf(stderr, "-");
|
fprintf(stderr, "-");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char *out_shp_text = u32_strconv_to_output(shapes_relevant[ds].text);
|
char *out_shp_text = bxs_to_output(shapes_relevant[ds].text);
|
||||||
fprintf(stderr, "\"%s\"(%d%s)", out_shp_text, (int) shapes_relevant[ds].length,
|
fprintf(stderr, "\"%s\"(%d%s)", out_shp_text, (int) shapes_relevant[ds].text->num_chars,
|
||||||
shapes_relevant[ds].elastic ? "E" : "");
|
shapes_relevant[ds].elastic ? "E" : "");
|
||||||
BFREE(out_shp_text);
|
BFREE(out_shp_text);
|
||||||
}
|
}
|
||||||
@ -242,36 +307,36 @@ static int match_horiz_line(remove_ctx_t *ctx, int hside, size_t input_line_idx,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t *cur_pos = NULL;
|
uint32_t *cur_pos = NULL;
|
||||||
uint32_t *input_prepped = prepare_comp_input(input_line_idx, 0, comp_type, 0, NULL, NULL);
|
bxstr_t *input_prepped = bxs_from_unicode(prepare_comp_input(input_line_idx, 0, comp_type, 0, NULL, NULL));
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
char *out_input_prepped = u32_strconv_to_output(input_prepped);
|
char *out_input_prepped = bxs_to_output(input_prepped);
|
||||||
fprintf(stderr, " input_prepped = \"%s\"\n", out_input_prepped);
|
fprintf(stderr, " input_prepped = \"%s\"\n", out_input_prepped);
|
||||||
BFREE(out_input_prepped);
|
BFREE(out_input_prepped);
|
||||||
#endif
|
#endif
|
||||||
if (input_prepped != NULL && (shapes_relevant[0].length == 0
|
if (input_prepped != NULL && (shapes_relevant[0].text->num_chars == 0
|
||||||
|| u32_strncmp(input_prepped, shapes_relevant[0].text, shapes_relevant[0].length) == 0))
|
|| u32_strncmp(input_prepped->memory, shapes_relevant[0].text->memory, shapes_relevant[0].text->num_chars) == 0))
|
||||||
{
|
{
|
||||||
cur_pos = input_prepped + shapes_relevant[0].length; // TODO check cur_pos and end_pos
|
cur_pos = input_prepped->memory + shapes_relevant[0].text->num_chars; // TODO check cur_pos and end_pos
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t *end_pos = NULL;
|
uint32_t *end_pos = NULL;
|
||||||
input_prepped = prepare_comp_input(
|
input_prepped = bxs_from_unicode(prepare_comp_input(
|
||||||
input_line_idx, 0, comp_type, shapes_relevant[SHAPES_PER_SIDE - 1].length, NULL, NULL);
|
input_line_idx, 0, comp_type, shapes_relevant[SHAPES_PER_SIDE - 1].text->num_chars, NULL, NULL));
|
||||||
if (input_prepped != NULL) {
|
if (input_prepped != NULL) {
|
||||||
if (shapes_relevant[SHAPES_PER_SIDE - 1].length == 0) {
|
if (shapes_relevant[SHAPES_PER_SIDE - 1].text->num_chars == 0) {
|
||||||
end_pos = input_prepped + u32_strlen(input_prepped); // point to NUL terminator
|
end_pos = input_prepped->memory + input_prepped->num_chars; // point to NUL terminator
|
||||||
}
|
}
|
||||||
else if (u32_strncmp(input_prepped, shapes_relevant[SHAPES_PER_SIDE - 1].text,
|
else if (u32_strncmp(input_prepped->memory, shapes_relevant[SHAPES_PER_SIDE - 1].text->memory,
|
||||||
shapes_relevant[SHAPES_PER_SIDE - 1].length) == 0)
|
shapes_relevant[SHAPES_PER_SIDE - 1].text->num_chars) == 0)
|
||||||
{
|
{
|
||||||
end_pos = input_prepped;
|
end_pos = input_prepped->memory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
char *out_cur_pos = u32_strconv_to_output(cur_pos);
|
char *out_cur_pos = u32_strconv_to_output(cur_pos);
|
||||||
char *out_end_pos = u32_strconv_to_output(end_pos);
|
char *out_end_pos = u32_strconv_to_output(end_pos);
|
||||||
fprintf(stderr, " cur_pos = \"%s\" (index %d)\n", out_cur_pos, (int) BMAX(cur_pos - input_prepped, 0));
|
fprintf(stderr, " cur_pos = \"%s\" (index %d)\n", out_cur_pos, (int) BMAX(cur_pos - input_prepped->memory, 0));
|
||||||
fprintf(stderr, " end_pos = \"%s\" (index %d)\n", out_end_pos, (int) BMAX(end_pos - input_prepped, 0));
|
fprintf(stderr, " end_pos = \"%s\" (index %d)\n", out_end_pos, (int) BMAX(end_pos - input_prepped->memory, 0));
|
||||||
BFREE(out_cur_pos);
|
BFREE(out_cur_pos);
|
||||||
BFREE(out_end_pos);
|
BFREE(out_end_pos);
|
||||||
#endif
|
#endif
|
||||||
@ -281,7 +346,7 @@ static int match_horiz_line(remove_ctx_t *ctx, int hside, size_t input_line_idx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < SHAPES_PER_SIDE; i++) {
|
for (size_t i = 0; i < SHAPES_PER_SIDE; i++) {
|
||||||
BFREE(shapes_relevant[i].text);
|
bxs_free(shapes_relevant[i].text);
|
||||||
}
|
}
|
||||||
BFREE(shapes_relevant);
|
BFREE(shapes_relevant);
|
||||||
|
|
||||||
@ -384,12 +449,14 @@ static shape_line_ctx_t **prepare_comp_shapes_vert(int vside, comparison_t comp_
|
|||||||
|
|
||||||
for (size_t shape_idx = 0, i = 0; shape_idx < SHAPES_PER_SIDE - CORNERS_PER_SIDE; shape_idx++) {
|
for (size_t shape_idx = 0, i = 0; shape_idx < SHAPES_PER_SIDE - CORNERS_PER_SIDE; shape_idx++) {
|
||||||
if (!isempty(opt.design->shape + side_shapes[shape_idx])) {
|
if (!isempty(opt.design->shape + side_shapes[shape_idx])) {
|
||||||
|
int deep_empty = isdeepempty(opt.design->shape + side_shapes[shape_idx]);
|
||||||
shape_lines[i] = (shape_line_ctx_t *) calloc(1, sizeof(shape_line_ctx_t));
|
shape_lines[i] = (shape_line_ctx_t *) calloc(1, sizeof(shape_line_ctx_t));
|
||||||
for (size_t slno = 0; slno < opt.design->shape[side_shapes[shape_idx]].height; slno++, i++) {
|
for (size_t slno = 0; slno < opt.design->shape[side_shapes[shape_idx]].height; slno++, i++) {
|
||||||
shape_lines[i]->text = prepare_comp_shape(opt.design, side_shapes[shape_idx], slno, comp_type, 0, 0);
|
uint32_t *s = prepare_comp_shape(opt.design, side_shapes[shape_idx], slno, comp_type, 0, 0);
|
||||||
shape_lines[i]->empty = u32_is_blank(shape_lines[i]->text);
|
shape_lines[i]->text = bxs_from_unicode(s);
|
||||||
shape_lines[i]->length = u32_strlen(shape_lines[i]->text);
|
shape_lines[i]->empty = deep_empty;
|
||||||
shape_lines[i]->elastic = opt.design->shape[side_shapes[shape_idx]].elastic;
|
shape_lines[i]->elastic = opt.design->shape[side_shapes[shape_idx]].elastic;
|
||||||
|
BFREE(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -403,7 +470,7 @@ static void free_shape_lines(shape_line_ctx_t **shape_lines)
|
|||||||
{
|
{
|
||||||
if (shape_lines != NULL) {
|
if (shape_lines != NULL) {
|
||||||
for (shape_line_ctx_t **p = shape_lines; *p != NULL; p++) {
|
for (shape_line_ctx_t **p = shape_lines; *p != NULL; p++) {
|
||||||
BFREE((*p)->text);
|
bxs_free((*p)->text);
|
||||||
BFREE(*p);
|
BFREE(*p);
|
||||||
}
|
}
|
||||||
BFREE(shape_lines);
|
BFREE(shape_lines);
|
||||||
@ -421,9 +488,9 @@ static void free_shape_lines(shape_line_ctx_t **shape_lines)
|
|||||||
*/
|
*/
|
||||||
static uint32_t *shorten(shape_line_ctx_t *shape_line_ctx, size_t *quality, int prefer_left)
|
static uint32_t *shorten(shape_line_ctx_t *shape_line_ctx, size_t *quality, int prefer_left)
|
||||||
{
|
{
|
||||||
uint32_t *s = shape_line_ctx->text;
|
uint32_t *s = shape_line_ctx->text->memory;
|
||||||
uint32_t *e = shape_line_ctx->text + shape_line_ctx->length;
|
uint32_t *e = shape_line_ctx->text->memory + shape_line_ctx->text->num_chars;
|
||||||
size_t reduction_steps = shape_line_ctx->length - *quality + 1;
|
size_t reduction_steps = shape_line_ctx->text->num_chars - *quality + 1;
|
||||||
for (size_t i = 0; i < reduction_steps; i++) {
|
for (size_t i = 0; i < reduction_steps; i++) {
|
||||||
if (prefer_left) {
|
if (prefer_left) {
|
||||||
if (is_blank(*s) && s < e) {
|
if (is_blank(*s) && s < e) {
|
||||||
@ -471,9 +538,9 @@ static void match_vertical_side(remove_ctx_t *ctx, int vside, shape_line_ctx_t *
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t max_quality = (*shape_line_ctx)->length;
|
size_t max_quality = (*shape_line_ctx)->text->num_chars;
|
||||||
size_t quality = max_quality;
|
size_t quality = max_quality;
|
||||||
uint32_t *shape_text = (*shape_line_ctx)->text;
|
uint32_t *shape_text = (*shape_line_ctx)->text->memory;
|
||||||
uint32_t *to_free = NULL;
|
uint32_t *to_free = NULL;
|
||||||
while(shape_text != NULL) {
|
while(shape_text != NULL) {
|
||||||
uint32_t *p;
|
uint32_t *p;
|
||||||
|
17
src/remove.h
17
src/remove.h
@ -21,6 +21,23 @@
|
|||||||
#define REMOVE_H
|
#define REMOVE_H
|
||||||
|
|
||||||
|
|
||||||
|
/** the result of a match operation at the beginning or end of a line */
|
||||||
|
typedef struct _match_result_t {
|
||||||
|
/** pointer to the matched position */
|
||||||
|
uint32_t *p;
|
||||||
|
|
||||||
|
/** index of the matched position in the haystack string */
|
||||||
|
size_t p_idx;
|
||||||
|
|
||||||
|
/** number of characters matched (between 1 and shape_line->num_chars) */
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
/** flag indicating the match was secured by including non-blank characters (0) or only blanks were matched (1) */
|
||||||
|
int shiftable;
|
||||||
|
} match_result_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove box from input.
|
* Remove box from input.
|
||||||
* @return == 0: success;
|
* @return == 0: success;
|
||||||
|
@ -19,8 +19,8 @@ SRC_DIR = ../src
|
|||||||
UTEST_DIR = ../utest
|
UTEST_DIR = ../utest
|
||||||
VPATH = $(SRC_DIR):$(SRC_DIR)/misc:$(UTEST_DIR)
|
VPATH = $(SRC_DIR):$(SRC_DIR)/misc:$(UTEST_DIR)
|
||||||
|
|
||||||
UTEST_NORM = global_mock.c bxstring_test.o cmdline_test.c tools_test.c regulex_test.o main.o unicode_test.o \
|
UTEST_NORM = global_mock.c bxstring_test.o cmdline_test.c tools_test.c regulex_test.o remove_test.o main.o \
|
||||||
utest_tools.o
|
unicode_test.o utest_tools.o
|
||||||
|
|
||||||
.PHONY: check_dir flags_unix flags_win32 flags_ utest
|
.PHONY: check_dir flags_unix flags_win32 flags_ utest
|
||||||
|
|
||||||
@ -71,6 +71,7 @@ bxstring_test.o: bxstring_test.c bxstring_test.h boxes.h bxstring.h global_mock.
|
|||||||
cmdline_test.o: cmdline_test.c cmdline_test.h boxes.h cmdline.h global_mock.h tools.h config.h | check_dir
|
cmdline_test.o: cmdline_test.c cmdline_test.h boxes.h cmdline.h global_mock.h tools.h config.h | check_dir
|
||||||
tools_test.o: tools_test.c tools_test.h tools.h unicode.h config.h | check_dir
|
tools_test.o: tools_test.c tools_test.h tools.h unicode.h config.h | check_dir
|
||||||
regulex_test.o: regulex_test.c regulex_test.h boxes.h global_mock.h regulex.h config.h | check_dir
|
regulex_test.o: regulex_test.c regulex_test.h boxes.h global_mock.h regulex.h config.h | check_dir
|
||||||
|
remove_test.o: remove_test.c remove_test.h boxes.h remove.h tools.h unicode.h global_mock.h utest_tools.h config.h | check_dir
|
||||||
main.o: main.c bxstring_test.h cmdline_test.h global_mock.h tools_test.h regulex_test.h unicode_test.h config.h | check_dir
|
main.o: main.c bxstring_test.h cmdline_test.h global_mock.h tools_test.h regulex_test.h unicode_test.h config.h | check_dir
|
||||||
unicode_test.o: unicode_test.c unicode_test.h boxes.h tools.h unicode.h config.h | check_dir
|
unicode_test.o: unicode_test.c unicode_test.h boxes.h tools.h unicode.h config.h | check_dir
|
||||||
utest_tools.o: utest_tools.c utest_tools.h config.h | check_dir
|
utest_tools.o: utest_tools.c utest_tools.h config.h | check_dir
|
||||||
|
20
utest/main.c
20
utest/main.c
@ -30,6 +30,7 @@
|
|||||||
#include "cmdline_test.h"
|
#include "cmdline_test.h"
|
||||||
#include "tools_test.h"
|
#include "tools_test.h"
|
||||||
#include "regulex_test.h"
|
#include "regulex_test.h"
|
||||||
|
#include "remove_test.h"
|
||||||
#include "unicode_test.h"
|
#include "unicode_test.h"
|
||||||
|
|
||||||
|
|
||||||
@ -178,12 +179,31 @@ int main(void)
|
|||||||
cmocka_unit_test_setup(test_bxs_concat_nullarg, beforeTest)
|
cmocka_unit_test_setup(test_bxs_concat_nullarg, beforeTest)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct CMUnitTest remove_tests[] = {
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_null, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_left_anchored, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_left_shiftable, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_left_shortened, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_left_not_found, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_left_too_far_in, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_left_edge, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_right_anchored, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_right_shiftable, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_right_shortened, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_right_shortened2, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_right_not_found, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_right_too_far_in, beforeTest),
|
||||||
|
cmocka_unit_test_setup(test_match_outer_shape_right_edge, beforeTest)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int num_failed = 0;
|
int num_failed = 0;
|
||||||
num_failed += cmocka_run_group_tests(cmdline_tests, NULL, NULL);
|
num_failed += cmocka_run_group_tests(cmdline_tests, NULL, NULL);
|
||||||
num_failed += cmocka_run_group_tests(regulex_tests, NULL, NULL);
|
num_failed += cmocka_run_group_tests(regulex_tests, NULL, NULL);
|
||||||
num_failed += cmocka_run_group_tests(tools_tests, NULL, NULL);
|
num_failed += cmocka_run_group_tests(tools_tests, NULL, NULL);
|
||||||
num_failed += cmocka_run_group_tests(unicode_tests, NULL, NULL);
|
num_failed += cmocka_run_group_tests(unicode_tests, NULL, NULL);
|
||||||
num_failed += cmocka_run_group_tests(bxstring_tests, NULL, NULL);
|
num_failed += cmocka_run_group_tests(bxstring_tests, NULL, NULL);
|
||||||
|
num_failed += cmocka_run_group_tests(remove_tests, NULL, NULL);
|
||||||
|
|
||||||
teardown();
|
teardown();
|
||||||
return num_failed;
|
return num_failed;
|
||||||
|
318
utest/remove_test.c
Normal file
318
utest/remove_test.c
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
/*
|
||||||
|
* boxes - Command line filter to draw/remove ASCII boxes around text
|
||||||
|
* Copyright (c) 1999-2023 Thomas Jensen and the boxes contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||||
|
* License, version 3, as published by the Free Software Foundation.
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program.
|
||||||
|
* If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unit tests of the 'remove' module
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <unistr.h>
|
||||||
|
|
||||||
|
#include <cmocka.h>
|
||||||
|
|
||||||
|
#include "boxes.h"
|
||||||
|
#include "unicode.h"
|
||||||
|
#include "tools.h"
|
||||||
|
#include "remove_test.h"
|
||||||
|
#include "global_mock.h"
|
||||||
|
#include "utest_tools.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_null(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" xx x xx ");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii(" xx ");
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BLEF, NULL, shape_line);
|
||||||
|
assert_null(actual);
|
||||||
|
|
||||||
|
actual = match_outer_shape(BLEF, input_line, NULL);
|
||||||
|
assert_null(actual);
|
||||||
|
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_left_anchored(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" xx x xx ");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii(" xx ");
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BLEF, input_line, shape_line);
|
||||||
|
uint32_t *expected_p = bxs_first_char_ptr(input_line, 3);
|
||||||
|
assert_non_null(actual);
|
||||||
|
assert_int_equal(3, (int) actual->p_idx);
|
||||||
|
assert_int_equal(0, u32_strcmp(expected_p, actual->p));
|
||||||
|
assert_int_equal(4, actual->len);
|
||||||
|
assert_int_equal(0, actual->shiftable);
|
||||||
|
|
||||||
|
BFREE(actual);
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_left_shiftable(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" xx x xx ");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii(" ");
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BLEF, input_line, shape_line);
|
||||||
|
assert_non_null(actual);
|
||||||
|
assert_int_equal(0, (int) actual->p_idx);
|
||||||
|
assert_int_equal(0, u32_strcmp(input_line->memory, actual->p));
|
||||||
|
assert_int_equal(0, actual->len);
|
||||||
|
assert_int_equal(1, actual->shiftable);
|
||||||
|
|
||||||
|
BFREE(actual);
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_left_shortened(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" xx x xx ");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii(" xx"); /* length 6 */
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BLEF, input_line, shape_line);
|
||||||
|
assert_non_null(actual);
|
||||||
|
assert_int_equal(0, (int) actual->p_idx);
|
||||||
|
assert_int_equal(0, u32_strcmp(input_line->memory, actual->p));
|
||||||
|
assert_int_equal(4, actual->len); /* only 4 characters matched */
|
||||||
|
assert_int_equal(0, actual->shiftable);
|
||||||
|
|
||||||
|
BFREE(actual);
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_left_not_found(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" xx x xx ");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii(" ---");
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BLEF, input_line, shape_line);
|
||||||
|
assert_null(actual);
|
||||||
|
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_left_too_far_in(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" xx M xx ");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii("x M");
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BLEF, input_line, shape_line);
|
||||||
|
assert_null(actual);
|
||||||
|
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_left_edge(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" x yy");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii("x");
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BLEF, input_line, shape_line);
|
||||||
|
|
||||||
|
uint32_t *expected_p = bxs_first_char_ptr(input_line, 3);
|
||||||
|
assert_non_null(actual);
|
||||||
|
assert_int_equal(3, (int) actual->p_idx);
|
||||||
|
assert_int_equal(0, u32_strcmp(expected_p, actual->p));
|
||||||
|
assert_int_equal(1, actual->len);
|
||||||
|
assert_int_equal(0, actual->shiftable);
|
||||||
|
|
||||||
|
BFREE(actual);
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_right_anchored(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" xx x xx ");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii(" xx ");
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BRIG, input_line, shape_line);
|
||||||
|
uint32_t *expected_p = bxs_first_char_ptr(input_line, 8);
|
||||||
|
assert_non_null(actual);
|
||||||
|
assert_int_equal(8, (int) actual->p_idx);
|
||||||
|
assert_int_equal(0, u32_strcmp(expected_p, actual->p));
|
||||||
|
assert_int_equal(4, actual->len);
|
||||||
|
assert_int_equal(0, actual->shiftable);
|
||||||
|
|
||||||
|
BFREE(actual);
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_right_shiftable(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" xx x xx ");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii(" ");
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BRIG, input_line, shape_line);
|
||||||
|
assert_non_null(actual);
|
||||||
|
assert_int_equal(15, (int) actual->p_idx);
|
||||||
|
assert_int_equal(1, is_char_at(actual->p, 0, char_nul));
|
||||||
|
assert_int_equal(0, actual->len);
|
||||||
|
assert_int_equal(1, actual->shiftable);
|
||||||
|
|
||||||
|
BFREE(actual);
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_right_shortened(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" xx x xx ");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii("xx "); /* length 6 */
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BRIG, input_line, shape_line);
|
||||||
|
|
||||||
|
uint32_t *expected_p = bxs_first_char_ptr(input_line, 7);
|
||||||
|
assert_non_null(actual);
|
||||||
|
assert_int_equal(7, (int) actual->p_idx);
|
||||||
|
assert_int_equal(0, u32_strcmp(expected_p, actual->p));
|
||||||
|
assert_int_equal(4, actual->len); /* only 4 characters matched */
|
||||||
|
assert_int_equal(0, actual->shiftable);
|
||||||
|
|
||||||
|
BFREE(actual);
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_right_not_found(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" xx x xx ");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii("--- ");
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BRIG, input_line, shape_line);
|
||||||
|
assert_null(actual);
|
||||||
|
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_right_too_far_in(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" xx M xx ");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii("M x");
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BRIG, input_line, shape_line);
|
||||||
|
assert_null(actual);
|
||||||
|
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_right_shortened2(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii(" x Y");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii("Y ");
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BRIG, input_line, shape_line);
|
||||||
|
|
||||||
|
uint32_t *expected_p = bxs_first_char_ptr(input_line, 4);
|
||||||
|
assert_non_null(actual);
|
||||||
|
assert_int_equal(4, (int) actual->p_idx);
|
||||||
|
assert_int_equal(0, u32_strcmp(expected_p, actual->p));
|
||||||
|
assert_int_equal(1, actual->len);
|
||||||
|
assert_int_equal(0, actual->shiftable);
|
||||||
|
|
||||||
|
BFREE(actual);
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_right_edge(void **state)
|
||||||
|
{
|
||||||
|
UNUSED(state);
|
||||||
|
|
||||||
|
bxstr_t *input_line = bxs_from_ascii("x");
|
||||||
|
bxstr_t *shape_line = bxs_from_ascii("x");
|
||||||
|
|
||||||
|
match_result_t *actual = match_outer_shape(BRIG, input_line, shape_line);
|
||||||
|
|
||||||
|
assert_non_null(actual);
|
||||||
|
assert_int_equal(0, (int) actual->p_idx);
|
||||||
|
assert_int_equal(0, u32_strcmp(input_line->memory, actual->p));
|
||||||
|
assert_int_equal(1, actual->len);
|
||||||
|
assert_int_equal(0, actual->shiftable);
|
||||||
|
|
||||||
|
BFREE(actual);
|
||||||
|
bxs_free(input_line);
|
||||||
|
bxs_free(shape_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* vim: set cindent sw=4: */
|
49
utest/remove_test.h
Normal file
49
utest/remove_test.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* boxes - Command line filter to draw/remove ASCII boxes around text
|
||||||
|
* Copyright (c) 1999-2023 Thomas Jensen and the boxes contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||||
|
* License, version 3, as published by the Free Software Foundation.
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program.
|
||||||
|
* If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unit tests of the 'remove' module
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef REMOVE_TEST_H
|
||||||
|
#define REMOVE_TEST_H
|
||||||
|
|
||||||
|
#include "bxstring.h"
|
||||||
|
#include "remove.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* defined here and not in remove.h because it's only visible for testing */
|
||||||
|
match_result_t *match_outer_shape(int vside, bxstr_t *input_line, bxstr_t *shape_line);
|
||||||
|
|
||||||
|
|
||||||
|
void test_match_outer_shape_null(void **state);
|
||||||
|
void test_match_outer_shape_left_anchored(void **state);
|
||||||
|
void test_match_outer_shape_left_shiftable(void **state);
|
||||||
|
void test_match_outer_shape_left_shortened(void **state);
|
||||||
|
void test_match_outer_shape_left_not_found(void **state);
|
||||||
|
void test_match_outer_shape_left_too_far_in(void **state);
|
||||||
|
void test_match_outer_shape_left_edge(void **state);
|
||||||
|
void test_match_outer_shape_right_anchored(void **state);
|
||||||
|
void test_match_outer_shape_right_shiftable(void **state);
|
||||||
|
void test_match_outer_shape_right_shortened(void **state);
|
||||||
|
void test_match_outer_shape_right_shortened2(void **state);
|
||||||
|
void test_match_outer_shape_right_not_found(void **state);
|
||||||
|
void test_match_outer_shape_right_too_far_in(void **state);
|
||||||
|
void test_match_outer_shape_right_edge(void **state);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* vim: set cindent sw=4: */
|
Loading…
Reference in New Issue
Block a user