1#############################################################################
2##
3## Copyright (C) 2017 The Qt Company Ltd.
4## Contact: https://www.qt.io/licensing/
5##
6## This file is part of the QtCore module of the Qt Toolkit.
7##
8## $QT_BEGIN_LICENSE:GPL-EXCEPT$
9## Commercial License Usage
10## Licensees holding valid commercial Qt licenses may use this file in
11## accordance with the commercial license agreement provided with the
12## Software or, alternatively, in accordance with the terms contained in
13## a written agreement between you and The Qt Company. For licensing terms
14## and conditions see https://www.qt.io/terms-conditions. For further
15## information use the contact form at https://www.qt.io/contact-us.
16##
17## GNU General Public License Usage
18## Alternatively, this file may be used under the terms of the GNU
19## General Public License version 3 as published by the Free Software
20## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21## included in the packaging of this file. Please review the following
22## information to ensure the GNU General Public License requirements will
23## be met: https://www.gnu.org/licenses/gpl-3.0.html.
24##
25## $QT_END_LICENSE$
26##
27#############################################################################
28
29import os
30import sys
31import imp
32
33from distutils.version import LooseVersion
34
35MODULE_NAME = 'qt'
36
37def import_bridge(path, debugger, session_dict, reload_module = False):
38    if not reload_module and MODULE_NAME in sys.modules:
39        del sys.modules[MODULE_NAME]
40
41    bridge = imp.load_source(MODULE_NAME, path)
42
43    if not hasattr(bridge, '__lldb_init_module'):
44        return None
45
46    # Make available for the current LLDB session, so that LLDB
47    # can find the functions when initializing the module.
48    session_dict[MODULE_NAME] = bridge
49
50    # Initialize the module now that it's available globally
51    bridge.__lldb_init_module(debugger, session_dict)
52
53    if not debugger.GetCategory('Qt'):
54        # Summary provider failed for some reason
55        del session_dict[MODULE_NAME]
56        return None
57
58    return bridge
59
60def report_success(bridge):
61    print "Using Qt summary providers from Creator %s in '%s'" \
62        % (bridge.CREATOR_VERSION, bridge.CREATOR_PATH)
63
64def __lldb_init_module(debugger, session_dict):
65    # Check if the module has already been imported globally. This ensures
66    # that the Qt Creator application search is only performed once per
67    # LLDB process invocation, while still reloading for each session.
68    if MODULE_NAME in sys.modules:
69        module = sys.modules[MODULE_NAME]
70        # Reload module for this sessions
71        bridge = import_bridge(module.__file__, debugger, session_dict,
72            reload_module = True)
73        if bridge:
74            report_success(bridge)
75            return
76
77    versions = {}
78    for install in os.popen(
79        'mdfind kMDItemCFBundleIdentifier=org.qt-project.qtcreator'
80            '| while read p;'
81                'do echo $p=$(mdls "$p" -name kMDItemVersion -raw);'
82            'done'):
83        install = install.strip()
84        (p, v) = install.split('=')
85        versions[v] = p
86
87    for version in sorted(versions, key=LooseVersion, reverse=True):
88        path = versions[version]
89
90        bridge_path = path + '/Contents/Resources/debugger/lldbbridge.py'
91        bridge = import_bridge(bridge_path, debugger, session_dict)
92        if bridge:
93            bridge.CREATOR_VERSION = version
94            bridge.CREATOR_PATH = path
95            report_success(bridge)
96            return
97
98    print "Could not find Qt Creator installation, no Qt summary providers installed"
99