LALStatusMacros.h

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Jolien Creighton
00003 *
00004 *  This program is free software; you can redistribute it and/or modify
00005 *  it under the terms of the GNU General Public License as published by
00006 *  the Free Software Foundation; either version 2 of the License, or
00007 *  (at your option) any later version.
00008 *
00009 *  This program is distributed in the hope that it will be useful,
00010 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 *  GNU General Public License for more details.
00013 *
00014 *  You should have received a copy of the GNU General Public License
00015 *  along with with program; see the file COPYING. If not, write to the
00016 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00017 *  MA  02111-1307  USA
00018 */
00019 
00020 /****************************** <lalVerbatim file="LALStatusMacrosHV">
00021 Author: Creighton, J. D. E. and Creighton, T. D.
00022 $Id: LALStatusMacros.h,v 1.25 2007/06/08 14:41:52 bema Exp $
00023 ******************************* </lalVerbatim> */
00024 
00025 /* <lalLaTeX>
00026 
00027 \section{Header \texttt{LALStatusMacros.h}}
00028 \label{s:LALStatusMacros.h}
00029 
00030 Provides macros for handling the LAL status structure.
00031 
00032 \subsection*{Synopsis}
00033 \begin{verbatim}
00034 #include <lal/LALStatusMacros.h>
00035 \end{verbatim}
00036 
00037 \noindent This header provides macros and functions for tracking and
00038 reporting the runtime status of a program.  The intent is
00039 simultaneously to standardize the error reporting, and to make the
00040 reporting as transparent as possible to people coding individual
00041 routines.
00042 
00043 \subsection{Status-reporting objects}
00044 \label{ss:status-reporting-objects}
00045 
00046 LAL routines make use of two objects in reporting their current
00047 status: the status structure \verb@LALStatus@, and the global integer
00048 \verb@lalDebugLevel@.  These two objects are described in the following
00049 sections.
00050 
00051 \subsubsection{The \texttt{LALStatus} structure}
00052 \idx[Type]{LALStatus}
00053 
00054 LAL routines store their current execution status in a linked list of
00055 structures of type \verb@LALStatus@, with each node in the list
00056 representing a subroutine in the current calling sequence.  The
00057 \verb@LALStatus@ structure is described in Sec.~\ref{ss:status-structure}
00058 of the header \verb@LALDatatypes.h@, but for completeness, we explain
00059 its fields below:
00060 \begin{description}
00061 \item[\texttt{INT4 statusCode}] A code indicating the exit status of a
00062 function.  0 represents a normal exit.  Negative values are reserved
00063 for certain standard error types.  The authors of individual functions
00064 should assign positive values to the various ways in which their code
00065 can fail.
00066 \item[\texttt{const CHAR *statusDescription}] An explanatory string
00067 corresponding to the numerical status code.
00068 \item[\texttt{volatile const CHAR *Id}] A character string identifying
00069 the source file and version number of the function being reported on.
00070 \item[\texttt{const CHAR *function}] The name of the function.
00071 \item[\texttt{const CHAR *file}] The file name of the \verb@.c@ file
00072 containing the function code.
00073 \item[\texttt{INT4 line}] The line number in the \verb@.c@ file of the
00074 instruction where any error was reported.
00075 \item[\texttt{LALStatus *statusPtr}] A recursive pointer to another
00076 status pointer.  This structure is used to report an error in a
00077 subroutine of the current function.  Thus if an error occurs in a
00078 deeply-nested routine, the status structure returned to the main
00079 program will be the head of a linked list of status structures, one
00080 for each nested level, with the tail structure reporting the actual
00081 error that caused the overlying routines to fail.
00082 \item[\texttt{INT4 level}] The nested-function level where any error
00083 was reported.
00084 \end{description}
00085 In almost all circumstances the programmer will \emph{not} have to
00086 access this structure directly, relying instead on the macros defined
00087 in this header.  The exception is the \verb@statusCode@ field, which
00088 the programmer may want to query directly.
00089 
00090 The \verb@statusCode@ field is set to a nonzero value any time an
00091 error condition arises that would lead to abnormal termination of the
00092 current function.  Programmers can assign positive error codes to the
00093 various types of error that may be encountered in their routines.
00094 Additionally, the following following status codes are reserved to
00095 report certain standard conditions:
00096 
00097 \begin{center}
00098 \begin{tabular}{|cp{3.5cm}p{6.5cm}|}
00099 \hline
00100 Code & Message & Explanation \\
00101 \hline
00102 
00103 \tt 0 & & Nominal execution; the function returned
00104 successfully. \\
00105 
00106 \tt -1 & \vspace{-1.4ex}\tt Recursive error & The function aborted due
00107 to failure of a subroutine. \\
00108 
00109 \tt -2 & \vspace{-1.4ex}\tt INITSTATUS: non-null status pointer & The
00110 status structure passed to the function had a non-\verb@NULL@
00111 \verb@statusPtr@ field, which blocks the function from calling
00112 subroutines (it is symptomatic of something screwy going on in the
00113 calling routine). \\
00114 
00115 \tt -4 & \vspace{-1.4ex}\tt ATTATCHSTATUSPTR: memory allocation error
00116 & The function was unable to allocate a \verb@statusPtr@ field to pass
00117 down to a subroutine. \\
00118 
00119 \tt -8 & \vspace{-1.4ex}\tt DETATCHSTATUSPTR: null status pointer &
00120 The \verb@statusPtr@ field could not be deallocated at the end of all
00121 subroutine calls; one of the subroutines must have lost it or set it
00122 to \verb@NULL@. \\
00123 
00124 \tt -16 & \vspace{-1.4ex}\tt INITSTATUS: non-zero xlalErrno &
00125 The \verb@xlalError@ variable is non-zero, which suggests that an
00126 error in an XLAL routine has occured and has not been handled. \\
00127 
00128 \tt -16 & \vspace{-1.4ex}\tt RETURN: untrapped XLAL error code &
00129 The \verb@xlalError@ variable is non-zero, which indicates that an
00130 error in an XLAL routine has occured and has not been handled. \\
00131 
00132 \hline
00133 \end{tabular}
00134 \end{center}
00135 
00136 \subsubsection{The \texttt{lalDebugLevel}}
00137 \idx[Variable]{lalDebugLevel}
00138 
00139 The \verb@lalDebugLevel@ is a global variable, set at runtime, that
00140 determines how much and what kind of debugging information will be
00141 reported.  It is declared as an \verb@extern int@ in the header
00142 \verb@LALStatusMacros.h@, and is therefore accessible in any standard
00143 LAL module that includes this header.  Note, however, that it is
00144 declared to be of the C type \verb@int@, which is usually but not
00145 always a 32-bit integer (on some systems it may only be 16 bits).
00146 
00147 The value of \verb@lalDebugLevel@ should be thought of not as a number,
00148 but as a \emph{bit mask}, wherein each bit in the binary
00149 representation turns on or off a specific type of status reporting.
00150 At present, there are five types of status reporting, each associated
00151 with a bit in \verb@lalDebugLevel@.
00152 
00153 \paragraph{Error messages} tell the operator that a computation has
00154 terminated abnormally, and has failed to produce an acceptable result.
00155 Normally this is associated with assigning a non-zero
00156 \verb@statusCode@; an error message is printed automatically whenever
00157 a function exits with non-zero \verb@statusCode@.
00158 
00159 \paragraph{Warning messages} tell the user that a computation is
00160 working, but with unusual behaviour that might indicate an unreliable
00161 or meaningless result.  Warnings do not normally result in a non-zero
00162 \verb@statusCode@.
00163 
00164 \paragraph{Information messages} tell the operator that the
00165 computation is proceeding as expected, and simply provide additional
00166 information about its progress.
00167 
00168 \paragraph{Tracing messages} are printed automatically a subroutine
00169 is called or returned; they simply track the current sequence of
00170 function calls.
00171 
00172 \paragraph{Memory information messages} are a special type of
00173 information message; they tell the operator when and how much memory
00174 is allocated or freed from the memory heap.
00175 
00176 \paragraph{}The module \verb@LALError.c@ defines functions for
00177 printing each of these types of status message.  Each type of message
00178 is turned on by setting the corrsponding bit in \verb@lalDebugLevel@ to
00179 1, and is suppressed by setting the bit to 0.  This header file
00180 \verb@#define@s flags with numerical values designed to switch on the
00181 appropriate bits.  Combinations of bits can be switched on by
00182 combining these flags using the bitwise-\textit{or} operator,
00183 \verb@|@.  The flags are defined as follows:
00184 
00185 \begin{center}
00186 \begin{tabular}{|lccl|}
00187 \hline
00188 Flag & Octal & Decimal & Meaning \\
00189 \hline
00190 \multicolumn{4}{|l|}{\it Primitive flags} \\
00191 \tt LALNDEBUG   & 000000 &     0 & No debugging or status messages \\
00192 \tt LALERROR    & 000001 &     1 & Turn on error messages \\
00193 \tt LALWARNING  & 000002 &     2 & Turn on warning messages \\
00194 \tt LALINFO     & 000004 &     4 & Turn on info messages \\
00195 \tt LALTRACE    & 000010 &     8 & Turn on tracing messages \\
00196 \tt LALMEMINFO  & 000020 &    16 & Turn on memory messages \\
00197 \tt LALNMEMDBG  & 000040 &    32 & Turn off all memory debugging \\
00198 \tt LALNMEMPAD  & 000100 &    64 & Turn off memory padding \\
00199 \tt LALNMEMTRK  & 000200 &   128 & Turn off memory tracking \\
00200 \tt LALMEMDBG   & 040000 & 16384 & Turn on memory debugging without messages \\
00201 \multicolumn{4}{|l|}{\it Combination flags} \\
00202 \tt LALMSGLVL1  & 000001 &     1 & Error messages only \\
00203 \tt LALMSGLVL2  & 000003 &     3 & Error and warning messages \\
00204 \tt LALMSGLVL3  & 000007 &     7 & Error, warning, and info messages \\
00205 \tt LALMEMTRACE & 000030 &    24 & Memory and tracing messages \\
00206 \tt LALALLDBG   & 077437 & 32543 & All messages and debugging \\
00207 \hline
00208 \end{tabular}
00209 \end{center}
00210 \idx[Constant]{LALNDEBUG}
00211 \idx[Constant]{LALERROR}
00212 \idx[Constant]{LALWARNING}
00213 \idx[Constant]{LALINFO}
00214 \idx[Constant]{LALTRACE}
00215 \idx[Constant]{LALMEMINFO}
00216 \idx[Constant]{LALMEMNDBG}
00217 \idx[Constant]{LALMEMNPAD}
00218 \idx[Constant]{LALMEMNTRK}
00219 \idx[Constant]{LALMEMDBG}
00220 \idx[Constant]{LALMSGLVL1}
00221 \idx[Constant]{LALMSGLVL2}
00222 \idx[Constant]{LALMSGLVL3}
00223 \idx[Constant]{LALMEMTRACE}
00224 \idx[Constant]{LALALLDBG}
00225 
00226 The most significant bit
00227 of \verb@lalDebugLevel@ has a special meaning in that it is not
00228 associated with any type of status message.  However, certain pieces
00229 of debugging or error-tracking code --- such as the memory leak
00230 detection code in \verb@LALMalloc.c@ --- do not write status messages
00231 and are not associated with a \verb@lalDebugLevel@ bit; instead, these
00232 pieces of code are turned on for \emph{any} nonzero value of
00233 \verb@lalDebugLevel@, unless the \verb@LALNMEMDBG@ bit is set.
00234 Switching on only the most significant bit with
00235 \verb@LALMEMDBG@ activates this code without turning on any other
00236 error reporting.
00237 
00238 To turn debugging code on or off at compile time (rather than
00239 runtime), see Sec.~\ref{ss:compilation-flags}, below.
00240 
00241 \subsection{Using the status tools}
00242 \label{ss:using-status-tools}
00243 
00244 The following summarizes everything the common programmer needs to
00245 know in order to follow LAL standard error reporting.  It can be
00246 treated as a primer on LAL coding conventions.
00247 
00248 \subsubsection{LAL function calls}
00249 
00250 All functions should have return type void.  The first argument of any
00251 function should be a pointer to a structure of type \verb@LALStatus@.
00252 Thus:
00253 \begin{verbatim} 
00254 void MyFunction( LALStatus *stat, ... )
00255 \end{verbatim}
00256 Since the function has no return code, it must report all errors or
00257 failure through the status structure.  A function that is passed a
00258 \verb@NULL@ pointer in place of the status pointer should terminate
00259 the program with a \verb@SIGABRT@ signal, as this is its only way to
00260 report the error.  However, this is one of the few circumstances under
00261 which a function sould deliberately raise a signal.  In all other
00262 cases the error should be trapped, reported in the status structure,
00263 and control returned to the calling routine.
00264 
00265 \subsubsection{Assigning an RCS \texttt{\$Id\$} string}
00266 \idx{NRCSID()}
00267 
00268 Every source file should have a unique character string identifying
00269 that version of that file.  The standard convention, for a file
00270 \verb@MyFile.c@, is to declare a string \verb@MYFILEC@ at the top of
00271 the module using the macro \verb@NRCSID()@ (defined in the include
00272 file \verb@LALRCSID.h@):
00273 
00274 \vspace{2ex}
00275 \noindent\texttt{NRCSID( MYFILEC, \$Id\$ );}
00276 \vspace{2ex}
00277 
00278 \noindent where \texttt{\$Id\$} is expanded by RCS to give the full
00279 name and version number of the source file.
00280 
00281 \subsubsection{Initializing the status structure}
00282 \idx{INITSTATUS()}
00283 
00284 The first instruction in any function, after variable declarations,
00285 should be the macro \verb@INITSTATUS()@, which takes three arguments:
00286 the function's status pointer, the function name (a string literal)
00287 and the module's RCS \texttt{\$Id\$} string.
00288 \begin{verbatim}
00289 INITSTATUS( stat, "MyFunction", MYFILEC );
00290 \end{verbatim}
00291 This macro checks that a valid status pointer has been passed to the
00292 function, and if so, initializes the other fields to indicate (by
00293 default) nominal execution.  If \verb@stat@ is null, the macro causes
00294 the program to terminate with a \verb@SIGABRT@ signal, as described
00295 above.
00296 
00297 \subsubsection{Normal return from a function}
00298 \idx{RETURN()}
00299 
00300 Upon completion, the function should issue the macro \verb@RETURN()@,
00301 which takes one argument: the function's status pointer.
00302 \begin{verbatim}
00303 RETURN( stat );
00304 \end{verbatim}
00305 This takes the place of any return statements.  If
00306 \verb@stat->statusCode@ is non-zero, the macro calls \verb@LALError()@
00307 (see \verb@LALError.c@) to log \verb@stat->statusDescription@ and
00308 other information, depending on implementation and the value of
00309 \verb@lalDebugLevel@.  Typically \verb@RETURN()@ is used only for
00310 successful completion, with other macros \verb@ABORT()@,
00311 \verb@ASSERT()@, \verb@CHECKSTATUSPTR()@, and \verb@TRY()@ being used
00312 to report failure.  However, it is possible for the programmer to
00313 assign the fields of \verb@*stat@ by hand, and then issue
00314 \verb@RETURN()@.
00315 
00316 \subsubsection{Abnormal return from a function}
00317 \idx{ABORT()}
00318 
00319 The standard method to terminate a function unsuccessfully is with the
00320 \verb@ABORT()@ macro, which takes three arguments: the status pointer,
00321 the status code, and the status description string.  Normally the
00322 various error codes and descriptions will be constants defined in the
00323 function's header file \verb@MyHeader.h@:
00324 \begin{verbatim}
00325 ABORT( stat, MYHEADERH_EMYERR, MYHEADERH_MSGEMYERR );
00326 \end{verbatim}
00327 where the error code \verb@MYHEADERH_EMYERR@ and the error message
00328 \verb@MYHEADERH_MSGEMYERR@ are defined in \verb@MyHeader.h@.  This
00329 standard LAL naming convention for error messages prevents namespace
00330 conflicts between different header files.  Like \verb@RETURN()@,
00331 \verb@ABORT()@ correctly handles any status logging required by the
00332 implementation and the \verb@lalDebugLevel@.  Note that \verb@ABORT()@
00333 does \emph{not} raise a \verb@SIGABRT@ signal, but instead returns
00334 control to the calling routine.
00335 
00336 \subsubsection{Error checking within a function}
00337 \idx{ASSERT()}
00338 
00339 Another way to indicate an unsuccessful termination is with the macro
00340 \verb@ASSERT()@, which takes as arguments a test statement, a status
00341 pointer, a status code, and a status description.  The statement
00342 \verb@ASSERT( assertion, ... );@ is in all ways equivalent to the
00343 statement \verb@if ( !assertion ) ABORT( ... );@, except on a failure
00344 the \verb@ASSERT()@ macro will also report the failed assertion.  In
00345 the above example, one might have:
00346 \begin{verbatim}
00347 ASSERT( assertion, stat, MYHEADERH_EMYERR, MYHEADERH_MSGEMYERR );
00348 \end{verbatim}
00349 
00350 One subtle but important point is that the \verb@ASSERT()@ should be
00351 used only to trap coding errors, rather than runtime errors, which
00352 would be trapped using \verb@ABORT()@.  In other words, the assertion
00353 should always test true in the final debugged program.  This is vital
00354 because certain compilation flags will remove all \verb@ASSERT()@
00355 macros at compile time, in order to speed execution of the final code.
00356 See Sec.~\ref{ss:compilation-flags}, below.
00357 
00358 Programmers should also be aware that using \verb@ASSERT()@ to exit a
00359 function in normal runtime can have serious side effects.  For
00360 example, it is an error to allocate dynamic memory to local variables
00361 in a function and then fail to free it before returning.  Thus, if you
00362 have dynamically allocated memory, you cannot then use \verb@ASSERT()@
00363 for runtime error checking, as this does not permit you to free the
00364 memory before returning.  Instead, you must explicitly check the
00365 assertion, and, if it fails, free the memory and call \verb@ABORT()@.
00366 
00367 \subsubsection{Calling subroutines}
00368 \idx{ATTATCHSTATUSPTR()}
00369 \idx{DETATCHSTATUSPTR()}
00370 \idx{CHECKSTATUSPTR()}
00371 \idx[Macro]{TRY()}
00372 
00373 If the function is to call other LAL functions as subroutines, four
00374 more macros are used to report possible errors arising in these
00375 routines.  The macros are \verb@ATTATCHSTATUSPTR()@,
00376 \verb@DETATCHSTATUSPTR()@, \verb@CHECKSTATUSPTR()@, and \verb@TRY()@.
00377 The usage of these macros is as follows.
00378 
00379 \begin{enumerate}
00380 
00381 \item First, before any subroutines are called, the function must call
00382 the macro \verb@ATTATCHSTATUSPTR()@ which takes as its argument the
00383 status pointer of the current function:
00384 \begin{verbatim}
00385 ATTATCHSTATUSPTR( stat );
00386 \end{verbatim}
00387 This allocates \verb@stat->statusPtr@, which is the status pointer
00388 that will be handed down into any and all subroutines.  If the pointer
00389 has already been allocated, \verb@ATTATCHSTATUSPTR()@ will raise a
00390 \verb@SIGABRT@, as this is symptomatic of a coding error.
00391 
00392 In most cases \verb@ATTATCHSTATUSPTR()@ need only be called once in a
00393 given function, immediately after \verb@INITSTATUS()@, no matter how
00394 many subroutine calls that function makes.  The exception is if the
00395 function deals with (or ignores) errors reported by its subroutines.
00396 In that case, the function should detatch the status pointer using
00397 \verb@DETATCHSTATUSPTR()@ (below), and then re-attatch it.
00398 
00399 The macro \verb@ATTATCHSTATUSPTR()@ sets the status code to be $-1$
00400 and the status message to be \verb@"Recursive error"@.  These flags
00401 are unset when \verb@DETATCHSTATUSPTR()@ (below) is called.  This is
00402 so that a use of \verb@RETURN()@ prior to detatching the status
00403 pointer will yield an error.
00404 
00405 \item When a subroutine is called, it should be handed the
00406 \verb@statusPtr@ field of the calling function's status structure, to
00407 report its own errors.  The calling function should test the returned
00408 status code, and either attempt to deal with any abnormal returns, or
00409 abort with status code $-1$.  The macro \verb@CHECKSTATUSPTR()@
00410 simplifies the latter case.  It takes one arguments: the status
00411 pointer of the current function (not the subroutine).
00412 \begin{verbatim}
00413 MySubroutine( stat->statusPtr, ... );
00414 CHECKSTATUSPTR( stat );
00415 \end{verbatim}
00416 The \verb@TRY()@ macro is a somewhat more streamlined approach but
00417 with equivalent results.  It takes two arguments.  The first is the
00418 subroutine call, and the second is the status pointer.  Thus:
00419 \begin{verbatim}
00420 TRY( MySubroutine( stat->statusPtr, ... ), stat );
00421 \end{verbatim}
00422 The only practical difference between these two approaches is that
00423 \verb@TRY()@ also reports the name of the failed subroutine call when
00424 logging errors.
00425 
00426 Similar caveats apply when using \verb@CHECKSTATUSPTR()@ and
00427 \verb@TRY()@ as when using \verb@ASSERT()@, in that these macros can
00428 force an immediate return with no additional housekeeping
00429 instructions.  For instance, if you have dynamically-allocated local
00430 memory, you should explicitly check the \verb@statusPtr->statusCode@
00431 field to see if a subroutine failed, then free the memory and call
00432 \verb@ABORT()@ to exit.
00433 
00434 If the calling routine attempts to work around an error reported from
00435 a subroutine, and the attempt fails, the routine should \emph{not} use
00436 \verb@CHECKSTATUSPTR()@ to exit with status code $-1$.  Instead, it
00437 should call \verb@ABORT()@ with an appropriate (positive) code and
00438 message to indicate how the attempted workaround failed.
00439 
00440 \item After all subroutines have been called, but before any
00441 \verb@RETURN()@ statement, the function must call the
00442 \verb@DETATCHSTATUSPTR()@ macro, with the status pointer of the
00443 current function (not the subroutines) as its argument:
00444 \begin{verbatim}
00445 DETATCHSTATUSPTR( stat );
00446 \end{verbatim}
00447 This simply deallocates \verb@stat->statusPtr@ (and any subsequent
00448 structures in the list), and sets it to \verb@NULL@.  It is an error
00449 to exit the function with non-\verb@NULL@ \verb@statusPtr@, unless the
00450 exit was due to a subroutine failure.  \verb@ABORT()@ and
00451 \verb@ASSERT()@ check for this automatically; the only place you
00452 normally need to call \verb@DETATCHSTATUSPTR()@ is immediately before
00453 \verb@RETURN()@.  This macro also sets the status code and the status
00454 message to nominal values.
00455 
00456 Additionally, if a function successfully works around an error
00457 reported by a subroutine, it should call \verb@DETATCHSTATUSPTR()@ and
00458 \verb@ATTATCHSTATUSPTR()@ to create a fresh status pointer before
00459 calling another subroutine.
00460 
00461 \end{enumerate}
00462 
00463 \subsubsection{Cleaning up after subroutine failure}
00464 \idx[Macro]{BEGINFAIL()}
00465 \idx[Macro]{ENDFAIL()}
00466 
00467 Although they are convenient, the \verb@TRY()@ and
00468 \verb@CHECKSTATUSPTR()@ macros have a serious drawback in that they
00469 may cause the calling function to return immediately.  If the calling
00470 function had previously allocated any local memory storage, this
00471 memory will be cast adrift, with no means of accessing or subsequently
00472 freeing it (short of terminating the runtime process).  Such a memory
00473 leak is a violation of the LAL function standard.
00474 
00475 The macros \verb@BEGINFAIL()@ and \verb@ENDFAIL()@ allow a function to
00476 test the return code of a subroutine, and, if that indicates a
00477 failure, to execute one or more ``cleanup'' instructions before itself
00478 returning.  Each macro takes a single argument: the current function's
00479 status pointer.  The macros must occur in matched pairs, and use the
00480 same syntax as a \verb@do ... while@ statement: they either span a
00481 single instruction, or a block of instructions enclosed in braces.
00482 
00483 For example, if a function had allocated memory to some pointer
00484 \verb@localPointer@, any subsequent call to a subroutine
00485 \verb@LALSubroutine()@ would take the following form:
00486 \begin{verbatim}
00487 LALSubroutine( stat->statusPtr, ... );
00488 BEGINFAIL( stat )
00489   LALFree( localPointer );
00490 ENDFAIL( stat );
00491 \end{verbatim}
00492 For another example, if a function had to create three vectors
00493 \verb@*vector1@, \verb@*vector2@, \verb@*vector3@, the allocation
00494 would look something like this:
00495 \begin{verbatim}
00496 TRY( LALSCreateVector( stat->statusPtr, &vector1, 100 ), stat );
00497 
00498 LALSCreateVector( stat->statusPtr, &vector2, 100 );
00499 BEGINFAIL( stat )
00500   TRY( LALSDestroyVector( stat->statusPtr, &vector1 ), stat );
00501 ENDFAIL( stat );
00502 
00503 LALSCreateVector( stat->statusPtr, &vector3, 100 );
00504 BEGINFAIL( stat ) {
00505   TRY( LALSDestroyVector( stat->statusPtr, &vector1 ), stat );
00506   TRY( LALSDestroyVector( stat->statusPtr, &vector2 ), stat );
00507 } ENDFAIL( stat );
00508 \end{verbatim}
00509 As indicated above, the cleanup instructions can include calls to
00510 other LAL routines.  The \verb@BEGINFAIL( stat )@ macro call first
00511 checks \verb@stat->statusPtr@ to see if a subroutine error has
00512 occured.  If it has, the macro detaches and saves that pointer, then
00513 attaches a new \verb@stat->statusPtr@ to be used in calls to the
00514 cleanup routines.  After the cleanup instructions have been executed,
00515 the \verb@ENDFAIL( stat )@ macro call reattaches the saved status
00516 pointer and returns with a subroutine error code.  In this way, the
00517 returned status list indicates where the original failure occurred,
00518 rather than giving an uninformative report from the last cleanup
00519 routine.
00520 
00521 Of course a \emph{second} failure in one of the cleanup routines can
00522 cause serious problems.  If the routine was called using a
00523 \verb@TRY()@ macro, it will force an immediate return from the calling
00524 function, with a status code and status list indicating how the cleanp
00525 routine failed.  The original status list saved by \verb@BEGINFAIL()@
00526 is lost.  While this loss does constitute a memory leak, the failure
00527 of a cleanup routine in itself indicates that there are serious
00528 problems with the memory management.
00529 
00530 It is possible to nest \verb@BEGINFAIL()@\ldots\verb@ENDFAIL();@
00531 blocks, but this is unlikely to serve any useful purpose.  Once
00532 cleanup routines start to fail, it is probably beyond the scope of the
00533 LAL function to deal with the resulting memory leaks.
00534 
00535 \subsubsection{Issuing status messages}
00536 \idx{LALError()}
00537 \idx{LALWarning()}
00538 \idx{LALInfo()}
00539 \idx{LALTrace()}
00540 \idx{REPORTSTATUS()}
00541 
00542 The module \verb@LALError.c@ defines the functions \verb@LALError()@,
00543 \verb@LALWarning()@, \verb@LALInfo()@, and \verb@LALTrace()@ to issue
00544 various types of status message.  This is the preferred means of
00545 printing status messages, since each type of message can be activated
00546 or suppressed by setting \verb@lalDebugLevel@ appropriately.  In fact,
00547 \verb@LALError()@ and \verb@LALTrace()@ are called automatically by
00548 the status macros whenever they are required, so most LAL modules will
00549 explicitly invoke only the \verb@LALWarning()@ and \verb@LALInfo()@
00550 functions.
00551 
00552 \verb@LALStatusMacros.h@ provides a macro, \verb@REPORTSTATUS()@,
00553 which is used to report the current state of the \verb@LALStatus@ list.
00554 It takes a status pointer as its argument:
00555 \begin{verbatim}
00556 REPORTSTATUS( stat );
00557 \end{verbatim}
00558 This macro iteratively prints the contents of \verb@stat@ and all
00559 subsequent structures in the list to the error log.
00560 
00561 The action of \verb@REPORTSTATUS()@ is not suppressed by any value of
00562 \verb@lalDebugLevel@.  Therefore, as a rule, it should only be called by
00563 test programs, not by LAL routines intended for use in production
00564 code.
00565 
00566 \subsubsection{Setting the initial \texttt{LALStatus} structure and
00567 global \texttt{lalDebugLevel}}
00568 \idx[Type]{LALStatus}
00569 \idx[Variable]{lalDebugLevel}
00570 
00571 As mentioned above, any module including \verb@LALStatusMacros.h@
00572 includes the global variable \verb@lalDebugLevel@ as an
00573 \verb@extern int@.  At least one module in the final executable
00574 program must have a global \emph{declaration} of \verb@int lalDebugLevel@
00575 (not \verb@extern int@), and assign \verb@lalDebugLevel@ a value.  In
00576 most cases \verb@lalDebugLevel@ will be declared in the module containing
00577 the \verb@main()@ function, and will be assigned a value on
00578 declaration or from command-line arguments to \verb@main()@.
00579 Alternatively, if the LAL functions are to be embedded in a non-LAL
00580 program, \verb@lalDebugLevel@ can be declared and set in the topmost
00581 module that calls LAL functions.
00582 
00583 A \verb@LALStatus@ structure should also be declared as a local variable
00584 in the \verb@main()@ function of a LAL program, or in the topmost
00585 function calling LAL functions withing a non-LAL program, to pass in
00586 its LAL function calls.  The structure must be empty (all fields set
00587 to zero) before being passed into a function.  The \verb@LALStatus@
00588 structure need only be declared and initialized once, no matter how
00589 many LAL functions are called.
00590 
00591 Thus a typical LAL program might look something like the following:
00592 
00593 \begin{verbatim}
00594 int lalDebugLevel = 1;
00595 
00596 int main( int argc, char **argv )
00597 {
00598   static LALStatus stat;
00599   MyFunction( &stat );
00600   REPORTSTATUS( &stat );
00601   return stat.statusCode;
00602 }
00603 \end{verbatim}
00604 
00605 Please note that all status macros described above can force a return
00606 from the calling routine.  This is a Bad Thing if the calling routine
00607 is \verb@main()@, since \verb@main()@ must normally return \verb@int@
00608 rather than \verb@void@.  It is therefore recommended that none of
00609 these macros except \verb@REPORTSTATUS()@ be used at the top level.
00610 
00611 \subsubsection{Non-confomant functions}
00612 
00613 These standards apply only to functions that will be publicly
00614 available in the LAL libraries.  Within a module, a programmer may
00615 define and use subroutines that do not conform to the LAL function
00616 standards, provided these routines are only visible within that
00617 module.  Such functions should be declared as \verb@static@ to ensure
00618 this.  A publicly-visible non-conformant function requires special
00619 dispensation.
00620 
00621 \subsection{Compilation flags}
00622 \label{ss:compilation-flags}
00623 
00624 LAL provides two flags that can be used to exclude or modify debugging
00625 code at compile time.  Although these flags are typically
00626 \verb@#define@d or \verb@#undef@ined globally and can affect many
00627 modules (notably modules in the \verb@support@ package), their primary
00628 effect is on the debugging and status-reporting tools defined in this
00629 header.  The two flags are named \verb@NDEBUG@ and \verb@NOLALMACROS@.
00630 
00631 \subsubsection{The \texttt{NDEBUG} flag}
00632 
00633 Setting the \verb@NDEBUG@ (or \verb@LAL_NDEBUG@) flag turns off debugging and
00634 error-reporting code, in order to get condensed production-line programs.  As
00635 far as error reporting is concerned, setting the \verb@NDEBUG@ flag at compile
00636 time is similar to setting \verb@lalDebugLevel@ equal to zero at runtime, in
00637 that it suppresses all status messages and memory leak detection.  However,
00638 the \verb@NDEBUG@ flag accoplishes this by telling the compiler preprocessor
00639 to remove the relevant code from the object file, thus eliminating frequent
00640 and unnecessary tests on \verb@lalDebugLevel@.  When debugging is turned off,
00641 the global integer variable \verb@lalNoDebug@ is non-zero; otherwise it is
00642 zero.
00643 
00644 Compiling with the \verb@NDEBUG@ flag set also removes all
00645 \verb@ASSERT()@ macros from the object code, in keeping with the
00646 philosophy that \verb@ASSERT()@ statements should only be used to
00647 catch coding bugs, not runtime errors.
00648 
00649 \subsubsection{The \texttt{NOLALMACROS} flag}
00650 
00651 Setting the \verb@NOLALMACROS@ flag replaces the status-handling
00652 macros described above with actual functions that accomplish the same
00653 results.  These functions are defined in the module \verb@LALError.c@.
00654 Function calls introduce computational and memory overheads that are
00655 absent in macros, since macro replacement occurs at compile time.
00656 However, there are circumstances in which one might want to use
00657 function calls rather than macro replacement.
00658 
00659 For example, debuggers typically cannot step through the individual
00660 instructions within a macro.  If a conflict somehow arose between a
00661 particular piece of code and its status macros, this conflict would be
00662 easier to catch and resolve by replacing the macros with function
00663 calls into which the debugger could step.
00664 
00665 \subsubsection{Using the compilation flags}
00666 
00667 There are three ways to set these flags when compiling LAL programs or
00668 libraries.
00669 
00670 When compiling your own modules, the flags can be set using one or
00671 more \verb@#define@ statements within the module or its header file:
00672 \begin{verbatim}
00673 #define NDEBUG
00674 #define NOLALMACROS
00675 \end{verbatim}
00676 To restrict the scope of these flags, they should later be unset using
00677 the corresponding \verb@#undef@ statements.
00678 
00679 Alternatively, these can be set in the \verb@Makefile@ or when
00680 compiling.  The syntax for most UNIX C compilers is something like the
00681 following:
00682 \begin{verbatim}
00683 > gcc ... -DNDEBUG -DNOLALMACROS ...
00684 \end{verbatim}
00685 
00686 If you want to compile a large number of modules, or the entire
00687 library, under the effects of one or more of these flags, you will not
00688 want to go through and modify every header or \verb@Makefile@.
00689 Instead, you may add either \verb@-DNDEBUG@ or \verb@-DNOLALMACROS@
00690 (or both) to the environment variable \verb@CPPFLAGS@.  They will then
00691 automatically be set for all compilations done in that environment.
00692 The command for doing this in \verb@sh@ or \verb@bash@ shells is:
00693 \begin{verbatim}
00694 > CPPFLAGS="$CPPFLAGS -DNDEBUG -DNOLALMACROS"
00695 \end{verbatim}
00696 while in \verb@csh@ or \verb@tcsh@ shells it is:
00697 \begin{verbatim}
00698 > setenv CPPFLAGS "$CPPFLAGS -DNDEBUG -DNOLALMACROS"
00699 \end{verbatim}
00700 Note that if you plan to do further LAL code development on the same
00701 system, you may want to keep two versions of the library around: one
00702 with the flag(s) set and one without.
00703 
00704 \subsection*{Notes}
00705 
00706 Why are the status handling routines written as macros rather than
00707 functions?  There are three good reasons.
00708 
00709 First, many of the handling routines must be able to force an exit
00710 from the function calling them.  This cannot be done if the routine is
00711 in its own function, except by raising signal flags (which is a Bad
00712 Thing according to LAL standards).
00713 
00714 Second, it is useful for these routines to assign a status structure's
00715 file and line fields using the \verb@__FILE__@ and \verb@__LINE__@
00716 macros.  If the routine is its own function, then these will just give
00717 the file and line number where the error handling routine is defined.
00718 If the routine is a macro, then these will give the file and line
00719 number where the macro was called, which is much more interesting.
00720 
00721 Third, by expanding macros at compile time, the runtime performance of
00722 the resulting code is marginally better.  Most of these macros will,
00723 under nominal conditions, reduce to a single conditional test of an
00724 integer value, with no additional overhead from function calling and
00725 parameter passing.  Thus programmers can be encouraged to include
00726 extensive error trapping in all their routines, without having to
00727 worry about compromising performance.
00728 
00729 It should be mentioned that, for these reasons, compiling a module
00730 with the \verb@NOLALMACROS@ flag above does not actually eliminate the
00731 status handling macros.  Rather, the macros are modified to call
00732 specialized functions that do most (but not all) of the processing.
00733 
00734 \subsection*{Example: A LAL primer}
00735 
00736 The following sections give a sample program program
00737 \verb@LALPrimerTest.c@, along with its supporting header file
00738 \verb@LALPrimer.h@ and function module \verb@LALPrimer.c@.  The
00739 program itself is trivial to the point of silliness: it takes two
00740 arguments from the command line and computes their ratio.  (Optionally
00741 it can take a third command line argument to set the
00742 \verb@lalDebugLevel@.)  It is intended simply to illustrate how to use
00743 the LAL status structure and macros in an actual, complete piece of
00744 code.
00745 
00746 For a more fully developed sample program, see the package
00747 \verb@hello@.  That package also demonstrates how to document a
00748 package using the autodocumentation utilities, which the
00749 \verb@LALPrimer@ routines ignore.
00750 
00751 
00752 \vfill{\footnotesize\input{LALStatusMacrosHV}}
00753 
00754 
00755 \newpage\subsection{Sample header: \texttt{LALPrimer.h}}
00756 \vspace{3ex}
00757 \input{LALPrimerH}
00758 
00759 \newpage\subsection{Sample module: \texttt{LALPrimer.c}}
00760 \vspace{3ex}
00761 \input{LALPrimerC}
00762 
00763 \newpage\subsection{Sample program: \texttt{LALPrimerTest.c}}
00764 \vspace{3ex}
00765 \input{LALPrimerTestC}
00766 
00767 </lalLaTeX> */
00768 
00769 
00770 #ifndef _LALSTATUSMACROS_H
00771 #define _LALSTATUSMACROS_H
00772 
00773 #include <lal/LALConfig.h>
00774 #ifdef NDEBUG 
00775 #ifndef LAL_NDEBUG
00776 #define LAL_NDEBUG
00777 #endif
00778 #endif
00779 
00780 #include <stdlib.h>
00781 #include <string.h>
00782 
00783 #include <lal/LALMalloc.h>
00784 #include <lal/LALDatatypes.h>
00785 #include <lal/LALError.h>
00786 #include <lal/LALRCSID.h>
00787 
00788 #ifdef  __cplusplus
00789 extern "C" {
00790 #endif
00791 
00792 
00793 NRCSID (LALSTATUSMACROSH, "$Id: LALStatusMacros.h,v 1.25 2007/06/08 14:41:52 bema Exp $");
00794 
00795 extern int lalDebugLevel;
00796 extern const int lalNoDebug;
00797 
00798 #define LAL_EXLAL     16384
00799 #define LAL_MSGEXLAL  "Failure in an XLAL routine"
00800 #define ABORTXLAL(sp) ABORT(sp,LAL_EXLAL,LAL_MSGEXLAL)
00801 
00802 #ifndef NOLALMACROS
00803 
00804 #define INITSTATUS( statusptr, funcname, id )                                 \
00805   if ( (statusptr) )                                                          \
00806   {                                                                           \
00807     INT4 level_ = (statusptr)->level ;                                        \
00808     INT4 statp_ = (statusptr)->statusPtr ? 1 : 0 ;                            \
00809     memset( (statusptr), 0, sizeof( LALStatus ) ); /* possible memory leak */ 00810     (statusptr)->level    = level_ > 0 ? level_ : 1 ;                         00811     (statusptr)->Id       = (id);                                             00812     (statusptr)->function = (funcname);                                       00813     SETSTATUSFILELINE( statusptr );                                           00814     (void) LALTrace( statusptr, 0 );                                          00815     if ( statp_ )                                                              00816     {                                                                         00817       ABORT( statusptr, -2, "INITSTATUS: non-null status pointer" );          00818     }                                                                         00819     else if ( xlalErrno )                                                     00820     {                                                                         00821       ABORT( statusptr, -16, "INITSTATUS: non-zero xlalErrno" );              00822     }                                                                         00823   }                                                                           00824   else                                                                        00825     lalAbortHook( "Abort: function %s, file %s, line %d, %s\n"                00826                   "       Null status pointer passed to function\n",          00827                   (funcname), __FILE__, __LINE__, (id) )
00828 
00829 #define RETURN( statusptr )                                                   \
00830   if ( 1 )                                                                    \
00831   {                                                                           \
00832     SETSTATUSFILELINE( statusptr );                                           \
00833     if ( (statusptr)->statusCode )                                            \
00834       (void) LALError( statusptr, "RETURN:" );                                \
00835     (void) LALTrace( statusptr, 1 );                                          \
00836     if ( xlalErrno )                                                          \
00837     {                                                                         \
00838       ABORT( statusptr, -32, "RETURN: untrapped XLAL error" );                \
00839     }                                                                         \
00840     return;                                                                   \
00841   }                                                                           \
00842   else (void)(0)
00843 
00844 #define ATTATCHSTATUSPTR(statusptr)                                           \
00845   if ( !(statusptr)->statusPtr )                                              \
00846   {                                                                           \
00847     (statusptr)->statusPtr = (LALStatus *)LALCalloc( 1, sizeof( LALStatus ) );\
00848     if ( !(statusptr)->statusPtr )                                            \
00849     {                                                                         \
00850       ABORT( statusptr, -4, "ATTATCHSTATUSPTR: memory allocation error" );    \
00851     }                                                                         \
00852     (statusptr)->statusPtr->level = (statusptr)->level + 1;                   \
00853   }                                                                           \
00854   else                                                                        \
00855     ABORT( statusptr, -2, "ATTATCHSTATUSPTR: non-null status pointer" )
00856 
00857 #define DETATCHSTATUSPTR( statusptr )                                         \
00858   if ( (statusptr)->statusPtr )                                               \
00859   {                                                                           \
00860     FREESTATUSPTR( statusptr );                                               \
00861     (statusptr)->statusCode = 0;                                              \
00862     (statusptr)->statusDescription = NULL;                                    \
00863   }                                                                           \
00864   else                                                                        \
00865     ABORT( statusptr, -8, "DETATCHSTATUSPTR: null status pointer" )
00866 
00867 #define ABORT( statusptr, code, mesg )                                        \
00868   if ( 1 )                                                                    \
00869   {                                                                           \
00870     if ( statusptr->statusPtr ) FREESTATUSPTR( statusptr );                   \
00871     SETSTATUS( statusptr, code, mesg );                                       \
00872     if ( code )                                                               \
00873       (void) LALError( statusptr, "ABORT:" );                                 \
00874     (void) LALTrace( statusptr, 1 );                                          \
00875     return;                                                                   \
00876   }                                                                           \
00877   else (void)(0)
00878 
00879 #ifdef LAL_NDEBUG
00880 #define ASSERT( assertion, statusptr, code, mesg )
00881 #else
00882 #define ASSERT( assertion, statusptr, code, mesg )                            \
00883   if ( !(assertion) )                                                         \
00884   {                                                                           \
00885     if ( statusptr->statusPtr )                                               \
00886       FREESTATUSPTR( statusptr );                                             \
00887     SETSTATUS( statusptr, code, mesg );                                       \
00888     (void) LALError( statusptr, "Assertion \"" #assertion "\" failed:" );     \
00889     (void) LALTrace( statusptr, 1 );                                          \
00890     return;                                                                   \
00891   }                                                                           \
00892   else (void)(0)
00893 #endif
00894 
00895 #define TRY( func, statusptr )                                                \
00896   if ( (func), (statusptr)->statusPtr->statusCode )                           \
00897   {                                                                           \
00898     SETSTATUS( statusptr, -1, "Recursive error" );                            \
00899     (void) LALError( statusptr, "Function call \"" #func "\" failed:" );      \
00900     (void) LALTrace( statusptr, 1 );                                          \
00901     return;                                                                   \
00902   }                                                                           \
00903   else (void)(0)
00904 
00905 #define CHECKSTATUSPTR( statusptr )                                           \
00906   if ( (statusptr)->statusPtr->statusCode )                                   \
00907   {                                                                           \
00908     SETSTATUS( statusptr, -1, "Recursive error" );                            \
00909     (void) LALError( statusptr, "CHECKSTATUSPTR:" );                          \
00910     (void) LALTrace( statusptr, 1 );                                          \
00911     return;                                                                   \
00912   }                                                                           \
00913   else (void)(0)
00914 
00915 #define FREESTATUSPTR( statusptr )                                            \
00916   do                                                                          \
00917   {                                                                           \
00918     LALStatus *next_ = (statusptr)->statusPtr->statusPtr;                      \
00919     LALFree( (statusptr)->statusPtr );                                        \
00920     (statusptr)->statusPtr = next_;                                            \
00921   }                                                                           \
00922   while ( (statusptr)->statusPtr )
00923 
00924 #define REPORTSTATUS( statusptr )                                             \
00925   do                                                                          \
00926   {                                                                           \
00927     LALStatus *ptr_;                                                          \
00928     for ( ptr_ = (statusptr); ptr_; ptr_ = ptr_->statusPtr )                  \
00929     {                                                                         \
00930       LALPrintError( "\nLevel %i: %s\n", ptr_->level, ptr_->Id );             \
00931       if ( ptr_->statusCode )                                                 \
00932       {                                                                       \
00933         LALPrintError( "\tStatus code %i: %s\n", ptr_->statusCode,            \
00934                        ptr_->statusDescription );                             \
00935       }                                                                       \
00936       else                                                                    \
00937       {                                                                       \
00938         LALPrintError( "\tStatus code 0: Nominal\n" );                        \
00939       }                                                                       \
00940       LALPrintError( "\tfunction %s, file %s, line %i\n",                     \
00941                      ptr_->function, ptr_->file, ptr_->line );                \
00942     }                                                                         \
00943   } while ( 0 )
00944 
00945 #else /* NOLALMACROS */
00946 
00947 #define INITSTATUS( statusptr, funcname, id ) \
00948   if ( LALInitStatus( statusptr, funcname, id, __FILE__, __LINE__ ) ) return
00949 
00950 #define RETURN( statusptr ) \
00951   if ( LALPrepareReturn( statusptr, __FILE__, __LINE__ ), 1 ) return
00952 
00953 #define ATTATCHSTATUSPTR( statusptr ) \
00954   if ( LALAttatchStatusPtr( statusptr, __FILE__, __LINE__ ) ) return
00955 
00956 #define DETATCHSTATUSPTR( statusptr ) \
00957   if ( LALDetatchStatusPtr( statusptr, __FILE__, __LINE__ ) ) return
00958 
00959 #define ABORT( statusptr, code, mesg ) \
00960   if ( LALPrepareAbort( statusptr, code, mesg, __FILE__, __LINE__ ), 1 ) return
00961 
00962 #ifdef LAL_NDEBUG
00963 #define ASSERT( assertion, statusptr, code, mesg )
00964 #else
00965 #define ASSERT( assertion, statusptr, code, mesg )                            \
00966   if ( !(assertion) )                                                         \
00967   {                                                                           \
00968     LALPrepareAssertFail( statusptr, code, mesg,                              \
00969                           "Assertion \"" #assertion "\" failed:",             \
00970                           __FILE__, __LINE__ );                               \
00971     return;                                                                   \
00972   }                                                                           \
00973   else (void)(0)
00974 #endif
00975 
00976 #define TRY( func, statusptr )                                                \
00977   do                                                                          \
00978   {                                                                           \
00979     (func);                                                                   \
00980     if ( LALCheckStatusPtr( statusptr, "Function call \"" #func "\" failed:", \
00981                             __FILE__, __LINE__ ) )                            \
00982       return;                                                                 \
00983   }                                                                           \
00984   while ( 0 )
00985 
00986 #define CHECKSTATUSPTR( statusptr )                                           \
00987   if ( LALCheckStatusPtr( statusptr, "CHECKSTATUSPTR:", __FILE__, __LINE__ ) )\
00988     return
00989   
00990 #endif /* NOLALMACROS */
00991 
00992 /* these just have to be macros... */
00993 
00994 #define BEGINFAIL( statusptr )                                                \
00995 do {                                                                          \
00996   if ( !(statusptr) ) {                                                       \
00997     ABORT( statusptr, -8, "BEGINFAIL: null status pointer" );                 \
00998   }                                                                           \
00999   if ( !( (statusptr)->statusPtr ) ) {                                        \
01000     ABORT( statusptr, -8, "BEGINFAIL: null status pointer pointer" );         \
01001   }                                                                           \
01002   if ( (statusptr)->statusPtr->statusCode ) {                                 \
01003     LALStatus *statusPtrSave_ = (statusptr)->statusPtr;                       \
01004     (statusptr)->statusPtr = NULL;                                            \
01005     ATTATCHSTATUSPTR( statusptr );                                            \
01006     do
01007 
01008 #define ENDFAIL( statusptr )                                                  \
01009     while ( 0 );                                                              \
01010     DETATCHSTATUSPTR( statusptr );                                            \
01011     (statusptr)->statusPtr = statusPtrSave_;                                  \
01012     SETSTATUS( statusptr, -1, "Recursive error" );                            \
01013     (void) LALError( statusptr, "ENDFAIL:" );                                 \
01014     (void) LALTrace( statusptr, 1 );                                          \
01015     return;                                                                   \
01016   }                                                                           \
01017 } while ( 0 )
01018 
01019 #define SETSTATUSFILELINE( statusptr ) \
01020   ( ( void ) ( (statusptr)->file = __FILE__, (statusptr)->line = __LINE__ ) )
01021 
01022 #define SETSTATUS( statusptr, code, mesg )                                    \
01023   ( SETSTATUSFILELINE( statusptr ),                                           \
01024     (statusptr)->statusDescription = (mesg),                                  \
01025     (statusptr)->statusCode = (code) )
01026 
01027 
01028 #ifdef  __cplusplus
01029 }
01030 #endif
01031 
01032 #endif /* _LALSTATUSMACROS_H */

Generated on Thu Aug 28 03:12:31 2008 for LAL by  doxygen 1.5.2