1 #define _DEBUGTRACE_MAIN_
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "mcw_malloc.h"
5 #ifndef MRILIB_MINI
6 #include "AFNI_version.h"
7 #endif
8 #include "debugtrace.h" /* contains 1 function */
9 #include <ctype.h>
10 #include <stdarg.h>
11 #include <string.h>
12
13 /*--------------------------------------------------------------------------*/
14
15 static int colorize_prefix = 0 ; /* use ANSI codes to change prefix colors? */
16
17 static FILE *messfp = NULL ;
18 static char *messfn = NULL ;
19
SET_message_file(char * fname)20 void SET_message_file( char *fname )
21 {
22 if( messfp != NULL ){ fclose(messfp); messfp = NULL; }
23 if( messfn != NULL ){ free (messfn); messfn = NULL; }
24
25 { char *eee = getenv("AFNI_USE_ERROR_FILE") ; /* 22 Sep 2015 */
26 if( eee != NULL && (*eee == 'N' || *eee == 'n') ) return ;
27 }
28
29 if( fname != NULL && *fname != '\0' ) messfn = strdup(fname) ;
30 return ;
31 }
32
fputs_messfp(char * msg)33 static void fputs_messfp( char *msg )
34 {
35 if( messfn != NULL && messfp == NULL ) messfp = fopen(messfn,"w") ;
36 if( messfp != NULL ){ fputs(msg,messfp); fflush(messfp); }
37 return ;
38 }
39
40
41 /*---------------------------------------------------------------------------*/
42 /* Originally written for THD_dataset_info(), now used in other places.
43 * Used to write results into an ever-lengthening string.
44 * On the first call, 'sss' should be NULL. It will be malloc()-ed and
45 contain the print-formatted results.
46 * On a subsequent call, 'sss' is the return value from the previous call.
47 * When finally done with it, you can free() the result.
48 * Moved here from thd_info.c on 01 May 2015 by RWCox.
49 *//*-------------------------------------------------------------------------*/
50
51 #undef ZMAX
52 #undef SZMAX
53 #define ZMAX 49999 /* increased for Ziad (who else is so crazy?) */
54 #define SZMAX "%.49999s" /* same as ZMAX */
55
THD_zzprintf(char * sss,char * fmt,...)56 char * THD_zzprintf( char *sss , char *fmt , ... )
57 {
58 static char *sbuf = NULL ; /* workspace */
59 char *zz ;
60 int nzz , nsbuf ;
61 va_list vararg_ptr ;
62
63 ENTRY("THD_zzprintf") ;
64
65 va_start( vararg_ptr , fmt ) ;
66
67 /* first time in ==> create workspace */
68
69 if( sbuf == NULL ) sbuf = malloc(sizeof(char)*(ZMAX+90)) ;
70
71 /* write current stuff into workspace */
72
73 sbuf[0] = '\0' ;
74 vsnprintf( sbuf , sizeof(char)*(ZMAX+89) , fmt , vararg_ptr ) ;
75 nsbuf = strlen(sbuf) ;
76 if( nsbuf == 0 ) RETURN(sss) ; /* nothing happened */
77 if( nsbuf >= ZMAX ){ /* too much happened */
78 WARNING_message("THD_zzprintf() long string truncation = the ZSS syndrome") ;
79 strcpy(sbuf+ZMAX-4,"...") ;
80 nsbuf = strlen(sbuf) ;
81 }
82
83 /* make new space, copy input string sss, append new stuff, return result */
84
85 if( sss == NULL || *sss == '\0' ){ /* no input string ==> copy new stuff */
86 zz = (char *) malloc( sizeof(char)*(nsbuf+8) ) ;
87 strcpy(zz,sbuf) ;
88 } else { /* the full Monty: copy old then new */
89 nzz = strlen(sss) + nsbuf + 8 ;
90 zz = (char *) malloc( sizeof(char) * nzz ) ;
91 strcpy(zz,sss) ; strcat(zz,sbuf) ;
92 free(sss) ; /* don't need input copy any more */
93 }
94 RETURN(zz) ;
95 }
96
97 /*--------------------------------------------------------------------------*/
98 /* Used to write messages into a buffer string rather than stderr */
99
100 static int mess_use_outbuf = 0 ; /* 01 May 2015 */
101 static char *mess_outbuf = NULL ;
102
GET_message_outbuf(void)103 char * GET_message_outbuf(void){ return mess_outbuf ; }
104
SET_message_outbuf(int use_outbuf)105 void SET_message_outbuf( int use_outbuf )
106 {
107 if( use_outbuf == 0 ){ /* turn message buffer string off */
108 mess_use_outbuf = 0 ;
109 if( mess_outbuf != NULL ) free(mess_outbuf) ;
110 mess_outbuf = NULL ;
111 } else { /* turn it on */
112 mess_use_outbuf = 1 ;
113 }
114 }
115
116 /*---------------------------------------------------------------------------*/
117 /* Write the message to stderr or the message buffer string.
118 If ump != 0, also write it to the message file pointer, if it is open.
119 *//*-------------------------------------------------------------------------*/
120
output_message(int ump,char * prefix,char * fmt,va_list vararg_ptr)121 static void output_message( int ump, char *prefix, char *fmt, va_list vararg_ptr )
122 {
123 char *ifmt=NULL,*imsg=NULL , *cfmt=NULL,*cmsg=NULL , *epr=NULL ; int ll ;
124 #ifdef va_copy
125 va_list vararg_cpy ;
126 va_copy(vararg_cpy,vararg_ptr) ; /* for re-use with cfmt and cmsg */
127 #else
128 colorize_prefix = 0 ; /* can't do this without va_copy (C99 feature) */
129 #endif
130
131 if( fmt == NULL || *fmt == '\0' ) return ; /* makes no sense */
132
133 if( colorize_prefix ){
134 epr = getenv("AFNI_MESSAGE_COLORIZE") ;
135 if( epr != NULL && toupper(*epr) == 'N' ) colorize_prefix = 0 ;
136 }
137
138 if( prefix == NULL || *prefix == '\0' ){
139 ifmt = fmt ;
140 } else {
141 ifmt = malloc( strlen(prefix)+strlen(fmt)+4 ) ;
142 strcpy(ifmt,prefix) ;
143 strcat(ifmt,fmt) ;
144 if( colorize_prefix && !mess_use_outbuf ){ /* 22 Feb 2016 */
145 cfmt = malloc( strlen(prefix)+strlen(fmt)+64 ) ;
146 #if 0
147 strcpy(cfmt,"\033[34;1m\033[43;1m") ; /* blue text on yellow bkgd */
148 #else
149 strcpy(cfmt,"\033[7m") ; /* inverse colors */
150 #endif
151 strcat(cfmt,prefix) ;
152 if( prefix[strlen(prefix)-1] == ' ' )
153 cfmt[strlen(cfmt)-1] = '\0' ;
154 strcat(cfmt,"\033[0m ") ; /* special formatting off */
155 strcat(cfmt,fmt) ;
156 }
157 }
158
159 if( mess_use_outbuf || cfmt == NULL || ump ){
160 ll = strlen(ifmt) ; if( ll < 1024 ) ll = 1024 ;
161 epr = getenv("AFNI_MESSAGE_PREFIX") ;
162 if( epr != NULL ) ll += strlen(epr)+1 ;
163 imsg = malloc(sizeof(char)*16*ll+1) ; imsg[0] = '\0' ;
164 if( epr != NULL ){ strcpy(imsg,epr); strcat(imsg,"::"); }
165 vsprintf(imsg+strlen(imsg),ifmt,vararg_ptr) ; ll = strlen(imsg) ;
166 if( imsg[ll-1] != '\n' ){ imsg[ll] = '\n' ; imsg[ll+1] = '\0' ; }
167 }
168
169 #ifdef va_copy
170 if( cfmt != NULL ){
171 ll = strlen(cfmt) ; if( ll < 1024 ) ll = 1024 ;
172 if( epr != NULL ) ll += strlen(epr)+1 ;
173 cmsg = malloc(sizeof(char)*16*ll+1) ; cmsg[0] = '\0' ;
174 if( epr != NULL ){ strcpy(cmsg,epr); strcat(cmsg,"::"); }
175 vsprintf(cmsg+strlen(cmsg),cfmt,vararg_cpy) ; ll = strlen(cmsg) ;
176 if( cmsg[ll-1] != '\n' ){ cmsg[ll] = '\n' ; cmsg[ll+1] = '\0' ; }
177 }
178 #endif
179
180 if( imsg == NULL && cmsg == NULL ){ /* should never happen */
181 if( ifmt != NULL ) free(ifmt) ;
182 if( cfmt != NULL ) free(cfmt) ;
183 colorize_prefix = 0 ; return ;
184 }
185
186 if( !mess_use_outbuf ){
187 if( cmsg != NULL ) fputs(cmsg,stderr) ;
188 else fputs(imsg,stderr) ;
189 fflush(stderr) ; /* nugatory */
190 } else {
191 mess_outbuf = THD_zzprintf(mess_outbuf,"%s",imsg) ; /* 01 May 2015 */
192 }
193 if( ump ) fputs_messfp(imsg) ; /* 12 Mar 2007 */
194
195 if( imsg != NULL ) free(imsg) ; /* 03 Mar 2006: forgot the free! */
196 if( ifmt != fmt ) free(ifmt) ;
197 if( cfmt != NULL ) free(cfmt) ;
198 if( cmsg != NULL ) free(cmsg) ;
199 colorize_prefix = 0 ; return ;
200 }
201
202 /*--------------------------------------------------------------------------*/
203
INFO_message(char * fmt,...)204 void INFO_message( char *fmt , ... )
205 {
206 va_list vararg_ptr ;
207 va_start( vararg_ptr , fmt ) ;
208 output_message( 0 , "++ " , fmt , vararg_ptr ) ;
209 va_end( vararg_ptr ) ;
210 return ;
211 }
212
213 /*--------------------------------------------------------------------------*/
214
ININFO_message(char * fmt,...)215 void ININFO_message( char *fmt , ... )
216 {
217 va_list vararg_ptr ;
218 va_start( vararg_ptr , fmt ) ;
219 output_message( 0 , " + " , fmt , vararg_ptr ) ;
220 va_end( vararg_ptr ) ;
221 return ;
222 }
223
224 /*--------------------------------------------------------------------------*/
225
WARNING_message(char * fmt,...)226 void WARNING_message( char *fmt , ... )
227 {
228 va_list vararg_ptr ;
229 va_start( vararg_ptr , fmt ) ;
230 colorize_prefix = 1 ;
231 output_message( 1 , "*+ WARNING: " , fmt , vararg_ptr ) ;
232 va_end( vararg_ptr ) ;
233 return ;
234 }
235
236 /*--------------------------------------------------------------------------*/
237
ERROR_message(char * fmt,...)238 void ERROR_message( char *fmt , ... )
239 {
240 va_list vararg_ptr ;
241 va_start( vararg_ptr , fmt ) ;
242 colorize_prefix = 1 ;
243 output_message( 1 , "** ERROR: " , fmt , vararg_ptr ) ;
244 va_end( vararg_ptr ) ;
245 return ;
246 }
247
248 /*--------------------------------------------------------------------------*/
249
ERROR_exit(char * fmt,...)250 void ERROR_exit( char *fmt , ... )
251 {
252 va_list vararg_ptr ;
253 va_start( vararg_ptr , fmt ) ;
254 colorize_prefix = 1 ;
255 output_message( 1 , "** FATAL ERROR: " , fmt , vararg_ptr ) ;
256 va_end( vararg_ptr ) ;
257 fprintf(stderr,"** Program compile date = %s\n",__DATE__) ;
258 exit(1) ;
259 }
260
261 /*--------------------------------------------------------------------------*/
262
263 #if 0
264 #ifdef USE_TRACING
265 void STATUS_message( char *fmt , ... )
266 {
267 char *msg ; int ll ;
268 va_list vararg_ptr ;
269 va_start( vararg_ptr , fmt ) ;
270 ll = strlen(fmt) ; if( ll < 128 ) ll = 128 ;
271 msg = malloc(sizeof(char)*16*ll+666) ; msg[0] = '\0' ;
272 sprintf(msg,"%*.*s%s -- ",DBG_num,DBG_num," ",DBROUT) ;
273 ll = strlen(msg) ;
274 vsprintf(msg+ll,fmt,vararg_ptr) ; ll = strlen(msg) ;
275 if( msg[ll-1] != '\n' ){ msg[ll] = '\n'; msg[ll+1] = '\0'; }
276 if( DBG_fp==NULL ) DBG_fp=stdout;
277 fputs(msg,DBG_fp) ;
278 strncpy(last_status,msg,1023); last_status[1023]='\0';
279 free(msg) ; va_end( vararg_ptr ) ; return ;
280 }
281 #endif
282 #endif
283
284 /*--------------------------------------------------------------------------*/
285 /* Clock time logging [03 Nov 2016] */
286
287 static char *pname=NULL ;
288
set_program_name(char * ch)289 void set_program_name(char *ch)
290 {
291 if( ch != NULL ) pname = strdup(ch) ;
292 return ;
293 }
294
295 #include <time.h>
296 extern char * nice_time_string(int) ;
297 extern int NI_clock_time(void) ;
298 extern int THD_is_directory( char * ) ;
299
clock_time_atexit(void)300 void clock_time_atexit(void)
301 {
302 #ifndef MRILIB_MINI
303 char *eee=getenv("HOME") ;
304 int ct=NI_clock_time() ;
305 time_t tnow=time(NULL) ;
306 char *fname ; char *cht=ctime(&tnow) ;
307 FILE *fp ;
308
309 if( ct == 0 || pname == NULL || !THD_is_directory(eee) ) return ;
310
311 fname = (char *)malloc(sizeof(char)*(strlen(eee)+32)) ;
312 if( fname == NULL ) return ;
313 strcpy(fname,eee) ; strcat(fname,"/.afni.clocktime.log") ;
314 fp = fopen(fname,"a") ; free(fname) ; if( fp == NULL ) return ;
315 fprintf(fp,"[%.24s] %s =%s\n",ctime(&tnow) , pname , nice_time_string(ct) ) ;
316 fclose(fp) ;
317 #endif
318 return ;
319 }
320