mirror of
https://github.com/ThomasDickey/mawk-snapshots.git
synced 2026-01-27 03:14:29 +00:00
163 lines
2.9 KiB
C
163 lines
2.9 KiB
C
/********************************************
|
|
trace.c
|
|
copyright 2012-2014,2016 Thomas E. Dickey
|
|
|
|
This is a source file for mawk, an implementation of
|
|
the AWK programming language.
|
|
|
|
Mawk is distributed without warranty under the terms of
|
|
the GNU General Public License, version 2, 1991.
|
|
********************************************/
|
|
|
|
/*
|
|
* $MawkId: trace.c,v 1.12 2016/09/30 17:11:26 tom Exp $
|
|
*/
|
|
#include <mawk.h>
|
|
#include <repl.h>
|
|
|
|
static FILE *trace_fp;
|
|
|
|
void
|
|
Trace(const char *format,...)
|
|
{
|
|
va_list args;
|
|
|
|
if (trace_fp == 0)
|
|
trace_fp = fopen("Trace.out", "w");
|
|
|
|
if (trace_fp == 0)
|
|
rt_error("cannot open Trace.out");
|
|
|
|
va_start(args, format);
|
|
vfprintf(trace_fp, format, args);
|
|
va_end(args);
|
|
|
|
fflush(trace_fp);
|
|
}
|
|
|
|
void
|
|
TraceVA(const char *format, va_list args)
|
|
{
|
|
vfprintf(trace_fp, format, args);
|
|
}
|
|
|
|
void
|
|
TraceCell(CELL *cp)
|
|
{
|
|
TRACE(("cell %p ", (void *) cp));
|
|
if (cp != 0) {
|
|
switch ((MAWK_CELL_TYPES) cp->type) {
|
|
case C_NOINIT:
|
|
TRACE(("is empty\n"));
|
|
break;
|
|
case C_DOUBLE:
|
|
TRACE(("double %g\n", cp->dval));
|
|
break;
|
|
case C_MBSTRN:
|
|
case C_STRNUM:
|
|
case C_STRING:
|
|
TRACE(("string "));
|
|
TraceString(string(cp));
|
|
TRACE((" (%d)\n", string(cp)->ref_cnt));
|
|
break;
|
|
case C_SPACE:
|
|
TRACE(("split on space\n"));
|
|
break;
|
|
case C_SNULL:
|
|
TRACE(("split on the empty string\n"));
|
|
break;
|
|
case C_RE:
|
|
TRACE(("a regular expression at %p: %s\n", cp->ptr, re_uncompile(cp->ptr)));
|
|
break;
|
|
case C_REPL:
|
|
TRACE(("a replacement string at %p: ", cp->ptr));
|
|
TraceString(string(cp));
|
|
TRACE(("\n"));
|
|
break;
|
|
case C_REPLV:
|
|
TRACE(("a vector replacement, count %d at %p\n", cp->vcnt, cp->ptr));
|
|
break;
|
|
case NUM_CELL_TYPES:
|
|
TRACE(("unknown type %d\n", cp->type));
|
|
break;
|
|
}
|
|
} else {
|
|
TRACE(("no cell\n"));
|
|
}
|
|
}
|
|
|
|
void
|
|
TraceFunc(const char *name, CELL *sp)
|
|
{
|
|
int nargs = sp->type;
|
|
int n;
|
|
|
|
TRACE(("** %s <-%p\n", name, (void *) sp));
|
|
for (n = 0; n < nargs; ++n) {
|
|
TRACE(("...arg%d: ", n));
|
|
TraceCell(sp + n - nargs);
|
|
}
|
|
}
|
|
|
|
void
|
|
TraceString2(const char *str, size_t len)
|
|
{
|
|
size_t limit = len;
|
|
size_t n;
|
|
|
|
TRACE(("\""));
|
|
if (limit) {
|
|
for (n = 0; n < limit; ++n) {
|
|
UChar ch = (UChar) str[n];
|
|
switch (ch) {
|
|
case '\"':
|
|
TRACE(("\\\""));
|
|
break;
|
|
case '\\':
|
|
TRACE(("\\\\"));
|
|
break;
|
|
case '\b':
|
|
TRACE(("\\b"));
|
|
break;
|
|
case '\f':
|
|
TRACE(("\\f"));
|
|
break;
|
|
case '\n':
|
|
TRACE(("\\n"));
|
|
break;
|
|
case '\r':
|
|
TRACE(("\\r"));
|
|
break;
|
|
case '\t':
|
|
TRACE(("\\t"));
|
|
break;
|
|
default:
|
|
if (ch < 32 || ch > 126)
|
|
TRACE(("\\%03o", ch));
|
|
else
|
|
TRACE(("%c", ch));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
TRACE(("\""));
|
|
}
|
|
|
|
void
|
|
TraceString(STRING * sp)
|
|
{
|
|
TraceString2(sp ? sp->str : "",
|
|
sp ? sp->len : 0);
|
|
}
|
|
|
|
#ifdef NO_LEAKS
|
|
void
|
|
trace_leaks(void)
|
|
{
|
|
if (trace_fp != 0) {
|
|
fclose(trace_fp);
|
|
trace_fp = 0;
|
|
}
|
|
}
|
|
#endif
|