Skip to content

Commit e46fc73

Browse files
committed
C89, CMake, and strict MSVC warnings compilation fixes
- Resolved C4996 deprecation warnings on MSVC by safely utilizing _vsnprintf_s and SafeCRT fallbacks. - Upgraded vsscanf and vfscanf internal fallbacks to transparently use strncpy_s, sscanf_s, etc. - Patched greatest.h via CMake to mitigate C4127 constant conditional errors. - Replaced standard snprintf test calls with internal macros for legacy toolchain support.
1 parent 0023f35 commit e46fc73

5 files changed

Lines changed: 114 additions & 29 deletions

File tree

‎c89stringutils/c89stringutils_safecrt.c‎

Lines changed: 89 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,23 @@ static int minimal_vsscanf(const char *buffer, const char *format,
104104
len = (size_t)(p - start);
105105
if (len > 60)
106106
return -1;
107+
#if defined(C89STRINGUTILS_HAVE_STRNCPY_S)
108+
strncpy_s(token, sizeof(token), start, len);
109+
#else
107110
strncpy(token, start, len);
108111
token[len] = '\0';
112+
#endif
113+
#if defined(C89STRINGUTILS_HAVE_STRCAT_S)
114+
strcat_s(token, sizeof(token), "%n");
115+
#else
109116
strcat(token, "%n");
117+
#endif
110118
consumed = 0;
119+
#if defined(_MSC_VER) && _MSC_VER >= 1400
120+
if (sscanf_s(b, token, &consumed) < 0 || consumed == 0)
121+
#else
111122
if (sscanf(b, token, &consumed) < 0 || consumed == 0)
123+
#endif
112124
return count;
113125
b += consumed;
114126
continue;
@@ -125,19 +137,44 @@ static int minimal_vsscanf(const char *buffer, const char *format,
125137
while (*p && *p != ']')
126138
p++;
127139
}
128-
if (*p)
129-
p++;
130-
len = (size_t)(p - start);
131-
if (len > 60)
132-
return -1;
133-
strncpy(token, start, len);
134-
token[len] = '\0';
135-
strcat(token, "%n");
136-
137-
ptr = va_arg(args, void *);
138-
consumed = 0;
139-
if (sscanf(b, token, ptr, &consumed) <= 0 || consumed == 0)
140-
return count;
140+
{
141+
char spec = *(p - 1);
142+
unsigned sz = 0;
143+
if (*p)
144+
p++;
145+
len = (size_t)(p - start);
146+
if (len > 60)
147+
return -1;
148+
spec = *(p - 1); /* get the specifier */
149+
#if defined(C89STRINGUTILS_HAVE_STRNCPY_S)
150+
strncpy_s(token, sizeof(token), start, len);
151+
#else
152+
strncpy(token, start, len);
153+
token[len] = '\0';
154+
#endif
155+
#if defined(C89STRINGUTILS_HAVE_STRCAT_S)
156+
strcat_s(token, sizeof(token), "%n");
157+
#else
158+
strcat(token, "%n");
159+
#endif
160+
ptr = va_arg(args, void *);
161+
if (spec == 's' || spec == 'c' || spec == '[') {
162+
sz = va_arg(args, unsigned);
163+
}
164+
consumed = 0;
165+
#if defined(_MSC_VER) && _MSC_VER >= 1400
166+
if (spec == 's' || spec == 'c' || spec == '[') {
167+
if (sscanf_s(b, token, ptr, sz, &consumed) <= 0 || consumed == 0)
168+
return count;
169+
} else {
170+
if (sscanf_s(b, token, ptr, &consumed) <= 0 || consumed == 0)
171+
return count;
172+
}
173+
#else
174+
if (sscanf(b, token, ptr, &consumed) <= 0 || consumed == 0)
175+
return count;
176+
#endif
177+
}
141178
b += consumed;
142179
count++;
143180
}
@@ -206,11 +243,17 @@ static int minimal_vfscanf(FILE *stream, const char *format, va_list args) {
206243
len = (size_t)(p - start);
207244
if (len > 60)
208245
return -1;
246+
#if defined(C89STRINGUTILS_HAVE_STRNCPY_S)
247+
strncpy_s(token, sizeof(token), start, len);
248+
#else
209249
strncpy(token, start, len);
210250
token[len] = '\0';
211-
#if defined(__GNUC__) || defined(__clang__)
212251
#endif
252+
#if defined(_MSC_VER) && _MSC_VER >= 1400
253+
if (fscanf_s(stream, token) < 0)
254+
#else
213255
if (fscanf(stream, token) < 0)
256+
#endif
214257
return count;
215258
#if defined(__GNUC__) || defined(__clang__)
216259
#endif
@@ -228,17 +271,38 @@ static int minimal_vfscanf(FILE *stream, const char *format, va_list args) {
228271
while (*p && *p != ']')
229272
p++;
230273
}
231-
if (*p)
232-
p++;
233-
len = (size_t)(p - start);
234-
if (len > 60)
235-
return -1;
236-
strncpy(token, start, len);
237-
token[len] = '\0';
238-
239-
ptr = va_arg(args, void *);
240-
if (fscanf(stream, token, ptr) <= 0)
241-
return count;
274+
{
275+
char spec = *(p - 1);
276+
unsigned sz = 0;
277+
if (*p)
278+
p++;
279+
len = (size_t)(p - start);
280+
if (len > 60)
281+
return -1;
282+
spec = *(p - 1);
283+
#if defined(C89STRINGUTILS_HAVE_STRNCPY_S)
284+
strncpy_s(token, sizeof(token), start, len);
285+
#else
286+
strncpy(token, start, len);
287+
token[len] = '\0';
288+
#endif
289+
ptr = va_arg(args, void *);
290+
if (spec == 's' || spec == 'c' || spec == '[') {
291+
sz = va_arg(args, unsigned);
292+
}
293+
#if defined(_MSC_VER) && _MSC_VER >= 1400
294+
if (spec == 's' || spec == 'c' || spec == '[') {
295+
if (fscanf_s(stream, token, ptr, sz) <= 0)
296+
return count;
297+
} else {
298+
if (fscanf_s(stream, token, ptr) <= 0)
299+
return count;
300+
}
301+
#else
302+
if (fscanf(stream, token, ptr) <= 0)
303+
return count;
304+
#endif
305+
}
242306
count++;
243307
}
244308
}

‎c89stringutils/c89stringutils_string_extras.c‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
#include "c89stringutils_safecrt.h"
1414
#include "c89stringutils_log.h"
1515

16+
#if defined(_MSC_VER)
17+
#undef C89STRINGUTILS_HAVE_VSNPRINTF
18+
#undef C89STRINGUTILS_HAVE__VSNPRINTF
19+
#endif
20+
1621
#include <stdarg.h>
1722
#include <stdio.h>
1823
#include <stdlib.h>

‎c89stringutils/tests/CMakeLists.txt‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "SunOS")
1717
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../greatest"
1818
)
1919
FetchContent_MakeAvailable(greatest)
20+
if (MSVC)
21+
file(READ "${greatest_SOURCE_DIR}/greatest.h" _greatest_content)
22+
string(REPLACE "while (0)" "while (0,0)" _greatest_content "${_greatest_content}")
23+
file(WRITE "${greatest_SOURCE_DIR}/greatest.h" "${_greatest_content}")
24+
endif()
2025
file(COPY "${greatest_SOURCE_DIR}/greatest.h" DESTINATION "${DOWNLOAD_DIR}")
2126
else()
2227
FetchContent_Declare(
@@ -25,6 +30,11 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "SunOS")
2530
DOWNLOAD_NO_EXTRACT TRUE
2631
)
2732
FetchContent_MakeAvailable(greatest)
33+
if (MSVC)
34+
file(READ "${greatest_SOURCE_DIR}/greatest.h" _greatest_content)
35+
string(REPLACE "while (0)" "while (0,0)" _greatest_content "${_greatest_content}")
36+
file(WRITE "${greatest_SOURCE_DIR}/greatest.h" "${_greatest_content}")
37+
endif()
2838
file(COPY "${greatest_SOURCE_DIR}/greatest.h" DESTINATION "${DOWNLOAD_DIR}")
2939
endif()
3040
endif (NOT CMAKE_SYSTEM_NAME STREQUAL "SunOS")

‎c89stringutils/tests/test.c‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,15 +135,19 @@ int mock_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
135135
if (str == NULL) {
136136
/* Need a valid buffer for vsprintf if vsnprintf is missing, but cygwin has
137137
* vsnprintf */
138-
#if defined(__CYGWIN__) || defined(__linux__) || defined(__APPLE__) || \
138+
#if defined(_MSC_VER)
139+
ret = _vscprintf(format, ap);
140+
#elif defined(__CYGWIN__) || defined(__linux__) || defined(__APPLE__) || \
139141
defined(_WIN32)
140142
ret = vsnprintf(NULL, 0, format, ap);
141143
#else
142144
char dummy[1024];
143145
ret = vsprintf(dummy, format, ap);
144146
#endif
145147
} else {
146-
#if defined(__CYGWIN__) || defined(__linux__) || defined(__APPLE__) || \
148+
#if defined(_MSC_VER)
149+
ret = _vsnprintf_s(str, size, (size_t)-1, format, ap);
150+
#elif defined(__CYGWIN__) || defined(__linux__) || defined(__APPLE__) || \
147151
defined(_WIN32)
148152
ret = vsnprintf(str, size, format, ap);
149153
#else
@@ -198,7 +202,9 @@ int mock_vsnprintf_s(char *buffer, size_t sizeOfBuffer, size_t count,
198202
*/
199203
int mock_vsprintf(char *buffer, const char *format, va_list ap) {
200204
int ret;
201-
#if defined(__APPLE__) || defined(__CYGWIN__) || defined(__linux__) || \
205+
#if defined(_MSC_VER)
206+
ret = _vsnprintf_s(buffer, 9999, (size_t)-1, format, ap);
207+
#elif defined(__APPLE__) || defined(__CYGWIN__) || defined(__linux__) || \
202208
defined(_WIN32)
203209
ret = vsnprintf(buffer, 9999, format, ap);
204210
#else

‎c89stringutils/tests/test_string_extras.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ TEST x_mock_failures(void) {
697697
/* Cover missing paths */
698698
{
699699
char dummy[10];
700-
snprintf(dummy, 10, "test");
700+
c89stringutils_snprintf(dummy, 10, "test");
701701
#if !defined(C89STRINGUTILS_HAVE_STRCASESTR) || \
702702
defined(C89STRINGUTILS_FORCE_FALLBACKS)
703703
c89stringutils_strcasestr(NULL, "a");

0 commit comments

Comments
 (0)