xref: /petsc/include/petscerror.h (revision db268bfa9c46c24c134d4e2e1d78f27d60e1123e)
1 /*
2     Contains all error handling interfaces for PETSc.
3 */
4 #if !defined(__PETSCERROR_H)
5 #define __PETSCERROR_H
6 #include "petsc.h"
7 PETSC_EXTERN_CXX_BEGIN
8 
9 /*
10    Defines the directory where the compiled source is located; used
11    in printing error messages. Each makefile has an entry
12    LOCDIR	  =  thedirectory
13    and bmake/common_variables includes in CCPPFLAGS -D__SDIR__='"${LOCDIR}"'
14    which is a flag passed to the C/C++ compilers. This declaration below
15    is only needed if some code is compiled without the -D__SDIR__
16 */
17 #if !defined(__SDIR__)
18 #define __SDIR__ "unknowndirectory/"
19 #endif
20 
21 /*
22    Defines the function where the compiled source is located; used
23    in printing error messages. This is defined here in case the user
24    does not declare it.
25 */
26 #if !defined(__FUNCT__)
27 #define __FUNCT__ "User provided function"
28 #endif
29 
30 /*
31      These are the generic error codes. These error codes are used
32      many different places in the PETSc source code. The string versions are
33      at src/sys/error/err.c any changes here must also be made there
34      These are also define in include/finclude/petscerror.h any CHANGES here
35      must be also made there.
36 
37 */
38 #define PETSC_ERR_MIN_VALUE        54   /* should always be one less then the smallest value */
39 
40 #define PETSC_ERR_MEM              55   /* unable to allocate requested memory */
41 #define PETSC_ERR_SUP              56   /* no support for requested operation */
42 #define PETSC_ERR_SUP_SYS          57   /* no support for requested operation on this computer system */
43 #define PETSC_ERR_ORDER            58   /* operation done in wrong order */
44 #define PETSC_ERR_SIG              59   /* signal received */
45 #define PETSC_ERR_FP               72   /* floating point exception */
46 #define PETSC_ERR_COR              74   /* corrupted PETSc object */
47 #define PETSC_ERR_LIB              76   /* error in library called by PETSc */
48 #define PETSC_ERR_PLIB             77   /* PETSc library generated inconsistent data */
49 #define PETSC_ERR_MEMC             78   /* memory corruption */
50 #define PETSC_ERR_CONV_FAILED      82   /* iterative method (KSP or SNES) failed */
51 #define PETSC_ERR_USER             83   /* user has not provided needed function */
52 
53 #define PETSC_ERR_ARG_SIZ          60   /* nonconforming object sizes used in operation */
54 #define PETSC_ERR_ARG_IDN          61   /* two arguments not allowed to be the same */
55 #define PETSC_ERR_ARG_WRONG        62   /* wrong argument (but object probably ok) */
56 #define PETSC_ERR_ARG_CORRUPT      64   /* null or corrupted PETSc object as argument */
57 #define PETSC_ERR_ARG_OUTOFRANGE   63   /* input argument, out of range */
58 #define PETSC_ERR_ARG_BADPTR       68   /* invalid pointer argument */
59 #define PETSC_ERR_ARG_NOTSAMETYPE  69   /* two args must be same object type */
60 #define PETSC_ERR_ARG_NOTSAMECOMM  80   /* two args must be same communicators */
61 #define PETSC_ERR_ARG_WRONGSTATE   73   /* object in argument is in wrong state, e.g. unassembled mat */
62 #define PETSC_ERR_ARG_INCOMP       75   /* two arguments are incompatible */
63 #define PETSC_ERR_ARG_NULL         85   /* argument is null that should not be */
64 #define PETSC_ERR_ARG_UNKNOWN_TYPE 86   /* type name doesn't match any registered type */
65 #define PETSC_ERR_ARG_DOMAIN       87   /* argument is not in domain of function */
66 
67 #define PETSC_ERR_FILE_OPEN        65   /* unable to open file */
68 #define PETSC_ERR_FILE_READ        66   /* unable to read from file */
69 #define PETSC_ERR_FILE_WRITE       67   /* unable to write to file */
70 #define PETSC_ERR_FILE_UNEXPECTED  79   /* unexpected data in file */
71 
72 #define PETSC_ERR_MAT_LU_ZRPVT     71   /* detected a zero pivot during LU factorization */
73 #define PETSC_ERR_MAT_CH_ZRPVT     81   /* detected a zero pivot during Cholesky factorization */
74 
75 #define PETSC_ERR_MAX_VALUE        88   /* this is always the one more than the largest error code */
76 
77 #if defined(PETSC_USE_ERRORCHECKING)
78 
79 /*MC
80    SETERRQ - Macro that is called when an error has been detected,
81 
82    Not Collective
83 
84    Synopsis:
85    void SETERRQ(PetscErrorCode errorcode,char *message)
86 
87 
88    Input Parameters:
89 +  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
90 -  message - error message
91 
92   Level: beginner
93 
94    Notes:
95     Once the error handler is called the calling function is then returned from with the given error code.
96 
97     See SETERRQ1(), SETERRQ2(), SETERRQ3() for versions that take arguments
98 
99 
100    Experienced users can set the error handler with PetscPushErrorHandler().
101 
102    Concepts: error^setting condition
103 
104 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3()
105 M*/
106 #define SETERRQ(n,s)              {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s);}
107 
108 /*MC
109    SETERRQ1 - Macro that is called when an error has been detected,
110 
111    Not Collective
112 
113    Synopsis:
114    void SETERRQ1(PetscErrorCode errorcode,char *formatmessage,arg)
115 
116 
117    Input Parameters:
118 +  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
119 .  message - error message in the printf format
120 -  arg - argument (for example an integer, string or double)
121 
122   Level: beginner
123 
124    Notes:
125     Once the error handler is called the calling function is then returned from with the given error code.
126 
127    Experienced users can set the error handler with PetscPushErrorHandler().
128 
129    Concepts: error^setting condition
130 
131 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ(), SETERRQ2(), SETERRQ3()
132 M*/
133 #define SETERRQ1(n,s,a1)          {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1);}
134 
135 /*MC
136    SETERRQ2 - Macro that is called when an error has been detected,
137 
138    Not Collective
139 
140    Synopsis:
141    void SETERRQ2(PetscErrorCode errorcode,char *formatmessage,arg1,arg2)
142 
143 
144    Input Parameters:
145 +  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
146 .  message - error message in the printf format
147 .  arg1 - argument (for example an integer, string or double)
148 -  arg2 - argument (for example an integer, string or double)
149 
150   Level: beginner
151 
152    Notes:
153     Once the error handler is called the calling function is then returned from with the given error code.
154 
155    Experienced users can set the error handler with PetscPushErrorHandler().
156 
157    Concepts: error^setting condition
158 
159 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ3()
160 M*/
161 #define SETERRQ2(n,s,a1,a2)       {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2);}
162 
163 /*MC
164    SETERRQ3 - Macro that is called when an error has been detected,
165 
166    Not Collective
167 
168    Synopsis:
169    void SETERRQ3(PetscErrorCode errorcode,char *formatmessage,arg1,arg2,arg3)
170 
171 
172    Input Parameters:
173 +  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
174 .  message - error message in the printf format
175 .  arg1 - argument (for example an integer, string or double)
176 .  arg2 - argument (for example an integer, string or double)
177 -  arg3 - argument (for example an integer, string or double)
178 
179   Level: beginner
180 
181    Notes:
182     Once the error handler is called the calling function is then returned from with the given error code.
183 
184     There are also versions for 4, 5, 6 and 7 arguments.
185 
186    Experienced users can set the error handler with PetscPushErrorHandler().
187 
188    Concepts: error^setting condition
189 
190 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2()
191 M*/
192 #define SETERRQ3(n,s,a1,a2,a3)    {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3);}
193 
194 #define SETERRQ4(n,s,a1,a2,a3,a4) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4);}
195 #define SETERRQ5(n,s,a1,a2,a3,a4,a5)       {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4,a5);}
196 #define SETERRQ6(n,s,a1,a2,a3,a4,a5,a6)    {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4,a5,a6);}
197 #define SETERRQ7(n,s,a1,a2,a3,a4,a5,a6,a7) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s,a1,a2,a3,a4,a5,a6,a7);}
198 #define SETERRABORT(comm,n,s)     {PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,1,s);MPI_Abort(comm,n);}
199 
200 /*MC
201    CHKERRQ - Checks error code, if non-zero it calls the error handler and then returns
202 
203    Not Collective
204 
205    Synopsis:
206    void CHKERRQ(PetscErrorCode errorcode)
207 
208 
209    Input Parameters:
210 .  errorcode - nonzero error code, see the list of standard error codes in include/petscerror.h
211 
212   Level: beginner
213 
214    Notes:
215     Once the error handler is called the calling function is then returned from with the given error code.
216 
217     Experienced users can set the error handler with PetscPushErrorHandler().
218 
219     CHKERRQ(n) is fundamentally a macro replacement for
220          if (n) return(PetscError(...,n,...));
221 
222     Although typical usage resembles "void CHKERRQ(PetscErrorCode)" as described above, for certain uses it is
223     highly inappropriate to use it in this manner as it invokes return(PetscErrorCode). In particular,
224     it cannot be used in functions which return(void) or any other datatype.  In these types of functions,
225     a more appropriate construct for using PETSc Error Handling would be
226          if (n) {PetscError(....); return(YourReturnType);}
227 
228    Concepts: error^setting condition
229 
230 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ2()
231 M*/
232 #define CHKERRQ(n)             if (n) {return PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");}
233 
234 #define CHKERRABORT(comm,n)    if (n) {PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");MPI_Abort(comm,n);}
235 #define CHKERRCONTINUE(n)      if (n) {PetscError(__LINE__,__FUNCT__,__FILE__,__SDIR__,n,0," ");}
236 
237 #define CHKFPQ(f) if (f != f) {SETERRQ(PETSC_ERR_FP, "Invalid value: NaN");}
238 
239 /*MC
240    CHKMEMQ - Checks the memory for corruption, calls error handler if any is detected
241 
242    Not Collective
243 
244    Synopsis:
245    CHKMEMQ;
246 
247   Level: beginner
248 
249    Notes:
250     Must run with the option -malloc_debug to enable this option
251 
252     Once the error handler is called the calling function is then returned from with the given error code.
253 
254     By defaults prints location where memory that is corrupted was allocated.
255 
256     Use CHKMEMA for functions that return void
257 
258    Concepts: memory corruption
259 
260 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
261           PetscMallocValidate()
262 M*/
263 #define CHKMEMQ {PetscErrorCode _7_ierr = PetscMallocValidate(__LINE__,__FUNCT__,__FILE__,__SDIR__);CHKERRQ(_7_ierr);}
264 
265 #define CHKMEMA {PetscMallocValidate(__LINE__,__FUNCT__,__FILE__,__SDIR__);}
266 
267 #if defined(PETSC_UNDERSCORE_CHKERR)
268 extern  PetscErrorCode __gierr;
269 #define _   __gierr =
270 #define ___  CHKERRQ(__gierr);
271 #endif
272 
273 #define               PETSC_EXCEPTIONS_MAX  256
274 extern PetscErrorCode PetscErrorUncatchable[PETSC_EXCEPTIONS_MAX];
275 extern PetscInt       PetscErrorUncatchableCount;
276 extern PetscErrorCode PetscExceptions[PETSC_EXCEPTIONS_MAX];
277 extern PetscInt       PetscExceptionsCount;
278 
279 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscExceptionPush(PetscErrorCode);
280 EXTERN void PETSC_DLLEXPORT PetscExceptionPop(PetscErrorCode);
281 
282 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscErrorSetCatchable(PetscErrorCode,PetscTruth);
283 EXTERN PetscTruth PETSC_DLLEXPORT PetscErrorIsCatchable(PetscErrorCode);
284 /*MC
285    PetscExceptionCaught - Indicates if a specific exception zierr was caught.
286 
287    Not Collective
288 
289    Synopsis:
290      PetscTruth PetscExceptionCaught(PetscErrorCode xierr,PetscErrorCode zierr);
291 
292   Input Parameters:
293   + xierr - error code returned from PetscExceptionTry1()
294   - zierr - error code you want it to be
295 
296   Level: advanced
297 
298    Notes:
299     PETSc must not be configured using the option --with-errorchecking=0 for this to work
300 
301     Use PetscExceptionValue() to see if the current error code is one that has been "tried"
302 
303   Concepts: exceptions, exception hanlding
304 
305 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
306           CHKERRQ(), PetscExceptionTry1(), PetscExceptionValue()
307 M*/
308 PETSC_STATIC_INLINE PetscTruth PetscExceptionCaught(PetscErrorCode xierr,PetscErrorCode zierr) {
309   PetscInt i;
310   if (xierr != zierr) return PETSC_FALSE;
311   for (i=0; i<PetscErrorUncatchableCount; i++) {
312     if (PetscErrorUncatchable[i] == zierr) {
313       return PETSC_FALSE;
314     }
315   }
316   return PETSC_TRUE;
317 }
318 
319 /*MC
320    PetscExceptionValue - Indicates if the error code is one that is currently being tried
321 
322    Not Collective
323 
324    Synopsis:
325      PetscTruth PetscExceptionValue(PetscErrorCode xierr);
326 
327   Input Parameters:
328   . xierr - error code
329 
330   Level: developer
331 
332    Notes:
333     PETSc must not be configured using the option --with-errorchecking=0 for this to work
334 
335     Use PetscExceptionCaught() to see if the current error code is EXACTLY the one you want
336 
337   Concepts: exceptions, exception hanlding
338 
339 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
340           CHKERRQ(), PetscExceptionTry1(), PetscExceptionCaught()
341 M*/
342 PETSC_STATIC_INLINE PetscTruth PetscExceptionValue(PetscErrorCode zierr) {
343   PetscInt i;
344   for (i=0; i<PetscExceptionsCount; i++) {
345     if (PetscExceptions[i] == zierr) {
346       return PETSC_TRUE;
347     }
348   }
349   return PETSC_FALSE;
350 }
351 
352 /*MC
353    PetscExceptionTry1 - Runs the routine, causing a particular error code to be treated as an exception,
354          rather than an error. That is if that error code is treated the program returns to this level,
355          but does not call the error handlers
356 
357    Not Collective
358 
359    Synopsis:
360      PetscExceptionTry1(PetscErrorCode routine(....),PetscErrorCode);
361 
362   Level: advanced
363 
364    Notes:
365     PETSc must not be configured using the option --with-errorchecking=0 for this to work
366 
367   Note: In general, the outer most try on an exception is the one that will be caught (that is trys down in
368         PETSc code will not usually handle an exception that was issued above). See SNESSolve() for an example
369         of how the local try is ignored if a higher (in the stack) one is also in effect.
370 
371   Concepts: exceptions, exception hanlding
372 
373 .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), PetscError(), SETERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2(), SETERRQ3(),
374           CHKERRQ(), PetscExceptionCaught(), PetscExceptionPush(), PetscExceptionPop()
375 M*/
376 extern PetscErrorCode PetscExceptionTmp;
377 #define PetscExceptionTry1(a,b) (PetscExceptionTmp = PetscExceptionPush(b)) ? PetscExceptionTmp : (PetscExceptionTmp = a , PetscExceptionPop(b),PetscExceptionTmp)
378 
379 #else
380 
381 /*
382     These are defined to be empty for when error checking is turned off, with config/configure.py --with-errorchecking=0
383 */
384 
385 #define SETERRQ(n,s) ;
386 #define SETERRQ1(n,s,a1) ;
387 #define SETERRQ2(n,s,a1,a2) ;
388 #define SETERRQ3(n,s,a1,a2,a3) ;
389 #define SETERRQ4(n,s,a1,a2,a3,a4) ;
390 #define SETERRQ5(n,s,a1,a2,a3,a4,a5) ;
391 #define SETERRQ6(n,s,a1,a2,a3,a4,a5,a6) ;
392 #define SETERRABORT(comm,n,s) ;
393 
394 #define CHKERRQ(n)     ;
395 #define CHKERRABORT(comm,n) ;
396 #define CHKERRCONTINUE(n) ;
397 
398 #define CHKMEMQ        ;
399 
400 #if !defined(PETSC_SKIP_UNDERSCORE_CHKERR)
401 #define _
402 #define ___
403 #endif
404 
405 #define PetscErrorSetCatchable(a,b) 0
406 #define PetscExceptionCaught(a,b)   PETSC_FALSE
407 #define PetscExceptionValue(a)      PETSC_FALSE
408 #define PetscExceptionTry1(a,b)     a
409 #endif
410 
411 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscErrorPrintfInitialize(void);
412 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscErrorMessage(int,const char*[],char **);
413 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscTraceBackErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
414 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscIgnoreErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
415 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscEmacsClientErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
416 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscMPIAbortErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
417 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscAbortErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
418 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscAttachDebuggerErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
419 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscReturnErrorHandler(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*);
420 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscError(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,...) PETSC_PRINTF_FORMAT_CHECK(7,8);
421 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscPushErrorHandler(PetscErrorCode (*handler)(int,const char*,const char*,const char*,PetscErrorCode,int,const char*,void*),void*);
422 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscPopErrorHandler(void);
423 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscDefaultSignalHandler(int,void*);
424 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscPushSignalHandler(PetscErrorCode (*)(int,void *),void*);
425 EXTERN PetscErrorCode PETSC_DLLEXPORT PetscPopSignalHandler(void);
426 
427 typedef enum {PETSC_FP_TRAP_OFF=0,PETSC_FP_TRAP_ON=1} PetscFPTrap;
428 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscSetFPTrap(PetscFPTrap);
429 
430 /*
431       Allows the code to build a stack frame as it runs
432 */
433 #if defined(PETSC_USE_DEBUG)
434 
435 #define PETSCSTACKSIZE 15
436 
437 typedef struct  {
438   const char *function[PETSCSTACKSIZE];
439   const char *file[PETSCSTACKSIZE];
440   const char *directory[PETSCSTACKSIZE];
441         int  line[PETSCSTACKSIZE];
442         int currentsize;
443 } PetscStack;
444 
445 extern PETSC_DLLEXPORT PetscStack *petscstack;
446 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackCopy(PetscStack*,PetscStack*);
447 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackPrint(PetscStack*,FILE* fp);
448 
449 #define PetscStackActive (petscstack != 0)
450 
451 
452 /*MC
453    PetscFunctionBegin - First executable line of each PETSc function
454         used for error handling.
455 
456    Synopsis:
457    void PetscFunctionBegin;
458 
459    Usage:
460 .vb
461      int something;
462 
463      PetscFunctionBegin;
464 .ve
465 
466    Notes:
467      Not available in Fortran
468 
469    Level: developer
470 
471 .seealso: PetscFunctionReturn()
472 
473 .keywords: traceback, error handling
474 M*/
475 #define PetscFunctionBegin \
476   {\
477    if (petscstack && (petscstack->currentsize < PETSCSTACKSIZE)) {    \
478     petscstack->function[petscstack->currentsize]  = __FUNCT__; \
479     petscstack->file[petscstack->currentsize]      = __FILE__; \
480     petscstack->directory[petscstack->currentsize] = __SDIR__; \
481     petscstack->line[petscstack->currentsize]      = __LINE__; \
482     petscstack->currentsize++; \
483   }}
484 
485 #define PetscStackPush(n) \
486   {if (petscstack && (petscstack->currentsize < PETSCSTACKSIZE)) {    \
487     petscstack->function[petscstack->currentsize]  = n; \
488     petscstack->file[petscstack->currentsize]      = "unknown"; \
489     petscstack->directory[petscstack->currentsize] = "unknown"; \
490     petscstack->line[petscstack->currentsize]      = 0; \
491     petscstack->currentsize++; \
492   }}
493 
494 #define PetscStackPop \
495   {if (petscstack && petscstack->currentsize > 0) {     \
496     petscstack->currentsize--; \
497     petscstack->function[petscstack->currentsize]  = 0; \
498     petscstack->file[petscstack->currentsize]      = 0; \
499     petscstack->directory[petscstack->currentsize] = 0; \
500     petscstack->line[petscstack->currentsize]      = 0; \
501   }};
502 
503 /*MC
504    PetscFunctionReturn - Last executable line of each PETSc function
505         used for error handling. Replaces return()
506 
507    Synopsis:
508    void PetscFunctionReturn(0);
509 
510    Usage:
511 .vb
512     ....
513      PetscFunctionReturn(0);
514    }
515 .ve
516 
517    Notes:
518      Not available in Fortran
519 
520    Level: developer
521 
522 .seealso: PetscFunctionBegin()
523 
524 .keywords: traceback, error handling
525 M*/
526 #define PetscFunctionReturn(a) \
527   {\
528   PetscStackPop; \
529   return(a);}
530 
531 #define PetscFunctionReturnVoid() \
532   {\
533   PetscStackPop; \
534   return;}
535 
536 
537 #else
538 
539 #define PetscFunctionBegin
540 #define PetscFunctionReturn(a)  return(a)
541 #define PetscFunctionReturnVoid() return
542 #define PetscStackPop
543 #define PetscStackPush(f)
544 #define PetscStackActive        0
545 
546 #endif
547 
548 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackCreate(void);
549 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackView(PetscViewer);
550 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackDestroy(void);
551 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackPublish(void);
552 EXTERN PetscErrorCode PETSC_DLLEXPORT  PetscStackDepublish(void);
553 
554 
555 PETSC_EXTERN_CXX_END
556 #endif
557