nanoprintf.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without modification,
7  * are permitted provided that the following conditions are met:
8  *
9  * Redistributions of source code must retain the above copyright notice, this list
10  * of conditions and the following disclaimer.
11  *
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.
15  *
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.
19  *
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.
30  */
31 
32 #include "nanoprintf.h"
33 
34 namespace rosflight_firmware
35 {
36 namespace nanoprintf
37 {
38 typedef void (*putcf)(void *, char);
40 static void *stdout_putp;
41 
42 #ifdef PRINTF_LONG_SUPPORT
43 
44 static void uli2a(unsigned long int num, unsigned int base, int uc, char *bf)
45 {
46  int n = 0;
47  unsigned int d = 1;
48  while (num / d >= base) d *= base;
49  while (d != 0)
50  {
51  int dgt = num / d;
52  num %= d;
53  d /= base;
54  if (n || dgt > 0 || d == 0)
55  {
56  *bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10);
57  ++n;
58  }
59  }
60  *bf = 0;
61 }
62 
63 static void li2a(long num, char *bf)
64 {
65  if (num < 0)
66  {
67  num = -num;
68  *bf++ = '-';
69  }
70  uli2a(num, 10, 0, bf);
71 }
72 
73 #endif
74 
75 static void ui2a(unsigned int num, unsigned int base, int uc, char *bf)
76 {
77  int n = 0;
78  unsigned int d = 1;
79 #pragma GCC diagnostic push
80 #pragma GCC diagnostic ignored "-Wstrict-overflow"
81  while (num / d >= base)
82 #pragma GCC diagnostic pop
83  d *= base;
84  while (d != 0)
85  {
86  int dgt = num / d;
87  num %= d;
88  d /= base;
89  if (n || dgt > 0 || d == 0)
90  {
91  *bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10);
92  ++n;
93  }
94  }
95  *bf = 0;
96 }
97 
98 static void i2a(int num, char *bf)
99 {
100  if (num < 0)
101  {
102  num = -num;
103  *bf++ = '-';
104  }
105  ui2a(num, 10, 0, bf);
106 }
107 
108 static int a2d(char ch)
109 {
110  if (ch >= '0' && ch <= '9')
111  return ch - '0';
112  else if (ch >= 'a' && ch <= 'f')
113  return ch - 'a' + 10;
114  else if (ch >= 'A' && ch <= 'F')
115  return ch - 'A' + 10;
116  else
117  return -1;
118 }
119 
120 static char a2i(char ch, char **src, int base, int *nump)
121 {
122  char *p = *src;
123  int num = 0;
124  int digit;
125  while ((digit = a2d(ch)) >= 0)
126  {
127  if (digit > base)
128  break;
129  num = num * base + digit;
130  ch = *p++;
131  }
132  *src = p;
133  *nump = num;
134  return ch;
135 }
136 
137 static void putchw(void *putp, putcf putf, int n, char z, char *bf)
138 {
139  char fc = z ? '0' : ' ';
140  char ch;
141  char *p = bf;
142  while (*p++ && n != 0) n--;
143  while (n-- != 0) putf(putp, fc);
144  while ((ch = *bf++)) putf(putp, ch);
145 }
146 
147 void tfp_format(void *putp, putcf putf, const char *fmt, va_list va)
148 {
149  char bf[12];
150 
151  char ch;
152 
153  while ((ch = *(fmt++)))
154  {
155  if (ch != '%')
156  putf(putp, ch);
157  else
158  {
159  char lz = 0;
160 #ifdef PRINTF_LONG_SUPPORT
161  char lng = 0;
162 #endif
163  int w = 0;
164  ch = *(fmt++);
165  if (ch == '0')
166  {
167  ch = *(fmt++);
168  lz = 1;
169  }
170  if (ch >= '0' && ch <= '9')
171  {
172  ch = a2i(ch, const_cast<char **>(&fmt), 10, &w);
173  }
174 #ifdef PRINTF_LONG_SUPPORT
175  if (ch == 'l')
176  {
177  ch = *(fmt++);
178  lng = 1;
179  }
180 #endif
181  switch (ch)
182  {
183  case 0:
184  goto abort;
185  case 'u':
186  {
187 #ifdef PRINTF_LONG_SUPPORT
188  if (lng)
189  uli2a(va_arg(va, unsigned long int), 10, 0, bf);
190  else
191 #endif
192  ui2a(va_arg(va, unsigned int), 10, 0, bf);
193  putchw(putp, putf, w, lz, bf);
194  break;
195  }
196  case 'd':
197  {
198 #ifdef PRINTF_LONG_SUPPORT
199  if (lng)
200  li2a(va_arg(va, unsigned long int), bf);
201  else
202 #endif
203  i2a(va_arg(va, int), bf);
204  putchw(putp, putf, w, lz, bf);
205  break;
206  }
207  case 'x':
208  case 'X':
209 #ifdef PRINTF_LONG_SUPPORT
210  if (lng)
211  uli2a(va_arg(va, unsigned long int), 16, (ch == 'X'), bf);
212  else
213 #endif
214  ui2a(va_arg(va, unsigned int), 16, (ch == 'X'), bf);
215  putchw(putp, putf, w, lz, bf);
216  break;
217  case 'c':
218  putf(putp, static_cast<char>(va_arg(va, int)));
219  break;
220  case 's':
221  putchw(putp, putf, w, 0, va_arg(va, char *));
222  break;
223  case '%':
224  putf(putp, ch);
225  default:
226  break;
227  }
228  }
229  }
230 abort:;
231 }
232 
233 void init_printf(void *putp, void (*putf)(void *, char))
234 {
235  stdout_putf = putf;
236  stdout_putp = putp;
237 }
238 
239 void tfp_printf(const char *fmt, ...)
240 {
241  va_list va;
242  va_start(va, fmt);
243  tfp_format(stdout_putp, stdout_putf, fmt, va);
244  va_end(va);
245 }
246 
247 static void putcp(void *p, char c)
248 {
249  *(*(static_cast<char **>(p)))++ = c;
250 }
251 
252 void tfp_sprintf(char *s, const char *fmt, va_list va)
253 {
254  tfp_format(&s, putcp, fmt, va);
255  putcp(&s, 0);
256 }
257 
258 } // namespace nanoprintf
259 } // namespace rosflight_firmware
d
void(* putcf)(void *, char)
Definition: nanoprintf.cpp:38
static void uli2a(unsigned long int num, unsigned int base, int uc, char *bf)
Definition: printf.cpp:50
static void li2a(long num, char *bf)
Definition: printf.cpp:68
static void ui2a(unsigned int num, unsigned int base, int uc, char *bf)
Definition: nanoprintf.cpp:75
void init_printf(void *putp, void(*putf)(void *, char))
Definition: nanoprintf.cpp:233
static void i2a(int num, char *bf)
Definition: nanoprintf.cpp:98
void tfp_format(void *putp, void(*putf)(void *, char), const char *fmt, va_list va)
Definition: nanoprintf.cpp:147
static void putcp(void *p, char c)
Definition: nanoprintf.cpp:247
static char a2i(char ch, char **src, int base, int *nump)
Definition: nanoprintf.cpp:120
void tfp_sprintf(char *s, const char *fmt, va_list va)
Definition: nanoprintf.cpp:252
void tfp_printf(const char *fmt,...)
Definition: nanoprintf.cpp:239
static void putchw(void *putp, putcf putf, int n, char z, char *bf)
Definition: nanoprintf.cpp:137


rosflight_firmware
Author(s): Daniel Koch , James Jackson
autogenerated on Thu Apr 15 2021 05:07:47