Make RunTest() handle newlines in a portable way
Rather than just outputting \n for a newline, there
is now a way the caller of RunTest() to implement
newline however they want, for example using \r\n
on Windows and \n Linux.
diff --git a/QCBOR.xcodeproj/project.pbxproj b/QCBOR.xcodeproj/project.pbxproj
index 9c5a03a..cc2614c 100644
--- a/QCBOR.xcodeproj/project.pbxproj
+++ b/QCBOR.xcodeproj/project.pbxproj
@@ -45,7 +45,7 @@
E73B575B2161CA7C0080D658 /* half_to_double_from_rfc7049.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = half_to_double_from_rfc7049.h; path = test/half_to_double_from_rfc7049.h; sourceTree = "<group>"; };
E73B575C2161CA7C0080D658 /* float_tests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = float_tests.h; path = test/float_tests.h; sourceTree = "<group>"; };
E73B575D2161CA7C0080D658 /* half_to_double_from_rfc7049.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = half_to_double_from_rfc7049.c; path = test/half_to_double_from_rfc7049.c; sourceTree = "<group>"; };
- E73B57632161F8F70080D658 /* run_tests.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = run_tests.c; path = test/run_tests.c; sourceTree = "<group>"; };
+ E73B57632161F8F70080D658 /* run_tests.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.c; name = run_tests.c; path = test/run_tests.c; sourceTree = "<group>"; tabWidth = 3; };
E73B57642161F8F80080D658 /* run_tests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = run_tests.h; path = test/run_tests.h; sourceTree = "<group>"; };
E776E07C214ADF7F00E67947 /* QCBOR */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = QCBOR; sourceTree = BUILT_PRODUCTS_DIR; };
E776E08C214AE07400E67947 /* qcbor_encode.c */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 3; lastKnownFileType = sourcecode.c.c; name = qcbor_encode.c; path = src/qcbor_encode.c; sourceTree = "<group>"; tabWidth = 3; };
diff --git a/cmd_line_main.c b/cmd_line_main.c
index f9678cd..22817dd 100644
--- a/cmd_line_main.c
+++ b/cmd_line_main.c
@@ -42,9 +42,12 @@
This is an implementation of OutputStringCB built using stdio. If
you don't have stdio, replaces this is
*/
-static void fputs_wrapper(const char *szString, void *ctx)
+static void fputs_wrapper(const char *szString, void *pOutCtx, int bNewLine)
{
- fputs(szString, (FILE *)ctx);
+ fputs(szString, (FILE *)pOutCtx);
+ if(bNewLine) {
+ fputs("\n", pOutCtx);
+ }
}
diff --git a/test/run_tests.c b/test/run_tests.c
index 0297de9..c2816ba 100644
--- a/test/run_tests.c
+++ b/test/run_tests.c
@@ -202,19 +202,19 @@
const char * szTestResult = (t2->test_fun)();
nTestsRun++;
if(pfOutput) {
- (*pfOutput)(t2->szTestName, poutCtx);
+ (*pfOutput)(t2->szTestName, poutCtx, 0);
}
if(szTestResult) {
if(pfOutput) {
- (*pfOutput)(" FAILED (returned ", poutCtx);
- (*pfOutput)(szTestResult, poutCtx);
- (*pfOutput)(")\n", poutCtx);
+ (*pfOutput)(" FAILED (returned ", poutCtx, 0);
+ (*pfOutput)(szTestResult, poutCtx, 0);
+ (*pfOutput)(")\n", poutCtx, 1);
}
nTestsFailed++;
} else {
if(pfOutput) {
- (*pfOutput)( " PASSED\n", poutCtx);
+ (*pfOutput)( " PASSED", poutCtx, 1);
}
}
}
@@ -248,19 +248,19 @@
int nTestResult = (t->test_fun)();
nTestsRun++;
if(pfOutput) {
- (*pfOutput)(t->szTestName, poutCtx);
+ (*pfOutput)(t->szTestName, poutCtx, 0);
}
if(nTestResult) {
if(pfOutput) {
- (*pfOutput)(" FAILED (returned ", poutCtx);
- (*pfOutput)(NumToString(nTestResult, StringStorage), poutCtx);
- (*pfOutput)(")\n", poutCtx);
+ (*pfOutput)(" FAILED (returned ", poutCtx, 0);
+ (*pfOutput)(NumToString(nTestResult, StringStorage), poutCtx, 0);
+ (*pfOutput)(")", poutCtx, 1);
}
nTestsFailed++;
} else {
if(pfOutput) {
- (*pfOutput)( " PASSED\n", poutCtx);
+ (*pfOutput)( " PASSED", poutCtx, 1);
}
}
}
@@ -270,11 +270,11 @@
}
if(pfOutput) {
- (*pfOutput)( "SUMMARY: ", poutCtx);
- (*pfOutput)( NumToString(nTestsRun, StringStorage), poutCtx);
- (*pfOutput)( " tests run; ", poutCtx);
- (*pfOutput)( NumToString(nTestsFailed, StringStorage), poutCtx);
- (*pfOutput)( " tests failed\n", poutCtx);
+ (*pfOutput)( "SUMMARY: ", poutCtx, 0);
+ (*pfOutput)( NumToString(nTestsRun, StringStorage), poutCtx, 0);
+ (*pfOutput)( " tests run; ", poutCtx, 0);
+ (*pfOutput)( NumToString(nTestsFailed, StringStorage), poutCtx, 0);
+ (*pfOutput)( " tests failed", poutCtx, 1);
}
return nTestsFailed;
@@ -285,24 +285,24 @@
static void PrintSize(const char *szWhat, uint32_t uSize, OutputStringCB pfOutput, void *pOutCtx)
{
- UsefulBuf_MAKE_STACK_UB(foo, 20);
+ UsefulBuf_MAKE_STACK_UB(buffer, 20);
- (*pfOutput)(szWhat, pOutCtx);
- (*pfOutput)(" ", pOutCtx);
- (*pfOutput)(NumToString(uSize,foo), pOutCtx);
- (*pfOutput)("\n", pOutCtx);
+ (*pfOutput)(szWhat, pOutCtx, 0);
+ (*pfOutput)(" ", pOutCtx, 0);
+ (*pfOutput)(NumToString(uSize, buffer), pOutCtx, 0);
+ (*pfOutput)("", pOutCtx, 1);
}
void PrintSizes(OutputStringCB pfOutput, void *pOutCtx)
{
- // Type and size of return from sizeof() varies. These will never be large so cast is safe
- PrintSize("sizeof(QCBORTrackNesting)", (uint32_t)sizeof(QCBORTrackNesting), pfOutput, pOutCtx);
- PrintSize("sizeof(QCBOREncodeContext)", (uint32_t)sizeof(QCBOREncodeContext), pfOutput, pOutCtx);
- PrintSize("sizeof(QCBORDecodeNesting)", (uint32_t)sizeof(QCBORDecodeNesting), pfOutput, pOutCtx);
- PrintSize("sizeof(QCBORDecodeContext)", (uint32_t)sizeof(QCBORDecodeContext), pfOutput, pOutCtx);
- PrintSize("sizeof(QCBORItem)", (uint32_t)sizeof(QCBORItem), pfOutput, pOutCtx);
- PrintSize("sizeof(QCBORStringAllocator)", (uint32_t)sizeof(QCBORStringAllocator), pfOutput, pOutCtx);
- PrintSize("sizeof(QCBORTagListIn)", (uint32_t)sizeof(QCBORTagListIn), pfOutput, pOutCtx);
- PrintSize("sizeof(QCBORTagListOut)", (uint32_t)sizeof(QCBORTagListOut), pfOutput, pOutCtx);
- (*pfOutput)("\n", pOutCtx);
+ // Type and size of return from sizeof() varies. These will never be large so cast is safe
+ PrintSize("sizeof(QCBORTrackNesting)", (uint32_t)sizeof(QCBORTrackNesting), pfOutput, pOutCtx);
+ PrintSize("sizeof(QCBOREncodeContext)", (uint32_t)sizeof(QCBOREncodeContext), pfOutput, pOutCtx);
+ PrintSize("sizeof(QCBORDecodeNesting)", (uint32_t)sizeof(QCBORDecodeNesting), pfOutput, pOutCtx);
+ PrintSize("sizeof(QCBORDecodeContext)", (uint32_t)sizeof(QCBORDecodeContext), pfOutput, pOutCtx);
+ PrintSize("sizeof(QCBORItem)", (uint32_t)sizeof(QCBORItem), pfOutput, pOutCtx);
+ PrintSize("sizeof(QCBORStringAllocator)",(uint32_t)sizeof(QCBORStringAllocator), pfOutput, pOutCtx);
+ PrintSize("sizeof(QCBORTagListIn)", (uint32_t)sizeof(QCBORTagListIn), pfOutput, pOutCtx);
+ PrintSize("sizeof(QCBORTagListOut)", (uint32_t)sizeof(QCBORTagListOut), pfOutput, pOutCtx);
+ (*pfOutput)("", pOutCtx, 1);
}
diff --git a/test/run_tests.h b/test/run_tests.h
index ae1b9d7..438d55e 100644
--- a/test/run_tests.h
+++ b/test/run_tests.h
@@ -1,6 +1,6 @@
/*==============================================================================
- run_tests.c -- test aggregator and results reporting
+ run_tests.h -- test aggregator and results reporting
Created 9/30/18.
@@ -34,28 +34,41 @@
==============================================================================*/
+
+
/**
@brief Type for function to output a text string
@param[in] szString The string to output
@param[in] pOutCtx A context pointer; NULL if not needed
+ @param[in] bNewline If non-zero, output a newline after the string
- This is a prototype of a function to be passed to run_tests() to
+ This is a prototype of a function to be passed to RunTests() to
output text strings. This can be implemented with stdio (if
available) using a straight call to fputs() where the FILE *
is passed as the ctx.
+
+ @code
+ static void fputs_wrapper(const char *szString, void *pOutCtx, int bNewLine)
+ {
+ fputs(szString, (FILE *)pOutCtx);
+ if(bNewLine) {
+ fputs("\n", pOutCtx);
+ }
+ }
+ @endcode
*/
-typedef void (*OutputStringCB)(const char *szString, void *pOutCtx);
+typedef void (*OutputStringCB)(const char *szString, void *pOutCtx, int bNewline);
/**
- @brief Runs the QCBOR tests
+ @brief Runs the QCBOR tests.
- @param[in] szTestNames An argv-style list of test names to run. If
- empty, all are run.
- @param[in] pfOutput Function that is called to output text strings.
- @param[in] pOutCtx Context pointer passed to output function.
- @param[out] pNumTestsRun Returns the number of tests run. May be NULL.
+ @param[in] szTestNames An argv-style list of test names to run. If
+ empty, all are run.
+ @param[in] pfOutput Function that is called to output text strings.
+ @param[in] pOutCtx Context pointer passed to output function.
+ @param[out] pNumTestsRun Returns the number of tests run. May be NULL.
@return The number of tests that failed. Zero means overall success.
*/
@@ -65,8 +78,8 @@
/**
@brief Print sizes of encoder / decoder contexts.
- @param[in] pfOutput Function that is called to output text strings.
- @param[in] pOutCtx Context pointer passed to output function.
+ @param[in] pfOutput Function that is called to output text strings.
+ @param[in] pOutCtx Context pointer passed to output function.
*/
void PrintSizes(OutputStringCB pfOutput, void *pOutCtx);