17 \h'-\w'\\$1\ 'u'\\$1\ \c
23 .TH gprintf 3 "9 March 2024" "Straylight/Edgeware" "mLib utilities library"
26 gprintf \- generalized output formatting
30 .B "#include <mLib/gprintf.h>"
33 .B "struct gprintf_ops {"
34 .BI " int (*putch)(void *" out ", int " ch ");"
35 .BI " int (*putm)(void *" out ", const char *" p ", size_t " sz ");"
36 .BI " int (*nputf)(void *" out ", size_t " maxsz ", const char *" p ", ...);"
39 .BI "int gprintf(const struct gprintf_ops *" ops ", void *" out ","
40 .ta \w'\fBint gprintf('u
41 .BI " const char *" p ", ...);"
42 .BI "int vgprintf(const struct gprintf_ops *" ops ", void *" out ","
43 .ta \w'\fBint vgprintf('u
44 .BI " const char *" p ", va_list *" ap ");"
46 .BI "int gprintf_memputf(char **" buf_inout ", size_t *" sz_inout ","
47 .ta \w'\fBint gprintf_memputf('u
48 .BI " size_t " maxsz ", const char *" p ", va_list " ap ");"
50 .B "const struct gprintf_ops file_printops;"
56 header file declares facilities for generalized output formatting
59 formatting to arbitrary output sinks.
60 This is the mechanism underlying the
66 To use it, you must define a
67 .B "struct gprintf_ops"
69 providing functions to write the formatted output to your chosen sink.
70 Each function receives a void pointer argument named
76 and should return the number of characters that it wrote
77 \(en or at least some nonnegative value \(en
79 or \-1 if it encountered an error.
81 The three functions are:
84 write out the single character
86 which is an integer holding an
94 characters from the buffer starting at
98 process the format string
102 writing out the formatted output;
103 the output will not be longer than
107 It may seem paradoxical for
109 to require the backend to do string formatting,
110 since its entire purpose is to do string formatting for you;
113 function can typically be done straightforwardly enough by calling
116 Difficult cases can be dealt with using
117 .BR gprintf_memputf ,
122 function formats a string
124 together with its variable argument list,
125 using the provided output operations
127 and passing them the pointer
129 when it calls on them.
133 except that it receives the format arguments as
138 The argument tail is updated in place,
139 and (on successful completion)
140 is left referring to the first unused argument.
144 function is a utility for implementing
149 should be a pointer to a buffer of
151 bytes, allocated from
152 .BR arena_global (3);
163 arguments are the maximum output size and format string passed to the
168 is the format-argument list, captured using
170 The function will adjust the buffer pointer and size as necessary,
171 write the formatted result to the buffer, null-terminated,
172 and return the actual output length.
173 The function is designed to be efficient when called multiple times,
174 retaining the same buffer across calls,
175 resizing it as necessary in a geometric progression.
176 When the buffer is no longer wanted, free it using
183 might look something like this.
190 /* ...\& other members ...\& */
193 /* ...\& define putch and putm ...\& */
195 static int nputf(void *out, size_t maxsz, const char *p, ...)
197 struct my_output *myout = out;
202 n = gprintf_memputf(&myout->buf, &myout->sz, maxsz, p, ap);
204 if (n > 0) n = putm(myout, myout->buf, n);
208 const struct gprintf_ops my_output_ops = { putch, putm, nputf };
212 struct my_output myout;
214 myout.buf = 0; myout.sz = 0;
215 /* ...\& other initialization ...\& */
216 gprintf(&my_output_ops, &myout, "Hello, %s!", "world");
217 xfree(myout.buf); myout.buf = 0; myout.sz = 0;
218 /* ...\& other cleanup ...\& */
227 Mark Wooding, <mdw@distorted.org.uk>