Commit | Line | Data |
---|---|---|
e63124bc MW |
1 | /* -*-c-*- |
2 | * | |
3 | * Format a string to a buffer | |
4 | * | |
5 | * (c) 2023 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 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. | |
16 | * | |
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. | |
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 Software | |
24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
25 | * USA. | |
26 | */ | |
27 | ||
28 | /*----- Header files ------------------------------------------------------*/ | |
29 | ||
67b5031e MW |
30 | #include "config.h" |
31 | ||
e63124bc MW |
32 | #include <stdarg.h> |
33 | #include <stddef.h> | |
34 | #include <stdio.h> | |
35 | ||
36 | #include "buf.h" | |
37 | #include "gprintf.h" | |
38 | ||
39 | /*----- Main code ---------------------------------------------------------*/ | |
40 | ||
41 | /* --- @buf_vputstrf@ --- * | |
42 | * | |
43 | * Arguments: @buf *b@ = pointer to a buffer | |
44 | * @const char *p@ = pointer to @printf@-style format string | |
45 | * @va_list *ap@ = argument handle | |
46 | * | |
47 | * Returns: The number of characters written to the string, or @-1@ on | |
48 | * failure. | |
49 | * | |
50 | * Use: As for @buf_putstrf@, but may be used as a back-end to user- | |
51 | * supplied functions with @printf@-style interfaces. | |
52 | */ | |
53 | ||
54 | static int putch(void *out, int ch) | |
55 | { buf *b = out; return (buf_putbyte(b, ch)); } | |
56 | ||
57 | static int putm(void *out, const char *p, size_t sz) | |
58 | { buf *b = out; return (buf_put(b, p, sz)); } | |
59 | ||
60 | static int nputf(void *out, size_t maxsz, const char *p, ...) | |
61 | { | |
62 | buf *b = out; | |
63 | va_list ap; | |
64 | int n; | |
65 | ||
66 | va_start(ap, p); | |
67 | if (BENSURE(b, maxsz + 1)) return (-1); | |
68 | #ifdef HAVE_SNPRINTF | |
69 | n = vsnprintf((char *)BCUR(b), maxsz + 1, p, ap); | |
70 | #else | |
71 | n = vsprintf((char *)BCUR(b), p, ap); | |
72 | #endif | |
73 | assert(0 <= n && n <= maxsz); | |
74 | va_end(ap); b->p += n; return (n); | |
75 | } | |
76 | ||
e63124bc MW |
77 | const struct gprintf_ops buf_printops = |
78 | { putch, putm, nputf }; | |
79 | ||
80 | int buf_vputstrf(buf *b, const char *p, va_list *ap) | |
81 | { return (vgprintf(&buf_printops, b, p, ap)); } | |
82 | ||
83 | /* --- @buf_putstrf@ --- * | |
84 | * | |
85 | * Arguments: @buf *b@ = pointer to a buffer | |
86 | * @const char *p@ = pointer to @printf@-style format string | |
87 | * @...@ = argument handle | |
88 | * | |
89 | * Returns: The number of characters written to the string, or @-1@ on | |
90 | * failure. | |
91 | * | |
92 | * Use: Format a string to a buffer. The resulting output is not | |
93 | * null-terminated. | |
94 | */ | |
95 | ||
96 | int buf_putstrf(buf *b, const char *p, ...) | |
97 | { | |
98 | va_list ap; | |
99 | int n; | |
100 | ||
101 | va_start(ap, p); n = buf_vputstrf(b, p, &ap); va_end(ap); | |
102 | return (n); | |
103 | } | |
104 | ||
105 | /* --- @buf_{,v}putstrf{8,{16,24,32,64}{,b,l},z}@ --- * | |
106 | * | |
107 | * Arguments: @buf *b@ = pointer to a buffer | |
108 | * @const char *p@ = pointer to @printf@-style format string | |
109 | * @va_list *ap@ = argument handle | |
110 | * | |
111 | * Returns: The number of characters written to the string, or @-1@ on | |
112 | * failure. | |
113 | * | |
114 | * Use: As for @buf_putstr@, but using a format string. | |
115 | */ | |
116 | ||
117 | #define BUF_DEF_VPUTSTRF_(n, W, w) \ | |
118 | int buf_vputstrf##w(buf *b, const char *p, va_list *ap) \ | |
119 | { \ | |
120 | size_t mk; \ | |
121 | int nn; \ | |
122 | \ | |
123 | BUF_ENCLOSE##W(b, mk) nn = buf_vputstrf(b, p, ap); \ | |
124 | return (BOK(b) ? nn : -1); \ | |
125 | } | |
126 | DOUINTCONV(BUF_DEF_VPUTSTRF_) | |
127 | BUF_DOKLUDGESUFFIXES(BUF_DEF_VPUTSTRF_) | |
128 | #undef BUF_DEF_VPUTSTRF_ | |
129 | ||
130 | int buf_vputstrfz(buf *b, const char *p, va_list *ap) | |
131 | { | |
132 | int nn; | |
133 | ||
134 | BUF_ENCLOSEZ(b) nn = buf_vputstrf(b, p, ap); | |
135 | return (BOK(b) ? nn : -1); | |
136 | } | |
137 | ||
138 | #define BUF_DEF_PUTSTRF_(n, W, w) \ | |
139 | int buf_putstrf##w(buf *b, const char *p, ...) \ | |
140 | { \ | |
141 | va_list ap; \ | |
142 | int nn; \ | |
143 | \ | |
144 | va_start(ap, p); nn = buf_vputstrf##w(b, p, &ap); va_end(ap); \ | |
145 | return (nn); \ | |
146 | } | |
147 | BUF_DOSUFFIXES(BUF_DEF_PUTSTRF_) | |
148 | #undef BUF_DEF_PUTSTRF_ | |
149 | ||
150 | /*----- That's all, folks -------------------------------------------------*/ |