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