#define _DEBUGTRACE_MAIN_ #include #include #include "mcw_malloc.h" #ifndef MRILIB_MINI #include "AFNI_version.h" #endif #include "debugtrace.h" /* contains 1 function */ #include #include #include /*--------------------------------------------------------------------------*/ static int colorize_prefix = 0 ; /* use ANSI codes to change prefix colors? */ static FILE *messfp = NULL ; static char *messfn = NULL ; void SET_message_file( char *fname ) { if( messfp != NULL ){ fclose(messfp); messfp = NULL; } if( messfn != NULL ){ free (messfn); messfn = NULL; } { char *eee = getenv("AFNI_USE_ERROR_FILE") ; /* 22 Sep 2015 */ if( eee != NULL && (*eee == 'N' || *eee == 'n') ) return ; } if( fname != NULL && *fname != '\0' ) messfn = strdup(fname) ; return ; } static void fputs_messfp( char *msg ) { if( messfn != NULL && messfp == NULL ) messfp = fopen(messfn,"w") ; if( messfp != NULL ){ fputs(msg,messfp); fflush(messfp); } return ; } /*---------------------------------------------------------------------------*/ /* Originally written for THD_dataset_info(), now used in other places. * Used to write results into an ever-lengthening string. * On the first call, 'sss' should be NULL. It will be malloc()-ed and contain the print-formatted results. * On a subsequent call, 'sss' is the return value from the previous call. * When finally done with it, you can free() the result. * Moved here from thd_info.c on 01 May 2015 by RWCox. *//*-------------------------------------------------------------------------*/ #undef ZMAX #undef SZMAX #define ZMAX 49999 /* increased for Ziad (who else is so crazy?) */ #define SZMAX "%.49999s" /* same as ZMAX */ char * THD_zzprintf( char *sss , char *fmt , ... ) { static char *sbuf = NULL ; /* workspace */ char *zz ; int nzz , nsbuf ; va_list vararg_ptr ; ENTRY("THD_zzprintf") ; va_start( vararg_ptr , fmt ) ; /* first time in ==> create workspace */ if( sbuf == NULL ) sbuf = malloc(sizeof(char)*(ZMAX+90)) ; /* write current stuff into workspace */ sbuf[0] = '\0' ; vsnprintf( sbuf , sizeof(char)*(ZMAX+89) , fmt , vararg_ptr ) ; nsbuf = strlen(sbuf) ; if( nsbuf == 0 ) RETURN(sss) ; /* nothing happened */ if( nsbuf >= ZMAX ){ /* too much happened */ WARNING_message("THD_zzprintf() long string truncation = the ZSS syndrome") ; strcpy(sbuf+ZMAX-4,"...") ; nsbuf = strlen(sbuf) ; } /* make new space, copy input string sss, append new stuff, return result */ if( sss == NULL || *sss == '\0' ){ /* no input string ==> copy new stuff */ zz = (char *) malloc( sizeof(char)*(nsbuf+8) ) ; strcpy(zz,sbuf) ; } else { /* the full Monty: copy old then new */ nzz = strlen(sss) + nsbuf + 8 ; zz = (char *) malloc( sizeof(char) * nzz ) ; strcpy(zz,sss) ; strcat(zz,sbuf) ; free(sss) ; /* don't need input copy any more */ } RETURN(zz) ; } /*--------------------------------------------------------------------------*/ /* Used to write messages into a buffer string rather than stderr */ static int mess_use_outbuf = 0 ; /* 01 May 2015 */ static char *mess_outbuf = NULL ; char * GET_message_outbuf(void){ return mess_outbuf ; } void SET_message_outbuf( int use_outbuf ) { if( use_outbuf == 0 ){ /* turn message buffer string off */ mess_use_outbuf = 0 ; if( mess_outbuf != NULL ) free(mess_outbuf) ; mess_outbuf = NULL ; } else { /* turn it on */ mess_use_outbuf = 1 ; } } /*---------------------------------------------------------------------------*/ /* Write the message to stderr or the message buffer string. If ump != 0, also write it to the message file pointer, if it is open. *//*-------------------------------------------------------------------------*/ static void output_message( int ump, char *prefix, char *fmt, va_list vararg_ptr ) { char *ifmt=NULL,*imsg=NULL , *cfmt=NULL,*cmsg=NULL , *epr=NULL ; int ll ; #ifdef va_copy va_list vararg_cpy ; va_copy(vararg_cpy,vararg_ptr) ; /* for reuse with cfmt and cmsg */ #else colorize_prefix = 0 ; /* can't do this without va_copy (C99 feature) */ #endif if( fmt == NULL || *fmt == '\0' ) return ; /* makes no sense */ if( colorize_prefix ){ epr = getenv("AFNI_MESSAGE_COLORIZE") ; if( epr != NULL && toupper(*epr) == 'N' ) colorize_prefix = 0 ; } if( prefix == NULL || *prefix == '\0' ){ ifmt = fmt ; } else { ifmt = malloc( strlen(prefix)+strlen(fmt)+4 ) ; strcpy(ifmt,prefix) ; strcat(ifmt,fmt) ; if( colorize_prefix && !mess_use_outbuf ){ /* 22 Feb 2016 */ cfmt = malloc( strlen(prefix)+strlen(fmt)+64 ) ; #if 0 strcpy(cfmt,"\033[34;1m\033[43;1m") ; /* blue text on yellow bkgd */ #else strcpy(cfmt,"\033[7m") ; /* inverse colors */ #endif strcat(cfmt,prefix) ; if( prefix[strlen(prefix)-1] == ' ' ) cfmt[strlen(cfmt)-1] = '\0' ; strcat(cfmt,"\033[0m ") ; /* special formatting off */ strcat(cfmt,fmt) ; } } if( mess_use_outbuf || cfmt == NULL || ump ){ ll = strlen(ifmt) ; if( ll < 1024 ) ll = 1024 ; epr = getenv("AFNI_MESSAGE_PREFIX") ; if( epr != NULL ) ll += strlen(epr)+1 ; imsg = malloc(sizeof(char)*16*ll+1) ; imsg[0] = '\0' ; if( epr != NULL ){ strcpy(imsg,epr); strcat(imsg,"::"); } vsprintf(imsg+strlen(imsg),ifmt,vararg_ptr) ; ll = strlen(imsg) ; if( imsg[ll-1] != '\n' ){ imsg[ll] = '\n' ; imsg[ll+1] = '\0' ; } } #ifdef va_copy if( cfmt != NULL ){ ll = strlen(cfmt) ; if( ll < 1024 ) ll = 1024 ; if( epr != NULL ) ll += strlen(epr)+1 ; cmsg = malloc(sizeof(char)*16*ll+1) ; cmsg[0] = '\0' ; if( epr != NULL ){ strcpy(cmsg,epr); strcat(cmsg,"::"); } vsprintf(cmsg+strlen(cmsg),cfmt,vararg_cpy) ; ll = strlen(cmsg) ; if( cmsg[ll-1] != '\n' ){ cmsg[ll] = '\n' ; cmsg[ll+1] = '\0' ; } } #endif if( imsg == NULL && cmsg == NULL ){ /* should never happen */ if( ifmt != NULL ) free(ifmt) ; if( cfmt != NULL ) free(cfmt) ; colorize_prefix = 0 ; return ; } if( !mess_use_outbuf ){ if( cmsg != NULL ) fputs(cmsg,stderr) ; else fputs(imsg,stderr) ; fflush(stderr) ; /* nugatory */ } else { mess_outbuf = THD_zzprintf(mess_outbuf,"%s",imsg) ; /* 01 May 2015 */ } if( ump ) fputs_messfp(imsg) ; /* 12 Mar 2007 */ if( imsg != NULL ) free(imsg) ; /* 03 Mar 2006: forgot the free! */ if( ifmt != fmt ) free(ifmt) ; if( cfmt != NULL ) free(cfmt) ; if( cmsg != NULL ) free(cmsg) ; colorize_prefix = 0 ; return ; } /*--------------------------------------------------------------------------*/ void INFO_message( char *fmt , ... ) { va_list vararg_ptr ; va_start( vararg_ptr , fmt ) ; output_message( 0 , "++ " , fmt , vararg_ptr ) ; va_end( vararg_ptr ) ; return ; } /*--------------------------------------------------------------------------*/ void ININFO_message( char *fmt , ... ) { va_list vararg_ptr ; va_start( vararg_ptr , fmt ) ; output_message( 0 , " + " , fmt , vararg_ptr ) ; va_end( vararg_ptr ) ; return ; } /*--------------------------------------------------------------------------*/ void WARNING_message( char *fmt , ... ) { va_list vararg_ptr ; va_start( vararg_ptr , fmt ) ; colorize_prefix = 1 ; output_message( 1 , "*+ WARNING: " , fmt , vararg_ptr ) ; va_end( vararg_ptr ) ; return ; } /*--------------------------------------------------------------------------*/ void ERROR_message( char *fmt , ... ) { va_list vararg_ptr ; va_start( vararg_ptr , fmt ) ; colorize_prefix = 1 ; output_message( 1 , "** ERROR: " , fmt , vararg_ptr ) ; va_end( vararg_ptr ) ; return ; } /*--------------------------------------------------------------------------*/ void ERROR_exit( char *fmt , ... ) { va_list vararg_ptr ; va_start( vararg_ptr , fmt ) ; colorize_prefix = 1 ; output_message( 1 , "** FATAL ERROR: " , fmt , vararg_ptr ) ; va_end( vararg_ptr ) ; fprintf(stderr,"** Program compile date = %s\n",__DATE__) ; exit(1) ; } /*--------------------------------------------------------------------------*/ #if 0 #ifdef USE_TRACING void STATUS_message( char *fmt , ... ) { char *msg ; int ll ; va_list vararg_ptr ; va_start( vararg_ptr , fmt ) ; ll = strlen(fmt) ; if( ll < 128 ) ll = 128 ; msg = malloc(sizeof(char)*16*ll+666) ; msg[0] = '\0' ; sprintf(msg,"%*.*s%s -- ",DBG_num,DBG_num," ",DBROUT) ; ll = strlen(msg) ; vsprintf(msg+ll,fmt,vararg_ptr) ; ll = strlen(msg) ; if( msg[ll-1] != '\n' ){ msg[ll] = '\n'; msg[ll+1] = '\0'; } if( DBG_fp==NULL ) DBG_fp=stdout; fputs(msg,DBG_fp) ; strncpy(last_status,msg,1023); last_status[1023]='\0'; free(msg) ; va_end( vararg_ptr ) ; return ; } #endif #endif /*--------------------------------------------------------------------------*/ /* Clock time logging [03 Nov 2016] */ static char *pname=NULL ; void set_program_name(char *ch) { if( ch != NULL ) pname = strdup(ch) ; return ; } #include extern char * nice_time_string(int) ; extern int NI_clock_time(void) ; extern int THD_is_directory( char * ) ; void clock_time_atexit(void) { #ifndef MRILIB_MINI char *eee=getenv("HOME") ; int ct=NI_clock_time() ; time_t tnow=time(NULL) ; char *fname ; char *cht=ctime(&tnow) ; FILE *fp ; if( ct == 0 || pname == NULL || !THD_is_directory(eee) ) return ; fname = (char *)malloc(sizeof(char)*(strlen(eee)+32)) ; if( fname == NULL ) return ; strcpy(fname,eee) ; strcat(fname,"/.afni.clocktime.log") ; fp = fopen(fname,"a") ; free(fname) ; if( fp == NULL ) return ; fprintf(fp,"[%.24s] %s =%s\n",ctime(&tnow) , pname , nice_time_string(ct) ) ; fclose(fp) ; #endif return ; }