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


rosflight_firmware
Author(s): Daniel Koch , James Jackson
autogenerated on Wed Jul 3 2019 19:59:25