+#ifndef COMPILE_UTILITY
+/*************************************************
+* Get a block annotated as being lookup-quoted *
+*************************************************/
+
+/* Allocate from pool a pool consistent with the proto_mem augmented by the
+requested quoter type.
+
+XXX currently not handling mark/release
+
+Args: size number of bytes to allocate
+ quoter id for the quoting type
+ func caller, for debug
+ linenumber caller, for debug
+
+Return: allocated memory block
+*/
+
+static void *
+store_force_get_quoted(int size, unsigned quoter,
+ const char * func, int linenumber)
+{
+pooldesc * pp = pool_for_quoter(quoter);
+void * yield;
+
+DEBUG(D_memory)
+ debug_printf("allocating quoted-block for quoter %u (from %s %d)\n", quoter, func, linenumber);
+
+if (!pp) pp = quoted_pool_new(quoter);
+yield = pool_get(pp, size, FALSE, func, linenumber);
+
+DEBUG(D_memory)
+ debug_printf("---QQ Get %6p %5d %-14s %4d\n",
+ pp->store_last_get, size, func, linenumber);
+
+return yield;
+}
+
+/* Maybe get memory for the specified quoter, but only if the
+prototype memory is tainted. Otherwise, get plain memory.
+*/
+void *
+store_get_quoted_3(int size, const void * proto_mem, unsigned quoter,
+ const char * func, int linenumber)
+{
+// debug_printf("store_get_quoted_3: quoter %u\n", quoter);
+return is_tainted(proto_mem)
+ ? store_force_get_quoted(size, quoter, func, linenumber)
+ : store_get_3(size, proto_mem, func, linenumber);
+}
+
+/* Return quoter for given address, or -1 if not in a quoted-pool. */
+int
+quoter_for_address(const void * p)
+{
+for (quoted_pooldesc * qp = quoted_pools; qp; qp = qp->next)
+ {
+ pooldesc * pp = &qp->pool;
+ storeblock * b;
+
+ if (b = pp->current_block)
+ if (is_pointer_in_block(b, p))
+ return qp->quoter;
+
+ for (b = pp->chainbase; b; b = b->next)
+ if (is_pointer_in_block(b, p))
+ return qp->quoter;
+ }
+return -1;
+}
+
+/* Return TRUE iff the given address is quoted for the given type.
+There is extra complexity to handle lookup providers with multiple
+find variants but shared quote functions. */
+BOOL
+is_quoted_like(const void * p, unsigned quoter)
+{
+int pq = quoter_for_address(p);
+BOOL y =
+ is_real_quoter(pq) && lookup_list[pq]->quote == lookup_list[quoter]->quote;
+/* debug_printf("is_quoted(%p, %u): %c\n", p, quoter, y?'T':'F'); */
+return y;
+}
+
+/* Return TRUE if the quoter value indicates an actual quoter */
+BOOL
+is_real_quoter(int quoter)
+{
+return quoter >= 0;
+}
+
+/* Return TRUE if the "new" data requires that the "old" data
+be recopied to new-class memory. We order the classes as
+
+ 2: tainted, not quoted
+ 1: quoted (which is also tainted)
+ 0: untainted
+
+If the "new" is higher-order than the "old", they are not compatible
+and a copy is needed. If both are quoted, but the quoters differ,
+not compatible. Otherwise they are compatible.
+*/
+BOOL
+is_incompatible_fn(const void * old, const void * new)
+{
+int oq, nq;
+unsigned oi, ni;
+
+ni = is_real_quoter(nq = quoter_for_address(new)) ? 1 : is_tainted(new) ? 2 : 0;
+oi = is_real_quoter(oq = quoter_for_address(old)) ? 1 : is_tainted(old) ? 2 : 0;
+return ni > oi || ni == oi && nq != oq;
+}
+
+#endif /*!COMPILE_UTILITY*/