1 /* -*- mode: C -*-  */
2 /*
3    IGraph library.
4    Copyright (C) 2010-2012  Gabor Csardi <csardi.gabor@gmail.com>
5    334 Harvard street, Cambridge, MA 02139 USA
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20    02110-1301 USA
21 
22 */
23 
24 #include "igraph_types.h"
25 #include "igraph_statusbar.h"
26 #include "igraph_error.h"
27 #include "config.h"
28 #include <stdio.h>
29 #include <stdarg.h>
30 
31 static IGRAPH_THREAD_LOCAL igraph_status_handler_t *igraph_i_status_handler = 0;
32 
33 /**
34  * \function igraph_status
35  * Report status from an igraph function.
36  *
37  * It calls the installed status handler function, if there is
38  * one. Otherwise it does nothing. Note that the standard way to
39  * report the status from an igraph function is the
40  * \ref IGRAPH_STATUS or \ref IGRAPH_STATUSF macro, as these
41  * take care of the termination of the calling function if the
42  * status handler returns with \c IGRAPH_INTERRUPTED.
43  * \param message The status message.
44  * \param data Additional context, with user-defined semantics.
45  *        Existing igraph functions pass a null pointer here.
46  * \return Error code. If a status handler function was called
47  *        and it did not return with \c IGRAPH_SUCCESS, then
48  *        \c IGRAPH_INTERRUPTED is returned by \c igraph_status().
49  *
50  * Time complexity: O(1).
51  */
52 
igraph_status(const char * message,void * data)53 int igraph_status(const char *message, void *data) {
54     if (igraph_i_status_handler) {
55         if (igraph_i_status_handler(message, data) != IGRAPH_SUCCESS) {
56             return IGRAPH_INTERRUPTED;
57         }
58     }
59     return IGRAPH_SUCCESS;
60 }
61 
62 /**
63  * \function igraph_statusf
64  * Report status, more flexible printf-like version.
65  *
66  * This is the more flexible version of \ref igraph_status(),
67  * that has a syntax similar to the \c printf standard C library function.
68  * It substitutes the values of the additional arguments into the
69  * \p message template string and calls \ref igraph_status().
70  * \param message Status message template string, the syntax is the same
71  *        as for the \c printf function.
72  * \param data Additional context, with user-defined semantics.
73  *        Existing igraph functions pass a null pointer here.
74  * \param ... The additional arguments to fill the template given in the
75  *        \p message argument.
76  * \return Error code. If a status handler function was called
77  *        and it did not return with \c IGRAPH_SUCCESS, then
78  *        \c IGRAPH_INTERRUPTED is returned by \c igraph_status().
79  */
80 
igraph_statusf(const char * message,void * data,...)81 int igraph_statusf(const char *message, void *data, ...) {
82     char buffer[300];
83     va_list ap;
84     va_start(ap, data);
85     vsnprintf(buffer, sizeof(buffer) - 1, message, ap);
86     return igraph_status(buffer, data);
87 }
88 
89 #ifndef USING_R
90 
91 /**
92  * \function igraph_status_handler_stderr
93  * A simple predefined status handler function.
94  *
95  * A simple status handler function, that writes the status
96  * message to the standard errror.
97  * \param message The status message.
98  * \param data Additional context, with user-defined semantics.
99  *        Existing igraph functions pass a null pointer here.
100  * \return Error code.
101  *
102  * Time complexity: O(1).
103  */
104 
igraph_status_handler_stderr(const char * message,void * data)105 int igraph_status_handler_stderr(const char *message, void *data) {
106     IGRAPH_UNUSED(data);
107     fputs(message, stderr);
108     return 0;
109 }
110 #endif
111 
112 /**
113  * \function igraph_set_status_handler
114  * Install of uninstall a status handler function.
115  *
116  * To uninstall the currently installed status handler, call
117  * this function with a null pointer.
118  * \param new_handler The status handler function to install.
119  * \return The previously installed status handler function.
120  *
121  * Time complexity: O(1).
122  */
123 
124 igraph_status_handler_t *
igraph_set_status_handler(igraph_status_handler_t new_handler)125 igraph_set_status_handler(igraph_status_handler_t new_handler) {
126     igraph_status_handler_t *previous_handler = igraph_i_status_handler;
127     igraph_i_status_handler = new_handler;
128     return previous_handler;
129 }
130 
131