]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/lwIP_AVR32_UC3/printf-stdarg.c
Update demos that use FreeRTOS+FAT SL to have correct version numbers after the updat...
[freertos] / FreeRTOS / Demo / lwIP_AVR32_UC3 / printf-stdarg.c
1 /*This file has been prepared for Doxygen automatic documentation generation.*/\r
2 /*! \file *********************************************************************\r
3  *\r
4  * \brief sprintf functions to replace newlib for AVR32 UC3.\r
5  *\r
6  * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32\r
7  * - Supported devices:  All AVR32 devices can be used.\r
8  * - AppNote:\r
9  *\r
10  * \author               Atmel Corporation: http://www.atmel.com \n\r
11  *                       Support and FAQ: http://support.atmel.no/\r
12  *\r
13  *****************************************************************************/\r
14 \r
15 /* Copyright (c) 2007, Atmel Corporation All rights reserved.\r
16  *\r
17  * Redistribution and use in source and binary forms, with or without\r
18  * modification, are permitted provided that the following conditions are met:\r
19  *\r
20  * 1. Redistributions of source code must retain the above copyright notice,\r
21  * this list of conditions and the following disclaimer.\r
22  *\r
23  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
24  * this list of conditions and the following disclaimer in the documentation\r
25  * and/or other materials provided with the distribution.\r
26  *\r
27  * 3. The name of ATMEL may not be used to endorse or promote products derived\r
28  * from this software without specific prior written permission.\r
29  *\r
30  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED\r
31  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
32  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND\r
33  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,\r
34  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
35  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
36  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
37  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
39  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
40  */\r
41 \r
42 /*\r
43         Copyright 2001, 2002 Georges Menie (www.menie.org)\r
44         stdarg version contributed by Christian Ettinger\r
45 \r
46     This program is free software; you can redistribute it and/or modify\r
47     it under the terms of the GNU Lesser General Public License as published by\r
48     the Free Software Foundation; either version 2 of the License, or\r
49     (at your option) any later version.\r
50 \r
51     This program is distributed in the hope that it will be useful,\r
52     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
53     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
54     GNU Lesser General Public License for more details.\r
55 \r
56     You should have received a copy of the GNU Lesser General Public License\r
57     along with this program; if not, write to the Free Software\r
58     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
59 */\r
60 \r
61 /*\r
62         putchar is the only external dependency for this file,\r
63         if you have a working putchar, leave it commented out.\r
64         If not, uncomment the define below and\r
65         replace outbyte(c) by your own function call.\r
66 \r
67 #define putchar(c) outbyte(c)\r
68 */\r
69 \r
70 #include <sys/reent.h>\r
71 #include <stdarg.h>\r
72 \r
73 \r
74 static void printchar(char **str, int c)\r
75 {\r
76         extern int putchar(int c);\r
77         \r
78         if (str) {\r
79                 **str = c;\r
80                 ++(*str);\r
81         }\r
82         else (void)putchar(c);\r
83 }\r
84 \r
85 #define PAD_RIGHT 1\r
86 #define PAD_ZERO 2\r
87 \r
88 static int prints(char **out, const char *string, int width, int pad)\r
89 {\r
90         register int pc = 0, padchar = ' ';\r
91 \r
92         if (width > 0) {\r
93                 register int len = 0;\r
94                 register const char *ptr;\r
95                 for (ptr = string; *ptr; ++ptr) ++len;\r
96                 if (len >= width) width = 0;\r
97                 else width -= len;\r
98                 if (pad & PAD_ZERO) padchar = '0';\r
99         }\r
100         if (!(pad & PAD_RIGHT)) {\r
101                 for ( ; width > 0; --width) {\r
102                         printchar (out, padchar);\r
103                         ++pc;\r
104                 }\r
105         }\r
106         for ( ; *string ; ++string) {\r
107                 printchar (out, *string);\r
108                 ++pc;\r
109         }\r
110         for ( ; width > 0; --width) {\r
111                 printchar (out, padchar);\r
112                 ++pc;\r
113         }\r
114 \r
115         return pc;\r
116 }\r
117 \r
118 /* the following should be enough for 32 bit int */\r
119 #define PRINT_BUF_LEN 12\r
120 \r
121 static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)\r
122 {\r
123         char print_buf[PRINT_BUF_LEN];\r
124         register char *s;\r
125         register int t, neg = 0, pc = 0;\r
126         register unsigned int u = i;\r
127 \r
128         if (i == 0) {\r
129                 print_buf[0] = '0';\r
130                 print_buf[1] = '\0';\r
131                 return prints (out, print_buf, width, pad);\r
132         }\r
133 \r
134         if (sg && b == 10 && i < 0) {\r
135                 neg = 1;\r
136                 u = -i;\r
137         }\r
138 \r
139         s = print_buf + PRINT_BUF_LEN-1;\r
140         *s = '\0';\r
141 \r
142         while (u) {\r
143                 t = u % b;\r
144                 if( t >= 10 )\r
145                         t += letbase - '0' - 10;\r
146                 *--s = t + '0';\r
147                 u /= b;\r
148         }\r
149 \r
150         if (neg) {\r
151                 if( width && (pad & PAD_ZERO) ) {\r
152                         printchar (out, '-');\r
153                         ++pc;\r
154                         --width;\r
155                 }\r
156                 else {\r
157                         *--s = '-';\r
158                 }\r
159         }\r
160 \r
161         return pc + prints (out, s, width, pad);\r
162 }\r
163 \r
164 int fprintf(__FILE *stream, const char *format, ...)\r
165 {\r
166 return 0;\r
167 }\r
168 static int print(char **out, const char *format, va_list args )\r
169 {\r
170         register int width, pad;\r
171         register int pc = 0;\r
172         char scr[2];\r
173 \r
174         for (; *format != 0; ++format) {\r
175                 if (*format == '%') {\r
176                         ++format;\r
177                         width = pad = 0;\r
178                         if (*format == '\0') break;\r
179                         if (*format == '%') goto out;\r
180                         if (*format == '-') {\r
181                                 ++format;\r
182                                 pad = PAD_RIGHT;\r
183                         }\r
184                         while (*format == '0') {\r
185                                 ++format;\r
186                                 pad |= PAD_ZERO;\r
187                         }\r
188                         for ( ; *format >= '0' && *format <= '9'; ++format) {\r
189                                 width *= 10;\r
190                                 width += *format - '0';\r
191                         }\r
192                         if( *format == 's' ) {\r
193                                 register char *s = (char *)va_arg( args, int );\r
194                                 pc += prints (out, s?s:"(null)", width, pad);\r
195                                 continue;\r
196                         }\r
197                         if( *format == 'd' ) {\r
198                                 pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');\r
199                                 continue;\r
200                         }\r
201                         if( *format == 'x' ) {\r
202                                 pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a');\r
203                                 continue;\r
204                         }\r
205                         if( *format == 'X' ) {\r
206                                 pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A');\r
207                                 continue;\r
208                         }\r
209                         if( *format == 'u' ) {\r
210                                 pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');\r
211                                 continue;\r
212                         }\r
213                         if( *format == 'c' ) {\r
214                                 /* char are converted to int then pushed on the stack */\r
215                                 scr[0] = (char)va_arg( args, int );\r
216                                 scr[1] = '\0';\r
217                                 pc += prints (out, scr, width, pad);\r
218                                 continue;\r
219                         }\r
220                 }\r
221                 else {\r
222                 out:\r
223                         printchar (out, *format);\r
224                         ++pc;\r
225                 }\r
226         }\r
227         if (out) **out = '\0';\r
228         va_end( args );\r
229         return pc;\r
230 }\r
231 \r
232 int printk(const char *format, ...)\r
233 {\r
234         va_list args;\r
235         \r
236         va_start( args, format );\r
237         return print( 0, format, args );\r
238 }\r
239 \r
240 int sprintf(char *out, const char *format, ...)\r
241 {\r
242         va_list args;\r
243         \r
244         va_start( args, format );\r
245         return print( &out, format, args );\r
246 }\r
247 \r
248 #ifdef TEST_PRINTF\r
249 int main(void)\r
250 {\r
251         char *ptr = "Hello world!";\r
252         char *np = 0;\r
253         int i = 5;\r
254         unsigned int bs = sizeof(int)*8;\r
255         int mi;\r
256         char buf[80];\r
257 \r
258         mi = (1 << (bs-1)) + 1;\r
259         printf("%s\n", ptr);\r
260         printf("printf test\n");\r
261         printf("%s is null pointer\n", np);\r
262         printf("%d = 5\n", i);\r
263         printf("%d = - max int\n", mi);\r
264         printf("char %c = 'a'\n", 'a');\r
265         printf("hex %x = ff\n", 0xff);\r
266         printf("hex %02x = 00\n", 0);\r
267         printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);\r
268         printf("%d %s(s)%", 0, "message");\r
269         printf("\n");\r
270         printf("%d %s(s) with %%\n", 0, "message");\r
271         sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf);\r
272         sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf);\r
273         sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf);\r
274         sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf);\r
275         sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf);\r
276         sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf);\r
277         sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf);\r
278         sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf);\r
279 \r
280         return 0;\r
281 }\r
282 \r
283 /*\r
284  * if you compile this file with\r
285  *   gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c\r
286  * you will get a normal warning:\r
287  *   printf.c:214: warning: spurious trailing `%' in format\r
288  * this line is testing an invalid % at the end of the format string.\r
289  *\r
290  * this should display (on 32bit int machine) :\r
291  *\r
292  * Hello world!\r
293  * printf test\r
294  * (null) is null pointer\r
295  * 5 = 5\r
296  * -2147483647 = - max int\r
297  * char a = 'a'\r
298  * hex ff = ff\r
299  * hex 00 = 00\r
300  * signed -3 = unsigned 4294967293 = hex fffffffd\r
301  * 0 message(s)\r
302  * 0 message(s) with %\r
303  * justif: "left      "\r
304  * justif: "     right"\r
305  *  3: 0003 zero padded\r
306  *  3: 3    left justif.\r
307  *  3:    3 right justif.\r
308  * -3: -003 zero padded\r
309  * -3: -3   left justif.\r
310  * -3:   -3 right justif.\r
311  */\r
312 \r
313 #endif\r