date decoding fixes and tests
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 2d53f4b..d882d99 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -2101,9 +2101,15 @@
    0xc0, // tag for string date
    0x6a, '1','9','8','5','-','0','4','-','1','2', // Date string
 
+   0xc0, // tag for string date
+   0x00, // Wrong type for a string date
+
    0xc1, // tag for epoch date
    0x1a, 0x53, 0x72, 0x4E, 0x00, // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
 
+   0xc1,
+   0x62, 'h', 'i', // wrong type tagged
+
    // CBOR_TAG_B64
    0xc1, 0xcf, 0xd8, 0x22, // 0xee, // Epoch date with extra tags
    0x1a, 0x53, 0x72, 0x4E, 0x01,
@@ -2122,10 +2128,20 @@
    //0xfa, 0x7f, 0x7f, 0xff, 0xff // 3.4028234663852886e+38 too large
 
    0xc1, // tag for epoch date
-   0xfb, 0x43, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe // 9223372036854773760 largest supported
+   0xfb, 0x43, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, // 9223372036854773760 largest supported
+
+   0xc1, // tag for epoch date
+   0xfa, 0x7f, 0xc0, 0x00, 0x00, // Single-precision NaN
+
+   0xc1,
+   0xfb, 0x7f,  0xf0,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // +infinity
+
+   0xc1, // tag for epoch date
+   0xf9, 0xfc, 0x00, // -Infinity
 };
 
 
+
 // have to check float expected only to within an epsilon
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
 static int CHECK_EXPECTED_DOUBLE(double val, double expected) {
@@ -2142,69 +2158,79 @@
 int32_t DateParseTest()
 {
    QCBORDecodeContext DCtx;
-   QCBORItem Item;
-   QCBORError nCBORError;
+   QCBORItem          Item;
+   QCBORError         uError;
 
    QCBORDecode_Init(&DCtx,
                     UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDateTestInput),
                     QCBOR_DECODE_MODE_NORMAL);
 
-   const uint64_t uTags[] = {15};
-   QCBORTagListIn TagList = {1, uTags};
-
-   QCBORDecode_SetCallerConfiguredTagList(&DCtx, &TagList);
-
    // String date
-   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+   if((uError = QCBORDecode_GetNext(&DCtx, &Item))) {
       return -1;
+   }
    if(Item.uDataType != QCBOR_TYPE_DATE_STRING ||
       UsefulBuf_Compare(Item.val.dateString, UsefulBuf_FromSZ("1985-04-12"))){
       return -2;
    }
 
-   // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
-   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
+   // Wrong type for a string date
+   uError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uError != QCBOR_ERR_BAD_OPT_TAG) {
       return -3;
+   }
+
+   // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
+   if((uError = QCBORDecode_GetNext(&DCtx, &Item))) {
+      return -4;
+   }
    if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
       Item.val.epochDate.nSeconds != 1400000000 ||
       Item.val.epochDate.fSecondsFraction != 0 ) {
-      return -4;
+      return -5;
+   }
+
+   // Wrong type for an epoch date
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_BAD_OPT_TAG) {
+      return -6;
    }
 
    // Epoch date with extra CBOR_TAG_B64 tag that doesn't really mean anything
    // but want to be sure extra tag doesn't cause a problem
-   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
-      return -5;
+   if((uError = QCBORDecode_GetNext(&DCtx, &Item))) {
+      return -7;
+   }
    if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
       Item.val.epochDate.nSeconds != 1400000001 ||
       Item.val.epochDate.fSecondsFraction != 0 ||
       !QCBORDecode_IsTagged(&DCtx, &Item, CBOR_TAG_B64)) {
-      return -6;
+      return -8;
    }
 
    // Epoch date that is too large for our representation
    if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
-      return -7;
+      return -9;
    }
 
-   // Epoch date in float format with fractional seconds
 #ifndef QCBOR_DISABLE_FLOAT_HW_USE
-   if((nCBORError = QCBORDecode_GetNext(&DCtx, &Item)))
-      return -8;
+   // Epoch date in float format with fractional seconds
+   if((uError = QCBORDecode_GetNext(&DCtx, &Item))) {
+      return -10;
+   }
    if(Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
       Item.val.epochDate.nSeconds != 1 ||
       CHECK_EXPECTED_DOUBLE(Item.val.epochDate.fSecondsFraction, 0.1 )) {
-      return -9;
+      return -11;
    }
 
    // Epoch date float that is too large for our representation
    if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
-      return -10;
+      return -12;
    }
 
    // Epoch date double that is just slightly too large
    if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
-      return -11;
+      return -13;
    }
 
    // Largest double epoch date supported
@@ -2212,30 +2238,188 @@
        Item.uDataType != QCBOR_TYPE_DATE_EPOCH ||
        Item.val.epochDate.nSeconds != 9223372036854773760 ||
        Item.val.epochDate.nSeconds == 0) {
-       return -12;
+       return -14;
     }
+
+   // Nan
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
+      return -15;
+   }
+
+   // +Inifinity double-precision
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
+      return -16;
+   }
+
+#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
+   // -Inifinity half-precision
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_DATE_OVERFLOW) {
+      return -17;
+   }
 #else
-   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
-      return -80;
-   }
-   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
-      return -80;
-   }
-   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
-      return -80;
-   }
-   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
-      return -80;
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_HALF_PRECISION_DISABLED) {
+      return -18;
    }
 #endif
 
+#else
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+      return -19;
+   }
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+      return -20;
+   }
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+      return -21;
+   }
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+      return -22;
+   }
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+      return -23;
+   }
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+      return -24;
+   }
+#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_FLOAT_DATE_DISABLED) {
+      return -25;
+   }
+#else
+   if(QCBORDecode_GetNext(&DCtx, &Item) != QCBOR_ERR_HALF_PRECISION_DISABLED) {
+      return -26;
+   }
+#endif
 
-   // TODO: could use a few more tests with float, double, and half precsion
-   // and negative (but coverage is still pretty good)
+#endif
 
    return 0;
 }
 
+
+static uint8_t spDateTestInput2[] = {
+   0xbf,
+
+   0x05,
+   0xc1, // tag for epoch date
+   0x1b, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // Too large integer
+
+   0x00,
+   0xc0, // tag for string date
+   0x6a, '1','9','8','5','-','0','4','-','1','2', // Date string
+
+   0x01,
+   0xc1, // tag for epoch date
+   0x1a, 0x53, 0x72, 0x4E, 0x00, // Epoch date 1400000000; Tue, 13 May 2014 16:53:20 GMT
+
+   // Untagged integer 0
+   0x08,
+   0x00,
+
+   // Utagged date string with string label y
+   0x61, 0x79,
+   0x6a, '2','0','8','5','-','0','4','-','1','2', // Date string
+
+   // Untagged -1000 with label z
+   0x61, 0x7a,
+   0x39, 0x03, 0xe7,
+
+#ifndef QCBOR_DISABLE_FLOAT_HW_USE
+   0x07,
+   0xc1, // tag for epoch date
+   0xfb, 0x43, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, // 9223372036854773760 largest supported
+
+   // Untagged single-precision float with value 3.14 with string label x
+   0x61, 0x78,
+   0xFA, 0x40, 0x48, 0xF5, 0xC3,
+
+#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
+   // Untagged half-precision float with value -2
+   0x09,
+   0xF9, 0xC0, 0x00,
+#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
+#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
+
+   0xff,
+};
+
+int32_t SpiffyDateDecodeTest()
+{
+   QCBORDecodeContext DC;
+   //QCBORItem Item;
+   QCBORError uError;
+   int64_t nEpochDate1, nEpochDate3, nEpochDate6;
+   UsefulBufC StringDate1, StringDate2;
+
+   QCBORDecode_Init(&DC,
+                    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(spDateTestInput2),
+                    QCBOR_DECODE_MODE_NORMAL);
+   QCBORDecode_EnterMap(&DC);
+   QCBORDecode_GetEpochDateInMapN(&DC, 5, QCBOR_TAG_REQUIREMENT_MATCH_TAG, &nEpochDate1);
+   uError = QCBORDecode_GetAndResetError(&DC);
+   if(uError == QCBOR_SUCCESS) {
+      return -999;
+   }
+   QCBORDecode_GetEpochDateInMapN(&DC, 1, QCBOR_TAG_REQUIREMENT_MATCH_TAG, &nEpochDate1);
+   QCBORDecode_GetDateStringInMapN(&DC, 0, QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG, &StringDate1);
+   QCBORDecode_GetEpochDateInMapN(&DC, 8, QCBOR_TAG_REQUIREMENT_NO_TAG, &nEpochDate3);
+   QCBORDecode_GetDateStringInMapSZ(&DC, "y", QCBOR_TAG_REQUIREMENT_NO_TAG, &StringDate2);
+   QCBORDecode_GetEpochDateInMapSZ(&DC, "z", QCBOR_TAG_REQUIREMENT_NO_TAG, &nEpochDate6);
+#ifndef QCBOR_DISABLE_FLOAT_HW_USE
+   int64_t nEpochDate5, nEpochDate2;
+   QCBORDecode_GetEpochDateInMapN(&DC, 7, QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG, &nEpochDate2);
+   QCBORDecode_GetEpochDateInMapSZ(&DC, "x", QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG, &nEpochDate5);
+#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
+   int64_t nEpochDate4;
+   QCBORDecode_GetEpochDateInMapN(&DC, 9, QCBOR_TAG_REQUIREMENT_OPTIONAL_TAG, &nEpochDate4);
+#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
+#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
+
+   QCBORDecode_ExitMap(&DC);
+   uError = QCBORDecode_Finish(&DC);
+   if(uError) {
+      return 1;
+   }
+
+   if(nEpochDate1 != 1400000000) {
+      return 100;
+   }
+
+   if(nEpochDate3 != 0) {
+      return 102;
+   }
+
+   if(nEpochDate6 != -1000) {
+      return 105;
+   }
+
+   if(UsefulBuf_Compare(StringDate1, UsefulBuf_FromSZ("1985-04-12"))) {
+      return 106;
+   }
+
+   if(UsefulBuf_Compare(StringDate2, UsefulBuf_FromSZ("2085-04-12"))) {
+      return 107;
+   }
+
+#ifndef QCBOR_DISABLE_FLOAT_HW_USE
+   if(nEpochDate2 != 9223372036854773760ULL) {
+      return 101;
+   }
+   if(nEpochDate5 != 3) {
+      return 104;
+   }
+#ifndef QCBOR_DISABLE_PREFERRED_FLOAT
+   if(nEpochDate4 != -2) {
+      return 103;
+   }
+#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
+#endif /* QCBOR_DISABLE_FLOAT_HW_USE */
+
+   return 0;
+}
+
+
+
 // Really simple basic input for tagging test
 static uint8_t spOptTestInput[] = {
    0xd9, 0xd9, 0xf7, // CBOR magic number
@@ -4724,9 +4908,15 @@
    if(Item.uDataType != QCBOR_TYPE_DATE_STRING) {
       return 2;
    }
-   
+
    // Get a second item
    uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
+   if(uCBORError != QCBOR_ERR_BAD_OPT_TAG) {
+      return 66;
+   }
+
+   // Get a third item
+   uCBORError = QCBORDecode_GetNext(&DCtx, &Item);
    if(uCBORError != QCBOR_SUCCESS) {
       return 2;
    }