1 /* This source file is part of the ATMEL FREERTOS-0.9.0 Release */
\r
3 /*This file has been prepared for Doxygen automatic documentation generation.*/
\r
4 /*! \file *********************************************************************
\r
6 * \brief sprintf functions to replace newlib for AVR32 UC3.
\r
8 * - Compiler: IAR EWAVR32 and GNU GCC for AVR32
\r
9 * - Supported devices: All AVR32 devices can be used.
\r
12 * \author Atmel Corporation: http://www.atmel.com \n
\r
13 * Support email: avr32@atmel.com
\r
15 *****************************************************************************/
\r
17 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
\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
22 * 1. Redistributions of source code must retain the above copyright notice,
\r
23 * this list of conditions and the following disclaimer.
\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
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
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
45 Copyright 2001, 2002 Georges Menie (www.menie.org)
\r
46 stdarg version contributed by Christian Ettinger
\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
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
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
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
69 #define putchar(c) outbyte(c)
\r
72 #include <sys/reent.h>
\r
76 static void printchar(char **str, int c)
\r
78 extern int putchar(int c);
\r
84 else (void)putchar(c);
\r
90 static int prints(char **out, const char *string, int width, int pad)
\r
92 register int pc = 0, padchar = ' ';
\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
100 if (pad & PAD_ZERO) padchar = '0';
\r
102 if (!(pad & PAD_RIGHT)) {
\r
103 for ( ; width > 0; --width) {
\r
104 printchar (out, padchar);
\r
108 for ( ; *string ; ++string) {
\r
109 printchar (out, *string);
\r
112 for ( ; width > 0; --width) {
\r
113 printchar (out, padchar);
\r
120 /* the following should be enough for 32 bit int */
\r
121 #define PRINT_BUF_LEN 12
\r
123 static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
\r
125 char print_buf[PRINT_BUF_LEN];
\r
127 register int t, neg = 0, pc = 0;
\r
128 register unsigned int u = i;
\r
131 print_buf[0] = '0';
\r
132 print_buf[1] = '\0';
\r
133 return prints (out, print_buf, width, pad);
\r
136 if (sg && b == 10 && i < 0) {
\r
141 s = print_buf + PRINT_BUF_LEN-1;
\r
147 t += letbase - '0' - 10;
\r
153 if( width && (pad & PAD_ZERO) ) {
\r
154 printchar (out, '-');
\r
163 return pc + prints (out, s, width, pad);
\r
166 int fprintf(__FILE *stream, const char *format, ...)
\r
170 static int print(char **out, const char *format, va_list args )
\r
172 register int width, pad;
\r
173 register int pc = 0;
\r
176 for (; *format != 0; ++format) {
\r
177 if (*format == '%') {
\r
180 if (*format == '\0') break;
\r
181 if (*format == '%') goto out;
\r
182 if (*format == '-') {
\r
186 while (*format == '0') {
\r
190 for ( ; *format >= '0' && *format <= '9'; ++format) {
\r
192 width += *format - '0';
\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
199 if( *format == 'd' ) {
\r
200 pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');
\r
203 if( *format == 'x' ) {
\r
204 pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a');
\r
207 if( *format == 'X' ) {
\r
208 pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A');
\r
211 if( *format == 'u' ) {
\r
212 pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');
\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
219 pc += prints (out, scr, width, pad);
\r
225 printchar (out, *format);
\r
229 if (out) **out = '\0';
\r
234 int printk(const char *format, ...)
\r
238 va_start( args, format );
\r
239 return print( 0, format, args );
\r
242 int sprintf(char *out, const char *format, ...)
\r
246 va_start( args, format );
\r
247 return print( &out, format, args );
\r
253 char *ptr = "Hello world!";
\r
256 unsigned int bs = sizeof(int)*8;
\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
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
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
292 * this should display (on 32bit int machine) :
\r
296 * (null) is null pointer
\r
298 * -2147483647 = - max int
\r
302 * signed -3 = unsigned 4294967293 = hex fffffffd
\r
304 * 0 message(s) with %
\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