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


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