/*
 * File types.c - datatype handling stuff for internal debugger.
 *
 * Copyright (C) 1997, Eric Youngdale.
 *
 * 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
 *
 * Note: This really doesn't do much at the moment, but it forms the framework
 * upon which full support for datatype handling will eventually be built.
 */

#include "config.h"
#include <stdlib.h>

#include "debugger.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winedbg);

/******************************************************************
 *		types_extract_as_integer
 *
 * Given a lvalue, try to get an integral (or pointer/address) value
 * out of it
 */
long int types_extract_as_integer(const struct dbg_lvalue* lvalue)
{
    long int            rtn = 0;
    DWORD               tag, size, bt;

    if (lvalue->type.id == dbg_itype_none ||
        !types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
        return 0;

    switch (tag)
    {
    case SymTagBaseType:
        if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size) ||
            !types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt))
        {
            WINE_ERR("Couldn't get information\n");
            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        }
        if (size > sizeof(rtn))
        {
            WINE_ERR("Size too large (%lu)\n", size);
            return 0;
        }
        /* FIXME: we have an ugly & non portable thing here !!! */
        if (!memory_read_value(lvalue, size, &rtn)) return 0;

        /* now let's do some promotions !! */
        switch (bt)
        {
        case btInt:
            /* propagate sign information */
            if (((size & 3) != 0) && (rtn >> (size * 8 - 1)) != 0)
                rtn |= (-1) << (size * 8);
            break;
        case btUInt:
        case btChar:
            break;
        case btFloat:
            RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
        }
        break;
    case SymTagPointerType:
        if (!memory_read_value(lvalue, sizeof(void*), &rtn)) return 0;
        break;
    case SymTagArrayType:
    case SymTagUDT:
        assert(lvalue->cookie == DLV_TARGET);
        if (!memory_read_value(lvalue, sizeof(rtn), &rtn)) return 0;
        break;
    case SymTagEnum:
        assert(lvalue->cookie == DLV_TARGET);
        if (!memory_read_value(lvalue, sizeof(rtn), &rtn)) return 0;
        break;
    default:
        WINE_FIXME("Unsupported tag %lu\n", tag);
        rtn = 0;
        break;
    }

    return rtn;
}

/******************************************************************
 *		types_deref
 *
 */
BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result)
{
    DWORD       tag;

    memset(result, 0, sizeof(*result));
    result->type.id = dbg_itype_none;
    result->type.module = 0;

    /*
     * Make sure that this really makes sense.
     */
    if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
        tag != SymTagPointerType ||
        memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset) ||
        !types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id))
        return FALSE;
    result->type.module = lvalue->type.module;
    result->cookie = DLV_TARGET;
    /* FIXME: this is currently buggy.
     * there is no way to tell were the deref:ed value is...
     * for example:
     *	x is a pointer to struct s, x being on the stack
     *		=> lvalue is in debuggee, result is in debugger
     *	x is a pointer to struct s, x being optimized into a reg
     *		=> lvalue is debugger, result is debuggee
     *	x is a pointer to internal variable x
     *	       	=> lvalue is debugger, result is debuggee
     * so we force debuggee address space, because dereferencing pointers to
     * internal variables is very unlikely. A correct fix would be
     * rather large.
     */
    result->addr.Mode = AddrModeFlat;
    return TRUE;
}

/******************************************************************
 *		types_get_udt_element_lvalue
 *
 * Implement a structure derefencement
 */
static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, 
                                         const struct dbg_type* type, long int* tmpbuf)
{
    DWORD       offset, length, bitoffset;
    DWORD       bt;
    unsigned    mask;

    types_get_info(type, TI_GET_TYPE, &lvalue->type.id);
    lvalue->type.module = type->module;
    types_get_info(type, TI_GET_OFFSET, &offset);

    if (types_get_info(type, TI_GET_BITPOSITION, &bitoffset))
    {
        types_get_info(type, TI_GET_LENGTH, &length);
        if (length > sizeof(*tmpbuf)) return FALSE;
        /*
         * Bitfield operation.  We have to extract the field and store
         * it in a temporary buffer so that we get it all right.
         */
        lvalue->addr.Offset += offset;
        if (!memory_read_value(lvalue, sizeof(*tmpbuf), tmpbuf)) return FALSE;
        mask = 0xffffffff << length;
        *tmpbuf >>= bitoffset & 7;
        *tmpbuf &= ~mask;

        lvalue->cookie      = DLV_HOST;
        lvalue->addr.Offset = (DWORD)tmpbuf;

        /*
         * OK, now we have the correct part of the number.
         * Check to see whether the basic type is signed or not, and if so,
         * we need to sign extend the number.
         */
        if (types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt) && 
            bt == btInt && (*tmpbuf & (1 << (length - 1))))
        {
            *tmpbuf |= mask;
        }
        return TRUE;
    }
    if (types_get_info(type, TI_GET_OFFSET, &offset))
    {
        lvalue->addr.Offset += offset;
        return TRUE;
    }
    return FALSE;
}

/******************************************************************
 *		types_udt_find_element
 *
 */
BOOL types_udt_find_element(struct dbg_lvalue* lvalue, const char* name, long int* tmpbuf)
{
    DWORD                       tag, count;
    char                        buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
    TI_FINDCHILDREN_PARAMS*     fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
    WCHAR*                      ptr;
    char                        tmp[256];
    int                         i;
    struct dbg_type             type;

    if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) ||
        tag != SymTagUDT)
        return FALSE;

    if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
    {
        fcp->Start = 0;
        while (count)
        {
            fcp->Count = min(count, 256);
            if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
            {
                type.module = lvalue->type.module;
                for (i = 0; i < min(fcp->Count, count); i++)
                {
                    ptr = NULL;
                    type.id = fcp->ChildId[i];
                    types_get_info(&type, TI_GET_SYMNAME, &ptr);
                    if (!ptr) continue;
                    WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
                    HeapFree(GetProcessHeap(), 0, ptr);
                    if (strcmp(tmp, name)) continue;

                    return types_get_udt_element_lvalue(lvalue, &type, tmpbuf);
                }
            }
            count -= min(count, 256);
            fcp->Start += 256;
        }
    }
    return FALSE;
}

/******************************************************************
 *		types_array_index
 *
 * Grab an element from an array
 */
BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, 
                       struct dbg_lvalue* result)
{
    DWORD       tag, length, count;

    if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
        return FALSE;
    switch (tag)
    {
    case SymTagArrayType:
        types_get_info(&lvalue->type, TI_GET_COUNT, &count);
        if (index < 0 || index >= count) return FALSE;
        /* fall through */
    case SymTagPointerType:
        /*
         * Get the base type, so we know how much to index by.
         */
        types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id);
        result->type.module = lvalue->type.module;
        types_get_info(&result->type, TI_GET_LENGTH, &length);
        /* Contents of array must be on same target */
        result->addr.Mode = lvalue->addr.Mode;
        memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset);
        result->addr.Offset += index * length;
        break;
    default:
        assert(FALSE);
    }
    return TRUE;
}

struct type_find_t
{
    unsigned long       result;  /* out: the found type */
    enum SymTagEnum     tag;    /* in: the tag to look for */
    union
    {
        unsigned long           typeid;
        const char*             name;
    } u;
};

static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
{
    struct type_find_t* user = (struct type_find_t*)_user;
    BOOL                ret = TRUE;
    struct dbg_type     type;

    if (sym->Tag == user->tag)
    {
        switch (user->tag)
        {
        case SymTagUDT:
            if (!strcmp(user->u.name, sym->Name))
            {
                user->result = sym->TypeIndex;
                ret = FALSE;
            }
            break;
        case SymTagPointerType:
            type.module = sym->ModBase;
            type.id = sym->TypeIndex;
            if (types_get_info(&type, TI_GET_TYPE, &type.id) && type.id == user->u.typeid)
            {
                user->result = sym->TypeIndex;
                ret = FALSE;
            }
        default: break;
        }
    }
    return ret;
}

/******************************************************************
 *		types_find_pointer
 *
 * Should look up in module based at linear whether (typeid*) exists
 * Otherwise, we could create it locally
 */
struct dbg_type types_find_pointer(const struct dbg_type* type)
{
    struct type_find_t  f;
    struct dbg_type     ret;

    f.result = dbg_itype_none;
    f.tag = SymTagPointerType;
    f.u.typeid = type->id;
    SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f);
    ret.module = type->module;
    ret.id = f.result;
    return ret;
}

/******************************************************************
 *		types_find_type
 *
 * Should look up in the module based at linear address whether a type
 * named 'name' and with the correct tag exists
 */
struct dbg_type types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag)

{
    struct type_find_t  f;
    struct dbg_type     ret;

    f.result = dbg_itype_none;
    f.tag = tag;
    f.u.name = name;
    SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f);
    ret.module = linear;
    ret.id = f.result;
    return ret;
}

/***********************************************************************
 *           print_value
 *
 * Implementation of the 'print' command.
 */
void print_value(const struct dbg_lvalue* lvalue, char format, int level)
{
    struct dbg_lvalue   lvalue_field;
    int		        i;
    DWORD               tag;
    DWORD               count;
    DWORD               size;

    if (lvalue->type.id == dbg_itype_none)
    {
        /* No type, just print the addr value */
        print_bare_address(&lvalue->addr);
        goto leave;
    }

    if (format == 'i' || format == 's' || format == 'w' || format == 'b' || format == 'g')
    {
        dbg_printf("Format specifier '%c' is meaningless in 'print' command\n", format);
        format = '\0';
    }

    if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag))
    {
        WINE_FIXME("---error\n");
        return;
    }
    switch (tag)
    {
    case SymTagBaseType:
    case SymTagEnum:
    case SymTagPointerType:
        print_basic(lvalue, 1, format);
        break;
    case SymTagUDT:
        if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
        {
            char                        buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
            TI_FINDCHILDREN_PARAMS*     fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
            WCHAR*                      ptr;
            char                        tmp[256];
            long int                    tmpbuf;
            struct dbg_type             type;

            dbg_printf("{");
            fcp->Start = 0;
            while (count)
            {
                fcp->Count = min(count, 256);
                if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
                {
                    for (i = 0; i < min(fcp->Count, count); i++)
                    {
                        ptr = NULL;
                        type.module = (unsigned long)memory_to_linear_addr(&lvalue->addr);
                        type.id = fcp->ChildId[i];
                        types_get_info(&type, TI_GET_SYMNAME, &ptr);
                        if (!ptr) continue;
                        WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
                        dbg_printf("%s=", tmp);
                        HeapFree(GetProcessHeap(), 0, ptr);
                        lvalue_field = *lvalue;
                        if (types_get_udt_element_lvalue(&lvalue_field, &type, &tmpbuf))
                        {
                            print_value(&lvalue_field, format, level + 1);
                        }
                        if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
                    }
                }
                count -= min(count, 256);
                fcp->Start += 256;
            }
            dbg_printf("}");
        }
        break;
    case SymTagArrayType:
        /*
         * Loop over all of the entries, printing stuff as we go.
         */
        count = 1; size = 1;
        types_get_info(&lvalue->type, TI_GET_COUNT, &count);
        types_get_info(&lvalue->type, TI_GET_LENGTH, &size);

        if (size == count)
	{
            unsigned    len;
            char        buffer[256];
            /*
             * Special handling for character arrays.
             */
            /* FIXME should check basic type here (should be a char!!!!)... */
            len = min(count, sizeof(buffer));
            memory_get_string(dbg_curr_process->handle,
                              memory_to_linear_addr(&lvalue->addr),
                              lvalue->cookie == DLV_TARGET, TRUE, buffer, len);
            dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
            break;
        }
        lvalue_field = *lvalue;
        types_get_info(&lvalue->type, TI_GET_TYPE, &lvalue_field.type.id);
        dbg_printf("{");
        for (i = 0; i < count; i++)
	{
            print_value(&lvalue_field, format, level + 1);
            lvalue_field.addr.Offset += size / count;
            dbg_printf((i == count - 1) ? "}" : ", ");
	}
        break;
    case SymTagFunctionType:
        dbg_printf("Function ");
        print_bare_address(&lvalue->addr);
        dbg_printf(": ");
        types_print_type(&lvalue->type, FALSE);
        break;
    default:
        WINE_FIXME("Unknown tag (%lu)\n", tag);
        RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
        break;
    }

leave:

    if (level == 0) dbg_printf("\n");
}

static BOOL CALLBACK print_types_cb(PSYMBOL_INFO sym, ULONG size, void* ctx)
{
    struct dbg_type     type;
    type.module = sym->ModBase;
    type.id = sym->TypeIndex;
    dbg_printf("Mod: %08lx ID: %08lx \n", type.module, type.id);
    types_print_type(&type, TRUE);
    dbg_printf("\n");
    return TRUE;
}

static BOOL CALLBACK print_types_mod_cb(PSTR mod_name, DWORD base, void* ctx)
{
    return SymEnumTypes(dbg_curr_process->handle, base, print_types_cb, ctx);
}

int print_types(void)
{
    SymEnumerateModules(dbg_curr_process->handle, print_types_mod_cb, NULL);
    return 0;
}

int types_print_type(const struct dbg_type* type, BOOL details)
{
    WCHAR*              ptr;
    char                tmp[256];
    const char*         name;
    DWORD               tag, udt, count;
    struct dbg_type     subtype;

    if (type->id == dbg_itype_none || !types_get_info(type, TI_GET_SYMTAG, &tag))
    {
        dbg_printf("--invalid--<%lxh>--", type->id);
        return FALSE;
    }

    if (types_get_info(type, TI_GET_SYMNAME, &ptr) && ptr)
    {
        WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
        name = tmp;
        HeapFree(GetProcessHeap(), 0, ptr);
    }
    else name = "--none--";

    switch (tag)
    {
    case SymTagBaseType:
        if (details) dbg_printf("Basic<%s>", name); else dbg_printf("%s", name);
        break;
    case SymTagPointerType:
        types_get_info(type, TI_GET_TYPE, &subtype.id);
        subtype.module = type->module;
        types_print_type(&subtype, FALSE);
        dbg_printf("*");
        break;
    case SymTagUDT:
        types_get_info(type, TI_GET_UDTKIND, &udt);
        switch (udt)
        {
        case UdtStruct: dbg_printf("struct %s", name); break;
        case UdtUnion:  dbg_printf("union %s", name); break;
        case UdtClass:  dbg_printf("class %s", name); break;
        }
        if (details &&
            types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
        {
            char                        buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
            TI_FINDCHILDREN_PARAMS*     fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
            WCHAR*                      ptr;
            char                        tmp[256];
            int                         i;
            struct dbg_type             type_elt;
            dbg_printf(" {");

            fcp->Start = 0;
            while (count)
            {
                fcp->Count = min(count, 256);
                if (types_get_info(type, TI_FINDCHILDREN, fcp))
                {
                    for (i = 0; i < min(fcp->Count, count); i++)
                    {
                        ptr = NULL;
                        type_elt.module = type->module;
                        type_elt.id = fcp->ChildId[i];
                        types_get_info(&type_elt, TI_GET_SYMNAME, &ptr);
                        if (!ptr) continue;
                        WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
                        HeapFree(GetProcessHeap(), 0, ptr);
                        dbg_printf("%s", tmp);
                        if (types_get_info(&type_elt, TI_GET_TYPE, &type_elt.id))
                        {
                            dbg_printf(":");
                            types_print_type(&type_elt, details);
                        }
                        if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
                    }
                }
                count -= min(count, 256);
                fcp->Start += 256;
            }
            dbg_printf("}");
        }
        break;
    case SymTagArrayType:
        types_get_info(type, TI_GET_TYPE, &subtype.id);
        subtype.module = type->module;
        types_print_type(&subtype, details);
        dbg_printf(" %s[]", name);
        break;
    case SymTagEnum:
        dbg_printf("enum %s", name);
        break;
    case SymTagFunctionType:
        types_get_info(type, TI_GET_TYPE, &subtype.id);
        subtype.module = type->module;
        types_print_type(&subtype, FALSE);
        dbg_printf(" (*%s)(", name);
        if (types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
        {
            char                        buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
            TI_FINDCHILDREN_PARAMS*     fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
            int                         i;

            fcp->Start = 0;
            while (count)
            {
                fcp->Count = min(count, 256);
                if (types_get_info(type, TI_FINDCHILDREN, fcp))
                {
                    for (i = 0; i < min(fcp->Count, count); i++)
                    {
                        subtype.id = fcp->ChildId[i];
                        types_print_type(&subtype, FALSE);
                        if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
                    }
                }
                count -= min(count, 256);
                fcp->Start += 256;
            }
        }
        dbg_printf(")");
        break;
    default:
        WINE_ERR("Unknown type %lu for %s\n", tag, name);
        break;
    }
    
    return TRUE;
}

BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
{
    if (type->id == dbg_itype_none) return FALSE;
    if (type->module != 0)
        return SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo);

    assert(type->id >= dbg_itype_first);
/* helper to typecast pInfo to its expected type (_t) */
#define X(_t) (*((_t*)pInfo))

    switch (type->id)
    {
    case dbg_itype_unsigned_int:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD) = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD) = 4; break;
        case TI_GET_BASETYPE:   X(DWORD) = btUInt; break;
        default: WINE_FIXME("unsupported %u for u-int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_signed_int:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD) = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD) = 4; break;
        case TI_GET_BASETYPE:   X(DWORD) = btInt; break;
        default: WINE_FIXME("unsupported %u for s-int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_unsigned_short_int:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD) = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD) = 2; break;
        case TI_GET_BASETYPE:   X(DWORD) = btUInt; break;
        default: WINE_FIXME("unsupported %u for u-short int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_signed_short_int:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD) = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD) = 2; break;
        case TI_GET_BASETYPE:   X(DWORD) = btInt; break;
        default: WINE_FIXME("unsupported %u for s-short int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_unsigned_char_int:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD) = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD) = 1; break;
        case TI_GET_BASETYPE:   X(DWORD) = btUInt; break;
        default: WINE_FIXME("unsupported %u for u-char int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_signed_char_int:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD) = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD) = 1; break;
        case TI_GET_BASETYPE:   X(DWORD) = btInt; break;
        default: WINE_FIXME("unsupported %u for s-char int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_char:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD) = SymTagBaseType; break;
        case TI_GET_LENGTH:     X(DWORD) = 1; break;
        case TI_GET_BASETYPE:   X(DWORD) = btChar; break;
        default: WINE_FIXME("unsupported %u for char int\n", ti); return FALSE;
        }
        break;
    case dbg_itype_astring:
        switch (ti)
        {
        case TI_GET_SYMTAG:     X(DWORD) = SymTagPointerType; break;
        case TI_GET_LENGTH:     X(DWORD) = 4; break;
        case TI_GET_TYPE:       X(DWORD) = dbg_itype_char; break;
        default: WINE_FIXME("unsupported %u for a string\n", ti); return FALSE;
        }
        break;
    default: WINE_FIXME("unsupported type id 0x%lx\n", type->id);
    }

#undef X
    return TRUE;
}
