Add workaround for mockable fprintf on MinGW

This commit is contained in:
Thomas Jensen 2021-11-01 14:19:52 +01:00
parent 96a79f309c
commit ab28ad8c3a
No known key found for this signature in database
GPG Key ID: A4ACEE270D0FB7DB
5 changed files with 32 additions and 14 deletions

View File

@ -55,7 +55,7 @@ pcre2_code *compile_pattern(char *pattern)
if (re == NULL) { if (re == NULL) {
PCRE2_UCHAR buffer[256]; PCRE2_UCHAR buffer[256];
pcre2_get_error_message(errornumber, buffer, sizeof(buffer)); pcre2_get_error_message(errornumber, buffer, sizeof(buffer));
fprintf(stderr, "Regular expression pattern \"%s\" failed to compile at position %d: %s\n", bx_fprintf(stderr, "Regular expression pattern \"%s\" failed to compile at position %d: %s\n",
pattern, (int) erroroffset, u32_strconv_to_output(buffer)); pattern, (int) erroroffset, u32_strconv_to_output(buffer));
} }
return re; return re;

View File

@ -737,4 +737,14 @@ char *bx_strndup(const char *s, size_t n)
} }
void bx_fprintf(FILE *stream, const char *format, ...)
{
va_list va;
va_start(va, format);
vfprintf(stream, format, va);
va_end(va);
}
/*EOF*/ /* vim: set sw=4: */ /*EOF*/ /* vim: set sw=4: */

View File

@ -126,6 +126,14 @@ int tag_is_valid(char *tag);
char *bx_strndup(const char *s, size_t n); char *bx_strndup(const char *s, size_t n);
/**
* Just calls `fprintf()` internally, but this function can be mocked in unit tests. So, it's a "mockable `fprintf()`".
* @param stream Where to print, for example `stderr`
* @param format the format string, followed by the arguments of the format string
*/
void bx_fprintf(FILE *stream, const char *format, ...);
#endif #endif
/*EOF*/ /* vim: set cindent sw=4: */ /*EOF*/ /* vim: set cindent sw=4: */

View File

@ -25,7 +25,7 @@ UTEST_DIR = ../utest
VPATH = $(SRC_DIR):$(SRC_DIR)/misc:$(UTEST_DIR) VPATH = $(SRC_DIR):$(SRC_DIR)/misc:$(UTEST_DIR)
UTEST_NORM = global_mock.c tools_test.c regulex_test.o main.o UTEST_NORM = global_mock.c tools_test.c regulex_test.o main.o
MOCKS = fprintf MOCKS = bx_fprintf
.PHONY: check_dir flags_unix flags_win32 flags_ utest .PHONY: check_dir flags_unix flags_win32 flags_ utest
@ -47,8 +47,8 @@ flags_unix:
$(eval UTEST_OBJ := $(UTEST_NORM:.c=.o)) $(eval UTEST_OBJ := $(UTEST_NORM:.c=.o))
flags_win32: flags_win32:
$(eval CFLAGS := -Os -s -m32 -I. -I$(SRC_DIR) -Wall -W $(CFLAGS_ADDTL)) $(eval CFLAGS := -Os -s -std=c99 -m32 -I. -I$(SRC_DIR) -Wall -W $(CFLAGS_ADDTL))
$(eval LDFLAGS := $(LDFLAGS) $(foreach MOCK,$(MOCKS),-Wl,--wrap=$(MOCK)) --coverage -s -m32 $(LDFLAGS_ADDTL)) $(eval LDFLAGS := $(LDFLAGS) -s -std=c99 -m32 $(foreach MOCK,$(MOCKS),-Wl,--wrap=$(MOCK)) $(LDFLAGS_ADDTL))
$(eval UTEST_EXECUTABLE_NAME := unittest.exe) $(eval UTEST_EXECUTABLE_NAME := unittest.exe)
$(eval UTEST_OBJ := $(UTEST_NORM:.c=.o)) $(eval UTEST_OBJ := $(UTEST_NORM:.c=.o))

View File

@ -65,25 +65,25 @@ void collect_reset()
/** /**
* Mock of the `fprintf()` function which records its output instead of printing it. Assumes that no output string will * Mock of the `bx_fprintf()` function which records its output instead of printing it. Assumes that no output string
* be longer than 512 characters. * will be longer than 512 characters.
* @param __stream `stdout` or `stderr` * @param stream `stdout` or `stderr`
* @param __format the format string, followed by the arguments * @param format the format string, followed by the arguments
*/ */
void __wrap_fprintf(FILE *__stream, const char *__format, ...) void __wrap_bx_fprintf(FILE *stream, const char *format, ...)
{ {
char **collect = __stream == stdout ? collect_out : collect_err; char **collect = stream == stdout ? collect_out : collect_err;
int collect_size = __stream == stdout ? collect_out_size : collect_err_size; int collect_size = stream == stdout ? collect_out_size : collect_err_size;
collect = (char **) realloc(collect, ++collect_size * sizeof(char *)); collect = (char **) realloc(collect, ++collect_size * sizeof(char *));
char *s = (char *) malloc(512); char *s = (char *) malloc(512);
va_list va; va_list va;
va_start(va, __format); va_start(va, format);
vsprintf(s, __format, va); vsprintf(s, format, va);
va_end(va); va_end(va);
collect[collect_size - 1] = s; collect[collect_size - 1] = s;
if (__stream == stdout) { if (stream == stdout) {
collect_out = collect; collect_out = collect;
collect_out_size = collect_size; collect_out_size = collect_size;
} }