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


rosflight_firmware
Author(s): Daniel Koch , James Jackson
autogenerated on Thu Oct 24 2019 03:17:19