3 .\" Manual for generalized output formatting
5 .\" (c) 2024 Straylight/Edgeware
8 .\"----- Licensing notice ---------------------------------------------------
10 .\" This file is part of the mLib utilities library.
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.
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.
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,
27 .\"--------------------------------------------------------------------------
28 .so ../defs.man \" @@@PRE@@@
30 .\"--------------------------------------------------------------------------
31 .TH gprintf 3mLib "9 March 2024" "Straylight/Edgeware" "mLib utilities library"
38 .\"--------------------------------------------------------------------------
40 gprintf \- generalized output formatting
42 .\"--------------------------------------------------------------------------
46 .B "#include <mLib/gprintf.h>"
49 .B "struct gprintf_ops {"
50 .BI " int (*putch)(void *" out ", int " ch ");"
51 .BI " int (*putm)(void *" out ", const char *" p ", size_t " sz ");"
52 .BI " int (*nputf)(void *" out ", size_t " maxsz ", const char *" p ", ...);"
55 .BI "int gprintf(const struct gprintf_ops *" ops ", void *" out ","
56 .ta \w'\fBint gprintf('u
57 .BI " const char *" p ", ...);"
58 .BI "int vgprintf(const struct gprintf_ops *" ops ", void *" out ","
59 .ta \w'\fBint vgprintf('u
60 .BI " const char *" p ", va_list *" ap ");"
62 .BI "int gprintf_memputf(char **" buf_inout ", size_t *" sz_inout ","
63 .ta \w'\fBint gprintf_memputf('u
64 .BI " size_t " maxsz ", const char *" p ", va_list " ap ");"
66 .B "const struct gprintf_ops file_printops;"
69 .\"--------------------------------------------------------------------------
74 header file declares facilities for generalized output formatting
77 formatting to arbitrary output sinks.
78 This is the mechanism underlying the
84 The formatting is intended to be convenient and safe
85 rather than efficient,
86 so don't expect blistering performance.
87 Similarly, there may be differences
88 between the formatting done by
92 because the former has to do most of its work itself.
97 positional parameter notation accepted by many Unix C libraries,
98 even if the underlying C library does not.
100 To use it, you must define a
101 .B "struct gprintf_ops"
103 providing functions to write the formatted output to your chosen sink.
104 Each function receives a void pointer argument named
110 and should return the number of characters that it wrote
111 \(en or at least some nonnegative value \(en
113 or \-1 if it encountered an error.
115 The three functions are:
118 write out the single character
120 which is an integer holding an
128 characters from the buffer starting at
132 process the format string
136 writing out the formatted output;
137 the output will not be longer than
141 It may seem paradoxical for
143 to require the backend to do string formatting,
144 since its entire purpose is to do string formatting for you;
147 function can typically be done straightforwardly enough by calling
150 Difficult cases can be dealt with using
151 .BR gprintf_memputf ,
156 function formats a string
158 together with its variable argument list,
159 using the provided output operations
161 and passing them the pointer
163 when it calls on them.
167 except that it receives the format arguments as
172 The argument tail is updated in place,
173 and (on successful completion)
174 is left referring to the first unused argument.
178 function is a utility for implementing
183 should be a pointer to a buffer of
185 bytes, allocated from
186 .BR arena_global (3);
197 arguments are the maximum output size and format string passed to the
202 is the format-argument list, captured using
204 The function will adjust the buffer pointer and size as necessary,
205 write the formatted result to the buffer, null-terminated,
206 and return the actual output length.
207 The function is designed to be efficient when called multiple times,
208 retaining the same buffer across calls,
209 resizing it as necessary in a geometric progression.
210 When the buffer is no longer wanted, free it using
217 might look something like this.
224 /* ...\& other members ...\& */
227 /* ...\& define putch and putm ...\& */
229 static int nputf(void *out, size_t maxsz, const char *p, ...)
231 struct my_output *myout = out;
236 n = gprintf_memputf(&myout->buf, &myout->sz, maxsz, p, ap);
238 if (n > 0) n = putm(myout, myout->buf, n);
242 const struct gprintf_ops my_output_ops = { putch, putm, nputf };
246 struct my_output myout;
248 myout.buf = 0; myout.sz = 0;
249 /* ...\& other initialization ...\& */
250 gprintf(&my_output_ops, &myout, "Hello, %s!", "world");
251 xfree(myout.buf); myout.buf = 0; myout.sz = 0;
252 /* ...\& other cleanup ...\& */
255 .\"--------------------------------------------------------------------------
262 .\"--------------------------------------------------------------------------
265 .\"--------------------------------------------------------------------------
266 Mark Wooding, <mdw@distorted.org.uk>
268 .\"----- That's all, folks --------------------------------------------------