chiark / gitweb /
@@@ so much mess
[mLib] / struct / dstr-putf.c
1 /* -*-c-*-
2  *
3  * `printf'-style formatting for dynamic strings
4  *
5  * (c) 1999 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
13  * it under the terms of the GNU Library General Public License as
14  * published by the Free Software Foundation; either version 2 of the
15  * License, or (at your option) any later version.
16  *
17  * mLib is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Library General Public 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
24  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25  * MA 02111-1307, USA.
26  */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #include <stdarg.h>
31 #include <stddef.h>
32 #include <stdio.h>
33
34 #include "dstr.h"
35 #include "gprintf.h"
36
37 /*----- Main code ---------------------------------------------------------*/
38
39 /* --- @dstr_vputf@ --- *
40  *
41  * Arguments:   @dstr *d@ = pointer to a dynamic string block
42  *              @const char *p@ = pointer to @printf@-style format string
43  *              @va_list *ap@ = argument handle
44  *
45  * Returns:     The number of characters written to the string.
46  *
47  * Use:         As for @dstr_putf@, but may be used as a back-end to user-
48  *              supplied functions with @printf@-style interfaces.
49  */
50
51 static int putch(void *out, int ch)
52   { dstr *d = out; DPUTC(d, ch); return (0); }
53 static int putm(void *out, const char *p, size_t sz)
54   { dstr *d = out; DPUTM(d, p, sz); return (0); }
55
56 static int nputf(void *out, size_t maxsz, const char *p, ...)
57 {
58   dstr *d = out;
59   va_list ap;
60   int n;
61
62   va_start(ap, p);
63   DENSURE(d, maxsz + 1);
64 #ifdef HAVE_SNPRINTF
65   n = vsnprintf(d->buf + d->len, maxsz + 1, p, ap);
66 #else
67   n = vsprintf(d->buf + d->len, p, ap);
68 #endif
69   assert(0 <= n && n <= maxsz);
70   va_end(ap); d->len += n; return (n);
71 }
72
73 const struct gprintf_ops dstr_printops =
74   { putch, putm, nputf };
75
76 int dstr_vputf(dstr *d, const char *p, va_list *ap)
77   { int n = vgprintf(&dstr_printops, d, p, ap); DPUTZ(d); return (n); }
78
79 /* --- @dstr_putf@ --- *
80  *
81  * Arguments:   @dstr *d@ = pointer to a dynamic string block
82  *              @const char *p@ = pointer to @printf@-style format string
83  *              @...@ = argument handle
84  *
85  * Returns:     The number of characters written to the string.
86  *
87  * Use:         Writes a piece of text to a dynamic string, doing @printf@-
88  *              style substitutions as it goes.  Intended to be robust if
89  *              faced with malicious arguments, but not if the format string
90  *              itself is malicious.
91  */
92
93 int dstr_putf(dstr *d, const char *p, ...)
94 {
95   int n;
96   va_list ap;
97   va_start(ap, p);
98   n = dstr_vputf(d, p, &ap);
99   va_end(ap);
100   return (n);
101 }
102
103 /*----- That's all, folks -------------------------------------------------*/