1 /* ----------------------------------------------------------------------------
2 @COPYRIGHT :
3 Copyright 1993,1994,1995 David MacDonald,
4 McConnell Brain Imaging Centre,
5 Montreal Neurological Institute, McGill University.
6 Permission to use, copy, modify, and distribute this
7 software and its documentation for any purpose and without
8 fee is hereby granted, provided that the above copyright
9 notice appear in all copies. The author and McGill University
10 make no representations about the suitability of this
11 software for any purpose. It is provided "as is" without
12 express or implied warranty.
13 ---------------------------------------------------------------------------- */
14 #ifdef HAVE_CONFIG_H
15 #include "config.h"
16 #endif /*HAVE_CONFIG_H*/
17
18 #include "minc_error.h"
19
20 #include <internal_volume_io.h>
21 #include <stdarg.h>
22
23 #define MAX_PRINT_STACK 100
24
25 typedef void (*print_function_type) ( VIO_STR );
26
27 static print_function_type print_function[MAX_PRINT_STACK] = { NULL };
28 static int top_of_stack = 0;
29
30 static print_function_type print_error_function[MAX_PRINT_STACK] = { NULL };
31 static int top_of_error_stack = 0;
32
33 /* ----------------------------- MNI Header -----------------------------------
34 @NAME : set_print_function
35 @INPUT : function
36 @OUTPUT :
37 @RETURNS :
38 @DESCRIPTION: Sets the output function. If you use the function print()
39 everywhere, in place of printf, then by default it uses
40 printf to send output to stdout. However, you can call
41 the set_print_function() to tell it to use a different output
42 function, e.g. output to a GL or X window.
43 @METHOD :
44 @GLOBALS :
45 @CALLS :
46 @CREATED : 1993 David MacDonald
47 @MODIFIED :
48 ---------------------------------------------------------------------------- */
49
set_print_function(void (* function)(VIO_STR))50 VIOAPI void set_print_function( void (*function) ( VIO_STR ) )
51 {
52 print_function[top_of_stack] = function;
53 }
54
55 /* ----------------------------- MNI Header -----------------------------------
56 @NAME : push_print_function
57 @INPUT :
58 @OUTPUT :
59 @RETURNS :
60 @DESCRIPTION: Save the current print function, so, for instance, you can
61 print to stdout temporarily.
62 @METHOD :
63 @GLOBALS :
64 @CALLS :
65 @CREATED : 1993 David MacDonald
66 @MODIFIED :
67 ---------------------------------------------------------------------------- */
68
push_print_function(void)69 VIOAPI void push_print_function( void )
70 {
71 if( top_of_stack < MAX_PRINT_STACK - 1 )
72 {
73 ++top_of_stack;
74 print_function[top_of_stack] = NULL;
75 }
76 else
77 handle_internal_error( "Stack overflow in push_print_function" );
78 }
79
80 /* ----------------------------- MNI Header -----------------------------------
81 @NAME : pop_print_function
82 @INPUT :
83 @OUTPUT :
84 @RETURNS :
85 @DESCRIPTION: Restore the print function.
86 @METHOD :
87 @GLOBALS :
88 @CALLS :
89 @CREATED : 1993 David MacDonald
90 @MODIFIED :
91 ---------------------------------------------------------------------------- */
92
pop_print_function(void)93 VIOAPI void pop_print_function( void )
94 {
95 if( top_of_stack > 0 )
96 --top_of_stack;
97 else
98 handle_internal_error( "Stack underflow in pop_print_function" );
99 }
100
101 /* ----------------------------- MNI Header -----------------------------------
102 @NAME : print
103 @INPUT : exactly same arguments as printf
104 @OUTPUT :
105 @RETURNS :
106 @DESCRIPTION: prints the arguments to a temporary string buffer, then either
107 printf's the or calls the user installed function to output
108 the string.
109 @METHOD :
110 @GLOBALS :
111 @CALLS :
112 @CREATED : 1993 David MacDonald
113 @MODIFIED :
114 ---------------------------------------------------------------------------- */
115
116 /* VARARGS */
print(VIO_STR format,...)117 VIOAPI void print( VIO_STR format, ... )
118 {
119 va_list ap;
120 char print_buffer[VIO_EXTREMELY_LARGE_STRING_SIZE];
121
122 va_start( ap, format );
123 (void) vsprintf( print_buffer, format, ap );
124 va_end( ap );
125
126 if( print_function[top_of_stack] == NULL )
127 (void) printf( "%s", print_buffer );
128 else
129 (*(print_function[top_of_stack])) ( print_buffer );
130 }
131
132 /* ----------------------------- MNI Header -----------------------------------
133 @NAME : set_print_error_function
134 @INPUT : function
135 @OUTPUT :
136 @RETURNS :
137 @DESCRIPTION: Sets the output function. If you use the function print_error()
138 everywhere, in place of printf, then by default it uses
139 printf to send output to stderr. However, you can call
140 the set_print_error_function() to tell it to use a different
141 output function, e.g. output to a GL or X window.
142 @METHOD :
143 @GLOBALS :
144 @CALLS :
145 @CREATED : 1993 David MacDonald
146 @MODIFIED :
147 ---------------------------------------------------------------------------- */
148
set_print_error_function(void (* function)(char[]))149 VIOAPI void set_print_error_function( void (*function) ( char [] ) )
150 {
151 print_error_function[top_of_error_stack] = function;
152 }
153
154 /* ----------------------------- MNI Header -----------------------------------
155 @NAME : push_print_error_function
156 @INPUT :
157 @OUTPUT :
158 @RETURNS :
159 @DESCRIPTION: Save the current print error function, so, for instance, you can
160 print to stdout temporarily.
161 @METHOD :
162 @GLOBALS :
163 @CALLS :
164 @CREATED : 1993 David MacDonald
165 @MODIFIED :
166 ---------------------------------------------------------------------------- */
167
push_print_error_function(void)168 VIOAPI void push_print_error_function( void )
169 {
170 if( top_of_error_stack < MAX_PRINT_STACK - 1 )
171 {
172 ++top_of_error_stack;
173 print_error_function[top_of_error_stack] = NULL;
174 }
175 else
176 handle_internal_error( "Stack overflow in push_print_error_function" );
177 }
178
179 /* ----------------------------- MNI Header -----------------------------------
180 @NAME : pop_print_error_function
181 @INPUT :
182 @OUTPUT :
183 @RETURNS :
184 @DESCRIPTION: Restore the print_error function.
185 @METHOD :
186 @GLOBALS :
187 @CALLS :
188 @CREATED : 1993 David MacDonald
189 @MODIFIED :
190 ---------------------------------------------------------------------------- */
191
pop_print_error_function(void)192 VIOAPI void pop_print_error_function( void )
193 {
194 if( top_of_error_stack > 0 )
195 --top_of_error_stack;
196 else
197 handle_internal_error( "Stack underflow in pop_print_error_function" );
198 }
199
200 /* ----------------------------- MNI Header -----------------------------------
201 @NAME : print_error
202 @INPUT : exactly same arguments as printf
203 @OUTPUT :
204 @RETURNS :
205 @DESCRIPTION: prints the arguments to a temporary string buffer, then either
206 fprintf's to stderr or calls the user installed function to
207 output the string.
208 @METHOD :
209 @GLOBALS :
210 @CALLS :
211 @CREATED : 1993 David MacDonald
212 @MODIFIED :
213 ---------------------------------------------------------------------------- */
214
215 /* VARARGS */
print_error(char format[],...)216 VIOAPI void print_error( char format[], ... )
217 {
218 va_list ap;
219 char print_buffer[VIO_EXTREMELY_LARGE_STRING_SIZE];
220
221 va_start( ap, format );
222 vsprintf( print_buffer, format, ap );
223 va_end( ap );
224
225 if( print_error_function[top_of_error_stack] == NULL )
226 MI_LOG_ERROR(MI_MSG_VOLUME_IO, print_buffer);
227 else
228 (*(print_error_function[top_of_error_stack])) ( print_buffer );
229 }
230
231 /* ----------------------------- MNI Header -----------------------------------
232 @NAME : handle_internal_error
233 @INPUT : str
234 @OUTPUT :
235 @RETURNS :
236 @DESCRIPTION: Prints the error string and tries to get users permission to
237 abort.
238 @METHOD :
239 @GLOBALS :
240 @CALLS :
241 @CREATED : 1993 David MacDonald
242 @MODIFIED :
243 ---------------------------------------------------------------------------- */
244
handle_internal_error(char str[])245 VIOAPI void handle_internal_error( char str[] )
246 {
247 /*print_error( "Internal error: %s\n", str );
248 abort_if_allowed();*/
249 MI_LOG_ERROR(MI_MSG_VOLUME_IO,"Internal error: %s", str);
250 }
251
252 /* ----------------------------- MNI Header -----------------------------------
253 @NAME : abort_if_allowed
254 @INPUT :
255 @OUTPUT :
256 @RETURNS :
257 @DESCRIPTION: Checks if the user wants to abort.
258 @METHOD :
259 @GLOBALS :
260 @CALLS :
261 @CREATED : David MacDonald
262 @MODIFIED :
263 ---------------------------------------------------------------------------- */
264
abort_if_allowed(void)265 VIOAPI void abort_if_allowed( void )
266 {
267 char ch;
268
269 if( VIO_ENV_EXISTS( "ABORT_FLAG" ) )
270 {
271 print_error( "Do you wish to abort (y/n): " );
272 do
273 {
274 ch = (char) getchar();
275 }
276 while( ch != 'y' && ch != 'n' );
277
278 while( getchar() != '\n' )
279 {
280 }
281
282 if( ch == 'y' )
283 {
284 abort();
285 }
286 }
287 }
288