Merge pull request #11198 from SteveCEvans/sce_rc2
[betaflight.git] / src / main / common / printf.c
blob4c65e293ed662f9982547880051a58e358ed4fa7
1 /*
2 * Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
9 * Redistributions of source code must retain the above copyright notice, this list
10 * of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice, this
13 * list of conditions and the following disclaimer in the documentation and/or other
14 * materials provided with the distribution.
16 * Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its
17 * contributors may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
26 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
29 * OF SUCH DAMAGE.
32 #include <stdbool.h>
33 #include <stdint.h>
34 #include <stdarg.h>
35 #include <stdlib.h>
37 #include "platform.h"
39 #include "build/build_config.h"
41 #include "printf.h"
43 #ifdef REQUIRE_PRINTF_LONG_SUPPORT
44 #include "typeconversion.h"
45 #endif
48 #ifdef REQUIRE_CC_ARM_PRINTF_SUPPORT
50 putcf stdout_putf;
51 void *stdout_putp;
53 // print bf, padded from left to at least n characters.
54 // padding is zero ('0') if z!=0, space (' ') otherwise
55 static int putchw(void *putp, putcf putf, int n, char z, char *bf)
57 int written = 0;
58 char fc = z ? '0' : ' ';
59 char ch;
60 char *p = bf;
61 while (*p++ && n > 0)
62 n--;
63 while (n-- > 0) {
64 putf(putp, fc); written++;
66 while ((ch = *bf++)) {
67 putf(putp, ch); written++;
69 return written;
72 // retrun number of bytes written
73 int tfp_format(void *putp, putcf putf, const char *fmt, va_list va)
75 char bf[12];
76 int written = 0;
77 char ch;
79 while ((ch = *(fmt++))) {
80 if (ch != '%') {
81 putf(putp, ch); written++;
82 } else {
83 char lz = 0;
84 #ifdef REQUIRE_PRINTF_LONG_SUPPORT
85 char lng = 0;
86 #endif
87 int w = 0;
88 ch = *(fmt++);
89 if (ch == '0') {
90 ch = *(fmt++);
91 lz = 1;
93 if (ch >= '0' && ch <= '9') {
94 ch = a2i(ch, &fmt, 10, &w);
96 #ifdef REQUIRE_PRINTF_LONG_SUPPORT
97 if (ch == 'l') {
98 ch = *(fmt++);
99 lng = 1;
101 #endif
102 switch (ch) {
103 case 0:
104 goto abort;
105 case 'u':{
106 #ifdef REQUIRE_PRINTF_LONG_SUPPORT
107 if (lng)
108 uli2a(va_arg(va, unsigned long int), 10, 0, bf);
109 else
110 #endif
111 ui2a(va_arg(va, unsigned int), 10, 0, bf);
112 written += putchw(putp, putf, w, lz, bf);
113 break;
115 case 'd':{
116 #ifdef REQUIRE_PRINTF_LONG_SUPPORT
117 if (lng)
118 li2a(va_arg(va, unsigned long int), bf);
119 else
120 #endif
121 i2a(va_arg(va, int), bf);
122 written += putchw(putp, putf, w, lz, bf);
123 break;
125 case 'x':
126 case 'X':
127 #ifdef REQUIRE_PRINTF_LONG_SUPPORT
128 if (lng)
129 uli2a(va_arg(va, unsigned long int), 16, (ch == 'X'), bf);
130 else
131 #endif
132 ui2a(va_arg(va, unsigned int), 16, (ch == 'X'), bf);
133 written += putchw(putp, putf, w, lz, bf);
134 break;
135 case 'c':
136 putf(putp, (char) (va_arg(va, int))); written++;
137 break;
138 case 's':
139 written += putchw(putp, putf, w, 0, va_arg(va, char *));
140 break;
141 case '%':
142 putf(putp, ch); written++;
143 break;
144 case 'n':
145 *va_arg(va, int*) = written;
146 break;
147 default:
148 break;
152 abort:
153 return written;
156 void init_printf(void *putp, void (*putf) (void *, char))
158 stdout_putf = putf;
159 stdout_putp = putp;
162 static void putcp(void *p, char c)
164 *(*((char **) p))++ = c;
167 int tfp_sprintf(char *s, const char *fmt, ...)
169 va_list va;
171 va_start(va, fmt);
172 int written = tfp_format(&s, putcp, fmt, va);
173 putcp(&s, 0);
174 va_end(va);
175 return written;
178 #endif // REQUIRE_CC_ARM_PRINTF_SUPPORT