SAM4S-EK_FreeRTOS+FAT-SL  1.0
An example project to test the functionality of FreeRTOS+FAT-SL using SD card as data storage medium
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Modules
printf_stdarg.c
Go to the documentation of this file.
1 /*
2  Copyright 2001, 2002 Georges Menie (www.menie.org)
3  stdarg version contributed by Christian Ettinger
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 
20 /*
21  putchar is the only external dependency for this file,
22  if you have a working putchar, leave it commented out.
23  If not, uncomment the define below and
24  replace outbyte(c) by your own function call.
25 */
26 
27 #define putchar(c) pchar(c)
28 
29 #include <stdarg.h>
30 #include "printf_stdarg.h"
31 
32 static void printchar(char **str, int c);
33 static int prints(char **out, const char *string, int width, int pad);
34 static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase);
35 static int print( char **out, const char *format, va_list args );
36 
37 int pchar (const char char_data)
38 {
39  /* Wait for transmitter to be ready */
40  while(!(UART0->UART_SR & UART_SR_TXRDY));
41  /* Send a character to transmit holding register */
42  UART0->UART_THR = char_data;
43  return 0;
44 }
45 
46 int gchar (uint8_t *puc_data)
47 {
48  /* Check if the receiver is ready */
49  while(!(UART0->UART_SR & UART_SR_RXRDY));
50  /* Read character from receive holding register */
51  *puc_data = (uint8_t) UART0->UART_RHR;
52  return 0;
53 }
54 
55 static void printchar(char **str, int c)
56 {
57  extern int pchar(const char c);
58 
59  if (str)
60  {
61  **str = c;
62  ++(*str);
63  }
64  else (void)pchar(c);
65 }
66 
67 #define PAD_RIGHT 1
68 #define PAD_ZERO 2
69 
70 static int prints(char **out, const char *string, int width, int pad)
71 {
72  register int pc = 0, padchar = ' ';
73 
74  if (width > 0)
75  {
76  register int len = 0;
77  register const char *ptr;
78  for (ptr = string; *ptr; ++ptr) ++len;
79  if (len >= width) width = 0;
80  else width -= len;
81  if (pad & PAD_ZERO) padchar = '0';
82  }
83  if (!(pad & PAD_RIGHT))
84  {
85  for ( ; width > 0; --width)
86  {
87  printchar (out, padchar);
88  ++pc;
89  }
90  }
91  for ( ; *string ; ++string)
92  {
93  printchar (out, *string);
94  ++pc;
95  }
96  for ( ; width > 0; --width)
97  {
98  printchar (out, padchar);
99  ++pc;
100  }
101 
102  return pc;
103 }
104 
105 /* the following should be enough for 32 bit int */
106 #define PRINT_BUF_LEN 12
107 
108 static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
109 {
110  char print_buf[PRINT_BUF_LEN];
111  register char *s;
112  register int t, neg = 0, pc = 0;
113  register unsigned int u = i;
114 
115  if (i == 0)
116  {
117  print_buf[0] = '0';
118  print_buf[1] = '\0';
119  return prints (out, print_buf, width, pad);
120  }
121 
122  if (sg && b == 10 && i < 0)
123  {
124  neg = 1;
125  u = -i;
126  }
127 
128  s = print_buf + PRINT_BUF_LEN-1;
129  *s = '\0';
130 
131  while (u)
132  {
133  t = u % b;
134  if( t >= 10 )
135  t += letbase - '0' - 10;
136  *--s = t + '0';
137  u /= b;
138  }
139 
140  if (neg)
141  {
142  if( width && (pad & PAD_ZERO) )
143  {
144  printchar (out, '-');
145  ++pc;
146  --width;
147  }
148  else
149  {
150  *--s = '-';
151  }
152  }
153 
154  return pc + prints (out, s, width, pad);
155 }
156 
157 static int print( char **out, const char *format, va_list args )
158 {
159  register int width, pad;
160  register int pc = 0;
161  char scr[2];
162 
163  for (; *format != 0; ++format)
164  {
165  if (*format == '%')
166  {
167  ++format;
168  width = pad = 0;
169  if (*format == '\0') break;
170  if (*format == '%') goto out;
171  if (*format == '-')
172  {
173  ++format;
174  pad = PAD_RIGHT;
175  }
176  while (*format == '0')
177  {
178  ++format;
179  pad |= PAD_ZERO;
180  }
181  for ( ; *format >= '0' && *format <= '9'; ++format)
182  {
183  width *= 10;
184  width += *format - '0';
185  }
186  if( *format == 's' )
187  {
188  register char *s = (char *)va_arg( args, int );
189  pc += prints (out, s?s:"(null)", width, pad);
190  continue;
191  }
192  if( *format == 'd' )
193  {
194  pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');
195  continue;
196  }
197  if( *format == 'x' )
198  {
199  pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a');
200  continue;
201  }
202  if( *format == 'X' )
203  {
204  pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A');
205  continue;
206  }
207  if( *format == 'u' )
208  {
209  pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');
210  continue;
211  }
212  if( *format == 'c' )
213  {
214  /* char are converted to int then pushed on the stack */
215  scr[0] = (char)va_arg( args, int );
216  scr[1] = '\0';
217  pc += prints (out, scr, width, pad);
218  continue;
219  }
220  }
221  else
222  {
223  out:
224  printchar (out, *format);
225  ++pc;
226  }
227  }
228  if (out) **out = '\0';
229  va_end( args );
230  return pc;
231 }
232 
233 int printf(const char *format, ...)
234 {
235  va_list args;
236 
237  va_start( args, format );
238  return print( 0, format, args );
239 }
240 
241 int sprintf(char *out, const char *format, ...)
242 {
243  va_list args;
244 
245  va_start( args, format );
246  return print( &out, format, args );
247 }
248 
249 
250 int snprintf( char *buf, unsigned int count, const char *format, ... )
251 {
252  va_list args;
253 
254  ( void ) count;
255 
256  va_start( args, format );
257  return print( &buf, format, args );
258 }
259 
260 
261 #ifdef TEST_PRINTF
262 int main(void)
263 {
264  char *ptr = "Hello world!";
265  char *np = 0;
266  int i = 5;
267  unsigned int bs = sizeof(int)*8;
268  int mi;
269  char buf[80];
270 
271  mi = (1 << (bs-1)) + 1;
272  printf("%s\n", ptr);
273  printf("printf test\n");
274  printf("%s is null pointer\n", np);
275  printf("%d = 5\n", i);
276  printf("%d = - max int\n", mi);
277  printf("char %c = 'a'\n", 'a');
278  printf("hex %x = ff\n", 0xff);
279  printf("hex %02x = 00\n", 0);
280  printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);
281  printf("%d %s(s)%", 0, "message");
282  printf("\n");
283  printf("%d %s(s) with %%\n", 0, "message");
284  sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf);
285  sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf);
286  sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf);
287  sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf);
288  sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf);
289  sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf);
290  sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf);
291  sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf);
292 
293  return 0;
294 }
295 
296 /*
297  * if you compile this file with
298  * gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c
299  * you will get a normal warning:
300  * printf.c:214: warning: spurious trailing `%' in format
301  * this line is testing an invalid % at the end of the format string.
302  *
303  * this should display (on 32bit int machine) :
304  *
305  * Hello world!
306  * printf test
307  * (null) is null pointer
308  * 5 = 5
309  * -2147483647 = - max int
310  * char a = 'a'
311  * hex ff = ff
312  * hex 00 = 00
313  * signed -3 = unsigned 4294967293 = hex fffffffd
314  * 0 message(s)
315  * 0 message(s) with %
316  * justif: "left "
317  * justif: " right"
318  * 3: 0003 zero padded
319  * 3: 3 left justif.
320  * 3: 3 right justif.
321  * -3: -003 zero padded
322  * -3: -3 left justif.
323  * -3: -3 right justif.
324  */
325 
326 #endif
#define PAD_RIGHT
Definition: printf_stdarg.c:67
#define PRINT_BUF_LEN
int printf(const char *format,...)
#define PAD_ZERO
Definition: printf_stdarg.c:68
int sprintf(char *out, const char *format,...)
int gchar(uint8_t *puc_data)
Definition: printf_stdarg.c:46
int pchar(const char char_data)
Definition: printf_stdarg.c:37
int main(void)
Application entry point.
int snprintf(char *buf, unsigned int count, const char *format,...)