Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
api_check.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# Copyright 2017 The PDFium Authors
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5"""Verifies exported functions in public/*.h are in fpdf_view_c_api_test.c.
6
7This script gathers a list of functions from public/*.h that contain
8FPDF_EXPORT. It then gathers a list of functions from
9fpdfsdk/fpdf_view_c_api_test.c. It then verifies both lists do not contain
10duplicates, and they match each other. It also checks that the order in
11fpdf_view_c_api_test.c is alphabetical within each section.
12
13"""
14
15import os
16import re
17import sys
18
19
20def _IsValidFunctionName(function, filename):
21 if function.startswith('FPDF'):
22 return True
23 if function.startswith('FSDK_') and filename == 'fpdf_ext.h':
24 return True
25 if function.startswith('FORM_') and filename == 'fpdf_formfill.h':
26 return True
27 return False
28
29
30def _FindFunction(function_snippet, filename):
31 function_split = function_snippet.split('(')
32 assert len(function_split) == 2
33 function = function_split[0]
34 assert _IsValidFunctionName(function, filename)
35 return function
36
37
38def _GetExportsFromHeader(dirname, filename):
39 with open(os.path.join(dirname, filename)) as f:
40 contents = f.readlines()
41 look_for_function_name = False
42 functions = []
43 for line in contents:
44 if look_for_function_name:
45 look_for_function_name = False
46 split_line = line.rstrip().split(' ')
47 functions.append(_FindFunction(split_line[0], filename))
48 continue
49
50 if not line.startswith('FPDF_EXPORT '):
51 continue
52
53 # Format should be: FPDF_EXPORT return_type FPDF_CALLCONV
54 split_line = line.rstrip().split(' ')
55 callconv_index = split_line.index('FPDF_CALLCONV')
56 assert callconv_index >= 2
57 if callconv_index + 1 == len(split_line):
58 look_for_function_name = True
59 continue
60
61 functions.append(_FindFunction(split_line[callconv_index + 1], filename))
62 return functions
63
64
66 public_path = os.path.join(src_path, 'public')
67 functions = []
68 for filename in os.listdir(public_path):
69 if filename.endswith('.h'):
70 functions.extend(_GetExportsFromHeader(public_path, filename))
71 return functions
72
73
74def _CheckSorted(functions):
75 unsorted_functions = set()
76 for i in range(len(functions) - 1):
77 if functions[i] > functions[i + 1]:
78 unsorted_functions.add(functions[i])
79 unsorted_functions.add(functions[i + 1])
80 return unsorted_functions
81
82
83def _GetFunctionsFromTest(api_test_path):
84 chk_regex = re.compile('^ CHK\‍((.*)\‍);\n$')
85 file_regex = re.compile('^ //.*\.h\n$')
86 with open(api_test_path) as f:
87 contents = f.readlines()
88 functions = []
89 functions_in_file = []
90 for line in contents:
91 if (file_regex.match(line)):
92 functions.append(functions_in_file)
93 functions_in_file = []
94 match = chk_regex.match(line)
95 if match:
96 functions_in_file.append(match.groups()[0])
97 functions.append(functions_in_file)
98 return functions
99
100
101def _FindDuplicates(functions):
102 return {f for f in functions if functions.count(f) > 1}
103
104
105def _CheckAndPrintFailures(failure_list, failure_message):
106 if not failure_list:
107 return True
108
109 print('%s:' % failure_message)
110 for f in sorted(failure_list):
111 print(f)
112 return False
113
114
115def main():
116 script_abspath = os.path.abspath(__file__)
117 src_path = os.path.dirname(os.path.dirname(os.path.dirname(script_abspath)))
118 public_functions = _GetFunctionsFromPublicHeaders(src_path)
119
120 api_test_relative_path = os.path.join('fpdfsdk', 'fpdf_view_c_api_test.c')
121 api_test_path = os.path.join(src_path, api_test_relative_path)
122 test_functions_per_section = _GetFunctionsFromTest(api_test_path)
123 result = True
124 unsorted_functions = set()
125 for functions in test_functions_per_section:
126 unsorted_functions |= _CheckSorted(functions)
128 unsorted_functions,
129 'Found CHKs that are not in alphabetical order within each section in %s'
130 % api_test_path)
131 result = result and check
132
133 duplicate_public_functions = _FindDuplicates(public_functions)
134 check = _CheckAndPrintFailures(duplicate_public_functions,
135 'Found duplicate functions in public headers')
136 result = result and check
137
138 test_functions = [
139 function for functions in test_functions_per_section
140 for function in functions
141 ]
142 duplicate_test_functions = _FindDuplicates(test_functions)
143 check = _CheckAndPrintFailures(duplicate_test_functions,
144 'Found duplicate functions in API test')
145 result = result and check
146
147 public_functions_set = set(public_functions)
148 test_functions_set = set(test_functions)
149 not_tested = public_functions_set.difference(test_functions_set)
150 check = _CheckAndPrintFailures(not_tested, 'Functions not tested')
151 result = result and check
152 non_existent = test_functions_set.difference(public_functions_set)
153 check = _CheckAndPrintFailures(non_existent, 'Tested functions do not exist')
154 result = result and check
155
156 if not result:
157 print('Some checks failed. Make sure %s is in sync with the public API '
158 'headers.' % api_test_relative_path)
159 return 1
160
161 return 0
162
163
164if __name__ == '__main__':
165 sys.exit(main())
_CheckSorted(functions)
Definition api_check.py:74
_GetFunctionsFromTest(api_test_path)
Definition api_check.py:83
_FindDuplicates(functions)
Definition api_check.py:101
_FindFunction(function_snippet, filename)
Definition api_check.py:30
_GetFunctionsFromPublicHeaders(src_path)
Definition api_check.py:65
_CheckAndPrintFailures(failure_list, failure_message)
Definition api_check.py:105
_IsValidFunctionName(function, filename)
Definition api_check.py:20
_GetExportsFromHeader(dirname, filename)
Definition api_check.py:38
static void split(QT_FT_Vector *b)
QDebug print(QDebug debug, QSslError::SslError error)
QFuture< QSet< QChar > > set
[10]
file open(QIODevice::ReadOnly)