17 \h'-\w'\\$1\ 'u'\\$1\ \c
33 .TH gprintf 3 "9 March 2024" "Straylight/Edgeware" "mLib utilities library"
36 gprintf \- generalized output formatting
40 .B "#include <mLib/gprintf.h>"
43 .B "struct gprintf_ops {"
44 .BI " int (*putch)(void *" out ", int " ch ");"
45 .BI " int (*putm)(void *" out ", const char *" p ", size_t " sz ");"
46 .BI " int (*nputf)(void *" out ", size_t " maxsz ", const char *" p ", ...);"
49 .BI "int gprintf(const struct gprintf_ops *" ops ", void *" out ","
50 .ta \w'\fBint gprintf('u
51 .BI " const char *" p ", ...);"
52 .BI "int vgprintf(const struct gprintf_ops *" ops ", void *" out ","
53 .ta \w'\fBint vgprintf('u
54 .BI " const char *" p ", va_list *" ap ");"
56 .BI "int gprintf_memputf(char **" buf_inout ", size_t *" sz_inout ","
57 .ta \w'\fBint gprintf_memputf('u
58 .BI " size_t " maxsz ", const char *" p ", va_list " ap ");"
60 .B "const struct gprintf_ops file_printops;"
66 header file declares facilities for generalized output formatting
69 formatting to arbitrary output sinks.
70 This is the mechanism underlying the
76 To use it, you must define a
77 .B "struct gprintf_ops"
79 providing functions to write the formatted output to your chosen sink.
80 Each function receives a void pointer argument named
86 and should return the number of characters that it wrote
87 \(en or at least some nonnegative value \(en
89 or \-1 if it encountered an error.
91 The three functions are:
94 write out the single character
96 which is an integer holding an
104 characters from the buffer starting at
108 process the format string
112 writing out the formatted output;
113 the output will not be longer than
117 It may seem paradoxical for
119 to require the backend to do string formatting,
120 since its entire purpose is to do string formatting for you;
123 function can typically be done straightforwardly enough by calling
126 Difficult cases can be dealt with using
127 .BR gprintf_memputf ,
132 function formats a string
134 together with its variable argument list,
135 using the provided output operations
137 and passing them the pointer
139 when it calls on them.
143 except that it receives the format arguments as
148 The argument tail is updated in place,
149 and (on successful completion)
150 is left referring to the first unused argument.
154 function is a utility for implementing
159 should be a pointer to a buffer of
161 bytes, allocated from
162 .BR arena_global (3);
173 arguments are the maximum output size and format string passed to the
178 is the format-argument list, captured using
180 The function will adjust the buffer pointer and size as necessary,
181 write the formatted result to the buffer, null-terminated,
182 and return the actual output length.
183 The function is designed to be efficient when called multiple times,
184 retaining the same buffer across calls,
185 resizing it as necessary in a geometric progression.
186 When the buffer is no longer wanted, free it using
193 might look something like this.
200 /* ...\& other members ...\& */
203 /* ...\& define putch and putm ...\& */
205 static int nputf(void *out, size_t maxsz, const char *p, ...)
207 struct my_output *myout = out;
212 n = gprintf_memputf(&myout->buf, &myout->sz, maxsz, p, ap);
214 if (n > 0) n = putm(myout, myout->buf, n);
218 const struct gprintf_ops my_output_ops = { putch, putm, nputf };
222 struct my_output myout;
224 myout.buf = 0; myout.sz = 0;
225 /* ...\& other initialization ...\& */
226 gprintf(&my_output_ops, &myout, "Hello, %s!", "world");
227 xfree(myout.buf); myout.buf = 0; myout.sz = 0;
228 /* ...\& other cleanup ...\& */
237 Mark Wooding, <mdw@distorted.org.uk>