1 /*============================================================================
2 * Base user-definable printf() wrapper or replacement.
3 *============================================================================*/
4
5 /*
6 This file is part of Code_Saturne, a general-purpose CFD tool.
7
8 Copyright (C) 1998-2021 EDF S.A.
9
10 This program is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free Software
12 Foundation; either version 2 of the License, or (at your option) any later
13 version.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
18 details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22 Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24
25 /*----------------------------------------------------------------------------*/
26
27 #include "cs_defs.h"
28
29 /*-----------------------------------------------------------------------------*/
30
31 /*
32 * Standard C library headers
33 */
34
35 #include <assert.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 /*
42 * Optional library and BFT headers
43 */
44
45 #include "bft_printf.h"
46
47 /*-----------------------------------------------------------------------------*/
48
49 BEGIN_C_DECLS
50
51 /*-----------------------------------------------------------------------------*/
52
53 /*-----------------------------------------------------------------------------
54 * Additional Doxygen documentation
55 *-----------------------------------------------------------------------------*/
56
57 /* Associated typedef documentation (for bft_printf.h) */
58
59 /*!
60 * \typedef bft_printf_proxy_t
61 *
62 * \brief Function pointer for printf() type functions.
63 *
64 * \param [in] format format string, as printf() and family.
65 * \param [in, out] arg_ptr pointer to variable argument list based on format
66 * string.
67 */
68
69 /*!
70 * \typedef bft_printf_flush_proxy_t
71 *
72 * \brief Function pointer for fflush(stdout) type functions.
73 */
74
75 /*! \cond DOXYGEN_SHOULD_SKIP_THIS */
76
77 /*-----------------------------------------------------------------------------
78 * Local type definitions
79 *-----------------------------------------------------------------------------*/
80
81 /*-----------------------------------------------------------------------------
82 * Local function prototypes
83 *-----------------------------------------------------------------------------*/
84
85 /*
86 * Default bft_printf_flush() proxy.
87 *
88 * returns:
89 * return code of fflush(stdout).
90 */
91
92 static int
93 _bft_printf_flush_proxy_default(void);
94
95 /*-----------------------------------------------------------------------------
96 * Local static variable definitions
97 *-----------------------------------------------------------------------------*/
98
99 static bft_printf_proxy_t *_bft_printf_proxy = vprintf;
100 static bft_printf_flush_proxy_t *_bft_printf_flush_proxy
101 = _bft_printf_flush_proxy_default;
102
103 /*-----------------------------------------------------------------------------
104 * Local function definitions
105 *-----------------------------------------------------------------------------*/
106
107 /*
108 * Default bft_printf_flush() proxy.
109 *
110 * returns:
111 * return code of fflush(stdout).
112 */
113
114 static int
_bft_printf_flush_proxy_default(void)115 _bft_printf_flush_proxy_default(void)
116 {
117 return fflush(stdout);
118 }
119
120 /*! (DOXYGEN_SHOULD_SKIP_THIS) \endcond */
121
122 /*============================================================================
123 * Public function definitions
124 *============================================================================*/
125
126 /*!
127 * \brief Replacement for printf() with modifiable behavior.
128 *
129 * This function calls vprintf() by default, or a function with similar
130 * arguments indicated by bft_printf_proxy_set().
131 *
132 * \param [in] format format string, as printf() and family.
133 * \param [in] ... variable arguments based on format string.
134 *
135 * \return number of characters printed, not counting the trailing '\\0'
136 * used to end output strings
137 */
138
139 int
bft_printf(const char * const format,...)140 bft_printf(const char *const format,
141 ...)
142 {
143 int retval;
144 va_list arg_ptr;
145
146 va_start(arg_ptr, format);
147
148 retval = _bft_printf_proxy(format, arg_ptr);
149
150 va_end(arg_ptr);
151
152 return retval;
153 }
154
155 /*!
156 * \brief Flush for output of bft_printf() with modifiable behavior.
157 *
158 * This function calls fflush(stdout) if bft_printf()'s default behavior is
159 * used. If bft_printf's behavior is modified with bft_printf_proxy_set(),
160 * bft_printf_flush()'s behavior may have to be also adjusted with
161 * bft_printf_flush_proxy_set().
162 *
163 * \return using the default behavior, the return value is that of
164 * fflush(stdout): O upon successful completion, EOF otherwise
165 * (with errno set to indicate the error).
166 */
167
168 int
bft_printf_flush(void)169 bft_printf_flush(void)
170 {
171 return _bft_printf_flush_proxy();
172 }
173
174 /*!
175 * \brief Returns function associated with the bft_printf() function.
176 *
177 * \return pointer to the vprintf() or replacement function.
178 */
179
180 bft_printf_proxy_t *
bft_printf_proxy_get(void)181 bft_printf_proxy_get(void)
182 {
183 return _bft_printf_proxy;
184 }
185
186 /*!
187 * \brief Associates a vprintf() type function with the bft_printf() function.
188 *
189 * \param [in] fct pointer to a vprintf() type function.
190 */
191
192 void
bft_printf_proxy_set(bft_printf_proxy_t * const fct)193 bft_printf_proxy_set(bft_printf_proxy_t *const fct)
194 {
195 _bft_printf_proxy = fct;
196 }
197
198 /*!
199 * \brief Returns function associated with bft_printf_flush().
200 *
201 * \return pointer to the bft_printf_flush() proxy.
202 */
203
204 bft_printf_flush_proxy_t *
bft_printf_flush_proxy_get(void)205 bft_printf_flush_proxy_get(void)
206 {
207 return _bft_printf_flush_proxy;
208 }
209
210 /*!
211 * \brief Associates a proxy function with bft_printf_flush().
212 *
213 * \warning
214 * bft_printf() is called by the default bft_error() error handler
215 * (so as to ensure that the error text appears at the end of the
216 * program output), so a bft_print_flush replacement must not itself
217 * call (directly or indirectly) bft_error() if the default error
218 * handler is used.
219 *
220 * \param [in] fct pointer to a function similar to {return fflush(stdout)}.
221 */
222
223 void
bft_printf_flush_proxy_set(bft_printf_flush_proxy_t * const fct)224 bft_printf_flush_proxy_set(bft_printf_flush_proxy_t *const fct)
225 {
226 _bft_printf_flush_proxy = fct;
227 }
228
229 /*-----------------------------------------------------------------------------*/
230
231 END_C_DECLS
232