/* * File display.c - display handling for Wine internal debugger. * * Copyright (C) 1997, Eric Youngdale. * Copyright (C) 2003, Michal Miroslaw * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "debugger.h" #include #define DISPTAB_DELTA 8 /* needs to be power of 2, search for MARK to see why :) */ struct display { struct expr *exp; int count; char format; char enabled; struct name_hash *function_name; }; static struct display *displaypoints = NULL; static unsigned int maxdisplays = 0, ndisplays = 0; static struct name_hash *DEBUG_GetCurrentFrameFunctionName(void) { struct name_hash *name; unsigned int eip, ebp; if (DEBUG_GetCurrentFrame(&name, &eip, &ebp)) return name; return NULL; } int DEBUG_AddDisplay(struct expr *exp, int count, char format, int in_frame) { int i; for (i = 0; i < ndisplays; i++) if (displaypoints[i].exp == NULL) break; if (i == maxdisplays) /* no space left - expand */ displaypoints = DBG_realloc(displaypoints, (maxdisplays += DISPTAB_DELTA) * sizeof(*displaypoints)); if (i == ndisplays) ++ndisplays; displaypoints[i].exp = DEBUG_CloneExpr(exp); displaypoints[i].count = count; displaypoints[i].format = format; displaypoints[i].enabled = TRUE; displaypoints[i].function_name = (in_frame ? DEBUG_GetCurrentFrameFunctionName() : NULL); return TRUE; } int DEBUG_InfoDisplay(void) { int i; for (i = 0; i < ndisplays; i++) { if (displaypoints[i].exp == NULL) continue; if (displaypoints[i].function_name) DEBUG_Printf(DBG_CHN_MESG, "%d in %s%s : ", i + 1, DEBUG_GetSymbolName(displaypoints[i].function_name), (displaypoints[i].enabled ? (displaypoints[i].function_name != DEBUG_GetCurrentFrameFunctionName() ? " (out of scope)" : "") : " (disabled)") ); else DEBUG_Printf(DBG_CHN_MESG, "%d%s : ", i + 1, (displaypoints[i].enabled ? "" : " (disabled)")); DEBUG_DisplayExpr(displaypoints[i].exp); DEBUG_Printf(DBG_CHN_MESG, "\n"); } return TRUE; } void DEBUG_PrintOneDisplay(int i) { DBG_VALUE value; if (displaypoints[i].enabled) { value = DEBUG_EvalExpr(displaypoints[i].exp); if (value.type == NULL) { DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression "); DEBUG_DisplayExpr(displaypoints[i].exp); DEBUG_Printf(DBG_CHN_MESG, "\nDisabling display %d ...\n", i + 1); displaypoints[i].enabled = FALSE; return; } } DEBUG_Printf(DBG_CHN_MESG, "%d : ", i + 1); DEBUG_DisplayExpr(displaypoints[i].exp); DEBUG_Printf(DBG_CHN_MESG, " = "); if (!displaypoints[i].enabled) DEBUG_Printf(DBG_CHN_MESG, "(disabled)\n"); else if (displaypoints[i].format == 'i') DEBUG_ExamineMemory(&value, displaypoints[i].count, displaypoints[i].format); else DEBUG_Print(&value, displaypoints[i].count, displaypoints[i].format, 0); } int DEBUG_DoDisplay(void) { int i; struct name_hash *cur_function_name = DEBUG_GetCurrentFrameFunctionName(); for (i = 0; i < ndisplays; i++) { if (displaypoints[i].exp == NULL || !displaypoints[i].enabled) continue; if (displaypoints[i].function_name && displaypoints[i].function_name != cur_function_name) continue; DEBUG_PrintOneDisplay(i); } return TRUE; } int DEBUG_DelDisplay(int displaynum) { int i; if (displaynum > ndisplays || displaynum == 0 || displaynum < -1 || displaypoints[displaynum - 1].exp == NULL) { DEBUG_Printf(DBG_CHN_MESG, "Invalid display number\n"); return TRUE; } if (displaynum == -1) { for (i = 0; i < ndisplays; i++) { if (displaypoints[i].exp != NULL) { DEBUG_FreeExpr(displaypoints[i].exp); displaypoints[i].exp = NULL; } } displaypoints = DBG_realloc(displaypoints, (maxdisplays = DISPTAB_DELTA) * sizeof(*displaypoints)); ndisplays = 0; } else if (displaypoints[--displaynum].exp != NULL) { DEBUG_FreeExpr(displaypoints[displaynum].exp); displaypoints[displaynum].exp = NULL; while (displaynum == ndisplays - 1 && displaypoints[displaynum].exp == NULL) --ndisplays, --displaynum; if (maxdisplays - ndisplays >= 2 * DISPTAB_DELTA) { maxdisplays = (ndisplays + DISPTAB_DELTA - 1) & ~(DISPTAB_DELTA - 1); /* MARK */ displaypoints = DBG_realloc(displaypoints, maxdisplays * sizeof(*displaypoints)); } } return TRUE; } int DEBUG_EnableDisplay(int displaynum, int enable) { --displaynum; if (displaynum >= ndisplays || displaynum < 0 || displaypoints[displaynum].exp == NULL) { DEBUG_Printf(DBG_CHN_MESG, "Invalid display number\n"); return TRUE; } displaypoints[displaynum].enabled = enable; if (!displaypoints[displaynum].function_name || displaypoints[displaynum].function_name == DEBUG_GetCurrentFrameFunctionName()) DEBUG_PrintOneDisplay(displaynum); return TRUE; }