ack/util/int/log.c

354 lines
6.1 KiB
C
Raw Permalink Normal View History

1988-06-22 16:57:09 +00:00
/*
2019-03-17 14:42:00 +00:00
The logging machine
*/
1988-06-22 16:57:09 +00:00
1994-06-24 11:31:16 +00:00
/* $Id$ */
1988-06-22 16:57:09 +00:00
#include <stdio.h>
#include <string.h>
#if __STDC__
#include <stdarg.h>
#else
1988-06-22 16:57:09 +00:00
#include <varargs.h>
#endif
1988-06-22 16:57:09 +00:00
#include "logging.h"
#include "global.h"
2019-03-17 14:42:00 +00:00
#include "dump.h"
1988-06-22 16:57:09 +00:00
#include "linfil.h"
2019-03-17 14:42:00 +00:00
#include "io.h"
1988-06-22 16:57:09 +00:00
#ifdef LOGGING
2019-03-17 14:42:00 +00:00
extern long mess_id; /* from io.c */
extern FILE *fcreat_high(); /* from io.c */
1988-06-22 16:57:09 +00:00
/******** The Logging Machine Variables ********/
extern long atol();
2019-03-17 14:42:00 +00:00
long inr; /* current instruction number */
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
int must_log; /* set if logging may be required */
long log_start; /* first instruction to be logged */
int logging; /* set as soon as logging starts */
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
PRIVATE long stop; /* inr after which to stop */
PRIVATE long gdump; /* inr at which to dump GDA */
PRIVATE ptr gmin, gmax; /* GDA dump limits */
PRIVATE long hdump; /* inr at which to dump the heap */
PRIVATE long stdsize; /* optional size of stack dump */
PRIVATE int stdrawflag; /* set if unformatted stack dump */
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
PRIVATE char log_file[64] = "int.log"; /* Name of log file */
PRIVATE long at; /* patch to set log_start */
PRIVATE char *lmask; /* patch to set logmask */
PRIVATE char *logvar; /* Name of LOG variable */
PRIVATE int log_level[128]; /* Holds the log levels */
PRIVATE FILE *log_fp; /* Filepointer of log file */
1988-06-22 16:57:09 +00:00
/* arguments for the logging machine */
PRIVATE int argcount;
2019-03-17 14:42:00 +00:00
PRIVATE char *arglist[20]; /* arbitrary size */
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
PRIVATE void set_lmask(char *mask);
PRIVATE char *getpar(char *);
PRIVATE long longpar(char *, long);
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
int logarg(char *str)
1988-06-22 16:57:09 +00:00
{
/* If the string might be an interesting argument for the
2019-03-17 14:42:00 +00:00
logging machine, it is stored in the arglist, and logarg
succeeds. Otherwise it fails.
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
The string is interesting if it contains a '='.
*/
1988-06-22 16:57:09 +00:00
register char *arg = str;
register char ch;
2019-03-17 14:42:00 +00:00
while ((ch = *arg) && (ch != '='))
{
1988-06-22 16:57:09 +00:00
arg++;
}
2019-03-17 14:42:00 +00:00
if (ch == '=')
{
if (argcount == (sizeof arglist / sizeof arglist[0]))
1988-06-22 16:57:09 +00:00
fatal("too many logging arguments on command line");
arglist[argcount++] = str;
return 1;
}
return 0;
}
2019-03-17 14:42:00 +00:00
void init_log(void)
1988-06-22 16:57:09 +00:00
{
/* setting the logging machine */
stop = longpar("STOP", 0L);
gdump = longpar("GDA", 0L);
2019-03-17 14:42:00 +00:00
if (gdump)
{
1988-06-22 16:57:09 +00:00
gmin = i2p(longpar("GMIN", 0L));
gmax = i2p(longpar("GMAX", 0L));
set_lmask("+1");
}
hdump = longpar("HEAP", 0L);
2019-03-17 14:42:00 +00:00
if (hdump)
{
1988-06-22 16:57:09 +00:00
set_lmask("*1");
}
stdsize = longpar("STDSIZE", 0L);
stdrawflag = longpar("RAWSTACK", 0L);
2019-03-17 14:42:00 +00:00
if (getpar("LOGFILE"))
{
1988-06-22 16:57:09 +00:00
strcpy(log_file, getpar("LOGFILE"));
}
2019-03-17 14:42:00 +00:00
if ((at = longpar("AT", 0L)))
{
1988-06-22 16:57:09 +00:00
/* abbreviation for: */
2019-03-17 14:42:00 +00:00
stop = at + 1; /* stop AFTER at + 1 */
1988-06-22 16:57:09 +00:00
/* Note: the setting of log_start is deferred to
2019-03-17 14:42:00 +00:00
init_ofiles(1), for implementation reasons. The
AT-variable presently only works for the top
level.
*/
1988-06-22 16:57:09 +00:00
}
2019-03-17 14:42:00 +00:00
if ((lmask = getpar("L")))
{
1988-06-22 16:57:09 +00:00
/* abbreviation for: */
log_start = 0;
must_log = 1;
}
inr = 0;
}
/******** The log file ********/
2019-03-17 14:42:00 +00:00
void open_log(int firsttime)
1988-06-22 16:57:09 +00:00
{
2019-03-17 14:42:00 +00:00
if (!firsttime)
{
1988-06-22 16:57:09 +00:00
sprintf(logvar, "%s%ld", logvar, mess_id);
2019-03-17 14:42:00 +00:00
if (log_fp)
{
1988-06-22 16:57:09 +00:00
fclose(log_fp);
log_fp = 0;
}
logging = 0;
2019-03-17 14:42:00 +00:00
if ((must_log = getpar(logvar) != 0))
{
1988-06-22 16:57:09 +00:00
sprintf(log_file, "%s%ld", log_file, mess_id);
log_start = atol(getpar(logvar));
}
}
2019-03-17 14:42:00 +00:00
else
{
1988-06-22 16:57:09 +00:00
/* first time, top level */
logvar = "LOG\0 ";
2019-03-17 14:42:00 +00:00
if (at)
{ /* patch */
1988-06-22 16:57:09 +00:00
must_log = 1;
log_start = at - 1;
}
2019-03-17 14:42:00 +00:00
else if (!must_log && (must_log = getpar(logvar) != 0))
{
1988-06-22 16:57:09 +00:00
log_start = atoi(getpar(logvar));
}
2019-03-17 14:42:00 +00:00
set_lmask(
lmask ? lmask :
getpar("LOGMASK") ? getpar("LOGMASK") : "A-Z9d2twx9");
1988-06-22 16:57:09 +00:00
}
2019-03-17 14:42:00 +00:00
1988-06-22 16:57:09 +00:00
/* Create logfile if needed */
2019-03-17 14:42:00 +00:00
if (must_log)
{
1988-06-22 16:57:09 +00:00
if ((log_fp = fcreat_high(log_file)) == NULL)
fatal("Cannot create logfile '%s'", log_file);
}
2019-03-17 14:42:00 +00:00
if (must_log && inr >= log_start)
{
1988-06-22 16:57:09 +00:00
logging = 1;
}
}
2019-03-17 14:42:00 +00:00
void close_log(void)
{
if (log_fp)
{
1988-06-22 16:57:09 +00:00
fclose(log_fp);
log_fp = 0;
}
}
/******** The logmask ********/
#define inrange(c,l,h) (l <= c && c <= h)
#define layout(c) (c == ' ' || c == '\t' || c == ',')
2019-03-17 14:42:00 +00:00
PRIVATE void set_lmask(char *mask)
1988-06-22 16:57:09 +00:00
{
register char *mp = mask;
2019-03-17 14:42:00 +00:00
while (*mp != 0)
{
1988-06-22 16:57:09 +00:00
register char *lvp;
register int lev;
2019-03-17 14:42:00 +00:00
while (layout(*mp))
{
1988-06-22 16:57:09 +00:00
mp++;
}
/* find level */
lvp = mp;
2019-03-17 14:42:00 +00:00
while (*lvp != 0 && !inrange(*lvp, '0', '9'))
{
1988-06-22 16:57:09 +00:00
lvp++;
}
lev = *lvp - '0';
/* find classes */
2019-03-17 14:42:00 +00:00
while (mp != lvp)
{
register int mc = *mp;
if ( inrange(mc, 'a', 'z') || inrange(mc, 'A', 'Z') || mc == '+'
|| mc == '*')
{
1988-06-22 16:57:09 +00:00
log_level[mc] = lev;
mp++;
}
2019-03-17 14:42:00 +00:00
else if (mc == '-')
{
1988-06-22 16:57:09 +00:00
register char c;
2019-03-17 14:42:00 +00:00
for (c = *(mp - 1) + 1; c <= *(mp + 1); c++)
{
log_level[(unsigned char)c] = lev;
1988-06-22 16:57:09 +00:00
}
mp += 2;
}
2019-03-17 14:42:00 +00:00
else if (layout(mc))
{
1988-06-22 16:57:09 +00:00
mp++;
}
2019-03-17 14:42:00 +00:00
else
fatal("Bad logmask initialization string");
1988-06-22 16:57:09 +00:00
}
mp = lvp + 1;
}
}
/******** The logging ********/
2019-03-17 14:42:00 +00:00
int check_log(char mark[])
1988-06-22 16:57:09 +00:00
{
/* mark must be of the form ".CL...", C is class letter,
2019-03-17 14:42:00 +00:00
L is level digit.
*/
1988-06-22 16:57:09 +00:00
if (!logging)
return 0;
2019-03-17 14:42:00 +00:00
return ((mark[2] - '0') <= log_level[(unsigned char)mark[1]]);
1988-06-22 16:57:09 +00:00
}
#if __STDC__
/*VARARGS*/
2019-03-17 14:42:00 +00:00
void do_log(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
{
#else
2019-03-17 14:42:00 +00:00
/*VARARGS*/
do_log(va_alist)
va_dcl
{
va_list ap;
1988-06-22 16:57:09 +00:00
2019-03-17 14:42:00 +00:00
va_start(ap);
{
char *fmt = va_arg(ap, char *);
1988-06-22 16:57:09 +00:00
#endif
1988-06-22 16:57:09 +00:00
if (!check_log(fmt))
return;
2019-03-17 14:42:00 +00:00
if (fmt[0] == '@')
{
1988-06-22 16:57:09 +00:00
/* include position */
fprintf(log_fp, "%.4s%s, ", fmt, position());
vfprintf(log_fp, &fmt[4], ap);
1988-06-22 16:57:09 +00:00
}
2019-03-17 14:42:00 +00:00
else
{
vfprintf(log_fp, &fmt[0], ap);
1988-06-22 16:57:09 +00:00
}
}
va_end(ap);
putc('\n', log_fp);
}
2019-03-17 14:42:00 +00:00
void log_eoi(void)
1988-06-22 16:57:09 +00:00
{
/* Logging to be done at end of instruction */
2019-03-17 14:42:00 +00:00
if (logging)
{
1988-06-22 16:57:09 +00:00
if (inr == gdump)
gdad_all(gmin, gmax);
if (inr == hdump)
hpd_all();
std_all(stdsize, stdrawflag);
}
2019-03-17 14:42:00 +00:00
if (inr == stop)
{
1988-06-22 16:57:09 +00:00
message("program stopped on request");
close_down(0);
}
}
/******** Service routines ********/
2019-03-17 14:42:00 +00:00
PRIVATE char *getpar(char *var)
1988-06-22 16:57:09 +00:00
{
/* Looks up the name in the argument list.
2019-03-17 14:42:00 +00:00
*/
1988-06-22 16:57:09 +00:00
register int count;
register int ln = strlen(var);
2019-03-17 14:42:00 +00:00
for (count = 0; count < argcount; count++)
{
1988-06-22 16:57:09 +00:00
register char *arg = arglist[count];
2019-03-17 14:42:00 +00:00
if (strncmp(var, arg, ln) == 0 && arg[ln] == '=')
{
return &arg[ln + 1];
1988-06-22 16:57:09 +00:00
}
}
return 0;
}
2019-03-17 14:42:00 +00:00
PRIVATE long longpar(
char *var, /* name of the variable */
long def /* default value */
)
1988-06-22 16:57:09 +00:00
{
register char *res = getpar(var);
2019-03-17 14:42:00 +00:00
1988-06-22 16:57:09 +00:00
return (res ? atol(res) : def);
}
#endif /* LOGGING */
1988-06-22 16:57:09 +00:00