⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 watchwnd.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 
Copyright 2001-2003 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  

You may contact the author at:

mailto::camille@bluegrass.net

or by snail mail at:

David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222

 **********************************************************************

WATCHWND.C holds the functionality for the watch window.  This includes
the window itself, a right click menu, and an interface for the editor
to add things to the watch window via its own right-click window.

 **********************************************************************
 */
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <ctype.h>
#include <richedit.h>
#include "header.h"
#include <dir.h>
#include "cvinfo.h"

extern HWND hwndSourceTab;
extern HWND hwndFrame, hwndProject, hwndRegister, hwndClient, hwndError,
    hwndTab;
extern HINSTANCE hInstance;
extern THREAD *StoppedThread;
extern PROCESS DebugProcess;
extern unsigned bitmask[];

HWND hwndWatch;
static HWND hwndTree, hwndCtrl;
static char szWatchClassName[] = "xccWatchClass";
static char szWatchTitle[] = "Watch Window";

static HBITMAP valueBitmap, itemBitmap;

static LOGFONT fontdata = 
{
    14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
        OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, 
        "Helvetica"
};
static WATCHINFO *watchinfo_list;
static int watchinfo_max;
static int watchinfo_count;

void AddTypeInfoToName(char *typetab, VARINFO *v)
{
    char buf[256],  *p;
    strcpy(v->screenname, v->membername);
    p = v->screenname + strlen(v->screenname);
    sprintf(p, "(%s)", SymTypeName(buf, typetab, v));
}

//-------------------------------------------------------------------------

WATCHINFO *MatchItem(VARINFO *var)
{
    int i;
    for (i = 0; i < watchinfo_count; i++)
        if (!strcmp(watchinfo_list[i].info->membername, var->membername))
            if (watchinfo_list[i].info->typetab == var->typetab)
                return  &watchinfo_list[i];
    return 0;
}

//-------------------------------------------------------------------------

void FreeTree(VARINFO *info)
{
    while (info)
    {
        FreeTree(info->subtype);
        if (info->hTreeItem)
            TreeView_DeleteItem(hwndTree, info->hTreeItem);
        info = info->link;
    }
}

//-------------------------------------------------------------------------

void RefreshAddresses(VARINFO *var, int address, int noscope)
{
    while (var)
    {
        int unscope = noscope;
        int val;
        if (noscope)
            var->outofscope = TRUE;
        else
        {
            var->outofscope = FALSE;
            val = var->address = address + var->offset;
            if (var->pointer)
                unscope = !ReadValue(var->address, &val, 4, var->inreg ? &var
                    ->thread->regs: 0) || !val;
        }
        RefreshAddresses(var->subtype, val, unscope);
        var = var->link;
    }
}

//-------------------------------------------------------------------------

void WatchValue(char *typetab, char *buf, VARINFO *info, int onevalue)
{
    int i;
    if (info->outofscope || info->outofscopereg)
        sprintf(buf, "out of scope");
    else if (info->structure)
    {
        sprintf(buf, "STRUCTURE: %p", info->address);
    }
    else if (info->unionx)
    {
        sprintf(buf, "UNION: %p", info->address);
    }
    else if (info->pointer)
    {
        int val;
        if (ReadValue(info->address, &val, 4, info->inreg ? &info->thread->regs
            : 0))
        {
            info->editable = TRUE;
            if (onevalue)
                sprintf(buf, "0x%p ", val);
            else
                sprintf(buf, "POINTER: %p ", val);
            GetStringValue(info, buf + strlen(buf), 32, val);
        }
        else
            sprintf(buf, "POINTER: <UNKNOWN>");
    }
    else if (info->enumx)
    {
        info->editable = TRUE;
        HintEnum(typetab, info, buf, FALSE, onevalue);
    }
    else if (info->bitfield)
    {
        int signedtype;
        int v = HintBf(info, &signedtype);
        if (onevalue)
            if (signedtype)
                sprintf(buf, "0x%x", v);
            else
                sprintf(buf, "0x%x", v);
            else
                if (signedtype)
                    sprintf(buf, "%d(0x%x)", v, v);
                else
                    sprintf(buf, "%u(0x%x)", v, v);
        info->editable = TRUE;
    }
    else if (info->array)
    {
        sprintf(buf, "ARRAY: %p ", info->address);
        GetStringValue(info, buf + strlen(buf), 32, info->address);
    }
    else
    {
        int signedtype;
        char buf1[20];
        LLONG_TYPE v;
        info->editable = TRUE;
        switch (HintBasicType(info, &signedtype, buf1))
        {
            case T_INT8:
                #ifndef BORLANDC
                    v = *(LLONG_TYPE*)buf1;
                    if (onevalue)
                        if (signedtype)
                            sprintf(buf, "0x%llx", v);
                        else
                            sprintf(buf, "0x%llx", v);
                        else
                            if (signedtype)
                                sprintf(buf, "%lld(0x%llx)", v, v);
                            else
                                sprintf(buf, "%lld(0x%llx)", v, v);
                    break;
                #endif 
            default:
                sprintf(buf, "unknown type");
                break;

            case T_INT4:
                v = *(int*)buf1;
                if (onevalue)
                    if (signedtype)
                        sprintf(buf, "0x%x", (int)v);
                    else
                        sprintf(buf, "0x%x", (int)v);
                    else
                        if (signedtype)
                            sprintf(buf, "%d(0x%x)", (int)v, (int)v);
                        else
                            sprintf(buf, "%u(0x%x)", (int)v, (int)v);
                break;
            case T_BOOL08:
                if (buf1[0])
                    sprintf(buf, "True");
                else
                    sprintf(buf, "False");
                break;
            case T_REAL32:
            case T_IMAGINARY32:
                sprintf(buf, "%f", (double)*(float*)buf1);
                break;
            case T_REAL80:
            case T_IMAGINARY80:
                *(double*)buf1 = *(long double*)buf1;
            case T_REAL64:
            case T_IMAGINARY64:
                sprintf(buf, "%f", *(double*)buf1);
                break;
            case T_CPLX32:
                sprintf(buf, "%f + %f * I", (double)*(float*)buf1, (double)*(float *)(buf1 + 4));
                break;
            case T_CPLX64:
                sprintf(buf, "%f + %f * I", *(double *)buf1, *(double *)(buf1 + 8));
                break;
            case T_CPLX80:
                sprintf(buf, "%f + %f * I", (double)*(long double *)buf1, (double)*(long double *)(buf1 + 10));
                break;
        }
    }
}

//-------------------------------------------------------------------------

void RefreshData(char *typetab, VARINFO *var)
{
    while (var)
    {
        WatchValue(typetab, var->value, var, FALSE);
        RefreshData(typetab, var->subtype);
        var = var->link;
    }
}

//-------------------------------------------------------------------------

void RefreshItem(WATCHINFO *var, int address)
{
    RefreshAddresses(var->info, address, var->info->outofscope);
    RefreshData(var->typetab, var->info);

}

//-------------------------------------------------------------------------

HTREEITEM InsertItem(HTREEITEM hParent, HTREEITEM after, VARINFO *var)
{
    HTREEITEM rv;
    TV_INSERTSTRUCT t;
    memset(&t, 0, sizeof(t));
    t.hParent = hParent;
    t.hInsertAfter = after;
    #if !defined( _WIN32_IE) && !defined(__CCDL__)
        t.item.mask = 0;
        t.item.lParam = (int)var;
    #else 
        t.u.item.mask = 0;
        t.u.item.lParam = (int)var;
    #endif 
    rv = TreeView_InsertItem(hwndTree, &t);
    return rv;
}

//-------------------------------------------------------------------------

void InsertSubTree(HTREEITEM parent, HTREEITEM after, VARINFO *var, int index)
{
    while (var)
    {
        AddTypeInfoToName(watchinfo_list[index].typetab, var);
        var->hTreeItem = InsertItem(parent, after, var);
        var->watchindex = index;
        var->watchhead.col1Text = &var->screenname;
        var->watchhead.col2Text = &var->value;
        if (var->pointer && !var->subtype)
        {
            var->hTreeHolder = InsertItem(var->hTreeItem, TVI_LAST, var);
            TreeView_Expand(hwndTree, var->hTreeItem, TVE_COLLAPSE);
        }
        else
            InsertSubTree(var->hTreeItem, 0, var->subtype, index);
        after = var->hTreeItem;
        var = var->link;
    }
}

//-------------------------------------------------------------------------

void AddItem(char *typetab, DEBUG_INFO *dbg, char *symtab, VARINFO *var, int
    ebp, int cursoreip)
{
    WATCHINFO *x = MatchItem(var);
    if (x)
    {
        FreeVarInfo(var);
    }
    else
    {
        HTREEITEM previous = 0;
        if (watchinfo_count >= watchinfo_max)
        {
            if (watchinfo_max >= 128)
            {
                ExtendedMessageBox("Watch Window Full", MB_SETFOREGROUND |
                    MB_SYSTEMMODAL, 
                    "There are too many items in the watch window\nNot adding the current selection");
                return ;
            }
            watchinfo_max += 64;
            watchinfo_list = realloc(watchinfo_list, watchinfo_max *sizeof
                (WATCHINFO));
        }
        if (watchinfo_count)
            previous = watchinfo_list[watchinfo_count - 1].info->hTreeItem;
        memset(&watchinfo_list[watchinfo_count], 0, sizeof(watchinfo_list[0]));
        watchinfo_list[watchinfo_count].info = var;
        watchinfo_list[watchinfo_count].dbg_info = dbg;
        watchinfo_list[watchinfo_count].symtab = symtab;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -