-/* This macro delivers a given character to either a memory buffer or a stream,
- depending on the contents of 'status' (struct _PDCLIB_status_t).
- x - the character to be delivered
- i - pointer to number of characters already delivered in this call
- n - pointer to maximum number of characters to be delivered in this call
- s - the buffer into which the character shall be delivered
-*/
-#define PUT( x ) \
-do { \
- int character = x; \
- if ( status->i < status->n ) { \
- if ( status->stream != NULL ) \
- _PDCLIB_putc_unlocked( character, status->stream ); \
- else \
- status->s[status->i] = character; \
- } \
- ++(status->i); \
-} while ( 0 )
-
-/* Maximum number of output characters =
- * number of bits in (u)intmax_t / number of bits per character in smallest
+#define E_TYPES (E_char | E_short | E_long | E_llong | E_intmax \
+ | E_size | E_ptrdiff | E_intptr)
+
+/* returns true if callback-based output succeeded; else false */
+static inline bool cbout(
+ struct _PDCLIB_status_t * status,
+ const void * buf,
+ size_t size )
+{
+ size_t rv = status->write( status->ctx, buf, size );
+ status->i += rv;
+ status->current += rv;
+ return rv == size;
+}
+
+/* repeated output of a single character */
+static inline bool cbrept(
+ struct _PDCLIB_status_t * status,
+ char c,
+ size_t times )
+{
+ if ( sizeof(size_t) == 8 && CHAR_BIT == 8)
+ {
+ uint64_t spread = UINT64_C(0x0101010101010101) * c;
+ while ( times )
+ {
+ size_t n = times > 8 ? 8 : times;
+ if ( !cbout( status, &spread, n ) )
+ return false;
+ times -= n;
+ }
+ return true;
+ }
+ else if ( sizeof(size_t) == 4 && CHAR_BIT == 8)
+ {
+ uint32_t spread = UINT32_C(0x01010101) * c;
+ while ( times )
+ {
+ size_t n = times > 4 ? 4 : times;
+ if ( !cbout( status, &spread, n ) )
+ return false;
+ times -= n;
+ }
+ return true;
+ }
+ else
+ {
+ while ( times )
+ {
+ if ( !cbout( status, &c, 1) )
+ return false;
+ times--;
+ }
+ return true;
+ }
+}
+
+
+/* Maximum number of output characters =
+ * number of bits in (u)intmax_t / number of bits per character in smallest