1 /*
2 Copyright (C) 2001-2014, Parrot Foundation.
3
4 =head1 NAME
5
6 src/string/sprintf.c - sprintf API routines
7
8 =head1 DESCRIPTION
9
10 This file implements the sprintf family of API routines. These routines
11 take different forms, but all redirect to a common generalized formatting
12 algorithm in F<src/spf_render.c> with a specialized vtables in
13 F<src/spf_vtable.c> to handle argument extraction.
14
15 =head2 Functions
16
17 The naming convention used is:
18
19 =over 4
20
21 =item C<Parrot_v?n?sprintf>
22
23 A (nearly) drop-in replacement for v?n?sprintf.
24
25 =item C<Parrot_v?sprintf_c>
26
27 Takes a C-string format, returns a Parrot string.
28
29 =item C<Parrot_v?sprintf_s>
30
31 Takes a Parrot string format, returns a Parrot string.
32
33 So the C<_> means "returns Parrot string" and the other letter indicates
34 the type for the format.
35
36 =cut
37
38 */
39
40 #include "parrot/parrot.h"
41 #include "spf_private.h"
42
43 /* HEADERIZER HFILE: include/parrot/string_funcs.h */
44
45 /*
46
47 =item C<STRING * Parrot_vsprintf_s(PARROT_INTERP, STRING *pat, va_list args)>
48
49 Almost all the other sprintf variants in this file are implemented in
50 terms of this function (see C<Parrot_psprintf()> for the exception). It
51 in turn calls C<Parrot_sprintf_format()> (see F<src/string/spf_render.c>).
52
53 =cut
54
55 */
56
57 PARROT_EXPORT
58 PARROT_WARN_UNUSED_RESULT
59 PARROT_CANNOT_RETURN_NULL
60 STRING *
Parrot_vsprintf_s(PARROT_INTERP,ARGIN (STRING * pat),va_list args)61 Parrot_vsprintf_s(PARROT_INTERP, ARGIN(STRING *pat), va_list args)
62 {
63 ASSERT_ARGS(Parrot_vsprintf_s)
64 SPRINTF_OBJ obj = va_core;
65 obj.data = PARROT_VA_TO_VAPTR(args);
66
67 return Parrot_sprintf_format(interp, pat, &obj);
68 }
69
70 /*
71
72 =item C<STRING * Parrot_vsprintf_c(PARROT_INTERP, ARGIN_FORMAT(const char *pat),
73 va_list args)>
74
75 C string version of C<Parrot_vsprintf_s()>.
76
77 =cut
78
79 */
80
81 PARROT_EXPORT
82 PARROT_CANNOT_RETURN_NULL
83 PARROT_WARN_UNUSED_RESULT
84 STRING *
Parrot_vsprintf_c(PARROT_INTERP,ARGIN_FORMAT (const char * pat),va_list args)85 Parrot_vsprintf_c(PARROT_INTERP, ARGIN_FORMAT(const char *pat), va_list args)
86 {
87 ASSERT_ARGS(Parrot_vsprintf_c)
88 STRING * const realpat = Parrot_str_new_init(interp, pat, strlen(pat),
89 Parrot_default_encoding_ptr, PObj_external_FLAG);
90
91 STRING * const ret = Parrot_vsprintf_s(interp, realpat, args);
92
93 return ret;
94 }
95
96 /*
97
98 =item C<void Parrot_vsnprintf(PARROT_INTERP, char *targ, size_t len,
99 ARGIN_FORMAT(const char *pat), va_list args)>
100
101 Similar to C<Parrot_vsprintf()> but with an option to specify the length
102 (C<len>) of the returned C string.
103
104 If len is zero, then C<targ> is unchanged.
105
106 =cut
107
108 */
109
110 PARROT_EXPORT
111 void
Parrot_vsnprintf(PARROT_INTERP,ARGMOD (char * targ),size_t len,ARGIN_FORMAT (const char * pat),va_list args)112 Parrot_vsnprintf(PARROT_INTERP, ARGMOD(char *targ),
113 size_t len, ARGIN_FORMAT(const char *pat), va_list args)
114 {
115 ASSERT_ARGS(Parrot_vsnprintf)
116
117 if (len == 0)
118 return;
119 --len;
120 if (len) {
121 const STRING * const ret = Parrot_vsprintf_c(interp, pat, args);
122 /* string_transcode(interp, ret, NULL, NULL, &ret); */
123
124 char * const str_ret = Parrot_str_to_cstring(interp, ret);
125 const size_t str_len = strlen(str_ret);
126 if (len > str_len) {
127 len = str_len;
128 }
129
130 if (len)
131 memcpy(targ, str_ret, len);
132 Parrot_str_free_cstring(str_ret);
133 }
134 targ[len] = 0;
135 }
136
137 /*
138
139 =item C<STRING * Parrot_sprintf_s(PARROT_INTERP, STRING *pat, ...)>
140
141 Calls C<Parrot_vsprintf_s()> with the C<va_list> obtained from C<...>.
142
143 =cut
144
145 */
146
147 PARROT_EXPORT
148 PARROT_WARN_UNUSED_RESULT
149 PARROT_CANNOT_RETURN_NULL
150 STRING *
Parrot_sprintf_s(PARROT_INTERP,ARGIN (STRING * pat),...)151 Parrot_sprintf_s(PARROT_INTERP, ARGIN(STRING *pat), ...)
152 {
153 ASSERT_ARGS(Parrot_sprintf_s)
154 STRING *ret;
155 va_list args;
156
157 va_start(args, pat);
158 ret = Parrot_vsprintf_s(interp, pat, args);
159 va_end(args);
160
161 return ret;
162 }
163
164 /*
165
166 =item C<STRING * Parrot_sprintf_c(PARROT_INTERP, ARGIN_FORMAT(const char *pat),
167 ...)>
168
169 C string version of C<Parrot_sprintf_s()>.
170
171 =cut
172
173 */
174
175 PARROT_EXPORT
176 PARROT_WARN_UNUSED_RESULT
177 PARROT_CANNOT_RETURN_NULL
178 STRING *
Parrot_sprintf_c(PARROT_INTERP,ARGIN_FORMAT (const char * pat),...)179 Parrot_sprintf_c(PARROT_INTERP, ARGIN_FORMAT(const char *pat), ...)
180 {
181 ASSERT_ARGS(Parrot_sprintf_c)
182 STRING *ret;
183 va_list args;
184
185 va_start(args, pat);
186 ret = Parrot_vsprintf_c(interp, pat, args);
187 va_end(args);
188
189 return ret;
190 }
191
192 /*
193
194 =item C<void Parrot_snprintf(PARROT_INTERP, char *targ, size_t len,
195 ARGIN_FORMAT(const char *pat), ...)>
196
197 Similar to C<Parrot_sprintf()> but with an option to specify the length
198 (C<len>) of the returned C string.
199
200 =cut
201
202 */
203
204 PARROT_EXPORT
205 void
Parrot_snprintf(PARROT_INTERP,ARGOUT (char * targ),size_t len,ARGIN_FORMAT (const char * pat),...)206 Parrot_snprintf(PARROT_INTERP, ARGOUT(char *targ), size_t len,
207 ARGIN_FORMAT(const char *pat), ...)
208 {
209 ASSERT_ARGS(Parrot_snprintf)
210 va_list args;
211
212 va_start(args, pat);
213
214 Parrot_vsnprintf(interp, targ, len, pat, args);
215
216 va_end(args);
217 }
218
219 /*
220
221 =item C<STRING * Parrot_psprintf(PARROT_INTERP, STRING *pat, PMC *ary)>
222
223 Calls C<Parrot_sprintf_format()> with the insertion arguments in an
224 C<Array> PMC.
225
226 =cut
227
228 */
229
230 PARROT_EXPORT
231 PARROT_WARN_UNUSED_RESULT
232 PARROT_CANNOT_RETURN_NULL
233 STRING *
Parrot_psprintf(PARROT_INTERP,ARGIN (STRING * pat),ARGOUT (PMC * ary))234 Parrot_psprintf(PARROT_INTERP, ARGIN(STRING *pat), ARGOUT(PMC *ary))
235 {
236 ASSERT_ARGS(Parrot_psprintf)
237 SPRINTF_OBJ obj = pmc_core;
238 obj.data = ary;
239
240 return Parrot_sprintf_format(interp, pat, &obj);
241 }
242
243 /*
244
245 =item C<int Parrot_secret_snprintf(char *buffer, size_t len, ARGIN_FORMAT(const
246 char *format), ...)>
247
248 A simulation of C<snprintf> for systems that do not support it.
249
250 =cut
251
252 */
253
254
255 PARROT_EXPORT
256 PARROT_IGNORABLE_RESULT
257 int
Parrot_secret_snprintf(ARGOUT (char * buffer),SHIM (size_t len),ARGIN_FORMAT (const char * format),...)258 Parrot_secret_snprintf(ARGOUT(char *buffer), SHIM(size_t len),
259 ARGIN_FORMAT(const char *format), ...)
260 {
261 ASSERT_ARGS(Parrot_secret_snprintf)
262 int retval;
263 va_list ap;
264 va_start(ap, format);
265 retval = vsprintf(buffer, format, ap);
266 va_end(ap);
267
268 return retval;
269 }
270
271 /*
272
273 =item C<int Parrot_vfprintf(PARROT_INTERP, Parrot_PMC pio, ARGIN_FORMAT(const
274 char *s), va_list args)>
275
276 Writes a C string format with a varargs list to a PIO.
277
278 =item C<int Parrot_fprintf(PARROT_INTERP, Parrot_PMC pio, ARGIN_FORMAT(const
279 char *s), ...)>
280
281 Writes a C string format with varargs to a PIO.
282
283 =item C<int Parrot_printf(NULLOK_INTERP, ARGIN_FORMAT(const char *s), ...)>
284
285 Writes a C string format with varargs to C<stdout>
286
287 =item C<int Parrot_eprintf(NULLOK_INTERP, ARGIN_FORMAT(const char *s), ...)>
288
289 Writes a C string format with varargs to C<stderr>.
290
291 =cut
292
293 */
294
295 PARROT_EXPORT
296 int
Parrot_vfprintf(PARROT_INTERP,ARGIN (Parrot_PMC pio),ARGIN_FORMAT (const char * s),va_list args)297 Parrot_vfprintf(PARROT_INTERP, ARGIN(Parrot_PMC pio),
298 ARGIN_FORMAT(const char *s), va_list args)
299 {
300 ASSERT_ARGS(Parrot_vfprintf)
301
302 STRING * str = Parrot_vsprintf_c(interp, s, args);
303 return Parrot_io_write_s(interp, pio, str);
304 }
305
306 PARROT_EXPORT
307 int
Parrot_fprintf(PARROT_INTERP,ARGIN (Parrot_PMC pio),ARGIN_FORMAT (const char * s),...)308 Parrot_fprintf(PARROT_INTERP, ARGIN(Parrot_PMC pio),
309 ARGIN_FORMAT(const char *s), ...)
310 {
311 ASSERT_ARGS(Parrot_fprintf)
312 va_list args;
313 INTVAL retval;
314
315 va_start(args, s);
316 retval = Parrot_vfprintf(interp, pio, s, args);
317 va_end(args);
318
319 return retval;
320 }
321
322 PARROT_EXPORT
323 int
Parrot_printf(NULLOK_INTERP,ARGIN_FORMAT (const char * s),...)324 Parrot_printf(NULLOK_INTERP, ARGIN_FORMAT(const char *s), ...)
325 {
326 ASSERT_ARGS(Parrot_printf)
327 va_list args;
328 INTVAL retval;
329 va_start(args, s);
330
331 if (interp)
332 retval = Parrot_vfprintf(interp, Parrot_io_STDOUT(interp), s, args);
333 else
334 retval = vfprintf(stdout, s, args);
335 va_end(args);
336
337 return retval;
338 }
339
340 PARROT_EXPORT
341 int
Parrot_eprintf(NULLOK_INTERP,ARGIN_FORMAT (const char * s),...)342 Parrot_eprintf(NULLOK_INTERP, ARGIN_FORMAT(const char *s), ...)
343 {
344 ASSERT_ARGS(Parrot_eprintf)
345 va_list args;
346 INTVAL retval;
347
348 va_start(args, s);
349
350 if (interp)
351 retval = Parrot_vfprintf(interp, Parrot_io_STDERR(interp), s, args);
352 else
353 retval = vfprintf(stderr, s, args);
354
355 va_end(args);
356
357 return retval;
358 }
359
360 /*
361
362 =back
363
364 =head1 SEE ALSO
365
366 F<src/string/spf_vtable.c>, F<src/string/spf_render.c>, F<include/parrot/misc.h>
367
368 =cut
369
370 */
371
372
373 /*
374 * Local variables:
375 * c-file-style: "parrot"
376 * End:
377 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
378 */
379