view fluid-mnf/trace.c @ 348:37b5f94de802

fluid-mnf: sensible target tty specification
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 13 Mar 2020 06:41:44 +0000
parents 9cecc930d78f
children
line wrap: on
line source

/******************************************************************************
 * Generic tracing library
 *
 * Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com
 *
 * $Id: trace.c 1.5 Fri, 11 Oct 2002 08:40:21 +0200 mmj $
 *
 ******************************************************************************/

#include "trace.h"

#include <stdio.h>
#include <string.h>
#include <stdarg.h>


#define TRACE_MODS 2


/******************************************************************************
 * 
 *****************************************************************************/

static struct trace_s {
    int spaces;    // number of spaces to indent per level
    int level;     // current indentation level (private)
    int enable;    // global trace enable/disable flag
    FILE *fp;      // file descriptor of file to write traces to
    int mask[TRACE_MODS];  // bitmask for each module
} trace;

int tr_init(int spaces, char *filename)
{
    trace.spaces = spaces;
    trace.level = 0;
    trace.enable = 1;
    trace.fp = stdout;
    memset(trace.mask, 0, sizeof(trace.mask));

    if (filename != NULL && (trace.fp = fopen(filename, "w")) == NULL) {
        return -1;
    }
    return 0;
}

int tr_mask(int mask)
{
    int module, old;

    module = ((mask & TrModMask) >> 24) - 1;
    if (module < 0 || module >= TRACE_MODS)
        return -1;

    old = trace.mask[module];
    trace.mask[module] = mask & TrBitMask;

    return old;
}

void tr_enable(int onoff)
{
    trace.enable = onoff;
}

// return current indentation if this trace type is enabled, otherwise
// return zero.
int tr_query(int mask)
{
    int module;

    module = (mask & TrModMask) >> 24;
    if (module < 0 || module >= TRACE_MODS)
        return 0;

    return (trace.mask[module] & (mask & TrBitMask) ?
            trace.level * trace.spaces : 0);
}

extern void hexdump(const char *p, int size, unsigned int address, int unitsize);

void tr_hexdump(int mask, const void *p, int size)
{
    unsigned int module;

    module = mask & TrModMask;
    mask   = mask & TrBitMask;

    if ((mask & trace.mask[module >> 24]) == 0)
        return;
    
    hexdump(p, size, 0, 1);
}

void tr(int mask, char *format, ...)
{
    va_list args;
    unsigned int type, module;
    int indent;
    static char buf[256];
    const char spaces[160 + 1] =
        "                                        "
        "                                        "
        "                                        "
        "                                        ";

    if (!trace.enable)
        return;

    type   = mask & TrTypeMask;
    module = mask & TrModMask;
    mask   = mask & TrBitMask;

    if ((mask & trace.mask[(module >> 24) - 1]) == 0)
        return;

    if (type == TrEnd)
        trace.level--;

    indent = (type == TrCont ? 0 : trace.level);

    if (indent < 0 || indent > 40) {
        indent = trace.level = 0;
        fprintf(stderr, "WARNING: trace indent out of range!\n");
    }
    if (strlen(format) > 0) {
        va_start(args, format);
        vsprintf(buf, format, args);
        indent *= trace.spaces;
        fprintf(trace.fp, "%s%s", &spaces[sizeof(spaces) - 1 - indent], buf);
        fflush(trace.fp);
    }
    if (type == TrBegin)
        trace.level++;
}