Remove obsolete INITLIST macro.
[bertos.git] / mware / sprintf.c
1 /*!
2  * \file
3  * <!--
4  * Copyright (C) 2002,2004 Develer S.r.l. (http://www.develer.com/)
5  * This file is part of DevLib - See devlib/README for information.
6  * -->
7  *
8  * \brief sprintf() implementation based on _formatted_write()
9  *
10  * \version $Id$
11  * \author Bernardo Innocenti <bernie@develer.com>
12  */
13
14 /*#*
15  *#* $Log$
16  *#* Revision 1.6  2004/11/16 21:15:19  bernie
17  *#* Fix off-by-one bug in [v]snprintf().
18  *#*
19  *#* Revision 1.5  2004/10/03 18:54:36  bernie
20  *#* sprintf(): Fix a serious bug; snprintf(): New function.
21  *#*
22  *#* Revision 1.4  2004/08/25 14:12:09  rasky
23  *#* Aggiornato il comment block dei log RCS
24  *#*
25  *#* Revision 1.3  2004/06/27 15:20:26  aleph
26  *#* Change UNUSED() macro to accept two arguments: type and name;
27  *#* Add macro GNUC_PREREQ to detect GCC version during build;
28  *#* Some spacing cleanups and typo fix
29  *#*
30  *#* Revision 1.2  2004/06/03 11:27:09  bernie
31  *#* Add dual-license information.
32  *#*
33  *#* Revision 1.1  2004/05/23 15:43:16  bernie
34  *#* Import mware modules.
35  *#*
36  *#* Revision 1.4  2004/04/03 20:42:27  aleph
37  *#* Remove duplicated defines
38  *#*
39  *#* Revision 1.3  2004/03/24 15:48:53  bernie
40  *#* Remove Copyright messages from Doxygen output
41  *#*
42  *#* Revision 1.2  2004/03/19 16:51:30  bernie
43  *#* Add PROGMEM kludge.
44  *#*
45  *#* Revision 1.1  2004/02/23 09:45:09  aleph
46  *#* Add missing library functions.
47  *#*
48  *#* Revision 1.1  2003/11/13 16:56:37  aleph
49  *#* Add first implementation of dsp firmware
50  *#*
51  *#*/
52
53 #include "compiler.h"
54 #include "formatwr.h"
55 #include <stdio.h>
56
57
58 static void __str_put_char(char c, void *ptr)
59 {
60         /*
61          * This Does not work on Code Warrior. Hmm...
62          *      *(*((char **)ptr))++ = c;
63          */
64
65         **((char **)ptr) = c;
66         (*((char **)ptr))++;
67 }
68
69 static void __null_put_char(UNUSED(char, c), UNUSED(void *, ptr))
70 {
71         /* nop */
72 }
73
74
75 int PGM_FUNC(vsprintf)(char * str, const char * PGM_ATTR fmt, va_list ap)
76 {
77         int result;
78
79         result = PGM_FUNC(_formatted_write)(
80                         fmt, (str ? __str_put_char : __null_put_char), &str, ap);
81
82         /* Terminate string */
83         *str = '\0';
84
85         return result;
86 }
87
88
89 int PGM_FUNC(sprintf)(char *str, const char * fmt, ...)
90 {
91         int result;
92         va_list ap;
93
94         va_start(ap, fmt);
95         result = PGM_FUNC(vsprintf)(str, fmt, ap);
96         va_end(ap);
97
98         return result;
99 }
100
101 /*!
102  * State information for __sn_put_char()
103  */
104 struct __sn_state
105 {
106         char *str;
107         size_t len;
108 };
109
110 /*!
111  * formatted_write() callback used [v]snprintf().
112  */
113 static void __sn_put_char(char c, void *ptr)
114 {
115         struct __sn_state *state = (struct __sn_state *)ptr;
116
117         if (state->len)
118         {
119                 --state->len;
120                 *state->str++ = c;
121         }
122 }
123
124
125 int PGM_FUNC(vsnprintf)(char *str, size_t size, const char * PGM_ATTR fmt, va_list ap)
126 {
127         int result = 0;
128
129         /* Make room for traling '\0'. */
130         if (size--)
131         {
132                 struct __sn_state state;
133                 state.str = str;
134                 state.len = size;
135
136                 result = PGM_FUNC(_formatted_write)(
137                         fmt, (str ? __sn_put_char : __null_put_char), &state, ap);
138
139                 /* Terminate string. */
140                 *state.str = '\0';
141         }
142
143         return result;
144 }
145
146
147 int PGM_FUNC(snprintf)(char *str, size_t size, const char * fmt, ...)
148 {
149         int result;
150         va_list ap;
151
152         va_start(ap, fmt);
153         result = PGM_FUNC(vsnprintf)(str, size, fmt, ap);
154         va_end(ap);
155
156         return result;
157 }