@@@ tvec wip
[mLib] / struct / buf-putf.c
1 /* -*-c-*-
2 *
3 * Format a string to a buffer
4 *
5 * (c) 2023 Straylight/Edgeware
6 */
7
8 /*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of the mLib utilities library.
11 *
12 * mLib is free software: you can redistribute it and/or modify it under
13 * the terms of the GNU Library General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version.
16 *
17 * mLib is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20 * License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with mLib. If not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 * USA.
26 */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include <stdarg.h>
31 #include <stddef.h>
32 #include <stdio.h>
33
34 #include "buf.h"
35 #include "gprintf.h"
36
37 /*----- Main code ---------------------------------------------------------*/
38
39 /* --- @buf_vputstrf@ --- *
40 *
41 * Arguments: @buf *b@ = pointer to a buffer
42 * @const char *p@ = pointer to @printf@-style format string
43 * @va_list *ap@ = argument handle
44 *
45 * Returns: The number of characters written to the string, or @-1@ on
46 * failure.
47 *
48 * Use: As for @buf_putstrf@, but may be used as a back-end to user-
49 * supplied functions with @printf@-style interfaces.
50 */
51
52 static int putch(void *out, int ch)
53 { buf *b = out; return (buf_putbyte(b, ch)); }
54
55 static int putm(void *out, const char *p, size_t sz)
56 { buf *b = out; return (buf_put(b, p, sz)); }
57
58 static int nputf(void *out, size_t maxsz, const char *p, ...)
59 {
60 buf *b = out;
61 va_list ap;
62 int n;
63
64 va_start(ap, p);
65 if (BENSURE(b, maxsz + 1)) return (-1);
66 #ifdef HAVE_SNPRINTF
67 n = vsnprintf((char *)BCUR(b), maxsz + 1, p, ap);
68 #else
69 n = vsprintf((char *)BCUR(b), p, ap);
70 #endif
71 assert(0 <= n && n <= maxsz);
72 va_end(ap); b->p += n; return (n);
73 }
74
75 static int putbuf(void *out, const char *p, size_t sz)
76 { buf *b = out; b->p += sz; return (0); }
77
78 const struct gprintf_ops buf_printops =
79 { putch, putm, nputf };
80
81 int buf_vputstrf(buf *b, const char *p, va_list *ap)
82 { return (vgprintf(&buf_printops, b, p, ap)); }
83
84 /* --- @buf_putstrf@ --- *
85 *
86 * Arguments: @buf *b@ = pointer to a buffer
87 * @const char *p@ = pointer to @printf@-style format string
88 * @...@ = argument handle
89 *
90 * Returns: The number of characters written to the string, or @-1@ on
91 * failure.
92 *
93 * Use: Format a string to a buffer. The resulting output is not
94 * null-terminated.
95 */
96
97 int buf_putstrf(buf *b, const char *p, ...)
98 {
99 va_list ap;
100 int n;
101
102 va_start(ap, p); n = buf_vputstrf(b, p, &ap); va_end(ap);
103 return (n);
104 }
105
106 /* --- @buf_{,v}putstrf{8,{16,24,32,64}{,b,l},z}@ --- *
107 *
108 * Arguments: @buf *b@ = pointer to a buffer
109 * @const char *p@ = pointer to @printf@-style format string
110 * @va_list *ap@ = argument handle
111 *
112 * Returns: The number of characters written to the string, or @-1@ on
113 * failure.
114 *
115 * Use: As for @buf_putstr@, but using a format string.
116 */
117
118 #define BUF_DEF_VPUTSTRF_(n, W, w) \
119 int buf_vputstrf##w(buf *b, const char *p, va_list *ap) \
120 { \
121 size_t mk; \
122 int nn; \
123 \
124 BUF_ENCLOSE##W(b, mk) nn = buf_vputstrf(b, p, ap); \
125 return (BOK(b) ? nn : -1); \
126 }
127 DOUINTCONV(BUF_DEF_VPUTSTRF_)
128 BUF_DOKLUDGESUFFIXES(BUF_DEF_VPUTSTRF_)
129 #undef BUF_DEF_VPUTSTRF_
130
131 int buf_vputstrfz(buf *b, const char *p, va_list *ap)
132 {
133 int nn;
134
135 BUF_ENCLOSEZ(b) nn = buf_vputstrf(b, p, ap);
136 return (BOK(b) ? nn : -1);
137 }
138
139 #define BUF_DEF_PUTSTRF_(n, W, w) \
140 int buf_putstrf##w(buf *b, const char *p, ...) \
141 { \
142 va_list ap; \
143 int nn; \
144 \
145 va_start(ap, p); nn = buf_vputstrf##w(b, p, &ap); va_end(ap); \
146 return (nn); \
147 }
148 BUF_DOSUFFIXES(BUF_DEF_PUTSTRF_)
149 #undef BUF_DEF_PUTSTRF_
150
151 /*----- That's all, folks -------------------------------------------------*/