chiark / gitweb /
*.[ch]: Remove unnecessary header files.
[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 "config.h"
31
32 #include <stdarg.h>
33 #include <stddef.h>
34
35 #include "buf.h"
36 #include "gprintf.h"
37
38 /*----- Main code ---------------------------------------------------------*/
39
40 /* --- @buf_vputstrf@ --- *
41  *
42  * Arguments:   @buf *b@ = pointer to a buffer
43  *              @const char *p@ = pointer to @printf@-style format string
44  *              @va_list *ap@ = argument handle
45  *
46  * Returns:     The number of characters written to the string, or @-1@ on
47  *              failure.
48  *
49  * Use:         As for @buf_putstrf@, but may be used as a back-end to user-
50  *              supplied functions with @printf@-style interfaces.
51  */
52
53 static int putch(void *out, int ch)
54   { buf *b = out; return (buf_putbyte(b, ch) ? -1 : 1); }
55
56 static int putm(void *out, const char *p, size_t sz)
57   { buf *b = out; return (buf_put(b, p, sz) ? -1 : sz); }
58
59 static int nputf(void *out, size_t maxsz, const char *p, ...)
60 {
61   buf *b = out;
62   va_list ap;
63   int n;
64
65   va_start(ap, p);
66   if (BENSURE(b, maxsz + 1)) return (-1);
67 #ifdef HAVE_SNPRINTF
68   n = vsnprintf((char *)BCUR(b), maxsz + 1, p, ap);
69 #else
70   n = vsprintf((char *)BCUR(b), p, ap);
71 #endif
72   assert(0 <= n && n <= maxsz);
73   va_end(ap); b->p += n; return (n);
74 }
75
76 const struct gprintf_ops buf_printops =
77   { putch, putm, nputf };
78
79 int buf_vputstrf(buf *b, const char *p, va_list *ap)
80   { return (vgprintf(&buf_printops, b, p, ap)); }
81
82 /* --- @buf_putstrf@ --- *
83  *
84  * Arguments:   @buf *b@ = pointer to a buffer
85  *              @const char *p@ = pointer to @printf@-style format string
86  *              @...@ = argument handle
87  *
88  * Returns:     The number of characters written to the string, or @-1@ on
89  *              failure.
90  *
91  * Use:         Format a string to a buffer.  The resulting output is not
92  *              null-terminated.
93  */
94
95 int buf_putstrf(buf *b, const char *p, ...)
96 {
97   va_list ap;
98   int n;
99
100   va_start(ap, p); n = buf_vputstrf(b, p, &ap); va_end(ap);
101   return (n);
102 }
103
104 /* --- @buf_{,v}putstrf{8,{16,24,32,64}{,b,l},z}@ --- *
105  *
106  * Arguments:   @buf *b@ = pointer to a buffer
107  *              @const char *p@ = pointer to @printf@-style format string
108  *              @va_list *ap@ = argument handle
109  *
110  * Returns:     The number of characters written to the string, or @-1@ on
111  *              failure.
112  *
113  * Use:         As for @buf_putstr@, but using a format string.
114  */
115
116 #define BUF_DEF_VPUTSTRF_(n, W, w)                                      \
117   int buf_vputstrf##w(buf *b, const char *p, va_list *ap)               \
118   {                                                                     \
119     size_t mk;                                                          \
120     int nn;                                                             \
121                                                                         \
122     BUF_ENCLOSE##W(b, mk) nn = buf_vputstrf(b, p, ap);                  \
123     return (BOK(b) ? nn : -1);                                          \
124   }
125 DOUINTCONV(BUF_DEF_VPUTSTRF_)
126 BUF_DOKLUDGESUFFIXES(BUF_DEF_VPUTSTRF_)
127 #undef BUF_DEF_VPUTSTRF_
128
129 int buf_vputstrfz(buf *b, const char *p, va_list *ap)
130 {
131   int nn;
132
133   BUF_ENCLOSEZ(b) nn = buf_vputstrf(b, p, ap);
134   return (BOK(b) ? nn : -1);
135 }
136
137 #define BUF_DEF_PUTSTRF_(n, W, w)                                       \
138   int buf_putstrf##w(buf *b, const char *p, ...)                        \
139   {                                                                     \
140     va_list ap;                                                         \
141     int nn;                                                             \
142                                                                         \
143     va_start(ap, p); nn = buf_vputstrf##w(b, p, &ap); va_end(ap);       \
144     return (nn);                                                                \
145   }
146 BUF_DOSUFFIXES(BUF_DEF_PUTSTRF_)
147 #undef BUF_DEF_PUTSTRF_
148
149 /*----- That's all, folks -------------------------------------------------*/