merge and #ifdef fan out fixes
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 49af24a..30253c2 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -107,7 +107,7 @@
    return uDataType == QCBOR_TYPE_MAP ||
 #ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
           uDataType == QCBOR_TYPE_MAP_AS_ARRAY ||
-#endif
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
           uDataType == QCBOR_TYPE_ARRAY;
 }
 
@@ -152,6 +152,7 @@
       if(Item2.uLabelType == QCBOR_TYPE_INT64 && Item1.label.int64 == Item2.label.int64) {
          return true;
       }
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
    } else if(Item1.uLabelType == QCBOR_TYPE_TEXT_STRING) {
       if(Item2.uLabelType == QCBOR_TYPE_TEXT_STRING && !UsefulBuf_Compare(Item1.label.string, Item2.label.string)) {
          return true;
@@ -164,6 +165,7 @@
       if(Item2.uLabelType == QCBOR_TYPE_UINT64 && Item1.label.uint64 == Item2.label.uint64) {
          return true;
       }
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
    }
 
    /* Other label types are never matched */
@@ -379,7 +381,7 @@
    if(uItemDataType == QCBOR_TYPE_MAP_AS_ARRAY) {
       uItemDataType = QCBOR_TYPE_ARRAY;
    }
-#endif
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
 
    if(uItemDataType != uType) {
       return false;
@@ -1089,43 +1091,50 @@
 /**
  * @brief Decode text and byte strings
  *
- * @param[in] pAllocator     The string allocator or NULL.
+ * @param[in] pMe            Decoder context.
+ * @param[in] bAllocate      Whether to allocate and copy string.
+ * @param[in] nMajorType     Whether it is a byte or text string.
  * @param[in] uStrLen        The length of the string.
- * @param[in] pUInBuf        The surce from which to read the string's bytes.
- * @param[out] pDecodedItem  The filled in decoded item.
+ * @param[in] nAdditionalInfo Whether it is an indefinite-length string.
+ * @param[out] pDecodedItem  The filled-in decoded item.
  *
  * @retval QCBOR_ERR_HIT_END          Unexpected end of input.
  * @retval QCBOR_ERR_STRING_ALLOCATE  Out of memory.
  * @retval QCBOR_ERR_STRING_TOO_LONG  String longer than SIZE_MAX - 4.
+ * @retval QCBOR_ERR_NO_STRING_ALLOCATOR  Allocation requested, but no allocator
  *
- * The reads @c uStrlen bytes from @c pUInBuf and fills in @c
- * pDecodedItem. If @c pAllocator is not NULL then memory for the
- * string is allocated.
+ * This reads @c uStrlen bytes from the input and fills in @c
+ * pDecodedItem. If @c bAllocate is true, then memory for the string
+ * is allocated.
  */
 static QCBORError
-QCBOR_Private_DecodeBytes(const QCBORInternalAllocator *pAllocator,
-                          int                           nMajorType,
-                          const uint64_t                uStrLen,
-                          int                           nAdditionalInfo,
-                          UsefulInputBuf               *pUInBuf,
-                          QCBORItem                    *pDecodedItem)
+QCBOR_Private_DecodeString(QCBORDecodeContext           *pMe,
+                           const bool                    bAllocate,
+                           const int                     nMajorType,
+                           const uint64_t                uStrLen,
+                           const int                     nAdditionalInfo,
+                           QCBORItem                    *pDecodedItem)
 {
    QCBORError uReturn = QCBOR_SUCCESS;
 
+   /* ---- Figure out the major type ---- */
    #if CBOR_MAJOR_TYPE_BYTE_STRING + 4 != QCBOR_TYPE_BYTE_STRING
-   #error QCBOR_TYPE_BYTE_STRING no lined up with major type
+   #error QCBOR_TYPE_BYTE_STRING not lined up with major type
    #endif
 
    #if CBOR_MAJOR_TYPE_TEXT_STRING + 4 != QCBOR_TYPE_TEXT_STRING
-   #error QCBOR_TYPE_TEXT_STRING no lined up with major type
+   #error QCBOR_TYPE_TEXT_STRING not lined up with major type
    #endif
    pDecodedItem->uDataType = (uint8_t)(nMajorType + 4);
 
-
    if(nAdditionalInfo == LEN_IS_INDEFINITE) {
+      /* --- Just the head of an indefinite-length string --- */
       pDecodedItem->val.string = (UsefulBufC){NULL, QCBOR_STRING_LENGTH_INDEFINITE};
 
    } else {
+      /* --- A definite-length string --- */
+      /* --- (which might be a chunk of an indefinte-length string) --- */
+
       /* CBOR lengths can be 64 bits, but size_t is not 64 bits on all
        * CPUs.  This check makes the casts to size_t below safe.
        *
@@ -1138,7 +1147,7 @@
          goto Done;
       }
 
-      const UsefulBufC Bytes = UsefulInputBuf_GetUsefulBuf(pUInBuf, (size_t)uStrLen);
+      const UsefulBufC Bytes = UsefulInputBuf_GetUsefulBuf(&(pMe->InBuf), (size_t)uStrLen);
       if(UsefulBuf_IsNULLC(Bytes)) {
          /* Failed to get the bytes for this string item */
          uReturn = QCBOR_ERR_HIT_END;
@@ -1146,14 +1155,21 @@
       }
 
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS
-      /* Note that this is not where allocation to coalesce
-       * indefinite-length strings is done. This is for when the caller
-       * has requested all strings be allocated. Disabling indefinite
-       * length strings also disables this allocate-all option.
-       */
-      if(pAllocator) {
-         /* request to use the string allocator to make a copy */
-         UsefulBuf NewMem = StringAllocator_Allocate(pAllocator, (size_t)uStrLen);
+       if(bAllocate) {
+          /* --- Put string in allocated memory --- */
+
+          /* Note that this is not where allocation to coalesce
+           * indefinite-length strings is done. This is for when the
+           * caller has requested all strings be allocated. Disabling
+           * indefinite length strings also disables this allocate-all
+           * option.
+           */
+
+          if(pMe->StringAllocator.pfAllocator == NULL) {
+            uReturn = QCBOR_ERR_NO_STRING_ALLOCATOR;
+            goto Done;
+         }
+         UsefulBuf NewMem = StringAllocator_Allocate(&(pMe->StringAllocator), (size_t)uStrLen);
          if(UsefulBuf_IsNULL(NewMem)) {
             uReturn = QCBOR_ERR_STRING_ALLOCATE;
             goto Done;
@@ -1162,11 +1178,11 @@
          pDecodedItem->uDataAlloc = 1;
          goto Done;
       }
-#else /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
-      (void)pAllocator;
+#else
+      (void)bAllocate;
 #endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
 
-      /* Normal case with no string allocator */
+      /* --- Normal case with no string allocator --- */
       pDecodedItem->val.string = Bytes;
    }
 
@@ -1177,7 +1193,25 @@
 
 
 
-
+/**
+ * @brief Decode array or map.
+ *
+ * @param[in] uMode            Decoder mode.
+ * @param[in] nMajorType     Whether it is a byte or text string.
+ * @param[in] uItemCount        The length of the string.
+ * @param[in] nAdditionalInfo Whether it is an indefinite-length.
+ * @param[out] pDecodedItem  The filled-in decoded item.
+ *
+ * @retval QCBOR_ERR_INDEF_LEN_ARRAYS_DISABLED Indefinites disabled.
+ * @retval QCBOR_ERR_ARRAY_DECODE_TOO_LONG     Too many items in array/map.
+ *
+ * Not much to do for arrays and maps. Just the type
+ * item count.
+ *
+ * This also does the bulk of the work for QCBOR_DECODE_MODE_MAP_AS_ARRAY,
+ * a special mode to handle arbitrarily complex map labels. This
+ * ifdefs out with QCBOR_DISABLE_NON_INTEGER_LABELS.
+ */
 static QCBORError
 QCBOR_Private_DecodeArrayOrMap(const uint8_t  uMode,
                                const int      nMajorType,
@@ -1202,12 +1236,12 @@
    }
 #else
    (void)uMode;
-#endif
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
 
    uReturn = QCBOR_SUCCESS;
 
    if(nAdditionalInfo == LEN_IS_INDEFINITE) {
-      /* ------ Indefinite-length arra/map ----- */
+      /* ------ Indefinite-length array/map ----- */
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS
       pDecodedItem->val.uCount = QCBOR_COUNT_INDICATES_INDEFINITE_LENGTH;
 #else /* QCBOR_DISABLE_INDEFINITE_LENGTH_ARRAYS */
@@ -1227,7 +1261,7 @@
          }
 
       } else
-#endif
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
       {
          /* ------ Definite-length array/map ------ */
          if(uItemCount > QCBOR_MAX_ITEMS_IN_ARRAY) {
@@ -1248,7 +1282,7 @@
  *
  * param[in] pUInBuf       Input buffer to read data item from.
  * @param[out] pDecodedItem  The filled-in decoded item.
- * @param[in] pAllocator    The allocator to use for strings or NULL.
+ * param[in] pAllocator    The allocator to use for strings or NULL.
  *
  * @retval QCBOR_ERR_UNSUPPORTED             Encountered unsupported/reserved
  *                                           features
@@ -1271,8 +1305,8 @@
  */
 static QCBORError
 QCBOR_Private_DecodeAtomicDataItem(QCBORDecodeContext           *pMe,
-                                   QCBORItem                    *pDecodedItem,
-                                   const QCBORInternalAllocator *pAllocator)
+                                   const bool                    bAllocateStrings,
+                                   QCBORItem                    *pDecodedItem)
 {
    QCBORError uReturn;
 
@@ -1300,7 +1334,7 @@
 
       case CBOR_MAJOR_TYPE_BYTE_STRING: /* Major type 2 */
       case CBOR_MAJOR_TYPE_TEXT_STRING: /* Major type 3 */
-         uReturn = QCBOR_Private_DecodeBytes(pAllocator, nMajorType, uArgument, nAdditionalInfo, &(pMe->InBuf), pDecodedItem);
+         uReturn = QCBOR_Private_DecodeString(pMe, bAllocateStrings, nMajorType, uArgument, nAdditionalInfo, pDecodedItem);
          break;
 
       case CBOR_MAJOR_TYPE_ARRAY: /* Major type 4 */
@@ -1376,57 +1410,26 @@
     *   QCBORItem                                     56          52
     *   TOTAL                                        120          74
     */
-
-   /* The string allocator is used here for two purposes: 1)
-    * coalescing the chunks of an indefinite-length string, 2)
-    * allocating storage for every string returned when requested.
-    *
-    * The first use is below in this function. Indefinite-length
-    * strings cannot be processed at all without a string allocator.
-    *
-    * The second used is in DecodeBytes() which is called by
-    * GetNext_Item() below. This second use unneccessary for most use
-    * and only happens when requested in the call to
-    * QCBORDecode_SetMemPool(). If the second use not requested then
-    * NULL is passed for the string allocator to GetNext_Item().
-    *
-    * QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS disables the string
-    * allocator altogether and thus both of these uses. It reduced the
-    * decoder object code by about 400 bytes.
-    */
-   const QCBORInternalAllocator *pAllocatorForGetNext = NULL;
-
-#ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS
-   const QCBORInternalAllocator *pAllocator = NULL;
-
-   if(pMe->StringAllocator.pfAllocator) {
-      pAllocator = &(pMe->StringAllocator);
-      if(pMe->bStringAllocateAll) {
-         pAllocatorForGetNext = pAllocator;
-      }
-   }
-#endif /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
-
    QCBORError uReturn;
-   uReturn = QCBOR_Private_DecodeAtomicDataItem(pMe, pDecodedItem, pAllocatorForGetNext);
+
+   uReturn = QCBOR_Private_DecodeAtomicDataItem(pMe, pMe->bStringAllocateAll, pDecodedItem);
    if(uReturn != QCBOR_SUCCESS) {
       goto Done;
    }
 
-   /* Only do indefinite-length processing on strings */
+   /* Skip out if not an indefinite-length string */
    const uint8_t uStringType = pDecodedItem->uDataType;
-   if(uStringType!= QCBOR_TYPE_BYTE_STRING && uStringType != QCBOR_TYPE_TEXT_STRING) {
+   if(uStringType != QCBOR_TYPE_BYTE_STRING &&
+      uStringType != QCBOR_TYPE_TEXT_STRING) {
       goto Done;
    }
-
-   /* Is this a string with an indefinite length? */
    if(pDecodedItem->val.string.len != QCBOR_STRING_LENGTH_INDEFINITE) {
       goto Done;
    }
 
 #ifndef QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS
    /* Can't decode indefinite-length strings without a string allocator */
-   if(pAllocator == NULL) {
+   if(!pMe->StringAllocator.pfAllocator) {
       uReturn = QCBOR_ERR_NO_STRING_ALLOCATOR;
       goto Done;
    }
@@ -1437,12 +1440,12 @@
    for(;;) {
       /* Get QCBORItem for next chunk */
       QCBORItem StringChunkItem;
-      /* Pass a NULL string allocator to GetNext_Item() because the
-       * individual string chunks in an indefinite-length should not
-       * be allocated. They are always copied in the the contiguous
+      /* Pass a false to DecodeAtomicDataItem() because the
+       * individual string chunks in an indefinite-length must not
+       * be allocated. They are always copied into the allocated contiguous
        * buffer allocated here.
        */
-      uReturn = QCBOR_Private_DecodeAtomicDataItem(pMe, &StringChunkItem, NULL);
+      uReturn = QCBOR_Private_DecodeAtomicDataItem(pMe, false, &StringChunkItem);
       if(uReturn) {
          break;
       }
@@ -1471,10 +1474,9 @@
           * equivalent to StringAllocator_Allocate(). Subsequently it is
           * not NULL and a reallocation happens.
           */
-         UsefulBuf NewMem = StringAllocator_Reallocate(pAllocator,
+         UsefulBuf NewMem = StringAllocator_Reallocate(&(pMe->StringAllocator),
                                                        FullString.ptr,
                                                        FullString.len + StringChunkItem.val.string.len);
-
          if(UsefulBuf_IsNULL(NewMem)) {
             uReturn = QCBOR_ERR_STRING_ALLOCATE;
             break;
@@ -1487,7 +1489,7 @@
 
    if(uReturn != QCBOR_SUCCESS && !UsefulBuf_IsNULLC(FullString)) {
       /* Getting the item failed, clean up the allocated memory */
-      StringAllocator_Free(pAllocator, FullString.ptr);
+      StringAllocator_Free(&(pMe->StringAllocator), FullString.ptr);
    }
 #else /* QCBOR_DISABLE_INDEFINITE_LENGTH_STRINGS */
    uReturn = QCBOR_ERR_INDEF_LEN_STRINGS_DISABLED;
@@ -1820,7 +1822,7 @@
    if(UsefulInputBuf_BytesUnconsumed(&(pMe->InBuf)) != 0) {
       QCBORItem Peek;
       size_t uPeek = UsefulInputBuf_Tell(&(pMe->InBuf));
-      QCBORError uReturn = QCBOR_Private_DecodeAtomicDataItem(pMe, &Peek, NULL);
+      QCBORError uReturn = QCBOR_Private_DecodeAtomicDataItem(pMe, false, &Peek);
       if(uReturn != QCBOR_SUCCESS) {
          return uReturn;
       }
@@ -3542,6 +3544,7 @@
       return;
    }
 
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
    QCBORItem OneItemSeach[2];
    OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
    OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
@@ -3559,8 +3562,16 @@
    }
 
    *pItem = OneItemSeach[0];
-
 Done:
+
+#else
+   (void)pMe;
+   (void)szLabel;
+   (void)uQcborType;
+   (void)pItem;
+   QCBORError uReturn = QCBOR_ERR_LABEL_NOT_FOUND;
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+
    pMe->uLastError = (uint8_t)uReturn;
 }
 
@@ -3615,7 +3626,7 @@
    if(uItemDataType == QCBOR_TYPE_MAP_AS_ARRAY) {
       uItemDataType = QCBOR_TYPE_ARRAY;
    }
-#endif
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
 
    if(uItemDataType != uType) {
       pMe->uLastError = QCBOR_ERR_UNEXPECTED_TYPE;
@@ -4032,6 +4043,7 @@
 void
 QCBORDecode_EnterMapFromMapSZ(QCBORDecodeContext *pMe, const char  *szLabel)
 {
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
    QCBORItem OneItemSeach[2];
    OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
    OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
@@ -4039,6 +4051,10 @@
    OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE;
 
    QCBORDecode_Private_SearchAndEnter(pMe, OneItemSeach);
+#else
+   (void)szLabel;
+   pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
 }
 
 /*
@@ -4062,6 +4078,7 @@
 void
 QCBORDecode_EnterArrayFromMapSZ(QCBORDecodeContext *pMe, const char  *szLabel)
 {
+#ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
    QCBORItem OneItemSeach[2];
    OneItemSeach[0].uLabelType   = QCBOR_TYPE_TEXT_STRING;
    OneItemSeach[0].label.string = UsefulBuf_FromSZ(szLabel);
@@ -4069,6 +4086,10 @@
    OneItemSeach[1].uLabelType   = QCBOR_TYPE_NONE;
 
    QCBORDecode_Private_SearchAndEnter(pMe, OneItemSeach);
+#else
+   (void)szLabel;
+   pMe->uLastError = QCBOR_ERR_LABEL_NOT_FOUND;
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
 }
 
 
@@ -4104,11 +4125,13 @@
    }
 
    uint8_t uItemDataType = Item.uDataType;
+
 #ifndef QCBOR_DISABLE_NON_INTEGER_LABELS
    if(uItemDataType == QCBOR_TYPE_MAP_AS_ARRAY ) {
       uItemDataType = QCBOR_TYPE_ARRAY;
    }
-#endif
+#endif /* ! QCBOR_DISABLE_NON_INTEGER_LABELS */
+   
    if(uItemDataType != uType) {
       uErr = QCBOR_ERR_UNEXPECTED_TYPE;
       goto Done;