Remove files added only for Wizard module discovery.
[bertos.git] / bertos / mware / sprintf.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2002, 2004, 2005 Develer S.r.l. (http://www.develer.com/)
30  *
31  * -->
32  *
33  * \brief sprintf() implementation based on _formatted_write()
34  *
35  * \version $Id$
36  * \author Bernie Innocenti <bernie@codewiz.org>
37  *
38  * $WIZ$ module_name = "sprintf"
39  * $WIZ$ module_depends = "formatwr"
40  * $WIZ$ module_harvard = "both"
41  */
42
43 #include <mware/formatwr.h>
44 #include <cpu/pgm.h>
45 #include <cfg/compiler.h>
46
47 #include <stdio.h>
48
49
50 static void __str_put_char(char c, void *ptr)
51 {
52         /*
53          * This Does not work on Code Warrior. Hmm...
54          *      *(*((char **)ptr))++ = c;
55          */
56
57         **((char **)ptr) = c;
58         (*((char **)ptr))++;
59 }
60
61 static void __null_put_char(UNUSED_ARG(char, c), UNUSED_ARG(void *, ptr))
62 {
63         /* nop */
64 }
65
66
67 int PGM_FUNC(vsprintf)(char *str, const char * PGM_ATTR fmt, va_list ap)
68 {
69         int result;
70
71         if (str)
72         {
73                 result = PGM_FUNC(_formatted_write)(fmt, __str_put_char, &str, ap);
74
75                 /* Terminate string */
76                 *str = '\0';
77         }
78         else
79                 result = PGM_FUNC(_formatted_write)(fmt, __null_put_char, 0, ap);
80
81
82         return result;
83 }
84
85
86 int PGM_FUNC(sprintf)(char *str, const char * fmt, ...)
87 {
88         int result;
89         va_list ap;
90
91         va_start(ap, fmt);
92         result = PGM_FUNC(vsprintf)(str, fmt, ap);
93         va_end(ap);
94
95         return result;
96 }
97
98 /**
99  * State information for __sn_put_char()
100  */
101 struct __sn_state
102 {
103         char *str;
104         size_t len;
105 };
106
107 /**
108  * formatted_write() callback used [v]snprintf().
109  */
110 static void __sn_put_char(char c, void *ptr)
111 {
112         struct __sn_state *state = (struct __sn_state *)ptr;
113
114         if (state->len)
115         {
116                 --state->len;
117                 *state->str++ = c;
118         }
119 }
120
121
122 int PGM_FUNC(vsnprintf)(char *str, size_t size, const char * PGM_ATTR fmt, va_list ap)
123 {
124         int result = 0;
125
126         /* Make room for traling '\0'. */
127         if (size--)
128         {
129                 if (str)
130                 {
131                         struct __sn_state state;
132                         state.str = str;
133                         state.len = size;
134
135                         result = PGM_FUNC(_formatted_write)(fmt, __sn_put_char, &state, ap);
136
137                         /* Terminate string. */
138                         *state.str = '\0';
139                 }
140                 else
141                         result = PGM_FUNC(_formatted_write)(fmt, __null_put_char, 0, ap);
142         }
143
144         return result;
145 }
146
147
148 int PGM_FUNC(snprintf)(char *str, size_t size, const char * fmt, ...)
149 {
150         int result;
151         va_list ap;
152
153         va_start(ap, fmt);
154         result = PGM_FUNC(vsnprintf)(str, size, fmt, ap);
155         va_end(ap);
156
157         return result;
158 }