1 /*This file has been prepared for Doxygen automatic documentation generation.*/
\r
2 /*! \file *********************************************************************
\r
4 * \brief sprintf functions to replace newlib for AVR32 UC3.
\r
6 * - Compiler: IAR EWAVR32 and GNU GCC for AVR32
\r
7 * - Supported devices: All AVR32 devices can be used.
\r
10 * \author Atmel Corporation: http://www.atmel.com \n
\r
11 * Support and FAQ: http://support.atmel.no/
\r
13 *****************************************************************************/
\r
15 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
\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
20 * 1. Redistributions of source code must retain the above copyright notice,
\r
21 * this list of conditions and the following disclaimer.
\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
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
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
43 Copyright 2001, 2002 Georges Menie (www.menie.org)
\r
44 stdarg version contributed by Christian Ettinger
\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
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
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
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
67 #define putchar(c) outbyte(c)
\r
70 #include <sys/reent.h>
\r
74 static void printchar(char **str, int c)
\r
76 extern int putchar(int c);
\r
82 else (void)putchar(c);
\r
88 static int prints(char **out, const char *string, int width, int pad)
\r
90 register int pc = 0, padchar = ' ';
\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
98 if (pad & PAD_ZERO) padchar = '0';
\r
100 if (!(pad & PAD_RIGHT)) {
\r
101 for ( ; width > 0; --width) {
\r
102 printchar (out, padchar);
\r
106 for ( ; *string ; ++string) {
\r
107 printchar (out, *string);
\r
110 for ( ; width > 0; --width) {
\r
111 printchar (out, padchar);
\r
118 /* the following should be enough for 32 bit int */
\r
119 #define PRINT_BUF_LEN 12
\r
121 static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
\r
123 char print_buf[PRINT_BUF_LEN];
\r
125 register int t, neg = 0, pc = 0;
\r
126 register unsigned int u = i;
\r
129 print_buf[0] = '0';
\r
130 print_buf[1] = '\0';
\r
131 return prints (out, print_buf, width, pad);
\r
134 if (sg && b == 10 && i < 0) {
\r
139 s = print_buf + PRINT_BUF_LEN-1;
\r
145 t += letbase - '0' - 10;
\r
151 if( width && (pad & PAD_ZERO) ) {
\r
152 printchar (out, '-');
\r
161 return pc + prints (out, s, width, pad);
\r
164 int fprintf(__FILE *stream, const char *format, ...)
\r
168 static int print(char **out, const char *format, va_list args )
\r
170 register int width, pad;
\r
171 register int pc = 0;
\r
174 for (; *format != 0; ++format) {
\r
175 if (*format == '%') {
\r
178 if (*format == '\0') break;
\r
179 if (*format == '%') goto out;
\r
180 if (*format == '-') {
\r
184 while (*format == '0') {
\r
188 for ( ; *format >= '0' && *format <= '9'; ++format) {
\r
190 width += *format - '0';
\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
197 if( *format == 'd' ) {
\r
198 pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');
\r
201 if( *format == 'x' ) {
\r
202 pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a');
\r
205 if( *format == 'X' ) {
\r
206 pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A');
\r
209 if( *format == 'u' ) {
\r
210 pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');
\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
217 pc += prints (out, scr, width, pad);
\r
223 printchar (out, *format);
\r
227 if (out) **out = '\0';
\r
232 int printk(const char *format, ...)
\r
236 va_start( args, format );
\r
237 return print( 0, format, args );
\r
240 int sprintf(char *out, const char *format, ...)
\r
244 va_start( args, format );
\r
245 return print( &out, format, args );
\r
251 char *ptr = "Hello world!";
\r
254 unsigned int bs = sizeof(int)*8;
\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
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
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
290 * this should display (on 32bit int machine) :
\r
294 * (null) is null pointer
\r
296 * -2147483647 = - max int
\r
300 * signed -3 = unsigned 4294967293 = hex fffffffd
\r
302 * 0 message(s) with %
\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