/**
\addtogroup lalapps_general

Several utilities (macros, global variables, and functions) are provided to
assist in writing programs in LALApps, and for maintaining a standard
look-and-feel.  This chapter describes these utilities and concludes with
the listing of an example program.

## Header lalapps.h

Provides utilities for writing programs for LALApps.

Several macros, global variables, and function prototypes are given that will
assist in writing LALApps programs, and will aid in maintaining a standard
look-and-feel.

To use these utilities, include the header \ref lalapps.h and make sure the
program links to the object <tt>lalapps.o</tt>.

### Function <tt>clear_status</tt>

<dl>

<dt>Name</dt><dd>
\c clear_status --- clears the LAL status structure after a failed LAL
function call</dd>

<dt>Synopsis</dt><dd>
\code
#include <lalapps.h>
extern const LALStatus blank_status;
int clear_status( LALStatus *status );
\endcode</dd>

<dt>Description</dt><dd>
Clears the LAL status structure and iteratively frees attatched (sic) any
linked status structures.  This is to be used after a failed LAL function
call to restore the status structure to a useable form.  The structure
\c blank_status contains a blank status structure that can be used to
initialize a status structure in the program.</dd>

<dt>Example</dt><dd>

The following program calls a routine \c LALFailUnlessNegative twice,
once with a positive argument (which causes the routine to fail) and once
with a negative argument (which causes the routine to pass).  The function
\c clear_status is used to clean up the status structure after the
failure and the constant structure \c blank_status is used to initialize
the status structure.

\code
#include <lalapps.h>
#include <lal/LALStdlib.h>

extern const LALStatus blank_status;

void LALFailUnlessNegative( LALStatus *status, INT4 n )
{
  INITSTATUS( status, "LALFail", "$Id$" );
  ATTATCHSTATUSPTR( status );
  ASSERT( n, status, 1, "Non-negative n" );
  if ( n > 0 )
  {
    TRY( LALFailUnlessNegative( status->statusPtr, n - 1 ), status );
  }
  DETATCHSTATUSPTR( status );
  RETURN( status );
}

int main( void )
{
  LALStatus status = blank_status;
  LALFailUnlessNegative( &status, 5 );
  clear_status( &status );
  LALFailUnlessNegative( &status, -2 );
  return status.statusCode;
}
\endcode
</dd>
</dl>

### Macro <tt>PRINT_VERSION</tt>

<dl>

<dt>Name</dt><dd>
\c PRINT_VERSION --- prints the LALApps version of the program</dd>

<dt>Synopsis</dt><dd>
\code
#include <lalapps.h>
static volatile const char *rcsid="$Id$";
#ifndef PRINT_VERSION
#define PRINT_VERSION( program ) \
  fprintf( stderr, PACKAGE "
#endif
\endcode</dd>

<dt>Description</dt><dd>
\c PRINT_VERSION prints the version information for \c program in a
standard format, along with the RCS Id information. Note that
\c PRINT_VERSION requires the string variable \c rcsid to be
set.</dd>

</dl>

### Macro <tt>LAL_CALL</tt>

Error Handler

<dl>

<dt>Name</dt><dd>
\c LAL_CALL --- call a LAL routine and handle any errors</dd>

<dt>Synopsis</dt><dd>
\code
#include <lalapps.h>

extern int vrblvl;
extern int ( *lal_errhandler )( LALStatus *stat, const char *func,
    const char *file, const int line, volatile const char *id );
extern lal_errhandler_t lal_errhandler;

static volatile const char *rcsid="$Id$";

#ifndef LAL_CALL
#define LAL_CALL( function, statusptr ) \
  ((function),lal_errhandler(statusptr,#function,__FILE__,__LINE__,rcsid))
#endif
\endcode</dd>

<dt>Description</dt><dd>
\c LAL_CALL executes the LAL function \c function and executes the
error handler \c lal_errhandler, which examines the status structure
\c statusptr to see if an error occurred.  Typically the error handler
will return with value 0 if there was no error; otherwise it will print a trace
of the execution stack and then perform a specific action.  The action
performed depends on the error handler, which can be set to one of the
following:
<ul>
<li>\c LAL_ERR_DFLT:
  The default error handler (same as \c LAL_ERR_ABRT).</li>
<li>\c LAL_ERR_ABRT:
  Raises \c SIGABRT if there is an error.</li>
<li>\c LAL_ERR_EXIT:
  Exits with the returned status code if there is an error.</li>
<li>\c LAL_ERR_RTRN:
  Returns the status code.</li>
</ul>

Note that \c LAL_CALL requires the string variable \c rcsid to be set.</dd>

<dt>Return Value</dt><dd>
If \c LAL_CALL returns (rather than terminating execution), the return
value is equal to the status code returned by the LAL function.</dd>

<dt>Example</dt><dd>
The following example program illustrates the use of \c LAL_CALL.
The routine \c LALInvert is called incorrectly twice.  The first time
the division by zero error is caught.  The second time, the unexpected null
pointer error is not caught and the default error handler aborts the program.
\code
#include <stdlib.h>
#include <lalapps.h>
#include <lal/LALStdlib.h>

RCSID( "$Id$" );

extern int vrblvl;
extern const LALStatus blank_status;

void LALInvert( LALStatus *status, REAL4 *y, REAL4 x )
{
  INITSTATUS( status, "LALInvert", rcsid );
  ASSERT( y, status, 1, "Null pointer" );
  if ( input == 0 )
  {
    ABORT( status, 1, "Division by zero" );
  }
  *y = 1 / x;
  RETURN( status );
}

int main( void )
{
  LALStatus status = blank_status;
  REAL4 x;
  int code;

  vrblvl = 1;

  lal_errhandler = LAL_ERR_RTRN;
  code = LAL_CALL( LALInvert( &status, &x, 0 ), &status );
  if ( code == 2 )
  {
    puts( "division by zero" );
    clear_status( &status );
  }
  else if ( code )
  {
    exit( code );
  }

  lal_errhandler = LAL_ERR_DFLT;
  LAL_CALL( LALInvert( &status, NULL, 1 ), &status );

  return 0;
}
\endcode
</dd>
</dl>

*/
