1 | # This file provides common utility functions for the test suite. |
2 | |
3 | import os |
4 | HAS_FSPATH = hasattr(os, 'fspath') |
5 | |
6 | if HAS_FSPATH: |
7 | from pathlib import Path as str_to_path |
8 | else: |
9 | str_to_path = None |
10 | |
11 | import unittest |
12 | |
13 | from clang.cindex import Cursor |
14 | from clang.cindex import TranslationUnit |
15 | |
16 | def get_tu(source, lang='c', all_warnings=False, flags=[]): |
17 | """Obtain a translation unit from source and language. |
18 | |
19 | By default, the translation unit is created from source file "t.<ext>" |
20 | where <ext> is the default file extension for the specified language. By |
21 | default it is C, so "t.c" is the default file name. |
22 | |
23 | Supported languages are {c, cpp, objc}. |
24 | |
25 | all_warnings is a convenience argument to enable all compiler warnings. |
26 | """ |
27 | args = list(flags) |
28 | name = 't.c' |
29 | if lang == 'cpp': |
30 | name = 't.cpp' |
31 | args.append('-std=c++11') |
32 | elif lang == 'objc': |
33 | name = 't.m' |
34 | elif lang != 'c': |
35 | raise Exception('Unknown language: %s' % lang) |
36 | |
37 | if all_warnings: |
38 | args += ['-Wall', '-Wextra'] |
39 | |
40 | return TranslationUnit.from_source(name, args, unsaved_files=[(name, |
41 | source)]) |
42 | |
43 | def get_cursor(source, spelling): |
44 | """Obtain a cursor from a source object. |
45 | |
46 | This provides a convenient search mechanism to find a cursor with specific |
47 | spelling within a source. The first argument can be either a |
48 | TranslationUnit or Cursor instance. |
49 | |
50 | If the cursor is not found, None is returned. |
51 | """ |
52 | # Convenience for calling on a TU. |
53 | root_cursor = source if isinstance(source, Cursor) else source.cursor |
54 | |
55 | for cursor in root_cursor.walk_preorder(): |
56 | if cursor.spelling == spelling: |
57 | return cursor |
58 | |
59 | return None |
60 | |
61 | def get_cursors(source, spelling): |
62 | """Obtain all cursors from a source object with a specific spelling. |
63 | |
64 | This provides a convenient search mechanism to find all cursors with |
65 | specific spelling within a source. The first argument can be either a |
66 | TranslationUnit or Cursor instance. |
67 | |
68 | If no cursors are found, an empty list is returned. |
69 | """ |
70 | # Convenience for calling on a TU. |
71 | root_cursor = source if isinstance(source, Cursor) else source.cursor |
72 | |
73 | cursors = [] |
74 | for cursor in root_cursor.walk_preorder(): |
75 | if cursor.spelling == spelling: |
76 | cursors.append(cursor) |
77 | |
78 | return cursors |
79 | |
80 | |
81 | skip_if_no_fspath = unittest.skipUnless(HAS_FSPATH, |
82 | "Requires file system path protocol / Python 3.6+") |
83 | |
84 | __all__ = [ |
85 | 'get_cursor', |
86 | 'get_cursors', |
87 | 'get_tu', |
88 | 'skip_if_no_fspath', |
89 | 'str_to_path', |
90 | ] |
91 | |