File:  [Coherent Logic Development] / freem / src / mdebug.c
Revision 1.3: download - view: text, annotated - select for diffs
Sun Mar 9 19:50:47 2025 UTC (3 weeks, 2 days ago) by snw
Branches: MAIN
CVS tags: v0-62-3, v0-62-2, v0-62-1, v0-62-0, HEAD
Second phase of REUSE compliance and header reformat

/*
 *   $Id: mdebug.c,v 1.3 2025/03/09 19:50:47 snw Exp $
 *    debugger enhancements
 *
 *  
 *   Author: Serena Willis <snw@coherent-logic.com>
 *    Copyright (C) 1998 MUG Deutschland
 *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
 *
 *
 *   This file is part of FreeM.
 *
 *   FreeM is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   FreeM is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Affero Public License for more details.
 *
 *   You should have received a copy of the GNU Affero Public License
 *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
 *
 *   $Log: mdebug.c,v $
 *   Revision 1.3  2025/03/09 19:50:47  snw
 *   Second phase of REUSE compliance and header reformat
 *
 *
 * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
 * SPDX-License-Identifier: AGPL-3.0-or-later
 **/

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

#include "mpsdef.h"
#include "mdebug.h"
#include "freem.h"
#include "mref.h"

dbg_watch dbg_watchlist[MAXWATCH];    /* list of watchpoints */
short dbg_enable_watch;               /* 0 = watches disabled, 1 = watches enabled */
int dbg_pending_watches;


void dbg_init (void)
{
    register int i;

    dbg_enable_watch = 0;
    dbg_pending_watches = 0;

    for (i = 0; i < MAXWATCH; i++) {

        dbg_watchlist[i].varnam = NULL;
        dbg_watchlist[i].chgct = 0;

    }

}

dbg_watch *dbg_add_watch (char *varnam)
{
    register int i;
    int index = -1;
    short found = 0;
    dbg_watch *w;

    if ((w = dbg_find_watch (varnam)) != NULL) {
        set_io (UNIX);
        fprintf (stderr, "You are already watching '%s' (changed %d times).\n", dbg_get_watch_name (w->varnam), w->chgct);
        set_io (MUMPS);
        return NULL;
    }

    for (i = 0; i < MAXWATCH; i++) {
        if (dbg_watchlist[i].varnam == NULL) {
            found++;
            index = i;
            break;
        }
    }

    if (!found) {
        set_io (UNIX);
        fprintf (stderr, "No free watchlist entries available. Try removing an existing watchpoint first.\n");
        set_io (MUMPS);

        return NULL;
    }

    if ((dbg_watchlist[index].varnam = (char *) malloc (256 * sizeof (char))) == NULL) {
        set_io (UNIX);
        fprintf (stderr, "Could not allocate memory for the new watchlist entry.\n");
        set_io (MUMPS);

        return NULL;
    }

    strcpy (dbg_watchlist[index].varnam, varnam);
    dbg_watchlist[index].chgct = 0;

    set_io (UNIX);
    fprintf (stderr, "Added '%s' to the watchlist.\n", dbg_get_watch_name (varnam));
    set_io (MUMPS);

    return NULL;
    
}

void dbg_dump_watchlist (void) 
{
	register int i;

	for (i = 0; i < MAXWATCH; i++) {
		if (dbg_watchlist[i].firect) {
			dbg_dump_watch (dbg_watchlist[i].varnam);
		}
	}

	dbg_pending_watches = 0;
}


void dbg_remove_watch (char *varnam)
{
    dbg_watch *w;

    if ((w = dbg_find_watch (varnam)) == NULL) {
        set_io (UNIX);
        fprintf (stderr, "'%s' is not being watched.\n", dbg_get_watch_name (varnam));
        set_io (MUMPS);

        return;
    }

    free (w->varnam);
    
    w->chgct = 0;
    w->firect = 0;

    set_io (UNIX);
    printf ("Removed '%s' from the watchlist.\n", dbg_get_watch_name (varnam));
    set_io (MUMPS);
    
    return;
}

void dbg_dump_watch (char *varnam)
{
    char *ddwbuf;
    dbg_watch *w;

    ddwbuf = (char *) malloc (STRLEN * sizeof (char));
    NULLPTRCHK(ddwbuf,"dbg_dump_watch");

    if ((w = dbg_find_watch (varnam)) == NULL) {
        set_io (UNIX);
        fprintf (stderr, "'%s' is not being watched.\n", dbg_get_watch_name (varnam));
        set_io (MUMPS);

        return;
    }

    w->firect = 0;

    if (varnam[0] != '^') {
    	symtab (get_sym, varnam, ddwbuf);
    }
    else {
    	if (varnam[1] == '$') {
    		ssvn (get_sym, varnam, ddwbuf);
    	}
    	else {
    		global (get_sym, varnam, ddwbuf);
    	}
    }

    stcnv_m2c (ddwbuf);

    set_io (UNIX);
    printf (">> WATCHPOINT:  %s => '%s' (changed %d times)\n", dbg_get_watch_name (varnam), ddwbuf, w->chgct);
    set_io (MUMPS);

    free (ddwbuf);

}

dbg_watch *dbg_find_watch (char *varnam)
{
    register int i;
    

    for (i = 0; i < MAXWATCH; i++) {
        if (dbg_watchlist[i].varnam != NULL) {
            if (strcmp (varnam, dbg_watchlist[i].varnam) == 0) {
                return &(dbg_watchlist[i]);
            }

        }
    }

    return NULL;
}

char *dbg_get_watch_name (char *varnam)
{
    freem_ref_t *r;
    char *s;
    
    r = (freem_ref_t *) malloc (sizeof (freem_ref_t));
    NULLPTRCHK(r,"dbg_get_watch_name");
    
    s = (char *) malloc (STRLEN * sizeof (char));
    NULLPTRCHK(s,"dbg_get_watch_name");
    
    mref_init (r, MREF_RT_LOCAL, "");
    internal_to_mref (r, varnam);
    mref_to_external (r, s);
        
    free (r);
        
    return s;
        
}

void dbg_fire_watch (char *varnam) {

	dbg_watch *w;

	if ((w = dbg_find_watch (varnam)) == NULL) {
		return;
	}

	w->chgct++;
	w->firect++;
	dbg_pending_watches++;

}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>