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/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);