4 * This source code is part of
8 * GROningen MAchine for Chemical Simulations
11 * Copyright (c) 1991-2001, University of Groningen, The Netherlands
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * If you want to redistribute modifications, please consider that
18 * scientific software is very special. Version control is crucial -
19 * bugs must be traceable. We will be happy to consider code for
20 * inclusion in the official distribution, but derived work must not
21 * be called official GROMACS. Details are found in the README & COPYING
22 * files - if they are missing, get the official version at www.gromacs.org.
24 * To help us fund GROMACS development, we humbly ask that you cite
25 * the papers on the package - you can find them in the top README file.
27 * For more info, check our website at http://www.gromacs.org
30 * Great Red Owns Many ACres of Sand
48 static bool bDebug
= FALSE
;
49 static char *fatal_tmp_file
= NULL
;
56 void _where(char *file
,int line
)
58 static bool bFirst
= TRUE
;
59 static int nskip
= -1;
60 static int nwhere
= 0;
65 if ((temp
=getenv("WHERE")) != NULL
)
71 /* Skip the first n occasions, this allows to see where it goes wrong */
72 if (nwhere
>= nskip
) {
77 fprintf(fp
,"WHERE %d, file %s - line %d\n",nwhere
,file
,line
);
83 static void bputc(char *msg
,int *len
,char ch
)
88 static void bputs(char *msg
,int *len
,char *s
,int fld
)
90 for (fld
-=(int)strlen(s
); fld
>0; fld
--) bputc(msg
,len
,' ');
91 while (*s
) bputc(msg
,len
,*(s
++));
94 static void bputd(char *msg
,int *len
,int d
)
96 if (d
<10) bputc(msg
,len
,d
+'0'); else bputc(msg
,len
,d
-10+'a');
99 static void bputi(char *msg
,int *len
,int val
,int radix
,int fld
,bool bNeg
)
108 for (fld
--; fld
>fmax
; fld
--)
118 bputi(msg
,len
,val
/radix
,radix
,fld
-1,FALSE
);
119 bputd(msg
,len
,val
%radix
);
123 static int getfld(char **p
)
128 while (isdigit(**p
)) fld
=(fld
*10)+((*((*p
)++))-'0');
132 void _halt(char *file
,int line
,char *reason
)
134 fprintf(stderr
,"\nHALT in file %s line %d because:\n\t%s\n",
139 void quit_gmx(int fatal_errno
,char *msg
)
143 fprintf(stdlog
,"%s\n",msg
);
144 fprintf(stderr
,"%s\n",msg
);
147 if (fatal_errno
!= -1)
157 nnodes
= gmx_node_num();
158 nodeid
= gmx_node_id();
161 fprintf(stderr
,"Error on node %d, will try to stop all the nodes\n",nodeid
);
162 gmx_abort(nodeid
,nnodes
,-1);
168 fprintf(stderr
,"dump core (y/n):");
170 if (toupper(getc(stdin
))!='N')
177 void _set_fatal_tmp_file(char *fn
, char *file
, int line
)
179 if (fatal_tmp_file
== NULL
)
180 fatal_tmp_file
= strdup(fn
);
182 fprintf(stderr
,"BUGWARNING: fatal_tmp_file already set at %s:%d",
186 void _unset_fatal_tmp_file(char *fn
, char *file
, int line
)
188 if (strcmp(fn
,fatal_tmp_file
) == 0) {
189 sfree(fatal_tmp_file
);
190 fatal_tmp_file
= NULL
;
192 fprintf(stderr
,"BUGWARNING: file %s not set as fatal_tmp_file at %s:%d",
196 void fatal_error(int fatal_errno
,char *fmt
,...)
199 char *p
,cval
,*sval
,msg
[STRLEN
];
200 char ibuf
[64],ifmt
[64];
201 int index
,ival
,fld
,len
;
203 #ifdef _SPECIAL_VAR_ARG
208 fatal_errno
=va_arg(ap
,int);
209 fmt
=va_arg(ap
,char *);
214 if (fatal_tmp_file
) {
215 fprintf(stderr
,"Cleaning up temporary file %s\n",fatal_tmp_file
);
216 remove(fatal_tmp_file
);
217 sfree(fatal_tmp_file
);
218 fatal_tmp_file
= NULL
;
222 bputs(msg
,&len
,"Fatal error: ",0);
223 for (p
=fmt
; *p
; p
++) {
232 sprintf(ifmt
,"0x%%%dx",fld
);
233 sprintf(ibuf
,ifmt
,(unsigned int)ival
);
234 for(index
=0; (index
<(int)strlen(ibuf
)); index
++)
235 bputc(msg
,&len
,ibuf
[index
]);
239 sprintf(ifmt
,"%%%dd",fld
);
240 sprintf(ibuf
,ifmt
,ival
);
241 for(index
=0; (index
<(int)strlen(ibuf
)); index
++)
242 bputc(msg
,&len
,ibuf
[index
]);
245 dval
=va_arg(ap
,double);
246 sprintf(ifmt
,"%%%df",fld
);
247 sprintf(ibuf
,ifmt
,dval
);
248 for(index
=0; (index
<(int)strlen(ibuf
)); index
++)
249 bputc(msg
,&len
,ibuf
[index
]);
252 cval
=(char) va_arg(ap
,int); /* char is promoted to int */
253 bputc(msg
,&len
,cval
);
256 sval
=va_arg(ap
,char *);
257 bputs(msg
,&len
,sval
,fld
);
265 bputc(msg
,&len
,'\0');
267 quit_gmx(fatal_errno
,msg
);
270 static int nwarn
= 0;
271 static int maxwarn
= 10;
272 static int lineno
= 1;
273 static char filenm
[256] = "";
276 void init_warning(int maxwarning
)
278 maxwarn
= maxwarning
;
282 void set_warning_line(char *s
,int line
)
288 int get_warning_line()
293 char *get_warning_file()
298 void warning(char *s
)
301 char linenobuf
[32], *temp
, *temp2
;
308 sprintf(linenobuf
,"%d",lineno
);
310 strcpy(linenobuf
,"unknown");
311 snew(temp
,strlen(s
)+indent
+1);
312 for(i
=0; i
<indent
; i
++)
316 temp2
= wrap_lines(temp
,81-indent
,indent
);
317 fprintf(stderr
,"WARNING %d [file %s, line %s]:\n%s\n",
318 nwarn
,filenm
,linenobuf
,temp2
);
321 if (nwarn
>= maxwarn
)
322 fatal_error(0,"Too many warnings, %s terminated",Program());
325 void print_warn_num(void)
328 fprintf(stderr
,"There %s %d warning%s\n",
329 (nwarn
==1) ? "was" : "were", nwarn
, (nwarn
==1) ? "" : "s");
332 void _too_few(char *fn
,int line
)
334 sprintf(warn_buf
,"Too few parameters on line (source file %s, line %d)",
339 void _invalid_case(char *fn
,int line
)
341 fatal_error(0,"Invalid case in switch statement, file %s, line %d",
345 void _unexpected_eof(char *fn
,int line
,char *srcfn
,int srcline
)
347 fatal_error(0,"Unexpected end of file in file %s at line %d\n"
348 "(Source file %s, line %d)",fn
,line
,srcfn
,srcline
);
352 * These files are global variables in the gromacs preprocessor
353 * Every routine in a file that includes fatal.h can write to these
354 * debug channels. Depending on the debuglevel used
355 * 0 to 3 of these filed are redirected to /dev/null
360 void init_debug (char *dbgfile
)
363 debug
=ffopen(dbgfile
,"w");
367 #if (defined __sgi && defined USE_SGI_FPE)
368 static void user_routine(unsigned us
[5], int ii
[2])
370 fprintf(stderr
,"User routine us=(%u,%u,%u,%u,%u) ii=(%d,%d)\n",
371 us
[0],us
[1],us
[2],us
[3],us
[4],ii
[0],ii
[1]);
372 fprintf(stderr
,"Exception encountered! Dumping core\n");
376 static void abort_routine(unsigned int **ii
)
378 fprintf(stderr
,"Abort routine\n");
382 static void handle_signals(int n
)
384 fprintf(stderr
,"Handle signals: n = %d\n",n
);
385 fprintf(stderr
,"Dumping core\n");
389 void doexceptions(void)
393 int hs
[] = { SIGILL
, SIGFPE
, SIGTRAP
, SIGEMT
, SIGSYS
};
395 int onoff
,en_mask
,abort_action
,i
;
398 en_mask
= _EN_UNDERFL
| _EN_OVERFL
| _EN_DIVZERO
|
399 _EN_INVALID
| _EN_INT_OVERFL
;
400 abort_action
= _ABORT_ON_ERROR
;
401 handle_sigfpes(onoff
,en_mask
,user_routine
,abort_action
,abort_routine
);
403 for(i
=0; (i
<asize(hs
)); i
++)
404 signal(hs
[i
],handle_signals
);
406 #endif /* __sgi and FPE */