11f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc# This file provides common utility functions for the test suite.
21f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
31f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorcfrom clang.cindex import Cursor
4fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorcfrom clang.cindex import TranslationUnit
51f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
61f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorcdef get_tu(source, lang='c', all_warnings=False):
71f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    """Obtain a translation unit from source and language.
81f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
91f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    By default, the translation unit is created from source file "t.<ext>"
101f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    where <ext> is the default file extension for the specified language. By
111f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    default it is C, so "t.c" is the default file name.
121f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
131f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    Supported languages are {c, cpp, objc}.
141f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
151f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    all_warnings is a convenience argument to enable all compiler warnings.
161f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    """
171f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    name = 't.c'
185b82b9606d9e36134724d5638efbc9d60fc8be90Anders Waldenborg    args = []
191f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    if lang == 'cpp':
201f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc        name = 't.cpp'
215b82b9606d9e36134724d5638efbc9d60fc8be90Anders Waldenborg        args.append('-std=c++11')
221f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    elif lang == 'objc':
231f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc        name = 't.m'
241f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    elif lang != 'c':
251f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc        raise Exception('Unknown language: %s' % lang)
261f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
271f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    if all_warnings:
285b82b9606d9e36134724d5638efbc9d60fc8be90Anders Waldenborg        args += ['-Wall', '-Wextra']
291f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
30fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc    return TranslationUnit.from_source(name, args, unsaved_files=[(name,
31fbf620bc2b7812e826f04befa31d3a48a86210baGregory Szorc                                       source)])
321f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
331f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorcdef get_cursor(source, spelling):
341f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    """Obtain a cursor from a source object.
351f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
361f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    This provides a convenient search mechanism to find a cursor with specific
371f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    spelling within a source. The first argument can be either a
381f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    TranslationUnit or Cursor instance.
391f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
401f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    If the cursor is not found, None is returned.
411f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    """
421f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    children = []
431f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    if isinstance(source, Cursor):
441f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc        children = source.get_children()
451f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    else:
461f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc        # Assume TU
471f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc        children = source.cursor.get_children()
481f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
491f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    for cursor in children:
501f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc        if cursor.spelling == spelling:
511f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc            return cursor
521f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
531f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc        # Recurse into children.
541f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc        result = get_cursor(cursor, spelling)
551f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc        if result is not None:
561f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc            return result
571f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
581f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    return None
59667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek
60667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimekdef get_cursors(source, spelling):
61667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    """Obtain all cursors from a source object with a specific spelling.
621f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
63667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    This provides a convenient search mechanism to find all cursors with specific
64667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    spelling within a source. The first argument can be either a
65667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    TranslationUnit or Cursor instance.
66667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek
67667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    If no cursors are found, an empty list is returned.
68667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    """
69667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    cursors = []
70667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    children = []
71667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    if isinstance(source, Cursor):
72667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek        children = source.get_children()
73667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    else:
74667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek        # Assume TU
75667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek        children = source.cursor.get_children()
76667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek
77667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    for cursor in children:
78667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek        if cursor.spelling == spelling:
79667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek            cursors.append(cursor)
80667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek
81667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek        # Recurse into children.
82667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek        cursors.extend(get_cursors(cursor, spelling))
83667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek
84667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    return cursors
85667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek
86667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek
87667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek
881f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc
891f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc__all__ = [
901f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    'get_cursor',
91667fd80de4c3b7b143ba98a3b73e9b9b200f6af0Manuel Klimek    'get_cursors',
921f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc    'get_tu',
931f1988fe75f27548459cabee2ea6162cbfd9add2Gregory Szorc]
94