|
8 | 8 | import argparse |
9 | 9 | import re |
10 | 10 | import shutil |
| 11 | +import subprocess |
11 | 12 |
|
12 | 13 | from fnmatch import fnmatch |
13 | 14 | from pathlib import Path |
@@ -37,6 +38,34 @@ def iter_code_files(root: Path) -> Iterable[Path]: |
37 | 38 | for ext in (".c", ".h"): |
38 | 39 | yield from directory_path.rglob(f"*{ext}") |
39 | 40 |
|
| 41 | +def run_ctags(file: Path) -> Set[str]: |
| 42 | + """ |
| 43 | + Extract the C identifiers in `file` using ctags. |
| 44 | +
|
| 45 | + Identifiers of the following types are returned (with their corresponding |
| 46 | + ctags c-kinds flag in parentheses): |
| 47 | +
|
| 48 | + - macro definitions (d) |
| 49 | + - enum values (e) |
| 50 | + - functions (f) |
| 51 | + - enum tags (g) |
| 52 | + - function prototypes (p) |
| 53 | + - struct tags (s) |
| 54 | + - typedefs (t) |
| 55 | + - union tags (u) |
| 56 | + - global variables (v) |
| 57 | + """ |
| 58 | + |
| 59 | + result = subprocess.run( |
| 60 | + ["ctags", "-x", "--language-force=C", "--c-kinds=defgpstuv", str(file)], |
| 61 | + capture_output=True, text=True, check=True |
| 62 | + ) |
| 63 | + identifiers = set() |
| 64 | + for line in result.stdout.splitlines(): |
| 65 | + identifiers.add(line.split()[0]) |
| 66 | + |
| 67 | + return identifiers |
| 68 | + |
40 | 69 | class TestDriverGenerator: |
41 | 70 | """A TF-PSA-Crypto test driver generator""" |
42 | 71 | def __init__(self, dst_dir: Path, driver: str): |
@@ -105,6 +134,25 @@ def build_tree(self, src_dir: Path, exclude_files: Optional[Set[str]] = None) -> |
105 | 134 | self.__rewrite_inclusions_in_file(f, headers, \ |
106 | 135 | src_include_dir_name, self.driver) |
107 | 136 |
|
| 137 | + def get_identifiers_with_prefixes(self, prefixes: Set[str]): |
| 138 | + """ |
| 139 | + Return the identifiers in the test driver that start with any of the given |
| 140 | + prefixes. |
| 141 | +
|
| 142 | + All exposed identifiers are expected to start with one of these prefixes. |
| 143 | + The returned set is therefore a superset of the exposed identifiers that |
| 144 | + need to be prefixed. |
| 145 | + """ |
| 146 | + identifiers = set() |
| 147 | + for file in iter_code_files(self.dst_dir): |
| 148 | + identifiers.update(run_ctags(file)) |
| 149 | + |
| 150 | + identifiers_with_prefixes = set() |
| 151 | + for identifier in identifiers: |
| 152 | + if any(identifier.startswith(prefix) for prefix in prefixes): |
| 153 | + identifiers_with_prefixes.add(identifier) |
| 154 | + return identifiers_with_prefixes |
| 155 | + |
108 | 156 | @staticmethod |
109 | 157 | def __rewrite_inclusions_in_file(file: Path, headers: Set[str], |
110 | 158 | src_include_dir: str, driver: str,) -> None: |
|
0 commit comments