dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
printf-stdarg.c
Go to the documentation of this file.
1 
13 /*
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful, but
20  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  * for more details.
23  *
24  * You should have received a copy of the GNU General Public License along
25  * with this program; if not, see <http://www.gnu.org/licenses/>
26  */
27 
28 /*
29  putchar is the only external dependency for this file,
30  if you have a working putchar, leave it commented out.
31  If not, uncomment the define below and
32  replace outbyte(c) by your own function call.
33 
34 #define putchar(c) outbyte(c)
35 */
36 //#define putchar(c) COMSendChar(c)
37 
38 #include <pios.h>
39 
40 static void printchar(char **str, int c)
41 {
42  if (str) {
43  **str = c;
44  ++(*str);
45  }
46 #if defined(PIOS_INCLUDE_DEBUG_CONSOLE)
47  else
49 #endif
50 
51 }
52 
53 #define PAD_RIGHT 1
54 #define PAD_ZERO 2
55 
56 static int prints(char **out, const char *string, int width, int pad)
57 {
58  register int pc = 0, padchar = ' ';
59 
60  if (width > 0) {
61  register int len = 0;
62  register const char *ptr;
63  for (ptr = string; *ptr; ++ptr)
64  ++len;
65  if (len >= width)
66  width = 0;
67  else
68  width -= len;
69  if (pad & PAD_ZERO)
70  padchar = '0';
71  }
72  if (!(pad & PAD_RIGHT)) {
73  for (; width > 0; --width) {
74  printchar(out, padchar);
75  ++pc;
76  }
77  }
78  for (; *string; ++string) {
79  printchar(out, *string);
80  ++pc;
81  }
82  for (; width > 0; --width) {
83  printchar(out, padchar);
84  ++pc;
85  }
86 
87  return pc;
88 }
89 
90 /* the following should be enough for 32 bit int */
91 #define PRINT_BUF_LEN 12
92 
93 static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
94 {
95  char print_buf[PRINT_BUF_LEN];
96  register char *s;
97  register int t, neg = 0, pc = 0;
98  register unsigned int u = i;
99 
100  if (i == 0) {
101  print_buf[0] = '0';
102  print_buf[1] = '\0';
103  return prints(out, print_buf, width, pad);
104  }
105 
106  if (sg && b == 10 && i < 0) {
107  neg = 1;
108  u = -i;
109  }
110 
111  s = print_buf + PRINT_BUF_LEN - 1;
112  *s = '\0';
113 
114  while (u) {
115  t = u % b;
116  if (t >= 10)
117  t += letbase - '0' - 10;
118  *--s = t + '0';
119  u /= b;
120  }
121 
122  if (neg) {
123  if (width && (pad & PAD_ZERO)) {
124  printchar(out, '-');
125  ++pc;
126  --width;
127  } else {
128  *--s = '-';
129  }
130  }
131 
132  return pc + prints(out, s, width, pad);
133 }
134 
135 static int print(char **out, const char *format, va_list args)
136 {
137  register int width, pad;
138  register int pc = 0;
139  char scr[2];
140 
141  for (; *format != 0; ++format) {
142  if (*format == '%') {
143  ++format;
144  width = pad = 0;
145  if (*format == '\0')
146  break;
147  if (*format == '%')
148  goto out;
149  if (*format == '-') {
150  ++format;
151  pad = PAD_RIGHT;
152  }
153  while (*format == '0') {
154  ++format;
155  pad |= PAD_ZERO;
156  }
157  for (; *format >= '0' && *format <= '9'; ++format) {
158  width *= 10;
159  width += *format - '0';
160  }
161  if (*format == 's') {
162  register char *s = (char *)va_arg(args, int);
163  pc += prints(out, s ? s : "(null)", width, pad);
164  continue;
165  }
166  if (*format == 'd') {
167  pc += printi(out, va_arg(args, int), 10, 1, width, pad, 'a');
168  continue;
169  }
170  if (*format == 'x') {
171  pc += printi(out, va_arg(args, int), 16, 0, width, pad, 'a');
172  continue;
173  }
174  if (*format == 'X') {
175  pc += printi(out, va_arg(args, int), 16, 0, width, pad, 'A');
176  continue;
177  }
178  if (*format == 'u') {
179  pc += printi(out, va_arg(args, int), 10, 0, width, pad, 'a');
180  continue;
181  }
182  if (*format == 'c') {
183  /* char are converted to int then pushed on the stack */
184  scr[0] = (char)va_arg(args, int);
185  scr[1] = '\0';
186  pc += prints(out, scr, width, pad);
187  continue;
188  }
189  } else {
190 out:
191  printchar(out, *format);
192  ++pc;
193  }
194  }
195  if (out)
196  **out = '\0';
197  va_end(args);
198  return pc;
199 }
200 
201 int printf(const char *format, ...)
202 {
203  va_list args;
204 
205  va_start(args, format);
206  return print(0, format, args);
207 }
208 
209 // TK: added for alternative parameter passing
210 int vprintf(const char *format, va_list args)
211 {
212  return print(0, format, args);
213 }
214 
215 int sprintf(char *out, const char *format, ...)
216 {
217  va_list args;
218 
219  va_start(args, format);
220  return print(&out, format, args);
221 }
222 
223 // TK: added for alternative parameter passing
224 int vsprintf(char *out, const char *format, va_list args)
225 {
226  char *_out;
227  _out = out;
228  return print(&_out, format, args);
229 }
230 
231 int snprintf(char *buf, size_t count, const char *format, ...)
232 {
233  va_list args;
234 
235  (void)count;
236 
237  va_start(args, format);
238  return print(&buf, format, args);
239 }
240 
#define PIOS_COM_DEBUG
Definition: pios_board.h:67
static int prints(char **out, const char *string, int width, int pad)
Definition: printf-stdarg.c:56
Main PiOS header to include all the compiled in PiOS options.
const uint8_t count
Definition: panel.c:515
int vprintf(const char *format, va_list args)
int sprintf(char *out, const char *format,...)
static int print(char **out, const char *format, va_list args)
int32_t PIOS_COM_SendChar(uintptr_t com_id, char c)
static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
Definition: printf-stdarg.c:93
static void printchar(char **str, int c)
Definition: printf-stdarg.c:40
uint8_t i
Definition: msp_messages.h:97
#define PRINT_BUF_LEN
Definition: printf-stdarg.c:91
#define PAD_ZERO
Definition: printf-stdarg.c:54
#define PAD_RIGHT
Definition: printf-stdarg.c:53
int vsprintf(char *out, const char *format, va_list args)
int printf(const char *format,...)
int snprintf(char *buf, size_t count, const char *format,...)
tuple args
Definition: px_mkfw.py:77
uint8_t pad[62]
Definition: bl_messages.h:155