blob: 06ad61154795d2c055bd2e1b51ca190707e48aa1 [file] [log] [blame]
Harald Welted09829d2017-02-27 22:58:59 +01001/* ----------------------------------------------------------------------------
2 * ATMEL Microcontroller Software Support
3 * ----------------------------------------------------------------------------
4 * Copyright (c) 2008, Atmel Corporation
Kévin Redon1836ac02018-08-02 15:02:05 +02005 * Copyright (c) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
Harald Welted09829d2017-02-27 22:58:59 +01006 *
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the disclaimer below.
14 *
15 * Atmel's name may not be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
21 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * ----------------------------------------------------------------------------
29 */
30
31//------------------------------------------------------------------------------
32/// \unit
33///
34/// !Purpose
35///
36/// Implementation of several stdio.h methods, such as printf(), sprintf() and
37/// so on. This reduces the memory footprint of the binary when using those
38/// methods, compared to the libc implementation.
39///
40/// !Usage
41///
42/// Adds stdio.c to the list of file to compile for the project. This will
43/// automatically replace libc methods by the custom ones.
44//------------------------------------------------------------------------------
45
46//------------------------------------------------------------------------------
47// Headers
48//------------------------------------------------------------------------------
49
50#include <stdio.h>
51#include <stdarg.h>
52
53//------------------------------------------------------------------------------
54// Local Definitions
55//------------------------------------------------------------------------------
56
57// Maximum string size allowed (in bytes).
Harald Welteee9ebb32017-03-02 16:52:08 +010058#define MAX_STRING_SIZE 512
Harald Welted09829d2017-02-27 22:58:59 +010059
60//------------------------------------------------------------------------------
61// Global Variables
62//------------------------------------------------------------------------------
Harald Weltec430ac12017-02-28 01:25:12 +010063//
64FILE* const stdin = NULL;
65FILE* const stdout = NULL;
66FILE* const stderr = NULL;
Harald Welted09829d2017-02-27 22:58:59 +010067
Harald Welted09829d2017-02-27 22:58:59 +010068
69//------------------------------------------------------------------------------
70// Local Functions
71//------------------------------------------------------------------------------
72
73//------------------------------------------------------------------------------
74// Writes a character inside the given string. Returns 1.
75// \param pStr Storage string.
76// \param c Character to write.
77//------------------------------------------------------------------------------
78signed int PutChar(char *pStr, char c)
79{
Kévin Redon33d1eb72018-07-08 13:58:12 +020080 *pStr = c;
81 return 1;
Harald Welted09829d2017-02-27 22:58:59 +010082}
83
84//------------------------------------------------------------------------------
85// Writes a string inside the given string.
86// Returns the size of the written
87// string.
88// \param pStr Storage string.
89// \param pSource Source string.
90//------------------------------------------------------------------------------
91signed int PutString(char *pStr, const char *pSource)
92{
Kévin Redon33d1eb72018-07-08 13:58:12 +020093 signed int num = 0;
Harald Welted09829d2017-02-27 22:58:59 +010094
Kévin Redon33d1eb72018-07-08 13:58:12 +020095 while (*pSource != 0) {
Harald Welted09829d2017-02-27 22:58:59 +010096
Kévin Redon33d1eb72018-07-08 13:58:12 +020097 *pStr++ = *pSource++;
98 num++;
99 }
Harald Welted09829d2017-02-27 22:58:59 +0100100
Kévin Redon33d1eb72018-07-08 13:58:12 +0200101 return num;
Harald Welted09829d2017-02-27 22:58:59 +0100102}
103
104//------------------------------------------------------------------------------
105// Writes an unsigned int inside the given string, using the provided fill &
106// width parameters.
107// Returns the size in characters of the written integer.
108// \param pStr Storage string.
109// \param fill Fill character.
110// \param width Minimum integer width.
111// \param value Integer value.
112//------------------------------------------------------------------------------
113signed int PutUnsignedInt(
Kévin Redon33d1eb72018-07-08 13:58:12 +0200114 char *pStr,
115 char fill,
116 signed int width,
117 unsigned int value)
Harald Welted09829d2017-02-27 22:58:59 +0100118{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200119 signed int num = 0;
Harald Welted09829d2017-02-27 22:58:59 +0100120
Kévin Redon33d1eb72018-07-08 13:58:12 +0200121 // Take current digit into account when calculating width
122 width--;
Harald Welted09829d2017-02-27 22:58:59 +0100123
Kévin Redon33d1eb72018-07-08 13:58:12 +0200124 // Recursively write upper digits
125 if ((value / 10) > 0) {
Harald Welted09829d2017-02-27 22:58:59 +0100126
Kévin Redon33d1eb72018-07-08 13:58:12 +0200127 num = PutUnsignedInt(pStr, fill, width, value / 10);
128 pStr += num;
129 }
130 // Write filler characters
131 else {
Harald Welted09829d2017-02-27 22:58:59 +0100132
Kévin Redon33d1eb72018-07-08 13:58:12 +0200133 while (width > 0) {
Harald Welted09829d2017-02-27 22:58:59 +0100134
Kévin Redon33d1eb72018-07-08 13:58:12 +0200135 PutChar(pStr, fill);
136 pStr++;
137 num++;
138 width--;
139 }
140 }
Harald Welted09829d2017-02-27 22:58:59 +0100141
Kévin Redon33d1eb72018-07-08 13:58:12 +0200142 // Write lower digit
143 num += PutChar(pStr, (value % 10) + '0');
Harald Welted09829d2017-02-27 22:58:59 +0100144
Kévin Redon33d1eb72018-07-08 13:58:12 +0200145 return num;
Harald Welted09829d2017-02-27 22:58:59 +0100146}
147
148//------------------------------------------------------------------------------
149// Writes a signed int inside the given string, using the provided fill & width
150// parameters.
151// Returns the size of the written integer.
152// \param pStr Storage string.
153// \param fill Fill character.
154// \param width Minimum integer width.
155// \param value Signed integer value.
156//------------------------------------------------------------------------------
157signed int PutSignedInt(
Kévin Redon33d1eb72018-07-08 13:58:12 +0200158 char *pStr,
159 char fill,
160 signed int width,
161 signed int value)
Harald Welted09829d2017-02-27 22:58:59 +0100162{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200163 signed int num = 0;
164 unsigned int absolute;
Harald Welted09829d2017-02-27 22:58:59 +0100165
Kévin Redon33d1eb72018-07-08 13:58:12 +0200166 // Compute absolute value
167 if (value < 0) {
Harald Welted09829d2017-02-27 22:58:59 +0100168
Kévin Redon33d1eb72018-07-08 13:58:12 +0200169 absolute = -value;
170 }
171 else {
Harald Welted09829d2017-02-27 22:58:59 +0100172
Kévin Redon33d1eb72018-07-08 13:58:12 +0200173 absolute = value;
174 }
Harald Welted09829d2017-02-27 22:58:59 +0100175
Kévin Redon33d1eb72018-07-08 13:58:12 +0200176 // Take current digit into account when calculating width
177 width--;
Harald Welted09829d2017-02-27 22:58:59 +0100178
Kévin Redon33d1eb72018-07-08 13:58:12 +0200179 // Recursively write upper digits
180 if ((absolute / 10) > 0) {
Harald Welted09829d2017-02-27 22:58:59 +0100181
Kévin Redon33d1eb72018-07-08 13:58:12 +0200182 if (value < 0) {
183
184 num = PutSignedInt(pStr, fill, width, -(absolute / 10));
185 }
186 else {
Harald Welted09829d2017-02-27 22:58:59 +0100187
Kévin Redon33d1eb72018-07-08 13:58:12 +0200188 num = PutSignedInt(pStr, fill, width, absolute / 10);
189 }
190 pStr += num;
191 }
192 else {
Harald Welted09829d2017-02-27 22:58:59 +0100193
Kévin Redon33d1eb72018-07-08 13:58:12 +0200194 // Reserve space for sign
195 if (value < 0) {
Harald Welted09829d2017-02-27 22:58:59 +0100196
Kévin Redon33d1eb72018-07-08 13:58:12 +0200197 width--;
198 }
Harald Welted09829d2017-02-27 22:58:59 +0100199
Kévin Redon33d1eb72018-07-08 13:58:12 +0200200 // Write filler characters
201 while (width > 0) {
Harald Welted09829d2017-02-27 22:58:59 +0100202
Kévin Redon33d1eb72018-07-08 13:58:12 +0200203 PutChar(pStr, fill);
204 pStr++;
205 num++;
206 width--;
207 }
Harald Welted09829d2017-02-27 22:58:59 +0100208
Kévin Redon33d1eb72018-07-08 13:58:12 +0200209 // Write sign
210 if (value < 0) {
Harald Welted09829d2017-02-27 22:58:59 +0100211
Kévin Redon33d1eb72018-07-08 13:58:12 +0200212 num += PutChar(pStr, '-');
213 pStr++;
214 }
215 }
Harald Welted09829d2017-02-27 22:58:59 +0100216
Kévin Redon33d1eb72018-07-08 13:58:12 +0200217 // Write lower digit
218 num += PutChar(pStr, (absolute % 10) + '0');
Harald Welted09829d2017-02-27 22:58:59 +0100219
Kévin Redon33d1eb72018-07-08 13:58:12 +0200220 return num;
Harald Welted09829d2017-02-27 22:58:59 +0100221}
222
223//------------------------------------------------------------------------------
224// Writes an hexadecimal value into a string, using the given fill, width &
225// capital parameters.
226// Returns the number of char written.
227// \param pStr Storage string.
228// \param fill Fill character.
229// \param width Minimum integer width.
230// \param maj Indicates if the letters must be printed in lower- or upper-case.
231// \param value Hexadecimal value.
232//------------------------------------------------------------------------------
233signed int PutHexa(
Kévin Redon33d1eb72018-07-08 13:58:12 +0200234 char *pStr,
235 char fill,
236 signed int width,
237 unsigned char maj,
238 unsigned int value)
Harald Welted09829d2017-02-27 22:58:59 +0100239{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200240 signed int num = 0;
Harald Welted09829d2017-02-27 22:58:59 +0100241
Kévin Redon33d1eb72018-07-08 13:58:12 +0200242 // Decrement width
243 width--;
Harald Welted09829d2017-02-27 22:58:59 +0100244
Kévin Redon33d1eb72018-07-08 13:58:12 +0200245 // Recursively output upper digits
246 if ((value >> 4) > 0) {
Harald Welted09829d2017-02-27 22:58:59 +0100247
Kévin Redon33d1eb72018-07-08 13:58:12 +0200248 num += PutHexa(pStr, fill, width, maj, value >> 4);
249 pStr += num;
250 }
251 // Write filler chars
252 else {
Harald Welted09829d2017-02-27 22:58:59 +0100253
Kévin Redon33d1eb72018-07-08 13:58:12 +0200254 while (width > 0) {
Harald Welted09829d2017-02-27 22:58:59 +0100255
Kévin Redon33d1eb72018-07-08 13:58:12 +0200256 PutChar(pStr, fill);
257 pStr++;
258 num++;
259 width--;
260 }
261 }
Harald Welted09829d2017-02-27 22:58:59 +0100262
Kévin Redon33d1eb72018-07-08 13:58:12 +0200263 // Write current digit
264 if ((value & 0xF) < 10) {
Harald Welted09829d2017-02-27 22:58:59 +0100265
Kévin Redon33d1eb72018-07-08 13:58:12 +0200266 PutChar(pStr, (value & 0xF) + '0');
267 }
268 else if (maj) {
Harald Welted09829d2017-02-27 22:58:59 +0100269
Kévin Redon33d1eb72018-07-08 13:58:12 +0200270 PutChar(pStr, (value & 0xF) - 10 + 'A');
271 }
272 else {
Harald Welted09829d2017-02-27 22:58:59 +0100273
Kévin Redon33d1eb72018-07-08 13:58:12 +0200274 PutChar(pStr, (value & 0xF) - 10 + 'a');
275 }
276 num++;
Harald Welted09829d2017-02-27 22:58:59 +0100277
Kévin Redon33d1eb72018-07-08 13:58:12 +0200278 return num;
Harald Welted09829d2017-02-27 22:58:59 +0100279}
280
281//------------------------------------------------------------------------------
282// Global Functions
283//------------------------------------------------------------------------------
284
285//------------------------------------------------------------------------------
286/// Stores the result of a formatted string into another string. Format
287/// arguments are given in a va_list instance.
288/// Return the number of characters written.
289/// \param pStr Destination string.
290/// \param length Length of Destination string.
291/// \param pFormat Format string.
292/// \param ap Argument list.
293//------------------------------------------------------------------------------
294signed int vsnprintf(char *pStr, size_t length, const char *pFormat, va_list ap)
295{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200296 char fill;
297 unsigned char width;
298 signed int num = 0;
299 size_t size = 0;
Harald Welted09829d2017-02-27 22:58:59 +0100300
Kévin Redon33d1eb72018-07-08 13:58:12 +0200301 // Clear the string
302 if (pStr) {
Harald Welted09829d2017-02-27 22:58:59 +0100303
Kévin Redon33d1eb72018-07-08 13:58:12 +0200304 *pStr = 0;
305 }
Harald Welted09829d2017-02-27 22:58:59 +0100306
Kévin Redon33d1eb72018-07-08 13:58:12 +0200307 // Phase string
308 while (*pFormat != 0 && size < length) {
Harald Welted09829d2017-02-27 22:58:59 +0100309
Kévin Redon33d1eb72018-07-08 13:58:12 +0200310 // Normal character
311 if (*pFormat != '%') {
Harald Welted09829d2017-02-27 22:58:59 +0100312
Kévin Redon33d1eb72018-07-08 13:58:12 +0200313 *pStr++ = *pFormat++;
314 size++;
315 }
316 // Escaped '%'
317 else if (*(pFormat+1) == '%') {
Harald Welted09829d2017-02-27 22:58:59 +0100318
Kévin Redon33d1eb72018-07-08 13:58:12 +0200319 *pStr++ = '%';
320 pFormat += 2;
321 size++;
322 }
323 // Token delimiter
324 else {
Harald Welted09829d2017-02-27 22:58:59 +0100325
Kévin Redon33d1eb72018-07-08 13:58:12 +0200326 fill = ' ';
327 width = 0;
328 pFormat++;
Harald Welted09829d2017-02-27 22:58:59 +0100329
Kévin Redon33d1eb72018-07-08 13:58:12 +0200330 // Parse filler
331 if (*pFormat == '0') {
Harald Welted09829d2017-02-27 22:58:59 +0100332
Kévin Redon33d1eb72018-07-08 13:58:12 +0200333 fill = '0';
334 pFormat++;
335 }
Harald Welted09829d2017-02-27 22:58:59 +0100336
Kévin Redon33d1eb72018-07-08 13:58:12 +0200337 // Parse width
338 while ((*pFormat >= '0') && (*pFormat <= '9')) {
339
340 width = (width*10) + *pFormat-'0';
341 pFormat++;
342 }
Harald Welted09829d2017-02-27 22:58:59 +0100343
Kévin Redon33d1eb72018-07-08 13:58:12 +0200344 // Check if there is enough space
345 if (size + width > length) {
Harald Welted09829d2017-02-27 22:58:59 +0100346
Kévin Redon33d1eb72018-07-08 13:58:12 +0200347 width = length - size;
348 }
349
350 // Parse type
351 switch (*pFormat) {
352 case 'd':
353 case 'i': num = PutSignedInt(pStr, fill, width, va_arg(ap, signed int)); break;
354 case 'u': num = PutUnsignedInt(pStr, fill, width, va_arg(ap, unsigned int)); break;
355 case 'x': num = PutHexa(pStr, fill, width, 0, va_arg(ap, unsigned int)); break;
356 case 'X': num = PutHexa(pStr, fill, width, 1, va_arg(ap, unsigned int)); break;
357 case 's': num = PutString(pStr, va_arg(ap, char *)); break;
358 case 'c': num = PutChar(pStr, va_arg(ap, unsigned int)); break;
359 default:
360 return EOF;
361 }
Harald Welted09829d2017-02-27 22:58:59 +0100362
Kévin Redon33d1eb72018-07-08 13:58:12 +0200363 pFormat++;
364 pStr += num;
365 size += num;
366 }
367 }
Harald Welted09829d2017-02-27 22:58:59 +0100368
Kévin Redon33d1eb72018-07-08 13:58:12 +0200369 // NULL-terminated (final \0 is not counted)
370 if (size < length) {
Harald Welted09829d2017-02-27 22:58:59 +0100371
Kévin Redon33d1eb72018-07-08 13:58:12 +0200372 *pStr = 0;
373 }
374 else {
Harald Welted09829d2017-02-27 22:58:59 +0100375
Kévin Redon33d1eb72018-07-08 13:58:12 +0200376 *(--pStr) = 0;
377 size--;
378 }
Harald Welted09829d2017-02-27 22:58:59 +0100379
Kévin Redon33d1eb72018-07-08 13:58:12 +0200380 return size;
Harald Welted09829d2017-02-27 22:58:59 +0100381}
382
383//------------------------------------------------------------------------------
384/// Stores the result of a formatted string into another string. Format
385/// arguments are given in a va_list instance.
386/// Return the number of characters written.
387/// \param pString Destination string.
388/// \param length Length of Destination string.
389/// \param pFormat Format string.
390/// \param ... Other arguments
391//------------------------------------------------------------------------------
392signed int snprintf(char *pString, size_t length, const char *pFormat, ...)
393{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200394 va_list ap;
395 signed int rc;
Harald Welted09829d2017-02-27 22:58:59 +0100396
Kévin Redon33d1eb72018-07-08 13:58:12 +0200397 va_start(ap, pFormat);
398 rc = vsnprintf(pString, length, pFormat, ap);
399 va_end(ap);
Harald Welted09829d2017-02-27 22:58:59 +0100400
Kévin Redon33d1eb72018-07-08 13:58:12 +0200401 return rc;
Harald Welted09829d2017-02-27 22:58:59 +0100402}
403
404//------------------------------------------------------------------------------
405/// Stores the result of a formatted string into another string. Format
406/// arguments are given in a va_list instance.
407/// Return the number of characters written.
408/// \param pString Destination string.
409/// \param pFormat Format string.
410/// \param ap Argument list.
411//------------------------------------------------------------------------------
412signed int vsprintf(char *pString, const char *pFormat, va_list ap)
413{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200414 return vsnprintf(pString, MAX_STRING_SIZE, pFormat, ap);
Harald Welted09829d2017-02-27 22:58:59 +0100415}
416
417//------------------------------------------------------------------------------
418/// Outputs a formatted string on the given stream. Format arguments are given
419/// in a va_list instance.
420/// \param pStream Output stream.
421/// \param pFormat Format string
422/// \param ap Argument list.
423//------------------------------------------------------------------------------
424signed int vfprintf(FILE *pStream, const char *pFormat, va_list ap)
425{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200426 char pStr[MAX_STRING_SIZE];
427 char pError[] = "stdio.c: increase MAX_STRING_SIZE\n\r";
Harald Welted09829d2017-02-27 22:58:59 +0100428
Kévin Redon33d1eb72018-07-08 13:58:12 +0200429 // Write formatted string in buffer
430 if (vsprintf(pStr, pFormat, ap) >= MAX_STRING_SIZE) {
Harald Welted09829d2017-02-27 22:58:59 +0100431
Kévin Redon33d1eb72018-07-08 13:58:12 +0200432 fputs(pError, stderr);
433 }
Harald Welted09829d2017-02-27 22:58:59 +0100434
Kévin Redon33d1eb72018-07-08 13:58:12 +0200435 // Display string
436 return fputs(pStr, pStream);
Harald Welted09829d2017-02-27 22:58:59 +0100437}
438
439//------------------------------------------------------------------------------
Kévin Redon1836ac02018-08-02 15:02:05 +0200440/// Outputs a formatted string on the given stream. Format arguments are given
441/// in a va_list instance.
442/// \note This function is synchronous (i.e. blocks until the print completes)
443/// \param pStream Output stream.
444/// \param pFormat Format string
445/// \param ap Argument list.
446//------------------------------------------------------------------------------
447#pragma GCC diagnostic push
448#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
449signed int vfprintf_sync(FILE *pStream, const char *pFormat, va_list ap)
450{
451 char pStr[MAX_STRING_SIZE];
452 char pError[] = "stdio.c: increase MAX_STRING_SIZE\n\r";
453
454 // Write formatted string in buffer
455 if (vsprintf(pStr, pFormat, ap) >= MAX_STRING_SIZE) {
456
457 fputs_sync(pError, stderr);
458 }
459
460 // Display string
461 return fputs_sync(pStr, pStream);
462}
463#pragma GCC diagnostic pop
464
465//------------------------------------------------------------------------------
Harald Welted09829d2017-02-27 22:58:59 +0100466/// Outputs a formatted string on the DBGU stream. Format arguments are given
467/// in a va_list instance.
468/// \param pFormat Format string
469/// \param ap Argument list.
470//------------------------------------------------------------------------------
471signed int vprintf(const char *pFormat, va_list ap)
472{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200473 return vfprintf(stdout, pFormat, ap);
Harald Welted09829d2017-02-27 22:58:59 +0100474}
475
476//------------------------------------------------------------------------------
Kévin Redon1836ac02018-08-02 15:02:05 +0200477/// Outputs a formatted string on the DBGU stream. Format arguments are given
478/// in a va_list instance.
479/// \note This function is synchronous (i.e. blocks until the print completes)
480/// \param pFormat Format string
481/// \param ap Argument list.
482//------------------------------------------------------------------------------
483signed int vprintf_sync(const char *pFormat, va_list ap)
484{
485 return vfprintf_sync(stdout, pFormat, ap);
486}
487
488//------------------------------------------------------------------------------
Harald Welted09829d2017-02-27 22:58:59 +0100489/// Outputs a formatted string on the given stream, using a variable number of
490/// arguments.
491/// \param pStream Output stream.
492/// \param pFormat Format string.
493//------------------------------------------------------------------------------
494signed int fprintf(FILE *pStream, const char *pFormat, ...)
495{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200496 va_list ap;
497 signed int result;
Harald Welted09829d2017-02-27 22:58:59 +0100498
Kévin Redon33d1eb72018-07-08 13:58:12 +0200499 // Forward call to vfprintf
500 va_start(ap, pFormat);
501 result = vfprintf(pStream, pFormat, ap);
502 va_end(ap);
Harald Welted09829d2017-02-27 22:58:59 +0100503
Kévin Redon33d1eb72018-07-08 13:58:12 +0200504 return result;
Harald Welted09829d2017-02-27 22:58:59 +0100505}
506
507//------------------------------------------------------------------------------
508/// Outputs a formatted string on the DBGU stream, using a variable number of
509/// arguments.
510/// \param pFormat Format string.
511//------------------------------------------------------------------------------
512signed int printf(const char *pFormat, ...)
513{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200514 va_list ap;
515 signed int result;
Harald Welted09829d2017-02-27 22:58:59 +0100516
Kévin Redon33d1eb72018-07-08 13:58:12 +0200517 // Forward call to vprintf
518 va_start(ap, pFormat);
519 result = vprintf(pFormat, ap);
520 va_end(ap);
Harald Welted09829d2017-02-27 22:58:59 +0100521
Kévin Redon33d1eb72018-07-08 13:58:12 +0200522 return result;
Harald Welted09829d2017-02-27 22:58:59 +0100523}
524
525//------------------------------------------------------------------------------
Kévin Redon1836ac02018-08-02 15:02:05 +0200526/// Outputs a formatted string on the DBGU stream, using a variable number of
527/// arguments.
528/// \note This function is synchronous (i.e. blocks until the print completes)
529/// \param pFormat Format string.
530//------------------------------------------------------------------------------
531signed int printf_sync(const char *pFormat, ...)
532{
533 va_list ap;
534 signed int result;
535
536 // Forward call to vprintf
537 va_start(ap, pFormat);
538 result = vprintf_sync(pFormat, ap);
539 va_end(ap);
540
541 return result;
542}
543
544//------------------------------------------------------------------------------
Harald Welted09829d2017-02-27 22:58:59 +0100545/// Writes a formatted string inside another string.
546/// \param pStr Storage string.
547/// \param pFormat Format string.
548//------------------------------------------------------------------------------
549signed int sprintf(char *pStr, const char *pFormat, ...)
550{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200551 va_list ap;
552 signed int result;
Harald Welted09829d2017-02-27 22:58:59 +0100553
Kévin Redon33d1eb72018-07-08 13:58:12 +0200554 // Forward call to vsprintf
555 va_start(ap, pFormat);
556 result = vsprintf(pStr, pFormat, ap);
557 va_end(ap);
Harald Welted09829d2017-02-27 22:58:59 +0100558
Kévin Redon33d1eb72018-07-08 13:58:12 +0200559 return result;
Harald Welted09829d2017-02-27 22:58:59 +0100560}
561
562//------------------------------------------------------------------------------
563/// Outputs a string on stdout.
564/// \param pStr String to output.
565//------------------------------------------------------------------------------
566signed int puts(const char *pStr)
567{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200568 return fputs(pStr, stdout);
Harald Welted09829d2017-02-27 22:58:59 +0100569}
570