Add user-defined/set errors; Fix minor VGetNext error handling bug

QCBORDecode_SetError() is added so QCBOR users can set an error and have it propagated up.

The data and label type of the item returned by VGetNext is correctly set to NONE when the error occurs right away, but was not set to NONE when the error occurred previously. This is fixed. This is a minor bug and only affected error handling use that relied solely on checking that the data and label were NONE.

Added more testing of error processing.


* Add SetError(); VGetNext error bug fix

* Documentation fixes

---------

Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 77514de..16ab10f 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -8829,3 +8829,85 @@
 
    return 0;
 }
+
+
+int32_t
+ErrorHandlingTests(void)
+{
+   QCBORDecodeContext DCtx;
+   QCBORItem          Item;
+   QCBORError         uError;
+   int64_t            integer;
+
+   /* Test QCBORDecode_SetError() */
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded),
+                    QCBOR_DECODE_MODE_NORMAL);
+
+   QCBORDecode_SetError(&DCtx, QCBOR_ERR_FIRST_USER_DEFINED);
+
+   QCBORDecode_VGetNext(&DCtx, &Item);
+
+   uError = QCBORDecode_GetError(&DCtx);
+
+   if(uError != QCBOR_ERR_FIRST_USER_DEFINED) {
+      return -1;
+   }
+
+   if(Item.uLabelType != QCBOR_TYPE_NONE ||
+      Item.uDataType != QCBOR_TYPE_NONE) {
+      return -2;
+   }
+
+
+   /* Test data type returned from previous error */
+   QCBORDecode_Init(&DCtx,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pValidMapEncoded),
+                    QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_GetInt64(&DCtx, &integer);
+   uError = QCBORDecode_GetError(&DCtx);
+   if(uError != QCBOR_ERR_UNEXPECTED_TYPE) {
+      return -3;
+   }
+
+   QCBORDecode_VGetNext(&DCtx, &Item);
+   if(Item.uLabelType != QCBOR_TYPE_NONE ||
+      Item.uDataType != QCBOR_TYPE_NONE) {
+      return -2;
+   }
+   uError = QCBORDecode_GetError(&DCtx);
+   if(uError != QCBOR_ERR_UNEXPECTED_TYPE) {
+      return -3;
+   }
+
+
+   /* Test error classification functions */
+
+   if(!QCBORDecode_IsUnrecoverableError(QCBOR_ERR_INDEFINITE_STRING_CHUNK)) {
+      return -10;
+   }
+   if(QCBORDecode_IsUnrecoverableError(QCBOR_SUCCESS)) {
+      return -11;
+   }
+   if(!QCBORDecode_IsUnrecoverableError(QCBOR_ERR_INDEFINITE_STRING_CHUNK)) {
+      return -12;
+   }
+   if(QCBORDecode_IsUnrecoverableError(QCBOR_ERR_DUPLICATE_LABEL)) {
+      return -13;
+   }
+
+   if(!QCBORDecode_IsNotWellFormedError(QCBOR_ERR_BAD_TYPE_7)) {
+      return -20;
+   }
+   if(!QCBORDecode_IsNotWellFormedError(QCBOR_ERR_BAD_BREAK)) {
+      return -21;
+   }
+   if(QCBORDecode_IsNotWellFormedError(QCBOR_SUCCESS)) {
+      return -22;
+   }
+   if(QCBORDecode_IsNotWellFormedError(QCBOR_ERR_ARRAY_DECODE_TOO_LONG)) {
+      return -23;
+   }
+
+   return 0;
+}