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