5 /* $Id: log.c,v 2.5 1995/08/17 14:30:57 ceriel Exp $ */
21 extern char *strcpy();
23 extern long mess_id; /* from io.c */
24 extern FILE *fcreat_high(); /* from io.c */
26 /******** The Logging Machine Variables ********/
30 long inr; /* current instruction number */
32 int must_log; /* set if logging may be required */
33 long log_start; /* first instruction to be logged */
34 int logging; /* set as soon as logging starts */
36 PRIVATE long stop; /* inr after which to stop */
37 PRIVATE long gdump; /* inr at which to dump GDA */
38 PRIVATE ptr gmin, gmax; /* GDA dump limits */
39 PRIVATE long hdump; /* inr at which to dump the heap */
40 PRIVATE long stdsize; /* optional size of stack dump */
41 PRIVATE int stdrawflag; /* set if unformatted stack dump */
43 PRIVATE char log_file[64] = "int.log"; /* Name of log file */
44 PRIVATE long at; /* patch to set log_start */
45 PRIVATE char *lmask; /* patch to set logmask */
46 PRIVATE char *logvar; /* Name of LOG variable */
47 PRIVATE int log_level[128]; /* Holds the log levels */
48 PRIVATE FILE *log_fp; /* Filepointer of log file */
50 /* arguments for the logging machine */
52 PRIVATE char *arglist[20]; /* arbitrary size */
54 PRIVATE char *getpar();
55 PRIVATE long longpar();
61 /* If the string might be an interesting argument for the
62 logging machine, it is stored in the arglist, and logarg
63 succeeds. Otherwise it fails.
65 The string is interesting if it contains a '='.
67 register char *arg = str;
70 while ((ch = *arg) && (ch != '=')) {
74 if (argcount == (sizeof arglist /sizeof arglist[0]))
75 fatal("too many logging arguments on command line");
76 arglist[argcount++] = str;
84 /* setting the logging machine */
86 stop = longpar("STOP", 0L);
87 gdump = longpar("GDA", 0L);
89 gmin = i2p(longpar("GMIN", 0L));
90 gmax = i2p(longpar("GMAX", 0L));
93 hdump = longpar("HEAP", 0L);
97 stdsize = longpar("STDSIZE", 0L);
98 stdrawflag = longpar("RAWSTACK", 0L);
100 if (getpar("LOGFILE")) {
101 strcpy(log_file, getpar("LOGFILE"));
104 if ((at = longpar("AT", 0L))) {
105 /* abbreviation for: */
106 stop = at + 1; /* stop AFTER at + 1 */
107 /* Note: the setting of log_start is deferred to
108 init_ofiles(1), for implementation reasons. The
109 AT-variable presently only works for the top
114 if ((lmask = getpar("L"))) {
115 /* abbreviation for: */
124 /******** The log file ********/
130 sprintf(logvar, "%s%ld", logvar, mess_id);
136 if ((must_log = getpar(logvar) != 0)) {
137 sprintf(log_file, "%s%ld", log_file, mess_id);
138 log_start = atol(getpar(logvar));
142 /* first time, top level */
145 if (at) { /* patch */
150 if (!must_log && (must_log = getpar(logvar) != 0)) {
151 log_start = atoi(getpar(logvar));
154 set_lmask(lmask ? lmask :
155 getpar("LOGMASK") ? getpar("LOGMASK") :
159 /* Create logfile if needed */
161 if ((log_fp = fcreat_high(log_file)) == NULL)
162 fatal("Cannot create logfile '%s'", log_file);
165 if (must_log && inr >= log_start) {
179 /******** The logmask ********/
181 #define inrange(c,l,h) (l <= c && c <= h)
182 #define layout(c) (c == ' ' || c == '\t' || c == ',')
184 PRIVATE set_lmask(mask)
187 register char *mp = mask;
193 while (layout(*mp)) {
198 while (*lvp != 0 && !inrange(*lvp, '0', '9')) {
206 if ( inrange(mc, 'a', 'z')
207 || inrange(mc, 'A', 'Z')
214 else if (mc == '-') {
217 for (c = *(mp-1) + 1; c <= *(mp + 1); c++) {
222 else if (layout(mc)) {
225 else fatal("Bad logmask initialization string");
232 /******** The logging ********/
237 /* mark must be of the form ".CL...", C is class letter,
243 return ((mark[2] - '0') <= log_level[mark[1]]);
248 do_log(char *fmt, ...)
264 char *fmt = va_arg(ap, char *);
271 /* include position */
272 fprintf(log_fp, "%.4s%s, ", fmt, position());
273 vfprintf(log_fp, &fmt[4], ap);
276 vfprintf(log_fp, &fmt[0], ap);
286 /* Logging to be done at end of instruction */
289 gdad_all(gmin, gmax);
292 std_all(stdsize, stdrawflag);
296 message("program stopped on request");
302 /******** Service routines ********/
304 PRIVATE char *getpar(var)
307 /* Looks up the name in the argument list.
310 register int ln = strlen(var);
312 for (count = 0; count < argcount; count++) {
313 register char *arg = arglist[count];
315 if (strncmp(var, arg, ln) == 0 && arg[ln] == '=') {
323 PRIVATE long longpar(var, def)
324 char *var; /* name of the variable */
325 long def; /* default value */
327 register char *res = getpar(var);
329 return (res ? atol(res) : def);