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