Skip to content

Commit 71dcb9d

Browse files
committed
C89 strictness
1 parent 835f0cc commit 71dcb9d

9 files changed

Lines changed: 303 additions & 40 deletions

CMakeLists.txt

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,7 @@ configure_file(
5555

5656
add_subdirectory("${PROJECT_NAME}")
5757

58-
include(CTest)
59-
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
60-
set(C89STRINGUTILS_BUILD_TESTING_DEFAULT ON)
61-
else()
62-
set(C89STRINGUTILS_BUILD_TESTING_DEFAULT OFF)
63-
endif()
64-
option(C89STRINGUTILS_BUILD_TESTING "Build the tests" ${C89STRINGUTILS_BUILD_TESTING_DEFAULT})
58+
option(BUILD_TESTING_${PROJECT_NAME} "Build the tests" ON)
6559

6660
set(CDD_CHARSET "Unicode" CACHE STRING "Charset to use: Unicode or ANSI")
6761
set(CDD_THREADING "Multi-threaded" CACHE STRING "Threading: Multi-threaded or Single-threaded")
@@ -93,9 +87,12 @@ if (CDD_LTO)
9387
endif()
9488
endif()
9589

96-
if (BUILD_TESTING AND C89STRINGUTILS_BUILD_TESTING)
97-
add_subdirectory("${PROJECT_NAME}/tests")
98-
endif (BUILD_TESTING AND C89STRINGUTILS_BUILD_TESTING)
90+
if (BUILD_TESTING_${PROJECT_NAME})
91+
include(CTest)
92+
if (BUILD_TESTING)
93+
add_subdirectory("${PROJECT_NAME}/tests")
94+
endif (BUILD_TESTING)
95+
endif (BUILD_TESTING_${PROJECT_NAME})
9996

10097
###########
10198
# Install #

alpine.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ WORKDIR /c89stringutils
88

99
RUN cmake -DCMAKE_BUILD_TYPE="Debug" \
1010
-DBUILD_TESTING=1 \
11-
-DC89STRINGUTILS_BUILD_TESTING=1 \
11+
-DBUILD_TESTING_c89stringutils=1 \
1212
-S . -B build && \
1313
cmake --build build
1414

c89stringutils/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ source_group("Source Files" FILES "${Source_Files}")
88

99
add_library("${LIBRARY_NAME}" "${Header_Files}" "${Source_Files}")
1010

11+
target_link_libraries("${LIBRARY_NAME}" PRIVATE "${PROJECT_NAME}_compiler_flags")
12+
1113
include(GNUInstallDirs)
1214
target_include_directories(
1315
"${LIBRARY_NAME}"

c89stringutils/c89stringutils_string_extras.c

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,20 @@
1616
#include <limits.h> /* for INT_MAX */
1717
/* clang-format on */
1818

19+
#ifdef C89STRINGUTILS_TEST_MOCKS
20+
extern void *mock_malloc(size_t size);
21+
extern void *mock_realloc(void *ptr, size_t size);
22+
extern int mock_vsnprintf(char *str, size_t size, const char *format,
23+
va_list ap);
24+
extern char *mock_strerror(int errnum);
25+
#define malloc mock_malloc
26+
#define realloc mock_realloc
27+
#define wtf_vsnprintf mock_vsnprintf
28+
#undef vsnprintf
29+
#define vsnprintf mock_vsnprintf
30+
#define strerror mock_strerror
31+
#endif
32+
1933
#if defined(__GNUC__) && __GNUC__ >= 7 && !defined(__clang__)
2034
#pragma GCC diagnostic push
2135
#pragma GCC diagnostic ignored "-Wnonnull-compare"
@@ -288,7 +302,6 @@ C89STRINGUTILS_EXPORT size_t c89stringutils_strerrorlen_s(errno_t errnum) {
288302
}
289303
}
290304

291-
292305
#ifndef VA_COPY
293306
#if defined(HAVE_VA_COPY) || defined(va_copy)
294307
#define VA_COPY(dest, src) va_copy(dest, src)
@@ -333,12 +346,17 @@ C89STRINGUTILS_EXPORT int c89stringutils_vasprintf(char **str, const char *fmt,
333346
VA_COPY(ap2, ap);
334347
rc = vsnprintf(string, INIT_SZ, fmt, ap2);
335348
va_end(ap2);
336-
if (rc >= 0 && rc < INIT_SZ) { /* succeeded with initial alloc */
337-
*str = string;
338-
} else if (rc == INT_MAX || rc < 0) { /* Bad length */
349+
350+
if (rc < 0) { /* Bad length */
339351
free(string);
340352
rc = -1;
341353
goto fail;
354+
} else if (rc == INT_MAX) { /* Bad length */
355+
free(string);
356+
rc = -1;
357+
goto fail;
358+
} else if (rc < INIT_SZ) { /* succeeded with initial alloc */
359+
*str = string;
342360
} else { /* bigger than initial, realloc allowing for nul */
343361
len = (size_t)rc + 1;
344362
newstr = (char *)realloc(string, len);
@@ -350,7 +368,11 @@ C89STRINGUTILS_EXPORT int c89stringutils_vasprintf(char **str, const char *fmt,
350368
VA_COPY(ap2, ap);
351369
rc = vsnprintf(newstr, len, fmt, ap2);
352370
va_end(ap2);
353-
if (rc < 0 || (size_t)rc >= len) { /* failed with realloc'ed string */
371+
if (rc < 0) { /* failed with realloc'ed string */
372+
free(newstr);
373+
rc = -1;
374+
goto fail;
375+
} else if ((size_t)rc >= len) {
354376
free(newstr);
355377
rc = -1;
356378
goto fail;
@@ -360,23 +382,24 @@ C89STRINGUTILS_EXPORT int c89stringutils_vasprintf(char **str, const char *fmt,
360382
return rc;
361383

362384
fail:
363-
if (rc != 0) {
364385
#ifdef _MSC_VER
365-
char errbuf[256];
366-
int err_rc;
367-
err_rc = strerror_s(errbuf, sizeof(errbuf), errno);
368-
if (err_rc != 0) {
369-
LOG_DEBUG("strerror_s failed with rc=%d", err_rc);
370-
errbuf[0] = '\0';
371-
}
372-
LOG_DEBUG("vasprintf failed with rc=%d, error=%s", rc, errbuf);
386+
{
387+
char errbuf[256];
388+
int err_rc;
389+
err_rc = strerror_s(errbuf, sizeof(errbuf), errno);
390+
if (err_rc != 0) {
391+
LOG_DEBUG("strerror_s failed with rc=%d", err_rc);
392+
errbuf[0] = '\0';
393+
}
394+
LOG_DEBUG("vasprintf failed with rc=%d, error=%s", rc, errbuf);
395+
}
373396
#else
374-
const char *errstr;
375-
errstr = strerror(errno);
376-
LOG_DEBUG("vasprintf failed with rc=%d, error=%s", rc,
377-
errstr ? errstr : "");
397+
{
398+
const char *errstr;
399+
errstr = strerror(errno);
400+
LOG_DEBUG("vasprintf failed with rc=%d, error=%s", rc, errstr ? errstr : "");
401+
}
378402
#endif
379-
}
380403
*str = NULL;
381404
errno = ENOMEM;
382405
return -1;
@@ -490,7 +513,6 @@ C89STRINGUTILS_EXPORT int c89stringutils_jasprintf(char **unto, const char *fmt,
490513
#pragma GCC diagnostic pop
491514
#endif
492515

493-
494516
#if !defined(HAVE_ASPRINTF)
495517
C89STRINGUTILS_EXPORT int vasprintf(char **str, const char *fmt, va_list ap) {
496518
return c89stringutils_vasprintf(str, fmt, ap);

c89stringutils/c89stringutils_string_extras.h

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,38 @@ extern C89STRINGUTILS_EXPORT int c89stringutils_asprintf(char **str,
206206
extern C89STRINGUTILS_EXPORT int c89stringutils_jasprintf(char **unto,
207207
const char *fmt, ...);
208208

209-
210209
#if !defined(HAVE_ASPRINTF)
211-
extern C89STRINGUTILS_EXPORT int vasprintf(char **str, const char *fmt, va_list ap);
210+
/**
211+
* @brief Write formatted output to a dynamically allocated string using a
212+
* va_list.
213+
* @param str A pointer to a string pointer where the allocated string will be
214+
* stored.
215+
* @param fmt The format string.
216+
* @param ap The va_list of arguments.
217+
* @return The number of characters printed, or -1 on error.
218+
*/
219+
extern C89STRINGUTILS_EXPORT int vasprintf(char **str, const char *fmt,
220+
va_list ap);
221+
222+
/**
223+
* @brief Write formatted output to a dynamically allocated string.
224+
* @param str A pointer to a string pointer where the allocated string will be
225+
* stored.
226+
* @param fmt The format string.
227+
* @param ... The arguments.
228+
* @return The number of characters printed, or -1 on error.
229+
*/
212230
extern C89STRINGUTILS_EXPORT int asprintf(char **str, const char *fmt, ...);
213231
#endif
214232

233+
/**
234+
* @brief `jasprintf`, a version of `asprintf` that concatenates on successive
235+
* calls.
236+
* @param unto The string to append to.
237+
* @param fmt The format string.
238+
* @param ... The arguments.
239+
* @return The number of characters printed, or -1 on error.
240+
*/
215241
extern C89STRINGUTILS_EXPORT int jasprintf(char **unto, const char *fmt, ...);
216242

217243
#ifdef __cplusplus

c89stringutils/tests/CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,21 @@ endif (NOT CMAKE_SYSTEM_NAME STREQUAL "SunOS")
2626
set(Header_Files "test_string_extras.h")
2727
source_group("Header Files" FILES "${Header_Files}")
2828

29-
set(Source_Files "test.c")
29+
set(Source_Files "test.c" "${CMAKE_CURRENT_SOURCE_DIR}/../c89stringutils_string_extras.c")
3030
source_group("Source Files" FILES "${Source_Files}")
3131

3232
add_executable("${EXEC_NAME}" "${Header_Files}" "${Source_Files}")
3333

34-
target_link_libraries("${EXEC_NAME}" PRIVATE "${PROJECT_NAME}")
34+
target_compile_definitions("${EXEC_NAME}" PRIVATE C89STRINGUTILS_TEST_MOCKS)
35+
3536
if (NOT CMAKE_C_COMPILER_ID STREQUAL "OpenWatcom")
3637
target_link_libraries("${EXEC_NAME}" PRIVATE "${PROJECT_NAME}_compiler_flags")
3738
endif (NOT CMAKE_C_COMPILER_ID STREQUAL "OpenWatcom")
3839
target_include_directories(
3940
"${EXEC_NAME}"
4041
PRIVATE
42+
"${CMAKE_CURRENT_SOURCE_DIR}/.."
43+
"${CMAKE_BINARY_DIR}"
4144
"$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/src>"
4245
"$<BUILD_INTERFACE:${DOWNLOAD_DIR}>"
4346
)

c89stringutils/tests/test.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,42 @@
55
/* clang-format off */
66
#include <greatest.h>
77
#include <c89stringutils_log.h>
8+
#include <stdlib.h>
9+
#include <string.h>
10+
#include <stdio.h>
11+
#include <stdarg.h>
12+
13+
int g_mock_malloc_fail = 0;
14+
int g_mock_realloc_fail = 0;
15+
int g_mock_vsnprintf_fail = 0;
16+
int g_mock_vsnprintf_ret = 0;
17+
int g_mock_strerror_null = 0;
18+
19+
void *mock_malloc(size_t size) {
20+
if (g_mock_malloc_fail) return NULL;
21+
return malloc(size);
22+
}
23+
24+
void *mock_realloc(void *ptr, size_t size) {
25+
if (g_mock_realloc_fail) return NULL;
26+
return realloc(ptr, size);
27+
}
28+
29+
int g_mock_vsnprintf_fail_call = 0;
30+
int g_mock_vsnprintf_call_count = 0;
31+
int g_mock_vsnprintf_ret2 = 0; /* for second call */
32+
33+
int mock_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
34+
g_mock_vsnprintf_call_count++;
35+
if (g_mock_vsnprintf_fail_call == g_mock_vsnprintf_call_count) return g_mock_vsnprintf_ret2;
36+
if (g_mock_vsnprintf_fail) return g_mock_vsnprintf_ret < 0 ? -1 : g_mock_vsnprintf_ret;
37+
return vsnprintf(str, size, format, ap);
38+
}
39+
40+
char *mock_strerror(int errnum) {
41+
if (g_mock_strerror_null) return NULL;
42+
return strerror(errnum);
43+
}
844

945
#include "test_string_extras.h"
1046
/* clang-format on */

0 commit comments

Comments
 (0)