1# This file provides common utility functions for the test suite. 2 3import os 4HAS_FSPATH = hasattr(os, 'fspath') 5 6if HAS_FSPATH: 7 from pathlib import Path as str_to_path 8else: 9 str_to_path = None 10 11import unittest 12 13from clang.cindex import Cursor 14from clang.cindex import TranslationUnit 15 16def 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 43def 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 61def 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 81skip_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