# Copyright (C) 2010, Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""GDB support for WebKit types.

Add this to your gdb by amending your ~/.gdbinit as follows:
  python
  import sys
  sys.path.insert(0, "/path/to/tools/gdb/")
  import webkit
"""

import gdb
import re
import struct


def guess_string_length(ptr):
    """Guess length of string pointed by ptr.

    Returns a tuple of (length, an error message).
    """
    # Try to guess at the length.
    for i in range(0, 2048):
        try:
            if int((ptr + i).dereference()) == 0:
                return i, ''
        except RuntimeError:
            # We indexed into inaccessible memory; give up.
            return i, ' (gdb hit inaccessible memory)'
    return 256, ' (gdb found no trailing NUL)'


def ustring_to_string(ptr, length=None):
    """Convert a pointer to UTF-16 data into a Python string encoded with utf-8.

    ptr and length are both gdb.Value objects.
    If length is unspecified, will guess at the length."""
    error_message = ''
    if length is None:
        length, error_message = guess_string_length(ptr)
    else:
        length = int(length)
    char_vals = [int((ptr + i).dereference()) for i in range(length)]
    string = struct.pack('H' * length, *char_vals).decode('utf-16', 'replace').encode('utf-8')
    return string + error_message


def lstring_to_string(ptr, length=None):
    """Convert a pointer to LChar* data into a Python (non-Unicode) string.

    ptr and length are both gdb.Value objects.
    If length is unspecified, will guess at the length."""
    error_message = ''
    if length is None:
        length, error_message = guess_string_length(ptr)
    else:
        length = int(length)
    string = ''.join([chr((ptr + i).dereference()) for i in range(length)])
    return string + error_message


class StringPrinter(object):
    "Shared code between different string-printing classes"
    def __init__(self, val):
        self.val = val

    def display_hint(self):
        return 'string'


class UCharStringPrinter(StringPrinter):
    "Print a UChar*; we must guess at the length"
    def to_string(self):
        return ustring_to_string(self.val)


class LCharStringPrinter(StringPrinter):
    "Print a LChar*; we must guess at the length"
    def to_string(self):
        return lstring_to_string(self.val)


class WTFAtomicStringPrinter(StringPrinter):
    "Print a WTF::AtomicString"
    def to_string(self):
        return self.val['m_string']


class WTFCStringPrinter(StringPrinter):
    "Print a WTF::CString"
    def to_string(self):
        string = (self.val['m_buffer']['m_ptr'] + 1).cast(gdb.lookup_type('char').pointer())
        length = self.val['m_buffer']['m_ptr']['m_length']
        return lstring_to_string(string, length)


class WTFStringImplPrinter(StringPrinter):
    "Print a WTF::StringImpl"
    def get_length(self):
        return self.val['m_length']

    def to_string(self):
        if self.is_8bit():
            return lstring_to_string(self.val['m_data8'], self.get_length())
        return ustring_to_string(self.val['m_data16'], self.get_length())

    def is_8bit(self):
        return self.val['m_hashAndFlags'] & self.val['s_hashFlag8BitBuffer']


class WTFStringPrinter(StringPrinter):
    "Print a WTF::String"
    def stringimpl_ptr(self):
        return self.val['m_impl']['m_ptr']

    def get_length(self):
        if not self.stringimpl_ptr():
            return 0
        return WTFStringImplPrinter(self.stringimpl_ptr().dereference()).get_length()

    def to_string(self):
        if not self.stringimpl_ptr():
            return '(null)'
        return self.stringimpl_ptr().dereference()



class JSCIdentifierPrinter(StringPrinter):
    "Print a JSC::Identifier"
    def to_string(self):
        return WTFStringPrinter(self.val['m_string']).to_string()


class JSCJSStringPrinter(StringPrinter):
    "Print a JSC::JSString"
    def to_string(self):
        if self.val['m_length'] == 0:
            return ''

        return WTFStringPrinter(self.val['m_value']).to_string()


class WebCoreLayoutUnitPrinter:
    "Print a WebCore::LayoutUnit"
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return "%gpx (%d)" % (self.val['m_value'] / 64.0, self.val['m_value'])


class WebCoreLayoutSizePrinter:
    "Print a WebCore::LayoutSize"
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return 'LayoutSize(%s, %s)' % (WebCoreLayoutUnitPrinter(self.val['m_width']).to_string(), WebCoreLayoutUnitPrinter(self.val['m_height']).to_string())


class WebCoreLayoutPointPrinter:
    "Print a WebCore::LayoutPoint"
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return 'LayoutPoint(%s, %s)' % (WebCoreLayoutUnitPrinter(self.val['m_x']).to_string(), WebCoreLayoutUnitPrinter(self.val['m_y']).to_string())


class WebCoreQualifiedNamePrinter(StringPrinter):
    "Print a WebCore::QualifiedName"

    def __init__(self, val):
        super(WebCoreQualifiedNamePrinter, self).__init__(val)
        self.prefix_length = 0
        self.length = 0
        if self.val['m_impl']:
            self.prefix_printer = WTFStringPrinter(
                self.val['m_impl']['m_prefix']['m_string'])
            self.local_name_printer = WTFStringPrinter(
                self.val['m_impl']['m_localName']['m_string'])
            self.prefix_length = self.prefix_printer.get_length()
            if self.prefix_length > 0:
                self.length = (self.prefix_length + 1 +
                    self.local_name_printer.get_length())
            else:
                self.length = self.local_name_printer.get_length()

    def get_length(self):
        return self.length

    def to_string(self):
        if self.get_length() == 0:
            return "(null)"
        else:
            if self.prefix_length > 0:
                return (self.prefix_printer.to_string() + ":" +
                    self.local_name_printer.to_string())
            else:
                return self.local_name_printer.to_string()


class WTFVectorPrinter:
    """Pretty Printer for a WTF::Vector.

    The output of this pretty printer is similar to the output of std::vector's
    pretty printer, which is bundled in gcc.

    Example gdb session should look like:
    (gdb) p v
    $3 = WTF::Vector of length 7, capacity 16 = {7, 17, 27, 37, 47, 57, 67}
    (gdb) set print elements 3
    (gdb) p v
    $6 = WTF::Vector of length 7, capacity 16 = {7, 17, 27...}
    (gdb) set print array
    (gdb) p v
    $7 = WTF::Vector of length 7, capacity 16 = {
      7,
      17,
      27
      ...
    }
    (gdb) set print elements 200
    (gdb) p v
    $8 = WTF::Vector of length 7, capacity 16 = {
      7,
      17,
      27,
      37,
      47,
      57,
      67
    }
    """

    class Iterator:
        def __init__(self, start, finish):
            self.item = start
            self.finish = finish
            self.count = 0

        def __iter__(self):
            return self

        def next(self):
            if self.item == self.finish:
                raise StopIteration
            count = self.count
            self.count += 1
            element = self.item.dereference()
            self.item += 1
            return ('[%d]' % count, element)

    def __init__(self, val):
        self.val = val

    def children(self):
        start = self.val['m_buffer']
        return self.Iterator(start, start + self.val['m_size'])

    def to_string(self):
        return ('%s of length %d, capacity %d'
                % ('WTF::Vector', self.val['m_size'], self.val['m_capacity']))

    def display_hint(self):
        return 'array'

def add_pretty_printers():
    pretty_printers = (
        (re.compile("^WTF::Vector<.*>$"), WTFVectorPrinter),
        (re.compile("^WTF::AtomicString$"), WTFAtomicStringPrinter),
        (re.compile("^WTF::CString$"), WTFCStringPrinter),
        (re.compile("^WTF::String$"), WTFStringPrinter),
        (re.compile("^WTF::StringImpl$"), WTFStringImplPrinter),
        (re.compile("^WebCore::LayoutUnit$"), WebCoreLayoutUnitPrinter),
        (re.compile("^WebCore::LayoutPoint$"), WebCoreLayoutPointPrinter),
        (re.compile("^WebCore::LayoutSize$"), WebCoreLayoutSizePrinter),
        (re.compile("^WebCore::QualifiedName$"), WebCoreQualifiedNamePrinter),
        (re.compile("^JSC::Identifier$"), JSCIdentifierPrinter),
        (re.compile("^JSC::JSString$"), JSCJSStringPrinter),
    )

    def lookup_function(val):
        """Function used to load pretty printers; will be passed to GDB."""
        type = val.type
        if type.code == gdb.TYPE_CODE_REF:
            type = type.target()
        type = type.unqualified().strip_typedefs()
        tag = type.tag
        if tag:
            for function, pretty_printer in pretty_printers:
                if function.search(tag):
                    return pretty_printer(val)

        if type.code == gdb.TYPE_CODE_PTR:
            name = str(type.target().unqualified())
            if name == 'UChar':
                return UCharStringPrinter(val)
            if name == 'LChar':
                return LCharStringPrinter(val)
        return None

    gdb.pretty_printers.append(lookup_function)


add_pretty_printers()


class PrintPathToRootCommand(gdb.Command):
    """Command for printing WebKit Node trees.

    Usage: printpathtoroot variable_name"""

    def __init__(self):
        super(PrintPathToRootCommand, self).__init__("printpathtoroot",
            gdb.COMMAND_SUPPORT,
            gdb.COMPLETE_NONE)

    def invoke(self, arg, from_tty):
        element_type = gdb.lookup_type('WebCore::Element')
        node_type = gdb.lookup_type('WebCore::Node')
        frame = gdb.selected_frame()
        try:
            val = gdb.Frame.read_var(frame, arg)
        except:
            print("No such variable, or invalid type")
            return

        target_type = str(val.type.target().strip_typedefs())
        if target_type == str(node_type):
            stack = []
            while val:
                stack.append([val,
                    val.cast(element_type.pointer()).dereference()['m_tagName']])
                val = val.dereference()['m_parent']

            padding = ''
            while len(stack) > 0:
                pair = stack.pop()
                print(padding, pair[1], pair[0])
                padding = padding + '  '
        else:
            print('Sorry: I don\'t know how to deal with %s yet.' % target_type)


PrintPathToRootCommand()
