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