summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/printfcommon.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/stdio/printfcommon.h')
-rw-r--r--lib/libc/stdio/printfcommon.h130
1 files changed, 130 insertions, 0 deletions
diff --git a/lib/libc/stdio/printfcommon.h b/lib/libc/stdio/printfcommon.h
new file mode 100644
index 0000000..7bc357a
--- /dev/null
+++ b/lib/libc/stdio/printfcommon.h
@@ -0,0 +1,130 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * This file defines common routines used by both printf and wprintf.
+ * You must define CHAR to either char or wchar_t prior to including this.
+ */
+
+#define NIOV 8
+struct io_state {
+ FILE *fp;
+ struct __suio uio; /* output information: summary */
+ struct __siov iov[NIOV];/* ... and individual io vectors */
+ struct __siov *iovp; /* pointer to next free slot in iov */
+};
+
+static inline void
+io_init(struct io_state *iop, FILE *fp)
+{
+
+ iop->uio.uio_iov = iop->iovp = iop->iov;
+ iop->uio.uio_resid = 0;
+ iop->uio.uio_iovcnt = 0;
+ iop->fp = fp;
+}
+
+/*
+ * WARNING: The buffer passed to io_print() is not copied immediately; it must
+ * remain valid until io_flush() is called.
+ */
+static inline int
+io_print(struct io_state *iop, const CHAR * __restrict ptr, int len)
+{
+
+ iop->iovp->iov_base = (char *)ptr;
+ iop->iovp->iov_len = len;
+ iop->uio.uio_resid += len;
+ iop->iovp++;
+ if (++iop->uio.uio_iovcnt >= NIOV) {
+ iop->iovp = iop->iov;
+ return (__sprint(iop->fp, &iop->uio));
+ }
+ return (0);
+}
+
+/*
+ * Choose PADSIZE to trade efficiency vs. size. If larger printf
+ * fields occur frequently, increase PADSIZE and make the initialisers
+ * below longer.
+ */
+#define PADSIZE 16 /* pad chunk size */
+static const CHAR blanks[PADSIZE] =
+{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
+static const CHAR zeroes[PADSIZE] =
+{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+
+/*
+ * Pad with blanks or zeroes. 'with' should point to either the blanks array
+ * or the zeroes array.
+ */
+static inline int
+io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with)
+{
+
+ while (howmany > PADSIZE) {
+ if (io_print(iop, with, PADSIZE))
+ return (-1);
+ howmany -= PADSIZE;
+ }
+ if (howmany > 0 && io_print(iop, with, howmany))
+ return (-1);
+ return (0);
+}
+
+/*
+ * Print exactly len characters of the string spanning p to ep, truncating
+ * or padding with 'with' as necessary.
+ */
+static inline int
+io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep,
+ int len, const CHAR * __restrict with)
+{
+ int p_len;
+
+ p_len = ep - p;
+ if (p_len > len)
+ p_len = len;
+ if (p_len > 0 && io_print(iop, p, p_len))
+ return (-1);
+ return (io_pad(iop, len - (p_len > 0 ? p_len : 0), with));
+}
+
+static inline int
+io_flush(struct io_state *iop)
+{
+
+ iop->iovp = iop->iov;
+ return (__sprint(iop->fp, &iop->uio));
+}
OpenPOWER on IntegriCloud