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 */
1.5.2