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