From 9ccf08746e57a03fd9afc187cb3e23404cdc88bb Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Tue, 19 Dec 2017 18:50:15 +0000 Subject: Add missing fpdfview_c_api_test.c entries. Add a presubmit check to prevent future missing entries. Also fix an erroneous header entry. Change-Id: I8aeafd820de984f5af90b3e4ea428f582e82f254 Reviewed-on: https://pdfium-review.googlesource.com/21571 Reviewed-by: Henrique Nakashima Commit-Queue: Lei Zhang --- fpdfsdk/fpdfview_c_api_test.c | 20 +++++++ public/PRESUBMIT.py | 33 +++++++++++ public/fpdf_edit.h | 4 +- testing/tools/api_check.py | 131 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 public/PRESUBMIT.py create mode 100755 testing/tools/api_check.py diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c index 1526ffa8ae..de4fa1c564 100644 --- a/fpdfsdk/fpdfview_c_api_test.c +++ b/fpdfsdk/fpdfview_c_api_test.c @@ -59,6 +59,7 @@ int CheckPDFiumCApi() { CHK(FPDFAnnot_SetRect); CHK(FPDFAnnot_GetRect); CHK(FPDFAnnot_HasKey); + CHK(FPDFAnnot_GetValueType); CHK(FPDFAnnot_SetStringValue); CHK(FPDFAnnot_GetStringValue); CHK(FPDFAnnot_GetLinkedAnnot); @@ -71,6 +72,7 @@ int CheckPDFiumCApi() { CHK(FPDFDoc_GetAttachmentCount); CHK(FPDFDoc_AddAttachment); CHK(FPDFDoc_GetAttachment); + CHK(FPDFDoc_DeleteAttachment); CHK(FPDFAttachment_GetName); CHK(FPDFAttachment_HasKey); CHK(FPDFAttachment_GetValueType); @@ -210,6 +212,9 @@ int CheckPDFiumCApi() { CHK(FPDF_SetFormFieldHighlightAlpha); CHK(FPDF_RemoveFormFieldHighlight); CHK(FPDF_FFLDraw); +#ifdef _SKIA_SUPPORT_ + CHK(FPDF_FFLRecord); +#endif CHK(FPDF_GetFormType); #ifdef PDF_ENABLE_XFA CHK(FPDF_LoadXFA); @@ -251,6 +256,7 @@ int CheckPDFiumCApi() { CHK(FPDF_StructTree_GetChildAtIndex); CHK(FPDF_StructElement_GetAltText); CHK(FPDF_StructElement_GetType); + CHK(FPDF_StructElement_GetTitle); CHK(FPDF_StructElement_CountChildren); CHK(FPDF_StructElement_GetChildAtIndex); @@ -303,6 +309,14 @@ int CheckPDFiumCApi() { CHK(FPDF_InitLibraryWithConfig); CHK(FPDF_DestroyLibrary); CHK(FPDF_SetSandBoxPolicy); +#if defined(_WIN32) +#if defined(PDFIUM_PRINT_TEXT_WITH_GDI) + CHK(FPDF_SetTypefaceAccessibleFunc); + CHK(FPDF_SetPrintTextWithGDI); +#endif + CHK(FPDF_SetPrintPostscriptLevel); + CHK(FPDF_SetPrintMode); +#endif CHK(FPDF_LoadDocument); CHK(FPDF_LoadMemDocument); CHK(FPDF_LoadCustomDocument); @@ -315,8 +329,14 @@ int CheckPDFiumCApi() { CHK(FPDF_GetPageWidth); CHK(FPDF_GetPageHeight); CHK(FPDF_GetPageSizeByIndex); +#ifdef _WIN32 + CHK(FPDF_RenderPage); +#endif CHK(FPDF_RenderPageBitmap); CHK(FPDF_RenderPageBitmapWithMatrix); +#ifdef _SKIA_SUPPORT_ + CHK(FPDF_RenderPageSkp); +#endif CHK(FPDF_ClosePage); CHK(FPDF_CloseDocument); CHK(FPDF_DeviceToPage); diff --git a/public/PRESUBMIT.py b/public/PRESUBMIT.py new file mode 100644 index 0000000000..35bd873fbc --- /dev/null +++ b/public/PRESUBMIT.py @@ -0,0 +1,33 @@ +# Copyright 2017 The PDFium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Presubmit script for pdfium. + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts +for more details about the presubmit API built into depot_tools. +""" + +def _CheckPublicHeaders(input_api, output_api): + """Checks that the public headers match the API tests.""" + src_path = input_api.os_path.dirname(input_api.PresubmitLocalPath()) + check_script = input_api.os_path.join( + src_path, 'testing' , 'tools' , 'api_check.py') + try: + input_api.subprocess.check_output(check_script) + return [] + except input_api.subprocess.CalledProcessError as error: + return [output_api.PresubmitError('api_check.py failed:', + long_text=error.output)] + + +def CheckChangeOnUpload(input_api, output_api): + results = [] + results += _CheckPublicHeaders(input_api, output_api) + return results + + +def CheckChangeOnCommit(input_api, output_api): + results = [] + results += _CheckPublicHeaders(input_api, output_api) + return results diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h index f2dad739ca..3bd246b0ad 100644 --- a/public/fpdf_edit.h +++ b/public/fpdf_edit.h @@ -524,8 +524,8 @@ FPDFPath_SetStrokeWidth(FPDF_PAGEOBJECT path, float width); // // Line join can be one of following: FPDF_LINEJOIN_MITER, FPDF_LINEJOIN_ROUND, // FPDF_LINEJOIN_BEVEL -FPDF_EXPORT void FPDF_CALLCONV FPDF_CALLCONV -FPDFPath_SetLineJoin(FPDF_PAGEOBJECT page_object, int line_join); +FPDF_EXPORT void FPDF_CALLCONV FPDFPath_SetLineJoin(FPDF_PAGEOBJECT page_object, + int line_join); // Set the line cap of |page_object|. // diff --git a/testing/tools/api_check.py b/testing/tools/api_check.py new file mode 100755 index 0000000000..29754e4b56 --- /dev/null +++ b/testing/tools/api_check.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python +# Copyright 2017 The PDFium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Verifies exported functions in public/*.h are in fpdfview_c_api_test.c. + +This script gathers a list of functions from public/*.h that contain +FPDF_EXPORT. It then gathers a list of functions from +fpdfsdk/fpdfview_c_api_test.c. It then verifies both lists do not contain +duplicates, and they match each other. + +""" + +import os +import re +import sys + +def _IsValidFunctionName(function, filename): + if function.startswith('FPDF'): + return True + if function == 'FSDK_SetUnSpObjProcessHandler' and filename == 'fpdf_ext.h': + return True + if function.startswith('FORM_') and filename == 'fpdf_formfill.h': + return True + return False + + +def _FindFunction(function_snippet, filename): + function_split = function_snippet.split('(') + assert len(function_split) == 2 + function = function_split[0] + assert _IsValidFunctionName(function, filename) + return function + + +def _GetExportsFromHeader(dirname, filename): + with open(os.path.join(dirname, filename)) as f: + contents = f.readlines() + look_for_function_name = False + functions = [] + for line in contents: + if look_for_function_name: + look_for_function_name = False + split_line = line.rstrip().split(' ') + functions.append(_FindFunction(split_line[0], filename)) + continue + + if not line.startswith('FPDF_EXPORT '): + continue + + # Format should be: FPDF_EXPORT return_type FPDF_CALLCONV + split_line = line.rstrip().split(' ') + callconv_index = split_line.index('FPDF_CALLCONV') + assert callconv_index >= 2 + if callconv_index + 1 == len(split_line): + look_for_function_name = True + continue + + functions.append(_FindFunction(split_line[callconv_index + 1], filename)) + return functions + + +def _GetFunctionsFromPublicHeaders(src_path): + public_path = os.path.join(src_path, 'public') + functions = [] + for filename in os.listdir(public_path): + if filename.endswith('.h'): + functions.extend(_GetExportsFromHeader(public_path, filename)) + return functions + + +def _GetFunctionsFromTest(api_test_path): + chk_regex = re.compile('^ CHK\((.*)\);\n$') + with open(api_test_path) as f: + contents = f.readlines() + functions = [] + for line in contents: + match = chk_regex.match(line) + if match: + functions.append(match.groups()[0]) + return functions + + +def _FindDuplicates(functions): + return set([f for f in functions if functions.count(f) > 1]) + + +def _CheckAndPrintFailures(failure_list, failure_message): + if not failure_list: + return True + + print '%s:' % failure_message + for f in sorted(failure_list): + print f + return False + + +def main(): + script_abspath = os.path.abspath(__file__) + src_path = os.path.dirname(os.path.dirname(os.path.dirname(script_abspath))) + public_functions = _GetFunctionsFromPublicHeaders(src_path) + + api_test_path = os.path.join(src_path, 'fpdfsdk', 'fpdfview_c_api_test.c') + test_functions = _GetFunctionsFromTest(api_test_path) + + result = True + duplicate_public_functions = _FindDuplicates(public_functions) + check = _CheckAndPrintFailures(duplicate_public_functions, + 'Found duplicate functions in public headers') + result = result and check + + duplicate_test_functions = _FindDuplicates(test_functions) + check = _CheckAndPrintFailures(duplicate_test_functions, + 'Found duplicate functions in API test') + result = result and check + + public_functions_set = set(public_functions) + test_functions_set = set(test_functions) + not_tested = public_functions_set.difference(test_functions_set) + check = _CheckAndPrintFailures(not_tested, 'Functions not tested') + result = result and check + non_existent = test_functions_set.difference(public_functions_set) + check = _CheckAndPrintFailures(non_existent, 'Tested functions do not exist') + result = result and check + + return 0 if result else 1 + + +if __name__ == '__main__': + sys.exit(main()) -- cgit v1.2.3