00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <math.h>
00030 #include <stdio.h>
00031 #include <stdarg.h>
00032 #include <stdlib.h>
00033 #include <lal/XLALError.h>
00034 #include <lal/LALStdlib.h>
00035
00036 NRCSID( XLALERRORC, "$Id: XLALError.c,v 1.13 2008/04/24 17:04:21 kipp Exp $" );
00037
00038
00039
00040
00041
00042
00043
00044
00045 int XLALPrintError( const char *fmt, ... )
00046 {
00047 int n = 0;
00048 if ( lalDebugLevel & LALERROR )
00049 {
00050 va_list ap;
00051 va_start( ap, fmt );
00052 n = vfprintf( stderr, fmt, ap );
00053 va_end( ap );
00054 }
00055 return n;
00056 }
00057
00058
00059 int XLALPrintWarning( const char *fmt, ... )
00060 {
00061 int n = 0;
00062 if ( lalDebugLevel & LALWARNING )
00063 {
00064 va_list ap;
00065 va_start( ap, fmt );
00066 n = vfprintf( stderr, fmt, ap );
00067 va_end( ap );
00068 }
00069 return n;
00070 }
00071
00072
00073 int XLALPrintInfo( const char *fmt, ... )
00074 {
00075 int n = 0;
00076 if ( lalDebugLevel & LALINFO )
00077 {
00078 va_list ap;
00079 va_start( ap, fmt );
00080 n = vfprintf( stderr, fmt, ap );
00081 va_end( ap );
00082 }
00083 return n;
00084 }
00085
00086
00087
00088
00089
00090 int XLALPrintProgressBar( double fraction )
00091 {
00092 static const char mrk[] = "+++++++++++++++++++++++++++++++++++++++++++++++++)";
00093 static const char spc[] = "-------------------------------------------------)";
00094 int l = sizeof(mrk)/sizeof(*mrk) - 1;
00095 int offset = floor((fraction < 0.0 ? 0.0 : fraction > 1.0 ? 1.0 : fraction) * l + 0.5);
00096
00097 return XLALPrintInfo("[%s%s %.1f%%", mrk + l - offset, spc + offset, 100.0 * fraction);
00098 }
00099
00100
00101
00102
00103
00104 int XLALPrintDeprecationWarning( const char *old, const char *replacement )
00105 {
00106 return XLALPrintWarning("DEPRECATION WARNING: program has invoked obsolete function %s(). Please see %s() for information about a replacement.\n", old, replacement);
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 #ifndef LAL_PTHREAD_LOCK
00118
00119
00120 int xlalErrnoGlobal = 0;
00121
00122
00123 int * XLALGetErrnoPtr( void )
00124 {
00125 return &xlalErrnoGlobal;
00126 }
00127
00128
00129 XLALErrorHandlerType *xlalErrorHandlerGlobal = NULL;
00130
00131
00132 XLALErrorHandlerType ** XLALGetErrorHandlerPtr( void )
00133 {
00134 return &xlalErrorHandlerGlobal;
00135 }
00136
00137 #else
00138
00139
00140
00141
00142
00143
00144 #include <unistd.h>
00145 #include <pthread.h>
00146
00147 pthread_key_t xlalErrnoKey;
00148 pthread_once_t xlalErrnoKeyOnce = PTHREAD_ONCE_INIT;
00149 pthread_key_t xlalErrorHandlerKey;
00150 pthread_once_t xlalErrorHandlerKeyOnce = PTHREAD_ONCE_INIT;
00151
00152
00153 static void XLALDestroyErrnoPtr( void *xlalErrnoPtr )
00154 {
00155 free( xlalErrnoPtr );
00156 return;
00157 }
00158
00159
00160 static void XLALDestroyErrorHandlerPtr( void *xlalErrorHandlerPtr )
00161 {
00162 free( xlalErrorHandlerPtr );
00163 return;
00164 }
00165
00166
00167 static void XLALCreateErrnoKey( void )
00168 {
00169 pthread_key_create( &xlalErrnoKey, XLALDestroyErrnoPtr );
00170 return;
00171 }
00172
00173
00174 static void XLALCreateErrorHandlerKey( void )
00175 {
00176 pthread_key_create( &xlalErrorHandlerKey, XLALDestroyErrorHandlerPtr );
00177 return;
00178 }
00179
00180
00181 int * XLALGetErrnoPtr( void )
00182 {
00183 int *xlalErrnoPtr;
00184
00185
00186 pthread_once( &xlalErrnoKeyOnce, XLALCreateErrnoKey );
00187
00188
00189 xlalErrnoPtr = pthread_getspecific( xlalErrnoKey );
00190 if ( ! xlalErrnoPtr )
00191 {
00192 xlalErrnoPtr = malloc( sizeof( *xlalErrnoPtr ) );
00193 if ( ! xlalErrnoPtr )
00194 lalAbortHook( "could not set xlal error number: malloc failed\n" );
00195 *xlalErrnoPtr = 0;
00196
00197 if ( pthread_setspecific( xlalErrnoKey, xlalErrnoPtr ) )
00198 lalAbortHook( "could not set xlal error number: pthread_setspecific failed\n" );
00199 }
00200 return xlalErrnoPtr;
00201 }
00202
00203
00204 XLALErrorHandlerType ** XLALGetErrorHandlerPtr( void )
00205 {
00206 XLALErrorHandlerType **xlalErrorHandlerPtr;
00207
00208
00209 pthread_once( &xlalErrorHandlerKeyOnce, XLALCreateErrorHandlerKey );
00210
00211
00212 xlalErrorHandlerPtr = pthread_getspecific( xlalErrorHandlerKey );
00213 if ( ! xlalErrorHandlerPtr )
00214 {
00215 xlalErrorHandlerPtr = malloc( sizeof( *xlalErrorHandlerPtr ) );
00216 if ( ! xlalErrorHandlerPtr )
00217 lalAbortHook( "could not set xlal error handler: malloc failed\n" );
00218 *xlalErrorHandlerPtr = NULL;
00219
00220 if ( pthread_setspecific( xlalErrorHandlerKey, xlalErrorHandlerPtr ) )
00221 lalAbortHook( "could not set xlal error handler: pthread_setspecific failed\n" );
00222 }
00223 return xlalErrorHandlerPtr;
00224 }
00225
00226 #endif
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 int XLALSetErrno( int errnum )
00238 {
00239 if ( errnum == 0 )
00240 {
00241 xlalErrno = 0;
00242 return xlalErrno;
00243 }
00244
00245
00246
00247 if ( errnum & XLAL_EFUNC )
00248 {
00249 xlalErrno |= XLAL_EFUNC;
00250 return xlalErrno;
00251 }
00252
00253
00254 if ( xlalErrno )
00255 XLALPrintWarning( "XLAL Warning - XLALSetErrno: "
00256 "Ignoring previous error (xlalErrno=%d) %s\n",
00257 xlalErrno, XLALErrorString( xlalErrno ) );
00258 xlalErrno = errnum;
00259 return xlalErrno;
00260 }
00261
00262
00263
00264 int XLALGetBaseErrno( void )
00265 {
00266 return xlalErrno & ~XLAL_EFUNC;
00267 }
00268
00269
00270
00271 int XLALClearErrno( void )
00272 {
00273 int olderrno = xlalErrno;
00274 xlalErrno = 0;
00275 return olderrno;
00276 }
00277
00278
00279
00280 XLALErrorHandlerType * XLALSetErrorHandler( XLALErrorHandlerType *newHandler )
00281 {
00282 XLALErrorHandlerType *oldHandler;
00283 oldHandler = XLALErrorHandler;
00284 XLALErrorHandler = newHandler;
00285 return oldHandler;
00286 }
00287
00288
00289
00290 XLALErrorHandlerType * XLALSetDefaultErrorHandler( void )
00291 {
00292 XLALErrorHandlerType *oldHandler;
00293 oldHandler = XLALErrorHandler;
00294 XLALErrorHandler = XLALDefaultErrorHandler;
00295 return oldHandler;
00296 }
00297
00298
00299 XLALErrorHandlerType * XLALSetSilentErrorHandler( void )
00300 {
00301 XLALErrorHandlerType *oldHandler;
00302 oldHandler = XLALErrorHandler;
00303 XLALErrorHandler = XLALSilentErrorHandler;
00304 return oldHandler;
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 const char * XLALErrorString( int code )
00317 {
00318
00319 if ( code <= 0 )
00320 {
00321 if ( code == 0 )
00322 return "Success";
00323 else if ( code == -1 )
00324 return "Failure";
00325 else
00326 return "Unknown return code";
00327 }
00328
00329
00330
00331 if ( code == XLAL_EFUNC )
00332 return "Internal function call failed";
00333
00334
00335
00336 # define XLAL_ERROR_STRING(s) \
00337 ( ( code & XLAL_EFUNC ) ? "Internal function call failed: " s : s )
00338 switch ( code & ~XLAL_EFUNC )
00339 {
00340
00341 case XLAL_EIO:
00342 return XLAL_ERROR_STRING( "I/O error" );
00343 case XLAL_ENOMEM:
00344 return XLAL_ERROR_STRING( "Memory allocation error" );
00345 case XLAL_EFAULT:
00346 return XLAL_ERROR_STRING( "Invalid pointer" );
00347 case XLAL_EINVAL:
00348 return XLAL_ERROR_STRING( "Invalid argument" );
00349 case XLAL_EDOM:
00350 return XLAL_ERROR_STRING( "Input domain error" );
00351 case XLAL_ERANGE:
00352 return XLAL_ERROR_STRING( "Output range error" );
00353
00354
00355
00356
00357 case XLAL_EFAILED:
00358 return XLAL_ERROR_STRING( "Generic failure" );
00359 case XLAL_EBADLEN:
00360 return XLAL_ERROR_STRING( "Inconsistent or invalid vector length" );
00361 case XLAL_ESIZE:
00362 return XLAL_ERROR_STRING( "Wrong size" );
00363 case XLAL_EDIMS:
00364 return XLAL_ERROR_STRING( "Wrong dimensions" );
00365 case XLAL_ETYPE:
00366 return XLAL_ERROR_STRING( "Wrong or unknown type" );
00367 case XLAL_ETIME:
00368 return XLAL_ERROR_STRING( "Invalid time" );
00369 case XLAL_EFREQ:
00370 return XLAL_ERROR_STRING( "Invalid freqency" );
00371 case XLAL_EUNIT:
00372 return XLAL_ERROR_STRING( "Invalid units" );
00373 case XLAL_ENAME:
00374 return XLAL_ERROR_STRING( "Wrong name" );
00375 case XLAL_EDATA:
00376 return XLAL_ERROR_STRING( "Invalid data" );
00377
00378
00379 case XLAL_EUSR0:
00380 return XLAL_ERROR_STRING( "User-defined error 0" );
00381 case XLAL_EUSR1:
00382 return XLAL_ERROR_STRING( "User-defined error 1" );
00383 case XLAL_EUSR2:
00384 return XLAL_ERROR_STRING( "User-defined error 2" );
00385 case XLAL_EUSR3:
00386 return XLAL_ERROR_STRING( "User-defined error 3" );
00387 case XLAL_EUSR4:
00388 return XLAL_ERROR_STRING( "User-defined error 4" );
00389 case XLAL_EUSR5:
00390 return XLAL_ERROR_STRING( "User-defined error 5" );
00391 case XLAL_EUSR6:
00392 return XLAL_ERROR_STRING( "User-defined error 6" );
00393 case XLAL_EUSR7:
00394 return XLAL_ERROR_STRING( "User-defined error 7" );
00395 case XLAL_EUSR8:
00396 return XLAL_ERROR_STRING( "User-defined error 8" );
00397 case XLAL_EUSR9:
00398 return XLAL_ERROR_STRING( "User-defined error 9" );
00399
00400
00401 case XLAL_ESYS:
00402 return XLAL_ERROR_STRING( "System error" );
00403 case XLAL_EERR:
00404 return XLAL_ERROR_STRING( "Internal error" );
00405
00406
00407
00408
00409 case XLAL_EFPINVAL:
00410 return XLAL_ERROR_STRING( "Invalid floating point operation, eg sqrt(-1), 0/0" );
00411 case XLAL_EFPDIV0:
00412 return XLAL_ERROR_STRING( "Division by zero floating point error" );
00413 case XLAL_EFPOVRFLW:
00414 return XLAL_ERROR_STRING( "Floating point overflow error" );
00415 case XLAL_EFPUNDFLW:
00416 return XLAL_ERROR_STRING( "Floating point underflow error" );
00417 case XLAL_EFPINEXCT:
00418 return XLAL_ERROR_STRING( "Floating point inexact error" );
00419
00420
00421 case XLAL_EMAXITER:
00422 return XLAL_ERROR_STRING( "Exceeded maximum number of iterations" );
00423 case XLAL_EDIVERGE:
00424 return XLAL_ERROR_STRING( "Series is diverging" );
00425 case XLAL_ESING:
00426 return XLAL_ERROR_STRING( "Apparent singularity detected" );
00427 case XLAL_ETOL:
00428 return XLAL_ERROR_STRING( "Failed to reach specified tolerance" );
00429 case XLAL_ELOSS:
00430 return XLAL_ERROR_STRING( "Loss of accuracy" );
00431
00432
00433 default:
00434 return "Unknown error";
00435 }
00436 # undef XLAL_ERROR_STRING
00437 return NULL;
00438 }
00439
00440
00441 void XLALPerror( const char *func, const char *file, int line, int code )
00442 {
00443 if ( code > 0 )
00444 XLALPrintError( "XLAL Error" );
00445 else
00446 XLALPrintError( "XLAL Result" );
00447 if ( func && *func )
00448 XLALPrintError( " - %s", func );
00449 if ( file && *file )
00450 XLALPrintError( " (%s:%d)", file, line );
00451 XLALPrintError( ": " );
00452 XLALPrintError( XLALErrorString( code ) );
00453 XLALPrintError( "\n" );
00454 return;
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 void XLALDefaultErrorHandler( const char *func, const char *file, int line, int errnum )
00466 {
00467 XLALPerror( func, file, line, errnum );
00468 return;
00469 }
00470
00471
00472 void XLALSilentErrorHandler( const char *func, const char *file, int line, int errnum )
00473 {
00474 func = NULL;
00475 file = NULL;
00476 line = 0;
00477 errnum = 0;
00478 return;
00479 }
00480
00481
00482
00483
00484
00485
00486
00487 void XLALError( const char *func, const char *file, int line, int errnum )
00488 {
00489 XLALSetErrno( errnum );
00490 if ( ! XLALErrorHandler )
00491 XLALErrorHandler = XLALDefaultErrorHandler;
00492 XLALErrorHandler( func, file, line, xlalErrno );
00493 return;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 void XLALAbortErrorHandler( const char *func, const char *file, int line,
00505 int errnum )
00506 {
00507 XLALPerror( func, file, line, errnum );
00508 abort();
00509 }
00510
00511
00512 void XLALExitErrorHandler( const char *func, const char *file, int line,
00513 int errnum )
00514 {
00515 XLALPerror( func, file, line, errnum );
00516 exit(1);
00517 }
00518
00519 static int print_stack(void);
00520
00521 void XLALBacktraceErrorHandler( const char *func, const char *file, int line,
00522 int errnum )
00523 {
00524 XLALPerror( func, file, line, errnum );
00525 print_stack();
00526 abort();
00527 }
00528
00529
00530
00531
00532
00533
00534 #ifdef __GNUC__
00535
00536 #if defined(__DARWIN_UNIX03) || defined(__GLIBC__)
00537
00538 #define LEVELMAX 0100
00539
00540 #if defined(__GLIBC__)
00541
00542
00543 #include <execinfo.h>
00544
00545 static int print_stack( void )
00546 {
00547 void *array[LEVELMAX];
00548 size_t size;
00549 size = backtrace( array, LEVELMAX );
00550 fprintf( stderr, "Call list:\n" );
00551 backtrace_symbols_fd( array, size, fileno( stderr ) );
00552 return 0;
00553 }
00554
00555 #else
00556
00557
00558
00559
00560 #ifdef __GLIBC__
00561 #define __USE_GNU
00562 #endif
00563 #include <dlfcn.h>
00564
00565 #define get_return_address(addr,level) \
00566 do switch (level) { \
00567 case 000: addr = __builtin_frame_address(000) ? __builtin_return_address(000) : NULL; break; \
00568 case 001: addr = __builtin_frame_address(001) ? __builtin_return_address(001) : NULL; break; \
00569 case 002: addr = __builtin_frame_address(002) ? __builtin_return_address(002) : NULL; break; \
00570 case 003: addr = __builtin_frame_address(003) ? __builtin_return_address(003) : NULL; break; \
00571 case 004: addr = __builtin_frame_address(004) ? __builtin_return_address(004) : NULL; break; \
00572 case 005: addr = __builtin_frame_address(005) ? __builtin_return_address(005) : NULL; break; \
00573 case 006: addr = __builtin_frame_address(006) ? __builtin_return_address(006) : NULL; break; \
00574 case 007: addr = __builtin_frame_address(007) ? __builtin_return_address(007) : NULL; break; \
00575 case 010: addr = __builtin_frame_address(010) ? __builtin_return_address(010) : NULL; break; \
00576 case 011: addr = __builtin_frame_address(011) ? __builtin_return_address(011) : NULL; break; \
00577 case 012: addr = __builtin_frame_address(012) ? __builtin_return_address(012) : NULL; break; \
00578 case 013: addr = __builtin_frame_address(013) ? __builtin_return_address(013) : NULL; break; \
00579 case 014: addr = __builtin_frame_address(014) ? __builtin_return_address(014) : NULL; break; \
00580 case 015: addr = __builtin_frame_address(015) ? __builtin_return_address(015) : NULL; break; \
00581 case 016: addr = __builtin_frame_address(016) ? __builtin_return_address(016) : NULL; break; \
00582 case 017: addr = __builtin_frame_address(017) ? __builtin_return_address(017) : NULL; break; \
00583 case 020: addr = __builtin_frame_address(020) ? __builtin_return_address(020) : NULL; break; \
00584 case 021: addr = __builtin_frame_address(021) ? __builtin_return_address(021) : NULL; break; \
00585 case 022: addr = __builtin_frame_address(022) ? __builtin_return_address(022) : NULL; break; \
00586 case 023: addr = __builtin_frame_address(023) ? __builtin_return_address(023) : NULL; break; \
00587 case 024: addr = __builtin_frame_address(024) ? __builtin_return_address(024) : NULL; break; \
00588 case 025: addr = __builtin_frame_address(025) ? __builtin_return_address(025) : NULL; break; \
00589 case 026: addr = __builtin_frame_address(026) ? __builtin_return_address(026) : NULL; break; \
00590 case 027: addr = __builtin_frame_address(027) ? __builtin_return_address(027) : NULL; break; \
00591 case 030: addr = __builtin_frame_address(030) ? __builtin_return_address(030) : NULL; break; \
00592 case 031: addr = __builtin_frame_address(031) ? __builtin_return_address(031) : NULL; break; \
00593 case 032: addr = __builtin_frame_address(032) ? __builtin_return_address(032) : NULL; break; \
00594 case 033: addr = __builtin_frame_address(033) ? __builtin_return_address(033) : NULL; break; \
00595 case 034: addr = __builtin_frame_address(034) ? __builtin_return_address(034) : NULL; break; \
00596 case 035: addr = __builtin_frame_address(035) ? __builtin_return_address(035) : NULL; break; \
00597 case 036: addr = __builtin_frame_address(036) ? __builtin_return_address(036) : NULL; break; \
00598 case 037: addr = __builtin_frame_address(037) ? __builtin_return_address(037) : NULL; break; \
00599 case 040: addr = __builtin_frame_address(040) ? __builtin_return_address(040) : NULL; break; \
00600 case 041: addr = __builtin_frame_address(041) ? __builtin_return_address(041) : NULL; break; \
00601 case 042: addr = __builtin_frame_address(042) ? __builtin_return_address(042) : NULL; break; \
00602 case 043: addr = __builtin_frame_address(043) ? __builtin_return_address(043) : NULL; break; \
00603 case 044: addr = __builtin_frame_address(044) ? __builtin_return_address(044) : NULL; break; \
00604 case 045: addr = __builtin_frame_address(045) ? __builtin_return_address(045) : NULL; break; \
00605 case 046: addr = __builtin_frame_address(046) ? __builtin_return_address(046) : NULL; break; \
00606 case 047: addr = __builtin_frame_address(047) ? __builtin_return_address(047) : NULL; break; \
00607 case 050: addr = __builtin_frame_address(050) ? __builtin_return_address(050) : NULL; break; \
00608 case 051: addr = __builtin_frame_address(051) ? __builtin_return_address(051) : NULL; break; \
00609 case 052: addr = __builtin_frame_address(052) ? __builtin_return_address(052) : NULL; break; \
00610 case 053: addr = __builtin_frame_address(053) ? __builtin_return_address(053) : NULL; break; \
00611 case 054: addr = __builtin_frame_address(054) ? __builtin_return_address(054) : NULL; break; \
00612 case 055: addr = __builtin_frame_address(055) ? __builtin_return_address(055) : NULL; break; \
00613 case 056: addr = __builtin_frame_address(056) ? __builtin_return_address(056) : NULL; break; \
00614 case 057: addr = __builtin_frame_address(057) ? __builtin_return_address(057) : NULL; break; \
00615 case 060: addr = __builtin_frame_address(060) ? __builtin_return_address(060) : NULL; break; \
00616 case 061: addr = __builtin_frame_address(061) ? __builtin_return_address(061) : NULL; break; \
00617 case 062: addr = __builtin_frame_address(062) ? __builtin_return_address(062) : NULL; break; \
00618 case 063: addr = __builtin_frame_address(063) ? __builtin_return_address(063) : NULL; break; \
00619 case 064: addr = __builtin_frame_address(064) ? __builtin_return_address(064) : NULL; break; \
00620 case 065: addr = __builtin_frame_address(065) ? __builtin_return_address(065) : NULL; break; \
00621 case 066: addr = __builtin_frame_address(066) ? __builtin_return_address(066) : NULL; break; \
00622 case 067: addr = __builtin_frame_address(067) ? __builtin_return_address(067) : NULL; break; \
00623 case 070: addr = __builtin_frame_address(070) ? __builtin_return_address(070) : NULL; break; \
00624 case 071: addr = __builtin_frame_address(071) ? __builtin_return_address(071) : NULL; break; \
00625 case 072: addr = __builtin_frame_address(072) ? __builtin_return_address(072) : NULL; break; \
00626 case 073: addr = __builtin_frame_address(073) ? __builtin_return_address(073) : NULL; break; \
00627 case 074: addr = __builtin_frame_address(074) ? __builtin_return_address(074) : NULL; break; \
00628 case 075: addr = __builtin_frame_address(075) ? __builtin_return_address(075) : NULL; break; \
00629 case 076: addr = __builtin_frame_address(076) ? __builtin_return_address(076) : NULL; break; \
00630 case 077: addr = __builtin_frame_address(077) ? __builtin_return_address(077) : NULL; break; \
00631 default: addr = NULL; break; \
00632 } while (0)
00633
00634 int print_stack( void )
00635 {
00636 Dl_info info;
00637 int level;
00638 fprintf( stderr, "Call list:\n" );
00639 for ( level = 0; level < LEVELMAX; ++level )
00640 {
00641 void *addr;
00642 get_return_address( addr, level );
00643 if ( ! addr )
00644 break;
00645 dladdr( addr, &info );
00646 fprintf( stderr, "%s(%s+%p)[%p]\n", info.dli_fname, info.dli_sname, (void *)((char *)addr - (char *)info.dli_saddr), addr );
00647 }
00648 return 0;
00649 }
00650
00651 #endif
00652
00653 #else
00654 static int print_stack( void ) { return 0; }
00655 #endif
00656
00657 #else
00658 static int print_stack( void ) { return 0; }
00659 #endif
00660