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


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