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 an arena,
185 .BR arena_global (3);
187 should be a pointer to a buffer of
189 bytes, allocated from the arena
201 arguments are the maximum output size and format string passed to the
206 is the format-argument list, captured using
208 The function will adjust the buffer pointer and size as necessary,
209 write the formatted result to the buffer, null-terminated,
210 and return the actual output length.
211 The function is designed to be efficient when called multiple times,
212 retaining the same buffer across calls,
213 resizing it as necessary in a geometric progression.
219 might look something like this.
226 /* ...\& other members ...\& */
229 /* ...\& define putch and putm ...\& */
231 static int nputf(void *out, size_t maxsz, const char *p, ...)
233 struct my_output *myout = out;
238 n = gprintf_memputf(&myout->buf, &myout->sz, maxsz, p, ap);
240 if (n > 0) n = putm(myout, myout->buf, n);
244 const struct gprintf_ops my_output_ops = { putch, putm, nputf };
248 struct my_output myout;
250 myout.buf = 0; myout.sz = 0;
251 /* ...\& other initialization ...\& */
252 gprintf(&my_output_ops, &myout, "Hello, %s!", "world");
253 xfree(myout.buf); myout.buf = 0; myout.sz = 0;
254 /* ...\& other cleanup ...\& */
257 .\"--------------------------------------------------------------------------
264 .\"--------------------------------------------------------------------------
267 .\"--------------------------------------------------------------------------
268 Mark Wooding, <mdw@distorted.org.uk>
270 .\"----- That's all, folks --------------------------------------------------